@ethersphere/bee-js 10.4.0 → 11.1.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 (81) hide show
  1. package/dist/cjs/bee.js +17 -10
  2. package/dist/cjs/chunk/bmt.js +1 -2
  3. package/dist/cjs/chunk/cac.js +3 -3
  4. package/dist/cjs/chunk/soc.js +24 -15
  5. package/dist/cjs/feed/identifier.js +1 -2
  6. package/dist/cjs/feed/index.js +25 -16
  7. package/dist/cjs/feed/retrievable.js +1 -2
  8. package/dist/cjs/index.js +17 -7
  9. package/dist/cjs/modules/bytes.js +4 -5
  10. package/dist/cjs/modules/bzz.js +4 -5
  11. package/dist/cjs/modules/chunk.js +2 -3
  12. package/dist/cjs/modules/debug/balance.js +4 -5
  13. package/dist/cjs/modules/debug/chequebook.js +8 -9
  14. package/dist/cjs/modules/debug/connectivity.js +7 -8
  15. package/dist/cjs/modules/debug/settlements.js +2 -3
  16. package/dist/cjs/modules/debug/stake.js +6 -7
  17. package/dist/cjs/modules/debug/stamps.js +7 -8
  18. package/dist/cjs/modules/debug/states.js +6 -6
  19. package/dist/cjs/modules/debug/status.js +9 -9
  20. package/dist/cjs/modules/debug/transactions.js +4 -5
  21. package/dist/cjs/modules/envelope.js +1 -2
  22. package/dist/cjs/modules/feed.js +3 -4
  23. package/dist/cjs/modules/grantee.js +3 -4
  24. package/dist/cjs/modules/gsoc.js +2 -3
  25. package/dist/cjs/modules/pinning.js +4 -5
  26. package/dist/cjs/modules/pss.js +2 -3
  27. package/dist/cjs/modules/rchash.js +1 -2
  28. package/dist/cjs/modules/soc.js +1 -2
  29. package/dist/cjs/modules/status.js +2 -3
  30. package/dist/cjs/modules/stewardship.js +2 -3
  31. package/dist/cjs/modules/tag.js +5 -6
  32. package/dist/cjs/types/debug.js +3 -3
  33. package/dist/cjs/types/index.js +2 -2
  34. package/dist/cjs/utils/bytes.js +2 -2
  35. package/dist/cjs/utils/chunk-size.js +1 -2
  36. package/dist/cjs/utils/chunk-stream.browser.js +30 -6
  37. package/dist/cjs/utils/chunk-stream.js +3 -4
  38. package/dist/cjs/utils/cid.js +3 -3
  39. package/dist/cjs/utils/collection.browser.js +2 -3
  40. package/dist/cjs/utils/collection.js +5 -6
  41. package/dist/cjs/utils/collection.node.js +2 -3
  42. package/dist/cjs/utils/data.browser.js +1 -2
  43. package/dist/cjs/utils/data.js +1 -2
  44. package/dist/cjs/utils/expose.js +2 -1
  45. package/dist/cjs/utils/file.js +2 -3
  46. package/dist/cjs/utils/headers.js +2 -3
  47. package/dist/cjs/utils/http.js +17 -3
  48. package/dist/cjs/utils/pss.js +1 -2
  49. package/dist/cjs/utils/redundancy.js +3 -4
  50. package/dist/cjs/utils/stamps.js +12 -13
  51. package/dist/cjs/utils/tar-uploader.browser.js +1 -2
  52. package/dist/cjs/utils/tar-uploader.js +1 -2
  53. package/dist/cjs/utils/tar-writer.browser.js +1 -2
  54. package/dist/cjs/utils/tar-writer.js +1 -2
  55. package/dist/cjs/utils/type.js +35 -25
  56. package/dist/cjs/utils/url.js +3 -4
  57. package/dist/cjs/utils/workaround.js +2 -3
  58. package/dist/index.browser.min.js +1 -1
  59. package/dist/index.browser.min.js.map +1 -1
  60. package/dist/mjs/bee.js +0 -3
  61. package/dist/mjs/modules/debug/states.js +3 -0
  62. package/dist/mjs/modules/debug/status.js +1 -1
  63. package/dist/mjs/utils/chunk-stream.browser.js +29 -5
  64. package/dist/mjs/utils/expose.js +1 -1
  65. package/dist/mjs/utils/http.js +17 -1
  66. package/dist/mjs/utils/type.js +2 -1
  67. package/dist/types/bee.d.ts +0 -4
  68. package/dist/types/index.d.ts +1 -0
  69. package/dist/types/modules/bzz.d.ts +0 -1
  70. package/dist/types/modules/debug/status.d.ts +1 -1
  71. package/dist/types/modules/gsoc.d.ts +0 -1
  72. package/dist/types/modules/pss.d.ts +0 -1
  73. package/dist/types/types/debug.d.ts +1 -0
  74. package/dist/types/types/index.d.ts +1 -0
  75. package/dist/types/utils/constants.d.ts +3 -3
  76. package/dist/types/utils/error.d.ts +2 -2
  77. package/dist/types/utils/expose.d.ts +1 -1
  78. package/dist/types/utils/tar.browser.d.ts +1 -1
  79. package/dist/types/utils/tar.d.ts +0 -1
  80. package/dist/types/utils/type.d.ts +0 -1
  81. package/package.json +10 -13
