wao 0.36.6 → 0.37.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.
@@ -1,1159 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.verifyContentDigest = exports.toBuffer = exports.hasValidSignature = exports.getSignatureNames = exports.from = exports.extractKeys = void 0;
7
- var _ramda = require("ramda");
8
- var _hbsig = require("hbsig");
9
- var _base64url = _interopRequireDefault(require("base64url"));
10
- function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
11
- function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
12
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
13
- function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
14
- function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
15
- function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
16
- function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
17
- function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
18
- function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
19
- function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
20
- function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
21
- function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
22
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
23
- function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
24
- function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
25
- function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
26
- function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
27
- function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
28
- /**
29
- * Get multipart boundary from content-type header
30
- */
31
- var getBoundary = function getBoundary(http) {
32
- var ctype = http.headers["content-type"];
33
- if (ctype && /^multipart\/form-data;/.test((0, _ramda.trim)(ctype))) {
34
- var _iterator = _createForOfIteratorHelper((0, _ramda.trim)(ctype).split(";").slice(1)),
35
- _step;
36
- try {
37
- for (_iterator.s(); !(_step = _iterator.n()).done;) {
38
- var v = _step.value;
39
- var sp2 = v.split("=");
40
- if ((0, _ramda.trim)(sp2[0]) === "boundary") return (0, _ramda.trim)(sp2[1]).replace(/"/g, "");
41
- }
42
- } catch (err) {
43
- _iterator.e(err);
44
- } finally {
45
- _iterator.f();
46
- }
47
- }
48
- return null;
49
- };
50
-
51
- /**
52
- * Extract specified components from HTTP message
53
- * @param {Object} http - HTTP message object with headers and optional body
54
- * @param {Array} components - Array of component names to extract
55
- * @returns {Object} Extracted components with their values
56
- */
57
- var extract = function extract(http, components) {
58
- var extracted = {};
59
- var needsBody = components.some(function (c) {
60
- return c.replace(/"/g, "").toLowerCase() === "content-digest";
61
- });
62
-
63
- // First extract ao-types if it's signed
64
- var hasAoTypes = components.some(function (c) {
65
- return c.replace(/"/g, "").toLowerCase() === "ao-types";
66
- });
67
- if (hasAoTypes) {
68
- var aoTypes = http.headers["ao-types"] || http.headers["Ao-Types"];
69
- if (aoTypes) {
70
- extracted["ao-types"] = aoTypes;
71
- }
72
- }
73
-
74
- // Extract ao-ids if it's signed
75
- var hasAoIds = components.some(function (c) {
76
- return c.replace(/"/g, "").toLowerCase() === "ao-ids";
77
- });
78
- if (hasAoIds) {
79
- var aoIds = http.headers["ao-ids"] || http.headers["Ao-Ids"];
80
- if (aoIds) {
81
- extracted["ao-ids"] = aoIds;
82
- }
83
- }
84
- var _iterator2 = _createForOfIteratorHelper(components),
85
- _step2;
86
- try {
87
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
88
- var component = _step2.value;
89
- var cleanComponent = component.replace(/"/g, "");
90
- if (cleanComponent.startsWith("@")) {
91
- // Handle derived components
92
- switch (cleanComponent) {
93
- case "@method":
94
- extracted[cleanComponent] = http.method || "GET";
95
- break;
96
- case "@target-uri":
97
- extracted[cleanComponent] = http.url || "";
98
- break;
99
- case "@authority":
100
- extracted[cleanComponent] = http.headers.host || "";
101
- break;
102
- case "@scheme":
103
- if (http.url) {
104
- var url = new URL(http.url);
105
- extracted[cleanComponent] = url.protocol.replace(":", "");
106
- }
107
- break;
108
- case "@request-target":
109
- if (http.url) {
110
- var _url = new URL(http.url);
111
- extracted[cleanComponent] = _url.pathname + _url.search;
112
- }
113
- break;
114
- case "@path":
115
- if (http.url) {
116
- var _url2 = new URL(http.url);
117
- extracted[cleanComponent] = _url2.pathname;
118
- }
119
- break;
120
- case "@query":
121
- if (http.url) {
122
- var _url3 = new URL(http.url);
123
- extracted[cleanComponent] = _url3.search;
124
- }
125
- break;
126
- case "@status":
127
- extracted[cleanComponent] = String(http.status || http["@status"] || "");
128
- break;
129
- case "@query-param":
130
- // This would need additional parsing logic for specific query parameters
131
- break;
132
- }
133
- } else {
134
- // Handle regular headers - try both exact case and lowercase
135
- var headerValue = http.headers[cleanComponent] || http.headers[cleanComponent.toLowerCase()];
136
- if (headerValue !== null && headerValue !== undefined) {
137
- extracted[cleanComponent] = headerValue;
138
- }
139
- }
140
- }
141
-
142
- // If content-digest is signed, we need to include the body
143
- } catch (err) {
144
- _iterator2.e(err);
145
- } finally {
146
- _iterator2.f();
147
- }
148
- if (needsBody && http.body !== undefined) {
149
- extracted["body"] = http.body;
150
- }
151
-
152
- // Add flag if body is needed but missing
153
- if (needsBody && http.body === undefined) {
154
- extracted["__bodyRequired__"] = true;
155
- }
156
- return extracted;
157
- };
158
-
159
- /**
160
- * Convert body to Buffer from various sources
161
- * @param {string|Buffer|ArrayBuffer} body - The body to convert
162
- * @returns {Buffer} The body as a Buffer
163
- */
164
- var toBuffer = exports.toBuffer = function toBuffer(body) {
165
- if (!body) {
166
- return Buffer.alloc(0);
167
- }
168
-
169
- // If it's already a Buffer, return it
170
- if (Buffer.isBuffer(body)) {
171
- return body;
172
- }
173
-
174
- // If it's a string, convert to Buffer
175
- if (typeof body === "string") {
176
- return Buffer.from(body, "utf-8");
177
- }
178
-
179
- // If it's an ArrayBuffer or TypedArray
180
- if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {
181
- return Buffer.from(body);
182
- }
183
- throw new Error("Unsupported body type");
184
- };
185
-
186
- /**
187
- * Parse ao-ids dictionary
188
- * @param {string} aoIds - The ao-ids header value
189
- * @returns {Object} Parsed ID mappings
190
- */
191
- var parseAoIds = function parseAoIds(aoIds) {
192
- var result = {};
193
-
194
- // Match pattern: ID="value"
195
- var regex = /([A-Za-z0-9_-]{43})="([^"]*)"/g;
196
- var match;
197
- while ((match = regex.exec(aoIds)) !== null) {
198
- var _match = match,
199
- _match2 = _slicedToArray(_match, 3),
200
- id = _match2[1],
201
- value = _match2[2];
202
- result[id] = value;
203
- }
204
- return result;
205
- };
206
-
207
- /**
208
- * Convert message to JSON with proper type conversions
209
- * Following the logic from dev_codec_structured, dev_codec_httpsig_conv, and dev_codec_flat
210
- * @param {Object} msg - The message to convert
211
- * @returns {Object} JSON representation
212
- */
213
- var _toJSON = function toJSON(msg) {
214
- if (!msg || _typeof(msg) !== "object") {
215
- return msg;
216
- }
217
- var result = _objectSpread({}, msg);
218
-
219
- // Handle ao-ids parsing
220
- if (result["ao-ids"]) {
221
- var parsedIds = parseAoIds(result["ao-ids"]);
222
- // Remove the ao-ids header and merge the parsed IDs
223
- delete result["ao-ids"];
224
- result = _objectSpread(_objectSpread({}, result), parsedIds);
225
- }
226
-
227
- // First, handle the multipart body if present
228
- var contentType = result["content-type"];
229
- var body = result.body;
230
- if (body && contentType && contentType.includes("multipart/form-data")) {
231
- var boundary = getBoundary({
232
- headers: {
233
- "content-type": contentType
234
- }
235
- });
236
- if (boundary) {
237
- // Parse multipart body
238
- var parts = parseMultipartBody(body, boundary);
239
-
240
- // Remove the raw body since we've parsed it
241
- delete result.body;
242
-
243
- // Merge parsed parts into result
244
- for (var _i = 0, _Object$entries = Object.entries(parts); _i < _Object$entries.length; _i++) {
245
- var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
246
- partName = _Object$entries$_i[0],
247
- partData = _Object$entries$_i[1];
248
- // Parse ao-types from part data if present
249
- var partTypes = {};
250
- if (partData["ao-types"]) {
251
- // Updated regex to handle spaces and trim the key
252
- var matches = _toConsumableArray(partData["ao-types"].matchAll(/([^=,]+)="([^"]+)"/g));
253
- var _iterator3 = _createForOfIteratorHelper(matches),
254
- _step3;
255
- try {
256
- for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
257
- var _step3$value = _slicedToArray(_step3.value, 3),
258
- _ = _step3$value[0],
259
- key = _step3$value[1],
260
- type = _step3$value[2];
261
- partTypes[key.trim()] = type;
262
- }
263
- } catch (err) {
264
- _iterator3.e(err);
265
- } finally {
266
- _iterator3.f();
267
- }
268
- }
269
-
270
- // Apply type conversions to part data
271
- var convertedPartData = {};
272
- for (var _i2 = 0, _Object$entries2 = Object.entries(partData); _i2 < _Object$entries2.length; _i2++) {
273
- var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2),
274
- _key = _Object$entries2$_i[0],
275
- value = _Object$entries2$_i[1];
276
- if (_key === "ao-types" || _key === "content-disposition") continue;
277
- var _type = partTypes[_key];
278
- if (_type && typeof value === "string") {
279
- convertedPartData[_key] = convertByType(value, _type);
280
- } else {
281
- convertedPartData[_key] = value;
282
- }
283
- }
284
-
285
- // Store the result
286
- if (Object.keys(convertedPartData).length > 0) {
287
- // Check if the part name suggests it's an array element (ends with /number)
288
- var isArrayElement = /\/\d+$/.test(partName);
289
-
290
- // For top-level parts (no slash in name) with objects, keep the structure
291
- var isTopLevel = !partName.includes("/");
292
-
293
- // Check if this is a nested path that will be unflattened
294
- var isNestedPath = partName.includes("/") && !isArrayElement;
295
- if (isArrayElement || isNestedPath) {
296
- // Array elements and nested paths keep their structure
297
- result[partName] = convertedPartData;
298
- } else if (isTopLevel || Object.keys(convertedPartData).length > 1) {
299
- // Top-level objects or multi-field objects keep their structure
300
- result[partName] = convertedPartData;
301
- } else {
302
- // Only lift single values for simple cases
303
- result[partName] = convertedPartData[Object.keys(convertedPartData)[0]];
304
- }
305
- }
306
-
307
- // Store type information for nested fields
308
- if (Object.keys(partTypes).length > 0) {
309
- for (var _i3 = 0, _Object$entries3 = Object.entries(partTypes); _i3 < _Object$entries3.length; _i3++) {
310
- var _Object$entries3$_i = _slicedToArray(_Object$entries3[_i3], 2),
311
- fieldKey = _Object$entries3$_i[0],
312
- fieldType = _Object$entries3$_i[1];
313
- if (fieldKey !== "ao-types" && fieldKey !== "content-disposition") {
314
- // Add to global typeMap with the full path
315
- var fullPath = partName + "/" + fieldKey;
316
- // Store in the ao-types for later use
317
- if (!result["__typeMap"]) result["__typeMap"] = {};
318
- result["__typeMap"][fullPath] = fieldType;
319
- }
320
- }
321
- }
322
- }
323
- }
324
- }
325
-
326
- // Parse global ao-types to get type information
327
- var typeMap = {};
328
- if (result["ao-types"]) {
329
- // Updated regex to handle spaces and trim the key
330
- var _matches = _toConsumableArray(result["ao-types"].matchAll(/([^=,]+)="([^"]+)"/g));
331
- var _iterator4 = _createForOfIteratorHelper(_matches),
332
- _step4;
333
- try {
334
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
335
- var _step4$value = _slicedToArray(_step4.value, 3),
336
- _2 = _step4$value[0],
337
- _key2 = _step4$value[1],
338
- _type2 = _step4$value[2];
339
- typeMap[_key2.trim()] = _type2;
340
- }
341
- } catch (err) {
342
- _iterator4.e(err);
343
- } finally {
344
- _iterator4.f();
345
- }
346
- }
347
-
348
- // Merge in types from multipart parsing
349
- if (result["__typeMap"]) {
350
- Object.assign(typeMap, result["__typeMap"]);
351
- delete result["__typeMap"];
352
- }
353
-
354
- // Also collect types from multipart parts for nested fields
355
- for (var _i4 = 0, _Object$entries4 = Object.entries(result); _i4 < _Object$entries4.length; _i4++) {
356
- var _Object$entries4$_i = _slicedToArray(_Object$entries4[_i4], 2),
357
- _key3 = _Object$entries4$_i[0],
358
- _value = _Object$entries4$_i[1];
359
- if (_key3.includes("/") && _typeof(_value) === "object" && _value !== null && _value.__partTypes) {
360
- // This is a multipart part with type information
361
- for (var _i5 = 0, _Object$entries5 = Object.entries(_value.__partTypes); _i5 < _Object$entries5.length; _i5++) {
362
- var _Object$entries5$_i = _slicedToArray(_Object$entries5[_i5], 2),
363
- _fieldKey = _Object$entries5$_i[0],
364
- _fieldType = _Object$entries5$_i[1];
365
- // Create the full path for the type
366
- var _fullPath = "".concat(_key3, "/").concat(_fieldKey);
367
- typeMap[_fullPath] = _fieldType;
368
- }
369
- // Remove the __partTypes after processing
370
- delete _value.__partTypes;
371
- }
372
- }
373
-
374
- // Add empty values for fields that are in ao-types but not in result
375
- for (var _i6 = 0, _Object$entries6 = Object.entries(typeMap); _i6 < _Object$entries6.length; _i6++) {
376
- var _Object$entries6$_i = _slicedToArray(_Object$entries6[_i6], 2),
377
- _key4 = _Object$entries6$_i[0],
378
- _type3 = _Object$entries6$_i[1];
379
- if (!(_key4 in result) && _type3.startsWith("empty-")) {
380
- result[_key4] = convertByType("", _type3);
381
- }
382
- }
383
-
384
- // Apply type conversions and build final result
385
- var finalResult = {};
386
- for (var _i7 = 0, _Object$entries7 = Object.entries(result); _i7 < _Object$entries7.length; _i7++) {
387
- var _Object$entries7$_i = _slicedToArray(_Object$entries7[_i7], 2),
388
- _key5 = _Object$entries7$_i[0],
389
- _value2 = _Object$entries7$_i[1];
390
- // Skip internal keys and headers we don't want in the final result
391
- if (_key5.startsWith("__")) continue;
392
-
393
- // Skip @ fields EXCEPT @path which we want to include
394
- if (_key5.startsWith("@") && _key5 !== "@path") continue;
395
- if (_key5 === "ao-types") continue;
396
- if (_key5 === "content-type") continue;
397
- if (_key5 === "content-digest") continue;
398
- if (_key5 === "signature") continue;
399
- if (_key5 === "signature-input") continue;
400
- if (_key5 === "body-keys") continue;
401
-
402
- // Get the type for this key
403
- var _type4 = typeMap[_key5];
404
-
405
- // Special handling for objects that should be lists
406
- if (_type4 === "list" && _typeof(_value2) === "object" && _value2 !== null && !Array.isArray(_value2)) {
407
- // This is an object that should be converted to a list
408
- var converted = maybeConvertToArray(_value2);
409
- finalResult[_key5] = converted;
410
- } else if (_type4 && typeof _value2 === "string") {
411
- // Convert based on type
412
- finalResult[_key5] = convertByType(_value2, _type4);
413
- } else if (_type4 && _value2 === undefined) {
414
- // Handle empty types
415
- finalResult[_key5] = convertByType("", _type4);
416
- } else if (_typeof(_value2) === "object" && _value2 !== null && !Array.isArray(_value2)) {
417
- // For objects without a specific type, keep them as objects
418
- // Only recurse for processing nested values
419
- var processedObj = {};
420
- for (var _i8 = 0, _Object$entries8 = Object.entries(_value2); _i8 < _Object$entries8.length; _i8++) {
421
- var _Object$entries8$_i = _slicedToArray(_Object$entries8[_i8], 2),
422
- k = _Object$entries8$_i[0],
423
- v = _Object$entries8$_i[1];
424
- if (Array.isArray(v)) {
425
- // Keep arrays as arrays
426
- processedObj[k] = v;
427
- } else if (_typeof(v) === "object" && v !== null) {
428
- processedObj[k] = _toJSON(v);
429
- } else {
430
- processedObj[k] = v;
431
- }
432
- }
433
- finalResult[_key5] = processedObj;
434
- } else {
435
- // Keep as-is (including arrays)
436
- finalResult[_key5] = _value2;
437
- }
438
- }
439
-
440
- // Handle flattened paths - pass typeMap for context
441
- return unflattenPaths(finalResult, typeMap);
442
- };
443
-
444
- /**
445
- * Convert objects with numeric keys to arrays
446
- */
447
- var maybeConvertToArray = function maybeConvertToArray(obj) {
448
- if (Array.isArray(obj)) return obj;
449
- var keys = Object.keys(obj);
450
- var numericKeys = keys.filter(function (k) {
451
- return /^\d+$/.test(k);
452
- });
453
-
454
- // If all keys are numeric and sequential starting from 1
455
- if (numericKeys.length > 0 && numericKeys.length === keys.length) {
456
- var sortedNumericKeys = numericKeys.map(Number).sort(function (a, b) {
457
- return a - b;
458
- });
459
- var maxIndex = Math.max.apply(Math, _toConsumableArray(sortedNumericKeys));
460
- var arr = [];
461
-
462
- // Fill array based on numeric keys (1-based to 0-based)
463
- for (var i = 1; i <= maxIndex; i++) {
464
- if (obj[String(i)] !== undefined) {
465
- arr[i - 1] = obj[String(i)];
466
- }
467
- }
468
- return arr;
469
- }
470
- return obj;
471
- };
472
-
473
- /**
474
- * Convert value based on its type
475
- */
476
- var convertByType = function convertByType(value, type) {
477
- switch (type) {
478
- case "integer":
479
- // Handle structured field integer format
480
- if (typeof value === "string" && value.match(/^"?\(ao-type-integer\)\s+(\d+)"?$/)) {
481
- var match = value.match(/(\d+)/);
482
- return parseInt(match[1], 10);
483
- }
484
- return parseInt(value, 10);
485
- case "float":
486
- case "decimal":
487
- return parseFloat(value);
488
- case "boolean":
489
- return value === "true" || value === "?1";
490
- case "atom":
491
- // Remove quotes from atom values
492
- var atomValue = value;
493
-
494
- // Remove any surrounding quotes (single or double)
495
- if (atomValue.startsWith('"') && atomValue.endsWith('"') || atomValue.startsWith("'") && atomValue.endsWith("'")) {
496
- atomValue = atomValue.slice(1, -1);
497
- }
498
-
499
- // Also handle escaped quotes
500
- atomValue = atomValue.replace(/\\"/g, '"').replace(/\\'/g, "'");
501
-
502
- // Handle special atom values
503
- if (atomValue === "true") return true;
504
- if (atomValue === "false") return false;
505
- if (atomValue === "null") return null;
506
-
507
- // For other atoms, return as Symbol
508
- return Symbol["for"](atomValue);
509
- case "list":
510
- // Handle case where list is a comma-separated string
511
- if (typeof value === "string" && !value.startsWith("(")) {
512
- var items = [];
513
- var current = "";
514
- var inQuotes = false;
515
- var depth = 0;
516
- for (var i = 0; i < value.length; i++) {
517
- var _char = value[i];
518
- var prevChar = value[i - 1];
519
- if (_char === '"' && prevChar !== "\\") {
520
- inQuotes = !inQuotes;
521
- }
522
- if (!inQuotes) {
523
- if (_char === "(") {
524
- depth++;
525
- } else if (_char === ")") {
526
- depth--;
527
- } else if (_char === "," && depth === 0) {
528
- if (current.trim()) {
529
- // Parse the item to handle type annotations
530
- items.push(parseStructuredItem(current.trim()));
531
- }
532
- current = "";
533
- continue;
534
- }
535
- }
536
- current += _char;
537
- }
538
- if (current.trim()) {
539
- items.push(parseStructuredItem(current.trim()));
540
- }
541
- return items;
542
- }
543
- return parseStructuredList(value);
544
- case "map":
545
- case "dictionary":
546
- return parseStructuredDict(value);
547
- case "empty-binary":
548
- return "";
549
- case "empty-list":
550
- return [];
551
- case "empty-message":
552
- return {};
553
- default:
554
- return value;
555
- }
556
- };
557
-
558
- /**
559
- * Parse structured field list
560
- */
561
- var parseStructuredList = function parseStructuredList(value) {
562
- if (!value || value === "()") return [];
563
-
564
- // Remove outer quotes if present
565
- var content = value.trim();
566
- if (content.startsWith('"') && content.endsWith('"')) {
567
- content = content.slice(1, -1);
568
- }
569
- var items = [];
570
- var current = "";
571
- var inQuotes = false;
572
- var depth = 0;
573
- for (var i = 0; i < content.length; i++) {
574
- var _char2 = content[i];
575
- var prevChar = content[i - 1];
576
- if (_char2 === '"' && prevChar !== "\\") {
577
- inQuotes = !inQuotes;
578
- current += _char2;
579
- } else if (!inQuotes) {
580
- if (_char2 === "(") {
581
- depth++;
582
- current += _char2;
583
- } else if (_char2 === ")") {
584
- depth--;
585
- current += _char2;
586
- } else if (_char2 === "," && depth === 0) {
587
- if (current.trim()) {
588
- items.push(parseStructuredItem(current.trim()));
589
- }
590
- current = "";
591
- } else {
592
- current += _char2;
593
- }
594
- } else {
595
- current += _char2;
596
- }
597
- }
598
- if (current.trim()) {
599
- items.push(parseStructuredItem(current.trim()));
600
- }
601
- return items;
602
- };
603
-
604
- /**
605
- * Parse structured field item
606
- */
607
- var parseStructuredItem = function parseStructuredItem(item) {
608
- // Quoted string - handle first to properly process inner content
609
- if (item.startsWith('"') && item.endsWith('"')) {
610
- var inner = item.slice(1, -1).replace(/\\"/g, '"');
611
-
612
- // Check if the inner content is ao-type encoded
613
- var innerAoTypeMatch = inner.match(/^\(ao-type-(\w+)\)\s+(.+)$/);
614
- if (innerAoTypeMatch) {
615
- var _innerAoTypeMatch = _slicedToArray(innerAoTypeMatch, 3),
616
- type = _innerAoTypeMatch[1],
617
- value = _innerAoTypeMatch[2];
618
- // The value here has already had escaped quotes converted to real quotes
619
- // If it's wrapped in quotes, remove them
620
- var cleanValue = value;
621
- if (cleanValue.startsWith('"') && cleanValue.endsWith('"') || cleanValue.startsWith("'") && cleanValue.endsWith("'")) {
622
- cleanValue = cleanValue.slice(1, -1);
623
- }
624
- return convertByType(cleanValue, type);
625
- }
626
- return inner;
627
- }
628
-
629
- // Handle ao-type encoded items without outer quotes
630
- var aoTypeMatch = item.match(/^\(ao-type-(\w+)\)\s+(.+)$/);
631
- if (aoTypeMatch) {
632
- var _aoTypeMatch = _slicedToArray(aoTypeMatch, 3),
633
- _type5 = _aoTypeMatch[1],
634
- _value3 = _aoTypeMatch[2];
635
- var _cleanValue = _value3;
636
- // Handle escaped quotes
637
- _cleanValue = _cleanValue.replace(/\\"/g, '"');
638
- // If wrapped in quotes, remove them
639
- if (_cleanValue.startsWith('"') && _cleanValue.endsWith('"') || _cleanValue.startsWith("'") && _cleanValue.endsWith("'")) {
640
- _cleanValue = _cleanValue.slice(1, -1);
641
- }
642
- return convertByType(_cleanValue, _type5);
643
- }
644
-
645
- // Boolean
646
- if (item === "?1") return true;
647
- if (item === "?0") return false;
648
-
649
- // Number
650
- if (/^-?\d+$/.test(item)) {
651
- return parseInt(item, 10);
652
- }
653
- if (/^-?\d+\.\d+$/.test(item)) {
654
- return parseFloat(item);
655
- }
656
-
657
- // Nested list
658
- if (item.startsWith("(") && item.endsWith(")")) {
659
- return parseStructuredList(item);
660
- }
661
- return item;
662
- };
663
-
664
- /**
665
- * Parse structured field dictionary
666
- */
667
- var parseStructuredDict = function parseStructuredDict(value) {
668
- var decoded = (0, _hbsig.decodeSigInput)(value);
669
- var result = {};
670
- for (var _i9 = 0, _Object$entries9 = Object.entries(decoded); _i9 < _Object$entries9.length; _i9++) {
671
- var _Object$entries9$_i = _slicedToArray(_Object$entries9[_i9], 2),
672
- key = _Object$entries9$_i[0],
673
- info = _Object$entries9$_i[1];
674
- if (info && info.components && info.components.length > 0) {
675
- result[key] = parseStructuredItem(info.components[0]);
676
- } else {
677
- result[key] = true;
678
- }
679
- }
680
- return result;
681
- };
682
-
683
- /**
684
- * Parse body-keys list
685
- */
686
- var parseBodyKeysList = function parseBodyKeysList(value) {
687
- var matches = _toConsumableArray(value.matchAll(/"([^"]+)"/g));
688
- return matches.map(function (m) {
689
- return m[1];
690
- });
691
- };
692
-
693
- /**
694
- * Parse multipart body
695
- */
696
- var parseMultipartBody = function parseMultipartBody(body, boundary) {
697
- var result = {};
698
-
699
- // Split by boundary lines
700
- var parts = body.split("--".concat(boundary));
701
- for (var i = 0; i < parts.length; i++) {
702
- var part = parts[i];
703
-
704
- // Skip empty parts and the terminating part
705
- if (!part || part === "--" || part === "--\r\n" || part.trim() === "") continue;
706
-
707
- // Remove leading \r\n if present
708
- var content = part;
709
- if (content.startsWith("\r\n")) {
710
- content = content.substring(2);
711
- }
712
-
713
- // Remove trailing \r\n or -- if present
714
- if (content.endsWith("\r\n")) {
715
- content = content.substring(0, content.length - 2);
716
- }
717
- if (!content) continue;
718
-
719
- // Parse all lines
720
- var lines = content.split("\r\n");
721
- var partData = {};
722
- var partName = null;
723
- var _iterator5 = _createForOfIteratorHelper(lines),
724
- _step5;
725
- try {
726
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
727
- var line = _step5.value;
728
- if (!line) continue;
729
- var colonIndex = line.indexOf(": ");
730
- if (colonIndex > -1) {
731
- var name = line.substring(0, colonIndex);
732
- var value = line.substring(colonIndex + 2);
733
-
734
- // Check if this is content-disposition to extract part name
735
- if (name.toLowerCase() === "content-disposition") {
736
- var nameMatch = value.match(/name="([^"]+)"/);
737
- if (nameMatch) {
738
- partName = nameMatch[1];
739
- }
740
- } else {
741
- // Store all other headers/fields
742
- partData[name] = value;
743
- }
744
- }
745
- }
746
-
747
- // Store the part data under its name
748
- } catch (err) {
749
- _iterator5.e(err);
750
- } finally {
751
- _iterator5.f();
752
- }
753
- if (partName && Object.keys(partData).length > 0) {
754
- result[partName] = partData;
755
- }
756
- }
757
- return result;
758
- };
759
-
760
- /**
761
- * Unflatten paths with '/'
762
- */
763
- var unflattenPaths = function unflattenPaths(obj) {
764
- var typeMap = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
765
- var result = {};
766
-
767
- // Check if there are any paths to unflatten
768
- var hasPathsToUnflatten = Object.keys(obj).some(function (key) {
769
- return key.includes("/");
770
- });
771
-
772
- // If no paths to unflatten, return the object as-is
773
- if (!hasPathsToUnflatten) {
774
- return obj;
775
- }
776
-
777
- // First pass: collect all keys and sort them to process parents before children
778
- var sortedKeys = Object.keys(obj).sort();
779
- var _iterator6 = _createForOfIteratorHelper(sortedKeys),
780
- _step6;
781
- try {
782
- for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
783
- var key = _step6.value;
784
- var value = obj[key];
785
- if (key.includes("/")) {
786
- var parts = key.split("/");
787
- var current = result;
788
- var i = 0;
789
- while (i < parts.length - 1) {
790
- var part = parts[i];
791
-
792
- // Check if we have consecutive empty parts (multiple slashes)
793
- if (part === "" && i + 1 < parts.length && parts[i + 1] === "") {
794
- // Skip empty parts until we find a non-empty one or reach the end
795
- var j = i;
796
- while (j < parts.length && parts[j] === "") {
797
- j++;
798
- }
799
- // Use "/" as the key for multiple slashes
800
- part = "/";
801
- i = j - 1; // Will be incremented at the end of loop
802
- } else if (part === "") {
803
- // Single empty part at the beginning or middle, skip it
804
- i++;
805
- continue;
806
- }
807
- if (!current[part]) {
808
- current[part] = {};
809
- }
810
- current = current[part];
811
- i++;
812
- }
813
-
814
- // Handle the final part
815
- var finalPart = parts[parts.length - 1];
816
- current[finalPart] = value;
817
- } else {
818
- result[key] = value;
819
- }
820
- }
821
-
822
- // Second pass: convert objects with numeric keys to arrays only if they have type="list"
823
- } catch (err) {
824
- _iterator6.e(err);
825
- } finally {
826
- _iterator6.f();
827
- }
828
- var _convertToArraysRecursive = function convertToArraysRecursive(obj) {
829
- var parentKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
830
- if (Array.isArray(obj)) {
831
- return obj.map(function (item, index) {
832
- return _convertToArraysRecursive(item, "".concat(parentKey, "/").concat(index + 1));
833
- });
834
- } else if (obj && _typeof(obj) === "object") {
835
- // Check if this object has type="list" in typeMap
836
- var hasListType = typeMap[parentKey] === "list";
837
-
838
- // Only convert to array if it has numeric keys AND type="list"
839
- if (hasListType) {
840
- var converted = maybeConvertToArray(obj);
841
- if (Array.isArray(converted)) {
842
- return converted.map(function (item, index) {
843
- return _convertToArraysRecursive(item, "".concat(parentKey, "/").concat(index + 1));
844
- });
845
- }
846
- }
847
-
848
- // Otherwise, keep as object and recurse
849
- var _result = {};
850
- for (var _i10 = 0, _Object$entries10 = Object.entries(obj); _i10 < _Object$entries10.length; _i10++) {
851
- var _Object$entries10$_i = _slicedToArray(_Object$entries10[_i10], 2),
852
- key = _Object$entries10$_i[0],
853
- value = _Object$entries10$_i[1];
854
- var childKey = parentKey ? "".concat(parentKey, "/").concat(key) : key;
855
- _result[key] = _convertToArraysRecursive(value, childKey);
856
- }
857
- return _result;
858
- }
859
- return obj;
860
- };
861
- return _convertToArraysRecursive(result);
862
- };
863
-
864
- /**
865
- * Helper to check if a key pattern suggests an array structure
866
- */
867
- var isArrayKey = function isArrayKey(obj, currentKey, partIndex) {
868
- var parts = currentKey.split("/");
869
- var prefix = parts.slice(0, partIndex + 1).join("/");
870
-
871
- // Check if there are other keys with the same prefix but numeric suffixes
872
- for (var _i11 = 0, _Object$keys = Object.keys(obj); _i11 < _Object$keys.length; _i11++) {
873
- var key = _Object$keys[_i11];
874
- if (key.startsWith(prefix + "/") && key !== currentKey) {
875
- var otherParts = key.split("/");
876
- if (otherParts.length > partIndex + 1 && /^\d+$/.test(otherParts[partIndex + 1])) {
877
- return true;
878
- }
879
- }
880
- }
881
- return false;
882
- };
883
-
884
- /**
885
- * Check if a string contains binary data (non-printable characters)
886
- * @param {string} str - The string to check
887
- * @returns {boolean} True if binary data detected
888
- */
889
- var isBinaryString = function isBinaryString(str) {
890
- if (!str || typeof str !== "string") return false;
891
-
892
- // Check for non-printable characters (excluding common whitespace)
893
- for (var i = 0; i < str.length; i++) {
894
- var code = str.charCodeAt(i);
895
- // Allow tab (9), newline (10), carriage return (13), and printable ASCII (32-126)
896
- if (code < 9 || code > 13 && code < 32 || code > 126) {
897
- return true;
898
- }
899
- }
900
- return false;
901
- };
902
-
903
- /**
904
- * Convert binary string to Buffer
905
- * @param {string} str - Binary string to convert
906
- * @returns {Buffer} Buffer representation of the string
907
- */
908
- var stringToBuffer = function stringToBuffer(str) {
909
- var buffer = Buffer.alloc(str.length);
910
- for (var i = 0; i < str.length; i++) {
911
- buffer[i] = str.charCodeAt(i);
912
- }
913
- return buffer;
914
- };
915
- var from = exports.from = function from(http) {
916
- var input = http.headers["signature-input"] || http.headers["Signature-Input"];
917
- if (!input) {
918
- return null;
919
- }
920
-
921
- // Decode signature inputs
922
- var inputs = (0, _hbsig.decodeSigInput)(input);
923
- // Process the first signature (following the original logic)
924
- for (var k in inputs) {
925
- var _sigData$params$tag, _sigData$params;
926
- var sigData = inputs[k];
927
- // Extract only the signed components
928
- var extractedComponents = extract(http, sigData.components);
929
- var ret = {
930
- hashpath: (_sigData$params$tag = sigData === null || sigData === void 0 || (_sigData$params = sigData.params) === null || _sigData$params === void 0 ? void 0 : _sigData$params.tag) !== null && _sigData$params$tag !== void 0 ? _sigData$params$tag : null
931
- };
932
- try {
933
- ret.signer = (0, _hbsig.toAddr)(sigData.params.keyid);
934
- } catch (e) {}
935
-
936
- // Check if @path was in the signed components
937
- var hasPathComponent = sigData.components.some(function (c) {
938
- return c.replace(/"/g, "") === "@path";
939
- });
940
-
941
- // If @path is signed, add the path header to extracted components
942
- if (hasPathComponent) {
943
- extractedComponents["path"] = http.headers.path;
944
- }
945
-
946
- // Check if ao-result header is present
947
- var aoResult = http.headers["ao-result"] || http.headers["Ao-Result"];
948
-
949
- // Handle ao-result pointing to body
950
- if (aoResult === "body") {
951
- // Handle empty body case
952
- if (!extractedComponents.body) {
953
- return _objectSpread({
954
- out: ""
955
- }, ret); // Return empty string for empty body
956
- }
957
- // Check if body is binary data
958
- if (isBinaryString(extractedComponents.body)) {
959
- return _objectSpread({
960
- out: stringToBuffer(extractedComponents.body)
961
- }, ret);
962
- }
963
- // Return body as-is if it's not binary
964
- return _objectSpread({
965
- out: extractedComponents.body
966
- }, ret);
967
- }
968
-
969
- // Convert the extracted components to JSON format
970
- var result = _toJSON(extractedComponents);
971
-
972
- // Handle ao-result if present and pointing to other fields
973
- if (aoResult && aoResult !== "body") {
974
- // Return the value of the key specified by ao-result
975
- // If the key doesn't exist, return undefined (or could return null/empty string)
976
- return _objectSpread({
977
- out: result[aoResult] !== undefined ? result[aoResult] : ""
978
- }, ret);
979
- }
980
- return _objectSpread({
981
- out: result
982
- }, ret);
983
- }
984
- return {
985
- out: null,
986
- hashpath: null
987
- };
988
- };
989
-
990
- /**
991
- * Extract all keys and signature information from HTTP signature message
992
- * @param {Object} http - HTTP message object with headers and body
993
- * @returns {Object} Object containing all extracted signature data
994
- */
995
- var extractKeys = exports.extractKeys = function extractKeys(http) {
996
- var result = {
997
- signatures: {},
998
- keys: {},
999
- boundary: null,
1000
- requiresBody: false,
1001
- body: http.body ? toBuffer(http.body) : null,
1002
- bodyText: typeof http.body === "string" ? http.body : null
1003
- };
1004
-
1005
- // Get multipart boundary if present
1006
- result.boundary = getBoundary(http);
1007
-
1008
- // Get signature header
1009
- var signatureHeader = http.headers.signature || http.headers.Signature;
1010
- if (!signatureHeader) {
1011
- return result;
1012
- }
1013
-
1014
- // Get signature-input header
1015
- var signatureInput = http.headers["signature-input"] || http.headers["Signature-Input"];
1016
- if (!signatureInput) {
1017
- return result;
1018
- }
1019
-
1020
- // Decode all signature inputs
1021
- var inputs = (0, _hbsig.decodeSigInput)(signatureInput);
1022
-
1023
- // Parse signature header to extract actual signatures
1024
- // Format: sig1=:base64signature:, sig2=:base64signature:
1025
- var signatures = {};
1026
- var sigPattern = /([a-zA-Z0-9-]+)=:([^:]+):/g;
1027
- var match;
1028
- while ((match = sigPattern.exec(signatureHeader)) !== null) {
1029
- signatures[match[1]] = match[2];
1030
- }
1031
-
1032
- // Process each signature
1033
- for (var _i12 = 0, _Object$entries11 = Object.entries(inputs); _i12 < _Object$entries11.length; _i12++) {
1034
- var _Object$entries11$_i = _slicedToArray(_Object$entries11[_i12], 2),
1035
- sigName = _Object$entries11$_i[0],
1036
- sigData = _Object$entries11$_i[1];
1037
- var extractedValues = extract(http, sigData.components);
1038
-
1039
- // Check if body is required
1040
- if (extractedValues.__bodyRequired__) {
1041
- result.requiresBody = true;
1042
- }
1043
- var signatureInfo = {
1044
- name: sigName,
1045
- signature: signatures[sigName] || null,
1046
- components: sigData.components,
1047
- params: sigData.params,
1048
- extractedValues: extractedValues,
1049
- hasContentDigest: sigData.components.some(function (c) {
1050
- return c.replace(/"/g, "").toLowerCase() === "content-digest";
1051
- })
1052
- };
1053
-
1054
- // If has content-digest, verify it
1055
- if (signatureInfo.hasContentDigest && result.body) {
1056
- var contentDigest = http.headers["content-digest"] || http.headers["Content-Digest"];
1057
- if (contentDigest) {
1058
- signatureInfo.contentDigestVerification = verifyContentDigest(contentDigest, result.body);
1059
- }
1060
- }
1061
-
1062
- // Extract key information from params
1063
- if (sigData.params.keyid) {
1064
- try {
1065
- var keyBuffer = _base64url["default"].toBuffer(sigData.params.keyid);
1066
- result.keys[sigName] = {
1067
- keyid: sigData.params.keyid,
1068
- keyBuffer: keyBuffer,
1069
- algorithm: sigData.params.alg || "unknown"
1070
- };
1071
- } catch (e) {
1072
- // If keyid is not base64url encoded, store as-is
1073
- result.keys[sigName] = {
1074
- keyid: sigData.params.keyid,
1075
- algorithm: sigData.params.alg || "unknown"
1076
- };
1077
- }
1078
- }
1079
- result.signatures[sigName] = signatureInfo;
1080
- }
1081
- return result;
1082
- };
1083
-
1084
- /**
1085
- * Verify if a message has valid HTTP signature structure
1086
- * @param {Object} http - HTTP message object
1087
- * @returns {boolean} True if message has valid signature structure
1088
- */
1089
- var hasValidSignature = exports.hasValidSignature = function hasValidSignature(http) {
1090
- var hasSignature = (http.headers.signature || http.headers.Signature) !== undefined;
1091
- var hasSignatureInput = (http.headers["signature-input"] || http.headers["Signature-Input"]) !== undefined;
1092
- return hasSignature && hasSignatureInput;
1093
- };
1094
-
1095
- /**
1096
- * Verify content-digest header against body
1097
- * @param {string} contentDigest - Content-Digest header value
1098
- * @param {string|Buffer} body - Request/response body
1099
- * @returns {Object} Verification result with digest info
1100
- */
1101
- var verifyContentDigest = exports.verifyContentDigest = function verifyContentDigest(contentDigest, body) {
1102
- // Parse content-digest header format: algorithm=:base64digest:
1103
- var match = contentDigest.match(/([^=]+)=:([^:]+):/);
1104
- if (!match) {
1105
- return {
1106
- valid: false,
1107
- error: "Invalid content-digest format"
1108
- };
1109
- }
1110
- var _match3 = _slicedToArray(match, 3),
1111
- algorithm = _match3[1],
1112
- expectedDigest = _match3[2];
1113
- try {
1114
- // Convert body to Buffer if needed
1115
- var bodyBuffer = typeof body === "string" ? Buffer.from(body, "utf-8") : body;
1116
-
1117
- // Calculate digest based on algorithm
1118
- var actualDigest;
1119
- var crypto = require("crypto");
1120
- if (algorithm === "sha-256") {
1121
- var hash = crypto.createHash("sha256");
1122
- hash.update(bodyBuffer);
1123
- actualDigest = hash.digest("base64");
1124
- } else if (algorithm === "sha-512") {
1125
- var _hash = crypto.createHash("sha512");
1126
- _hash.update(bodyBuffer);
1127
- actualDigest = _hash.digest("base64");
1128
- } else {
1129
- return {
1130
- valid: false,
1131
- error: "Unsupported algorithm: ".concat(algorithm)
1132
- };
1133
- }
1134
- return {
1135
- valid: actualDigest === expectedDigest,
1136
- algorithm: algorithm,
1137
- expectedDigest: expectedDigest,
1138
- actualDigest: actualDigest,
1139
- matches: actualDigest === expectedDigest
1140
- };
1141
- } catch (error) {
1142
- return {
1143
- valid: false,
1144
- error: error.message
1145
- };
1146
- }
1147
- };
1148
-
1149
- /**
1150
- * Get all signature names from a message
1151
- * @param {Object} http - HTTP message object
1152
- * @returns {Array} Array of signature names
1153
- */
1154
- var getSignatureNames = exports.getSignatureNames = function getSignatureNames(http) {
1155
- var signatureInput = http.headers["signature-input"] || http.headers["Signature-Input"];
1156
- if (!signatureInput) return [];
1157
- var inputs = (0, _hbsig.decodeSigInput)(signatureInput);
1158
- return Object.keys(inputs);
1159
- };