@strapi/data-transfer 5.42.0 → 5.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/directory/providers/source/index.d.ts.map +1 -1
  2. package/dist/directory/providers/source/index.js +3 -2
  3. package/dist/directory/providers/source/index.js.map +1 -1
  4. package/dist/directory/providers/source/index.mjs +3 -2
  5. package/dist/directory/providers/source/index.mjs.map +1 -1
  6. package/dist/engine/index.d.ts.map +1 -1
  7. package/dist/engine/index.js +130 -5
  8. package/dist/engine/index.js.map +1 -1
  9. package/dist/engine/index.mjs +130 -5
  10. package/dist/engine/index.mjs.map +1 -1
  11. package/dist/engine/validation/schemas/index.js +2 -0
  12. package/dist/engine/validation/schemas/index.js.map +1 -1
  13. package/dist/engine/validation/schemas/index.mjs +2 -0
  14. package/dist/engine/validation/schemas/index.mjs.map +1 -1
  15. package/dist/file/providers/source/index.d.ts.map +1 -1
  16. package/dist/file/providers/source/index.js +84 -45
  17. package/dist/file/providers/source/index.js.map +1 -1
  18. package/dist/file/providers/source/index.mjs +85 -46
  19. package/dist/file/providers/source/index.mjs.map +1 -1
  20. package/dist/strapi/providers/index.js +2 -0
  21. package/dist/strapi/providers/index.js.map +1 -1
  22. package/dist/strapi/providers/index.mjs +1 -0
  23. package/dist/strapi/providers/index.mjs.map +1 -1
  24. package/dist/strapi/providers/local-destination/assets-destination-writable.d.ts +22 -0
  25. package/dist/strapi/providers/local-destination/assets-destination-writable.d.ts.map +1 -0
  26. package/dist/strapi/providers/local-destination/assets-destination-writable.js +107 -0
  27. package/dist/strapi/providers/local-destination/assets-destination-writable.js.map +1 -0
  28. package/dist/strapi/providers/local-destination/assets-destination-writable.mjs +105 -0
  29. package/dist/strapi/providers/local-destination/assets-destination-writable.mjs.map +1 -0
  30. package/dist/strapi/providers/local-destination/index.d.ts +2 -0
  31. package/dist/strapi/providers/local-destination/index.d.ts.map +1 -1
  32. package/dist/strapi/providers/local-destination/index.js +18 -79
  33. package/dist/strapi/providers/local-destination/index.js.map +1 -1
  34. package/dist/strapi/providers/local-destination/index.mjs +18 -79
  35. package/dist/strapi/providers/local-destination/index.mjs.map +1 -1
  36. package/dist/strapi/providers/local-destination/strategies/restore/entities.js +2 -0
  37. package/dist/strapi/providers/local-destination/strategies/restore/entities.js.map +1 -1
  38. package/dist/strapi/providers/local-destination/strategies/restore/entities.mjs +2 -0
  39. package/dist/strapi/providers/local-destination/strategies/restore/entities.mjs.map +1 -1
  40. package/dist/strapi/providers/local-destination/strategies/restore/index.js +2 -0
  41. package/dist/strapi/providers/local-destination/strategies/restore/index.js.map +1 -1
  42. package/dist/strapi/providers/local-destination/strategies/restore/index.mjs +2 -0
  43. package/dist/strapi/providers/local-destination/strategies/restore/index.mjs.map +1 -1
  44. package/dist/strapi/providers/local-source/assets.d.ts +8 -1
  45. package/dist/strapi/providers/local-source/assets.d.ts.map +1 -1
  46. package/dist/strapi/providers/local-source/assets.js +47 -19
  47. package/dist/strapi/providers/local-source/assets.js.map +1 -1
  48. package/dist/strapi/providers/local-source/assets.mjs +46 -20
  49. package/dist/strapi/providers/local-source/assets.mjs.map +1 -1
  50. package/dist/strapi/providers/local-source/estimate-asset-totals.d.ts +11 -0
  51. package/dist/strapi/providers/local-source/estimate-asset-totals.d.ts.map +1 -0
  52. package/dist/strapi/providers/local-source/estimate-asset-totals.js +130 -0
  53. package/dist/strapi/providers/local-source/estimate-asset-totals.js.map +1 -0
  54. package/dist/strapi/providers/local-source/estimate-asset-totals.mjs +128 -0
  55. package/dist/strapi/providers/local-source/estimate-asset-totals.mjs.map +1 -0
  56. package/dist/strapi/providers/local-source/index.d.ts +3 -2
  57. package/dist/strapi/providers/local-source/index.d.ts.map +1 -1
  58. package/dist/strapi/providers/local-source/index.js +30 -3
  59. package/dist/strapi/providers/local-source/index.js.map +1 -1
  60. package/dist/strapi/providers/local-source/index.mjs +30 -4
  61. package/dist/strapi/providers/local-source/index.mjs.map +1 -1
  62. package/dist/strapi/providers/remote-destination/index.d.ts +3 -1
  63. package/dist/strapi/providers/remote-destination/index.d.ts.map +1 -1
  64. package/dist/strapi/providers/remote-destination/index.js +88 -19
  65. package/dist/strapi/providers/remote-destination/index.js.map +1 -1
  66. package/dist/strapi/providers/remote-destination/index.mjs +89 -20
  67. package/dist/strapi/providers/remote-destination/index.mjs.map +1 -1
  68. package/dist/strapi/providers/remote-source/index.d.ts +6 -3
  69. package/dist/strapi/providers/remote-source/index.d.ts.map +1 -1
  70. package/dist/strapi/providers/remote-source/index.js +180 -47
  71. package/dist/strapi/providers/remote-source/index.js.map +1 -1
  72. package/dist/strapi/providers/remote-source/index.mjs +181 -48
  73. package/dist/strapi/providers/remote-source/index.mjs.map +1 -1
  74. package/dist/strapi/providers/utils.d.ts +9 -6
  75. package/dist/strapi/providers/utils.d.ts.map +1 -1
  76. package/dist/strapi/providers/utils.js +9 -4
  77. package/dist/strapi/providers/utils.js.map +1 -1
  78. package/dist/strapi/providers/utils.mjs +9 -4
  79. package/dist/strapi/providers/utils.mjs.map +1 -1
  80. package/dist/strapi/remote/handlers/pull.d.ts +1 -0
  81. package/dist/strapi/remote/handlers/pull.d.ts.map +1 -1
  82. package/dist/strapi/remote/handlers/pull.js +36 -15
  83. package/dist/strapi/remote/handlers/pull.js.map +1 -1
  84. package/dist/strapi/remote/handlers/pull.mjs +37 -16
  85. package/dist/strapi/remote/handlers/pull.mjs.map +1 -1
  86. package/dist/strapi/remote/handlers/push.d.ts +13 -2
  87. package/dist/strapi/remote/handlers/push.d.ts.map +1 -1
  88. package/dist/strapi/remote/handlers/push.js +81 -34
  89. package/dist/strapi/remote/handlers/push.js.map +1 -1
  90. package/dist/strapi/remote/handlers/push.mjs +82 -35
  91. package/dist/strapi/remote/handlers/push.mjs.map +1 -1
  92. package/dist/strapi/remote/handlers/utils.d.ts.map +1 -1
  93. package/dist/strapi/remote/handlers/utils.js +5 -3
  94. package/dist/strapi/remote/handlers/utils.js.map +1 -1
  95. package/dist/strapi/remote/handlers/utils.mjs +5 -3
  96. package/dist/strapi/remote/handlers/utils.mjs.map +1 -1
  97. package/dist/utils/index.d.ts +2 -0
  98. package/dist/utils/index.d.ts.map +1 -1
  99. package/dist/utils/index.js +7 -0
  100. package/dist/utils/index.js.map +1 -1
  101. package/dist/utils/index.mjs +2 -0
  102. package/dist/utils/index.mjs.map +1 -1
  103. package/dist/utils/stream.d.ts.map +1 -1
  104. package/dist/utils/stream.js +40 -3
  105. package/dist/utils/stream.js.map +1 -1
  106. package/dist/utils/stream.mjs +40 -3
  107. package/dist/utils/stream.mjs.map +1 -1
  108. package/dist/utils/transfer-asset-chunk.d.ts +41 -0
  109. package/dist/utils/transfer-asset-chunk.d.ts.map +1 -0
  110. package/dist/utils/transfer-asset-chunk.js +93 -0
  111. package/dist/utils/transfer-asset-chunk.js.map +1 -0
  112. package/dist/utils/transfer-asset-chunk.mjs +88 -0
  113. package/dist/utils/transfer-asset-chunk.mjs.map +1 -0
  114. package/dist/utils/transfer-websocket-json.d.ts +24 -0
  115. package/dist/utils/transfer-websocket-json.d.ts.map +1 -0
  116. package/dist/utils/transfer-websocket-json.js +67 -0
  117. package/dist/utils/transfer-websocket-json.js.map +1 -0
  118. package/dist/utils/transfer-websocket-json.mjs +63 -0
  119. package/dist/utils/transfer-websocket-json.mjs.map +1 -0
  120. package/dist/utils/writable-async-write.d.ts +17 -0
  121. package/dist/utils/writable-async-write.d.ts.map +1 -0
  122. package/dist/utils/writable-async-write.js +61 -0
  123. package/dist/utils/writable-async-write.js.map +1 -0
  124. package/dist/utils/writable-async-write.mjs +59 -0
  125. package/dist/utils/writable-async-write.mjs.map +1 -0
  126. package/package.json +6 -6
