@proveanything/smartlinks 2.1.10 → 2.1.12
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/claimSet.d.ts +38 -1
- package/dist/api/claimSet.js +83 -1
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/partner.d.ts +24 -0
- package/dist/api/partner.js +45 -0
- package/dist/docs/API_SUMMARY.md +279 -35
- package/dist/docs/tag-ranges.md +77 -0
- package/dist/http.js +3 -0
- package/dist/openapi.yaml +1094 -218
- package/dist/types/claimSet.d.ts +195 -0
- package/dist/types/nfc.d.ts +4 -0
- package/docs/API_SUMMARY.md +279 -35
- package/docs/tag-ranges.md +77 -0
- package/openapi.yaml +1094 -218
- package/package.json +87 -87
- package/scripts/publish.mjs +22 -7
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# NFC tag ranges and partners
|
|
2
|
+
|
|
3
|
+
For partners and enterprise clients who run their own tag programmes: mint a batch of tags, send them
|
|
4
|
+
to a manufacturer with instructions, get the chip UIDs back, then put the tags to work for a client or
|
|
5
|
+
product. Ordinary business collections don't use this.
|
|
6
|
+
|
|
7
|
+
## The words
|
|
8
|
+
|
|
9
|
+
| Word | Means |
|
|
10
|
+
|---|---|
|
|
11
|
+
| **Claim set** | A pool of codes on one tap domain and one tag type (NTAG 424 DNA, NTAG 213/215/216, or QR). Most partners need one. |
|
|
12
|
+
| **Range** | A named, contiguous block of tags inside a set: "Tap to donate - February", 100 tags, indexes 201-300. |
|
|
13
|
+
| **Index** | A tag's place in its set. Ranges never overlap and indexes are never reused. |
|
|
14
|
+
| **Partner** | An organisation above collections that owns sets and assigns their tags into collections its people administer. Set up by SmartLinks staff. |
|
|
15
|
+
|
|
16
|
+
## Who can do what
|
|
17
|
+
|
|
18
|
+
`scope` is `{ partnerId }` for a partner's sets, or `{ collectionId }` for a collection's own sets.
|
|
19
|
+
|
|
20
|
+
| Role | Can |
|
|
21
|
+
|---|---|
|
|
22
|
+
| Partner owner / admin, or a collection admin | Make sets, mint ranges, download the printer file and instructions, import UIDs, program tags, assign |
|
|
23
|
+
| Partner assigner | See ranges and tags (never keys), assign |
|
|
24
|
+
|
|
25
|
+
Assigning always needs you to be an admin of the collection the tags go to.
|
|
26
|
+
|
|
27
|
+
## The flow
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import { partner, claimSet } from '@proveanything/smartlinks'
|
|
31
|
+
|
|
32
|
+
const [p] = await partner.list() // the partners you belong to
|
|
33
|
+
const scope = { partnerId: p.id }
|
|
34
|
+
const [set] = await partner.claimSets(p.id) // or partner.createClaimSet(p.id, { name, tagType: 'ntag424', tapDomain })
|
|
35
|
+
|
|
36
|
+
// 1. Mint
|
|
37
|
+
const range = await claimSet.ranges.create(scope, set.id, { name: 'Tap to donate - February', quantity: 100 })
|
|
38
|
+
|
|
39
|
+
// 2. Send to print: the CSV (carries each tag's key) and the instruction sheet
|
|
40
|
+
const file = await claimSet.ranges.exportFile(scope, set.id, range.id) // { filename, csv }
|
|
41
|
+
const sheet = await claimSet.ranges.instructions(scope, set.id, range.id, 'pdf') // { filename, base64 }
|
|
42
|
+
await claimSet.ranges.update(scope, set.id, range.id, { stage: 'sent', manufacturer: 'Print Co', orderRef: 'PO-123' })
|
|
43
|
+
|
|
44
|
+
// 3. Receive: the manufacturer sends back the same file with UID filled in
|
|
45
|
+
const check = await claimSet.ranges.importUids(scope, set.id, range.id, { csv: returnedCsv })
|
|
46
|
+
// check.rows: ok / index_mismatch / bad_uid / uid_in_use / … ; nothing written yet
|
|
47
|
+
await claimSet.ranges.importUids(scope, set.id, range.id, { csv: returnedCsv, commit: true })
|
|
48
|
+
|
|
49
|
+
// 4. Assign all of it, or from-to
|
|
50
|
+
await claimSet.ranges.assign(scope, set.id, range.id, { collectionId: 'reading-fc', productId: 'scarf', start: 201, end: 250 })
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
**Programming on a phone instead of a manufacturer** (Sidekick): `ranges.next()` gives the lowest
|
|
54
|
+
tag without a chip, with its URL and key; write it, then `ranges.recordTag(scope, set.id, range.id, code, { uid })` (add `password` for a plain tag's write password).
|
|
55
|
+
|
|
56
|
+
To find where a chip or code went, `partner.lookupTags(partner.id, { uid })` or `{ code }` searches every set the partner owns and returns each hit's set, tag and range, never a key.
|
|
57
|
+
|
|
58
|
+
## The printer file
|
|
59
|
+
|
|
60
|
+
One row per tag, in index order. The manufacturer fills in `UID` and sends the same file back; rows are
|
|
61
|
+
matched by `Code`, and `Index` is checked.
|
|
62
|
+
|
|
63
|
+
| Tag type | Columns |
|
|
64
|
+
|---|---|
|
|
65
|
+
| NTAG 424 DNA | `Index, Code, URL, PiccOffset, Key, UID` |
|
|
66
|
+
| NTAG 213/215/216 | `Index, Code, URL, MirrorOffset, MirrorPage, MirrorByte, UID` |
|
|
67
|
+
| QR | `Index, Code, URL` |
|
|
68
|
+
|
|
69
|
+
`URL` is `https://{tap domain}/t/{set}/{code}` plus the placeholder the chip fills on every read
|
|
70
|
+
(`?p=` + 32 zeros for 424 SUN, `?m=00000000000000x000000` for the 21x UID and counter mirror). The
|
|
71
|
+
offsets are byte positions in the NDEF data, assuming the `https://` URI prefix code and a short record.
|
|
72
|
+
|
|
73
|
+
## Notes
|
|
74
|
+
|
|
75
|
+
- Range responses are never cached by the SDK: tags change as they're programmed and several carry keys.
|
|
76
|
+
- A tag bound to a proof (minted or claimed) is never moved or cleared by `assign`; it's reported in `skipped`.
|
|
77
|
+
- `status` is the stage (`minted`, `sent`, `received`), or `assigned` once every tag is assigned.
|
package/dist/http.js
CHANGED
|
@@ -219,6 +219,9 @@ function shouldSkipCache(path) {
|
|
|
219
219
|
// Bookings change by the second (places left, busy times, a booking's status) — never serve them stale.
|
|
220
220
|
if (/\/app\/[^/]+\/bookings(\/|\?|$)/i.test(path))
|
|
221
221
|
return true;
|
|
222
|
+
// Tag ranges change as tags are programmed, and carry the tags' keys — never cached, never persisted.
|
|
223
|
+
if (/\/claimSet\/[^/]+\/ranges(\/|\?|$)/i.test(path))
|
|
224
|
+
return true;
|
|
222
225
|
return false;
|
|
223
226
|
}
|
|
224
227
|
/** Evict the oldest (LRU) entry when the cache is at capacity. */
|