sello 0.1.0 → 0.1.2

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/README.md CHANGED
@@ -48,6 +48,8 @@ The implementation includes a local end-to-end demo, compact JWS token verificat
48
48
 
49
49
  ## Start Here
50
50
 
51
+ Sello currently requires Node.js 22.7 or newer.
52
+
51
53
  | Goal | Read |
52
54
  |------|------|
53
55
  | Add Sello in a few lines | [SDK Quickstart](docs/sdk-quickstart.md) |
package/dist/cbor.js ADDED
@@ -0,0 +1,337 @@
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+
18
+ export function cborTag(tag , value ) {
19
+ assertNonNegativeSafeInteger(tag, "tag");
20
+ return { tag, value };
21
+ }
22
+
23
+ export function encodeCbor(value ) {
24
+ if (typeof value === "number") {
25
+ return encodeInteger(value);
26
+ }
27
+
28
+ if (typeof value === "string") {
29
+ return concat([encodeLength(3, utf8ByteLength(value)), encodeUtf8(value)]);
30
+ }
31
+
32
+ if (value instanceof Uint8Array) {
33
+ return concat([encodeLength(2, value.byteLength), value]);
34
+ }
35
+
36
+ if (Array.isArray(value)) {
37
+ return concat([
38
+ encodeLength(4, value.length),
39
+ ...value.map((entry) => encodeCbor(entry)),
40
+ ]);
41
+ }
42
+
43
+ if (value instanceof Map) {
44
+ return encodeMap(value);
45
+ }
46
+
47
+ if (isTagged(value)) {
48
+ return concat([encodeLength(6, value.tag), encodeCbor(value.value)]);
49
+ }
50
+
51
+ throw new TypeError("unsupported CBOR value");
52
+ }
53
+
54
+ export function decodeCbor(bytes ) {
55
+ const reader = new CborReader(bytes);
56
+ const value = reader.readValue();
57
+ reader.assertDone();
58
+ return value;
59
+ }
60
+
61
+ export function concat(parts ) {
62
+ const length = parts.reduce((sum, part) => sum + part.byteLength, 0);
63
+ const out = new Uint8Array(length);
64
+ let offset = 0;
65
+
66
+ for (const part of parts) {
67
+ out.set(part, offset);
68
+ offset += part.byteLength;
69
+ }
70
+
71
+ return out;
72
+ }
73
+
74
+ function encodeInteger(value ) {
75
+ if (!Number.isSafeInteger(value)) {
76
+ throw new TypeError("CBOR integer must be a safe integer");
77
+ }
78
+
79
+ if (value >= 0) {
80
+ return encodeLength(0, value);
81
+ }
82
+
83
+ return encodeLength(1, -1 - value);
84
+ }
85
+
86
+ function encodeMap(value ) {
87
+ const entries = [...value.entries()].map(([key, entryValue]) => {
88
+ if (typeof key !== "number" && typeof key !== "string") {
89
+ throw new TypeError("CBOR map keys must be strings or numbers");
90
+ }
91
+
92
+ return {
93
+ key: encodeCbor(key),
94
+ value: encodeCbor(entryValue),
95
+ };
96
+ });
97
+
98
+ entries.sort((a, b) => compareBytes(a.key, b.key));
99
+
100
+ for (let index = 1; index < entries.length; index += 1) {
101
+ if (compareBytes(entries[index - 1].key, entries[index].key) === 0) {
102
+ throw new TypeError("CBOR map contains duplicate keys");
103
+ }
104
+ }
105
+
106
+ return concat([
107
+ encodeLength(5, entries.length),
108
+ ...entries.flatMap((entry) => [entry.key, entry.value]),
109
+ ]);
110
+ }
111
+
112
+ function encodeLength(majorType , value ) {
113
+ assertNonNegativeSafeInteger(value, "CBOR length/value");
114
+ const prefix = majorType << 5;
115
+
116
+ if (value < 24) {
117
+ return Uint8Array.of(prefix | value);
118
+ }
119
+
120
+ if (value <= 0xff) {
121
+ return Uint8Array.of(prefix | 24, value);
122
+ }
123
+
124
+ if (value <= 0xffff) {
125
+ return Uint8Array.of(prefix | 25, value >> 8, value & 0xff);
126
+ }
127
+
128
+ if (value <= 0xffffffff) {
129
+ return Uint8Array.of(
130
+ prefix | 26,
131
+ (value >>> 24) & 0xff,
132
+ (value >>> 16) & 0xff,
133
+ (value >>> 8) & 0xff,
134
+ value & 0xff,
135
+ );
136
+ }
137
+
138
+ throw new RangeError("CBOR values larger than uint32 are not supported yet");
139
+ }
140
+
141
+ function compareBytes(a , b ) {
142
+ const length = Math.min(a.byteLength, b.byteLength);
143
+
144
+ for (let index = 0; index < length; index += 1) {
145
+ const diff = a[index] - b[index];
146
+ if (diff !== 0) {
147
+ return diff;
148
+ }
149
+ }
150
+
151
+ return a.byteLength - b.byteLength;
152
+ }
153
+
154
+ function assertNonNegativeSafeInteger(value , name ) {
155
+ if (!Number.isSafeInteger(value) || value < 0) {
156
+ throw new TypeError(`${name} must be a non-negative safe integer`);
157
+ }
158
+ }
159
+
160
+ function isTagged(value ) {
161
+ return (
162
+ typeof value === "object" &&
163
+ value !== null &&
164
+ "tag" in value &&
165
+ "value" in value
166
+ );
167
+ }
168
+
169
+ const textEncoder = new TextEncoder();
170
+ const textDecoder = new TextDecoder("utf-8", { fatal: true });
171
+
172
+ function encodeUtf8(value ) {
173
+ return textEncoder.encode(value);
174
+ }
175
+
176
+ function decodeUtf8(value ) {
177
+ return textDecoder.decode(value);
178
+ }
179
+
180
+ function utf8ByteLength(value ) {
181
+ return encodeUtf8(value).byteLength;
182
+ }
183
+
184
+ class CborReader {
185
+ #bytes ;
186
+ #offset = 0;
187
+
188
+ constructor(bytes ) {
189
+ this.#bytes = bytes;
190
+ }
191
+
192
+ readValue() {
193
+ const initialByte = this.readByte();
194
+ const majorType = initialByte >> 5;
195
+ const additionalInfo = initialByte & 0x1f;
196
+
197
+ if (majorType === 0) {
198
+ return this.readLength(additionalInfo);
199
+ }
200
+
201
+ if (majorType === 1) {
202
+ return -1 - this.readLength(additionalInfo);
203
+ }
204
+
205
+ if (majorType === 2) {
206
+ const length = this.readLength(additionalInfo);
207
+ return this.readBytes(length);
208
+ }
209
+
210
+ if (majorType === 3) {
211
+ const length = this.readLength(additionalInfo);
212
+ return decodeUtf8(this.readBytes(length));
213
+ }
214
+
215
+ if (majorType === 4) {
216
+ const length = this.readLength(additionalInfo);
217
+ return this.readArray(length);
218
+ }
219
+
220
+ if (majorType === 5) {
221
+ const length = this.readLength(additionalInfo);
222
+ return this.readMap(length);
223
+ }
224
+
225
+ if (majorType === 6) {
226
+ const tag = this.readLength(additionalInfo);
227
+ return cborTag(tag, this.readValue());
228
+ }
229
+
230
+ throw new TypeError(`unsupported CBOR major type ${majorType}`);
231
+ }
232
+
233
+ assertDone() {
234
+ if (this.#offset !== this.#bytes.byteLength) {
235
+ throw new TypeError("CBOR data has trailing bytes");
236
+ }
237
+ }
238
+
239
+ readArray(length ) {
240
+ const out = [];
241
+
242
+ for (let index = 0; index < length; index += 1) {
243
+ out.push(this.readValue());
244
+ }
245
+
246
+ return out;
247
+ }
248
+
249
+ readMap(length ) {
250
+ const out = new Map();
251
+ let previousEncodedKey ;
252
+
253
+ for (let index = 0; index < length; index += 1) {
254
+ const keyStart = this.#offset;
255
+ const key = this.readValue();
256
+ const encodedKey = this.#bytes.subarray(keyStart, this.#offset);
257
+
258
+ if (typeof key !== "string" && typeof key !== "number") {
259
+ throw new TypeError("CBOR map keys must be strings or numbers");
260
+ }
261
+
262
+ if (previousEncodedKey && compareBytes(previousEncodedKey, encodedKey) >= 0) {
263
+ throw new TypeError("CBOR map keys are not in deterministic order");
264
+ }
265
+
266
+ previousEncodedKey = encodedKey;
267
+ out.set(key, this.readValue());
268
+ }
269
+
270
+ return out;
271
+ }
272
+
273
+ readLength(additionalInfo ) {
274
+ if (additionalInfo < 24) {
275
+ return additionalInfo;
276
+ }
277
+
278
+ if (additionalInfo === 24) {
279
+ const value = this.readByte();
280
+ if (value < 24) {
281
+ throw new TypeError("CBOR integer/length is not minimally encoded");
282
+ }
283
+ return value;
284
+ }
285
+
286
+ if (additionalInfo === 25) {
287
+ const value = this.readUint16();
288
+ if (value <= 0xff) {
289
+ throw new TypeError("CBOR integer/length is not minimally encoded");
290
+ }
291
+ return value;
292
+ }
293
+
294
+ if (additionalInfo === 26) {
295
+ const value = this.readUint32();
296
+ if (value <= 0xffff) {
297
+ throw new TypeError("CBOR integer/length is not minimally encoded");
298
+ }
299
+ return value;
300
+ }
301
+
302
+ throw new TypeError("CBOR indefinite or uint64 lengths are not supported");
303
+ }
304
+
305
+ readByte() {
306
+ if (this.#offset >= this.#bytes.byteLength) {
307
+ throw new TypeError("unexpected end of CBOR data");
308
+ }
309
+
310
+ return this.#bytes[this.#offset++];
311
+ }
312
+
313
+ readBytes(length ) {
314
+ const end = this.#offset + length;
315
+
316
+ if (end > this.#bytes.byteLength) {
317
+ throw new TypeError("unexpected end of CBOR data");
318
+ }
319
+
320
+ const out = this.#bytes.subarray(this.#offset, end);
321
+ this.#offset = end;
322
+ return out;
323
+ }
324
+
325
+ readUint16() {
326
+ return (this.readByte() << 8) | this.readByte();
327
+ }
328
+
329
+ readUint32() {
330
+ return (
331
+ (this.readByte() * 0x1000000) +
332
+ (this.readByte() << 16) +
333
+ (this.readByte() << 8) +
334
+ this.readByte()
335
+ );
336
+ }
337
+ }