@ethersphere/bee-js 3.2.0 → 3.3.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 (183) hide show
  1. package/dist/cjs/bee-debug.js +615 -0
  2. package/dist/cjs/bee.js +922 -0
  3. package/dist/cjs/chunk/bmt.js +50 -0
  4. package/dist/cjs/chunk/cac.js +56 -0
  5. package/dist/cjs/chunk/serialize.js +19 -0
  6. package/dist/cjs/chunk/signer.js +132 -0
  7. package/dist/cjs/chunk/soc.js +172 -0
  8. package/dist/cjs/chunk/span.js +29 -0
  9. package/dist/cjs/feed/index.js +184 -0
  10. package/dist/cjs/feed/json.js +41 -0
  11. package/dist/cjs/feed/topic.js +25 -0
  12. package/dist/cjs/feed/type.js +15 -0
  13. package/dist/cjs/index.js +35 -0
  14. package/dist/cjs/modules/bytes.js +74 -0
  15. package/dist/cjs/modules/bzz.js +131 -0
  16. package/dist/cjs/modules/chunk.js +58 -0
  17. package/dist/cjs/modules/debug/balance.js +77 -0
  18. package/dist/cjs/modules/debug/chequebook.js +167 -0
  19. package/dist/cjs/modules/debug/chunk.js +51 -0
  20. package/dist/cjs/modules/debug/connectivity.js +75 -0
  21. package/dist/cjs/modules/debug/settlements.js +45 -0
  22. package/dist/cjs/modules/debug/stamps.js +89 -0
  23. package/dist/cjs/modules/debug/states.js +47 -0
  24. package/dist/cjs/modules/debug/status.js +153 -0
  25. package/dist/cjs/modules/debug/tag.js +30 -0
  26. package/dist/cjs/modules/debug/transactions.js +81 -0
  27. package/dist/cjs/modules/feed.js +76 -0
  28. package/dist/cjs/modules/pinning.js +84 -0
  29. package/dist/cjs/modules/pss.js +55 -0
  30. package/dist/cjs/modules/soc.js +40 -0
  31. package/dist/cjs/modules/status.js +26 -0
  32. package/dist/cjs/modules/stewardship.js +41 -0
  33. package/dist/cjs/modules/tag.js +96 -0
  34. package/dist/cjs/package.json +7 -0
  35. package/dist/cjs/types/debug.js +9 -0
  36. package/dist/cjs/types/index.js +46 -0
  37. package/dist/cjs/utils/bytes.js +107 -0
  38. package/dist/cjs/utils/collection.browser.js +36 -0
  39. package/dist/cjs/utils/collection.js +70 -0
  40. package/dist/cjs/utils/collection.node.js +115 -0
  41. package/dist/cjs/utils/data.browser.js +78 -0
  42. package/dist/cjs/utils/data.js +60 -0
  43. package/dist/cjs/utils/error.js +50 -0
  44. package/dist/cjs/utils/eth.js +206 -0
  45. package/dist/cjs/utils/expose.js +44 -0
  46. package/dist/cjs/utils/file.js +49 -0
  47. package/dist/cjs/utils/hash.js +16 -0
  48. package/dist/cjs/utils/headers.js +59 -0
  49. package/dist/cjs/utils/hex.js +150 -0
  50. package/dist/cjs/utils/http.js +166 -0
  51. package/dist/cjs/utils/merge.js +34 -0
  52. package/dist/cjs/utils/pss.js +18 -0
  53. package/dist/cjs/utils/stamps.js +17 -0
  54. package/dist/cjs/utils/stream.js +137 -0
  55. package/dist/cjs/utils/tar.js +25 -0
  56. package/dist/cjs/utils/type.js +327 -0
  57. package/dist/cjs/utils/uint64.js +29 -0
  58. package/dist/cjs/utils/url.js +56 -0
  59. package/dist/index.js +28326 -0
  60. package/dist/index.js.map +1 -0
  61. package/dist/mjs/bee-debug.js +509 -0
  62. package/dist/mjs/bee.js +845 -0
  63. package/dist/mjs/chunk/bmt.js +46 -0
  64. package/dist/mjs/chunk/cac.js +50 -0
  65. package/dist/mjs/chunk/serialize.js +15 -0
  66. package/dist/mjs/chunk/signer.js +112 -0
  67. package/dist/mjs/chunk/soc.js +127 -0
  68. package/dist/mjs/chunk/span.js +25 -0
  69. package/dist/mjs/feed/index.js +136 -0
  70. package/dist/mjs/feed/json.js +23 -0
  71. package/dist/mjs/feed/topic.js +20 -0
  72. package/dist/mjs/feed/type.js +10 -0
  73. package/dist/mjs/index.js +7 -0
  74. package/dist/mjs/modules/bytes.js +56 -0
  75. package/dist/mjs/modules/bzz.js +119 -0
  76. package/dist/mjs/modules/chunk.js +43 -0
  77. package/dist/mjs/modules/debug/balance.js +53 -0
  78. package/dist/mjs/modules/debug/chequebook.js +131 -0
  79. package/dist/mjs/modules/debug/chunk.js +33 -0
  80. package/dist/mjs/modules/debug/connectivity.js +45 -0
  81. package/dist/mjs/modules/debug/settlements.js +27 -0
  82. package/dist/mjs/modules/debug/stamps.js +59 -0
  83. package/dist/mjs/modules/debug/states.js +29 -0
  84. package/dist/mjs/modules/debug/status.js +114 -0
  85. package/dist/mjs/modules/debug/tag.js +15 -0
  86. package/dist/mjs/modules/debug/transactions.js +57 -0
  87. package/dist/mjs/modules/feed.js +61 -0
  88. package/dist/mjs/modules/pinning.js +60 -0
  89. package/dist/mjs/modules/pss.js +36 -0
  90. package/dist/mjs/modules/soc.js +28 -0
  91. package/dist/mjs/modules/status.js +11 -0
  92. package/dist/mjs/modules/stewardship.js +23 -0
  93. package/dist/mjs/modules/tag.js +69 -0
  94. package/dist/mjs/package.json +7 -0
  95. package/dist/mjs/types/debug.js +6 -0
  96. package/dist/mjs/types/index.js +33 -0
  97. package/dist/mjs/utils/bytes.js +95 -0
  98. package/dist/mjs/utils/collection.browser.js +18 -0
  99. package/dist/mjs/utils/collection.js +52 -0
  100. package/dist/mjs/utils/collection.node.js +63 -0
  101. package/dist/mjs/utils/data.browser.js +57 -0
  102. package/dist/mjs/utils/data.js +39 -0
  103. package/dist/mjs/utils/error.js +48 -0
  104. package/dist/mjs/utils/eth.js +184 -0
  105. package/dist/mjs/utils/expose.js +9 -0
  106. package/dist/mjs/utils/file.js +33 -0
  107. package/dist/mjs/utils/hash.js +12 -0
  108. package/dist/mjs/utils/headers.js +54 -0
  109. package/dist/mjs/utils/hex.js +139 -0
  110. package/dist/mjs/utils/http.js +136 -0
  111. package/dist/mjs/utils/merge.js +30 -0
  112. package/dist/mjs/utils/pss.js +14 -0
  113. package/dist/mjs/utils/stamps.js +13 -0
  114. package/dist/mjs/utils/stream.js +131 -0
  115. package/dist/mjs/utils/tar.js +18 -0
  116. package/dist/mjs/utils/type.js +296 -0
  117. package/dist/mjs/utils/uint64.js +23 -0
  118. package/dist/mjs/utils/url.js +50 -0
  119. package/dist/{src → types}/bee-debug.d.ts +47 -1
  120. package/dist/{src → types}/bee.d.ts +0 -0
  121. package/dist/{src → types}/chunk/bmt.d.ts +0 -0
  122. package/dist/{src → types}/chunk/cac.d.ts +0 -0
  123. package/dist/{src → types}/chunk/serialize.d.ts +0 -0
  124. package/dist/{src → types}/chunk/signer.d.ts +0 -0
  125. package/dist/{src → types}/chunk/soc.d.ts +0 -0
  126. package/dist/{src → types}/chunk/span.d.ts +0 -0
  127. package/dist/{src → types}/feed/index.d.ts +0 -0
  128. package/dist/{src → types}/feed/json.d.ts +0 -0
  129. package/dist/{src → types}/feed/topic.d.ts +0 -0
  130. package/dist/{src → types}/feed/type.d.ts +0 -0
  131. package/dist/{src → types}/index.d.ts +0 -0
  132. package/dist/{src → types}/modules/bytes.d.ts +0 -0
  133. package/dist/{src → types}/modules/bzz.d.ts +0 -0
  134. package/dist/{src → types}/modules/chunk.d.ts +0 -0
  135. package/dist/{src → types}/modules/debug/balance.d.ts +0 -0
  136. package/dist/{src → types}/modules/debug/chequebook.d.ts +0 -0
  137. package/dist/{src → types}/modules/debug/chunk.d.ts +0 -0
  138. package/dist/{src → types}/modules/debug/connectivity.d.ts +0 -0
  139. package/dist/{src → types}/modules/debug/settlements.d.ts +0 -0
  140. package/dist/{src → types}/modules/debug/stamps.d.ts +0 -0
  141. package/dist/{src → types}/modules/debug/states.d.ts +0 -0
  142. package/dist/types/modules/debug/status.d.ts +72 -0
  143. package/dist/{src → types}/modules/debug/tag.d.ts +0 -0
  144. package/dist/{src → types}/modules/debug/transactions.d.ts +0 -0
  145. package/dist/{src → types}/modules/feed.d.ts +0 -0
  146. package/dist/{src → types}/modules/pinning.d.ts +0 -0
  147. package/dist/{src → types}/modules/pss.d.ts +0 -0
  148. package/dist/{src → types}/modules/soc.d.ts +0 -0
  149. package/dist/{src → types}/modules/status.d.ts +0 -0
  150. package/dist/{src → types}/modules/stewardship.d.ts +0 -0
  151. package/dist/{src → types}/modules/tag.d.ts +0 -0
  152. package/dist/{src → types}/types/debug.d.ts +8 -0
  153. package/dist/{src → types}/types/index.d.ts +1 -0
  154. package/dist/{src → types}/utils/bytes.d.ts +0 -0
  155. package/dist/types/utils/collection.browser.d.ts +15 -0
  156. package/dist/{src → types}/utils/collection.d.ts +0 -14
  157. package/dist/types/utils/collection.node.d.ts +15 -0
  158. package/dist/{src → types}/utils/data.browser.d.ts +0 -0
  159. package/dist/{src → types}/utils/data.d.ts +0 -0
  160. package/dist/{src → types}/utils/error.d.ts +0 -0
  161. package/dist/{src → types}/utils/eth.d.ts +0 -0
  162. package/dist/{src → types}/utils/expose.d.ts +2 -1
  163. package/dist/{src → types}/utils/file.d.ts +0 -0
  164. package/dist/{src → types}/utils/hash.d.ts +0 -0
  165. package/dist/{src → types}/utils/headers.d.ts +0 -0
  166. package/dist/{src → types}/utils/hex.d.ts +0 -0
  167. package/dist/{src → types}/utils/http.d.ts +0 -0
  168. package/dist/{src → types}/utils/merge.d.ts +0 -0
  169. package/dist/{src → types}/utils/pss.d.ts +0 -0
  170. package/dist/{src → types}/utils/stamps.d.ts +0 -0
  171. package/dist/{src → types}/utils/stream.d.ts +0 -0
  172. package/dist/{src → types}/utils/tar.d.ts +0 -0
  173. package/dist/{src → types}/utils/type.d.ts +0 -0
  174. package/dist/{src → types}/utils/uint64.d.ts +0 -0
  175. package/dist/{src → types}/utils/url.d.ts +0 -0
  176. package/package.json +39 -23
  177. package/dist/index.browser.min.js +0 -3
  178. package/dist/index.browser.min.js.LICENSE.txt +0 -59
  179. package/dist/index.browser.min.js.map +0 -1
  180. package/dist/index.min.js +0 -3
  181. package/dist/index.min.js.LICENSE.txt +0 -50
  182. package/dist/index.min.js.map +0 -1
  183. package/dist/src/modules/debug/status.d.ts +0 -24