package/dist/mjs/bee.js CHANGED
@@ -953,9 +953,6 @@ export class Bee {
953
953
  *
954
954
  * @param rawPayload Data to be stored in the chunk. If the data is a string, it will be converted to UTF-8 bytes.
955
955
  * @param span Optional span for the chunk. If not provided, it will be set to the length of the payload.
956
- *
957
- * @example
958
- *
959
956
  */
960
957
  makeContentAddressedChunk(rawPayload, span) {
961
958
  return makeContentAddressedChunk(rawPayload, span);
@@ -30,6 +30,9 @@ export async function getReserveState(requestOptions) {
30
30
  }),
31
31
  storageRadius: Types.asNumber(body.storageRadius, {
32
32
  name: 'storageRadius'
33
+ }),
34
+ reserveCapacityDoubling: Types.asNumber(body.reserveCapacityDoubling, {
35
+ name: 'reserveCapacityDoubling'
33
36
  })
34
37
  };
35
38
  }
@@ -2,7 +2,7 @@ import { Types } from 'cafe-utility';
2
2
  import getMajorSemver from 'semver/functions/major.js';
3
3
  import { toBeeMode } from "../../types/debug.js";
4
4
  import { http } from "../../utils/http.js";
5
- export const SUPPORTED_BEE_VERSION_EXACT = '2.6.0-d0aa8b93';
5
+ export const SUPPORTED_BEE_VERSION_EXACT = '2.7.0-6ddf9b45';
6
6
  export const SUPPORTED_BEE_VERSION = SUPPORTED_BEE_VERSION_EXACT.split('-')[0];
7
7
  export const SUPPORTED_API_VERSION = '7.3.0';
8
8
  const NODE_INFO_URL = 'node';
@@ -12,6 +12,10 @@ export async function streamDirectory(_bee, _dir, _postageBatchId, _onUploadProg
12
12
  throw new Error('Streaming directories is not supported in browsers!');
13
13
  }
