wao 0.27.2 → 0.27.3
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/cjs/encode.js +445 -64
- package/esm/encode.js +364 -26
- package/package.json +1 -1
package/cjs/encode.js
CHANGED
|
@@ -356,11 +356,8 @@ function collectBodyKeys(obj) {
|
|
|
356
356
|
nestedPaths.push(fullPath);
|
|
357
357
|
}
|
|
358
358
|
}
|
|
359
|
-
} else if (isBytes(value)) {
|
|
360
|
-
|
|
361
|
-
if (buffer.length > 0) {
|
|
362
|
-
hasSimpleFields = true;
|
|
363
|
-
}
|
|
359
|
+
} else if (isBytes(value) && value.length > 0) {
|
|
360
|
+
hasSimpleFields = true;
|
|
364
361
|
} else if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null || value === undefined || _typeof(value) === "symbol") {
|
|
365
362
|
hasSimpleFields = true;
|
|
366
363
|
}
|
|
@@ -590,15 +587,24 @@ function collectBodyKeys(obj) {
|
|
|
590
587
|
}
|
|
591
588
|
}
|
|
592
589
|
} else if (isPojo(value)) {
|
|
593
|
-
console.log("[main loop]
|
|
594
|
-
//
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
590
|
+
console.log("[main loop] Traversing object at key: \"".concat(key, "\""));
|
|
591
|
+
// Check if this object contains arrays with only empty elements
|
|
592
|
+
var hasArraysWithOnlyEmptyElements = false;
|
|
593
|
+
for (var _i7 = 0, _Object$entries6 = Object.entries(value); _i7 < _Object$entries6.length; _i7++) {
|
|
594
|
+
var _Object$entries6$_i = _slicedToArray(_Object$entries6[_i7], 2),
|
|
595
|
+
k = _Object$entries6$_i[0],
|
|
596
|
+
v = _Object$entries6$_i[1];
|
|
597
|
+
if (Array.isArray(v) && v.length > 0 && v.every(function (item) {
|
|
598
|
+
return Array.isArray(item) && item.length === 0 || isPojo(item) && Object.keys(item).length === 0 || typeof item === "string" && item === "";
|
|
599
|
+
})) {
|
|
600
|
+
hasArraysWithOnlyEmptyElements = true;
|
|
601
|
+
keys.push("".concat(key, "/").concat(k));
|
|
602
|
+
}
|
|
601
603
|
}
|
|
604
|
+
traverse(value, key);
|
|
605
|
+
} else if (isBytes(value) && value.length > 0) {
|
|
606
|
+
console.log("[main loop] Adding key for non-empty bytes: \"".concat(key, "\""));
|
|
607
|
+
keys.push(key);
|
|
602
608
|
} else if (typeof value === "string" && value.includes("\n")) {
|
|
603
609
|
console.log("[main loop] Adding key for string with newline: \"".concat(key, "\""));
|
|
604
610
|
keys.push(key);
|
|
@@ -667,9 +673,9 @@ function _encode() {
|
|
|
667
673
|
var obj,
|
|
668
674
|
_processValue,
|
|
669
675
|
processedObj,
|
|
670
|
-
|
|
671
|
-
_Object$
|
|
672
|
-
_Object$
|
|
676
|
+
_i9,
|
|
677
|
+
_Object$entries8,
|
|
678
|
+
_Object$entries8$_i,
|
|
673
679
|
k,
|
|
674
680
|
v,
|
|
675
681
|
objKeys,
|
|
@@ -701,15 +707,15 @@ function _encode() {
|
|
|
701
707
|
_encoded,
|
|
702
708
|
_contentDigest3,
|
|
703
709
|
_base3,
|
|
704
|
-
bodyKeys,
|
|
705
710
|
headers,
|
|
706
711
|
headerTypes,
|
|
712
|
+
bodyKeys,
|
|
707
713
|
_loop3,
|
|
708
|
-
_i9,
|
|
709
|
-
_Object$entries8,
|
|
710
|
-
_loop4,
|
|
711
714
|
_i10,
|
|
712
715
|
_Object$entries9,
|
|
716
|
+
_loop4,
|
|
717
|
+
_i11,
|
|
718
|
+
_Object$entries10,
|
|
713
719
|
allBodyKeysAreEmptyBinaries,
|
|
714
720
|
singleKey,
|
|
715
721
|
pathParts,
|
|
@@ -755,10 +761,10 @@ function _encode() {
|
|
|
755
761
|
return value.map(_processValue);
|
|
756
762
|
} else if (isPojo(value)) {
|
|
757
763
|
var result = {};
|
|
758
|
-
for (var
|
|
759
|
-
var _Object$
|
|
760
|
-
k = _Object$
|
|
761
|
-
v = _Object$
|
|
764
|
+
for (var _i8 = 0, _Object$entries7 = Object.entries(value); _i8 < _Object$entries7.length; _i8++) {
|
|
765
|
+
var _Object$entries7$_i = _slicedToArray(_Object$entries7[_i8], 2),
|
|
766
|
+
k = _Object$entries7$_i[0],
|
|
767
|
+
v = _Object$entries7$_i[1];
|
|
762
768
|
result[k] = _processValue(v);
|
|
763
769
|
}
|
|
764
770
|
return result;
|
|
@@ -766,8 +772,8 @@ function _encode() {
|
|
|
766
772
|
return value;
|
|
767
773
|
};
|
|
768
774
|
processedObj = {};
|
|
769
|
-
for (
|
|
770
|
-
_Object$
|
|
775
|
+
for (_i9 = 0, _Object$entries8 = Object.entries(obj); _i9 < _Object$entries8.length; _i9++) {
|
|
776
|
+
_Object$entries8$_i = _slicedToArray(_Object$entries8[_i9], 2), k = _Object$entries8$_i[0], v = _Object$entries8$_i[1];
|
|
771
777
|
processedObj[k] = _processValue(v);
|
|
772
778
|
}
|
|
773
779
|
if (!(Object.keys(obj).length === 0)) {
|
|
@@ -907,15 +913,15 @@ function _encode() {
|
|
|
907
913
|
body: _fieldValue
|
|
908
914
|
});
|
|
909
915
|
case 71:
|
|
910
|
-
bodyKeys = collectBodyKeys(obj);
|
|
911
916
|
headers = {};
|
|
912
917
|
headerTypes = [];
|
|
918
|
+
bodyKeys = collectBodyKeys(obj);
|
|
913
919
|
_loop3 = /*#__PURE__*/_regeneratorRuntime().mark(function _loop3() {
|
|
914
|
-
var _Object$
|
|
920
|
+
var _Object$entries9$_i, key, value, needsBody, hasNonAsciiItems, encodedItems;
|
|
915
921
|
return _regeneratorRuntime().wrap(function _loop3$(_context3) {
|
|
916
922
|
while (1) switch (_context3.prev = _context3.next) {
|
|
917
923
|
case 0:
|
|
918
|
-
_Object$
|
|
924
|
+
_Object$entries9$_i = _slicedToArray(_Object$entries9[_i10], 2), key = _Object$entries9$_i[0], value = _Object$entries9$_i[1];
|
|
919
925
|
needsBody = bodyKeys.includes(key) || bodyKeys.some(function (k) {
|
|
920
926
|
return k.startsWith("".concat(key, "/"));
|
|
921
927
|
});
|
|
@@ -1034,9 +1040,9 @@ function _encode() {
|
|
|
1034
1040
|
}
|
|
1035
1041
|
}, _loop3);
|
|
1036
1042
|
});
|
|
1037
|
-
|
|
1043
|
+
_i10 = 0, _Object$entries9 = Object.entries(obj);
|
|
1038
1044
|
case 76:
|
|
1039
|
-
if (!(
|
|
1045
|
+
if (!(_i10 < _Object$entries9.length)) {
|
|
1040
1046
|
_context6.next = 83;
|
|
1041
1047
|
break;
|
|
1042
1048
|
}
|
|
@@ -1048,16 +1054,16 @@ function _encode() {
|
|
|
1048
1054
|
}
|
|
1049
1055
|
return _context6.abrupt("continue", 80);
|
|
1050
1056
|
case 80:
|
|
1051
|
-
|
|
1057
|
+
_i10++;
|
|
1052
1058
|
_context6.next = 76;
|
|
1053
1059
|
break;
|
|
1054
1060
|
case 83:
|
|
1055
1061
|
_loop4 = /*#__PURE__*/_regeneratorRuntime().mark(function _loop4() {
|
|
1056
|
-
var _Object$
|
|
1062
|
+
var _Object$entries10$_i, key, value;
|
|
1057
1063
|
return _regeneratorRuntime().wrap(function _loop4$(_context4) {
|
|
1058
1064
|
while (1) switch (_context4.prev = _context4.next) {
|
|
1059
1065
|
case 0:
|
|
1060
|
-
_Object$
|
|
1066
|
+
_Object$entries10$_i = _slicedToArray(_Object$entries10[_i11], 2), key = _Object$entries10$_i[0], value = _Object$entries10$_i[1];
|
|
1061
1067
|
if (Array.isArray(value)) {
|
|
1062
1068
|
if (bodyKeys.includes(key) || bodyKeys.some(function (k) {
|
|
1063
1069
|
return k.startsWith("".concat(key, "/"));
|
|
@@ -1075,15 +1081,15 @@ function _encode() {
|
|
|
1075
1081
|
}
|
|
1076
1082
|
}, _loop4);
|
|
1077
1083
|
});
|
|
1078
|
-
|
|
1084
|
+
_i11 = 0, _Object$entries10 = Object.entries(obj);
|
|
1079
1085
|
case 85:
|
|
1080
|
-
if (!(
|
|
1086
|
+
if (!(_i11 < _Object$entries10.length)) {
|
|
1081
1087
|
_context6.next = 90;
|
|
1082
1088
|
break;
|
|
1083
1089
|
}
|
|
1084
1090
|
return _context6.delegateYield(_loop4(), "t1", 87);
|
|
1085
1091
|
case 87:
|
|
1086
|
-
|
|
1092
|
+
_i11++;
|
|
1087
1093
|
_context6.next = 85;
|
|
1088
1094
|
break;
|
|
1089
1095
|
case 90:
|
|
@@ -1231,7 +1237,7 @@ function _encode() {
|
|
|
1231
1237
|
_iterator5 = _createForOfIteratorHelper(sortedBodyKeys);
|
|
1232
1238
|
_context6.prev = 123;
|
|
1233
1239
|
_loop5 = /*#__PURE__*/_regeneratorRuntime().mark(function _loop5() {
|
|
1234
|
-
var bodyKey, lines, pathParts, value, parent,
|
|
1240
|
+
var bodyKey, lines, pathParts, value, parent, _i12, _part, hasOnlyEmptyElements, hasOnlyNonEmptyObjects, hasOnlyEmptyObjects, hasObjects, hasArrays, nonObjectItems, _fieldLines, _partTypes, _isInline, orderedLines, _orderedLines, isLastBodyPart, hasOnlyTypes, indicesWithOwnParts, hasNestedObjectParts, fieldLines, partTypes, hasEmptyStrings, hasEmptyObjects, hasObjectsWithOnlyEmptyValues, isMixedArray, _isInline2, _orderedLines2, _iterator6, _step6, line, _orderedLines3, _iterator7, _step7, _line, parentPath, parentValue, _iterator8, _step8, _part2, _hasEmptyStrings, _hasEmptyObjects, _hasObjects, _isInline3, objectTypes, _fieldLines2, binaryFields, hasOnlyEmptyCollections, hasArraysWithOnlyEmptyElements, arrayTypes, _i13, _Object$entries11, _Object$entries11$_i, _k, _v, _i14, _Object$entries12, _Object$entries12$_i, _k2, _v2, childPath, hasOnlyEmpty, desc, _buffer3, _childPath, _hasObjects2, encodedItems, allTypes, shouldSkipObject, onlyEmptyCollections, _orderedLines4, _iterator9, _step9, _line2, binaryFieldsForInline, parts, _iterator10, _step10, _step10$value, key, _buffer4, fullBody, _isLastBodyPart, _hasOnlyTypes, _orderedLines5, hasBinaryFields, _iterator11, _step11, _line3, _parts, headerText, _i15, _binaryFields$_i, _key, _buffer5, _fullBody, isInline, _buffer6, _headerText, content;
|
|
1235
1241
|
return _regeneratorRuntime().wrap(function _loop5$(_context5) {
|
|
1236
1242
|
while (1) switch (_context5.prev = _context5.next) {
|
|
1237
1243
|
case 0:
|
|
@@ -1241,9 +1247,9 @@ function _encode() {
|
|
|
1241
1247
|
pathParts = bodyKey.split("/");
|
|
1242
1248
|
value = obj;
|
|
1243
1249
|
parent = null;
|
|
1244
|
-
for (
|
|
1250
|
+
for (_i12 = 0; _i12 < pathParts.length; _i12++) {
|
|
1245
1251
|
parent = value;
|
|
1246
|
-
_part = pathParts[
|
|
1252
|
+
_part = pathParts[_i12];
|
|
1247
1253
|
if (/^\d+$/.test(_part)) {
|
|
1248
1254
|
value = value[parseInt(_part) - 1];
|
|
1249
1255
|
} else {
|
|
@@ -1264,19 +1270,8 @@ function _encode() {
|
|
|
1264
1270
|
bodyParts.push(new Blob([lines.join("\r\n")]));
|
|
1265
1271
|
return _context5.abrupt("return", 0);
|
|
1266
1272
|
case 15:
|
|
1267
|
-
if (!isBytes(value)) {
|
|
1268
|
-
_context5.next = 22;
|
|
1269
|
-
break;
|
|
1270
|
-
}
|
|
1271
|
-
console.log("[Body part] Creating part for binary at ".concat(bodyKey));
|
|
1272
|
-
lines.push("content-disposition: form-data;name=\"".concat(bodyKey, "\""));
|
|
1273
|
-
_buffer = toBuffer(value);
|
|
1274
|
-
headerText = lines.join("\r\n") + "\r\n\r\n";
|
|
1275
|
-
bodyParts.push(new Blob([headerText, _buffer]));
|
|
1276
|
-
return _context5.abrupt("return", 0);
|
|
1277
|
-
case 22:
|
|
1278
1273
|
if (!Array.isArray(value)) {
|
|
1279
|
-
_context5.next =
|
|
1274
|
+
_context5.next = 45;
|
|
1280
1275
|
break;
|
|
1281
1276
|
}
|
|
1282
1277
|
hasOnlyEmptyElements = value.length > 0 && value.every(function (item) {
|
|
@@ -1304,13 +1299,13 @@ function _encode() {
|
|
|
1304
1299
|
return !isPojo(item);
|
|
1305
1300
|
});
|
|
1306
1301
|
if (!hasOnlyNonEmptyObjects) {
|
|
1307
|
-
_context5.next =
|
|
1302
|
+
_context5.next = 24;
|
|
1308
1303
|
break;
|
|
1309
1304
|
}
|
|
1310
1305
|
return _context5.abrupt("return", 0);
|
|
1311
|
-
case
|
|
1306
|
+
case 24:
|
|
1312
1307
|
if (!hasOnlyEmptyElements) {
|
|
1313
|
-
_context5.next =
|
|
1308
|
+
_context5.next = 31;
|
|
1314
1309
|
break;
|
|
1315
1310
|
}
|
|
1316
1311
|
_fieldLines = [];
|
|
@@ -1361,7 +1356,7 @@ function _encode() {
|
|
|
1361
1356
|
}
|
|
1362
1357
|
}
|
|
1363
1358
|
return _context5.abrupt("return", 0);
|
|
1364
|
-
case
|
|
1359
|
+
case 31:
|
|
1365
1360
|
// Build list of which indices have their own parts
|
|
1366
1361
|
indicesWithOwnParts = new Set();
|
|
1367
1362
|
sortedBodyKeys.forEach(function (key) {
|
|
@@ -1457,8 +1452,8 @@ function _encode() {
|
|
|
1457
1452
|
// Use the full encodeArrayItem for nested arrays
|
|
1458
1453
|
return encodeArrayItem(subItem);
|
|
1459
1454
|
} else if (isBytes(subItem)) {
|
|
1460
|
-
var
|
|
1461
|
-
if (
|
|
1455
|
+
var _buffer = toBuffer(subItem);
|
|
1456
|
+
if (_buffer.length === 0 || _buffer.byteLength === 0) {
|
|
1462
1457
|
return "\"\"";
|
|
1463
1458
|
}
|
|
1464
1459
|
return "\"(ao-type-binary)\"";
|
|
@@ -1496,8 +1491,8 @@ function _encode() {
|
|
|
1496
1491
|
fieldLines.push("".concat(index, ": ").concat(item));
|
|
1497
1492
|
}
|
|
1498
1493
|
} else if (isBytes(item)) {
|
|
1499
|
-
var
|
|
1500
|
-
if (
|
|
1494
|
+
var _buffer2 = toBuffer(item);
|
|
1495
|
+
if (_buffer2.length === 0) {
|
|
1501
1496
|
partTypes.push("".concat(index, "=\"empty-binary\""));
|
|
1502
1497
|
} else {
|
|
1503
1498
|
partTypes.push("".concat(index, "=\"binary\""));
|
|
@@ -1563,15 +1558,401 @@ function _encode() {
|
|
|
1563
1558
|
}
|
|
1564
1559
|
}
|
|
1565
1560
|
return _context5.abrupt("return", 0);
|
|
1566
|
-
case
|
|
1567
|
-
|
|
1561
|
+
case 45:
|
|
1562
|
+
if (!isPojo(value)) {
|
|
1563
|
+
_context5.next = 126;
|
|
1564
|
+
break;
|
|
1565
|
+
}
|
|
1566
|
+
if (!(Object.keys(value).length === 0)) {
|
|
1567
|
+
_context5.next = 60;
|
|
1568
|
+
break;
|
|
1569
|
+
}
|
|
1570
|
+
// Check if this is a parent array context where empty objects should get parts
|
|
1571
|
+
parentPath = pathParts.slice(0, -1).join("/");
|
|
1572
|
+
parentValue = obj;
|
|
1573
|
+
_iterator8 = _createForOfIteratorHelper(pathParts.slice(0, -1));
|
|
1574
|
+
try {
|
|
1575
|
+
for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
|
|
1576
|
+
_part2 = _step8.value;
|
|
1577
|
+
if (/^\d+$/.test(_part2)) {
|
|
1578
|
+
parentValue = parentValue[parseInt(_part2) - 1];
|
|
1579
|
+
} else {
|
|
1580
|
+
parentValue = parentValue[_part2];
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
} catch (err) {
|
|
1584
|
+
_iterator8.e(err);
|
|
1585
|
+
} finally {
|
|
1586
|
+
_iterator8.f();
|
|
1587
|
+
}
|
|
1588
|
+
if (!Array.isArray(parentValue)) {
|
|
1589
|
+
_context5.next = 58;
|
|
1590
|
+
break;
|
|
1591
|
+
}
|
|
1592
|
+
// Check if parent array has mixed content
|
|
1593
|
+
_hasEmptyStrings = parentValue.some(function (item) {
|
|
1594
|
+
return typeof item === "string" && item === "";
|
|
1595
|
+
});
|
|
1596
|
+
_hasEmptyObjects = parentValue.some(function (item) {
|
|
1597
|
+
return isPojo(item) && Object.keys(item).length === 0;
|
|
1598
|
+
});
|
|
1599
|
+
_hasObjects = parentValue.some(function (item) {
|
|
1600
|
+
return isPojo(item);
|
|
1601
|
+
});
|
|
1602
|
+
if (!(_hasObjects && (_hasEmptyStrings || _hasEmptyObjects))) {
|
|
1603
|
+
_context5.next = 58;
|
|
1604
|
+
break;
|
|
1605
|
+
}
|
|
1606
|
+
// Special mixed array case - empty objects don't get parts
|
|
1607
|
+
console.log("[Body part] Skipping empty object in mixed array at ".concat(bodyKey));
|
|
1608
|
+
return _context5.abrupt("return", 0);
|
|
1609
|
+
case 58:
|
|
1610
|
+
// Normal case - empty objects might get parts
|
|
1611
|
+
console.log("[Body part] Empty object at ".concat(bodyKey));
|
|
1612
|
+
// For now, skip empty objects
|
|
1613
|
+
return _context5.abrupt("return", 0);
|
|
1614
|
+
case 60:
|
|
1615
|
+
if (!(hasSpecialDataBody && bodyKey === "data" && Object.keys(value).length === 1 && value.body && isBytes(value.body))) {
|
|
1616
|
+
_context5.next = 62;
|
|
1617
|
+
break;
|
|
1618
|
+
}
|
|
1619
|
+
return _context5.abrupt("return", 0);
|
|
1620
|
+
case 62:
|
|
1621
|
+
// Handle non-empty objects
|
|
1622
|
+
_isInline3 = bodyKey === "body" && headers["inline-body-key"] === "body";
|
|
1623
|
+
if (_isInline3) {
|
|
1624
|
+
lines.push("content-disposition: inline");
|
|
1625
|
+
} else {
|
|
1626
|
+
lines.push("content-disposition: form-data;name=\"".concat(bodyKey, "\""));
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
// Continue with object processing...
|
|
1630
|
+
objectTypes = [];
|
|
1631
|
+
_fieldLines2 = [];
|
|
1632
|
+
binaryFields = []; // First check if this object only contains empty collections
|
|
1633
|
+
hasOnlyEmptyCollections = Object.entries(value).every(function (_ref8) {
|
|
1634
|
+
var _ref9 = _slicedToArray(_ref8, 2),
|
|
1635
|
+
k = _ref9[0],
|
|
1636
|
+
v = _ref9[1];
|
|
1637
|
+
return Array.isArray(v) && v.length === 0 || isPojo(v) && Object.keys(v).length === 0 || isBytes(v) && (v.length === 0 || v.byteLength === 0) || typeof v === "string" && v.length === 0;
|
|
1638
|
+
}); // Also check if it contains arrays with only empty elements
|
|
1639
|
+
hasArraysWithOnlyEmptyElements = Object.entries(value).some(function (_ref10) {
|
|
1640
|
+
var _ref11 = _slicedToArray(_ref10, 2),
|
|
1641
|
+
k = _ref11[0],
|
|
1642
|
+
v = _ref11[1];
|
|
1643
|
+
return Array.isArray(v) && v.length > 0 && v.every(function (item) {
|
|
1644
|
+
return Array.isArray(item) && item.length === 0 || isPojo(item) && Object.keys(item).length === 0 || typeof item === "string" && item === "";
|
|
1645
|
+
});
|
|
1646
|
+
}); // Collect type information for arrays in the object BEFORE processing fields
|
|
1647
|
+
arrayTypes = [];
|
|
1648
|
+
for (_i13 = 0, _Object$entries11 = Object.entries(value); _i13 < _Object$entries11.length; _i13++) {
|
|
1649
|
+
_Object$entries11$_i = _slicedToArray(_Object$entries11[_i13], 2), _k = _Object$entries11$_i[0], _v = _Object$entries11$_i[1];
|
|
1650
|
+
if (Array.isArray(_v)) {
|
|
1651
|
+
arrayTypes.push("".concat(_k.toLowerCase(), "=\"").concat(_v.length === 0 ? "empty-list" : "list", "\""));
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
_i14 = 0, _Object$entries12 = Object.entries(value);
|
|
1655
|
+
case 72:
|
|
1656
|
+
if (!(_i14 < _Object$entries12.length)) {
|
|
1657
|
+
_context5.next = 119;
|
|
1658
|
+
break;
|
|
1659
|
+
}
|
|
1660
|
+
_Object$entries12$_i = _slicedToArray(_Object$entries12[_i14], 2), _k2 = _Object$entries12$_i[0], _v2 = _Object$entries12$_i[1];
|
|
1661
|
+
childPath = "".concat(bodyKey, "/").concat(_k2);
|
|
1662
|
+
if (!sortedBodyKeys.includes(childPath)) {
|
|
1663
|
+
_context5.next = 77;
|
|
1664
|
+
break;
|
|
1665
|
+
}
|
|
1666
|
+
return _context5.abrupt("continue", 116);
|
|
1667
|
+
case 77:
|
|
1668
|
+
if (!(Array.isArray(_v2) && _v2.some(function (item) {
|
|
1669
|
+
return isPojo(item);
|
|
1670
|
+
}))) {
|
|
1671
|
+
_context5.next = 83;
|
|
1672
|
+
break;
|
|
1673
|
+
}
|
|
1674
|
+
if (!sortedBodyKeys.includes(childPath)) {
|
|
1675
|
+
_context5.next = 80;
|
|
1676
|
+
break;
|
|
1677
|
+
}
|
|
1678
|
+
return _context5.abrupt("continue", 116);
|
|
1679
|
+
case 80:
|
|
1680
|
+
// Check if array has only empty elements
|
|
1681
|
+
hasOnlyEmpty = _v2.every(function (item) {
|
|
1682
|
+
return Array.isArray(item) && item.length === 0 || isPojo(item) && Object.keys(item).length === 0 || typeof item === "string" && item === "";
|
|
1683
|
+
});
|
|
1684
|
+
if (!hasOnlyEmpty) {
|
|
1685
|
+
_context5.next = 83;
|
|
1686
|
+
break;
|
|
1687
|
+
}
|
|
1688
|
+
return _context5.abrupt("continue", 116);
|
|
1689
|
+
case 83:
|
|
1690
|
+
if (Array.isArray(_v2)) {
|
|
1691
|
+
// Type info already added above in arrayTypes
|
|
1692
|
+
} else if (_v2 === null || _v2 === undefined || _typeof(_v2) === "symbol" || typeof _v2 === "boolean") {
|
|
1693
|
+
objectTypes.push("".concat(_k2.toLowerCase(), "=\"atom\""));
|
|
1694
|
+
} else if (typeof _v2 === "number") {
|
|
1695
|
+
objectTypes.push("".concat(_k2.toLowerCase(), "=\"").concat(Number.isInteger(_v2) ? "integer" : "float", "\""));
|
|
1696
|
+
} else if (typeof _v2 === "string" && _v2.length === 0) {
|
|
1697
|
+
objectTypes.push("".concat(_k2.toLowerCase(), "=\"empty-binary\""));
|
|
1698
|
+
} else if (isBytes(_v2) && (_v2.length === 0 || _v2.byteLength === 0)) {
|
|
1699
|
+
objectTypes.push("".concat(_k2.toLowerCase(), "=\"empty-binary\""));
|
|
1700
|
+
} else if (isPojo(_v2) && Object.keys(_v2).length === 0) {
|
|
1701
|
+
objectTypes.push("".concat(_k2.toLowerCase(), "=\"empty-message\""));
|
|
1702
|
+
}
|
|
1703
|
+
if (!(typeof _v2 === "string")) {
|
|
1704
|
+
_context5.next = 88;
|
|
1705
|
+
break;
|
|
1706
|
+
}
|
|
1707
|
+
if (_v2.length === 0) {
|
|
1708
|
+
// Empty strings are shown as "empty: " (with trailing space)
|
|
1709
|
+
_fieldLines2.push("".concat(_k2, ": "));
|
|
1710
|
+
} else {
|
|
1711
|
+
_fieldLines2.push("".concat(_k2, ": ").concat(_v2));
|
|
1712
|
+
}
|
|
1713
|
+
_context5.next = 116;
|
|
1714
|
+
break;
|
|
1715
|
+
case 88:
|
|
1716
|
+
if (!(typeof _v2 === "number")) {
|
|
1717
|
+
_context5.next = 92;
|
|
1718
|
+
break;
|
|
1719
|
+
}
|
|
1720
|
+
_fieldLines2.push("".concat(_k2, ": ").concat(_v2));
|
|
1721
|
+
_context5.next = 116;
|
|
1722
|
+
break;
|
|
1723
|
+
case 92:
|
|
1724
|
+
if (!(typeof _v2 === "boolean")) {
|
|
1725
|
+
_context5.next = 96;
|
|
1726
|
+
break;
|
|
1727
|
+
}
|
|
1728
|
+
_fieldLines2.push("".concat(_k2, ": \"").concat(_v2, "\""));
|
|
1729
|
+
_context5.next = 116;
|
|
1730
|
+
break;
|
|
1731
|
+
case 96:
|
|
1732
|
+
if (!(_v2 === null)) {
|
|
1733
|
+
_context5.next = 100;
|
|
1734
|
+
break;
|
|
1735
|
+
}
|
|
1736
|
+
_fieldLines2.push("".concat(_k2, ": \"null\""));
|
|
1737
|
+
_context5.next = 116;
|
|
1738
|
+
break;
|
|
1739
|
+
case 100:
|
|
1740
|
+
if (!(_v2 === undefined)) {
|
|
1741
|
+
_context5.next = 104;
|
|
1742
|
+
break;
|
|
1743
|
+
}
|
|
1744
|
+
_fieldLines2.push("".concat(_k2, ": \"undefined\""));
|
|
1745
|
+
_context5.next = 116;
|
|
1746
|
+
break;
|
|
1747
|
+
case 104:
|
|
1748
|
+
if (!(_typeof(_v2) === "symbol")) {
|
|
1749
|
+
_context5.next = 109;
|
|
1750
|
+
break;
|
|
1751
|
+
}
|
|
1752
|
+
desc = _v2.description || "Symbol.for()";
|
|
1753
|
+
_fieldLines2.push("".concat(_k2, ": \"").concat(desc, "\""));
|
|
1754
|
+
_context5.next = 116;
|
|
1755
|
+
break;
|
|
1756
|
+
case 109:
|
|
1757
|
+
if (!isBytes(_v2)) {
|
|
1758
|
+
_context5.next = 115;
|
|
1759
|
+
break;
|
|
1760
|
+
}
|
|
1761
|
+
_buffer3 = toBuffer(_v2);
|
|
1762
|
+
binaryFields.push({
|
|
1763
|
+
key: _k2,
|
|
1764
|
+
buffer: _buffer3
|
|
1765
|
+
});
|
|
1766
|
+
return _context5.abrupt("continue", 116);
|
|
1767
|
+
case 115:
|
|
1768
|
+
if (Array.isArray(_v2)) {
|
|
1769
|
+
if (_v2.length === 0) {
|
|
1770
|
+
// Don't add field line for empty array
|
|
1771
|
+
} else {
|
|
1772
|
+
// Check if this array will have its own body part
|
|
1773
|
+
_childPath = "".concat(bodyKey, "/").concat(_k2);
|
|
1774
|
+
if (!sortedBodyKeys.includes(_childPath)) {
|
|
1775
|
+
// Check if this array contains objects - if so, don't add field line
|
|
1776
|
+
_hasObjects2 = _v2.some(function (item) {
|
|
1777
|
+
return isPojo(item);
|
|
1778
|
+
});
|
|
1779
|
+
if (!_hasObjects2) {
|
|
1780
|
+
encodedItems = _v2.map(function (item) {
|
|
1781
|
+
return encodeArrayItem(item);
|
|
1782
|
+
}).join(", ");
|
|
1783
|
+
_fieldLines2.push("".concat(_k2, ": ").concat(encodedItems));
|
|
1784
|
+
}
|
|
1785
|
+
}
|
|
1786
|
+
}
|
|
1787
|
+
} else if (isPojo(_v2) && Object.keys(_v2).length === 0) {
|
|
1788
|
+
// Empty object - don't add field line
|
|
1789
|
+
}
|
|
1790
|
+
case 116:
|
|
1791
|
+
_i14++;
|
|
1792
|
+
_context5.next = 72;
|
|
1793
|
+
break;
|
|
1794
|
+
case 119:
|
|
1795
|
+
// Combine arrayTypes with objectTypes
|
|
1796
|
+
allTypes = [].concat(arrayTypes, objectTypes); // Check if this object should be skipped entirely
|
|
1797
|
+
shouldSkipObject = Object.entries(value).every(function (_ref12) {
|
|
1798
|
+
var _ref13 = _slicedToArray(_ref12, 2),
|
|
1799
|
+
k = _ref13[0],
|
|
1800
|
+
v = _ref13[1];
|
|
1801
|
+
var childPath = "".concat(bodyKey, "/").concat(k);
|
|
1802
|
+
if (sortedBodyKeys.includes(childPath)) return true;
|
|
1803
|
+
if (Array.isArray(v) && v.some(function (item) {
|
|
1804
|
+
return isPojo(item);
|
|
1805
|
+
})) {
|
|
1806
|
+
// Check if array has only empty elements
|
|
1807
|
+
var _hasOnlyEmpty = v.every(function (item) {
|
|
1808
|
+
return Array.isArray(item) && item.length === 0 || isPojo(item) && Object.keys(item).length === 0 || typeof item === "string" && item === "";
|
|
1809
|
+
});
|
|
1810
|
+
return _hasOnlyEmpty || sortedBodyKeys.includes(childPath);
|
|
1811
|
+
}
|
|
1812
|
+
return false;
|
|
1813
|
+
});
|
|
1814
|
+
if (!(shouldSkipObject && !hasOnlyEmptyCollections && !hasArraysWithOnlyEmptyElements)) {
|
|
1815
|
+
_context5.next = 123;
|
|
1816
|
+
break;
|
|
1817
|
+
}
|
|
1818
|
+
return _context5.abrupt("return", 0);
|
|
1819
|
+
case 123:
|
|
1820
|
+
onlyEmptyCollections = Object.entries(value).every(function (_ref14) {
|
|
1821
|
+
var _ref15 = _slicedToArray(_ref14, 2),
|
|
1822
|
+
k = _ref15[0],
|
|
1823
|
+
v = _ref15[1];
|
|
1824
|
+
var childPath = "".concat(bodyKey, "/").concat(k);
|
|
1825
|
+
if (sortedBodyKeys.includes(childPath)) return true;
|
|
1826
|
+
if (Array.isArray(v) && v.some(function (item) {
|
|
1827
|
+
return isPojo(item);
|
|
1828
|
+
})) return true;
|
|
1829
|
+
return Array.isArray(v) && v.length === 0 || isPojo(v) && Object.keys(v).length === 0 || isBytes(v) && (v.length === 0 || v.byteLength === 0);
|
|
1830
|
+
});
|
|
1831
|
+
if (_isInline3) {
|
|
1832
|
+
_orderedLines4 = []; // FIXED: For inline body, put field lines FIRST
|
|
1833
|
+
_iterator9 = _createForOfIteratorHelper(_fieldLines2);
|
|
1834
|
+
try {
|
|
1835
|
+
for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
|
|
1836
|
+
_line2 = _step9.value;
|
|
1837
|
+
_orderedLines4.push(_line2);
|
|
1838
|
+
}
|
|
1839
|
+
} catch (err) {
|
|
1840
|
+
_iterator9.e(err);
|
|
1841
|
+
} finally {
|
|
1842
|
+
_iterator9.f();
|
|
1843
|
+
}
|
|
1844
|
+
if (allTypes.length > 0) {
|
|
1845
|
+
_orderedLines4.push("ao-types: ".concat(allTypes.sort().join(", ")));
|
|
1846
|
+
}
|
|
1847
|
+
_orderedLines4.push("content-disposition: inline");
|
|
1848
|
+
binaryFieldsForInline = Object.entries(value).filter(function (_ref16) {
|
|
1849
|
+
var _ref17 = _slicedToArray(_ref16, 2),
|
|
1850
|
+
k = _ref17[0],
|
|
1851
|
+
v = _ref17[1];
|
|
1852
|
+
return isBytes(v) && !sortedBodyKeys.includes("".concat(bodyKey, "/").concat(k));
|
|
1853
|
+
}).map(function (_ref18) {
|
|
1854
|
+
var _ref19 = _slicedToArray(_ref18, 2),
|
|
1855
|
+
k = _ref19[0],
|
|
1856
|
+
v = _ref19[1];
|
|
1857
|
+
return {
|
|
1858
|
+
key: k,
|
|
1859
|
+
buffer: toBuffer(v)
|
|
1860
|
+
};
|
|
1861
|
+
});
|
|
1862
|
+
if (binaryFieldsForInline.length > 0) {
|
|
1863
|
+
parts = [];
|
|
1864
|
+
parts.push(Buffer.from(_orderedLines4.join("\r\n")));
|
|
1865
|
+
_iterator10 = _createForOfIteratorHelper(binaryFieldsForInline);
|
|
1866
|
+
try {
|
|
1867
|
+
for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
|
|
1868
|
+
_step10$value = _step10.value, key = _step10$value.key, _buffer4 = _step10$value.buffer;
|
|
1869
|
+
parts.push(Buffer.from("\r\n".concat(key, ": ")));
|
|
1870
|
+
parts.push(_buffer4);
|
|
1871
|
+
}
|
|
1872
|
+
} catch (err) {
|
|
1873
|
+
_iterator10.e(err);
|
|
1874
|
+
} finally {
|
|
1875
|
+
_iterator10.f();
|
|
1876
|
+
}
|
|
1877
|
+
parts.push(Buffer.from("\r\n"));
|
|
1878
|
+
fullBody = Buffer.concat(parts);
|
|
1879
|
+
bodyParts.push(new Blob([fullBody]));
|
|
1880
|
+
} else {
|
|
1881
|
+
// Check if this is the last body part for special handling
|
|
1882
|
+
_isLastBodyPart = sortedBodyKeys.indexOf(bodyKey) === sortedBodyKeys.length - 1;
|
|
1883
|
+
_hasOnlyTypes = allTypes.length > 0 && _fieldLines2.length === 0;
|
|
1884
|
+
if (_isLastBodyPart && _hasOnlyTypes) {
|
|
1885
|
+
// Don't add empty line for last part with only types
|
|
1886
|
+
bodyParts.push(new Blob([_orderedLines4.join("\r\n")]));
|
|
1887
|
+
} else if (_fieldLines2.length === 0) {
|
|
1888
|
+
bodyParts.push(new Blob([_orderedLines4.join("\r\n")]));
|
|
1889
|
+
} else {
|
|
1890
|
+
bodyParts.push(new Blob([_orderedLines4.join("\r\n") + "\r\n"]));
|
|
1891
|
+
}
|
|
1892
|
+
}
|
|
1893
|
+
} else {
|
|
1894
|
+
// Put ao-types first, then content-disposition, then field lines
|
|
1895
|
+
_orderedLines5 = [];
|
|
1896
|
+
if (allTypes.length > 0) {
|
|
1897
|
+
_orderedLines5.push("ao-types: ".concat(allTypes.sort().join(", ")));
|
|
1898
|
+
}
|
|
1899
|
+
_orderedLines5.push("content-disposition: form-data;name=\"".concat(bodyKey, "\""));
|
|
1900
|
+
|
|
1901
|
+
// Check if we have any binary fields
|
|
1902
|
+
hasBinaryFields = binaryFields && binaryFields.length > 0; // Add blank line before field lines if we have binary fields or no field lines
|
|
1903
|
+
if (hasBinaryFields || _fieldLines2.length === 0) {
|
|
1904
|
+
_orderedLines5.push("");
|
|
1905
|
+
}
|
|
1906
|
+
|
|
1907
|
+
// Add field lines
|
|
1908
|
+
_iterator11 = _createForOfIteratorHelper(_fieldLines2);
|
|
1909
|
+
try {
|
|
1910
|
+
for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
|
|
1911
|
+
_line3 = _step11.value;
|
|
1912
|
+
_orderedLines5.push(_line3);
|
|
1913
|
+
}
|
|
1914
|
+
} catch (err) {
|
|
1915
|
+
_iterator11.e(err);
|
|
1916
|
+
} finally {
|
|
1917
|
+
_iterator11.f();
|
|
1918
|
+
}
|
|
1919
|
+
if (binaryFields && binaryFields.length > 0) {
|
|
1920
|
+
_parts = [];
|
|
1921
|
+
headerText = _orderedLines5.join("\r\n");
|
|
1922
|
+
_parts.push(Buffer.from(headerText));
|
|
1923
|
+
for (_i15 = 0; _i15 < binaryFields.length; _i15++) {
|
|
1924
|
+
_binaryFields$_i = binaryFields[_i15], _key = _binaryFields$_i.key, _buffer5 = _binaryFields$_i.buffer;
|
|
1925
|
+
if (_i15 > 0) {
|
|
1926
|
+
_parts.push(Buffer.from("\r\n"));
|
|
1927
|
+
}
|
|
1928
|
+
_parts.push(Buffer.from("".concat(_key, ": ")));
|
|
1929
|
+
_parts.push(_buffer5);
|
|
1930
|
+
}
|
|
1931
|
+
_parts.push(Buffer.from("\r\n"));
|
|
1932
|
+
_fullBody = Buffer.concat(_parts);
|
|
1933
|
+
bodyParts.push(new Blob([_fullBody]));
|
|
1934
|
+
} else {
|
|
1935
|
+
// Add trailing blank line if we have field lines
|
|
1936
|
+
if (_fieldLines2.length > 0) {
|
|
1937
|
+
bodyParts.push(new Blob([_orderedLines5.join("\r\n") + "\r\n"]));
|
|
1938
|
+
} else {
|
|
1939
|
+
bodyParts.push(new Blob([_orderedLines5.join("\r\n")]));
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
return _context5.abrupt("return", 0);
|
|
1944
|
+
case 126:
|
|
1568
1945
|
isInline = bodyKey === "body" && headers["inline-body-key"] === "body";
|
|
1569
1946
|
if (isInline) {
|
|
1570
1947
|
lines.push("content-disposition: inline");
|
|
1571
1948
|
} else {
|
|
1572
1949
|
lines.push("content-disposition: form-data;name=\"".concat(bodyKey, "\""));
|
|
1573
1950
|
}
|
|
1574
|
-
if (
|
|
1951
|
+
if (isBytes(value)) {
|
|
1952
|
+
_buffer6 = toBuffer(value);
|
|
1953
|
+
_headerText = lines.join("\r\n") + "\r\n\r\n";
|
|
1954
|
+
bodyParts.push(new Blob([_headerText, _buffer6]));
|
|
1955
|
+
} else if (typeof value === "string") {
|
|
1575
1956
|
lines.push("");
|
|
1576
1957
|
lines.push(value);
|
|
1577
1958
|
bodyParts.push(new Blob([lines.join("\r\n")]));
|
|
@@ -1591,7 +1972,7 @@ function _encode() {
|
|
|
1591
1972
|
lines.push(content);
|
|
1592
1973
|
bodyParts.push(new Blob([lines.join("\r\n")]));
|
|
1593
1974
|
}
|
|
1594
|
-
case
|
|
1975
|
+
case 129:
|
|
1595
1976
|
case "end":
|
|
1596
1977
|
return _context5.stop();
|
|
1597
1978
|
}
|
package/esm/encode.js
CHANGED
|
@@ -339,11 +339,8 @@ function collectBodyKeys(obj, prefix = "") {
|
|
|
339
339
|
nestedPaths.push(fullPath)
|
|
340
340
|
}
|
|
341
341
|
}
|
|
342
|
-
} else if (isBytes(value)) {
|
|
343
|
-
|
|
344
|
-
if (buffer.length > 0) {
|
|
345
|
-
hasSimpleFields = true
|
|
346
|
-
}
|
|
342
|
+
} else if (isBytes(value) && value.length > 0) {
|
|
343
|
+
hasSimpleFields = true
|
|
347
344
|
} else if (
|
|
348
345
|
typeof value === "string" ||
|
|
349
346
|
typeof value === "number" ||
|
|
@@ -631,15 +628,28 @@ function collectBodyKeys(obj, prefix = "") {
|
|
|
631
628
|
}
|
|
632
629
|
}
|
|
633
630
|
} else if (isPojo(value)) {
|
|
634
|
-
console.log(`[main loop]
|
|
635
|
-
//
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
631
|
+
console.log(`[main loop] Traversing object at key: "${key}"`)
|
|
632
|
+
// Check if this object contains arrays with only empty elements
|
|
633
|
+
let hasArraysWithOnlyEmptyElements = false
|
|
634
|
+
for (const [k, v] of Object.entries(value)) {
|
|
635
|
+
if (
|
|
636
|
+
Array.isArray(v) &&
|
|
637
|
+
v.length > 0 &&
|
|
638
|
+
v.every(
|
|
639
|
+
item =>
|
|
640
|
+
(Array.isArray(item) && item.length === 0) ||
|
|
641
|
+
(isPojo(item) && Object.keys(item).length === 0) ||
|
|
642
|
+
(typeof item === "string" && item === "")
|
|
643
|
+
)
|
|
644
|
+
) {
|
|
645
|
+
hasArraysWithOnlyEmptyElements = true
|
|
646
|
+
keys.push(`${key}/${k}`)
|
|
647
|
+
}
|
|
642
648
|
}
|
|
649
|
+
traverse(value, key)
|
|
650
|
+
} else if (isBytes(value) && value.length > 0) {
|
|
651
|
+
console.log(`[main loop] Adding key for non-empty bytes: "${key}"`)
|
|
652
|
+
keys.push(key)
|
|
643
653
|
} else if (typeof value === "string" && value.includes("\n")) {
|
|
644
654
|
console.log(`[main loop] Adding key for string with newline: "${key}"`)
|
|
645
655
|
keys.push(key)
|
|
@@ -852,10 +862,11 @@ async function encode(obj = {}) {
|
|
|
852
862
|
}
|
|
853
863
|
}
|
|
854
864
|
|
|
855
|
-
const bodyKeys = collectBodyKeys(obj)
|
|
856
865
|
const headers = {}
|
|
857
866
|
const headerTypes = []
|
|
858
867
|
|
|
868
|
+
const bodyKeys = collectBodyKeys(obj)
|
|
869
|
+
|
|
859
870
|
for (const [key, value] of Object.entries(obj)) {
|
|
860
871
|
const needsBody =
|
|
861
872
|
bodyKeys.includes(key) || bodyKeys.some(k => k.startsWith(`${key}/`))
|
|
@@ -1106,16 +1117,6 @@ async function encode(obj = {}) {
|
|
|
1106
1117
|
continue
|
|
1107
1118
|
}
|
|
1108
1119
|
|
|
1109
|
-
// Handle direct binary values
|
|
1110
|
-
if (isBytes(value)) {
|
|
1111
|
-
console.log(`[Body part] Creating part for binary at ${bodyKey}`)
|
|
1112
|
-
lines.push(`content-disposition: form-data;name="${bodyKey}"`)
|
|
1113
|
-
const buffer = toBuffer(value)
|
|
1114
|
-
const headerText = lines.join("\r\n") + "\r\n\r\n"
|
|
1115
|
-
bodyParts.push(new Blob([headerText, buffer]))
|
|
1116
|
-
continue
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
1120
|
if (Array.isArray(value)) {
|
|
1120
1121
|
const hasOnlyEmptyElements =
|
|
1121
1122
|
value.length > 0 &&
|
|
@@ -1439,7 +1440,340 @@ async function encode(obj = {}) {
|
|
|
1439
1440
|
continue
|
|
1440
1441
|
}
|
|
1441
1442
|
|
|
1442
|
-
|
|
1443
|
+
if (isPojo(value)) {
|
|
1444
|
+
// Handle non-empty objects - skip empty ones
|
|
1445
|
+
if (Object.keys(value).length === 0) {
|
|
1446
|
+
// Check if this is a parent array context where empty objects should get parts
|
|
1447
|
+
const parentPath = pathParts.slice(0, -1).join("/")
|
|
1448
|
+
let parentValue = obj
|
|
1449
|
+
for (const part of pathParts.slice(0, -1)) {
|
|
1450
|
+
if (/^\d+$/.test(part)) {
|
|
1451
|
+
parentValue = parentValue[parseInt(part) - 1]
|
|
1452
|
+
} else {
|
|
1453
|
+
parentValue = parentValue[part]
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
if (Array.isArray(parentValue)) {
|
|
1458
|
+
// Check if parent array has mixed content
|
|
1459
|
+
const hasEmptyStrings = parentValue.some(
|
|
1460
|
+
item => typeof item === "string" && item === ""
|
|
1461
|
+
)
|
|
1462
|
+
const hasEmptyObjects = parentValue.some(
|
|
1463
|
+
item => isPojo(item) && Object.keys(item).length === 0
|
|
1464
|
+
)
|
|
1465
|
+
const hasObjects = parentValue.some(item => isPojo(item))
|
|
1466
|
+
|
|
1467
|
+
if (hasObjects && (hasEmptyStrings || hasEmptyObjects)) {
|
|
1468
|
+
// Special mixed array case - empty objects don't get parts
|
|
1469
|
+
console.log(
|
|
1470
|
+
`[Body part] Skipping empty object in mixed array at ${bodyKey}`
|
|
1471
|
+
)
|
|
1472
|
+
continue
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
// Normal case - empty objects might get parts
|
|
1477
|
+
console.log(`[Body part] Empty object at ${bodyKey}`)
|
|
1478
|
+
// For now, skip empty objects
|
|
1479
|
+
continue
|
|
1480
|
+
}
|
|
1481
|
+
|
|
1482
|
+
// Skip the special case where bodyKey is "data" and has only body:Buffer
|
|
1483
|
+
if (
|
|
1484
|
+
hasSpecialDataBody &&
|
|
1485
|
+
bodyKey === "data" &&
|
|
1486
|
+
Object.keys(value).length === 1 &&
|
|
1487
|
+
value.body &&
|
|
1488
|
+
isBytes(value.body)
|
|
1489
|
+
) {
|
|
1490
|
+
continue
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
// Handle non-empty objects
|
|
1494
|
+
const isInline =
|
|
1495
|
+
bodyKey === "body" && headers["inline-body-key"] === "body"
|
|
1496
|
+
if (isInline) {
|
|
1497
|
+
lines.push(`content-disposition: inline`)
|
|
1498
|
+
} else {
|
|
1499
|
+
lines.push(`content-disposition: form-data;name="${bodyKey}"`)
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
// Continue with object processing...
|
|
1503
|
+
const objectTypes = []
|
|
1504
|
+
const fieldLines = []
|
|
1505
|
+
const binaryFields = []
|
|
1506
|
+
|
|
1507
|
+
// First check if this object only contains empty collections
|
|
1508
|
+
const hasOnlyEmptyCollections = Object.entries(value).every(([k, v]) => {
|
|
1509
|
+
return (
|
|
1510
|
+
(Array.isArray(v) && v.length === 0) ||
|
|
1511
|
+
(isPojo(v) && Object.keys(v).length === 0) ||
|
|
1512
|
+
(isBytes(v) && (v.length === 0 || v.byteLength === 0)) ||
|
|
1513
|
+
(typeof v === "string" && v.length === 0)
|
|
1514
|
+
)
|
|
1515
|
+
})
|
|
1516
|
+
|
|
1517
|
+
// Also check if it contains arrays with only empty elements
|
|
1518
|
+
const hasArraysWithOnlyEmptyElements = Object.entries(value).some(
|
|
1519
|
+
([k, v]) => {
|
|
1520
|
+
return (
|
|
1521
|
+
Array.isArray(v) &&
|
|
1522
|
+
v.length > 0 &&
|
|
1523
|
+
v.every(
|
|
1524
|
+
item =>
|
|
1525
|
+
(Array.isArray(item) && item.length === 0) ||
|
|
1526
|
+
(isPojo(item) && Object.keys(item).length === 0) ||
|
|
1527
|
+
(typeof item === "string" && item === "")
|
|
1528
|
+
)
|
|
1529
|
+
)
|
|
1530
|
+
}
|
|
1531
|
+
)
|
|
1532
|
+
|
|
1533
|
+
// Collect type information for arrays in the object BEFORE processing fields
|
|
1534
|
+
const arrayTypes = []
|
|
1535
|
+
for (const [k, v] of Object.entries(value)) {
|
|
1536
|
+
if (Array.isArray(v)) {
|
|
1537
|
+
arrayTypes.push(
|
|
1538
|
+
`${k.toLowerCase()}="${v.length === 0 ? "empty-list" : "list"}"`
|
|
1539
|
+
)
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
|
|
1543
|
+
for (const [k, v] of Object.entries(value)) {
|
|
1544
|
+
const childPath = `${bodyKey}/${k}`
|
|
1545
|
+
|
|
1546
|
+
if (sortedBodyKeys.includes(childPath)) {
|
|
1547
|
+
continue
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
if (Array.isArray(v) && v.some(item => isPojo(item))) {
|
|
1551
|
+
// Check if this array will have its own body part
|
|
1552
|
+
if (sortedBodyKeys.includes(childPath)) {
|
|
1553
|
+
continue
|
|
1554
|
+
}
|
|
1555
|
+
// Check if array has only empty elements
|
|
1556
|
+
const hasOnlyEmpty = v.every(
|
|
1557
|
+
item =>
|
|
1558
|
+
(Array.isArray(item) && item.length === 0) ||
|
|
1559
|
+
(isPojo(item) && Object.keys(item).length === 0) ||
|
|
1560
|
+
(typeof item === "string" && item === "")
|
|
1561
|
+
)
|
|
1562
|
+
if (hasOnlyEmpty) {
|
|
1563
|
+
continue
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
if (Array.isArray(v)) {
|
|
1568
|
+
// Type info already added above in arrayTypes
|
|
1569
|
+
} else if (
|
|
1570
|
+
v === null ||
|
|
1571
|
+
v === undefined ||
|
|
1572
|
+
typeof v === "symbol" ||
|
|
1573
|
+
typeof v === "boolean"
|
|
1574
|
+
) {
|
|
1575
|
+
objectTypes.push(`${k.toLowerCase()}="atom"`)
|
|
1576
|
+
} else if (typeof v === "number") {
|
|
1577
|
+
objectTypes.push(
|
|
1578
|
+
`${k.toLowerCase()}="${Number.isInteger(v) ? "integer" : "float"}"`
|
|
1579
|
+
)
|
|
1580
|
+
} else if (typeof v === "string" && v.length === 0) {
|
|
1581
|
+
objectTypes.push(`${k.toLowerCase()}="empty-binary"`)
|
|
1582
|
+
} else if (isBytes(v) && (v.length === 0 || v.byteLength === 0)) {
|
|
1583
|
+
objectTypes.push(`${k.toLowerCase()}="empty-binary"`)
|
|
1584
|
+
} else if (isPojo(v) && Object.keys(v).length === 0) {
|
|
1585
|
+
objectTypes.push(`${k.toLowerCase()}="empty-message"`)
|
|
1586
|
+
}
|
|
1587
|
+
|
|
1588
|
+
if (typeof v === "string") {
|
|
1589
|
+
if (v.length === 0) {
|
|
1590
|
+
// Empty strings are shown as "empty: " (with trailing space)
|
|
1591
|
+
fieldLines.push(`${k}: `)
|
|
1592
|
+
} else {
|
|
1593
|
+
fieldLines.push(`${k}: ${v}`)
|
|
1594
|
+
}
|
|
1595
|
+
} else if (typeof v === "number") {
|
|
1596
|
+
fieldLines.push(`${k}: ${v}`)
|
|
1597
|
+
} else if (typeof v === "boolean") {
|
|
1598
|
+
fieldLines.push(`${k}: "${v}"`)
|
|
1599
|
+
} else if (v === null) {
|
|
1600
|
+
fieldLines.push(`${k}: "null"`)
|
|
1601
|
+
} else if (v === undefined) {
|
|
1602
|
+
fieldLines.push(`${k}: "undefined"`)
|
|
1603
|
+
} else if (typeof v === "symbol") {
|
|
1604
|
+
const desc = v.description || "Symbol.for()"
|
|
1605
|
+
fieldLines.push(`${k}: "${desc}"`)
|
|
1606
|
+
} else if (isBytes(v)) {
|
|
1607
|
+
const buffer = toBuffer(v)
|
|
1608
|
+
binaryFields.push({ key: k, buffer })
|
|
1609
|
+
continue
|
|
1610
|
+
} else if (Array.isArray(v)) {
|
|
1611
|
+
if (v.length === 0) {
|
|
1612
|
+
// Don't add field line for empty array
|
|
1613
|
+
} else {
|
|
1614
|
+
// Check if this array will have its own body part
|
|
1615
|
+
const childPath = `${bodyKey}/${k}`
|
|
1616
|
+
if (!sortedBodyKeys.includes(childPath)) {
|
|
1617
|
+
// Check if this array contains objects - if so, don't add field line
|
|
1618
|
+
const hasObjects = v.some(item => isPojo(item))
|
|
1619
|
+
if (!hasObjects) {
|
|
1620
|
+
const encodedItems = v
|
|
1621
|
+
.map(item => encodeArrayItem(item))
|
|
1622
|
+
.join(", ")
|
|
1623
|
+
fieldLines.push(`${k}: ${encodedItems}`)
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
} else if (isPojo(v) && Object.keys(v).length === 0) {
|
|
1628
|
+
// Empty object - don't add field line
|
|
1629
|
+
}
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
// Combine arrayTypes with objectTypes
|
|
1633
|
+
const allTypes = [...arrayTypes, ...objectTypes]
|
|
1634
|
+
|
|
1635
|
+
// Check if this object should be skipped entirely
|
|
1636
|
+
const shouldSkipObject = Object.entries(value).every(([k, v]) => {
|
|
1637
|
+
const childPath = `${bodyKey}/${k}`
|
|
1638
|
+
if (sortedBodyKeys.includes(childPath)) return true
|
|
1639
|
+
if (Array.isArray(v) && v.some(item => isPojo(item))) {
|
|
1640
|
+
// Check if array has only empty elements
|
|
1641
|
+
const hasOnlyEmpty = v.every(
|
|
1642
|
+
item =>
|
|
1643
|
+
(Array.isArray(item) && item.length === 0) ||
|
|
1644
|
+
(isPojo(item) && Object.keys(item).length === 0) ||
|
|
1645
|
+
(typeof item === "string" && item === "")
|
|
1646
|
+
)
|
|
1647
|
+
return hasOnlyEmpty || sortedBodyKeys.includes(childPath)
|
|
1648
|
+
}
|
|
1649
|
+
return false
|
|
1650
|
+
})
|
|
1651
|
+
|
|
1652
|
+
if (
|
|
1653
|
+
shouldSkipObject &&
|
|
1654
|
+
!hasOnlyEmptyCollections &&
|
|
1655
|
+
!hasArraysWithOnlyEmptyElements
|
|
1656
|
+
) {
|
|
1657
|
+
continue
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1660
|
+
const onlyEmptyCollections = Object.entries(value).every(([k, v]) => {
|
|
1661
|
+
const childPath = `${bodyKey}/${k}`
|
|
1662
|
+
if (sortedBodyKeys.includes(childPath)) return true
|
|
1663
|
+
if (Array.isArray(v) && v.some(item => isPojo(item))) return true
|
|
1664
|
+
|
|
1665
|
+
return (
|
|
1666
|
+
(Array.isArray(v) && v.length === 0) ||
|
|
1667
|
+
(isPojo(v) && Object.keys(v).length === 0) ||
|
|
1668
|
+
(isBytes(v) && (v.length === 0 || v.byteLength === 0))
|
|
1669
|
+
)
|
|
1670
|
+
})
|
|
1671
|
+
|
|
1672
|
+
if (isInline) {
|
|
1673
|
+
const orderedLines = []
|
|
1674
|
+
|
|
1675
|
+
// FIXED: For inline body, put field lines FIRST
|
|
1676
|
+
for (const line of fieldLines) {
|
|
1677
|
+
orderedLines.push(line)
|
|
1678
|
+
}
|
|
1679
|
+
|
|
1680
|
+
if (allTypes.length > 0) {
|
|
1681
|
+
orderedLines.push(`ao-types: ${allTypes.sort().join(", ")}`)
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
orderedLines.push("content-disposition: inline")
|
|
1685
|
+
|
|
1686
|
+
const binaryFieldsForInline = Object.entries(value)
|
|
1687
|
+
.filter(
|
|
1688
|
+
([k, v]) =>
|
|
1689
|
+
isBytes(v) && !sortedBodyKeys.includes(`${bodyKey}/${k}`)
|
|
1690
|
+
)
|
|
1691
|
+
.map(([k, v]) => ({
|
|
1692
|
+
key: k,
|
|
1693
|
+
buffer: toBuffer(v),
|
|
1694
|
+
}))
|
|
1695
|
+
|
|
1696
|
+
if (binaryFieldsForInline.length > 0) {
|
|
1697
|
+
const parts = []
|
|
1698
|
+
parts.push(Buffer.from(orderedLines.join("\r\n")))
|
|
1699
|
+
|
|
1700
|
+
for (const { key, buffer } of binaryFieldsForInline) {
|
|
1701
|
+
parts.push(Buffer.from(`\r\n${key}: `))
|
|
1702
|
+
parts.push(buffer)
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
parts.push(Buffer.from("\r\n"))
|
|
1706
|
+
|
|
1707
|
+
const fullBody = Buffer.concat(parts)
|
|
1708
|
+
bodyParts.push(new Blob([fullBody]))
|
|
1709
|
+
} else {
|
|
1710
|
+
// Check if this is the last body part for special handling
|
|
1711
|
+
const isLastBodyPart =
|
|
1712
|
+
sortedBodyKeys.indexOf(bodyKey) === sortedBodyKeys.length - 1
|
|
1713
|
+
const hasOnlyTypes = allTypes.length > 0 && fieldLines.length === 0
|
|
1714
|
+
|
|
1715
|
+
if (isLastBodyPart && hasOnlyTypes) {
|
|
1716
|
+
// Don't add empty line for last part with only types
|
|
1717
|
+
bodyParts.push(new Blob([orderedLines.join("\r\n")]))
|
|
1718
|
+
} else if (fieldLines.length === 0) {
|
|
1719
|
+
bodyParts.push(new Blob([orderedLines.join("\r\n")]))
|
|
1720
|
+
} else {
|
|
1721
|
+
bodyParts.push(new Blob([orderedLines.join("\r\n") + "\r\n"]))
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
} else {
|
|
1725
|
+
// Put ao-types first, then content-disposition, then field lines
|
|
1726
|
+
const orderedLines = []
|
|
1727
|
+
|
|
1728
|
+
if (allTypes.length > 0) {
|
|
1729
|
+
orderedLines.push(`ao-types: ${allTypes.sort().join(", ")}`)
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
orderedLines.push(`content-disposition: form-data;name="${bodyKey}"`)
|
|
1733
|
+
|
|
1734
|
+
// Check if we have any binary fields
|
|
1735
|
+
const hasBinaryFields = binaryFields && binaryFields.length > 0
|
|
1736
|
+
|
|
1737
|
+
// Add blank line before field lines if we have binary fields or no field lines
|
|
1738
|
+
if (hasBinaryFields || fieldLines.length === 0) {
|
|
1739
|
+
orderedLines.push("")
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
// Add field lines
|
|
1743
|
+
for (const line of fieldLines) {
|
|
1744
|
+
orderedLines.push(line)
|
|
1745
|
+
}
|
|
1746
|
+
|
|
1747
|
+
if (binaryFields && binaryFields.length > 0) {
|
|
1748
|
+
const parts = []
|
|
1749
|
+
const headerText = orderedLines.join("\r\n")
|
|
1750
|
+
parts.push(Buffer.from(headerText))
|
|
1751
|
+
|
|
1752
|
+
for (let i = 0; i < binaryFields.length; i++) {
|
|
1753
|
+
const { key, buffer } = binaryFields[i]
|
|
1754
|
+
if (i > 0) {
|
|
1755
|
+
parts.push(Buffer.from("\r\n"))
|
|
1756
|
+
}
|
|
1757
|
+
parts.push(Buffer.from(`${key}: `))
|
|
1758
|
+
parts.push(buffer)
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
parts.push(Buffer.from("\r\n"))
|
|
1762
|
+
const fullBody = Buffer.concat(parts)
|
|
1763
|
+
bodyParts.push(new Blob([fullBody]))
|
|
1764
|
+
} else {
|
|
1765
|
+
// Add trailing blank line if we have field lines
|
|
1766
|
+
if (fieldLines.length > 0) {
|
|
1767
|
+
bodyParts.push(new Blob([orderedLines.join("\r\n") + "\r\n"]))
|
|
1768
|
+
} else {
|
|
1769
|
+
bodyParts.push(new Blob([orderedLines.join("\r\n")]))
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
|
|
1774
|
+
continue
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1443
1777
|
const isInline = bodyKey === "body" && headers["inline-body-key"] === "body"
|
|
1444
1778
|
if (isInline) {
|
|
1445
1779
|
lines.push(`content-disposition: inline`)
|
|
@@ -1447,7 +1781,11 @@ async function encode(obj = {}) {
|
|
|
1447
1781
|
lines.push(`content-disposition: form-data;name="${bodyKey}"`)
|
|
1448
1782
|
}
|
|
1449
1783
|
|
|
1450
|
-
if (
|
|
1784
|
+
if (isBytes(value)) {
|
|
1785
|
+
const buffer = toBuffer(value)
|
|
1786
|
+
const headerText = lines.join("\r\n") + "\r\n\r\n"
|
|
1787
|
+
bodyParts.push(new Blob([headerText, buffer]))
|
|
1788
|
+
} else if (typeof value === "string") {
|
|
1451
1789
|
lines.push("")
|
|
1452
1790
|
lines.push(value)
|
|
1453
1791
|
bodyParts.push(new Blob([lines.join("\r\n")]))
|