wao 0.27.1 → 0.27.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/cjs/encode.js CHANGED
@@ -114,13 +114,14 @@ function _sha() {
114
114
  return _sha.apply(this, arguments);
115
115
  }
116
116
  function formatFloat(num) {
117
- // Format float in scientific notation with proper padding
118
117
  var exp = num.toExponential(20);
119
- // Replace "1.23e+0" with "1.23e+00"
120
118
  exp = exp.replace(/e\+(\d)$/, "e+0$1");
121
119
  exp = exp.replace(/e-(\d)$/, "e-0$1");
122
120
  return exp;
123
121
  }
122
+ function hasNonAscii(str) {
123
+ return /[^\x00-\x7F]/.test(str);
124
+ }
124
125
  function encodeArrayItem(item) {
125
126
  if (typeof item === "number") {
126
127
  if (Number.isInteger(item)) {
@@ -140,7 +141,6 @@ function encodeArrayItem(item) {
140
141
  } else if (typeof item === "boolean") {
141
142
  return "\"(ao-type-atom) \\\"".concat(item, "\\\"\"");
142
143
  } else if (Array.isArray(item)) {
143
- // Nested array
144
144
  var nestedItems = item.map(function (nestedItem) {
145
145
  if (typeof nestedItem === "number") {
146
146
  if (Number.isInteger(nestedItem)) {
@@ -152,21 +152,64 @@ function encodeArrayItem(item) {
152
152
  return "\\\"".concat(nestedItem, "\\\"");
153
153
  } else if (nestedItem === null) {
154
154
  return "\\\"(ao-type-atom) \\\\\\\"null\\\\\\\"\\\"";
155
+ } else if (nestedItem === undefined) {
156
+ return "\\\"(ao-type-atom) \\\\\\\"undefined\\\\\\\"\\\"";
155
157
  } else if (_typeof(nestedItem) === "symbol") {
156
158
  var _desc = nestedItem.description || "Symbol.for()";
157
159
  return "\\\"(ao-type-atom) \\\\\\\"".concat(_desc, "\\\\\\\"\\\"");
160
+ } else if (typeof nestedItem === "boolean") {
161
+ return "\\\"(ao-type-atom) \\\\\\\"".concat(nestedItem, "\\\\\\\"\\\"");
162
+ } else if (Array.isArray(nestedItem)) {
163
+ // Handle nested arrays recursively
164
+ var deeperItems = nestedItem.map(function (deepItem) {
165
+ if (typeof deepItem === "number") {
166
+ if (Number.isInteger(deepItem)) {
167
+ return "\\\\\\\"(ao-type-integer) ".concat(deepItem, "\\\\\\\"");
168
+ } else {
169
+ return "\\\\\\\"(ao-type-float) ".concat(formatFloat(deepItem), "\\\\\\\"");
170
+ }
171
+ } else if (typeof deepItem === "string") {
172
+ return "\\\\\\\"".concat(deepItem, "\\\\\\\"");
173
+ } else if (Array.isArray(deepItem)) {
174
+ // Even deeper nesting - need to escape more
175
+ var deepestItems = deepItem.map(function (deepestItem) {
176
+ if (typeof deepestItem === "number") {
177
+ if (Number.isInteger(deepestItem)) {
178
+ return "\\\\\\\\\\\\\\\"(ao-type-integer) ".concat(deepestItem, "\\\\\\\\\\\\\\\"");
179
+ } else {
180
+ return "\\\\\\\\\\\\\\\"(ao-type-float) ".concat(formatFloat(deepestItem), "\\\\\\\\\\\\\\\"");
181
+ }
182
+ } else if (typeof deepestItem === "string") {
183
+ return "\\\\\\\\\\\\\\\"".concat(deepestItem, "\\\\\\\\\\\\\\\"");
184
+ } else {
185
+ return "\\\\\\\\\\\\\\\"".concat(String(deepestItem), "\\\\\\\\\\\\\\\"");
186
+ }
187
+ }).join(", ");
188
+ return "\\\\\\\"(ao-type-list) ".concat(deepestItems, "\\\\\\\"");
189
+ } else if (deepItem === null) {
190
+ return "\\\\\\\"(ao-type-atom) \\\\\\\\\\\\\\\"null\\\\\\\\\\\\\\\"\\\\\\\"";
191
+ } else if (deepItem === undefined) {
192
+ return "\\\\\\\"(ao-type-atom) \\\\\\\\\\\\\\\"undefined\\\\\\\\\\\\\\\"\\\\\\\"";
193
+ } else if (_typeof(deepItem) === "symbol") {
194
+ var _desc2 = deepItem.description || "Symbol.for()";
195
+ return "\\\\\\\"(ao-type-atom) \\\\\\\\\\\\\\\"".concat(_desc2, "\\\\\\\\\\\\\\\"\\\\\\\"");
196
+ } else if (typeof deepItem === "boolean") {
197
+ return "\\\\\\\"(ao-type-atom) \\\\\\\\\\\\\\\"".concat(deepItem, "\\\\\\\\\\\\\\\"\\\\\\\"");
198
+ } else {
199
+ return "\\\\\\\"".concat(String(deepItem), "\\\\\\\"");
200
+ }
201
+ }).join(", ");
202
+ return "\\\"(ao-type-list) ".concat(deeperItems, "\\\"");
158
203
  } else {
159
204
  return "\\\"".concat(String(nestedItem), "\\\"");
160
205
  }
161
206
  }).join(", ");
162
207
  return "\"(ao-type-list) ".concat(nestedItems, "\"");
163
208
  } else if (isBytes(item)) {
164
- // For empty binaries in arrays, return empty string
165
209
  var buffer = toBuffer(item);
166
210
  if (buffer.length === 0 || buffer.byteLength === 0) {
167
211
  return "\"\"";
168
212
  }
169
- // For non-empty binaries, we can't include them in headers
170
213
  return "\"(ao-type-binary)\"";
171
214
  } else if (isPojo(item)) {
172
215
  var json = JSON.stringify(item);
@@ -176,64 +219,148 @@ function encodeArrayItem(item) {
176
219
  return "\"".concat(String(item), "\"");
177
220
  }
178
221
  }
179
- function needsOwnBodyPart(value) {
180
- if (Array.isArray(value)) return true;
181
- if (isBytes(value)) return true;
182
- if (isPojo(value)) {
183
- // Check if object has complex fields
184
- return Object.values(value).some(function (v) {
185
- return Array.isArray(v) || isPojo(v) || isBytes(v) || v === null || v === undefined || _typeof(v) === "symbol";
186
- });
222
+ function toBuffer(value) {
223
+ if (Buffer.isBuffer(value)) {
224
+ return value;
225
+ } else if (value && _typeof(value) === "object" && value.type === "Buffer" && Array.isArray(value.data)) {
226
+ return Buffer.from(value.data);
227
+ } else if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
228
+ return Buffer.from(value);
229
+ } else {
230
+ return Buffer.from(value);
187
231
  }
188
- return false;
189
232
  }
190
233
  function collectBodyKeys(obj) {
191
234
  var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "";
235
+ console.log("=== collectBodyKeys START ===");
236
+ console.log("Input object:", JSON.stringify(obj));
192
237
  var keys = [];
193
238
  function traverse(current, path) {
194
- // Track if current level has simple fields or empty objects
239
+ console.log("[traverse] Called with path: \"".concat(path, "\""));
195
240
  var hasSimpleFields = false;
196
- // Track nested paths that need body parts
197
241
  var nestedPaths = [];
242
+ var hasArraysWithObjects = false;
198
243
  var _loop = function _loop() {
199
244
  var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
200
245
  key = _Object$entries$_i[0],
201
246
  value = _Object$entries$_i[1];
202
247
  var fullPath = path ? "".concat(path, "/").concat(key) : key;
203
248
  if (Array.isArray(value)) {
249
+ console.log("[traverse] Found array at ".concat(fullPath, ", length: ").concat(value.length));
204
250
  var hasObjects = value.some(function (item) {
205
251
  return isPojo(item);
206
252
  });
207
253
  var hasNonObjects = value.some(function (item) {
208
254
  return !isPojo(item);
209
255
  });
210
- if (hasObjects) {
211
- // Each object in array gets its own key
212
- value.forEach(function (item, index) {
213
- if (isPojo(item)) {
214
- nestedPaths.push("".concat(fullPath, "/").concat(index + 1));
215
- }
256
+ if (value.length === 0) {
257
+ console.log("[traverse] Empty array at ".concat(fullPath, " - marking parent as having simple fields"));
258
+ hasSimpleFields = true;
259
+ } else if (hasObjects) {
260
+ hasArraysWithObjects = true;
261
+ // Check if we need special handling for mixed arrays
262
+ var hasEmptyStrings = value.some(function (item) {
263
+ return typeof item === "string" && item === "";
264
+ });
265
+ var hasEmptyObjects = value.some(function (item) {
266
+ return isPojo(item) && Object.keys(item).length === 0;
267
+ });
268
+ var hasNonEmptyObjects = value.some(function (item) {
269
+ return isPojo(item) && Object.keys(item).length > 0;
216
270
  });
217
271
 
218
- // If array ALSO has non-object items, it needs its own body part
219
- if (hasNonObjects) {
220
- hasSimpleFields = true;
272
+ // Check if objects contain only empty values (not empty objects)
273
+ var hasObjectsWithOnlyEmptyValues = value.some(function (item) {
274
+ if (!isPojo(item) || Object.keys(item).length === 0) return false;
275
+ return Object.values(item).every(function (v) {
276
+ return typeof v === "string" && v === "" || Array.isArray(v) && v.length === 0 || isPojo(v) && Object.keys(v).length === 0;
277
+ });
278
+ });
279
+
280
+ // Only use special handling if we have BOTH empty elements AND non-empty objects
281
+ if ((hasEmptyStrings || hasEmptyObjects) && hasNonEmptyObjects) {
282
+ // Special case: mixed array with empty strings/objects - only non-empty objects get parts
283
+ value.forEach(function (item, index) {
284
+ if (isPojo(item) && Object.keys(item).length > 0) {
285
+ var itemPath = "".concat(fullPath, "/").concat(index + 1);
286
+ keys.push(itemPath);
287
+ nestedPaths.push(itemPath);
288
+ }
289
+ });
290
+ if (hasNonObjects) {
291
+ hasSimpleFields = true;
292
+ keys.push(fullPath);
293
+ }
294
+ } else if (hasObjectsWithOnlyEmptyValues && !hasNonObjects) {
295
+ // Special case: objects that contain only empty values should get parts
296
+ value.forEach(function (item, index) {
297
+ if (isPojo(item)) {
298
+ var itemPath = "".concat(fullPath, "/").concat(index + 1);
299
+ keys.push(itemPath);
300
+ if (Object.keys(item).length > 0) {
301
+ nestedPaths.push(itemPath);
302
+ }
303
+ }
304
+ });
305
+ } else {
306
+ // Normal case: all objects get parts
307
+ value.forEach(function (item, index) {
308
+ if (isPojo(item)) {
309
+ var itemPath = "".concat(fullPath, "/").concat(index + 1);
310
+ keys.push(itemPath);
311
+ if (Object.keys(item).length > 0) {
312
+ nestedPaths.push(itemPath);
313
+ }
314
+ }
315
+ });
316
+ if (hasNonObjects) {
317
+ hasSimpleFields = true;
318
+ keys.push(fullPath);
319
+ }
221
320
  }
222
321
  } else {
223
- // Simple array - parent needs body part
322
+ console.log("[traverse] Non-empty array without objects at ".concat(fullPath, " - marking as simple field"));
224
323
  hasSimpleFields = true;
225
324
  }
226
325
  } else if (isPojo(value)) {
227
- // Check if this is an empty object
228
326
  if (Object.keys(value).length === 0) {
229
- // Empty objects need a body part
327
+ console.log("[traverse] Empty object at ".concat(fullPath, " - marking parent as having simple fields"));
230
328
  hasSimpleFields = true;
231
329
  } else {
232
- // Non-empty objects are processed recursively
233
- nestedPaths.push(fullPath);
330
+ // Don't traverse into the object if it only contains empty values
331
+ var containsOnlyEmptyCollections = Object.entries(value).every(function (_ref) {
332
+ var _ref2 = _slicedToArray(_ref, 2),
333
+ k = _ref2[0],
334
+ v = _ref2[1];
335
+ 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;
336
+ });
337
+ if (containsOnlyEmptyCollections && Object.keys(value).length > 0) {
338
+ console.log("[traverse] Object at ".concat(fullPath, " contains only empty collections - adding as body key"));
339
+ keys.push(fullPath);
340
+ } else {
341
+ // Check if this object contains arrays with only empty elements
342
+ var hasArraysWithOnlyEmptyElements = Object.entries(value).some(function (_ref3) {
343
+ var _ref4 = _slicedToArray(_ref3, 2),
344
+ k = _ref4[0],
345
+ v = _ref4[1];
346
+ return Array.isArray(v) && v.length > 0 && v.every(function (item) {
347
+ return Array.isArray(item) && item.length === 0 || isPojo(item) && Object.keys(item).length === 0 || typeof item === "string" && item === "";
348
+ });
349
+ });
350
+ if (hasArraysWithOnlyEmptyElements) {
351
+ // This object needs a body part to show its array types
352
+ console.log("[traverse] Object at ".concat(fullPath, " has arrays with empty elements - adding as body key"));
353
+ keys.push(fullPath);
354
+ }
355
+ console.log("[traverse] Non-empty object at ".concat(fullPath, " - will traverse into it"));
356
+ nestedPaths.push(fullPath);
357
+ }
234
358
  }
235
359
  } else if (isBytes(value)) {
236
- hasSimpleFields = true;
360
+ var buffer = toBuffer(value);
361
+ if (buffer.length > 0) {
362
+ hasSimpleFields = true;
363
+ }
237
364
  } else if (typeof value === "string" || typeof value === "number" || typeof value === "boolean" || value === null || value === undefined || _typeof(value) === "symbol") {
238
365
  hasSimpleFields = true;
239
366
  }
@@ -241,15 +368,33 @@ function collectBodyKeys(obj) {
241
368
  for (var _i = 0, _Object$entries = Object.entries(current); _i < _Object$entries.length; _i++) {
242
369
  _loop();
243
370
  }
244
-
245
- // Add current path if it has simple fields or empty objects
246
371
  if (hasSimpleFields) {
372
+ console.log("[traverse] Adding \"".concat(path, "\" to keys (has simple fields)"));
373
+ keys.push(path);
374
+ } else if (hasArraysWithObjects && path) {
375
+ // If the object only contains arrays with objects, we still need to add it as a body key
376
+ console.log("[traverse] Adding \"".concat(path, "\" to keys (contains arrays with objects)"));
247
377
  keys.push(path);
248
378
  }
249
379
 
250
- // Process nested paths
251
- for (var _i2 = 0, _nestedPaths = nestedPaths; _i2 < _nestedPaths.length; _i2++) {
252
- var nestedPath = _nestedPaths[_i2];
380
+ // Check for arrays with only empty elements that need their own body parts
381
+ for (var _i2 = 0, _Object$entries2 = Object.entries(current); _i2 < _Object$entries2.length; _i2++) {
382
+ var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2),
383
+ key = _Object$entries2$_i[0],
384
+ value = _Object$entries2$_i[1];
385
+ var fullPath = path ? "".concat(path, "/").concat(key) : key;
386
+ if (Array.isArray(value) && value.length > 0) {
387
+ var hasOnlyEmptyElements = value.every(function (item) {
388
+ return Array.isArray(item) && item.length === 0 || isPojo(item) && Object.keys(item).length === 0 || typeof item === "string" && item === "";
389
+ });
390
+ if (hasOnlyEmptyElements) {
391
+ console.log("[traverse] Array at ".concat(fullPath, " has only empty elements - adding as body key"));
392
+ keys.push(fullPath);
393
+ }
394
+ }
395
+ }
396
+ for (var _i3 = 0, _nestedPaths = nestedPaths; _i3 < _nestedPaths.length; _i3++) {
397
+ var nestedPath = _nestedPaths[_i3];
253
398
  var parts = nestedPath.split("/");
254
399
  var nestedObj = obj;
255
400
  var _iterator = _createForOfIteratorHelper(parts),
@@ -273,13 +418,29 @@ function collectBodyKeys(obj) {
273
418
  }
274
419
  }
275
420
  }
276
-
277
- // Handle top-level fields
421
+ var objKeys = Object.keys(obj);
278
422
  var _loop2 = function _loop2() {
279
- var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i3], 2),
280
- key = _Object$entries2$_i[0],
281
- value = _Object$entries2$_i[1];
282
- if (Array.isArray(value)) {
423
+ var _Object$entries3$_i = _slicedToArray(_Object$entries3[_i4], 2),
424
+ key = _Object$entries3$_i[0],
425
+ value = _Object$entries3$_i[1];
426
+ console.log("\n[main loop] Processing key: \"".concat(key, "\""));
427
+ console.log("[main loop] Value type: ".concat(Array.isArray(value) ? "array" : _typeof(value)));
428
+ console.log("[main loop] Array length: ".concat(Array.isArray(value) ? value.length : "N/A"));
429
+ if ((key === "data" || key === "body") && (typeof value === "string" || typeof value === "boolean" || typeof value === "number" || value === null || value === undefined || _typeof(value) === "symbol") && objKeys.length > 1) {
430
+ // Special handling: only add to body keys if there's no other data/body field with an object
431
+ if (key === "data" && obj.body && isPojo(obj.body) && Object.keys(obj.body).length > 0) {
432
+ console.log("[main loop] Skipping special data field");
433
+ } else if (key === "body" && obj.data && isPojo(obj.data) && Object.keys(obj.data).length > 0) {
434
+ console.log("[main loop] Skipping special body field");
435
+ } else {
436
+ console.log("[main loop] Adding special data/body key: \"".concat(key, "\""));
437
+ keys.push(key);
438
+ }
439
+ } else if (Array.isArray(value)) {
440
+ if (value.length === 0) {
441
+ console.log("[main loop] SKIPPING empty array for key: \"".concat(key, "\""));
442
+ return 1; // continue
443
+ }
283
444
  var hasObjects = value.some(function (item) {
284
445
  return isPojo(item);
285
446
  });
@@ -289,61 +450,214 @@ function collectBodyKeys(obj) {
289
450
  var hasNonObjects = value.some(function (item) {
290
451
  return !isPojo(item);
291
452
  });
292
- if (hasObjects) {
293
- value.forEach(function (item, index) {
294
- if (isPojo(item)) {
295
- keys.push("".concat(key, "/").concat(index + 1));
296
- // Also need to traverse into nested objects within array items
297
- for (var _i4 = 0, _Object$entries3 = Object.entries(item); _i4 < _Object$entries3.length; _i4++) {
298
- var _Object$entries3$_i = _slicedToArray(_Object$entries3[_i4], 2),
299
- nestedKey = _Object$entries3$_i[0],
300
- nestedValue = _Object$entries3$_i[1];
301
- if (isPojo(nestedValue)) {
302
- keys.push("".concat(key, "/").concat(index + 1, "/").concat(nestedKey));
303
- }
304
- }
305
- }
453
+
454
+ // Check if this is an array of arrays containing objects
455
+ var hasArraysOfObjects = value.some(function (item) {
456
+ return Array.isArray(item) && item.some(function (subItem) {
457
+ return isPojo(subItem);
458
+ });
459
+ });
460
+ console.log("[main loop] Array analysis: hasObjects=".concat(hasObjects, ", hasArrays=").concat(hasArrays, ", hasNonObjects=").concat(hasNonObjects, ", hasArraysOfObjects=").concat(hasArraysOfObjects));
461
+ if (value.length > 0) {
462
+ var bodyPartCounter = 1; // Start counting from 1
463
+
464
+ // Check for special mixed array case
465
+ var hasEmptyStrings = value.some(function (item) {
466
+ return typeof item === "string" && item === "";
467
+ });
468
+ var hasEmptyObjects = value.some(function (item) {
469
+ return isPojo(item) && Object.keys(item).length === 0;
306
470
  });
307
471
 
308
- // Mixed arrays also need their own body part
309
- if (hasNonObjects) {
472
+ // Check for objects that contain only empty values
473
+ var hasObjectsWithOnlyEmptyValues = value.some(function (item) {
474
+ if (!isPojo(item) || Object.keys(item).length === 0) return false;
475
+ return Object.values(item).every(function (v) {
476
+ return typeof v === "string" && v === "" || Array.isArray(v) && v.length === 0 || isPojo(v) && Object.keys(v).length === 0;
477
+ });
478
+ });
479
+ if (hasArraysOfObjects) {
480
+ // Handle arrays of arrays containing objects
481
+ value.forEach(function (item, index) {
482
+ if (Array.isArray(item)) {
483
+ item.forEach(function (subItem, subIndex) {
484
+ if (isPojo(subItem)) {
485
+ var path = "".concat(key, "/").concat(index + 1, "/").concat(subIndex + 1);
486
+ console.log("[main loop] Adding nested object path: \"".concat(path, "\""));
487
+ keys.push(path);
488
+ }
489
+ });
490
+ }
491
+ bodyPartCounter++;
492
+ });
493
+ // Always add the main array key
494
+ console.log("[main loop] ADDING main array key: \"".concat(key, "\""));
495
+ keys.push(key);
496
+ } else if (hasObjects && (hasEmptyStrings || hasEmptyObjects) && !hasObjectsWithOnlyEmptyValues) {
497
+ // Special handling: only non-empty objects get parts
498
+ value.forEach(function (item, index) {
499
+ if (isPojo(item) && Object.keys(item).length > 0) {
500
+ var path = "".concat(key, "/").concat(bodyPartCounter);
501
+ console.log("[main loop] Adding non-empty object path: \"".concat(path, "\" (array index ").concat(index, ")"));
502
+ keys.push(path);
503
+ // Add paths for nested objects
504
+ for (var _i5 = 0, _Object$entries4 = Object.entries(item); _i5 < _Object$entries4.length; _i5++) {
505
+ var _Object$entries4$_i = _slicedToArray(_Object$entries4[_i5], 2),
506
+ nestedKey = _Object$entries4$_i[0],
507
+ nestedValue = _Object$entries4$_i[1];
508
+ if (isPojo(nestedValue)) {
509
+ var nestedPath = "".concat(key, "/").concat(bodyPartCounter, "/").concat(nestedKey);
510
+ console.log("[main loop] Adding nested object path: \"".concat(nestedPath, "\""));
511
+ keys.push(nestedPath);
512
+ }
513
+ }
514
+ }
515
+ bodyPartCounter++;
516
+ });
517
+ // Always add the main array key
518
+ console.log("[main loop] ADDING main array key: \"".concat(key, "\""));
310
519
  keys.push(key);
520
+ } else if (hasObjects) {
521
+ // Normal handling: all objects get parts (except if parent array has only empty elements)
522
+ var skipEmptyObjects = false;
523
+
524
+ // Check if this array contains only empty elements
525
+ var arrayHasOnlyEmptyElements = value.every(function (item) {
526
+ return Array.isArray(item) && item.length === 0 || isPojo(item) && Object.keys(item).length === 0 || typeof item === "string" && item === "";
527
+ });
528
+ if (arrayHasOnlyEmptyElements) {
529
+ skipEmptyObjects = true;
530
+ }
531
+ value.forEach(function (item, index) {
532
+ if (isPojo(item)) {
533
+ // Skip empty objects if array has only empty elements
534
+ if (skipEmptyObjects && Object.keys(item).length === 0) {
535
+ bodyPartCounter++;
536
+ return;
537
+ }
538
+ var path = "".concat(key, "/").concat(bodyPartCounter);
539
+ console.log("[main loop] Adding object path: \"".concat(path, "\" (array index ").concat(index, ", empty=").concat(Object.keys(item).length === 0, ")"));
540
+ keys.push(path);
541
+ // Add paths for nested objects (but not empty ones)
542
+ if (Object.keys(item).length > 0) {
543
+ for (var _i6 = 0, _Object$entries5 = Object.entries(item); _i6 < _Object$entries5.length; _i6++) {
544
+ var _Object$entries5$_i = _slicedToArray(_Object$entries5[_i6], 2),
545
+ nestedKey = _Object$entries5$_i[0],
546
+ nestedValue = _Object$entries5$_i[1];
547
+ if (isPojo(nestedValue) && Object.keys(nestedValue).length > 0) {
548
+ var nestedPath = "".concat(key, "/").concat(bodyPartCounter, "/").concat(nestedKey);
549
+ console.log("[main loop] Adding nested object path: \"".concat(nestedPath, "\""));
550
+ keys.push(nestedPath);
551
+ }
552
+ }
553
+ }
554
+ } else if (typeof item === "string" && item === "") {
555
+ // Empty strings may get parts in some formats
556
+ var _path = "".concat(key, "/").concat(bodyPartCounter);
557
+ console.log("[main loop] Adding empty string path: \"".concat(_path, "\" (array index ").concat(index, ")"));
558
+ keys.push(_path);
559
+ }
560
+ bodyPartCounter++;
561
+ });
562
+ // Don't add main array key for arrays with only objects containing empty values
563
+ if (!hasObjectsWithOnlyEmptyValues || value.some(function (item) {
564
+ return !isPojo(item);
565
+ })) {
566
+ // Check if array has only empty elements
567
+ var hasOnlyEmptyElements = value.every(function (item) {
568
+ return Array.isArray(item) && item.length === 0 || isPojo(item) && Object.keys(item).length === 0 || typeof item === "string" && item === "";
569
+ });
570
+ if (!hasOnlyEmptyElements) {
571
+ // Always add the main array key
572
+ console.log("[main loop] ADDING main array key: \"".concat(key, "\""));
573
+ keys.push(key);
574
+ }
575
+ }
576
+ } else {
577
+ // Check if array has only empty elements
578
+ var hasOnlyEmptyArraysOrObjects = value.every(function (item) {
579
+ return Array.isArray(item) && item.length === 0 || isPojo(item) && Object.keys(item).length === 0 || typeof item === "string" && item === "";
580
+ });
581
+ if (hasOnlyEmptyArraysOrObjects && value.length > 0) {
582
+ // Always add the main array key for arrays with only empty elements
583
+ console.log("[main loop] ADDING main array key for empty elements: \"".concat(key, "\""));
584
+ keys.push(key);
585
+ } else if (!hasOnlyEmptyArraysOrObjects) {
586
+ // Always add the main array key
587
+ console.log("[main loop] ADDING main array key: \"".concat(key, "\""));
588
+ keys.push(key);
589
+ }
311
590
  }
312
- } else if (hasArrays) {
313
- // Array containing arrays needs body part
314
- keys.push(key);
315
- } else {
316
- // Simple array at top level - DO NOT add to body keys
317
- // It will go in headers instead
318
591
  }
319
592
  } else if (isPojo(value)) {
320
- // Top-level object that may have nested structures
593
+ console.log("[main loop] Processing object at key: \"".concat(key, "\""));
594
+ // Objects should be traversed, not have their fields individually added
321
595
  traverse(value, key);
322
596
  } else if (isBytes(value)) {
323
- // All binary data needs body parts, even empty ones
324
- keys.push(key);
597
+ var buffer = toBuffer(value);
598
+ if (buffer.length > 0) {
599
+ console.log("[main loop] Adding key for non-empty bytes: \"".concat(key, "\""));
600
+ keys.push(key);
601
+ }
325
602
  } else if (typeof value === "string" && value.includes("\n")) {
326
- // Multiline string
603
+ console.log("[main loop] Adding key for string with newline: \"".concat(key, "\""));
604
+ keys.push(key);
605
+ } else if (typeof value === "string" && hasNonAscii(value)) {
606
+ console.log("[main loop] Adding key for non-ASCII string: \"".concat(key, "\""));
327
607
  keys.push(key);
608
+ } else {
609
+ console.log("[main loop] Skipping key: \"".concat(key, "\" (no match)"));
328
610
  }
329
611
  };
330
- for (var _i3 = 0, _Object$entries2 = Object.entries(obj); _i3 < _Object$entries2.length; _i3++) {
331
- _loop2();
612
+ for (var _i4 = 0, _Object$entries3 = Object.entries(obj); _i4 < _Object$entries3.length; _i4++) {
613
+ if (_loop2()) continue;
332
614
  }
333
- return _toConsumableArray(new Set(keys)).filter(function (k) {
334
- return k !== "";
615
+ var result = _toConsumableArray(new Set(keys)).filter(function (k) {
616
+ if (k === "") return false;
617
+
618
+ // Check if this is a path to an empty object inside an array with only empty elements
619
+ var parts = k.split("/");
620
+ if (parts.length >= 2 && /^\d+$/.test(parts[parts.length - 1])) {
621
+ // This is an array element path like "maps/1"
622
+ var arrayPath = parts.slice(0, -1).join("/");
623
+ var arrayValue = obj;
624
+
625
+ // Navigate to the array
626
+ var _iterator2 = _createForOfIteratorHelper(parts.slice(0, -1)),
627
+ _step2;
628
+ try {
629
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
630
+ var part = _step2.value;
631
+ if (/^\d+$/.test(part)) {
632
+ arrayValue = arrayValue[parseInt(part) - 1];
633
+ } else {
634
+ arrayValue = arrayValue[part];
635
+ }
636
+ }
637
+
638
+ // Check if this array contains only empty elements
639
+ } catch (err) {
640
+ _iterator2.e(err);
641
+ } finally {
642
+ _iterator2.f();
643
+ }
644
+ if (Array.isArray(arrayValue)) {
645
+ var hasOnlyEmptyElements = arrayValue.every(function (item) {
646
+ return Array.isArray(item) && item.length === 0 || isPojo(item) && Object.keys(item).length === 0 || typeof item === "string" && item === "";
647
+ });
648
+ if (hasOnlyEmptyElements) {
649
+ // Filter out paths to individual empty elements
650
+ console.log("[filter] Removing path to empty element: \"".concat(k, "\""));
651
+ return false;
652
+ }
653
+ }
654
+ }
655
+ return true;
335
656
  });
336
- }
337
- function toBuffer(value) {
338
- if (Buffer.isBuffer(value)) {
339
- return value;
340
- } else if (value && _typeof(value) === "object" && value.type === "Buffer" && Array.isArray(value.data)) {
341
- return Buffer.from(value.data);
342
- } else if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
343
- return Buffer.from(value);
344
- } else {
345
- return Buffer.from(value);
346
- }
657
+ console.log("\n=== collectBodyKeys RESULT ===");
658
+ console.log("Final bodyKeys:", JSON.stringify(result));
659
+ console.log("=== collectBodyKeys END ===\n");
660
+ return result;
347
661
  }
348
662
  function encode() {
349
663
  return _encode.apply(this, arguments);
@@ -353,50 +667,66 @@ function _encode() {
353
667
  var obj,
354
668
  _processValue,
355
669
  processedObj,
356
- _i6,
357
- _Object$entries5,
358
- _Object$entries5$_i,
670
+ _i8,
671
+ _Object$entries7,
672
+ _Object$entries7$_i,
359
673
  k,
360
674
  v,
675
+ objKeys,
676
+ fieldName,
677
+ fieldValue,
678
+ _headers,
361
679
  hasBodyBinary,
362
680
  otherFields,
363
- allOthersSimpleOrEmptyBinary,
364
- _headers,
365
- _headerTypes,
366
- _i7,
367
- _Object$entries6,
368
- _Object$entries6$_i,
369
- key,
370
- value,
371
- encodedItems,
681
+ _headers2,
372
682
  bodyBuffer,
373
683
  bodyArrayBuffer,
374
- _contentDigest,
375
- _base,
376
- objKeys,
377
- fieldName,
378
- binaryData,
379
- _headers2,
684
+ contentDigest,
685
+ base64,
686
+ _fieldName,
687
+ _fieldValue,
688
+ _headers3,
380
689
  _bodyBuffer,
381
690
  _bodyArrayBuffer,
691
+ _contentDigest,
692
+ _base,
693
+ _headers4,
694
+ bodyContent,
695
+ encoder,
696
+ encoded,
382
697
  _contentDigest2,
383
698
  _base2,
699
+ _headers5,
700
+ _encoder,
701
+ _encoded,
702
+ _contentDigest3,
703
+ _base3,
704
+ bodyKeys,
384
705
  headers,
385
706
  headerTypes,
386
- bodyKeys,
387
707
  _loop3,
388
- _i8,
389
- _Object$entries7,
390
- _loop4,
391
708
  _i9,
392
709
  _Object$entries8,
710
+ _loop4,
711
+ _i10,
712
+ _Object$entries9,
393
713
  allBodyKeysAreEmptyBinaries,
714
+ singleKey,
715
+ pathParts,
716
+ value,
717
+ _iterator4,
718
+ _step4,
719
+ part,
720
+ otherFieldsAreEmpty,
721
+ _bodyBuffer2,
722
+ _bodyArrayBuffer2,
723
+ _contentDigest4,
724
+ _base4,
394
725
  sortedBodyKeys,
395
726
  hasSpecialDataBody,
396
- inlineKey,
397
727
  bodyParts,
398
- _iterator3,
399
- _step3,
728
+ _iterator5,
729
+ _step5,
400
730
  _loop5,
401
731
  _ret,
402
732
  buffer,
@@ -409,19 +739,15 @@ function _encode() {
409
739
  i,
410
740
  body,
411
741
  finalContent,
412
- contentDigest,
413
- base64,
414
- bodyText,
415
- boundaryMatch,
416
- debugBoundary,
417
- parts,
418
- lines,
742
+ _contentDigest5,
743
+ _base5,
419
744
  _args6 = arguments;
420
745
  return _regeneratorRuntime().wrap(function _callee3$(_context6) {
421
746
  while (1) switch (_context6.prev = _context6.next) {
422
747
  case 0:
423
748
  obj = _args6.length > 0 && _args6[0] !== undefined ? _args6[0] : {};
424
- // Convert symbols to strings for logging
749
+ console.log("\n=== ENCODE START ===");
750
+ console.log("Encoding object:", JSON.stringify(obj));
425
751
  _processValue = function processValue(value) {
426
752
  if (_typeof(value) === "symbol") {
427
753
  return value.description || "Symbol.for()";
@@ -429,10 +755,10 @@ function _encode() {
429
755
  return value.map(_processValue);
430
756
  } else if (isPojo(value)) {
431
757
  var result = {};
432
- for (var _i5 = 0, _Object$entries4 = Object.entries(value); _i5 < _Object$entries4.length; _i5++) {
433
- var _Object$entries4$_i = _slicedToArray(_Object$entries4[_i5], 2),
434
- k = _Object$entries4$_i[0],
435
- v = _Object$entries4$_i[1];
758
+ for (var _i7 = 0, _Object$entries6 = Object.entries(value); _i7 < _Object$entries6.length; _i7++) {
759
+ var _Object$entries6$_i = _slicedToArray(_Object$entries6[_i7], 2),
760
+ k = _Object$entries6$_i[0],
761
+ v = _Object$entries6$_i[1];
436
762
  result[k] = _processValue(v);
437
763
  }
438
764
  return result;
@@ -440,243 +766,306 @@ function _encode() {
440
766
  return value;
441
767
  };
442
768
  processedObj = {};
443
- for (_i6 = 0, _Object$entries5 = Object.entries(obj); _i6 < _Object$entries5.length; _i6++) {
444
- _Object$entries5$_i = _slicedToArray(_Object$entries5[_i6], 2), k = _Object$entries5$_i[0], v = _Object$entries5$_i[1];
769
+ for (_i8 = 0, _Object$entries7 = Object.entries(obj); _i8 < _Object$entries7.length; _i8++) {
770
+ _Object$entries7$_i = _slicedToArray(_Object$entries7[_i8], 2), k = _Object$entries7$_i[0], v = _Object$entries7$_i[1];
445
771
  processedObj[k] = _processValue(v);
446
772
  }
447
-
448
- // Remove debug logging for cleaner output
449
- console.log("[encode] START with obj:", JSON.stringify(processedObj));
450
773
  if (!(Object.keys(obj).length === 0)) {
451
- _context6.next = 7;
774
+ _context6.next = 8;
452
775
  break;
453
776
  }
454
777
  return _context6.abrupt("return", {
455
778
  headers: {},
456
779
  body: undefined
457
780
  });
458
- case 7:
459
- // Check for special case: body field with binary + other simple fields or empty binaries
460
- hasBodyBinary = obj.body && isBytes(obj.body);
461
- otherFields = Object.keys(obj).filter(function (k) {
462
- return k !== "body";
463
- });
464
- allOthersSimpleOrEmptyBinary = otherFields.every(function (k) {
465
- var v = obj[k];
466
- // Allow empty binaries as "simple"
467
- if (isBytes(v) && (v.length === 0 || v.byteLength === 0)) return true;
468
- return !isBytes(v) && !isPojo(v) && !(Array.isArray(v) && v.some(function (item) {
469
- return isPojo(item) || isBytes(item);
470
- }));
471
- });
472
- if (!(hasBodyBinary && allOthersSimpleOrEmptyBinary)) {
473
- _context6.next = 34;
781
+ case 8:
782
+ objKeys = Object.keys(obj);
783
+ if (!(objKeys.length === 1)) {
784
+ _context6.next = 16;
474
785
  break;
475
786
  }
476
- console.log("[encode] Special case: body with binary + simple fields");
477
- // Special case: body with binary + other simple fields
478
- _headers = {};
479
- _headerTypes = []; // Process other fields into headers
480
- _i7 = 0, _Object$entries6 = Object.entries(obj);
481
- case 15:
482
- if (!(_i7 < _Object$entries6.length)) {
483
- _context6.next = 24;
787
+ fieldName = objKeys[0];
788
+ fieldValue = obj[fieldName];
789
+ if (!(isBytes(fieldValue) && (fieldValue.length === 0 || fieldValue.byteLength === 0))) {
790
+ _context6.next = 16;
484
791
  break;
485
792
  }
486
- _Object$entries6$_i = _slicedToArray(_Object$entries6[_i7], 2), key = _Object$entries6$_i[0], value = _Object$entries6$_i[1];
487
- if (!(key === "body")) {
488
- _context6.next = 19;
793
+ _headers = {};
794
+ _headers["ao-types"] = "".concat(fieldName.toLowerCase(), "=\"empty-binary\"");
795
+ return _context6.abrupt("return", {
796
+ headers: _headers,
797
+ body: undefined
798
+ });
799
+ case 16:
800
+ if (obj.body && isBytes(obj.body) && (obj.body.length === 0 || obj.body.byteLength === 0) && objKeys.length > 1) {}
801
+ hasBodyBinary = obj.body && isBytes(obj.body);
802
+ otherFields = Object.keys(obj).filter(function (k) {
803
+ return k !== "body";
804
+ });
805
+ if (!(hasBodyBinary && otherFields.length === 0)) {
806
+ _context6.next = 29;
489
807
  break;
490
808
  }
491
- return _context6.abrupt("continue", 21);
492
- case 19:
493
- console.log("[encode] Processing special case field: ".concat(key, " = ").concat(JSON.stringify(value)));
494
- if (value === null) {
495
- _headers[key] = '"null"';
496
- _headerTypes.push("".concat(key, "=\"atom\""));
497
- } else if (value === undefined) {
498
- _headers[key] = '"undefined"';
499
- _headerTypes.push("".concat(key, "=\"atom\""));
500
- } else if (typeof value === "boolean") {
501
- _headers[key] = "\"".concat(value, "\"");
502
- _headerTypes.push("".concat(key, "=\"atom\""));
503
- } else if (_typeof(value) === "symbol") {
504
- _headers[key] = "\"".concat(value.description || "Symbol.for()", "\"");
505
- _headerTypes.push("".concat(key, "=\"atom\""));
506
- } else if (typeof value === "number") {
507
- _headers[key] = String(value);
508
- _headerTypes.push("".concat(key, "=\"").concat(Number.isInteger(value) ? "integer" : "float", "\""));
509
- } else if (typeof value === "string") {
510
- if (value.length === 0) {
511
- // Empty strings only go in ao-types, not as headers
512
- console.log("[encode] Adding empty string type for key: ".concat(key));
513
- _headerTypes.push("".concat(key, "=\"empty-binary\""));
514
- } else {
515
- _headers[key] = value;
516
- }
517
- } else if (Array.isArray(value) && value.length === 0) {
518
- // Empty array only goes in ao-types, not as a header
519
- _headerTypes.push("".concat(key, "=\"empty-list\""));
520
- } else if (Array.isArray(value) && !value.some(function (item) {
521
- return isPojo(item);
522
- })) {
523
- encodedItems = value.map(function (item) {
524
- return encodeArrayItem(item);
525
- }).join(", ");
526
- _headers[key] = encodedItems;
527
- _headerTypes.push("".concat(key, "=\"list\""));
528
- } else if (isBytes(value) && (value.length === 0 || value.byteLength === 0)) {
529
- // Empty binary goes in ao-types only
530
- _headerTypes.push("".concat(key, "=\"empty-binary\""));
531
- }
532
- case 21:
533
- _i7++;
534
- _context6.next = 15;
535
- break;
536
- case 24:
537
- // Add ao-types if needed
538
- if (_headerTypes.length > 0) {
539
- _headers["ao-types"] = _headerTypes.sort().join(", ");
540
- }
541
-
542
- // Set body to binary
809
+ _headers2 = {};
543
810
  bodyBuffer = toBuffer(obj.body);
544
811
  bodyArrayBuffer = bodyBuffer.buffer.slice(bodyBuffer.byteOffset, bodyBuffer.byteOffset + bodyBuffer.byteLength);
545
- _context6.next = 29;
812
+ _context6.next = 25;
546
813
  return sha256(bodyArrayBuffer);
547
- case 29:
548
- _contentDigest = _context6.sent;
549
- _base = _base64url["default"].toBase64(_base64url["default"].encode(_contentDigest));
550
- _headers["content-digest"] = "sha-256=:".concat(_base, ":");
551
- console.log("[encode] FINAL (body with binary) - headers:", _headers, "body:", obj.body);
814
+ case 25:
815
+ contentDigest = _context6.sent;
816
+ base64 = _base64url["default"].toBase64(_base64url["default"].encode(contentDigest));
817
+ _headers2["content-digest"] = "sha-256=:".concat(base64, ":");
552
818
  return _context6.abrupt("return", {
553
- headers: _headers,
819
+ headers: _headers2,
554
820
  body: obj.body
555
821
  });
556
- case 34:
557
- // Check if single binary field
558
- objKeys = Object.keys(obj);
559
- if (!(objKeys.length === 1 && isBytes(obj[objKeys[0]]))) {
560
- _context6.next = 49;
822
+ case 29:
823
+ if (!(objKeys.length === 1)) {
824
+ _context6.next = 71;
561
825
  break;
562
826
  }
563
- fieldName = objKeys[0];
564
- binaryData = obj[fieldName];
565
- _headers2 = {};
566
- _bodyBuffer = toBuffer(binaryData);
827
+ _fieldName = objKeys[0];
828
+ _fieldValue = obj[_fieldName];
829
+ if (!(isBytes(_fieldValue) && _fieldValue.length > 0)) {
830
+ _context6.next = 45;
831
+ break;
832
+ }
833
+ _headers3 = {};
834
+ _bodyBuffer = toBuffer(_fieldValue);
567
835
  _bodyArrayBuffer = _bodyBuffer.buffer.slice(_bodyBuffer.byteOffset, _bodyBuffer.byteOffset + _bodyBuffer.byteLength);
568
- _context6.next = 43;
836
+ _context6.next = 38;
569
837
  return sha256(_bodyArrayBuffer);
570
- case 43:
838
+ case 38:
839
+ _contentDigest = _context6.sent;
840
+ _base = _base64url["default"].toBase64(_base64url["default"].encode(_contentDigest));
841
+ _headers3["content-digest"] = "sha-256=:".concat(_base, ":");
842
+ if (_fieldName !== "body") {
843
+ _headers3["inline-body-key"] = _fieldName;
844
+ }
845
+ return _context6.abrupt("return", {
846
+ headers: _headers3,
847
+ body: _fieldValue
848
+ });
849
+ case 45:
850
+ if (!((_fieldName === "data" || _fieldName === "body") && (typeof _fieldValue === "string" || typeof _fieldValue === "boolean" || typeof _fieldValue === "number" || _fieldValue === null || _fieldValue === undefined || _typeof(_fieldValue) === "symbol"))) {
851
+ _context6.next = 60;
852
+ break;
853
+ }
854
+ _headers4 = {};
855
+ if (typeof _fieldValue === "string") {
856
+ bodyContent = _fieldValue;
857
+ } else if (typeof _fieldValue === "boolean") {
858
+ bodyContent = "\"".concat(_fieldValue, "\"");
859
+ } else if (typeof _fieldValue === "number") {
860
+ bodyContent = String(_fieldValue);
861
+ } else if (_fieldValue === null) {
862
+ bodyContent = '"null"';
863
+ } else if (_fieldValue === undefined) {
864
+ bodyContent = '"undefined"';
865
+ } else if (_typeof(_fieldValue) === "symbol") {
866
+ bodyContent = "\"".concat(_fieldValue.description || "Symbol.for()", "\"");
867
+ }
868
+ encoder = new TextEncoder();
869
+ encoded = encoder.encode(bodyContent);
870
+ _context6.next = 52;
871
+ return sha256(encoded.buffer);
872
+ case 52:
571
873
  _contentDigest2 = _context6.sent;
572
874
  _base2 = _base64url["default"].toBase64(_base64url["default"].encode(_contentDigest2));
573
- _headers2["content-digest"] = "sha-256=:".concat(_base2, ":");
574
-
575
- // Add inline-body-key header to preserve the field name
576
- if (fieldName !== "body") {
577
- _headers2["inline-body-key"] = fieldName;
875
+ _headers4["content-digest"] = "sha-256=:".concat(_base2, ":");
876
+ if (typeof _fieldValue === "boolean" || _fieldValue === null || _fieldValue === undefined || _typeof(_fieldValue) === "symbol") {
877
+ _headers4["ao-types"] = "".concat(_fieldName.toLowerCase(), "=\"atom\"");
878
+ } else if (typeof _fieldValue === "number") {
879
+ _headers4["ao-types"] = "".concat(_fieldName.toLowerCase(), "=\"").concat(Number.isInteger(_fieldValue) ? "integer" : "float", "\"");
880
+ }
881
+ if (_fieldName !== "body") {
882
+ _headers4["inline-body-key"] = _fieldName;
578
883
  }
579
- console.log("[encode] FINAL (simple binary field) - headers:", _headers2, "body:", binaryData);
580
884
  return _context6.abrupt("return", {
581
- headers: _headers2,
582
- body: binaryData
885
+ headers: _headers4,
886
+ body: bodyContent
583
887
  });
584
- case 49:
585
- // Continue with normal multipart processing
888
+ case 60:
889
+ if (!(typeof _fieldValue === "string" && hasNonAscii(_fieldValue))) {
890
+ _context6.next = 71;
891
+ break;
892
+ }
893
+ _headers5 = {};
894
+ _encoder = new TextEncoder();
895
+ _encoded = _encoder.encode(_fieldValue);
896
+ _context6.next = 66;
897
+ return sha256(_encoded.buffer);
898
+ case 66:
899
+ _contentDigest3 = _context6.sent;
900
+ _base3 = _base64url["default"].toBase64(_base64url["default"].encode(_contentDigest3));
901
+ _headers5["content-digest"] = "sha-256=:".concat(_base3, ":");
902
+ if (_fieldName !== "body") {
903
+ _headers5["inline-body-key"] = _fieldName;
904
+ }
905
+ return _context6.abrupt("return", {
906
+ headers: _headers5,
907
+ body: _fieldValue
908
+ });
909
+ case 71:
910
+ bodyKeys = collectBodyKeys(obj);
586
911
  headers = {};
587
- headerTypes = []; // Collect all body keys
588
- bodyKeys = collectBodyKeys(obj); // Process simple header fields AND collect types for body fields
912
+ headerTypes = [];
589
913
  _loop3 = /*#__PURE__*/_regeneratorRuntime().mark(function _loop3() {
590
- var _Object$entries7$_i, key, value, needsBody, _encodedItems;
914
+ var _Object$entries8$_i, key, value, needsBody, hasNonAsciiItems, encodedItems;
591
915
  return _regeneratorRuntime().wrap(function _loop3$(_context3) {
592
916
  while (1) switch (_context3.prev = _context3.next) {
593
917
  case 0:
594
- _Object$entries7$_i = _slicedToArray(_Object$entries7[_i8], 2), key = _Object$entries7$_i[0], value = _Object$entries7$_i[1];
595
- console.log("[encode] Processing field: ".concat(key, " = ").concat(JSON.stringify(value), ", type: ").concat(_typeof(value)));
918
+ _Object$entries8$_i = _slicedToArray(_Object$entries8[_i9], 2), key = _Object$entries8$_i[0], value = _Object$entries8$_i[1];
596
919
  needsBody = bodyKeys.includes(key) || bodyKeys.some(function (k) {
597
920
  return k.startsWith("".concat(key, "/"));
598
921
  });
599
- if (!needsBody) {
600
- console.log("[encode] Field ".concat(key, " doesn't need body, adding to headers"));
601
- // Simple value goes in header
602
- if (value === null) {
603
- headers[key] = '"null"';
604
- headerTypes.push("".concat(key, "=\"atom\""));
605
- } else if (value === undefined) {
606
- headers[key] = '"undefined"';
607
- headerTypes.push("".concat(key, "=\"atom\""));
608
- } else if (typeof value === "boolean") {
609
- headers[key] = "\"".concat(value, "\"");
610
- headerTypes.push("".concat(key, "=\"atom\""));
611
- } else if (_typeof(value) === "symbol") {
612
- headers[key] = "\"".concat(value.description || "Symbol.for()", "\"");
613
- headerTypes.push("".concat(key, "=\"atom\""));
614
- } else if (typeof value === "number") {
615
- headers[key] = String(value);
616
- headerTypes.push("".concat(key, "=\"").concat(Number.isInteger(value) ? "integer" : "float", "\""));
617
- } else if (typeof value === "string") {
618
- if (value.length === 0) {
619
- headerTypes.push("".concat(key, "=\"empty-binary\""));
620
- // Don't add empty strings as headers
621
- } else {
622
- headers[key] = value;
623
- }
624
- } else if (Array.isArray(value) && !value.some(function (item) {
625
- return isPojo(item);
626
- })) {
627
- // Simple array (no objects) goes in header
628
- _encodedItems = value.map(function (item) {
922
+ if (needsBody) {
923
+ _context3.next = 43;
924
+ break;
925
+ }
926
+ if (!(value === null)) {
927
+ _context3.next = 8;
928
+ break;
929
+ }
930
+ headers[key] = '"null"';
931
+ headerTypes.push("".concat(key.toLowerCase(), "=\"atom\""));
932
+ _context3.next = 41;
933
+ break;
934
+ case 8:
935
+ if (!(value === undefined)) {
936
+ _context3.next = 13;
937
+ break;
938
+ }
939
+ headers[key] = '"undefined"';
940
+ headerTypes.push("".concat(key.toLowerCase(), "=\"atom\""));
941
+ _context3.next = 41;
942
+ break;
943
+ case 13:
944
+ if (!(typeof value === "boolean")) {
945
+ _context3.next = 18;
946
+ break;
947
+ }
948
+ headers[key] = "\"".concat(value, "\"");
949
+ headerTypes.push("".concat(key.toLowerCase(), "=\"atom\""));
950
+ _context3.next = 41;
951
+ break;
952
+ case 18:
953
+ if (!(_typeof(value) === "symbol")) {
954
+ _context3.next = 23;
955
+ break;
956
+ }
957
+ headers[key] = "\"".concat(value.description || "Symbol.for()", "\"");
958
+ headerTypes.push("".concat(key.toLowerCase(), "=\"atom\""));
959
+ _context3.next = 41;
960
+ break;
961
+ case 23:
962
+ if (!(typeof value === "number")) {
963
+ _context3.next = 28;
964
+ break;
965
+ }
966
+ headers[key] = String(value);
967
+ headerTypes.push("".concat(key.toLowerCase(), "=\"").concat(Number.isInteger(value) ? "integer" : "float", "\""));
968
+ _context3.next = 41;
969
+ break;
970
+ case 28:
971
+ if (!(typeof value === "string")) {
972
+ _context3.next = 40;
973
+ break;
974
+ }
975
+ if (!(value.length === 0)) {
976
+ _context3.next = 33;
977
+ break;
978
+ }
979
+ headerTypes.push("".concat(key.toLowerCase(), "=\"empty-binary\""));
980
+ _context3.next = 38;
981
+ break;
982
+ case 33:
983
+ if (!hasNonAscii(value)) {
984
+ _context3.next = 37;
985
+ break;
986
+ }
987
+ return _context3.abrupt("return", 1);
988
+ case 37:
989
+ headers[key] = value;
990
+ case 38:
991
+ _context3.next = 41;
992
+ break;
993
+ case 40:
994
+ if (Array.isArray(value) && value.length === 0) {
995
+ headerTypes.push("".concat(key.toLowerCase(), "=\"empty-list\""));
996
+ } else if (Array.isArray(value) && !value.some(function (item) {
997
+ return isPojo(item);
998
+ })) {
999
+ hasNonAsciiItems = value.some(function (item) {
1000
+ return typeof item === "string" && hasNonAscii(item);
1001
+ });
1002
+ if (!hasNonAsciiItems) {
1003
+ encodedItems = value.map(function (item) {
629
1004
  return encodeArrayItem(item);
630
1005
  }).join(", ");
631
- headers[key] = _encodedItems;
632
- headerTypes.push("".concat(key, "=\"list\""));
633
- }
634
- } else {
635
- // Field needs body - still need to add type info to ao-types
636
- if (isBytes(value) && (value.length === 0 || value.byteLength === 0)) {
637
- headerTypes.push("".concat(key, "=\"empty-binary\""));
638
- } else if (typeof value === "string" && value.length === 0) {
639
- headerTypes.push("".concat(key, "=\"empty-binary\""));
640
- } else if (Array.isArray(value) && value.length === 0) {
641
- headerTypes.push("".concat(key, "=\"empty-list\""));
642
- } else if (isPojo(value) && Object.keys(value).length === 0) {
643
- headerTypes.push("".concat(key, "=\"empty-message\""));
1006
+ headers[key] = encodedItems;
1007
+ headerTypes.push("".concat(key.toLowerCase(), "=\"list\""));
644
1008
  }
1009
+ } else if (isBytes(value) && (value.length === 0 || value.byteLength === 0)) {
1010
+ headerTypes.push("".concat(key.toLowerCase(), "=\"empty-binary\""));
1011
+ } else if (isPojo(value) && Object.keys(value).length === 0) {
1012
+ headerTypes.push("".concat(key.toLowerCase(), "=\"empty-message\""));
1013
+ }
1014
+ case 41:
1015
+ _context3.next = 44;
1016
+ break;
1017
+ case 43:
1018
+ if (isBytes(value) && (value.length === 0 || value.byteLength === 0)) {
1019
+ headerTypes.push("".concat(key.toLowerCase(), "=\"empty-binary\""));
1020
+ } else if (typeof value === "string" && value.length === 0) {
1021
+ headerTypes.push("".concat(key.toLowerCase(), "=\"empty-binary\""));
1022
+ } else if (Array.isArray(value) && value.length === 0) {
1023
+ headerTypes.push("".concat(key.toLowerCase(), "=\"empty-list\""));
1024
+ } else if (isPojo(value) && Object.keys(value).length === 0) {
1025
+ headerTypes.push("".concat(key.toLowerCase(), "=\"empty-message\""));
1026
+ } else if (typeof value === "boolean" || value === null || value === undefined || _typeof(value) === "symbol") {
1027
+ headerTypes.push("".concat(key.toLowerCase(), "=\"atom\""));
1028
+ } else if (typeof value === "number") {
1029
+ headerTypes.push("".concat(key.toLowerCase(), "=\"").concat(Number.isInteger(value) ? "integer" : "float", "\""));
645
1030
  }
646
- case 4:
1031
+ case 44:
647
1032
  case "end":
648
1033
  return _context3.stop();
649
1034
  }
650
1035
  }, _loop3);
651
1036
  });
652
- _i8 = 0, _Object$entries7 = Object.entries(obj);
653
- case 54:
654
- if (!(_i8 < _Object$entries7.length)) {
655
- _context6.next = 59;
1037
+ _i9 = 0, _Object$entries8 = Object.entries(obj);
1038
+ case 76:
1039
+ if (!(_i9 < _Object$entries8.length)) {
1040
+ _context6.next = 83;
1041
+ break;
1042
+ }
1043
+ return _context6.delegateYield(_loop3(), "t0", 78);
1044
+ case 78:
1045
+ if (!_context6.t0) {
1046
+ _context6.next = 80;
656
1047
  break;
657
1048
  }
658
- return _context6.delegateYield(_loop3(), "t0", 56);
659
- case 56:
660
- _i8++;
661
- _context6.next = 54;
1049
+ return _context6.abrupt("continue", 80);
1050
+ case 80:
1051
+ _i9++;
1052
+ _context6.next = 76;
662
1053
  break;
663
- case 59:
1054
+ case 83:
664
1055
  _loop4 = /*#__PURE__*/_regeneratorRuntime().mark(function _loop4() {
665
- var _Object$entries8$_i, key, value;
1056
+ var _Object$entries9$_i, key, value;
666
1057
  return _regeneratorRuntime().wrap(function _loop4$(_context4) {
667
1058
  while (1) switch (_context4.prev = _context4.next) {
668
1059
  case 0:
669
- _Object$entries8$_i = _slicedToArray(_Object$entries8[_i9], 2), key = _Object$entries8$_i[0], value = _Object$entries8$_i[1];
1060
+ _Object$entries9$_i = _slicedToArray(_Object$entries9[_i10], 2), key = _Object$entries9$_i[0], value = _Object$entries9$_i[1];
670
1061
  if (Array.isArray(value)) {
671
- // Check if this array goes in the body
672
1062
  if (bodyKeys.includes(key) || bodyKeys.some(function (k) {
673
1063
  return k.startsWith("".concat(key, "/"));
674
1064
  })) {
675
- // Don't add list type if it's already been added
676
1065
  if (!headerTypes.some(function (t) {
677
- return t.startsWith("".concat(key, "="));
1066
+ return t.startsWith("".concat(key.toLowerCase(), "="));
678
1067
  })) {
679
- headerTypes.push("".concat(key, "=\"list\""));
1068
+ headerTypes.push("".concat(key.toLowerCase(), "=\"list\""));
680
1069
  }
681
1070
  }
682
1071
  }
@@ -686,407 +1075,453 @@ function _encode() {
686
1075
  }
687
1076
  }, _loop4);
688
1077
  });
689
- _i9 = 0, _Object$entries8 = Object.entries(obj);
690
- case 61:
691
- if (!(_i9 < _Object$entries8.length)) {
692
- _context6.next = 66;
1078
+ _i10 = 0, _Object$entries9 = Object.entries(obj);
1079
+ case 85:
1080
+ if (!(_i10 < _Object$entries9.length)) {
1081
+ _context6.next = 90;
693
1082
  break;
694
1083
  }
695
- return _context6.delegateYield(_loop4(), "t1", 63);
696
- case 63:
697
- _i9++;
698
- _context6.next = 61;
1084
+ return _context6.delegateYield(_loop4(), "t1", 87);
1085
+ case 87:
1086
+ _i10++;
1087
+ _context6.next = 85;
699
1088
  break;
700
- case 66:
1089
+ case 90:
701
1090
  if (!(bodyKeys.length === 0)) {
702
- _context6.next = 70;
1091
+ _context6.next = 94;
703
1092
  break;
704
1093
  }
1094
+ console.log("No bodyKeys, returning headers only");
705
1095
  if (headerTypes.length > 0) {
706
1096
  headers["ao-types"] = headerTypes.sort().join(", ");
707
1097
  }
708
- console.log("[encode] FINAL - headers:", headers, "body:", undefined);
709
1098
  return _context6.abrupt("return", {
710
1099
  headers: headers,
711
1100
  body: undefined
712
1101
  });
713
- case 70:
714
- // Check if all body keys are for empty binaries - if so, treat as no body needed
1102
+ case 94:
715
1103
  allBodyKeysAreEmptyBinaries = bodyKeys.every(function (key) {
716
1104
  var pathParts = key.split("/");
717
1105
  var value = obj;
718
- var _iterator2 = _createForOfIteratorHelper(pathParts),
719
- _step2;
1106
+ var _iterator3 = _createForOfIteratorHelper(pathParts),
1107
+ _step3;
720
1108
  try {
721
- for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
722
- var part = _step2.value;
1109
+ for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
1110
+ var part = _step3.value;
723
1111
  if (/^\d+$/.test(part)) {
724
- value = value[parseInt(part) - 1];
1112
+ var index = parseInt(part) - 1;
1113
+ console.log("[Body part] Getting array element at index ".concat(index, " from part ").concat(part));
1114
+ value = value[index];
725
1115
  } else {
726
1116
  value = value[part];
727
1117
  }
728
1118
  }
729
1119
  } catch (err) {
730
- _iterator2.e(err);
1120
+ _iterator3.e(err);
731
1121
  } finally {
732
- _iterator2.f();
1122
+ _iterator3.f();
733
1123
  }
734
1124
  return isBytes(value) && (value.length === 0 || value.byteLength === 0);
735
1125
  });
736
1126
  if (!allBodyKeysAreEmptyBinaries) {
737
- _context6.next = 75;
1127
+ _context6.next = 98;
738
1128
  break;
739
1129
  }
740
- // Treat as header-only encoding
741
1130
  if (headerTypes.length > 0) {
742
1131
  headers["ao-types"] = headerTypes.sort().join(", ");
743
1132
  }
744
- console.log("[encode] FINAL (all empty binaries) - headers:", headers, "body:", undefined);
745
1133
  return _context6.abrupt("return", {
746
1134
  headers: headers,
747
1135
  body: undefined
748
1136
  });
749
- case 75:
750
- // Sort body keys and add to headers
1137
+ case 98:
1138
+ if (!(bodyKeys.length === 1)) {
1139
+ _context6.next = 116;
1140
+ break;
1141
+ }
1142
+ singleKey = bodyKeys[0];
1143
+ pathParts = singleKey.split("/");
1144
+ value = obj;
1145
+ _iterator4 = _createForOfIteratorHelper(pathParts);
1146
+ try {
1147
+ for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
1148
+ part = _step4.value;
1149
+ if (/^\d+$/.test(part)) {
1150
+ value = value[parseInt(part) - 1];
1151
+ } else {
1152
+ value = value[part];
1153
+ }
1154
+ }
1155
+ } catch (err) {
1156
+ _iterator4.e(err);
1157
+ } finally {
1158
+ _iterator4.f();
1159
+ }
1160
+ otherFieldsAreEmpty = Object.entries(obj).every(function (_ref5) {
1161
+ var _ref6 = _slicedToArray(_ref5, 2),
1162
+ key = _ref6[0],
1163
+ val = _ref6[1];
1164
+ if (key === singleKey) return true;
1165
+ return Array.isArray(val) && val.length === 0 || isPojo(val) && Object.keys(val).length === 0 || isBytes(val) && (val.length === 0 || val.byteLength === 0) || typeof val === "string" && val.length === 0;
1166
+ });
1167
+ if (!(otherFieldsAreEmpty && isBytes(value) && value.length > 0)) {
1168
+ _context6.next = 116;
1169
+ break;
1170
+ }
1171
+ _bodyBuffer2 = toBuffer(value);
1172
+ _bodyArrayBuffer2 = _bodyBuffer2.buffer.slice(_bodyBuffer2.byteOffset, _bodyBuffer2.byteOffset + _bodyBuffer2.byteLength);
1173
+ _context6.next = 110;
1174
+ return sha256(_bodyArrayBuffer2);
1175
+ case 110:
1176
+ _contentDigest4 = _context6.sent;
1177
+ _base4 = _base64url["default"].toBase64(_base64url["default"].encode(_contentDigest4));
1178
+ headers["content-digest"] = "sha-256=:".concat(_base4, ":");
1179
+ if (singleKey !== "body") {
1180
+ headers["inline-body-key"] = singleKey;
1181
+ }
1182
+ if (headerTypes.length > 0) {
1183
+ headers["ao-types"] = headerTypes.sort().join(", ");
1184
+ }
1185
+ return _context6.abrupt("return", {
1186
+ headers: headers,
1187
+ body: value
1188
+ });
1189
+ case 116:
1190
+ // Sort body keys: main array comes first, then element parts by index
751
1191
  sortedBodyKeys = bodyKeys.sort(function (a, b) {
752
- // Special sorting to ensure parent paths come before child paths
753
- if (a.startsWith(b + "/")) return 1;
754
- if (b.startsWith(a + "/")) return -1;
1192
+ var aIsArrayElement = /\/\d+$/.test(a);
1193
+ var bIsArrayElement = /\/\d+$/.test(b);
1194
+ var aBase = a.split("/")[0];
1195
+ var bBase = b.split("/")[0];
1196
+
1197
+ // If both are for the same array
1198
+ if (aBase === bBase) {
1199
+ // Main array comes before element parts
1200
+ if (!aIsArrayElement && bIsArrayElement) {
1201
+ return -1; // main array comes first
1202
+ }
1203
+ if (aIsArrayElement && !bIsArrayElement) {
1204
+ return 1; // element parts come after
1205
+ }
1206
+ // Both are elements - sort by index
1207
+ if (aIsArrayElement && bIsArrayElement) {
1208
+ var aIndex = parseInt(a.split("/")[1]);
1209
+ var bIndex = parseInt(b.split("/")[1]);
1210
+ return aIndex - bIndex;
1211
+ }
1212
+ return a.localeCompare(b);
1213
+ }
1214
+
1215
+ // Different arrays, sort by base name
755
1216
  return a.localeCompare(b);
756
- }); // Special case: if we have both 'data' and 'body' keys where data.body is binary
757
- // then we need special handling per Erlang behavior
1217
+ }); // Check if we have the special case where data contains body with bytes and body contains data with bytes
758
1218
  hasSpecialDataBody = sortedBodyKeys.includes("data") && sortedBodyKeys.includes("body") && obj.data && obj.data.body && isBytes(obj.data.body) && obj.body && obj.body.data && isBytes(obj.body.data);
759
1219
  headers["body-keys"] = sortedBodyKeys.map(function (k) {
760
1220
  return "\"".concat(k, "\"");
761
1221
  }).join(", ");
762
-
763
- // Check for inline keys - but not in the special data/body case
764
1222
  if (!hasSpecialDataBody) {
765
- inlineKey = headers["inline-body-key"];
766
- if (!inlineKey) {
767
- // Only set inline-body-key if we have ONLY body (not data)
768
- if (sortedBodyKeys.includes("body") && !sortedBodyKeys.includes("data")) {
769
- headers["inline-body-key"] = "body";
770
- }
1223
+ if (sortedBodyKeys.includes("body") && sortedBodyKeys.length === 1) {
1224
+ headers["inline-body-key"] = "body";
771
1225
  }
772
1226
  }
773
-
774
- // Add ao-types header if needed
775
1227
  if (headerTypes.length > 0) {
776
1228
  headers["ao-types"] = headerTypes.sort().join(", ");
777
1229
  }
778
-
779
- // Create multipart body parts
780
1230
  bodyParts = [];
781
- _iterator3 = _createForOfIteratorHelper(sortedBodyKeys);
782
- _context6.prev = 82;
1231
+ _iterator5 = _createForOfIteratorHelper(sortedBodyKeys);
1232
+ _context6.prev = 123;
783
1233
  _loop5 = /*#__PURE__*/_regeneratorRuntime().mark(function _loop5() {
784
- var bodyKey, lines, pathParts, value, parent, _i10, part, isInline, _buffer, textPart, _textPart, objectTypes, fieldLines, binaryFields, _i11, _Object$entries9, _Object$entries9$_i, _k, _v, childPath, _buffer2, _encodedItems2, onlyEmptyCollections, orderedLines, _iterator4, _step4, line, _binaryFields, _parts, _iterator5, _step5, _step5$value, _key, _buffer3, fullBody, _iterator6, _step6, _line, _parts2, headerText, _iterator7, _step7, _step7$value, _key2, _buffer4, _fullBody, hasObjects, hasArrays, nonObjectItems, _fieldLines, partTypes, _iterator8, _step8, _step8$value, item, index, _buffer5, _encodedItems3, _orderedLines, _iterator9, _step9, _line2, _iterator10, _step10, _line3, _fieldLines2, _partTypes, _orderedLines2, _iterator11, _step11, _line4, _iterator12, _step12, _line5, _fieldName, _partTypes2;
1234
+ var bodyKey, lines, pathParts, value, parent, _i11, _part, _buffer, headerText, 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, isInline, content;
785
1235
  return _regeneratorRuntime().wrap(function _loop5$(_context5) {
786
1236
  while (1) switch (_context5.prev = _context5.next) {
787
1237
  case 0:
788
- bodyKey = _step3.value;
789
- lines = []; // Parse the path to get to the value
1238
+ bodyKey = _step5.value;
1239
+ console.log("\n[Body part] Processing bodyKey: ".concat(bodyKey));
1240
+ lines = [];
790
1241
  pathParts = bodyKey.split("/");
791
1242
  value = obj;
792
- parent = null; // Get the actual value at this path
793
- for (_i10 = 0; _i10 < pathParts.length; _i10++) {
1243
+ parent = null;
1244
+ for (_i11 = 0; _i11 < pathParts.length; _i11++) {
794
1245
  parent = value;
795
- part = pathParts[_i10];
796
- if (/^\d+$/.test(part)) {
797
- value = value[parseInt(part) - 1];
1246
+ _part = pathParts[_i11];
1247
+ if (/^\d+$/.test(_part)) {
1248
+ value = value[parseInt(_part) - 1];
798
1249
  } else {
799
- value = value[part];
1250
+ value = value[_part];
800
1251
  }
801
1252
  }
802
- console.log("[encode] Processing body key:", bodyKey, "value type:", Array.isArray(value) ? "array" : _typeof(value));
1253
+ console.log("[Body part] Value at ".concat(bodyKey, ":"), JSON.stringify(value));
803
1254
 
804
- // Skip if value is an array with only objects (no content for this body part)
805
- if (!(Array.isArray(value) && value.every(function (item) {
806
- return isPojo(item);
807
- }))) {
808
- _context5.next = 9;
1255
+ // Special handling for empty strings in arrays
1256
+ if (!(typeof value === "string" && value === "" && pathParts.length > 1)) {
1257
+ _context5.next = 15;
809
1258
  break;
810
1259
  }
1260
+ console.log("[Body part] Creating part for empty string at ".concat(bodyKey));
1261
+ lines.push("content-disposition: form-data;name=\"".concat(bodyKey, "\""));
1262
+ lines.push("");
1263
+ lines.push("");
1264
+ bodyParts.push(new Blob([lines.join("\r\n")]));
811
1265
  return _context5.abrupt("return", 0);
812
- case 9:
813
- if (!(isPojo(value) && Object.keys(value).length === 0)) {
814
- _context5.next = 11;
1266
+ case 15:
1267
+ if (!isBytes(value)) {
1268
+ _context5.next = 22;
815
1269
  break;
816
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]));
817
1276
  return _context5.abrupt("return", 0);
818
- case 11:
819
- if (!(hasSpecialDataBody && bodyKey === "data" && isPojo(value) && Object.keys(value).length === 1 && value.body && isBytes(value.body))) {
820
- _context5.next = 13;
1277
+ case 22:
1278
+ if (!Array.isArray(value)) {
1279
+ _context5.next = 52;
821
1280
  break;
822
1281
  }
823
- return _context5.abrupt("return", 0);
824
- case 13:
825
- console.log("[encode] Creating body part for key:", bodyKey, "value type:", _typeof(value), "isBytes:", isBytes(value));
826
-
827
- // Determine content-disposition
828
- isInline = bodyKey === "body" && headers["inline-body-key"] === "body";
829
- if (isInline) {
830
- lines.push("content-disposition: inline");
831
- } else {
832
- lines.push("content-disposition: form-data;name=\"".concat(bodyKey, "\""));
833
- }
834
- console.log("[encode] Value type checks:", {
835
- isBytes: isBytes(value),
836
- isPojo: isPojo(value),
837
- isArray: Array.isArray(value),
838
- valueType: _typeof(value)
1282
+ hasOnlyEmptyElements = value.length > 0 && value.every(function (item) {
1283
+ return Array.isArray(item) && item.length === 0 || isPojo(item) && Object.keys(item).length === 0 || typeof item === "string" && item === "";
839
1284
  });
840
- if (!isBytes(value)) {
841
- _context5.next = 23;
842
- break;
843
- }
844
- console.log("[encode] Processing binary value for key:", bodyKey);
845
- // Binary data
846
- _buffer = toBuffer(value); // Check if this is a nested path like "data/body"
847
- if (bodyKey.includes("/")) {
848
- // For nested binary, we need to replace the disposition
849
- lines[lines.length - 1] = "content-disposition: form-data;name=\"".concat(bodyKey, "\"");
850
- lines.push(""); // Empty line
851
- lines.push(""); // Another empty line before binary
852
- textPart = lines.join("\r\n");
853
- bodyParts.push(new Blob([textPart, _buffer]));
854
- } else {
855
- lines.push(""); // Empty line after headers
856
- lines.push(""); // Another empty line before binary data
857
- _textPart = lines.join("\r\n");
858
- bodyParts.push(new Blob([_textPart, _buffer]));
859
- }
860
- _context5.next = 80;
861
- break;
862
- case 23:
863
- if (!isPojo(value)) {
864
- _context5.next = 79;
865
- break;
866
- }
867
- console.log("[encode] Processing object value");
868
- // Object - only include fields that aren't handled by nested body parts
869
- objectTypes = [];
870
- fieldLines = [];
871
- binaryFields = [];
872
- _i11 = 0, _Object$entries9 = Object.entries(value);
873
- case 29:
874
- if (!(_i11 < _Object$entries9.length)) {
875
- _context5.next = 75;
876
- break;
877
- }
878
- _Object$entries9$_i = _slicedToArray(_Object$entries9[_i11], 2), _k = _Object$entries9$_i[0], _v = _Object$entries9$_i[1];
879
- childPath = "".concat(bodyKey, "/").concat(_k); // Skip if this field has its own body part
880
- if (!sortedBodyKeys.includes(childPath)) {
881
- _context5.next = 34;
882
- break;
883
- }
884
- return _context5.abrupt("continue", 72);
885
- case 34:
886
- if (!(Array.isArray(_v) && _v.some(function (item) {
1285
+ hasOnlyNonEmptyObjects = value.length > 0 && value.every(function (item) {
1286
+ return isPojo(item) && Object.keys(item).length > 0;
1287
+ });
1288
+ hasOnlyEmptyObjects = value.length > 0 && value.every(function (item) {
1289
+ return isPojo(item) && Object.keys(item).length === 0;
1290
+ });
1291
+ hasObjects = value.some(function (item) {
887
1292
  return isPojo(item);
888
- }))) {
889
- _context5.next = 36;
890
- break;
891
- }
892
- return _context5.abrupt("continue", 72);
893
- case 36:
894
- // Add type info
895
- if (Array.isArray(_v)) {
896
- objectTypes.push("".concat(_k, "=\"").concat(_v.length === 0 ? "empty-list" : "list", "\""));
897
- } else if (_v === null || _v === undefined || _typeof(_v) === "symbol" || typeof _v === "boolean") {
898
- objectTypes.push("".concat(_k, "=\"atom\""));
899
- } else if (typeof _v === "number") {
900
- objectTypes.push("".concat(_k, "=\"").concat(Number.isInteger(_v) ? "integer" : "float", "\""));
901
- } else if (typeof _v === "string" && _v.length === 0) {
902
- objectTypes.push("".concat(_k, "=\"empty-binary\""));
903
- } else if (isBytes(_v) && (_v.length === 0 || _v.byteLength === 0)) {
904
- objectTypes.push("".concat(_k, "=\"empty-binary\""));
905
- } else if (isPojo(_v) && Object.keys(_v).length === 0) {
906
- objectTypes.push("".concat(_k, "=\"empty-message\""));
907
- }
908
-
909
- // Add field value
910
- if (!(typeof _v === "string")) {
911
- _context5.next = 41;
912
- break;
913
- }
914
- fieldLines.push("".concat(_k, ": ").concat(_v));
915
- _context5.next = 72;
916
- break;
917
- case 41:
918
- if (!(typeof _v === "number")) {
919
- _context5.next = 45;
920
- break;
921
- }
922
- fieldLines.push("".concat(_k, ": ").concat(_v));
923
- _context5.next = 72;
924
- break;
925
- case 45:
926
- if (!(typeof _v === "boolean")) {
927
- _context5.next = 49;
928
- break;
929
- }
930
- fieldLines.push("".concat(_k, ": \"").concat(_v, "\""));
931
- _context5.next = 72;
932
- break;
933
- case 49:
934
- if (!(_v === null)) {
935
- _context5.next = 53;
936
- break;
937
- }
938
- fieldLines.push("".concat(_k, ": \"null\""));
939
- _context5.next = 72;
940
- break;
941
- case 53:
942
- if (!(_v === undefined)) {
943
- _context5.next = 57;
944
- break;
945
- }
946
- fieldLines.push("".concat(_k, ": \"undefined\""));
947
- _context5.next = 72;
948
- break;
949
- case 57:
950
- if (!(_typeof(_v) === "symbol")) {
951
- _context5.next = 61;
952
- break;
953
- }
954
- fieldLines.push("".concat(_k, ": \"").concat(_v.description || "Symbol.for()", "\""));
955
- _context5.next = 72;
956
- break;
957
- case 61:
958
- if (!isBytes(_v)) {
959
- _context5.next = 71;
1293
+ });
1294
+ hasArrays = value.some(function (item) {
1295
+ return Array.isArray(item);
1296
+ });
1297
+ nonObjectItems = value.map(function (item, index) {
1298
+ return {
1299
+ item: item,
1300
+ index: index + 1
1301
+ };
1302
+ }).filter(function (_ref7) {
1303
+ var item = _ref7.item;
1304
+ return !isPojo(item);
1305
+ });
1306
+ if (!hasOnlyNonEmptyObjects) {
1307
+ _context5.next = 31;
960
1308
  break;
961
1309
  }
962
- _buffer2 = toBuffer(_v); // For inline data/body parts, binary fields get raw bytes
963
- if (!isInline) {
964
- _context5.next = 67;
1310
+ return _context5.abrupt("return", 0);
1311
+ case 31:
1312
+ if (!hasOnlyEmptyElements) {
1313
+ _context5.next = 38;
965
1314
  break;
966
1315
  }
967
- return _context5.abrupt("continue", 72);
968
- case 67:
969
- // For non-inline parts, we need to add raw bytes, not base64
970
- // Store the binary field for later processing
971
- binaryFields.push({
972
- key: _k,
973
- buffer: _buffer2
1316
+ _fieldLines = [];
1317
+ _partTypes = []; // Process items for type information
1318
+ value.forEach(function (item, idx) {
1319
+ var index = idx + 1;
1320
+ if (Array.isArray(item) && item.length === 0) {
1321
+ _partTypes.push("".concat(index, "=\"empty-list\""));
1322
+ } else if (isPojo(item) && Object.keys(item).length === 0) {
1323
+ _partTypes.push("".concat(index, "=\"empty-message\""));
1324
+ } else if (typeof item === "string" && item === "") {
1325
+ _partTypes.push("".concat(index, "=\"empty-binary\""));
1326
+ }
974
1327
  });
975
- return _context5.abrupt("continue", 72);
976
- case 69:
977
- _context5.next = 72;
978
- break;
979
- case 71:
980
- if (Array.isArray(_v)) {
981
- if (_v.length === 0) {
982
- fieldLines.push("".concat(_k, ": "));
1328
+ _isInline = bodyKey === "body" && headers["inline-body-key"] === "body";
1329
+ if (_isInline) {
1330
+ orderedLines = [];
1331
+ if (_partTypes.length > 0) {
1332
+ orderedLines.push("ao-types: ".concat(_partTypes.sort(function (a, b) {
1333
+ var aNum = parseInt(a.split("=")[0]);
1334
+ var bNum = parseInt(b.split("=")[0]);
1335
+ return aNum - bNum;
1336
+ }).join(", ")));
1337
+ }
1338
+ orderedLines.push("content-disposition: inline");
1339
+ orderedLines.push("");
1340
+ bodyParts.push(new Blob([orderedLines.join("\r\n")]));
1341
+ } else {
1342
+ _orderedLines = [];
1343
+ if (_partTypes.length > 0) {
1344
+ _orderedLines.push("ao-types: ".concat(_partTypes.sort(function (a, b) {
1345
+ var aNum = parseInt(a.split("=")[0]);
1346
+ var bNum = parseInt(b.split("=")[0]);
1347
+ return aNum - bNum;
1348
+ }).join(", ")));
1349
+ }
1350
+ _orderedLines.push("content-disposition: form-data;name=\"".concat(bodyKey, "\""));
1351
+
1352
+ // Check if this is the last body part
1353
+ isLastBodyPart = sortedBodyKeys.indexOf(bodyKey) === sortedBodyKeys.length - 1;
1354
+ hasOnlyTypes = _partTypes.length > 0 && _fieldLines.length === 0;
1355
+ if (isLastBodyPart && hasOnlyTypes) {
1356
+ // Don't add empty line for last part with only types
1357
+ bodyParts.push(new Blob([_orderedLines.join("\r\n")]));
983
1358
  } else {
984
- _encodedItems2 = _v.map(function (item) {
985
- return encodeArrayItem(item);
986
- }).join(", ");
987
- fieldLines.push("".concat(_k, ": ").concat(_encodedItems2));
1359
+ _orderedLines.push("");
1360
+ bodyParts.push(new Blob([_orderedLines.join("\r\n")]));
988
1361
  }
989
- } else if (isPojo(_v) && Object.keys(_v).length === 0) {
990
- // Empty object - no content line needed, just ao-type
991
1362
  }
992
- case 72:
993
- _i11++;
994
- _context5.next = 29;
995
- break;
996
- case 75:
997
- // Check if this object only has empty collections
998
- onlyEmptyCollections = Object.entries(value).every(function (_ref) {
999
- var _ref2 = _slicedToArray(_ref, 2),
1000
- k = _ref2[0],
1001
- v = _ref2[1];
1002
- var childPath = "".concat(bodyKey, "/").concat(k);
1003
- if (sortedBodyKeys.includes(childPath)) return true;
1004
- if (Array.isArray(v) && v.some(function (item) {
1005
- return isPojo(item);
1006
- })) return true;
1007
- return Array.isArray(v) && v.length === 0 || isPojo(v) && Object.keys(v).length === 0 || isBytes(v) && (v.length === 0 || v.byteLength === 0);
1008
- }); // Special handling for inline body
1009
- if (isInline) {
1010
- // For inline: fields first, then ao-types, then content-disposition
1011
- orderedLines = []; // First: field lines
1012
- if (!onlyEmptyCollections) {
1013
- _iterator4 = _createForOfIteratorHelper(fieldLines);
1014
- try {
1015
- for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
1016
- line = _step4.value;
1017
- orderedLines.push(line);
1018
- }
1019
- } catch (err) {
1020
- _iterator4.e(err);
1021
- } finally {
1022
- _iterator4.f();
1363
+ return _context5.abrupt("return", 0);
1364
+ case 38:
1365
+ // Build list of which indices have their own parts
1366
+ indicesWithOwnParts = new Set();
1367
+ sortedBodyKeys.forEach(function (key) {
1368
+ if (key.startsWith(bodyKey + "/")) {
1369
+ var subPath = key.substring(bodyKey.length + 1);
1370
+ var match = subPath.match(/^(\d+)/);
1371
+ if (match) {
1372
+ indicesWithOwnParts.add(parseInt(match[1]));
1023
1373
  }
1024
1374
  }
1375
+ });
1025
1376
 
1026
- // Then: ao-types
1027
- if (objectTypes.length > 0) {
1028
- orderedLines.push("ao-types: ".concat(objectTypes.sort().join(", ")));
1029
- }
1030
-
1031
- // Finally: content-disposition
1032
- orderedLines.push("content-disposition: inline");
1377
+ // Check if this array contains sub-arrays with objects that have their own parts
1378
+ hasNestedObjectParts = sortedBodyKeys.some(function (key) {
1379
+ return key.startsWith(bodyKey + "/") && key.split("/").length > pathParts.length + 1;
1380
+ });
1381
+ fieldLines = [];
1382
+ partTypes = []; // For arrays that contain sub-arrays with objects, we need to add type info for the sub-arrays
1383
+ if (hasNestedObjectParts) {
1384
+ value.forEach(function (item, idx) {
1385
+ var index = idx + 1;
1386
+ if (Array.isArray(item)) {
1387
+ partTypes.push("".concat(index, "=\"list\""));
1388
+ }
1389
+ });
1390
+ }
1033
1391
 
1034
- // Check if this has binary fields
1035
- _binaryFields = Object.entries(value).filter(function (_ref3) {
1036
- var _ref4 = _slicedToArray(_ref3, 2),
1037
- k = _ref4[0],
1038
- v = _ref4[1];
1039
- return isBytes(v) && !sortedBodyKeys.includes("".concat(bodyKey, "/").concat(k));
1040
- }).map(function (_ref5) {
1041
- var _ref6 = _slicedToArray(_ref5, 2),
1042
- k = _ref6[0],
1043
- v = _ref6[1];
1044
- return {
1045
- key: k,
1046
- buffer: toBuffer(v)
1047
- };
1392
+ // Check if this array has mixed content with empty strings/objects
1393
+ hasEmptyStrings = value.some(function (item) {
1394
+ return typeof item === "string" && item === "";
1395
+ });
1396
+ hasEmptyObjects = value.some(function (item) {
1397
+ return isPojo(item) && Object.keys(item).length === 0;
1398
+ }); // Check if we have objects with only empty values (like {empty: ""})
1399
+ hasObjectsWithOnlyEmptyValues = value.some(function (item) {
1400
+ if (!isPojo(item) || Object.keys(item).length === 0) return false;
1401
+ return Object.values(item).every(function (v) {
1402
+ return typeof v === "string" && v === "" || Array.isArray(v) && v.length === 0 || isPojo(v) && Object.keys(v).length === 0;
1048
1403
  });
1049
- if (_binaryFields.length > 0) {
1050
- // Build the parts
1051
- _parts = []; // Add the text part
1052
- _parts.push(Buffer.from(orderedLines.join("\r\n")));
1404
+ });
1405
+ isMixedArray = hasObjects && (hasEmptyStrings || hasEmptyObjects) && !hasObjectsWithOnlyEmptyValues; // Process ALL items for type information
1406
+ value.forEach(function (item, idx) {
1407
+ var index = idx + 1;
1053
1408
 
1054
- // Add binary fields with raw bytes
1055
- _iterator5 = _createForOfIteratorHelper(_binaryFields);
1056
- try {
1057
- for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
1058
- _step5$value = _step5.value, _key = _step5$value.key, _buffer3 = _step5$value.buffer;
1059
- _parts.push(Buffer.from("\r\n".concat(_key, ": ")));
1060
- _parts.push(_buffer3);
1061
- }
1409
+ // Skip type info for elements that have their own parts
1410
+ if (indicesWithOwnParts.has(index)) {
1411
+ return;
1412
+ }
1062
1413
 
1063
- // Add trailing \r\n for inline parts with binary
1064
- } catch (err) {
1065
- _iterator5.e(err);
1066
- } finally {
1067
- _iterator5.f();
1414
+ // If we have nested object parts and this is an array with objects, skip processing it inline
1415
+ if (hasNestedObjectParts && Array.isArray(item) && item.some(function (subItem) {
1416
+ return isPojo(subItem);
1417
+ })) {
1418
+ // Type info already added above
1419
+ return;
1420
+ }
1421
+
1422
+ // For all arrays (not just mixed ones), we need to process all items
1423
+ if (typeof item === "string" && item === "") {
1424
+ // Empty strings get type annotation but no field line
1425
+ partTypes.push("".concat(index, "=\"empty-binary\""));
1426
+ } else if (isPojo(item) && Object.keys(item).length === 0) {
1427
+ // Empty objects don't get field lines but do get type annotations
1428
+ partTypes.push("".concat(index, "=\"empty-message\""));
1429
+ } else if (isPojo(item)) {
1430
+ // Non-empty objects might have parts
1431
+ } else if (Array.isArray(item)) {
1432
+ if (item.length === 0) {
1433
+ // Empty arrays don't get field lines but do get type annotations
1434
+ partTypes.push("".concat(index, "=\"empty-list\""));
1435
+ } else {
1436
+ partTypes.push("".concat(index, "=\"list\""));
1437
+ // Encode array
1438
+ var encodedItems = item.map(function (subItem) {
1439
+ if (typeof subItem === "number") {
1440
+ if (Number.isInteger(subItem)) {
1441
+ return "\"(ao-type-integer) ".concat(subItem, "\"");
1442
+ } else {
1443
+ return "\"(ao-type-float) ".concat(formatFloat(subItem), "\"");
1444
+ }
1445
+ } else if (typeof subItem === "string") {
1446
+ return "\"".concat(subItem, "\"");
1447
+ } else if (subItem === null) {
1448
+ return "\"(ao-type-atom) \\\"null\\\"\"";
1449
+ } else if (subItem === undefined) {
1450
+ return "\"(ao-type-atom) \\\"undefined\\\"\"";
1451
+ } else if (_typeof(subItem) === "symbol") {
1452
+ var desc = subItem.description || "Symbol.for()";
1453
+ return "\"(ao-type-atom) \\\"".concat(desc, "\\\"\"");
1454
+ } else if (typeof subItem === "boolean") {
1455
+ return "\"(ao-type-atom) \\\"".concat(subItem, "\\\"\"");
1456
+ } else if (Array.isArray(subItem)) {
1457
+ // Use the full encodeArrayItem for nested arrays
1458
+ return encodeArrayItem(subItem);
1459
+ } else if (isBytes(subItem)) {
1460
+ var _buffer2 = toBuffer(subItem);
1461
+ if (_buffer2.length === 0 || _buffer2.byteLength === 0) {
1462
+ return "\"\"";
1463
+ }
1464
+ return "\"(ao-type-binary)\"";
1465
+ } else if (isPojo(subItem)) {
1466
+ var json = JSON.stringify(subItem);
1467
+ var escaped = json.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
1468
+ return "\"(ao-type-map) ".concat(escaped, "\"");
1469
+ } else {
1470
+ return "\"".concat(String(subItem), "\"");
1471
+ }
1472
+ }).join(", ");
1473
+ fieldLines.push("".concat(index, ": ").concat(encodedItems));
1474
+ }
1475
+ } else if (typeof item === "number") {
1476
+ if (Number.isInteger(item)) {
1477
+ partTypes.push("".concat(index, "=\"integer\""));
1478
+ fieldLines.push("".concat(index, ": ").concat(item));
1479
+ } else {
1480
+ partTypes.push("".concat(index, "=\"float\""));
1481
+ fieldLines.push("".concat(index, ": ").concat(formatFloat(item)));
1482
+ }
1483
+ } else if (typeof item === "string") {
1484
+ // Non-empty strings just get field lines, no type annotation
1485
+ fieldLines.push("".concat(index, ": ").concat(item));
1486
+ } else if (item === null || item === undefined || _typeof(item) === "symbol" || typeof item === "boolean") {
1487
+ partTypes.push("".concat(index, "=\"atom\""));
1488
+ if (item === null) {
1489
+ fieldLines.push("".concat(index, ": null"));
1490
+ } else if (item === undefined) {
1491
+ fieldLines.push("".concat(index, ": undefined"));
1492
+ } else if (_typeof(item) === "symbol") {
1493
+ var desc = item.description || "Symbol.for()";
1494
+ fieldLines.push("".concat(index, ": ").concat(desc));
1495
+ } else {
1496
+ fieldLines.push("".concat(index, ": ").concat(item));
1497
+ }
1498
+ } else if (isBytes(item)) {
1499
+ var _buffer3 = toBuffer(item);
1500
+ if (_buffer3.length === 0) {
1501
+ partTypes.push("".concat(index, "=\"empty-binary\""));
1502
+ } else {
1503
+ partTypes.push("".concat(index, "=\"binary\""));
1068
1504
  }
1069
- _parts.push(Buffer.from("\r\n"));
1070
- fullBody = Buffer.concat(_parts);
1071
- bodyParts.push(new Blob([fullBody]));
1072
- } else {
1073
- orderedLines.push(""); // Add empty line for trailing \r\n
1074
- bodyParts.push(new Blob([orderedLines.join("\r\n")]));
1075
1505
  }
1076
- } else {
1077
- // Normal handling (non-inline)
1078
- // ao-types first if needed
1079
- if (objectTypes.length > 0) {
1080
- lines.unshift("ao-types: ".concat(objectTypes.sort().join(", ")));
1506
+ });
1507
+ _isInline2 = bodyKey === "body" && headers["inline-body-key"] === "body";
1508
+ if (_isInline2) {
1509
+ _orderedLines2 = [];
1510
+ if (partTypes.length > 0) {
1511
+ _orderedLines2.push("ao-types: ".concat(partTypes.sort(function (a, b) {
1512
+ var aNum = parseInt(a.split("=")[0]);
1513
+ var bNum = parseInt(b.split("=")[0]);
1514
+ return aNum - bNum;
1515
+ }).join(", ")));
1081
1516
  }
1082
-
1083
- // Only add field lines if not all collections are empty
1084
- if (!onlyEmptyCollections) {
1517
+ _orderedLines2.push("content-disposition: inline");
1518
+ if (fieldLines.length > 0) {
1519
+ _orderedLines2.push("");
1085
1520
  _iterator6 = _createForOfIteratorHelper(fieldLines);
1086
1521
  try {
1087
1522
  for (_iterator6.s(); !(_step6 = _iterator6.n()).done;) {
1088
- _line = _step6.value;
1089
- lines.push(_line);
1523
+ line = _step6.value;
1524
+ _orderedLines2.push(line);
1090
1525
  }
1091
1526
  } catch (err) {
1092
1527
  _iterator6.e(err);
@@ -1094,344 +1529,121 @@ function _encode() {
1094
1529
  _iterator6.f();
1095
1530
  }
1096
1531
  }
1097
-
1098
- // Then handle binary fields with raw bytes if any
1099
- if (binaryFields && binaryFields.length > 0) {
1100
- // Create parts array for proper ordering
1101
- _parts2 = []; // Add headers and text fields
1102
- headerText = lines.join("\r\n") + "\r\n";
1103
- _parts2.push(Buffer.from(headerText));
1104
-
1105
- // Add binary fields with raw bytes
1106
- _iterator7 = _createForOfIteratorHelper(binaryFields);
1107
- try {
1108
- for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
1109
- _step7$value = _step7.value, _key2 = _step7$value.key, _buffer4 = _step7$value.buffer;
1110
- _parts2.push(Buffer.from("".concat(_key2, ": ")));
1111
- _parts2.push(_buffer4);
1112
- _parts2.push(Buffer.from("\r\n"));
1113
- }
1114
- } catch (err) {
1115
- _iterator7.e(err);
1116
- } finally {
1117
- _iterator7.f();
1118
- }
1119
- _fullBody = Buffer.concat(_parts2);
1120
- bodyParts.push(new Blob([_fullBody]));
1121
- } else {
1122
- lines.push("");
1123
- bodyParts.push(new Blob([lines.join("\r\n")]));
1532
+ bodyParts.push(new Blob([_orderedLines2.join("\r\n") + "\r\n"]));
1533
+ } else {
1534
+ // Put ao-types first, then content-disposition, then field lines
1535
+ _orderedLines3 = [];
1536
+ if (partTypes.length > 0) {
1537
+ _orderedLines3.push("ao-types: ".concat(partTypes.sort(function (a, b) {
1538
+ var aNum = parseInt(a.split("=")[0]);
1539
+ var bNum = parseInt(b.split("=")[0]);
1540
+ return aNum - bNum;
1541
+ }).join(", ")));
1124
1542
  }
1125
- }
1126
- _context5.next = 80;
1127
- break;
1128
- case 79:
1129
- if (Array.isArray(value)) {
1130
- // Array field - check if it's a mixed array or array of arrays
1131
- hasObjects = value.some(function (item) {
1132
- return isPojo(item);
1133
- });
1134
- hasArrays = value.some(function (item) {
1135
- return Array.isArray(item);
1136
- });
1137
- nonObjectItems = value.map(function (item, index) {
1138
- return {
1139
- item: item,
1140
- index: index + 1
1141
- };
1142
- }).filter(function (_ref7) {
1143
- var item = _ref7.item;
1144
- return !isPojo(item);
1145
- });
1146
- if (hasObjects && nonObjectItems.length > 0) {
1147
- // Mixed array - only include non-object items
1148
- _fieldLines = [];
1149
- partTypes = [];
1150
- _iterator8 = _createForOfIteratorHelper(nonObjectItems);
1151
- try {
1152
- for (_iterator8.s(); !(_step8 = _iterator8.n()).done;) {
1153
- _step8$value = _step8.value, item = _step8$value.item, index = _step8$value.index;
1154
- if (typeof item === "number") {
1155
- if (Number.isInteger(item)) {
1156
- partTypes.push("".concat(index, "=\"integer\""));
1157
- _fieldLines.push("".concat(index, ": ").concat(item));
1158
- } else {
1159
- partTypes.push("".concat(index, "=\"float\""));
1160
- _fieldLines.push("".concat(index, ": ").concat(formatFloat(item)));
1161
- }
1162
- } else if (typeof item === "string") {
1163
- _fieldLines.push("".concat(index, ": ").concat(item));
1164
- } else if (item === null || item === undefined || _typeof(item) === "symbol" || typeof item === "boolean") {
1165
- partTypes.push("".concat(index, "=\"atom\""));
1166
- if (item === null) {
1167
- _fieldLines.push("".concat(index, ": \"null\""));
1168
- } else if (item === undefined) {
1169
- _fieldLines.push("".concat(index, ": \"undefined\""));
1170
- } else if (_typeof(item) === "symbol") {
1171
- _fieldLines.push("".concat(index, ": \"").concat(item.description || "Symbol.for()", "\""));
1172
- } else {
1173
- _fieldLines.push("".concat(index, ": \"").concat(item, "\""));
1174
- }
1175
- } else if (isBytes(item)) {
1176
- // Binary items in arrays need special handling
1177
- _buffer5 = toBuffer(item);
1178
- if (_buffer5.length === 0) {
1179
- partTypes.push("".concat(index, "=\"empty-binary\""));
1180
- }
1181
- // For now, skip binary items in mixed arrays
1182
- // They should be handled differently
1183
- partTypes.push("".concat(index, "=\"binary\""));
1184
- } else if (Array.isArray(item)) {
1185
- partTypes.push("".concat(index, "=\"list\""));
1186
- _encodedItems3 = item.map(function (subItem) {
1187
- return encodeArrayItem(subItem);
1188
- }).join(", ");
1189
- _fieldLines.push("".concat(index, ": ").concat(_encodedItems3));
1190
- }
1191
- }
1543
+ _orderedLines3.push("content-disposition: form-data;name=\"".concat(bodyKey, "\""));
1192
1544
 
1193
- // For inline arrays, use different order
1194
- } catch (err) {
1195
- _iterator8.e(err);
1196
- } finally {
1197
- _iterator8.f();
1545
+ // Add field lines directly without blank line
1546
+ _iterator7 = _createForOfIteratorHelper(fieldLines);
1547
+ try {
1548
+ for (_iterator7.s(); !(_step7 = _iterator7.n()).done;) {
1549
+ _line = _step7.value;
1550
+ _orderedLines3.push(_line);
1198
1551
  }
1199
- if (isInline) {
1200
- console.log("[encode] Reordering for inline array:", {
1201
- bodyKey: bodyKey,
1202
- fieldLines: _fieldLines,
1203
- partTypes: partTypes
1204
- });
1205
-
1206
- // Rebuild in correct order: field lines, ao-types, content-disposition
1207
- _orderedLines = []; // First: field lines
1208
- _iterator9 = _createForOfIteratorHelper(_fieldLines);
1209
- try {
1210
- for (_iterator9.s(); !(_step9 = _iterator9.n()).done;) {
1211
- _line2 = _step9.value;
1212
- _orderedLines.push(_line2);
1213
- }
1214
1552
 
1215
- // Then: ao-types
1216
- } catch (err) {
1217
- _iterator9.e(err);
1218
- } finally {
1219
- _iterator9.f();
1220
- }
1221
- if (partTypes.length > 0) {
1222
- _orderedLines.push("ao-types: ".concat(partTypes.sort(function (a, b) {
1223
- var aNum = parseInt(a.split("=")[0]);
1224
- var bNum = parseInt(b.split("=")[0]);
1225
- return aNum - bNum;
1226
- }).join(", ")));
1227
- }
1228
-
1229
- // Finally: content-disposition (from lines[0])
1230
- _orderedLines.push(lines[0]);
1231
- _orderedLines.push("");
1232
- console.log("[encode] Ordered lines:", _orderedLines);
1233
- bodyParts.push(new Blob([_orderedLines.join("\r\n")]));
1234
- } else {
1235
- // Normal order for non-inline parts
1236
- if (partTypes.length > 0) {
1237
- lines.unshift("ao-types: ".concat(partTypes.sort(function (a, b) {
1238
- var aNum = parseInt(a.split("=")[0]);
1239
- var bNum = parseInt(b.split("=")[0]);
1240
- return aNum - bNum;
1241
- }).join(", ")));
1242
- }
1243
- _iterator10 = _createForOfIteratorHelper(_fieldLines);
1244
- try {
1245
- for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
1246
- _line3 = _step10.value;
1247
- lines.push(_line3);
1248
- }
1249
- } catch (err) {
1250
- _iterator10.e(err);
1251
- } finally {
1252
- _iterator10.f();
1253
- }
1254
- lines.push("");
1255
- bodyParts.push(new Blob([lines.join("\r\n")]));
1256
- }
1257
- } else if (hasArrays || !hasObjects && value.length > 0) {
1258
- // Array of arrays or simple array - use indexed format
1259
- _fieldLines2 = [];
1260
- _partTypes = [];
1261
- value.forEach(function (item, idx) {
1262
- var index = idx + 1;
1263
- if (Array.isArray(item)) {
1264
- if (item.length === 0) {
1265
- _partTypes.push("".concat(index, "=\"empty-list\""));
1266
- } else {
1267
- _partTypes.push("".concat(index, "=\"list\""));
1268
- var _encodedItems4 = item.map(function (subItem) {
1269
- return encodeArrayItem(subItem);
1270
- }).join(", ");
1271
- _fieldLines2.push("".concat(index, ": ").concat(_encodedItems4));
1272
- }
1273
- } else if (typeof item === "number") {
1274
- if (Number.isInteger(item)) {
1275
- _partTypes.push("".concat(index, "=\"integer\""));
1276
- _fieldLines2.push("".concat(index, ": ").concat(item));
1277
- } else {
1278
- _partTypes.push("".concat(index, "=\"float\""));
1279
- _fieldLines2.push("".concat(index, ": ").concat(formatFloat(item)));
1280
- }
1281
- } else if (typeof item === "string") {
1282
- if (item.length === 0) {
1283
- _partTypes.push("".concat(index, "=\"empty-binary\""));
1284
- }
1285
- _fieldLines2.push("".concat(index, ": ").concat(item));
1286
- } else if (item === null || item === undefined || _typeof(item) === "symbol" || typeof item === "boolean") {
1287
- _partTypes.push("".concat(index, "=\"atom\""));
1288
- if (item === null) {
1289
- _fieldLines2.push("".concat(index, ": \"null\""));
1290
- } else if (item === undefined) {
1291
- _fieldLines2.push("".concat(index, ": \"undefined\""));
1292
- } else if (_typeof(item) === "symbol") {
1293
- _fieldLines2.push("".concat(index, ": \"").concat(item.description || "Symbol.for()", "\""));
1294
- } else {
1295
- _fieldLines2.push("".concat(index, ": \"").concat(item, "\""));
1296
- }
1297
- } else if (isBytes(item)) {
1298
- var _buffer6 = toBuffer(item);
1299
- if (_buffer6.length === 0) {
1300
- _partTypes.push("".concat(index, "=\"empty-binary\""));
1301
- } else {
1302
- _partTypes.push("".concat(index, "=\"binary\""));
1303
- }
1304
- // For indexed format, we also can't include raw bytes inline
1305
- // This is a limitation of the format
1306
- }
1307
- });
1308
-
1309
- // For inline arrays, use different order
1310
- if (isInline) {
1311
- console.log("[encode] Reordering for inline array - indexed format");
1312
- _orderedLines2 = []; // First: field lines
1313
- _iterator11 = _createForOfIteratorHelper(_fieldLines2);
1314
- try {
1315
- for (_iterator11.s(); !(_step11 = _iterator11.n()).done;) {
1316
- _line4 = _step11.value;
1317
- _orderedLines2.push(_line4);
1318
- }
1319
-
1320
- // Then: ao-types
1321
- } catch (err) {
1322
- _iterator11.e(err);
1323
- } finally {
1324
- _iterator11.f();
1325
- }
1326
- if (_partTypes.length > 0) {
1327
- _orderedLines2.push("ao-types: ".concat(_partTypes.sort(function (a, b) {
1328
- var aNum = parseInt(a.split("=")[0]);
1329
- var bNum = parseInt(b.split("=")[0]);
1330
- return aNum - bNum;
1331
- }).join(", ")));
1332
- }
1333
-
1334
- // Finally: content-disposition
1335
- _orderedLines2.push(lines[0]);
1336
- _orderedLines2.push("");
1337
- console.log("[encode] Final ordered lines:", _orderedLines2);
1338
- bodyParts.push(new Blob([_orderedLines2.join("\r\n")]));
1339
- } else {
1340
- // Normal order for non-inline parts
1341
- if (_partTypes.length > 0) {
1342
- console.log("[encode] Adding ao-types to beginning of lines array");
1343
- lines.unshift("ao-types: ".concat(_partTypes.sort(function (a, b) {
1344
- var aNum = parseInt(a.split("=")[0]);
1345
- var bNum = parseInt(b.split("=")[0]);
1346
- return aNum - bNum;
1347
- }).join(", ")));
1348
- }
1349
- console.log("[encode] Adding field lines:", _fieldLines2);
1350
- _iterator12 = _createForOfIteratorHelper(_fieldLines2);
1351
- try {
1352
- for (_iterator12.s(); !(_step12 = _iterator12.n()).done;) {
1353
- _line5 = _step12.value;
1354
- lines.push(_line5);
1355
- }
1356
- } catch (err) {
1357
- _iterator12.e(err);
1358
- } finally {
1359
- _iterator12.f();
1360
- }
1361
- console.log("[encode] Final lines before blob:", lines);
1362
- lines.push("");
1363
- bodyParts.push(new Blob([lines.join("\r\n")]));
1364
- }
1365
- } else if (!hasObjects && value.length === 0) {
1366
- // Empty array
1367
- _fieldName = pathParts[pathParts.length - 1];
1368
- _partTypes2 = ["".concat(_fieldName, "=\"empty-list\"")];
1369
- lines.unshift("ao-types: ".concat(_partTypes2.join(", ")));
1370
- lines.push("");
1371
- bodyParts.push(new Blob([lines.join("\r\n")]));
1553
+ // Add trailing blank line if we have field lines
1554
+ } catch (err) {
1555
+ _iterator7.e(err);
1556
+ } finally {
1557
+ _iterator7.f();
1558
+ }
1559
+ if (fieldLines.length > 0) {
1560
+ bodyParts.push(new Blob([_orderedLines3.join("\r\n") + "\r\n"]));
1561
+ } else {
1562
+ bodyParts.push(new Blob([_orderedLines3.join("\r\n")]));
1372
1563
  }
1373
- } else if (typeof value === "string") {
1374
- // String with newlines or too long
1564
+ }
1565
+ return _context5.abrupt("return", 0);
1566
+ case 52:
1567
+ // This should not be reached for binary values as they're handled above
1568
+ isInline = bodyKey === "body" && headers["inline-body-key"] === "body";
1569
+ if (isInline) {
1570
+ lines.push("content-disposition: inline");
1571
+ } else {
1572
+ lines.push("content-disposition: form-data;name=\"".concat(bodyKey, "\""));
1573
+ }
1574
+ if (typeof value === "string") {
1375
1575
  lines.push("");
1376
1576
  lines.push(value);
1577
+ bodyParts.push(new Blob([lines.join("\r\n")]));
1578
+ } else if (typeof value === "boolean" || typeof value === "number" || value === null || value === undefined || _typeof(value) === "symbol") {
1579
+ if (typeof value === "boolean") {
1580
+ content = "\"".concat(value, "\"");
1581
+ } else if (typeof value === "number") {
1582
+ content = String(value);
1583
+ } else if (value === null) {
1584
+ content = '"null"';
1585
+ } else if (value === undefined) {
1586
+ content = '"undefined"';
1587
+ } else if (_typeof(value) === "symbol") {
1588
+ content = "\"".concat(value.description || "Symbol.for()", "\"");
1589
+ }
1377
1590
  lines.push("");
1591
+ lines.push(content);
1378
1592
  bodyParts.push(new Blob([lines.join("\r\n")]));
1379
1593
  }
1380
- case 80:
1594
+ case 55:
1381
1595
  case "end":
1382
1596
  return _context5.stop();
1383
1597
  }
1384
1598
  }, _loop5);
1385
1599
  });
1386
- _iterator3.s();
1387
- case 85:
1388
- if ((_step3 = _iterator3.n()).done) {
1389
- _context6.next = 92;
1600
+ _iterator5.s();
1601
+ case 126:
1602
+ if ((_step5 = _iterator5.n()).done) {
1603
+ _context6.next = 133;
1390
1604
  break;
1391
1605
  }
1392
- return _context6.delegateYield(_loop5(), "t2", 87);
1393
- case 87:
1606
+ return _context6.delegateYield(_loop5(), "t2", 128);
1607
+ case 128:
1394
1608
  _ret = _context6.t2;
1395
1609
  if (!(_ret === 0)) {
1396
- _context6.next = 90;
1610
+ _context6.next = 131;
1397
1611
  break;
1398
1612
  }
1399
- return _context6.abrupt("continue", 90);
1400
- case 90:
1401
- _context6.next = 85;
1613
+ return _context6.abrupt("continue", 131);
1614
+ case 131:
1615
+ _context6.next = 126;
1402
1616
  break;
1403
- case 92:
1404
- _context6.next = 97;
1617
+ case 133:
1618
+ _context6.next = 138;
1405
1619
  break;
1406
- case 94:
1407
- _context6.prev = 94;
1408
- _context6.t3 = _context6["catch"](82);
1409
- _iterator3.e(_context6.t3);
1410
- case 97:
1411
- _context6.prev = 97;
1412
- _iterator3.f();
1413
- return _context6.finish(97);
1414
- case 100:
1415
- // Special case: add data/body as a separate form-data part if needed
1620
+ case 135:
1621
+ _context6.prev = 135;
1622
+ _context6.t3 = _context6["catch"](123);
1623
+ _iterator5.e(_context6.t3);
1624
+ case 138:
1625
+ _context6.prev = 138;
1626
+ _iterator5.f();
1627
+ return _context6.finish(138);
1628
+ case 141:
1629
+ // Add the special data/body part if needed
1416
1630
  if (hasSpecialDataBody && obj.data && obj.data.body && isBytes(obj.data.body)) {
1417
1631
  buffer = toBuffer(obj.data.body);
1418
1632
  specialPart = ["content-disposition: form-data;name=\"data/body\"", "", ""].join("\r\n");
1419
1633
  bodyParts.push(new Blob([specialPart, buffer]));
1420
1634
  }
1421
-
1422
- // Calculate boundary from content
1423
- _context6.next = 103;
1635
+ _context6.next = 144;
1424
1636
  return Promise.all(bodyParts.map(function (part) {
1425
1637
  return part.text();
1426
1638
  }));
1427
- case 103:
1639
+ case 144:
1428
1640
  partsContent = _context6.sent;
1429
1641
  allContent = partsContent.join("");
1430
- _context6.next = 107;
1642
+ _context6.next = 148;
1431
1643
  return sha256(new TextEncoder().encode(allContent));
1432
- case 107:
1644
+ case 148:
1433
1645
  boundaryHash = _context6.sent;
1434
- boundary = _base64url["default"].encode(Buffer.from(boundaryHash)); // Assemble final multipart body - NO newlines after each part except the last
1646
+ boundary = _base64url["default"].encode(Buffer.from(boundaryHash));
1435
1647
  finalParts = [];
1436
1648
  for (i = 0; i < bodyParts.length; i++) {
1437
1649
  if (i === 0) {
@@ -1443,60 +1655,33 @@ function _encode() {
1443
1655
  }
1444
1656
  finalParts.push(new Blob(["\r\n--".concat(boundary, "--")]));
1445
1657
  headers["content-type"] = "multipart/form-data; boundary=\"".concat(boundary, "\"");
1446
- body = new Blob(finalParts); // Calculate content digest
1447
- _context6.next = 116;
1658
+ body = new Blob(finalParts);
1659
+ _context6.next = 157;
1448
1660
  return body.arrayBuffer();
1449
- case 116:
1661
+ case 157:
1450
1662
  finalContent = _context6.sent;
1451
- _context6.next = 119;
1663
+ if (!(finalContent.byteLength > 0)) {
1664
+ _context6.next = 164;
1665
+ break;
1666
+ }
1667
+ _context6.next = 161;
1452
1668
  return sha256(finalContent);
1453
- case 119:
1454
- contentDigest = _context6.sent;
1455
- base64 = _base64url["default"].toBase64(_base64url["default"].encode(contentDigest));
1456
- headers["content-digest"] = "sha-256=:".concat(base64, ":");
1669
+ case 161:
1670
+ _contentDigest5 = _context6.sent;
1671
+ _base5 = _base64url["default"].toBase64(_base64url["default"].encode(_contentDigest5));
1672
+ headers["content-digest"] = "sha-256=:".concat(_base5, ":");
1673
+ case 164:
1457
1674
  headers["content-length"] = String(finalContent.byteLength);
1458
- console.log("[encode] FINAL - headers:", headers, "body:", body);
1459
-
1460
- // Debug: decode the multipart body to verify structure
1461
- _context6.next = 126;
1462
- return body.text();
1463
- case 126:
1464
- bodyText = _context6.sent;
1465
- console.log("\n[encode] DEBUG - Full body text:");
1466
- console.log(bodyText);
1467
-
1468
- // Parse multipart body
1469
- boundaryMatch = headers["content-type"].match(/boundary="([^"]+)"/);
1470
- if (boundaryMatch) {
1471
- debugBoundary = boundaryMatch[1];
1472
- parts = bodyText.split("--".concat(debugBoundary));
1473
- console.log("\n[encode] DEBUG - Multipart parts:");
1474
- parts.forEach(function (part, idx) {
1475
- console.log("Part ".concat(idx, ":"), JSON.stringify(part));
1476
- });
1477
-
1478
- // Show the actual content part
1479
- if (parts[1]) {
1480
- console.log("\n[encode] DEBUG - Content part structure:");
1481
- lines = parts[1].trim().split("\r\n");
1482
- lines.forEach(function (line, idx) {
1483
- if (line.includes("\0")) {
1484
- console.log("Line ".concat(idx, ": \"").concat(line.substring(0, line.indexOf("\0")), "\" + [").concat(line.length - line.indexOf("\0"), " bytes]"));
1485
- } else {
1486
- console.log("Line ".concat(idx, ": \"").concat(line, "\""));
1487
- }
1488
- });
1489
- }
1490
- }
1675
+ console.log("=== ENCODE END ===\n");
1491
1676
  return _context6.abrupt("return", {
1492
1677
  headers: headers,
1493
1678
  body: body
1494
1679
  });
1495
- case 132:
1680
+ case 167:
1496
1681
  case "end":
1497
1682
  return _context6.stop();
1498
1683
  }
1499
- }, _callee3, null, [[82, 94, 97, 100]]);
1684
+ }, _callee3, null, [[123, 135, 138, 141]]);
1500
1685
  }));
1501
1686
  return _encode.apply(this, arguments);
1502
1687
  }