14
14
  export async function streamFiles(bee, files, postageBatchId, onUploadProgress, options, requestOptions) {
15
+ const signal = requestOptions?.signal;
16
+ if (signal?.aborted) {
17
+ throw new Error('Request aborted');
18
+ }
15
19
  const queue = new AsyncQueue(64, 64);
16
20
  let total = 0;
17
21
  let processed = 0;
@@ -21,15 +25,28 @@ export async function streamFiles(bee, files, postageBatchId, onUploadProgress,
21
25
  postageBatchId = new BatchId(postageBatchId);
22
26
  async function onChunk(chunk) {
23
27
  await queue.enqueue(async () => {
24
- await bee.uploadChunk(postageBatchId, chunk.build(), options, requestOptions);
25
- onUploadProgress?.({
26
- total,
27
- processed: ++processed
28
- });
28
+ if (signal?.aborted) {
29
+ return;
30
+ }
31
+ try {
32
+ await bee.uploadChunk(postageBatchId, chunk.build(), options, requestOptions);
33
+ onUploadProgress?.({
34
+ total,
35
+ processed: ++processed
36
+ });
37
+ } catch (err) {
38
+ if (signal?.aborted) {
39
+ return;
40
+ }
41
+ throw err;
42
+ }
29
43
  });
30
44
  }
31
45
  const mantaray = new MantarayNode();
32
46
  for (const file of files) {
47
+ if (signal?.aborted) {
48
+ throw new Error('Request aborted');
49
+ }
33
50
  const rootChunk = await new Promise((resolve, reject) => {
34
51
  const tree = new MerkleTree(onChunk);
35
52
  let offset = 0;
@@ -38,6 +55,10 @@ export async function streamFiles(bee, files, postageBatchId, onUploadProgress,
38
55
  reject(reader.error);
39
56
  };
40
57
  const readNextChunk = async () => {
58
+ if (signal?.aborted) {
59
+ reject(new Error('Request aborted'));
60
+ return;
61
+ }
41
62
  if (offset >= file.size) {
42
63
  const rootChunk = await tree.finalize();
43
64
  resolve(rootChunk);
@@ -75,6 +96,9 @@ export async function streamFiles(bee, files, postageBatchId, onUploadProgress,
75
96
  });
76
97
  }
77
98
  }
99
+ if (signal?.aborted) {
100
+ throw new Error('Request aborted');
101
+ }
78
102
  return mantaray.saveRecursively(bee, postageBatchId, options, requestOptions);
79
103
  }
80
104
  function maybeEnrichMime(mime) {
@@ -2,4 +2,4 @@ export { getCollectionSize, makeCollectionFromFileList } from "./collection.js";
2
2
  export { getFolderSize } from "./collection.node.js";
3
3
  export { makeMaxTarget } from "./pss.js";
4
4
  export { approximateOverheadForRedundancyLevel, getRedundancyStat, getRedundancyStats } from "./redundancy.js";
5
- export { getAmountForDuration, getDepthForSize, getStampCost, getStampDuration, getStampEffectiveBytes, getStampEffectiveBytesBreakpoints, getStampTheoreticalBytes, getStampUsage, mapPostageBatch, unmapPostageBatch } from "./stamps.js";
5
+ export { convertEnvelopeToMarshaledStamp, getAmountForDuration, getDepthForSize, getStampCost, getStampDuration, getStampEffectiveBytes, getStampEffectiveBytesBreakpoints, getStampTheoreticalBytes, getStampUsage, mapPostageBatch, unmapPostageBatch } from "./stamps.js";
@@ -10,6 +10,7 @@ const MAX_FAILED_ATTEMPTS = 100000;
10
10
  const DELAY_FAST = 200;
11
11
  const DELAY_SLOW = 1000;
12
12
  const DELAY_THRESHOLD = Dates.minutes(1) / DELAY_FAST;
13
+ const ABORT_ERROR_MESSAGE = 'Request aborted';
13
14
  export const DEFAULT_HTTP_CONFIG = {
14
15
  headers: {
15
16
  accept: 'application/json, text/plain, */*'
@@ -17,6 +18,11 @@ export const DEFAULT_HTTP_CONFIG = {
17
18
  maxBodyLength: Infinity,
18
19
  maxContentLength: Infinity
19
20
  };
21
+ function throwIfAborted(signal, config, responseData, responseStatus) {
22
+ if (signal?.aborted) {
23
+ throw new BeeResponseError(config.method || 'get', config.url || '<unknown>', ABORT_ERROR_MESSAGE, responseData, responseStatus, 'ERR_CANCELED');
24
+ }
25
+ }
20
26
  /**
21
27
  * Main function to make HTTP requests.
22
28
  * @param options User defined settings
@@ -24,6 +30,10 @@ export const DEFAULT_HTTP_CONFIG = {
24
30
  */
25
31
  export async function http(options, config) {
26
32
  const requestConfig = Objects.deepMerge3(DEFAULT_HTTP_CONFIG, config, options);
33
+ if (options.signal) {
34
+ requestConfig.signal = options.signal;
35
+ throwIfAborted(options.signal, config);
36
+ }
27
37
  if (requestConfig.data && typeof Buffer !== 'undefined' && Buffer.isBuffer(requestConfig.data)) {
28
38
  requestConfig.data = requestConfig.data.buffer.slice(requestConfig.data.byteOffset, requestConfig.data.byteOffset + requestConfig.data.byteLength);
29
39
  }
@@ -38,6 +48,7 @@ export async function http(options, config) {
38
48
  }
39
49
  let failedAttempts = 0;
40
50
  while (failedAttempts < MAX_FAILED_ATTEMPTS) {
51
+ throwIfAborted(options.signal, config);
41
52
  try {
42
53
  debug(`${requestConfig.method || 'get'} ${Strings.joinUrl([requestConfig.baseURL, requestConfig.url])}`, {
43
54
  headers: {
@@ -50,11 +61,16 @@ export async function http(options, config) {
50
61
  return response;
51
62
  } catch (e) {
52
63
  if (e instanceof AxiosError) {
64
+ if (e.code === 'ERR_CANCELED') {
65
+ throwIfAborted({
66
+ aborted: true
67
+ }, config, e.response?.data, e.response?.status);
68
+ }
53
69
  if (e.code === 'ECONNABORTED' && options.endlesslyRetry) {
54
70
  failedAttempts++;
55
71
  await System.sleepMillis(failedAttempts < DELAY_THRESHOLD ? DELAY_FAST : DELAY_SLOW);
56
72
  } else {
57
- throw new BeeResponseError(config.method || 'get', config.url || '<unknown>', e.message, e.response?.data, e.response?.status, e.code);
73
+ throw new BeeResponseError(config.method || 'get', config.url || '<unknown>', e.message, e.response?.data, e.response?.status, e.response?.statusText);
58
74
  }
59
75
  } else {
60
76
  throw e;
@@ -34,7 +34,8 @@ export function prepareBeeRequestOptions(value) {
34
34
  httpsAgent: object.httpsAgent,
35
35
  endlesslyRetry: Types.asOptional(x => Types.asBoolean(x, {
36
36
  name: 'endlesslyRetry'
37
- }), object.endlesslyRetry)
37
+ }), object.endlesslyRetry),
38
+ signal: object.signal
38
39
  };
39
40
  }
40
41
  export function prepareDownloadOptions(value) {
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { Readable } from 'stream';
3
2
  import { Chunk } from './chunk/cac';
4
3
  import { SingleOwnerChunk } from './chunk/soc';
@@ -618,9 +617,6 @@ export declare class Bee {
618
617
  *
619
618
  * @param rawPayload Data to be stored in the chunk. If the data is a string, it will be converted to UTF-8 bytes.
620
619
  * @param span Optional span for the chunk. If not provided, it will be set to the length of the payload.
621
- *
622
- * @example
623
- *
624
620
  */
625
621
  makeContentAddressedChunk(rawPayload: Bytes | Uint8Array | string, span?: Span | bigint): Chunk;
626
622
  /**
@@ -15,6 +15,7 @@ export * as Utils from './utils/expose';
15
15
  export { Size } from './utils/size';
16
16
  export * from './utils/tokens';
17
17
  export * from './utils/typed-bytes';
18
+ export type { UploadProgress } from './utils/upload-progress';
18
19
  export { Bee, BeeDev, Stamper };
19
20
  declare global {
20
21
  interface Window {
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { Readable } from 'stream';
3
2
  import { BeeRequestOptions, Collection, CollectionUploadOptions, DownloadOptions, FileData, FileUploadOptions, UploadResult } from '../types';
4
3
  import { Bytes } from '../utils/bytes';
@@ -1,7 +1,7 @@
1
1
  import { BeeRequestOptions } from '../../index';
2
2
  import type { DebugStatus, Health, NodeInfo, Readiness } from '../../types/debug';
3
3
  import { BeeVersions } from '../../types/debug';
4
- export declare const SUPPORTED_BEE_VERSION_EXACT = "2.6.0-d0aa8b93";
4
+ export declare const SUPPORTED_BEE_VERSION_EXACT = "2.7.0-6ddf9b45";
5
5
  export declare const SUPPORTED_BEE_VERSION: string;
6
6
  export declare const SUPPORTED_API_VERSION = "7.3.0";
7
7
  export declare function getDebugStatus(requestOptions: BeeRequestOptions): Promise<DebugStatus>;
@@ -1,4 +1,3 @@
1
- /// <reference types="ws" />
2
1
  import WebSocket from 'isomorphic-ws';
3
2
  import { BeeRequestOptions, UploadOptions } from '..';
4
3
  import { SingleOwnerChunk } from '../chunk/soc';
@@ -1,4 +1,3 @@
1
- /// <reference types="ws" />
2
1
  import WebSocket from 'isomorphic-ws';
3
2
  import type { BeeRequestOptions } from '../types';
4
3
  import { BatchId, PublicKey, Topic } from '../utils/typed-bytes';
@@ -212,6 +212,7 @@ export interface ReserveState {
212
212
  radius: number;
213
213
  storageRadius: number;
214
214
  commitment: number;
215
+ reserveCapacityDoubling: number;
215
216
  }
216
217
  export interface ChainState {
217
218
  chainTip: number;
@@ -39,6 +39,7 @@ export type BeeRequestOptions = {
39
39
  httpAgent?: unknown;
40
40
  httpsAgent?: unknown;
41
41
  endlesslyRetry?: boolean;
42
+ signal?: AbortSignal;
42
43
  };
43
44
  /**
44
45
  * Options for the Bee client which affect all method calls *(unless overridden in the method call itself)*.
@@ -2,6 +2,6 @@ import { BatchId, Topic } from './typed-bytes';
2
2
  export declare const SWARM_GATEWAY_URL = "https://api.gateway.ethswarm.org";
3
3
  export declare const NULL_STAMP: BatchId;
4
4
  export declare const NULL_TOPIC: Topic;
5
- export declare const NULL_ADDRESS: Uint8Array;
6
- export declare const NULL_IDENTIFIER: Uint8Array;
7
- export declare const NULL_OWNER: Uint8Array;
5
+ export declare const NULL_ADDRESS: Uint8Array<ArrayBuffer>;
6
+ export declare const NULL_IDENTIFIER: Uint8Array<ArrayBuffer>;
7
+ export declare const NULL_OWNER: Uint8Array<ArrayBuffer>;
@@ -8,8 +8,8 @@ export declare class BeeArgumentError extends BeeError {
8
8
  export declare class BeeResponseError extends BeeError {
9
9
  method: string;
10
10
  url: string;
11
- responseBody?: unknown;
11
+ responseBody?: unknown | undefined;
12
12
  status?: number | undefined;
13
13
  statusText?: string | undefined;
14
- constructor(method: string, url: string, message: string, responseBody?: unknown, status?: number | undefined, statusText?: string | undefined);
14
+ constructor(method: string, url: string, message: string, responseBody?: unknown | undefined, status?: number | undefined, statusText?: string | undefined);
15
15
  }
@@ -2,4 +2,4 @@ export { getCollectionSize, makeCollectionFromFileList } from './collection';
2
2
  export { getFolderSize } from './collection.node';
3
3
  export { makeMaxTarget } from './pss';
4
4
  export { approximateOverheadForRedundancyLevel, getRedundancyStat, getRedundancyStats } from './redundancy';
5
- export { getAmountForDuration, getDepthForSize, getStampCost, getStampDuration, getStampEffectiveBytes, getStampEffectiveBytesBreakpoints, getStampTheoreticalBytes, getStampUsage, mapPostageBatch, unmapPostageBatch, } from './stamps';
5
+ export { convertEnvelopeToMarshaledStamp, getAmountForDuration, getDepthForSize, getStampCost, getStampDuration, getStampEffectiveBytes, getStampEffectiveBytesBreakpoints, getStampTheoreticalBytes, getStampUsage, mapPostageBatch, unmapPostageBatch, } from './stamps';
@@ -1,7 +1,7 @@
1
1
  export declare class TarStream {
2
2
  pieces: Uint8Array[];
3
3
  currentFileSize: number;
4
- get output(): Uint8Array;
4
+ get output(): Uint8Array<ArrayBufferLike>;
5
5
  beginFile(path: string, size: number): void;
6
6
  appendFile(data: Uint8Array): Promise<void>;
7
7
  endFile(): Promise<void>;
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { PassThrough } from 'stream';
3
2
  export declare class TarStream {
4
3
  output: PassThrough;
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import * as stream from 'stream';
3
2
  import { AllTagsOptions, BeeRequestOptions, CollectionUploadOptions, DownloadOptions, FileUploadOptions, GsocMessageHandler, NumberString, PostageBatchOptions, PssMessageHandler, RedundantUploadOptions, Tag, TransactionOptions, UploadOptions } from '../types';
4
3
  export declare function isReadable(value: unknown): value is stream.Readable;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ethersphere/bee-js",
3
- "version": "10.4.0",
3
+ "version": "11.1.0",
4
4
  "description": "Javascript client for Bee",
5
5
  "keywords": [
6
6
  "bee",
@@ -50,19 +50,19 @@
50
50
  "dist"
51
51
  ],
52
52
  "scripts": {
53
- "prepublishOnly": "cross-env NODE_ENV=production npm run build",
53
+ "prepublishOnly": "NODE_ENV=production npm run build",
54
54
  "build": "rimraf dist && npm run build:node && npm run build:types && npm run build:browser",
55
55
  "build:node": "tsc -p tsconfig.json && tsc -p tsconfig-mjs.json && ./build-fixup && babel --plugins \"babel-plugin-add-import-extension\" --out-dir dist/mjs/ dist/mjs/",
56
56
  "build:types": "tsc --emitDeclarationOnly --declaration --outDir dist/types",
57
57
  "build:browser": "webpack --progress",
58
- "test": "jest --config=jest.config.ts --runInBand --verbose --forceExit",
58
+ "test": "TS_NODE_PROJECT=tsconfig.test.json jest --runInBand --verbose --forceExit",
59
59
  "check": "tsc --project tsconfig.test.json",
60
60
  "lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\" && prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
61
61
  "depcheck": "depcheck ."
62
62
  },
63
63
  "dependencies": {
64
- "axios": "^0.30.0",
65
- "cafe-utility": "^33.3.4",
64
+ "axios": "^0.30.2",
65
+ "cafe-utility": "^33.6.1",
66
66
  "debug": "^4.4.1",
67
67
  "isomorphic-ws": "^4.0.1",
68
68
  "semver": "^7.3.5",
@@ -77,10 +77,8 @@
77
77
  "@babel/preset-typescript": "^7.18.6",
78
78
  "@commitlint/cli": "^17.0.2",
79
79
  "@commitlint/config-conventional": "^17.4.2",
80
- "@jest/types": "^29.6.3",
81
- "@naholyr/cross-env": "^1.0.0",
82
80
  "@types/debug": "^4.1.12",
83
- "@types/jest": "^29.5.13",
81
+ "@types/jest": "^30.0.0",
84
82
  "@types/node": "^18.11.11",
85
83
  "@types/semver": "^7.3.9",
86
84
  "@types/ws": "^8.5.3",
@@ -88,20 +86,19 @@
88
86
  "@typescript-eslint/parser": "^5.46.0",
89
87
  "babel-loader": "^9.1.0",
90
88
  "babel-plugin-add-import-extension": "^1.6.0",
91
- "cross-env": "^7.0.3",
92
89
  "depcheck": "^1.4.7",
93
90
  "eslint": "^8.13.0",
94
91
  "eslint-config-prettier": "^8.5.0",
95
92
  "eslint-plugin-prettier": "^4.0.0",
96
93
  "eslint-plugin-unused-imports": "^2.0.0",
97
94
  "husky": "^8.0.1",
98
- "jest": "^29.7.0",
95
+ "jest": "^30.2.0",
99
96
  "prettier": "^2.6.2",
100
97
  "rimraf": "^3.0.2",
101
98
  "terser-webpack-plugin": "^5.3.1",
102
- "ts-jest": "^29.2.5",
103
- "ts-node": "^10.9.1",
104
- "typescript": "^4.9.5",
99
+ "ts-jest": "^29.4.6",
100
+ "ts-node": "^10.9.2",
101
+ "typescript": "^5.9.3",
105
102
  "webpack": "^5.75.0",
106
103
  "webpack-cli": "^5.0.1"
107
104
  }