@@ -0,0 +1,39 @@
1
+ import Blob from 'cross-blob';
2
+ import { isNodeReadable, isReadableStream, readableWebToNode } from './stream';
3
+ /**
4
+ * Prepare data for valid input for node-fetch.
5
+ *
6
+ * node-fetch is not using WHATWG ReadableStream but NodeJS Readable so we need to convert in case of ReadableStream,
7
+ * but the typings are set to use ReadableStream so hence why type conversion here.
8
+ *
9
+ * @param data any string, ArrayBuffer, Uint8Array or Readable
10
+ */
11
+ export async function prepareData(data) {
12
+ if (typeof data === 'string')
13
+ return new Blob([data], { type: 'text/plain' });
14
+ if (data instanceof Uint8Array || data instanceof ArrayBuffer) {
15
+ return new Blob([data], { type: 'application/octet-stream' });
16
+ }
17
+ if (data instanceof Blob || isNodeReadable(data))
18
+ return data;
19
+ if (isReadableStream(data)) {
20
+ return readableWebToNode(data);
21
+ }
22
+ throw new TypeError('unknown data type');
23
+ }
24
+ function isBufferArray(buffer) {
25
+ return Array.isArray(buffer) && buffer.length > 0 && buffer.every(data => data instanceof Buffer);
26
+ }
27
+ export async function prepareWebsocketData(data) {
28
+ if (typeof data === 'string')
29
+ return new TextEncoder().encode(data);
30
+ if (data instanceof Buffer)
31
+ return new Uint8Array(data);
32
+ if (data instanceof ArrayBuffer)
33
+ return new Uint8Array(data);
34
+ if (data instanceof Blob)
35
+ return new Uint8Array(await new Response(data).arrayBuffer());
36
+ if (isBufferArray(data))
37
+ return new Uint8Array(Buffer.concat(data));
38
+ throw new TypeError('unknown websocket data type');
39
+ }
@@ -0,0 +1,48 @@
1
+ export class BeeError extends Error {
2
+ constructor(message) {
3
+ super(message);
4
+ }
5
+ }
6
+ export class BeeArgumentError extends BeeError {
7
+ value;
8
+ constructor(message, value) {
9
+ super(message);
10
+ this.value = value;
11
+ }
12
+ }
13
+ export class BeeRequestError extends BeeError {
14
+ requestOptions;
15
+ /**
16
+ * @param message
17
+ * @param requestOptions KyOptions that were used to assemble the request. THIS MIGHT NOT BE COMPLETE! If custom Ky instance was used that has set defaults then these defaults are not visible in this object!
18
+ */
19
+ constructor(message, requestOptions) {
20
+ super(message);
21
+ this.requestOptions = requestOptions;
22
+ }
23
+ }
24
+ export class BeeResponseError extends BeeError {
25
+ status;
26
+ response;
27
+ responseBody;
28
+ requestOptions;
29
+ /**
30
+ * @param status HTTP status code number
31
+ * @param response Response returned from the server
32
+ * @param responseBody Response body as string which is returned from response.text() call
33
+ * @param requestOptions KyOptions that were used to assemble the request. THIS MIGHT NOT BE COMPLETE! If custom Ky instance was used that has set defaults then these defaults are not visible in this object!
34
+ * @param message
35
+ */
36
+ constructor(status, response, responseBody, requestOptions, message) {
37
+ super(message);
38
+ this.status = status;
39
+ this.response = response;
40
+ this.responseBody = responseBody;
41
+ this.requestOptions = requestOptions;
42
+ }
43
+ }
44
+ export class BeeNotAJsonError extends BeeError {
45
+ constructor() {
46
+ super(`Received response is not valid JSON.`);
47
+ }
48
+ }
@@ -0,0 +1,184 @@
1
+ import { keccak256, sha3_256 } from 'js-sha3';
2
+ import { hexToBytes, intToHex, makeHexString, assertHexString } from './hex';
3
+ import { assertBytes } from './bytes';
4
+ const ETH_ADDR_BYTES_LENGTH = 20;
5
+ const ETH_ADDR_HEX_LENGTH = 40;
6
+ export function makeEthAddress(address) {
7
+ if (typeof address === 'string') {
8
+ const hexAddr = makeHexString(address, ETH_ADDR_HEX_LENGTH);
9
+ const ownerBytes = hexToBytes(hexAddr);
10
+ assertBytes(ownerBytes, ETH_ADDR_BYTES_LENGTH);
11
+ return ownerBytes;
12
+ }
13
+ else if (address instanceof Uint8Array) {
14
+ assertBytes(address, ETH_ADDR_BYTES_LENGTH);
15
+ return address;
16
+ }
17
+ throw new TypeError('Invalid EthAddress');
18
+ }
19
+ export function makeHexEthAddress(address) {
20
+ try {
21
+ return makeHexString(address, ETH_ADDR_HEX_LENGTH);
22
+ }
23
+ catch (e) {
24
+ if (e instanceof TypeError) {
25
+ e.message = `Invalid HexEthAddress: ${e.message}`;
26
+ }
27
+ throw e;
28
+ }
29
+ }
30
+ /**
31
+ * Check if this is all caps or small caps eth address (=address without checksum)
32
+ *
33
+ * @param address Ethereum address as hex string
34
+ */
35
+ function isEthAddrCaseIns(address) {
36
+ // Check it's string, all small caps or all all caps hex and 40 chars long without the `0x` prefix
37
+ return (typeof address === 'string' && (/^(0x|0X)?[0-9a-f]{40}$/.test(address) || /^(0x|0X)?[0-9A-F]{40}$/.test(address)));
38
+ }
39
+ /**
40
+ * Check if this is checksummed ethereum address
41
+ *
42
+ * @param address Ethereum address as hex string
43
+ */
44
+ function isValidChecksummedEthAddress(address) {
45
+ try {
46
+ // Check for valid case insensitive hex type string, 40 chars
47
+ const addr = makeHexString(address, ETH_ADDR_HEX_LENGTH);
48
+ // Check the checksum
49
+ const addressHash = keccak256(addr.toLowerCase());
50
+ for (let i = 0; i < 40; i += 1) {
51
+ // the nth letter should be uppercase if the nth digit of casemap is 1
52
+ if ((parseInt(addressHash[i], 16) > 7 && addr[i].toUpperCase() !== addr[i]) ||
53
+ (parseInt(addressHash[i], 16) <= 7 && addr[i].toLowerCase() !== addr[i])) {
54
+ return false;
55
+ }
56
+ }
57
+ return true;
58
+ }
59
+ catch (e) {
60
+ if (e instanceof TypeError) {
61
+ return false;
62
+ }
63
+ throw e;
64
+ }
65
+ }
66
+ /**
67
+ * Check if is valid ethereum address
68
+ *
69
+ * Pretty much typed version from web3js
70
+ * https://github.com/ChainSafe/web3.js/blob/1.x/packages/web3-utils/src/utils.js
71
+ *
72
+ * @param address Ethereum address as hex string
73
+ *
74
+ * @return True if is valid eth address
75
+ */
76
+ export function isHexEthAddress(address) {
77
+ return isEthAddrCaseIns(address) || isValidChecksummedEthAddress(address);
78
+ }
79
+ /**
80
+ * Convert big-endian hex or number to little-endian.
81
+ * Note: Before conversion it is automatically padded to even length hexstring
82
+ *
83
+ * @param bigEndian Big-endian hex string or number to convert
84
+ * @param pad Length to which the string should be padded before conversion (defaul: 2)
85
+ *
86
+ * @return little-endian encoded hexstring
87
+ */
88
+ export function toLittleEndian(bigEndian, pad = 2) {
89
+ if (!(Number.isInteger(pad) && pad >= 2 && pad % 2 === 0)) {
90
+ throw new TypeError('minimal padding for conversion needs to be positive even integer');
91
+ }
92
+ let hexRep;
93
+ if (typeof bigEndian === 'string')
94
+ hexRep = makeHexString(bigEndian);
95
+ else if (typeof bigEndian === 'number')
96
+ hexRep = intToHex(bigEndian);
97
+ else
98
+ throw new TypeError('incorrect input type');
99
+ hexRep = hexRep.padStart(pad, '0');
100
+ // Extend to an even length hexstring
101
+ if (hexRep.length % 2 !== 0)
102
+ hexRep = hexRep.padStart(hexRep.length + 1, '0');
103
+ // Match all two pairs in the hexstring, reverse the pairs and join it again
104
+ const littleEndian = hexRep.match(/../g)?.reverse().join('');
105
+ if (littleEndian)
106
+ return littleEndian;
107
+ throw new Error('failed to convert');
108
+ }
109
+ /**
110
+ * Convert little-endian hex or number to big-endian
111
+ * Note: Before conversion it is automatically padded to even length hexstring
112
+ *
113
+ * @param littleEndian Little-endian hex string or number to convert
114
+ * @param pad Length to which the string should be padded before conversion (defaul: 2)
115
+ *
116
+ * @return big-endian encoded hexstring
117
+ */
118
+ export function fromLittleEndian(littleEndian, pad = 2) {
119
+ // It's a reversible function
120
+ return toLittleEndian(littleEndian, pad);
121
+ }
122
+ function assertEthAddress(ethAddress) {
123
+ if (!isHexEthAddress(ethAddress))
124
+ throw new TypeError('invalid ETH address');
125
+ }
126
+ function assertSwarmNetworkId(networkId) {
127
+ if (Number.isInteger(networkId && networkId > 0 && networkId < Number.MAX_SAFE_INTEGER)) {
128
+ throw new TypeError('swarm network id must be positive integer');
129
+ }
130
+ }
131
+ /**
132
+ * Get swarm overlay address from public ethereum address and swarm network id
133
+ *
134
+ * @param ethAddress Public ethereum address
135
+ * @param networkId Swarm network id
136
+ *
137
+ * @return Swarm overlay address
138
+ */
139
+ export function ethToSwarmAddress(ethAddress, networkId = 1) {
140
+ assertEthAddress(ethAddress);
141
+ assertSwarmNetworkId(networkId);
142
+ const hex = `${makeHexString(ethAddress)}${toLittleEndian(networkId, 16)}`;
143
+ assertHexString(hex);
144
+ const overlayAddress = sha3_256(hexToBytes(hex));
145
+ return overlayAddress;
146
+ }
147
+ /**
148
+ * Function that takes Ethereum EIP-1193 compatible provider and create an Signer instance that
149
+ * uses `personal_sign` method to sign requested data.
150
+ *
151
+ * @param provider Injected web3 provider like window.ethereum or other compatible with EIP-1193
152
+ * @param ethAddress Optional address of the account which the data should be signed with. If not specified `eth_requestAccounts` request is used to get the account address.
153
+ */
154
+ export async function makeEthereumWalletSigner(provider, ethAddress) {
155
+ let executorFnc;
156
+ if (typeof provider !== 'object' || provider === null) {
157
+ throw new TypeError('We need JsonRPC provider object!');
158
+ }
159
+ if (provider.request) {
160
+ executorFnc = provider.request;
161
+ }
162
+ else if (provider.sendAsync) {
163
+ executorFnc = provider.sendAsync;
164
+ }
165
+ else {
166
+ throw new Error('Incompatible interface of given provider!');
167
+ }
168
+ if (!ethAddress) {
169
+ ethAddress = (await executorFnc({ method: 'eth_requestAccounts' }))[0];
170
+ }
171
+ const bytesEthAddress = makeEthAddress(ethAddress);
172
+ const hexEthAddress = makeHexEthAddress(ethAddress);
173
+ return {
174
+ address: bytesEthAddress,
175
+ sign: async (data) => {
176
+ const result = await executorFnc({
177
+ jsonrpc: '2.0',
178
+ method: 'personal_sign',
179
+ params: ['0x' + data.hex(), '0x' + hexEthAddress],
180
+ });
181
+ return result;
182
+ },
183
+ };
184
+ }
@@ -0,0 +1,9 @@
1
+ export { getCollectionSize } from './collection';
2
+ export { getFolderSize } from './collection.node';
3
+ export { isBytes, assertBytes, isFlexBytes, assertFlexBytes, bytesAtOffset, flexBytesAtOffset, bytesEqual, } from './bytes';
4
+ export { makeHexString, hexToBytes, bytesToHex, intToHex, isHexString, assertHexString, assertPrefixedHexString, } from './hex';
5
+ export { makeEthAddress, makeHexEthAddress, isHexEthAddress, ethToSwarmAddress, toLittleEndian, fromLittleEndian, makeEthereumWalletSigner, } from './eth';
6
+ export { readableWebToNode, readableNodeToWeb, isReadableStream, isNodeReadable, normalizeToReadableStream, isReadable, } from './stream';
7
+ export { keccak256Hash } from './hash';
8
+ export { makeMaxTarget } from './pss';
9
+ export { getStampUsage } from './stamps';
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Compatibility functions for working with File API objects
3
+ *
4
+ * https://developer.mozilla.org/en-US/docs/Web/API/File
5
+ */
6
+ export function isFile(file) {
7
+ // browser
8
+ if (typeof File === 'function') {
9
+ return file instanceof File;
10
+ }
11
+ // node.js
12
+ const f = file;
13
+ return (typeof f === 'object' &&
14
+ typeof f.name === 'string' &&
15
+ (typeof f.stream === 'function' || typeof f.arrayBuffer === 'function'));
16
+ }
17
+ /**
18
+ * Compatibility helper for browsers where the `arrayBuffer function is
19
+ * missing from `File` objects.
20
+ *
21
+ * @param file A File object
22
+ */
23
+ export async function fileArrayBuffer(file) {
24
+ if (file.arrayBuffer) {
25
+ return file.arrayBuffer();
26
+ }
27
+ // workaround for Safari where arrayBuffer is not supported on Files
28
+ return new Promise(resolve => {
29
+ const fr = new FileReader();
30
+ fr.onload = () => resolve(fr.result);
31
+ fr.readAsArrayBuffer(file);
32
+ });
33
+ }
@@ -0,0 +1,12 @@
1
+ import { keccak256 } from 'js-sha3';
2
+ /**
3
+ * Helper function for calculating the keccak256 hash with
4
+ * correct types.
5
+ *
6
+ * @param messages Any number of messages (strings, byte arrays etc.)
7
+ */
8
+ export function keccak256Hash(...messages) {
9
+ const hasher = keccak256.create();
10
+ messages.forEach(bytes => hasher.update(bytes));
11
+ return Uint8Array.from(hasher.digest());
12
+ }
@@ -0,0 +1,54 @@
1
+ import { BeeError } from './error';
2
+ /**
3
+ * Read the filename from the content-disposition header
4
+ * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition
5
+ *
6
+ * @param header the content-disposition header value
7
+ *
8
+ * @returns the filename
9
+ */
10
+ function readContentDispositionFilename(header) {
11
+ if (!header) {
12
+ throw new BeeError('missing content-disposition header');
13
+ }
14
+ // Regex was found here
15
+ // https://stackoverflow.com/questions/23054475/javascript-regex-for-extracting-filename-from-content-disposition-header
16
+ const dispositionMatch = header.match(/filename\*?=['"]?(?:UTF-\d['"]*)?([^;\r\n"']*)['"]?;?/i);
17
+ if (dispositionMatch && dispositionMatch.length > 0) {
18
+ return dispositionMatch[1];
19
+ }
20
+ throw new BeeError('invalid content-disposition header');
21
+ }
22
+ function readTagUid(header) {
23
+ if (!header) {
24
+ return undefined;
25
+ }
26
+ return parseInt(header, 10);
27
+ }
28
+ export function readFileHeaders(headers) {
29
+ const name = readContentDispositionFilename(headers.get('content-disposition'));
30
+ const tagUid = readTagUid(headers.get('swarm-tag-uid'));
31
+ const contentType = headers.get('content-type') || undefined;
32
+ return {
33
+ name,
34
+ tagUid,
35
+ contentType,
36
+ };
37
+ }
38
+ export function extractUploadHeaders(postageBatchId, options) {
39
+ if (!postageBatchId) {
40
+ throw new BeeError('Postage BatchID has to be specified!');
41
+ }
42
+ const headers = {
43
+ 'swarm-postage-batch-id': postageBatchId,
44
+ };
45
+ if (options?.pin)
46
+ headers['swarm-pin'] = String(options.pin);
47
+ if (options?.encrypt)
48
+ headers['swarm-encrypt'] = String(options.encrypt);
49
+ if (options?.tag)
50
+ headers['swarm-tag'] = String(options.tag);
51
+ if (typeof options?.deferred === 'boolean')
52
+ headers['swarm-deferred-upload'] = options.deferred.toString();
53
+ return headers;
54
+ }
@@ -0,0 +1,139 @@
1
+ import { makeBytes } from './bytes';
2
+ /**
3
+ * Creates unprefixed hex string from wide range of data.
4
+ *
5
+ * TODO: Make Length mandatory: https://github.com/ethersphere/bee-js/issues/208
6
+ *
7
+ * @param input
8
+ * @param len of the resulting HexString WITHOUT prefix!
9
+ */
10
+ export function makeHexString(input, len) {
11
+ if (typeof input === 'number') {
12
+ return intToHex(input, len);
13
+ }
14
+ if (input instanceof Uint8Array) {
15
+ return bytesToHex(input, len);
16
+ }
17
+ if (typeof input === 'string') {
18
+ if (isPrefixedHexString(input)) {
19
+ const hex = input.slice(2);
20
+ if (len && hex.length !== len) {
21
+ throw new TypeError(`Length mismatch for valid hex string. Expecting length ${len}: ${hex}`);
22
+ }
23
+ return hex;
24
+ }
25
+ else {
26
+ // We use assertHexString() as there might be more reasons why a string is not valid hex string
27
+ // and usage of isHexString() would not give enough information to the user on what is going
28
+ // wrong.
29
+ assertHexString(input, len);
30
+ return input;
31
+ }
32
+ }
33
+ throw new TypeError('Not HexString compatible type!');
34
+ }
35
+ /**
36
+ * Converts a hex string to Uint8Array
37
+ *
38
+ * @param hex string input without 0x prefix!
39
+ */
40
+ export function hexToBytes(hex) {
41
+ assertHexString(hex);
42
+ const bytes = makeBytes(hex.length / 2);
43
+ for (let i = 0; i < bytes.length; i++) {
44
+ const hexByte = hex.substr(i * 2, 2);
45
+ bytes[i] = parseInt(hexByte, 16);
46
+ }
47
+ return bytes;
48
+ }
49
+ /**
50
+ * Converts array of number or Uint8Array to HexString without prefix.
51
+ *
52
+ * @param bytes The input array
53
+ * @param len The length of the non prefixed HexString
54
+ */
55
+ export function bytesToHex(bytes, len) {
56
+ const hexByte = (n) => n.toString(16).padStart(2, '0');
57
+ const hex = Array.from(bytes, hexByte).join('');
58
+ // TODO: Make Length mandatory: https://github.com/ethersphere/bee-js/issues/208
59
+ if (len && hex.length !== len) {
60
+ throw new TypeError(`Resulting HexString does not have expected length ${len}: ${hex}`);
61
+ }
62
+ return hex;
63
+ }
64
+ /**
65
+ * Converts integer number to hex string.
66
+ *
67
+ * Optionally provides '0x' prefix or padding
68
+ *
69
+ * @param int The positive integer to be converted
70
+ * @param len The length of the non prefixed HexString
71
+ */
72
+ export function intToHex(int, len) {
73
+ if (!Number.isInteger(int))
74
+ throw new TypeError('the value provided is not integer');
75
+ if (int > Number.MAX_SAFE_INTEGER)
76
+ throw new TypeError('the value provided exceeds safe integer');
77
+ if (int < 0)
78
+ throw new TypeError('the value provided is a negative integer');
79
+ const hex = int.toString(16);
80
+ // TODO: Make Length mandatory: https://github.com/ethersphere/bee-js/issues/208
81
+ if (len && hex.length !== len) {
82
+ throw new TypeError(`Resulting HexString does not have expected length ${len}: ${hex}`);
83
+ }
84
+ return hex;
85
+ }
86
+ /**
87
+ * Type guard for HexStrings.
88
+ * Requires no 0x prefix!
89
+ *
90
+ * TODO: Make Length mandatory: https://github.com/ethersphere/bee-js/issues/208
91
+ *
92
+ * @param s string input
93
+ * @param len expected length of the HexString
94
+ */
95
+ export function isHexString(s, len) {
96
+ return typeof s === 'string' && /^[0-9a-f]+$/i.test(s) && (!len || s.length === len);
97
+ }
98
+ /**
99
+ * Type guard for PrefixedHexStrings.
100
+ * Does enforce presence of 0x prefix!
101
+ *
102
+ * @param s string input
103
+ */
104
+ export function isPrefixedHexString(s) {
105
+ return typeof s === 'string' && /^0x[0-9a-f]+$/i.test(s);
106
+ }
107
+ /**
108
+ * Verifies if the provided input is a HexString.
109
+ *
110
+ * TODO: Make Length mandatory: https://github.com/ethersphere/bee-js/issues/208
111
+ *
112
+ * @param s string input
113
+ * @param len expected length of the HexString
114
+ * @param name optional name for the asserted value
115
+ * @returns HexString or throws error
116
+ */
117
+ export function assertHexString(s, len, name = 'value') {
118
+ if (!isHexString(s, len)) {
119
+ if (isPrefixedHexString(s)) {
120
+ throw new TypeError(`${name} not valid non prefixed hex string (has 0x prefix): ${s}`);
121
+ }
122
+ // Don't display length error if no length specified in order not to confuse user
123
+ const lengthMsg = len ? ` of length ${len}` : '';
124
+ throw new TypeError(`${name} not valid hex string${lengthMsg}: ${s}`);
125
+ }
126
+ }
127
+ /**
128
+ * Verifies if the provided input is a PrefixedHexString.
129
+ *
130
+ * @param s string input
131
+ * @param len expected length of the HexString
132
+ * @param name optional name for the asserted value
133
+ * @returns HexString or throws error
134
+ */
135
+ export function assertPrefixedHexString(s, name = 'value') {
136
+ if (!isPrefixedHexString(s)) {
137
+ throw new TypeError(`${name} not valid prefixed hex string: ${s}`);
138
+ }
139
+ }
@@ -0,0 +1,136 @@
1
+ import { BeeError, BeeNotAJsonError, BeeRequestError, BeeResponseError } from './error';
2
+ import kyFactory from 'ky-universal';
3
+ import { normalizeToReadableStream } from './stream';
4
+ import { deepMerge } from './merge';
5
+ import { isObject, isStrictlyObject } from './type';
6
+ const DEFAULT_KY_CONFIG = {
7
+ headers: {
8
+ accept: 'application/json, text/plain, */*',
9
+ 'user-agent': `bee-js`,
10
+ },
11
+ };
12
+ function isHttpError(e) {
13
+ return isObject(e) && typeof e.response !== 'undefined';
14
+ }
15
+ function isHttpRequestError(e) {
16
+ return isObject(e) && typeof e.request !== 'undefined';
17
+ }
18
+ function headersToObject(header) {
19
+ return [...header.entries()].reduce((obj, [key, val]) => {
20
+ obj[key] = val;
21
+ return obj;
22
+ }, {});
23
+ }
24
+ function wrapRequest(request) {
25
+ return {
26
+ url: request.url,
27
+ method: request.method.toUpperCase(),
28
+ headers: headersToObject(request.headers),
29
+ };
30
+ }
31
+ export function wrapRequestClosure(cb) {
32
+ return async (request) => {
33
+ await cb(wrapRequest(request));
34
+ };
35
+ }
36
+ export function wrapResponseClosure(cb) {
37
+ return async (request, options, response) => {
38
+ await cb({
39
+ headers: headersToObject(response.headers),
40
+ status: response.status,
41
+ statusText: response.statusText,
42
+ request: wrapRequest(request),
43
+ });
44
+ };
45
+ }
46
+ /**
47
+ * Filters out entries that has undefined value from headers object.
48
+ * Modifies the original object!
49
+ *
50
+ * @param obj
51
+ */
52
+ // eslint-disable-next-line @typescript-eslint/ban-types
53
+ export function filterHeaders(obj) {
54
+ if (obj === undefined) {
55
+ return undefined;
56
+ }
57
+ isStrictlyObject(obj);
58
+ const typedObj = obj;
59
+ for (const key in typedObj) {
60
+ if (typedObj[key] === undefined) {
61
+ delete typedObj[key];
62
+ }
63
+ }
64
+ if (Object.keys(typedObj).length === 0) {
65
+ return undefined;
66
+ }
67
+ return typedObj;
68
+ }
69
+ /**
70
+ * Main utility function to make HTTP requests.
71
+ * @param ky
72
+ * @param config
73
+ */
74
+ export async function http(ky, config) {
75
+ try {
76
+ const { path, responseType, ...kyConfig } = config;
77
+ const response = (await ky(path, {
78
+ ...kyConfig,
79
+ searchParams: filterHeaders(kyConfig.searchParams),
80
+ }));
81
+ switch (responseType) {
82
+ case 'stream':
83
+ if (!response.body) {
84
+ throw new BeeError('Response was expected to get data but did not get any!');
85
+ }
86
+ response.data = normalizeToReadableStream(response.body);
87
+ break;
88
+ case 'arraybuffer':
89
+ response.data = (await response.arrayBuffer());
90
+ break;
91
+ case 'json':
92
+ try {
93
+ response.data = (await response.json());
94
+ }
95
+ catch (e) {
96
+ throw new BeeNotAJsonError();
97
+ }
98
+ break;
99
+ default:
100
+ break; // If responseType is not set, then no data are expected
101
+ }
102
+ return response;
103
+ }
104
+ catch (e) {
105
+ // Passthrough thrown errors
106
+ if (e instanceof BeeNotAJsonError) {
107
+ throw e;
108
+ }
109
+ if (isHttpError(e)) {
110
+ let message;
111
+ // We store the response body here as it can be read only once in Response's lifecycle so to make it exposed
112
+ // to the user in the BeeResponseError, for further analysis.
113
+ const body = await e.response.text();
114
+ try {
115
+ // The response can be Bee's JSON with structure `{code, message}` lets try to parse it
116
+ message = JSON.parse(body).message;
117
+ }
118
+ catch (e) { }
119
+ if (message) {
120
+ throw new BeeResponseError(e.response.status, e.response, body, config, `${e.response.statusText}: ${message}`);
121
+ }
122
+ else {
123
+ throw new BeeResponseError(e.response.status, e.response, body, config, e.response.statusText);
124
+ }
125
+ }
126
+ else if (isHttpRequestError(e)) {
127
+ throw new BeeRequestError(e.message, config);
128
+ }
129
+ else {
130
+ throw new BeeError(e.message);
131
+ }
132
+ }
133
+ }
134
+ export function makeDefaultKy(kyConfig) {
135
+ return kyFactory.create(deepMerge(DEFAULT_KY_CONFIG, kyConfig));
136
+ }
@@ -0,0 +1,30 @@
1
+ import { isObject } from './type';
2
+ /**
3
+ * Function that deep merges objects
4
+ *
5
+ * @copyright https://github.com/sindresorhus/ky/blob/b3c9e88fa49d50150dbb6e6b771b4af56cb40c98/source/utils/merge.ts
6
+ * @licence MIT
7
+ * @param sources
8
+ */
9
+ export function deepMerge(...sources) {
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ let returnValue = {};
12
+ for (const source of sources) {
13
+ if (Array.isArray(source)) {
14
+ if (!Array.isArray(returnValue)) {
15
+ returnValue = [];
16
+ }
17
+ returnValue = [...returnValue, ...source];
18
+ }
19
+ else if (isObject(source)) {
20
+ // eslint-disable-next-line prefer-const
21
+ for (let [key, value] of Object.entries(source)) {
22
+ if (isObject(value) && key in returnValue) {
23
+ value = deepMerge(returnValue[key], value);
24
+ }
25
+ returnValue = { ...returnValue, [key]: value };
26
+ }
27
+ }
28
+ }
29
+ return returnValue;
30
+ }