@@ -0,0 +1,93 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Canonical **outbound** asset chunk for WebSocket JSON (push and pull).
5
+ * Base64 string `data` keeps `JSON.parse` heap bounded vs `{ type: 'Buffer', data: [n,…] }`.
6
+ */ function createTransferAssetStreamChunk(assetID, chunk) {
7
+ if (chunk == null) {
8
+ throw new TypeError('Asset stream yielded a null/undefined chunk; refusing to encode (would trigger Buffer.from(undefined))');
9
+ }
10
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
11
+ return {
12
+ action: 'stream',
13
+ assetID,
14
+ encoding: 'base64',
15
+ data: buffer.toString('base64')
16
+ };
17
+ }
18
+ /**
19
+ * Decode a stream item from `TransferAssetFlow` after `JSON.parse` (shared by push + pull handlers
20
+ * and the remote source provider).
21
+ */ function decodeTransferAssetStreamItem(item) {
22
+ return decodeTransferAssetStreamData(item.data, item.encoding === 'base64' ? 'base64' : undefined);
23
+ }
24
+ const getLegacyBufferJsonData = (value)=>{
25
+ if (!value || typeof value !== 'object' || !('type' in value)) {
26
+ return null;
27
+ }
28
+ if (value.type !== 'Buffer') {
29
+ return null;
30
+ }
31
+ const raw = value.data;
32
+ if (Array.isArray(raw) || ArrayBuffer.isView(raw)) {
33
+ return raw;
34
+ }
35
+ return null;
36
+ };
37
+ /**
38
+ * Decode binary payload for `TransferAssetFlow` `action: 'stream'` after JSON.parse.
39
+ *
40
+ * Supported shapes (receivers should accept all of these):
41
+ * - **String `data`:** preferred wire form (`createTransferAssetStreamChunk` / `encoding: 'base64'`).
42
+ * - **`{ type: 'Buffer', data: number[] | TypedArray }`:** legacy `Buffer.toJSON()` from default
43
+ * `JSON.stringify` (older clients/servers).
44
+ * - **`Buffer` instance:** in-process only.
45
+ *
46
+ * Note: Node’s `JSON.stringify` runs `Buffer.toJSON()` before any replacer, so nested `Buffer`
47
+ * values become the legacy object unless you pass a string (use `createTransferAssetStreamChunk`).
48
+ */ function decodeTransferAssetStreamData(data, encoding) {
49
+ if (encoding === 'base64' && typeof data === 'string') {
50
+ return Buffer.from(data, 'base64');
51
+ }
52
+ // `encoding: 'base64'` with a non-string payload (or no encoding) uses the same fallbacks as
53
+ // legacy peers — avoids throwing when flags and payload disagree.
54
+ if (Buffer.isBuffer(data)) {
55
+ return Buffer.from(data);
56
+ }
57
+ const legacyBufferData = getLegacyBufferJsonData(data);
58
+ if (legacyBufferData) {
59
+ return Buffer.from(legacyBufferData);
60
+ }
61
+ // Wire base64 string (pull generator and any other path that stringifies a string payload).
62
+ if (typeof data === 'string') {
63
+ return Buffer.from(data, 'base64');
64
+ }
65
+ throw new TypeError('Invalid transfer asset stream chunk payload');
66
+ }
67
+ /** Approximate decoded byte size for batching (pull asset generator). */ function transferAssetStreamChunkByteLength(chunk) {
68
+ if (chunk.action !== 'stream') {
69
+ return 0;
70
+ }
71
+ if (typeof chunk.data === 'string') {
72
+ return Math.floor(chunk.data.length * 3 / 4);
73
+ }
74
+ if (Buffer.isBuffer(chunk.data)) {
75
+ return chunk.data.byteLength;
76
+ }
77
+ const legacyBufferData = getLegacyBufferJsonData(chunk.data);
78
+ if (legacyBufferData) {
79
+ if (Array.isArray(legacyBufferData)) {
80
+ return legacyBufferData.length;
81
+ }
82
+ if (ArrayBuffer.isView(legacyBufferData)) {
83
+ return legacyBufferData.byteLength;
84
+ }
85
+ }
86
+ return 0;
87
+ }
88
+
89
+ exports.createTransferAssetStreamChunk = createTransferAssetStreamChunk;
90
+ exports.decodeTransferAssetStreamData = decodeTransferAssetStreamData;
91
+ exports.decodeTransferAssetStreamItem = decodeTransferAssetStreamItem;
92
+ exports.transferAssetStreamChunkByteLength = transferAssetStreamChunkByteLength;
93
+ //# sourceMappingURL=transfer-asset-chunk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer-asset-chunk.js","sources":["../../src/utils/transfer-asset-chunk.ts"],"sourcesContent":["/**\n * Canonical **outbound** asset chunk for WebSocket JSON (push and pull).\n * Base64 string `data` keeps `JSON.parse` heap bounded vs `{ type: 'Buffer', data: [n,…] }`.\n */\nexport function createTransferAssetStreamChunk(\n assetID: string,\n chunk: Buffer | Uint8Array\n): { action: 'stream'; assetID: string; encoding: 'base64'; data: string } {\n if (chunk == null) {\n throw new TypeError(\n 'Asset stream yielded a null/undefined chunk; refusing to encode (would trigger Buffer.from(undefined))'\n );\n }\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n return {\n action: 'stream',\n assetID,\n encoding: 'base64',\n data: buffer.toString('base64'),\n };\n}\n\n/**\n * Decode a stream item from `TransferAssetFlow` after `JSON.parse` (shared by push + pull handlers\n * and the remote source provider).\n */\nexport function decodeTransferAssetStreamItem(item: {\n action: 'stream';\n data: unknown;\n encoding?: 'base64';\n}): Buffer {\n return decodeTransferAssetStreamData(\n item.data,\n item.encoding === 'base64' ? 'base64' : undefined\n );\n}\n\nconst getLegacyBufferJsonData = (value: unknown): Uint8Array | readonly number[] | null => {\n if (!value || typeof value !== 'object' || !('type' in value)) {\n return null;\n }\n if ((value as { type: unknown }).type !== 'Buffer') {\n return null;\n }\n const raw = (value as { data?: unknown }).data;\n if (Array.isArray(raw) || ArrayBuffer.isView(raw)) {\n return raw as Uint8Array | readonly number[];\n }\n return null;\n};\n\n/**\n * Decode binary payload for `TransferAssetFlow` `action: 'stream'` after JSON.parse.\n *\n * Supported shapes (receivers should accept all of these):\n * - **String `data`:** preferred wire form (`createTransferAssetStreamChunk` / `encoding: 'base64'`).\n * - **`{ type: 'Buffer', data: number[] | TypedArray }`:** legacy `Buffer.toJSON()` from default\n * `JSON.stringify` (older clients/servers).\n * - **`Buffer` instance:** in-process only.\n *\n * Note: Node’s `JSON.stringify` runs `Buffer.toJSON()` before any replacer, so nested `Buffer`\n * values become the legacy object unless you pass a string (use `createTransferAssetStreamChunk`).\n */\nexport function decodeTransferAssetStreamData(data: unknown, encoding?: 'base64'): Buffer {\n if (encoding === 'base64' && typeof data === 'string') {\n return Buffer.from(data, 'base64');\n }\n // `encoding: 'base64'` with a non-string payload (or no encoding) uses the same fallbacks as\n // legacy peers — avoids throwing when flags and payload disagree.\n\n if (Buffer.isBuffer(data)) {\n return Buffer.from(data);\n }\n\n const legacyBufferData = getLegacyBufferJsonData(data);\n if (legacyBufferData) {\n return Buffer.from(legacyBufferData);\n }\n\n // Wire base64 string (pull generator and any other path that stringifies a string payload).\n if (typeof data === 'string') {\n return Buffer.from(data, 'base64');\n }\n\n throw new TypeError('Invalid transfer asset stream chunk payload');\n}\n\n/** Approximate decoded byte size for batching (pull asset generator). */\nexport function transferAssetStreamChunkByteLength(chunk: {\n action: string;\n data?: unknown;\n encoding?: 'base64';\n}): number {\n if (chunk.action !== 'stream') {\n return 0;\n }\n if (typeof chunk.data === 'string') {\n return Math.floor((chunk.data.length * 3) / 4);\n }\n if (Buffer.isBuffer(chunk.data)) {\n return chunk.data.byteLength;\n }\n\n const legacyBufferData = getLegacyBufferJsonData(chunk.data);\n if (legacyBufferData) {\n if (Array.isArray(legacyBufferData)) {\n return legacyBufferData.length;\n }\n if (ArrayBuffer.isView(legacyBufferData)) {\n return legacyBufferData.byteLength;\n }\n }\n return 0;\n}\n"],"names":["createTransferAssetStreamChunk","assetID","chunk","TypeError","buffer","Buffer","isBuffer","from","action","encoding","data","toString","decodeTransferAssetStreamItem","item","decodeTransferAssetStreamData","undefined","getLegacyBufferJsonData","value","type","raw","Array","isArray","ArrayBuffer","isView","legacyBufferData","transferAssetStreamChunkByteLength","Math","floor","length","byteLength"],"mappings":"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"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Canonical **outbound** asset chunk for WebSocket JSON (push and pull).
3
+ * Base64 string `data` keeps `JSON.parse` heap bounded vs `{ type: 'Buffer', data: [n,…] }`.
4
+ */ function createTransferAssetStreamChunk(assetID, chunk) {
5
+ if (chunk == null) {
6
+ throw new TypeError('Asset stream yielded a null/undefined chunk; refusing to encode (would trigger Buffer.from(undefined))');
7
+ }
8
+ const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
9
+ return {
10
+ action: 'stream',
11
+ assetID,
12
+ encoding: 'base64',
13
+ data: buffer.toString('base64')
14
+ };
15
+ }
16
+ /**
17
+ * Decode a stream item from `TransferAssetFlow` after `JSON.parse` (shared by push + pull handlers
18
+ * and the remote source provider).
19
+ */ function decodeTransferAssetStreamItem(item) {
20
+ return decodeTransferAssetStreamData(item.data, item.encoding === 'base64' ? 'base64' : undefined);
21
+ }
22
+ const getLegacyBufferJsonData = (value)=>{
23
+ if (!value || typeof value !== 'object' || !('type' in value)) {
24
+ return null;
25
+ }
26
+ if (value.type !== 'Buffer') {
27
+ return null;
28
+ }
29
+ const raw = value.data;
30
+ if (Array.isArray(raw) || ArrayBuffer.isView(raw)) {
31
+ return raw;
32
+ }
33
+ return null;
34
+ };
35
+ /**
36
+ * Decode binary payload for `TransferAssetFlow` `action: 'stream'` after JSON.parse.
37
+ *
38
+ * Supported shapes (receivers should accept all of these):
39
+ * - **String `data`:** preferred wire form (`createTransferAssetStreamChunk` / `encoding: 'base64'`).
40
+ * - **`{ type: 'Buffer', data: number[] | TypedArray }`:** legacy `Buffer.toJSON()` from default
41
+ * `JSON.stringify` (older clients/servers).
42
+ * - **`Buffer` instance:** in-process only.
43
+ *
44
+ * Note: Node’s `JSON.stringify` runs `Buffer.toJSON()` before any replacer, so nested `Buffer`
45
+ * values become the legacy object unless you pass a string (use `createTransferAssetStreamChunk`).
46
+ */ function decodeTransferAssetStreamData(data, encoding) {
47
+ if (encoding === 'base64' && typeof data === 'string') {
48
+ return Buffer.from(data, 'base64');
49
+ }
50
+ // `encoding: 'base64'` with a non-string payload (or no encoding) uses the same fallbacks as
51
+ // legacy peers — avoids throwing when flags and payload disagree.
52
+ if (Buffer.isBuffer(data)) {
53
+ return Buffer.from(data);
54
+ }
55
+ const legacyBufferData = getLegacyBufferJsonData(data);
56
+ if (legacyBufferData) {
57
+ return Buffer.from(legacyBufferData);
58
+ }
59
+ // Wire base64 string (pull generator and any other path that stringifies a string payload).
60
+ if (typeof data === 'string') {
61
+ return Buffer.from(data, 'base64');
62
+ }
63
+ throw new TypeError('Invalid transfer asset stream chunk payload');
64
+ }
65
+ /** Approximate decoded byte size for batching (pull asset generator). */ function transferAssetStreamChunkByteLength(chunk) {
66
+ if (chunk.action !== 'stream') {
67
+ return 0;
68
+ }
69
+ if (typeof chunk.data === 'string') {
70
+ return Math.floor(chunk.data.length * 3 / 4);
71
+ }
72
+ if (Buffer.isBuffer(chunk.data)) {
73
+ return chunk.data.byteLength;
74
+ }
75
+ const legacyBufferData = getLegacyBufferJsonData(chunk.data);
76
+ if (legacyBufferData) {
77
+ if (Array.isArray(legacyBufferData)) {
78
+ return legacyBufferData.length;
79
+ }
80
+ if (ArrayBuffer.isView(legacyBufferData)) {
81
+ return legacyBufferData.byteLength;
82
+ }
83
+ }
84
+ return 0;
85
+ }
86
+
87
+ export { createTransferAssetStreamChunk, decodeTransferAssetStreamData, decodeTransferAssetStreamItem, transferAssetStreamChunkByteLength };
88
+ //# sourceMappingURL=transfer-asset-chunk.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer-asset-chunk.mjs","sources":["../../src/utils/transfer-asset-chunk.ts"],"sourcesContent":["/**\n * Canonical **outbound** asset chunk for WebSocket JSON (push and pull).\n * Base64 string `data` keeps `JSON.parse` heap bounded vs `{ type: 'Buffer', data: [n,…] }`.\n */\nexport function createTransferAssetStreamChunk(\n assetID: string,\n chunk: Buffer | Uint8Array\n): { action: 'stream'; assetID: string; encoding: 'base64'; data: string } {\n if (chunk == null) {\n throw new TypeError(\n 'Asset stream yielded a null/undefined chunk; refusing to encode (would trigger Buffer.from(undefined))'\n );\n }\n const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);\n return {\n action: 'stream',\n assetID,\n encoding: 'base64',\n data: buffer.toString('base64'),\n };\n}\n\n/**\n * Decode a stream item from `TransferAssetFlow` after `JSON.parse` (shared by push + pull handlers\n * and the remote source provider).\n */\nexport function decodeTransferAssetStreamItem(item: {\n action: 'stream';\n data: unknown;\n encoding?: 'base64';\n}): Buffer {\n return decodeTransferAssetStreamData(\n item.data,\n item.encoding === 'base64' ? 'base64' : undefined\n );\n}\n\nconst getLegacyBufferJsonData = (value: unknown): Uint8Array | readonly number[] | null => {\n if (!value || typeof value !== 'object' || !('type' in value)) {\n return null;\n }\n if ((value as { type: unknown }).type !== 'Buffer') {\n return null;\n }\n const raw = (value as { data?: unknown }).data;\n if (Array.isArray(raw) || ArrayBuffer.isView(raw)) {\n return raw as Uint8Array | readonly number[];\n }\n return null;\n};\n\n/**\n * Decode binary payload for `TransferAssetFlow` `action: 'stream'` after JSON.parse.\n *\n * Supported shapes (receivers should accept all of these):\n * - **String `data`:** preferred wire form (`createTransferAssetStreamChunk` / `encoding: 'base64'`).\n * - **`{ type: 'Buffer', data: number[] | TypedArray }`:** legacy `Buffer.toJSON()` from default\n * `JSON.stringify` (older clients/servers).\n * - **`Buffer` instance:** in-process only.\n *\n * Note: Node’s `JSON.stringify` runs `Buffer.toJSON()` before any replacer, so nested `Buffer`\n * values become the legacy object unless you pass a string (use `createTransferAssetStreamChunk`).\n */\nexport function decodeTransferAssetStreamData(data: unknown, encoding?: 'base64'): Buffer {\n if (encoding === 'base64' && typeof data === 'string') {\n return Buffer.from(data, 'base64');\n }\n // `encoding: 'base64'` with a non-string payload (or no encoding) uses the same fallbacks as\n // legacy peers — avoids throwing when flags and payload disagree.\n\n if (Buffer.isBuffer(data)) {\n return Buffer.from(data);\n }\n\n const legacyBufferData = getLegacyBufferJsonData(data);\n if (legacyBufferData) {\n return Buffer.from(legacyBufferData);\n }\n\n // Wire base64 string (pull generator and any other path that stringifies a string payload).\n if (typeof data === 'string') {\n return Buffer.from(data, 'base64');\n }\n\n throw new TypeError('Invalid transfer asset stream chunk payload');\n}\n\n/** Approximate decoded byte size for batching (pull asset generator). */\nexport function transferAssetStreamChunkByteLength(chunk: {\n action: string;\n data?: unknown;\n encoding?: 'base64';\n}): number {\n if (chunk.action !== 'stream') {\n return 0;\n }\n if (typeof chunk.data === 'string') {\n return Math.floor((chunk.data.length * 3) / 4);\n }\n if (Buffer.isBuffer(chunk.data)) {\n return chunk.data.byteLength;\n }\n\n const legacyBufferData = getLegacyBufferJsonData(chunk.data);\n if (legacyBufferData) {\n if (Array.isArray(legacyBufferData)) {\n return legacyBufferData.length;\n }\n if (ArrayBuffer.isView(legacyBufferData)) {\n return legacyBufferData.byteLength;\n }\n }\n return 0;\n}\n"],"names":["createTransferAssetStreamChunk","assetID","chunk","TypeError","buffer","Buffer","isBuffer","from","action","encoding","data","toString","decodeTransferAssetStreamItem","item","decodeTransferAssetStreamData","undefined","getLegacyBufferJsonData","value","type","raw","Array","isArray","ArrayBuffer","isView","legacyBufferData","transferAssetStreamChunkByteLength","Math","floor","length","byteLength"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Shared `JSON.stringify` replacer for data-transfer WebSocket frames (push and pull).
3
+ *
4
+ * Default `JSON.stringify` uses `Buffer.toJSON()` → `{ type: 'Buffer', data: [n,n,...] }`, which
5
+ * allocates a large array on the peer during `JSON.parse`. Encode binary values as compact base64 strings instead.
6
+ *
7
+ * Note: Node runs `Buffer.prototype.toJSON` before the replacer sees a `Buffer` property, so the
8
+ * replacer receives `{ type: 'Buffer', data: [...] }` unless the value is already a string (see
9
+ * `createTransferAssetStreamChunk` in `transfer-asset-chunk.ts`).
10
+ */
11
+ export declare const replacerForTransferWebSocket: (_key: string, value: unknown) => unknown;
12
+ /**
13
+ * `JSON.stringify` invokes an own enumerable `toJSON` on the root value before replacers run. If that
14
+ * method returns `undefined`, the whole `JSON.stringify` result is `undefined`, and `ws.send(undefined)`
15
+ * throws ("The first argument must be of type string or an instance of Buffer... Received undefined").
16
+ * Spreading transfer messages (`{ ...message, uuid }`) can copy an enumerable `toJSON` from user / ORM
17
+ * objects onto the wire payload — strip it on the root object we control.
18
+ */
19
+ export declare function stripRootToJSONMethod(payload: Record<string, unknown>): void;
20
+ /**
21
+ * Serialize a transfer WebSocket envelope. Never returns `undefined` (unlike raw `JSON.stringify`).
22
+ */
23
+ export declare function stringifyTransferWebSocketPayload(payload: Record<string, unknown>): string;
24
+ //# sourceMappingURL=transfer-websocket-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer-websocket-json.d.ts","sourceRoot":"","sources":["../../src/utils/transfer-websocket-json.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,eAAO,MAAM,4BAA4B,SAAU,MAAM,SAAS,OAAO,KAAG,OA4B3E,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAI5E;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAe1F"}
@@ -0,0 +1,67 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Shared `JSON.stringify` replacer for data-transfer WebSocket frames (push and pull).
5
+ *
6
+ * Default `JSON.stringify` uses `Buffer.toJSON()` → `{ type: 'Buffer', data: [n,n,...] }`, which
7
+ * allocates a large array on the peer during `JSON.parse`. Encode binary values as compact base64 strings instead.
8
+ *
9
+ * Note: Node runs `Buffer.prototype.toJSON` before the replacer sees a `Buffer` property, so the
10
+ * replacer receives `{ type: 'Buffer', data: [...] }` unless the value is already a string (see
11
+ * `createTransferAssetStreamChunk` in `transfer-asset-chunk.ts`).
12
+ */ const replacerForTransferWebSocket = (_key, value)=>{
13
+ /** `JSON.stringify` throws on bigint; upload metadata or ORM fields may surface as BigInt. */ if (typeof value === 'bigint') {
14
+ return value.toString();
15
+ }
16
+ if (Buffer.isBuffer(value)) {
17
+ return value.toString('base64');
18
+ }
19
+ if (value instanceof Uint8Array) {
20
+ const { buffer, byteOffset, byteLength } = value;
21
+ if (buffer == null) {
22
+ throw new TypeError('Invalid Uint8Array in transfer payload (missing underlying ArrayBuffer); cannot encode for WebSocket');
23
+ }
24
+ return Buffer.from(buffer, byteOffset, byteLength).toString('base64');
25
+ }
26
+ if (ArrayBuffer.isView(value) && !(value instanceof DataView)) {
27
+ const v = value;
28
+ const { buffer, byteOffset, byteLength } = v;
29
+ if (buffer == null) {
30
+ throw new TypeError('Invalid typed array in transfer payload (missing underlying ArrayBuffer); cannot encode for WebSocket');
31
+ }
32
+ return Buffer.from(buffer, byteOffset, byteLength).toString('base64');
33
+ }
34
+ return value;
35
+ };
36
+ /**
37
+ * `JSON.stringify` invokes an own enumerable `toJSON` on the root value before replacers run. If that
38
+ * method returns `undefined`, the whole `JSON.stringify` result is `undefined`, and `ws.send(undefined)`
39
+ * throws ("The first argument must be of type string or an instance of Buffer... Received undefined").
40
+ * Spreading transfer messages (`{ ...message, uuid }`) can copy an enumerable `toJSON` from user / ORM
41
+ * objects onto the wire payload — strip it on the root object we control.
42
+ */ function stripRootToJSONMethod(payload) {
43
+ if (typeof payload.toJSON === 'function') {
44
+ delete payload.toJSON;
45
+ }
46
+ }
47
+ /**
48
+ * Serialize a transfer WebSocket envelope. Never returns `undefined` (unlike raw `JSON.stringify`).
49
+ */ function stringifyTransferWebSocketPayload(payload) {
50
+ stripRootToJSONMethod(payload);
51
+ let s;
52
+ try {
53
+ s = JSON.stringify(payload, replacerForTransferWebSocket);
54
+ } catch (err) {
55
+ const message = err instanceof Error ? err.message : String(err);
56
+ throw new TypeError(`Transfer WebSocket payload could not be serialized to JSON: ${message}`);
57
+ }
58
+ if (typeof s !== 'string') {
59
+ throw new TypeError('Transfer WebSocket payload could not be serialized to JSON (result was undefined). Check for Symbol or other non-JSON values on the root payload.');
60
+ }
61
+ return s;
62
+ }
63
+
64
+ exports.replacerForTransferWebSocket = replacerForTransferWebSocket;
65
+ exports.stringifyTransferWebSocketPayload = stringifyTransferWebSocketPayload;
66
+ exports.stripRootToJSONMethod = stripRootToJSONMethod;
67
+ //# sourceMappingURL=transfer-websocket-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer-websocket-json.js","sources":["../../src/utils/transfer-websocket-json.ts"],"sourcesContent":["/**\n * Shared `JSON.stringify` replacer for data-transfer WebSocket frames (push and pull).\n *\n * Default `JSON.stringify` uses `Buffer.toJSON()` → `{ type: 'Buffer', data: [n,n,...] }`, which\n * allocates a large array on the peer during `JSON.parse`. Encode binary values as compact base64 strings instead.\n *\n * Note: Node runs `Buffer.prototype.toJSON` before the replacer sees a `Buffer` property, so the\n * replacer receives `{ type: 'Buffer', data: [...] }` unless the value is already a string (see\n * `createTransferAssetStreamChunk` in `transfer-asset-chunk.ts`).\n */\nexport const replacerForTransferWebSocket = (_key: string, value: unknown): unknown => {\n /** `JSON.stringify` throws on bigint; upload metadata or ORM fields may surface as BigInt. */\n if (typeof value === 'bigint') {\n return value.toString();\n }\n if (Buffer.isBuffer(value)) {\n return value.toString('base64');\n }\n if (value instanceof Uint8Array) {\n const { buffer, byteOffset, byteLength } = value;\n if (buffer == null) {\n throw new TypeError(\n 'Invalid Uint8Array in transfer payload (missing underlying ArrayBuffer); cannot encode for WebSocket'\n );\n }\n return Buffer.from(buffer, byteOffset, byteLength).toString('base64');\n }\n if (ArrayBuffer.isView(value) && !(value instanceof DataView)) {\n const v = value as NodeJS.TypedArray;\n const { buffer, byteOffset, byteLength } = v;\n if (buffer == null) {\n throw new TypeError(\n 'Invalid typed array in transfer payload (missing underlying ArrayBuffer); cannot encode for WebSocket'\n );\n }\n return Buffer.from(buffer, byteOffset, byteLength).toString('base64');\n }\n return value;\n};\n\n/**\n * `JSON.stringify` invokes an own enumerable `toJSON` on the root value before replacers run. If that\n * method returns `undefined`, the whole `JSON.stringify` result is `undefined`, and `ws.send(undefined)`\n * throws (\"The first argument must be of type string or an instance of Buffer... Received undefined\").\n * Spreading transfer messages (`{ ...message, uuid }`) can copy an enumerable `toJSON` from user / ORM\n * objects onto the wire payload — strip it on the root object we control.\n */\nexport function stripRootToJSONMethod(payload: Record<string, unknown>): void {\n if (typeof payload.toJSON === 'function') {\n delete payload.toJSON;\n }\n}\n\n/**\n * Serialize a transfer WebSocket envelope. Never returns `undefined` (unlike raw `JSON.stringify`).\n */\nexport function stringifyTransferWebSocketPayload(payload: Record<string, unknown>): string {\n stripRootToJSONMethod(payload);\n let s: string | undefined;\n try {\n s = JSON.stringify(payload, replacerForTransferWebSocket);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new TypeError(`Transfer WebSocket payload could not be serialized to JSON: ${message}`);\n }\n if (typeof s !== 'string') {\n throw new TypeError(\n 'Transfer WebSocket payload could not be serialized to JSON (result was undefined). Check for Symbol or other non-JSON values on the root payload.'\n );\n }\n return s;\n}\n"],"names":["replacerForTransferWebSocket","_key","value","toString","Buffer","isBuffer","Uint8Array","buffer","byteOffset","byteLength","TypeError","from","ArrayBuffer","isView","DataView","v","stripRootToJSONMethod","payload","toJSON","stringifyTransferWebSocketPayload","s","JSON","stringify","err","message","Error","String"],"mappings":";;AAAA;;;;;;;;;AASC,IACM,MAAMA,4BAAAA,GAA+B,CAACC,IAAAA,EAAcC,KAAAA,GAAAA;AACzD,mGACA,IAAI,OAAOA,KAAAA,KAAU,QAAA,EAAU;AAC7B,QAAA,OAAOA,MAAMC,QAAQ,EAAA;AACvB,IAAA;IACA,IAAIC,MAAAA,CAAOC,QAAQ,CAACH,KAAAA,CAAAA,EAAQ;QAC1B,OAAOA,KAAAA,CAAMC,QAAQ,CAAC,QAAA,CAAA;AACxB,IAAA;AACA,IAAA,IAAID,iBAAiBI,UAAAA,EAAY;AAC/B,QAAA,MAAM,EAAEC,MAAM,EAAEC,UAAU,EAAEC,UAAU,EAAE,GAAGP,KAAAA;AAC3C,QAAA,IAAIK,UAAU,IAAA,EAAM;AAClB,YAAA,MAAM,IAAIG,SAAAA,CACR,sGAAA,CAAA;AAEJ,QAAA;AACA,QAAA,OAAON,OAAOO,IAAI,CAACJ,QAAQC,UAAAA,EAAYC,UAAAA,CAAAA,CAAYN,QAAQ,CAAC,QAAA,CAAA;AAC9D,IAAA;IACA,IAAIS,WAAAA,CAAYC,MAAM,CAACX,KAAAA,CAAAA,IAAU,EAAEA,KAAAA,YAAiBY,QAAO,CAAA,EAAI;AAC7D,QAAA,MAAMC,CAAAA,GAAIb,KAAAA;AACV,QAAA,MAAM,EAAEK,MAAM,EAAEC,UAAU,EAAEC,UAAU,EAAE,GAAGM,CAAAA;AAC3C,QAAA,IAAIR,UAAU,IAAA,EAAM;AAClB,YAAA,MAAM,IAAIG,SAAAA,CACR,uGAAA,CAAA;AAEJ,QAAA;AACA,QAAA,OAAON,OAAOO,IAAI,CAACJ,QAAQC,UAAAA,EAAYC,UAAAA,CAAAA,CAAYN,QAAQ,CAAC,QAAA,CAAA;AAC9D,IAAA;IACA,OAAOD,KAAAA;AACT;AAEA;;;;;;IAOO,SAASc,qBAAAA,CAAsBC,OAAgC,EAAA;AACpE,IAAA,IAAI,OAAOA,OAAAA,CAAQC,MAAM,KAAK,UAAA,EAAY;AACxC,QAAA,OAAOD,QAAQC,MAAM;AACvB,IAAA;AACF;AAEA;;IAGO,SAASC,iCAAAA,CAAkCF,OAAgC,EAAA;IAChFD,qBAAAA,CAAsBC,OAAAA,CAAAA;IACtB,IAAIG,CAAAA;IACJ,IAAI;QACFA,CAAAA,GAAIC,IAAAA,CAAKC,SAAS,CAACL,OAAAA,EAASjB,4BAAAA,CAAAA;AAC9B,IAAA,CAAA,CAAE,OAAOuB,GAAAA,EAAK;AACZ,QAAA,MAAMC,UAAUD,GAAAA,YAAeE,KAAAA,GAAQF,GAAAA,CAAIC,OAAO,GAAGE,MAAAA,CAAOH,GAAAA,CAAAA;AAC5D,QAAA,MAAM,IAAIb,SAAAA,CAAU,CAAC,4DAA4D,EAAEc,OAAAA,CAAAA,CAAS,CAAA;AAC9F,IAAA;IACA,IAAI,OAAOJ,MAAM,QAAA,EAAU;AACzB,QAAA,MAAM,IAAIV,SAAAA,CACR,mJAAA,CAAA;AAEJ,IAAA;IACA,OAAOU,CAAAA;AACT;;;;;;"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Shared `JSON.stringify` replacer for data-transfer WebSocket frames (push and pull).
3
+ *
4
+ * Default `JSON.stringify` uses `Buffer.toJSON()` → `{ type: 'Buffer', data: [n,n,...] }`, which
5
+ * allocates a large array on the peer during `JSON.parse`. Encode binary values as compact base64 strings instead.
6
+ *
7
+ * Note: Node runs `Buffer.prototype.toJSON` before the replacer sees a `Buffer` property, so the
8
+ * replacer receives `{ type: 'Buffer', data: [...] }` unless the value is already a string (see
9
+ * `createTransferAssetStreamChunk` in `transfer-asset-chunk.ts`).
10
+ */ const replacerForTransferWebSocket = (_key, value)=>{
11
+ /** `JSON.stringify` throws on bigint; upload metadata or ORM fields may surface as BigInt. */ if (typeof value === 'bigint') {
12
+ return value.toString();
13
+ }
14
+ if (Buffer.isBuffer(value)) {
15
+ return value.toString('base64');
16
+ }
17
+ if (value instanceof Uint8Array) {
18
+ const { buffer, byteOffset, byteLength } = value;
19
+ if (buffer == null) {
20
+ throw new TypeError('Invalid Uint8Array in transfer payload (missing underlying ArrayBuffer); cannot encode for WebSocket');
21
+ }
22
+ return Buffer.from(buffer, byteOffset, byteLength).toString('base64');
23
+ }
24
+ if (ArrayBuffer.isView(value) && !(value instanceof DataView)) {
25
+ const v = value;
26
+ const { buffer, byteOffset, byteLength } = v;
27
+ if (buffer == null) {
28
+ throw new TypeError('Invalid typed array in transfer payload (missing underlying ArrayBuffer); cannot encode for WebSocket');
29
+ }
30
+ return Buffer.from(buffer, byteOffset, byteLength).toString('base64');
31
+ }
32
+ return value;
33
+ };
34
+ /**
35
+ * `JSON.stringify` invokes an own enumerable `toJSON` on the root value before replacers run. If that
36
+ * method returns `undefined`, the whole `JSON.stringify` result is `undefined`, and `ws.send(undefined)`
37
+ * throws ("The first argument must be of type string or an instance of Buffer... Received undefined").
38
+ * Spreading transfer messages (`{ ...message, uuid }`) can copy an enumerable `toJSON` from user / ORM
39
+ * objects onto the wire payload — strip it on the root object we control.
40
+ */ function stripRootToJSONMethod(payload) {
41
+ if (typeof payload.toJSON === 'function') {
42
+ delete payload.toJSON;
43
+ }
44
+ }
45
+ /**
46
+ * Serialize a transfer WebSocket envelope. Never returns `undefined` (unlike raw `JSON.stringify`).
47
+ */ function stringifyTransferWebSocketPayload(payload) {
48
+ stripRootToJSONMethod(payload);
49
+ let s;
50
+ try {
51
+ s = JSON.stringify(payload, replacerForTransferWebSocket);
52
+ } catch (err) {
53
+ const message = err instanceof Error ? err.message : String(err);
54
+ throw new TypeError(`Transfer WebSocket payload could not be serialized to JSON: ${message}`);
55
+ }
56
+ if (typeof s !== 'string') {
57
+ throw new TypeError('Transfer WebSocket payload could not be serialized to JSON (result was undefined). Check for Symbol or other non-JSON values on the root payload.');
58
+ }
59
+ return s;
60
+ }
61
+
62
+ export { replacerForTransferWebSocket, stringifyTransferWebSocketPayload, stripRootToJSONMethod };
63
+ //# sourceMappingURL=transfer-websocket-json.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transfer-websocket-json.mjs","sources":["../../src/utils/transfer-websocket-json.ts"],"sourcesContent":["/**\n * Shared `JSON.stringify` replacer for data-transfer WebSocket frames (push and pull).\n *\n * Default `JSON.stringify` uses `Buffer.toJSON()` → `{ type: 'Buffer', data: [n,n,...] }`, which\n * allocates a large array on the peer during `JSON.parse`. Encode binary values as compact base64 strings instead.\n *\n * Note: Node runs `Buffer.prototype.toJSON` before the replacer sees a `Buffer` property, so the\n * replacer receives `{ type: 'Buffer', data: [...] }` unless the value is already a string (see\n * `createTransferAssetStreamChunk` in `transfer-asset-chunk.ts`).\n */\nexport const replacerForTransferWebSocket = (_key: string, value: unknown): unknown => {\n /** `JSON.stringify` throws on bigint; upload metadata or ORM fields may surface as BigInt. */\n if (typeof value === 'bigint') {\n return value.toString();\n }\n if (Buffer.isBuffer(value)) {\n return value.toString('base64');\n }\n if (value instanceof Uint8Array) {\n const { buffer, byteOffset, byteLength } = value;\n if (buffer == null) {\n throw new TypeError(\n 'Invalid Uint8Array in transfer payload (missing underlying ArrayBuffer); cannot encode for WebSocket'\n );\n }\n return Buffer.from(buffer, byteOffset, byteLength).toString('base64');\n }\n if (ArrayBuffer.isView(value) && !(value instanceof DataView)) {\n const v = value as NodeJS.TypedArray;\n const { buffer, byteOffset, byteLength } = v;\n if (buffer == null) {\n throw new TypeError(\n 'Invalid typed array in transfer payload (missing underlying ArrayBuffer); cannot encode for WebSocket'\n );\n }\n return Buffer.from(buffer, byteOffset, byteLength).toString('base64');\n }\n return value;\n};\n\n/**\n * `JSON.stringify` invokes an own enumerable `toJSON` on the root value before replacers run. If that\n * method returns `undefined`, the whole `JSON.stringify` result is `undefined`, and `ws.send(undefined)`\n * throws (\"The first argument must be of type string or an instance of Buffer... Received undefined\").\n * Spreading transfer messages (`{ ...message, uuid }`) can copy an enumerable `toJSON` from user / ORM\n * objects onto the wire payload — strip it on the root object we control.\n */\nexport function stripRootToJSONMethod(payload: Record<string, unknown>): void {\n if (typeof payload.toJSON === 'function') {\n delete payload.toJSON;\n }\n}\n\n/**\n * Serialize a transfer WebSocket envelope. Never returns `undefined` (unlike raw `JSON.stringify`).\n */\nexport function stringifyTransferWebSocketPayload(payload: Record<string, unknown>): string {\n stripRootToJSONMethod(payload);\n let s: string | undefined;\n try {\n s = JSON.stringify(payload, replacerForTransferWebSocket);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n throw new TypeError(`Transfer WebSocket payload could not be serialized to JSON: ${message}`);\n }\n if (typeof s !== 'string') {\n throw new TypeError(\n 'Transfer WebSocket payload could not be serialized to JSON (result was undefined). Check for Symbol or other non-JSON values on the root payload.'\n );\n }\n return s;\n}\n"],"names":["replacerForTransferWebSocket","_key","value","toString","Buffer","isBuffer","Uint8Array","buffer","byteOffset","byteLength","TypeError","from","ArrayBuffer","isView","DataView","v","stripRootToJSONMethod","payload","toJSON","stringifyTransferWebSocketPayload","s","JSON","stringify","err","message","Error","String"],"mappings":"AAAA;;;;;;;;;AASC,IACM,MAAMA,4BAAAA,GAA+B,CAACC,IAAAA,EAAcC,KAAAA,GAAAA;AACzD,mGACA,IAAI,OAAOA,KAAAA,KAAU,QAAA,EAAU;AAC7B,QAAA,OAAOA,MAAMC,QAAQ,EAAA;AACvB,IAAA;IACA,IAAIC,MAAAA,CAAOC,QAAQ,CAACH,KAAAA,CAAAA,EAAQ;QAC1B,OAAOA,KAAAA,CAAMC,QAAQ,CAAC,QAAA,CAAA;AACxB,IAAA;AACA,IAAA,IAAID,iBAAiBI,UAAAA,EAAY;AAC/B,QAAA,MAAM,EAAEC,MAAM,EAAEC,UAAU,EAAEC,UAAU,EAAE,GAAGP,KAAAA;AAC3C,QAAA,IAAIK,UAAU,IAAA,EAAM;AAClB,YAAA,MAAM,IAAIG,SAAAA,CACR,sGAAA,CAAA;AAEJ,QAAA;AACA,QAAA,OAAON,OAAOO,IAAI,CAACJ,QAAQC,UAAAA,EAAYC,UAAAA,CAAAA,CAAYN,QAAQ,CAAC,QAAA,CAAA;AAC9D,IAAA;IACA,IAAIS,WAAAA,CAAYC,MAAM,CAACX,KAAAA,CAAAA,IAAU,EAAEA,KAAAA,YAAiBY,QAAO,CAAA,EAAI;AAC7D,QAAA,MAAMC,CAAAA,GAAIb,KAAAA;AACV,QAAA,MAAM,EAAEK,MAAM,EAAEC,UAAU,EAAEC,UAAU,EAAE,GAAGM,CAAAA;AAC3C,QAAA,IAAIR,UAAU,IAAA,EAAM;AAClB,YAAA,MAAM,IAAIG,SAAAA,CACR,uGAAA,CAAA;AAEJ,QAAA;AACA,QAAA,OAAON,OAAOO,IAAI,CAACJ,QAAQC,UAAAA,EAAYC,UAAAA,CAAAA,CAAYN,QAAQ,CAAC,QAAA,CAAA;AAC9D,IAAA;IACA,OAAOD,KAAAA;AACT;AAEA;;;;;;IAOO,SAASc,qBAAAA,CAAsBC,OAAgC,EAAA;AACpE,IAAA,IAAI,OAAOA,OAAAA,CAAQC,MAAM,KAAK,UAAA,EAAY;AACxC,QAAA,OAAOD,QAAQC,MAAM;AACvB,IAAA;AACF;AAEA;;IAGO,SAASC,iCAAAA,CAAkCF,OAAgC,EAAA;IAChFD,qBAAAA,CAAsBC,OAAAA,CAAAA;IACtB,IAAIG,CAAAA;IACJ,IAAI;QACFA,CAAAA,GAAIC,IAAAA,CAAKC,SAAS,CAACL,OAAAA,EAASjB,4BAAAA,CAAAA;AAC9B,IAAA,CAAA,CAAE,OAAOuB,GAAAA,EAAK;AACZ,QAAA,MAAMC,UAAUD,GAAAA,YAAeE,KAAAA,GAAQF,GAAAA,CAAIC,OAAO,GAAGE,MAAAA,CAAOH,GAAAA,CAAAA;AAC5D,QAAA,MAAM,IAAIb,SAAAA,CAAU,CAAC,4DAA4D,EAAEc,OAAAA,CAAAA,CAAS,CAAA;AAC9F,IAAA;IACA,IAAI,OAAOJ,MAAM,QAAA,EAAU;AACzB,QAAA,MAAM,IAAIV,SAAAA,CACR,mJAAA,CAAA;AAEJ,IAAA;IACA,OAAOU,CAAAA;AACT;;;;"}
@@ -0,0 +1,17 @@
1
+ /// <reference types="node" />
2
+ import type { Writable } from 'stream';
3
+ /**
4
+ * Async helper for application code that `await`s sequential writes to a `Writable`.
5
+ *
6
+ * 1. Waits until `writable.write` invokes its callback (chunk accepted / `_write` finished).
7
+ * 2. If `write()` returned `false` **and** `writable.writableNeedDrain` is still true after the
8
+ * callback, waits for `'drain'`.
9
+ *
10
+ * We check both: the return value tells us backpressure was signaled; `writableNeedDrain` avoids
11
+ * awaiting `'drain'` when it already fired before we subscribed (would otherwise hang forever).
12
+ *
13
+ * While waiting for `'drain'`, we also race {@link finished} so destroying the writable (e.g. abort)
14
+ * cannot leave this promise pending forever.
15
+ */
16
+ export declare function write(writable: Writable, chunk: unknown): Promise<void>;
17
+ //# sourceMappingURL=writable-async-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writable-async-write.d.ts","sourceRoot":"","sources":["../../src/utils/writable-async-write.ts"],"names":[],"mappings":";AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEvC;;;;;;;;;;;;GAYG;AACH,wBAAsB,KAAK,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAuC7E"}
@@ -0,0 +1,61 @@
1
+ 'use strict';
2
+
3
+ var node_events = require('node:events');
4
+ var promises = require('node:stream/promises');
5
+
6
+ /**
7
+ * Async helper for application code that `await`s sequential writes to a `Writable`.
8
+ *
9
+ * 1. Waits until `writable.write` invokes its callback (chunk accepted / `_write` finished).
10
+ * 2. If `write()` returned `false` **and** `writable.writableNeedDrain` is still true after the
11
+ * callback, waits for `'drain'`.
12
+ *
13
+ * We check both: the return value tells us backpressure was signaled; `writableNeedDrain` avoids
14
+ * awaiting `'drain'` when it already fired before we subscribed (would otherwise hang forever).
15
+ *
16
+ * While waiting for `'drain'`, we also race {@link finished} so destroying the writable (e.g. abort)
17
+ * cannot leave this promise pending forever.
18
+ */ async function write(writable, chunk) {
19
+ let flushed = true;
20
+ await new Promise((resolve, reject)=>{
21
+ let settled = false;
22
+ const finish = (fn)=>{
23
+ if (settled) {
24
+ return;
25
+ }
26
+ settled = true;
27
+ writable.off('error', onError);
28
+ fn();
29
+ };
30
+ const onError = (err)=>{
31
+ finish(()=>reject(err));
32
+ };
33
+ writable.once('error', onError);
34
+ flushed = writable.write(chunk, (err)=>{
35
+ if (err) {
36
+ // Do not reject or remove `error` here: Node may emit `error` after this callback, and
37
+ // clearing the listener first would leave that emission unhandled.
38
+ setImmediate(()=>{
39
+ if (!settled) {
40
+ finish(()=>reject(err));
41
+ }
42
+ });
43
+ return;
44
+ }
45
+ finish(()=>resolve());
46
+ });
47
+ });
48
+ if (!flushed && writable.writableNeedDrain) {
49
+ // Without `finished`, awaiting only `drain` can hang forever if the writable is destroyed first.
50
+ await Promise.race([
51
+ node_events.once(writable, 'drain'),
52
+ promises.finished(writable, {
53
+ readable: false,
54
+ writable: true
55
+ })
56
+ ]);
57
+ }
58
+ }
59
+
60
+ exports.write = write;
61
+ //# sourceMappingURL=writable-async-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writable-async-write.js","sources":["../../src/utils/writable-async-write.ts"],"sourcesContent":["import { once } from 'node:events';\nimport { finished } from 'node:stream/promises';\nimport type { Writable } from 'stream';\n\n/**\n * Async helper for application code that `await`s sequential writes to a `Writable`.\n *\n * 1. Waits until `writable.write` invokes its callback (chunk accepted / `_write` finished).\n * 2. If `write()` returned `false` **and** `writable.writableNeedDrain` is still true after the\n * callback, waits for `'drain'`.\n *\n * We check both: the return value tells us backpressure was signaled; `writableNeedDrain` avoids\n * awaiting `'drain'` when it already fired before we subscribed (would otherwise hang forever).\n *\n * While waiting for `'drain'`, we also race {@link finished} so destroying the writable (e.g. abort)\n * cannot leave this promise pending forever.\n */\nexport async function write(writable: Writable, chunk: unknown): Promise<void> {\n let flushed = true;\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n const finish = (fn: () => void) => {\n if (settled) {\n return;\n }\n settled = true;\n writable.off('error', onError);\n fn();\n };\n const onError = (err: Error) => {\n finish(() => reject(err));\n };\n writable.once('error', onError);\n flushed = writable.write(chunk, (err) => {\n if (err) {\n // Do not reject or remove `error` here: Node may emit `error` after this callback, and\n // clearing the listener first would leave that emission unhandled.\n setImmediate(() => {\n if (!settled) {\n finish(() => reject(err));\n }\n });\n return;\n }\n finish(() => resolve());\n });\n });\n\n if (!flushed && writable.writableNeedDrain) {\n // Without `finished`, awaiting only `drain` can hang forever if the writable is destroyed first.\n await Promise.race([\n once(writable, 'drain'),\n finished(writable, { readable: false, writable: true }),\n ]);\n }\n}\n"],"names":["write","writable","chunk","flushed","Promise","resolve","reject","settled","finish","fn","off","onError","err","once","setImmediate","writableNeedDrain","race","finished","readable"],"mappings":";;;;;AAIA;;;;;;;;;;;;AAYC,IACM,eAAeA,KAAAA,CAAMC,QAAkB,EAAEC,KAAc,EAAA;AAC5D,IAAA,IAAIC,OAAAA,GAAU,IAAA;IAEd,MAAM,IAAIC,OAAAA,CAAc,CAACC,OAAAA,EAASC,MAAAA,GAAAA;AAChC,QAAA,IAAIC,OAAAA,GAAU,KAAA;AACd,QAAA,MAAMC,SAAS,CAACC,EAAAA,GAAAA;AACd,YAAA,IAAIF,OAAAA,EAAS;AACX,gBAAA;AACF,YAAA;YACAA,OAAAA,GAAU,IAAA;YACVN,QAAAA,CAASS,GAAG,CAAC,OAAA,EAASC,OAAAA,CAAAA;AACtBF,YAAAA,EAAAA,EAAAA;AACF,QAAA,CAAA;AACA,QAAA,MAAME,UAAU,CAACC,GAAAA,GAAAA;AACfJ,YAAAA,MAAAA,CAAO,IAAMF,MAAAA,CAAOM,GAAAA,CAAAA,CAAAA;AACtB,QAAA,CAAA;QACAX,QAAAA,CAASY,IAAI,CAAC,OAAA,EAASF,OAAAA,CAAAA;AACvBR,QAAAA,OAAAA,GAAUF,QAAAA,CAASD,KAAK,CAACE,KAAAA,EAAO,CAACU,GAAAA,GAAAA;AAC/B,YAAA,IAAIA,GAAAA,EAAK;;;gBAGPE,YAAAA,CAAa,IAAA;AACX,oBAAA,IAAI,CAACP,OAAAA,EAAS;AACZC,wBAAAA,MAAAA,CAAO,IAAMF,MAAAA,CAAOM,GAAAA,CAAAA,CAAAA;AACtB,oBAAA;AACF,gBAAA,CAAA,CAAA;AACA,gBAAA;AACF,YAAA;AACAJ,YAAAA,MAAAA,CAAO,IAAMH,OAAAA,EAAAA,CAAAA;AACf,QAAA,CAAA,CAAA;AACF,IAAA,CAAA,CAAA;AAEA,IAAA,IAAI,CAACF,OAAAA,IAAWF,QAAAA,CAASc,iBAAiB,EAAE;;QAE1C,MAAMX,OAAAA,CAAQY,IAAI,CAAC;AACjBH,YAAAA,gBAAAA,CAAKZ,QAAAA,EAAU,OAAA,CAAA;AACfgB,YAAAA,iBAAAA,CAAShB,QAAAA,EAAU;gBAAEiB,QAAAA,EAAU,KAAA;gBAAOjB,QAAAA,EAAU;AAAK,aAAA;AACtD,SAAA,CAAA;AACH,IAAA;AACF;;;;"}
@@ -0,0 +1,59 @@
1
+ import { once } from 'node:events';
2
+ import { finished } from 'node:stream/promises';
3
+
4
+ /**
5
+ * Async helper for application code that `await`s sequential writes to a `Writable`.
6
+ *
7
+ * 1. Waits until `writable.write` invokes its callback (chunk accepted / `_write` finished).
8
+ * 2. If `write()` returned `false` **and** `writable.writableNeedDrain` is still true after the
9
+ * callback, waits for `'drain'`.
10
+ *
11
+ * We check both: the return value tells us backpressure was signaled; `writableNeedDrain` avoids
12
+ * awaiting `'drain'` when it already fired before we subscribed (would otherwise hang forever).
13
+ *
14
+ * While waiting for `'drain'`, we also race {@link finished} so destroying the writable (e.g. abort)
15
+ * cannot leave this promise pending forever.
16
+ */ async function write(writable, chunk) {
17
+ let flushed = true;
18
+ await new Promise((resolve, reject)=>{
19
+ let settled = false;
20
+ const finish = (fn)=>{
21
+ if (settled) {
22
+ return;
23
+ }
24
+ settled = true;
25
+ writable.off('error', onError);
26
+ fn();
27
+ };
28
+ const onError = (err)=>{
29
+ finish(()=>reject(err));
30
+ };
31
+ writable.once('error', onError);
32
+ flushed = writable.write(chunk, (err)=>{
33
+ if (err) {
34
+ // Do not reject or remove `error` here: Node may emit `error` after this callback, and
35
+ // clearing the listener first would leave that emission unhandled.
36
+ setImmediate(()=>{
37
+ if (!settled) {
38
+ finish(()=>reject(err));
39
+ }
40
+ });
41
+ return;
42
+ }
43
+ finish(()=>resolve());
44
+ });
45
+ });
46
+ if (!flushed && writable.writableNeedDrain) {
47
+ // Without `finished`, awaiting only `drain` can hang forever if the writable is destroyed first.
48
+ await Promise.race([
49
+ once(writable, 'drain'),
50
+ finished(writable, {
51
+ readable: false,
52
+ writable: true
53
+ })
54
+ ]);
55
+ }
56
+ }
57
+
58
+ export { write };
59
+ //# sourceMappingURL=writable-async-write.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"writable-async-write.mjs","sources":["../../src/utils/writable-async-write.ts"],"sourcesContent":["import { once } from 'node:events';\nimport { finished } from 'node:stream/promises';\nimport type { Writable } from 'stream';\n\n/**\n * Async helper for application code that `await`s sequential writes to a `Writable`.\n *\n * 1. Waits until `writable.write` invokes its callback (chunk accepted / `_write` finished).\n * 2. If `write()` returned `false` **and** `writable.writableNeedDrain` is still true after the\n * callback, waits for `'drain'`.\n *\n * We check both: the return value tells us backpressure was signaled; `writableNeedDrain` avoids\n * awaiting `'drain'` when it already fired before we subscribed (would otherwise hang forever).\n *\n * While waiting for `'drain'`, we also race {@link finished} so destroying the writable (e.g. abort)\n * cannot leave this promise pending forever.\n */\nexport async function write(writable: Writable, chunk: unknown): Promise<void> {\n let flushed = true;\n\n await new Promise<void>((resolve, reject) => {\n let settled = false;\n const finish = (fn: () => void) => {\n if (settled) {\n return;\n }\n settled = true;\n writable.off('error', onError);\n fn();\n };\n const onError = (err: Error) => {\n finish(() => reject(err));\n };\n writable.once('error', onError);\n flushed = writable.write(chunk, (err) => {\n if (err) {\n // Do not reject or remove `error` here: Node may emit `error` after this callback, and\n // clearing the listener first would leave that emission unhandled.\n setImmediate(() => {\n if (!settled) {\n finish(() => reject(err));\n }\n });\n return;\n }\n finish(() => resolve());\n });\n });\n\n if (!flushed && writable.writableNeedDrain) {\n // Without `finished`, awaiting only `drain` can hang forever if the writable is destroyed first.\n await Promise.race([\n once(writable, 'drain'),\n finished(writable, { readable: false, writable: true }),\n ]);\n }\n}\n"],"names":["write","writable","chunk","flushed","Promise","resolve","reject","settled","finish","fn","off","onError","err","once","setImmediate","writableNeedDrain","race","finished","readable"],"mappings":";;;AAIA;;;;;;;;;;;;AAYC,IACM,eAAeA,KAAAA,CAAMC,QAAkB,EAAEC,KAAc,EAAA;AAC5D,IAAA,IAAIC,OAAAA,GAAU,IAAA;IAEd,MAAM,IAAIC,OAAAA,CAAc,CAACC,OAAAA,EAASC,MAAAA,GAAAA;AAChC,QAAA,IAAIC,OAAAA,GAAU,KAAA;AACd,QAAA,MAAMC,SAAS,CAACC,EAAAA,GAAAA;AACd,YAAA,IAAIF,OAAAA,EAAS;AACX,gBAAA;AACF,YAAA;YACAA,OAAAA,GAAU,IAAA;YACVN,QAAAA,CAASS,GAAG,CAAC,OAAA,EAASC,OAAAA,CAAAA;AACtBF,YAAAA,EAAAA,EAAAA;AACF,QAAA,CAAA;AACA,QAAA,MAAME,UAAU,CAACC,GAAAA,GAAAA;AACfJ,YAAAA,MAAAA,CAAO,IAAMF,MAAAA,CAAOM,GAAAA,CAAAA,CAAAA;AACtB,QAAA,CAAA;QACAX,QAAAA,CAASY,IAAI,CAAC,OAAA,EAASF,OAAAA,CAAAA;AACvBR,QAAAA,OAAAA,GAAUF,QAAAA,CAASD,KAAK,CAACE,KAAAA,EAAO,CAACU,GAAAA,GAAAA;AAC/B,YAAA,IAAIA,GAAAA,EAAK;;;gBAGPE,YAAAA,CAAa,IAAA;AACX,oBAAA,IAAI,CAACP,OAAAA,EAAS;AACZC,wBAAAA,MAAAA,CAAO,IAAMF,MAAAA,CAAOM,GAAAA,CAAAA,CAAAA;AACtB,oBAAA;AACF,gBAAA,CAAA,CAAA;AACA,gBAAA;AACF,YAAA;AACAJ,YAAAA,MAAAA,CAAO,IAAMH,OAAAA,EAAAA,CAAAA;AACf,QAAA,CAAA,CAAA;AACF,IAAA,CAAA,CAAA;AAEA,IAAA,IAAI,CAACF,OAAAA,IAAWF,QAAAA,CAASc,iBAAiB,EAAE;;QAE1C,MAAMX,OAAAA,CAAQY,IAAI,CAAC;AACjBH,YAAAA,IAAAA,CAAKZ,QAAAA,EAAU,OAAA,CAAA;AACfgB,YAAAA,QAAAA,CAAShB,QAAAA,EAAU;gBAAEiB,QAAAA,EAAU,KAAA;gBAAOjB,QAAAA,EAAU;AAAK,aAAA;AACtD,SAAA,CAAA;AACH,IAAA;AACF;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/data-transfer",
3
- "version": "5.42.0",
3
+ "version": "5.43.0",
4
4
  "description": "Data transfer capabilities for Strapi",
5
5
  "keywords": [
6
6
  "strapi",
@@ -51,15 +51,15 @@
51
51
  "watch": "run -T rollup -c -w"
52
52
  },
53
53
  "dependencies": {
54
- "@strapi/logger": "5.42.0",
55
- "@strapi/types": "5.42.0",
56
- "@strapi/utils": "5.42.0",
54
+ "@strapi/logger": "5.43.0",
55
+ "@strapi/types": "5.43.0",
56
+ "@strapi/utils": "5.43.0",
57
57
  "chalk": "4.1.2",
58
58
  "cli-table3": "0.6.5",
59
59
  "commander": "8.3.0",
60
60
  "fs-extra": "11.2.0",
61
61
  "inquirer": "9.3.8",
62
- "lodash": "4.17.23",
62
+ "lodash": "4.18.1",
63
63
  "ora": "5.4.1",
64
64
  "resolve-cwd": "3.0.0",
65
65
  "semver": "7.5.4",
@@ -70,7 +70,7 @@
70
70
  "ws": "8.17.1"
71
71
  },
72
72
  "devDependencies": {
73
- "@strapi/database": "5.42.0",
73
+ "@strapi/database": "5.43.0",
74
74
  "@types/fs-extra": "11.0.4",
75
75
  "@types/jest": "29.5.2",
76
76
  "@types/koa": "2.13.4",