@azure/storage-common 12.5.0 → 12.6.0-beta.1

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 (107) hide show
  1. package/dist/browser/StorageResponseFormat.d.ts +1 -1
  2. package/dist/browser/StorageResponseFormat.js +1 -1
  3. package/dist/browser/StorageResponseFormat.js.map +1 -1
  4. package/dist/browser/StructuredMessageEncodingStream-browser.d.mts.map +1 -1
  5. package/dist/browser/StructuredMessageEncodingStream-browser.mjs +1 -2
  6. package/dist/browser/StructuredMessageEncodingStream-browser.mjs.map +1 -1
  7. package/dist/browser/package.json +6 -1
  8. package/dist/browser/policies/StorageRetryPolicy.js +1 -1
  9. package/dist/browser/policies/StorageRetryPolicy.js.map +1 -1
  10. package/dist/browser/policies/StorageRetryPolicyV2.d.ts.map +1 -1
  11. package/dist/browser/policies/StorageRetryPolicyV2.js +28 -0
  12. package/dist/browser/policies/StorageRetryPolicyV2.js.map +1 -1
  13. package/dist/browser/utils/constants.d.ts.map +1 -1
  14. package/dist/browser/utils/constants.js +1 -1
  15. package/dist/browser/utils/constants.js.map +1 -1
  16. package/dist/browser/utils/utils.common.d.ts.map +1 -1
  17. package/dist/browser/utils/utils.common.js +5 -9
  18. package/dist/browser/utils/utils.common.js.map +1 -1
  19. package/dist/commonjs/BufferScheduler.d.ts.map +1 -1
  20. package/dist/commonjs/BufferScheduler.js +24 -7
  21. package/dist/commonjs/BufferScheduler.js.map +2 -2
  22. package/dist/commonjs/BuffersStream.d.ts.map +1 -1
  23. package/dist/commonjs/BuffersStream.js +0 -1
  24. package/dist/commonjs/BuffersStream.js.map +2 -2
  25. package/dist/commonjs/StorageResponseFormat.d.ts +1 -1
  26. package/dist/commonjs/StorageResponseFormat.js +1 -1
  27. package/dist/commonjs/StorageResponseFormat.js.map +1 -1
  28. package/dist/commonjs/indexPlatform.d.ts +1 -0
  29. package/dist/commonjs/indexPlatform.d.ts.map +1 -1
  30. package/dist/commonjs/indexPlatform.js +3 -0
  31. package/dist/commonjs/indexPlatform.js.map +2 -2
  32. package/dist/commonjs/package.json +6 -1
  33. package/dist/commonjs/policies/SharedKeySigning.d.ts +32 -0
  34. package/dist/commonjs/policies/SharedKeySigning.d.ts.map +1 -0
  35. package/dist/commonjs/policies/SharedKeySigning.js +125 -0
  36. package/dist/commonjs/policies/SharedKeySigning.js.map +7 -0
  37. package/dist/commonjs/policies/StorageRetryPolicy.js +1 -1
  38. package/dist/commonjs/policies/StorageRetryPolicy.js.map +2 -2
  39. package/dist/commonjs/policies/StorageRetryPolicyV2.d.ts.map +1 -1
  40. package/dist/commonjs/policies/StorageRetryPolicyV2.js +16 -0
  41. package/dist/commonjs/policies/StorageRetryPolicyV2.js.map +2 -2
  42. package/dist/commonjs/policies/StorageSharedKeyCredentialPolicy.d.ts +0 -28
  43. package/dist/commonjs/policies/StorageSharedKeyCredentialPolicy.d.ts.map +1 -1
  44. package/dist/commonjs/policies/StorageSharedKeyCredentialPolicy.js +10 -94
  45. package/dist/commonjs/policies/StorageSharedKeyCredentialPolicy.js.map +2 -2
  46. package/dist/commonjs/policies/StorageSharedKeyCredentialPolicyV2.d.ts.map +1 -1
  47. package/dist/commonjs/policies/StorageSharedKeyCredentialPolicyV2.js +2 -76
  48. package/dist/commonjs/policies/StorageSharedKeyCredentialPolicyV2.js.map +2 -2
  49. package/dist/commonjs/tsdoc-metadata.json +1 -1
  50. package/dist/commonjs/utils/constants.d.ts.map +1 -1
  51. package/dist/commonjs/utils/constants.js +1 -1
  52. package/dist/commonjs/utils/constants.js.map +1 -1
  53. package/dist/commonjs/utils/utils.common.d.ts.map +1 -1
  54. package/dist/commonjs/utils/utils.common.js +11 -9
  55. package/dist/commonjs/utils/utils.common.js.map +2 -2
  56. package/dist/esm/BufferScheduler.d.ts.map +1 -1
  57. package/dist/esm/BufferScheduler.js +29 -7
  58. package/dist/esm/BufferScheduler.js.map +1 -1
  59. package/dist/esm/BuffersStream.d.ts.map +1 -1
  60. package/dist/esm/BuffersStream.js +0 -1
  61. package/dist/esm/BuffersStream.js.map +1 -1
  62. package/dist/esm/StorageResponseFormat.d.ts +1 -1
  63. package/dist/esm/StorageResponseFormat.js +1 -1
  64. package/dist/esm/StorageResponseFormat.js.map +1 -1
  65. package/dist/esm/indexPlatform.d.ts +1 -0
  66. package/dist/esm/indexPlatform.d.ts.map +1 -1
  67. package/dist/esm/indexPlatform.js +1 -0
  68. package/dist/esm/indexPlatform.js.map +1 -1
  69. package/dist/esm/package.json +6 -1
  70. package/dist/esm/policies/SharedKeySigning.d.ts +32 -0
  71. package/dist/esm/policies/SharedKeySigning.d.ts.map +1 -0
  72. package/dist/esm/policies/SharedKeySigning.js +156 -0
  73. package/dist/esm/policies/SharedKeySigning.js.map +1 -0
  74. package/dist/esm/policies/StorageRetryPolicy.js +1 -1
  75. package/dist/esm/policies/StorageRetryPolicy.js.map +1 -1
  76. package/dist/esm/policies/StorageRetryPolicyV2.d.ts.map +1 -1
  77. package/dist/esm/policies/StorageRetryPolicyV2.js +28 -0
  78. package/dist/esm/policies/StorageRetryPolicyV2.js.map +1 -1
  79. package/dist/esm/policies/StorageSharedKeyCredentialPolicy.d.ts +0 -28
  80. package/dist/esm/policies/StorageSharedKeyCredentialPolicy.d.ts.map +1 -1
  81. package/dist/esm/policies/StorageSharedKeyCredentialPolicy.js +9 -105
  82. package/dist/esm/policies/StorageSharedKeyCredentialPolicy.js.map +1 -1
  83. package/dist/esm/policies/StorageSharedKeyCredentialPolicyV2.d.ts.map +1 -1
  84. package/dist/esm/policies/StorageSharedKeyCredentialPolicyV2.js +2 -101
  85. package/dist/esm/policies/StorageSharedKeyCredentialPolicyV2.js.map +1 -1
  86. package/dist/esm/utils/constants.d.ts.map +1 -1
  87. package/dist/esm/utils/constants.js +1 -1
  88. package/dist/esm/utils/constants.js.map +1 -1
  89. package/dist/esm/utils/utils.common.d.ts.map +1 -1
  90. package/dist/esm/utils/utils.common.js +5 -9
  91. package/dist/esm/utils/utils.common.js.map +1 -1
  92. package/dist/react-native/StorageResponseFormat.d.ts +1 -1
  93. package/dist/react-native/StorageResponseFormat.js +1 -1
  94. package/dist/react-native/StorageResponseFormat.js.map +1 -1
  95. package/dist/react-native/package.json +6 -1
  96. package/dist/react-native/policies/StorageRetryPolicy.js +1 -1
  97. package/dist/react-native/policies/StorageRetryPolicy.js.map +1 -1
  98. package/dist/react-native/policies/StorageRetryPolicyV2.d.ts.map +1 -1
  99. package/dist/react-native/policies/StorageRetryPolicyV2.js +28 -0
  100. package/dist/react-native/policies/StorageRetryPolicyV2.js.map +1 -1
  101. package/dist/react-native/utils/constants.d.ts.map +1 -1
  102. package/dist/react-native/utils/constants.js +1 -1
  103. package/dist/react-native/utils/constants.js.map +1 -1
  104. package/dist/react-native/utils/utils.common.d.ts.map +1 -1
  105. package/dist/react-native/utils/utils.common.js +5 -9
  106. package/dist/react-native/utils/utils.common.js.map +1 -1
  107. package/package.json +9 -9
@@ -130,10 +130,14 @@ class BufferScheduler {
130
130
  async do() {
131
131
  return new Promise((resolve, reject) => {
132
132
  this.readable.on("data", (data) => {
133
- data = typeof data === "string" ? Buffer.from(data, this.encoding) : data;
134
- this.appendUnresolvedData(data);
135
- if (!this.resolveData()) {
136
- this.readable.pause();
133
+ try {
134
+ data = typeof data === "string" ? Buffer.from(data, this.encoding) : data;
135
+ this.appendUnresolvedData(data);
136
+ if (!this.resolveData()) {
137
+ this.readable.pause();
138
+ }
139
+ } catch (err) {
140
+ this.emitter.emit("error", err);
137
141
  }
138
142
  });
139
143
  this.readable.on("error", (err) => {
@@ -149,13 +153,22 @@ class BufferScheduler {
149
153
  reject(err);
150
154
  });
151
155
  this.emitter.on("checkEnd", () => {
156
+ if (this.isError) {
157
+ return;
158
+ }
152
159
  if (this.outgoing.length > 0) {
153
160
  this.triggerOutgoingHandlers();
154
161
  return;
155
162
  }
156
163
  if (this.isStreamEnd && this.executingOutgoingHandlers === 0) {
157
164
  if (this.unresolvedLength > 0 && this.unresolvedLength < this.bufferSize) {
158
- const buffer = this.shiftBufferFromUnresolvedDataArray();
165
+ let buffer;
166
+ try {
167
+ buffer = this.shiftBufferFromUnresolvedDataArray();
168
+ } catch (err) {
169
+ this.emitter.emit("error", err);
170
+ return;
171
+ }
159
172
  this.outgoingHandler(() => buffer.getReadableStream(), buffer.size, this.offset).then(resolve).catch(reject);
160
173
  } else if (this.unresolvedLength >= this.bufferSize) {
161
174
  return;
@@ -263,8 +276,12 @@ class BufferScheduler {
263
276
  */
264
277
  reuseBuffer(buffer) {
265
278
  this.incoming.push(buffer);
266
- if (!this.isError && this.resolveData() && !this.isStreamEnd) {
267
- this.readable.resume();
279
+ try {
280
+ if (!this.isError && this.resolveData() && !this.isStreamEnd) {
281
+ this.readable.resume();
282
+ }
283
+ } catch (err) {
284
+ this.emitter.emit("error", err);
268
285
  }
269
286
  }
270
287
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/BufferScheduler.ts"],
4
- "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { EventEmitter } from \"events\";\nimport { PooledBuffer } from \"./PooledBuffer.js\";\n\n/**\n * OutgoingHandler is an async function triggered by BufferScheduler.\n */\nexport declare type OutgoingHandler = (\n body: () => NodeJS.ReadableStream,\n length: number,\n offset?: number,\n) => Promise<any>;\n\n/**\n * This class accepts a Node.js Readable stream as input, and keeps reading data\n * from the stream into the internal buffer structure, until it reaches maxBuffers.\n * Every available buffer will try to trigger outgoingHandler.\n *\n * The internal buffer structure includes an incoming buffer array, and a outgoing\n * buffer array. The incoming buffer array includes the \"empty\" buffers can be filled\n * with new incoming data. The outgoing array includes the filled buffers to be\n * handled by outgoingHandler. Every above buffer size is defined by parameter bufferSize.\n *\n * NUM_OF_ALL_BUFFERS = BUFFERS_IN_INCOMING + BUFFERS_IN_OUTGOING + BUFFERS_UNDER_HANDLING\n *\n * NUM_OF_ALL_BUFFERS lesser than or equal to maxBuffers\n *\n * PERFORMANCE IMPROVEMENT TIPS:\n * 1. Input stream highWaterMark is better to set a same value with bufferSize\n * parameter, which will avoid Buffer.concat() operations.\n * 2. concurrency should set a smaller value than maxBuffers, which is helpful to\n * reduce the possibility when a outgoing handler waits for the stream data.\n * in this situation, outgoing handlers are blocked.\n * Outgoing queue shouldn't be empty.\n */\nexport class BufferScheduler {\n /**\n * Size of buffers in incoming and outgoing queues. This class will try to align\n * data read from Readable stream into buffer chunks with bufferSize defined.\n */\n private readonly bufferSize: number;\n\n /**\n * How many buffers can be created or maintained.\n */\n private readonly maxBuffers: number;\n\n /**\n * A Node.js Readable stream.\n */\n private readonly readable: NodeJS.ReadableStream;\n\n /**\n * OutgoingHandler is an async function triggered by BufferScheduler when there\n * are available buffers in outgoing array.\n */\n private readonly outgoingHandler: OutgoingHandler;\n\n /**\n * An internal event emitter.\n */\n private readonly emitter: EventEmitter = new EventEmitter();\n\n /**\n * Concurrency of executing outgoingHandlers. (0 lesser than concurrency lesser than or equal to maxBuffers)\n */\n private readonly concurrency: number;\n\n /**\n * An internal offset marker to track data offset in bytes of next outgoingHandler.\n */\n private offset: number = 0;\n\n /**\n * An internal marker to track whether stream is end.\n */\n private isStreamEnd: boolean = false;\n\n /**\n * An internal marker to track whether stream or outgoingHandler returns error.\n */\n private isError: boolean = false;\n\n /**\n * How many handlers are executing.\n */\n private executingOutgoingHandlers: number = 0;\n\n /**\n * Encoding of the input Readable stream which has string data type instead of Buffer.\n */\n private encoding?: BufferEncoding;\n\n /**\n * How many buffers have been allocated.\n */\n private numBuffers: number = 0;\n\n /**\n * Because this class doesn't know how much data every time stream pops, which\n * is defined by highWaterMarker of the stream. So BufferScheduler will cache\n * data received from the stream, when data in unresolvedDataArray exceeds the\n * blockSize defined, it will try to concat a blockSize of buffer, fill into available\n * buffers from incoming and push to outgoing array.\n */\n private unresolvedDataArray: Buffer[] = [];\n\n /**\n * How much data consisted in unresolvedDataArray.\n */\n private unresolvedLength: number = 0;\n\n /**\n * The array includes all the available buffers can be used to fill data from stream.\n */\n private incoming: PooledBuffer[] = [];\n\n /**\n * The array (queue) includes all the buffers filled from stream data.\n */\n private outgoing: PooledBuffer[] = [];\n\n /**\n * Creates an instance of BufferScheduler.\n *\n * @param readable - A Node.js Readable stream\n * @param bufferSize - Buffer size of every maintained buffer\n * @param maxBuffers - How many buffers can be allocated\n * @param outgoingHandler - An async function scheduled to be\n * triggered when a buffer fully filled\n * with stream data\n * @param concurrency - Concurrency of executing outgoingHandlers (&gt;0)\n * @param encoding - [Optional] Encoding of Readable stream when it's a string stream\n */\n constructor(\n readable: NodeJS.ReadableStream,\n bufferSize: number,\n maxBuffers: number,\n outgoingHandler: OutgoingHandler,\n concurrency: number,\n encoding?: BufferEncoding,\n ) {\n if (bufferSize <= 0) {\n throw new RangeError(`bufferSize must be larger than 0, current is ${bufferSize}`);\n }\n\n if (maxBuffers <= 0) {\n throw new RangeError(`maxBuffers must be larger than 0, current is ${maxBuffers}`);\n }\n\n if (concurrency <= 0) {\n throw new RangeError(`concurrency must be larger than 0, current is ${concurrency}`);\n }\n\n this.bufferSize = bufferSize;\n this.maxBuffers = maxBuffers;\n this.readable = readable;\n this.outgoingHandler = outgoingHandler;\n this.concurrency = concurrency;\n this.encoding = encoding;\n }\n\n /**\n * Start the scheduler, will return error when stream of any of the outgoingHandlers\n * returns error.\n *\n */\n public async do(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.readable.on(\"data\", (data) => {\n data = typeof data === \"string\" ? Buffer.from(data, this.encoding) : data;\n this.appendUnresolvedData(data);\n\n if (!this.resolveData()) {\n this.readable.pause();\n }\n });\n\n this.readable.on(\"error\", (err) => {\n this.emitter.emit(\"error\", err);\n });\n\n this.readable.on(\"end\", () => {\n this.isStreamEnd = true;\n this.emitter.emit(\"checkEnd\");\n });\n\n this.emitter.on(\"error\", (err) => {\n this.isError = true;\n this.readable.pause();\n reject(err);\n });\n\n this.emitter.on(\"checkEnd\", () => {\n if (this.outgoing.length > 0) {\n this.triggerOutgoingHandlers();\n return;\n }\n\n if (this.isStreamEnd && this.executingOutgoingHandlers === 0) {\n if (this.unresolvedLength > 0 && this.unresolvedLength < this.bufferSize) {\n const buffer = this.shiftBufferFromUnresolvedDataArray();\n this.outgoingHandler(() => buffer.getReadableStream(), buffer.size, this.offset)\n .then(resolve)\n .catch(reject);\n } else if (this.unresolvedLength >= this.bufferSize) {\n return;\n } else {\n resolve();\n }\n }\n });\n });\n }\n\n /**\n * Insert a new data into unresolved array.\n *\n * @param data -\n */\n private appendUnresolvedData(data: Buffer): void {\n this.unresolvedDataArray.push(data);\n this.unresolvedLength += data.length;\n }\n\n /**\n * Try to shift a buffer with size in blockSize. The buffer returned may be less\n * than blockSize when data in unresolvedDataArray is less than bufferSize.\n *\n */\n private shiftBufferFromUnresolvedDataArray(buffer?: PooledBuffer): PooledBuffer {\n if (!buffer) {\n buffer = new PooledBuffer(this.bufferSize, this.unresolvedDataArray, this.unresolvedLength);\n } else {\n buffer.fill(this.unresolvedDataArray, this.unresolvedLength);\n }\n\n this.unresolvedLength -= buffer.size;\n return buffer;\n }\n\n /**\n * Resolve data in unresolvedDataArray. For every buffer with size in blockSize\n * shifted, it will try to get (or allocate a buffer) from incoming, and fill it,\n * then push it into outgoing to be handled by outgoing handler.\n *\n * Return false when available buffers in incoming are not enough, else true.\n *\n * @returns Return false when buffers in incoming are not enough, else true.\n */\n private resolveData(): boolean {\n while (this.unresolvedLength >= this.bufferSize) {\n let buffer: PooledBuffer;\n\n if (this.incoming.length > 0) {\n buffer = this.incoming.shift()!;\n this.shiftBufferFromUnresolvedDataArray(buffer);\n } else {\n if (this.numBuffers < this.maxBuffers) {\n buffer = this.shiftBufferFromUnresolvedDataArray();\n this.numBuffers++;\n } else {\n // No available buffer, wait for buffer returned\n return false;\n }\n }\n\n this.outgoing.push(buffer);\n this.triggerOutgoingHandlers();\n }\n return true;\n }\n\n /**\n * Try to trigger a outgoing handler for every buffer in outgoing. Stop when\n * concurrency reaches.\n */\n private async triggerOutgoingHandlers(): Promise<void> {\n let buffer: PooledBuffer | undefined;\n do {\n if (this.executingOutgoingHandlers >= this.concurrency) {\n return;\n }\n\n buffer = this.outgoing.shift();\n if (buffer) {\n this.triggerOutgoingHandler(buffer);\n }\n } while (buffer);\n }\n\n /**\n * Trigger a outgoing handler for a buffer shifted from outgoing.\n *\n * @param buffer -\n */\n private async triggerOutgoingHandler(buffer: PooledBuffer): Promise<any> {\n const bufferLength = buffer.size;\n\n this.executingOutgoingHandlers++;\n this.offset += bufferLength;\n\n try {\n await this.outgoingHandler(\n () => buffer.getReadableStream(),\n bufferLength,\n this.offset - bufferLength,\n );\n } catch (err: any) {\n this.emitter.emit(\"error\", err);\n return;\n }\n\n this.executingOutgoingHandlers--;\n this.reuseBuffer(buffer);\n this.emitter.emit(\"checkEnd\");\n }\n\n /**\n * Return buffer used by outgoing handler into incoming.\n *\n * @param buffer -\n */\n private reuseBuffer(buffer: PooledBuffer): void {\n this.incoming.push(buffer);\n if (!this.isError && this.resolveData() && !this.isStreamEnd) {\n this.readable.resume();\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { EventEmitter } from \"events\";\nimport { PooledBuffer } from \"./PooledBuffer.js\";\n\n/**\n * OutgoingHandler is an async function triggered by BufferScheduler.\n */\nexport declare type OutgoingHandler = (\n body: () => NodeJS.ReadableStream,\n length: number,\n offset?: number,\n) => Promise<any>;\n\n/**\n * This class accepts a Node.js Readable stream as input, and keeps reading data\n * from the stream into the internal buffer structure, until it reaches maxBuffers.\n * Every available buffer will try to trigger outgoingHandler.\n *\n * The internal buffer structure includes an incoming buffer array, and a outgoing\n * buffer array. The incoming buffer array includes the \"empty\" buffers can be filled\n * with new incoming data. The outgoing array includes the filled buffers to be\n * handled by outgoingHandler. Every above buffer size is defined by parameter bufferSize.\n *\n * NUM_OF_ALL_BUFFERS = BUFFERS_IN_INCOMING + BUFFERS_IN_OUTGOING + BUFFERS_UNDER_HANDLING\n *\n * NUM_OF_ALL_BUFFERS lesser than or equal to maxBuffers\n *\n * PERFORMANCE IMPROVEMENT TIPS:\n * 1. Input stream highWaterMark is better to set a same value with bufferSize\n * parameter, which will avoid Buffer.concat() operations.\n * 2. concurrency should set a smaller value than maxBuffers, which is helpful to\n * reduce the possibility when a outgoing handler waits for the stream data.\n * in this situation, outgoing handlers are blocked.\n * Outgoing queue shouldn't be empty.\n */\nexport class BufferScheduler {\n /**\n * Size of buffers in incoming and outgoing queues. This class will try to align\n * data read from Readable stream into buffer chunks with bufferSize defined.\n */\n private readonly bufferSize: number;\n\n /**\n * How many buffers can be created or maintained.\n */\n private readonly maxBuffers: number;\n\n /**\n * A Node.js Readable stream.\n */\n private readonly readable: NodeJS.ReadableStream;\n\n /**\n * OutgoingHandler is an async function triggered by BufferScheduler when there\n * are available buffers in outgoing array.\n */\n private readonly outgoingHandler: OutgoingHandler;\n\n /**\n * An internal event emitter.\n */\n private readonly emitter: EventEmitter = new EventEmitter();\n\n /**\n * Concurrency of executing outgoingHandlers. (0 lesser than concurrency lesser than or equal to maxBuffers)\n */\n private readonly concurrency: number;\n\n /**\n * An internal offset marker to track data offset in bytes of next outgoingHandler.\n */\n private offset: number = 0;\n\n /**\n * An internal marker to track whether stream is end.\n */\n private isStreamEnd: boolean = false;\n\n /**\n * An internal marker to track whether stream or outgoingHandler returns error.\n */\n private isError: boolean = false;\n\n /**\n * How many handlers are executing.\n */\n private executingOutgoingHandlers: number = 0;\n\n /**\n * Encoding of the input Readable stream which has string data type instead of Buffer.\n */\n private encoding?: BufferEncoding;\n\n /**\n * How many buffers have been allocated.\n */\n private numBuffers: number = 0;\n\n /**\n * Because this class doesn't know how much data every time stream pops, which\n * is defined by highWaterMarker of the stream. So BufferScheduler will cache\n * data received from the stream, when data in unresolvedDataArray exceeds the\n * blockSize defined, it will try to concat a blockSize of buffer, fill into available\n * buffers from incoming and push to outgoing array.\n */\n private unresolvedDataArray: Buffer[] = [];\n\n /**\n * How much data consisted in unresolvedDataArray.\n */\n private unresolvedLength: number = 0;\n\n /**\n * The array includes all the available buffers can be used to fill data from stream.\n */\n private incoming: PooledBuffer[] = [];\n\n /**\n * The array (queue) includes all the buffers filled from stream data.\n */\n private outgoing: PooledBuffer[] = [];\n\n /**\n * Creates an instance of BufferScheduler.\n *\n * @param readable - A Node.js Readable stream\n * @param bufferSize - Buffer size of every maintained buffer\n * @param maxBuffers - How many buffers can be allocated\n * @param outgoingHandler - An async function scheduled to be\n * triggered when a buffer fully filled\n * with stream data\n * @param concurrency - Concurrency of executing outgoingHandlers (&gt;0)\n * @param encoding - [Optional] Encoding of Readable stream when it's a string stream\n */\n constructor(\n readable: NodeJS.ReadableStream,\n bufferSize: number,\n maxBuffers: number,\n outgoingHandler: OutgoingHandler,\n concurrency: number,\n encoding?: BufferEncoding,\n ) {\n if (bufferSize <= 0) {\n throw new RangeError(`bufferSize must be larger than 0, current is ${bufferSize}`);\n }\n\n if (maxBuffers <= 0) {\n throw new RangeError(`maxBuffers must be larger than 0, current is ${maxBuffers}`);\n }\n\n if (concurrency <= 0) {\n throw new RangeError(`concurrency must be larger than 0, current is ${concurrency}`);\n }\n\n this.bufferSize = bufferSize;\n this.maxBuffers = maxBuffers;\n this.readable = readable;\n this.outgoingHandler = outgoingHandler;\n this.concurrency = concurrency;\n this.encoding = encoding;\n }\n\n /**\n * Start the scheduler, will return error when stream of any of the outgoingHandlers\n * returns error.\n *\n */\n public async do(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n this.readable.on(\"data\", (data) => {\n try {\n data = typeof data === \"string\" ? Buffer.from(data, this.encoding) : data;\n this.appendUnresolvedData(data);\n\n if (!this.resolveData()) {\n this.readable.pause();\n }\n } catch (err: any) {\n this.emitter.emit(\"error\", err);\n }\n });\n\n this.readable.on(\"error\", (err) => {\n this.emitter.emit(\"error\", err);\n });\n\n this.readable.on(\"end\", () => {\n this.isStreamEnd = true;\n this.emitter.emit(\"checkEnd\");\n });\n\n this.emitter.on(\"error\", (err) => {\n this.isError = true;\n this.readable.pause();\n reject(err);\n });\n\n this.emitter.on(\"checkEnd\", () => {\n // Handlers still in flight when the error was raised keep emitting \"checkEnd\";\n // without this the queued buffers would be uploaded after do() already rejected.\n if (this.isError) {\n return;\n }\n\n if (this.outgoing.length > 0) {\n this.triggerOutgoingHandlers();\n return;\n }\n\n if (this.isStreamEnd && this.executingOutgoingHandlers === 0) {\n if (this.unresolvedLength > 0 && this.unresolvedLength < this.bufferSize) {\n let buffer: PooledBuffer;\n try {\n buffer = this.shiftBufferFromUnresolvedDataArray();\n } catch (err: any) {\n this.emitter.emit(\"error\", err);\n return;\n }\n this.outgoingHandler(() => buffer.getReadableStream(), buffer.size, this.offset)\n .then(resolve)\n .catch(reject);\n } else if (this.unresolvedLength >= this.bufferSize) {\n return;\n } else {\n resolve();\n }\n }\n });\n });\n }\n\n /**\n * Insert a new data into unresolved array.\n *\n * @param data -\n */\n private appendUnresolvedData(data: Buffer): void {\n this.unresolvedDataArray.push(data);\n this.unresolvedLength += data.length;\n }\n\n /**\n * Try to shift a buffer with size in blockSize. The buffer returned may be less\n * than blockSize when data in unresolvedDataArray is less than bufferSize.\n *\n */\n private shiftBufferFromUnresolvedDataArray(buffer?: PooledBuffer): PooledBuffer {\n if (!buffer) {\n buffer = new PooledBuffer(this.bufferSize, this.unresolvedDataArray, this.unresolvedLength);\n } else {\n buffer.fill(this.unresolvedDataArray, this.unresolvedLength);\n }\n\n this.unresolvedLength -= buffer.size;\n return buffer;\n }\n\n /**\n * Resolve data in unresolvedDataArray. For every buffer with size in blockSize\n * shifted, it will try to get (or allocate a buffer) from incoming, and fill it,\n * then push it into outgoing to be handled by outgoing handler.\n *\n * Return false when available buffers in incoming are not enough, else true.\n *\n * @returns Return false when buffers in incoming are not enough, else true.\n */\n private resolveData(): boolean {\n while (this.unresolvedLength >= this.bufferSize) {\n let buffer: PooledBuffer;\n\n if (this.incoming.length > 0) {\n buffer = this.incoming.shift()!;\n this.shiftBufferFromUnresolvedDataArray(buffer);\n } else {\n if (this.numBuffers < this.maxBuffers) {\n buffer = this.shiftBufferFromUnresolvedDataArray();\n this.numBuffers++;\n } else {\n // No available buffer, wait for buffer returned\n return false;\n }\n }\n\n this.outgoing.push(buffer);\n this.triggerOutgoingHandlers();\n }\n return true;\n }\n\n /**\n * Try to trigger a outgoing handler for every buffer in outgoing. Stop when\n * concurrency reaches.\n */\n private async triggerOutgoingHandlers(): Promise<void> {\n let buffer: PooledBuffer | undefined;\n do {\n if (this.executingOutgoingHandlers >= this.concurrency) {\n return;\n }\n\n buffer = this.outgoing.shift();\n if (buffer) {\n this.triggerOutgoingHandler(buffer);\n }\n } while (buffer);\n }\n\n /**\n * Trigger a outgoing handler for a buffer shifted from outgoing.\n *\n * @param buffer -\n */\n private async triggerOutgoingHandler(buffer: PooledBuffer): Promise<any> {\n const bufferLength = buffer.size;\n\n this.executingOutgoingHandlers++;\n this.offset += bufferLength;\n\n try {\n await this.outgoingHandler(\n () => buffer.getReadableStream(),\n bufferLength,\n this.offset - bufferLength,\n );\n } catch (err: any) {\n this.emitter.emit(\"error\", err);\n return;\n }\n\n this.executingOutgoingHandlers--;\n this.reuseBuffer(buffer);\n this.emitter.emit(\"checkEnd\");\n }\n\n /**\n * Return buffer used by outgoing handler into incoming.\n *\n * @param buffer -\n */\n private reuseBuffer(buffer: PooledBuffer): void {\n this.incoming.push(buffer);\n try {\n if (!this.isError && this.resolveData() && !this.isStreamEnd) {\n this.readable.resume();\n }\n } catch (err: any) {\n this.emitter.emit(\"error\", err);\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"BuffersStream.d.ts","sourceRoot":"","sources":["../../src/BuffersStream.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,eAAe;CAAG;AAEhE;;GAEG;AACH,qBAAa,aAAc,SAAQ,QAAQ;IAwBvC,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAxBpB;;OAEG;IACH,OAAO,CAAC,yBAAyB,CAAS;IAE1C;;OAEG;IACH,OAAO,CAAC,WAAW,CAAS;IAE5B;;OAEG;IACH,OAAO,CAAC,iBAAiB,CAAS;IAElC;;;;;;OAMG;gBAEO,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,EAAE,MAAM,EAC1B,OAAO,CAAC,EAAE,oBAAoB;IAiBhC;;;;OAIG;IACI,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;CA+ClC"}
1
+ {"version":3,"file":"BuffersStream.d.ts","sourceRoot":"","sources":["../../src/BuffersStream.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,eAAe;CAAG;AAEhE;;GAEG;AACH,qBAAa,aAAc,SAAQ,QAAQ;IAwBvC,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,UAAU;IAxBpB;;OAEG;IACH,OAAO,CAAC,yBAAyB,CAAS;IAE1C;;OAEG;IACH,OAAO,CAAC,WAAW,CAAS;IAE5B;;OAEG;IACH,OAAO,CAAC,iBAAiB,CAAS;IAElC;;;;;;OAMG;gBAEO,OAAO,EAAE,MAAM,EAAE,EACjB,UAAU,EAAE,MAAM,EAC1B,OAAO,CAAC,EAAE,oBAAoB;IAiBhC;;;;OAIG;IACI,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI;CA8ClC"}
@@ -81,7 +81,6 @@ class BuffersStream extends import_node_stream.Readable {
81
81
  outBuffers.push(this.buffers[this.bufferIndex].slice(this.byteOffsetInCurrentBuffer, end));
82
82
  this.pushedBytesLength += size - i;
83
83
  this.byteOffsetInCurrentBuffer = end;
84
- i = size;
85
84
  break;
86
85
  } else {
87
86
  const end = this.byteOffsetInCurrentBuffer + remaining;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/BuffersStream.ts"],
4
- "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { ReadableOptions } from \"node:stream\";\nimport { Readable } from \"node:stream\";\n\n/**\n * Options to configure the BuffersStream.\n */\nexport interface BuffersStreamOptions extends ReadableOptions {}\n\n/**\n * This class generates a readable stream from the data in an array of buffers.\n */\nexport class BuffersStream extends Readable {\n /**\n * The offset of data to be read in the current buffer.\n */\n private byteOffsetInCurrentBuffer: number;\n\n /**\n * The index of buffer to be read in the array of buffers.\n */\n private bufferIndex: number;\n\n /**\n * The total length of data already read.\n */\n private pushedBytesLength: number;\n\n /**\n * Creates an instance of BuffersStream that will emit the data\n * contained in the array of buffers.\n *\n * @param buffers - Array of buffers containing the data\n * @param byteLength - The total length of data contained in the buffers\n */\n constructor(\n private buffers: Buffer[],\n private byteLength: number,\n options?: BuffersStreamOptions,\n ) {\n super(options);\n this.byteOffsetInCurrentBuffer = 0;\n this.bufferIndex = 0;\n this.pushedBytesLength = 0;\n\n // check byteLength is no larger than buffers[] total length\n let buffersLength = 0;\n for (const buf of this.buffers) {\n buffersLength += buf.byteLength;\n }\n if (buffersLength < this.byteLength) {\n throw new Error(\"Data size shouldn't be larger than the total length of buffers.\");\n }\n }\n\n /**\n * Internal _read() that will be called when the stream wants to pull more data in.\n *\n * @param size - Optional. The size of data to be read\n */\n public _read(size?: number): void {\n if (this.pushedBytesLength >= this.byteLength) {\n this.push(null);\n }\n\n if (!size) {\n size = this.readableHighWaterMark;\n }\n\n const outBuffers: Buffer[] = [];\n let i = 0;\n while (i < size && this.pushedBytesLength < this.byteLength) {\n // The last buffer may be longer than the data it contains.\n const remainingDataInAllBuffers = this.byteLength - this.pushedBytesLength;\n const remainingCapacityInThisBuffer =\n this.buffers[this.bufferIndex].byteLength - this.byteOffsetInCurrentBuffer;\n const remaining = Math.min(remainingCapacityInThisBuffer, remainingDataInAllBuffers);\n if (remaining > size - i) {\n // chunkSize = size - i\n const end = this.byteOffsetInCurrentBuffer + size - i;\n outBuffers.push(this.buffers[this.bufferIndex].slice(this.byteOffsetInCurrentBuffer, end));\n this.pushedBytesLength += size - i;\n this.byteOffsetInCurrentBuffer = end;\n i = size;\n break;\n } else {\n // chunkSize = remaining\n const end = this.byteOffsetInCurrentBuffer + remaining;\n outBuffers.push(this.buffers[this.bufferIndex].slice(this.byteOffsetInCurrentBuffer, end));\n if (remaining === remainingCapacityInThisBuffer) {\n // this.buffers[this.bufferIndex] used up, shift to next one\n this.byteOffsetInCurrentBuffer = 0;\n this.bufferIndex++;\n } else {\n this.byteOffsetInCurrentBuffer = end;\n }\n this.pushedBytesLength += remaining;\n i += remaining;\n }\n }\n\n if (outBuffers.length > 1) {\n this.push(Buffer.concat(outBuffers));\n } else if (outBuffers.length === 1) {\n this.push(outBuffers[0]);\n }\n }\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,yBAAyB;AAUlB,MAAM,sBAAsB,4BAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuB1C,YACU,SACA,YACR,SACA;AACA,UAAM,OAAO;AAJL;AACA;AAIR,SAAK,4BAA4B;AACjC,SAAK,cAAc;AACnB,SAAK,oBAAoB;AAGzB,QAAI,gBAAgB;AACpB,eAAW,OAAO,KAAK,SAAS;AAC9B,uBAAiB,IAAI;AAAA,IACvB;AACA,QAAI,gBAAgB,KAAK,YAAY;AACnC,YAAM,IAAI,MAAM,iEAAiE;AAAA,IACnF;AAAA,EACF;AAAA,EAjBU;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EArBF;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCD,MAAM,MAAqB;AAChC,QAAI,KAAK,qBAAqB,KAAK,YAAY;AAC7C,WAAK,KAAK,IAAI;AAAA,IAChB;AAEA,QAAI,CAAC,MAAM;AACT,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,aAAuB,CAAC;AAC9B,QAAI,IAAI;AACR,WAAO,IAAI,QAAQ,KAAK,oBAAoB,KAAK,YAAY;AAE3D,YAAM,4BAA4B,KAAK,aAAa,KAAK;AACzD,YAAM,gCACJ,KAAK,QAAQ,KAAK,WAAW,EAAE,aAAa,KAAK;AACnD,YAAM,YAAY,KAAK,IAAI,+BAA+B,yBAAyB;AACnF,UAAI,YAAY,OAAO,GAAG;AAExB,cAAM,MAAM,KAAK,4BAA4B,OAAO;AACpD,mBAAW,KAAK,KAAK,QAAQ,KAAK,WAAW,EAAE,MAAM,KAAK,2BAA2B,GAAG,CAAC;AACzF,aAAK,qBAAqB,OAAO;AACjC,aAAK,4BAA4B;AACjC,YAAI;AACJ;AAAA,MACF,OAAO;AAEL,cAAM,MAAM,KAAK,4BAA4B;AAC7C,mBAAW,KAAK,KAAK,QAAQ,KAAK,WAAW,EAAE,MAAM,KAAK,2BAA2B,GAAG,CAAC;AACzF,YAAI,cAAc,+BAA+B;AAE/C,eAAK,4BAA4B;AACjC,eAAK;AAAA,QACP,OAAO;AACL,eAAK,4BAA4B;AAAA,QACnC;AACA,aAAK,qBAAqB;AAC1B,aAAK;AAAA,MACP;AAAA,IACF;AAEA,QAAI,WAAW,SAAS,GAAG;AACzB,WAAK,KAAK,OAAO,OAAO,UAAU,CAAC;AAAA,IACrC,WAAW,WAAW,WAAW,GAAG;AAClC,WAAK,KAAK,WAAW,CAAC,CAAC;AAAA,IACzB;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { ReadableOptions } from \"node:stream\";\nimport { Readable } from \"node:stream\";\n\n/**\n * Options to configure the BuffersStream.\n */\nexport interface BuffersStreamOptions extends ReadableOptions {}\n\n/**\n * This class generates a readable stream from the data in an array of buffers.\n */\nexport class BuffersStream extends Readable {\n /**\n * The offset of data to be read in the current buffer.\n */\n private byteOffsetInCurrentBuffer: number;\n\n /**\n * The index of buffer to be read in the array of buffers.\n */\n private bufferIndex: number;\n\n /**\n * The total length of data already read.\n */\n private pushedBytesLength: number;\n\n /**\n * Creates an instance of BuffersStream that will emit the data\n * contained in the array of buffers.\n *\n * @param buffers - Array of buffers containing the data\n * @param byteLength - The total length of data contained in the buffers\n */\n constructor(\n private buffers: Buffer[],\n private byteLength: number,\n options?: BuffersStreamOptions,\n ) {\n super(options);\n this.byteOffsetInCurrentBuffer = 0;\n this.bufferIndex = 0;\n this.pushedBytesLength = 0;\n\n // check byteLength is no larger than buffers[] total length\n let buffersLength = 0;\n for (const buf of this.buffers) {\n buffersLength += buf.byteLength;\n }\n if (buffersLength < this.byteLength) {\n throw new Error(\"Data size shouldn't be larger than the total length of buffers.\");\n }\n }\n\n /**\n * Internal _read() that will be called when the stream wants to pull more data in.\n *\n * @param size - Optional. The size of data to be read\n */\n public _read(size?: number): void {\n if (this.pushedBytesLength >= this.byteLength) {\n this.push(null);\n }\n\n if (!size) {\n size = this.readableHighWaterMark;\n }\n\n const outBuffers: Buffer[] = [];\n let i = 0;\n while (i < size && this.pushedBytesLength < this.byteLength) {\n // The last buffer may be longer than the data it contains.\n const remainingDataInAllBuffers = this.byteLength - this.pushedBytesLength;\n const remainingCapacityInThisBuffer =\n this.buffers[this.bufferIndex].byteLength - this.byteOffsetInCurrentBuffer;\n const remaining = Math.min(remainingCapacityInThisBuffer, remainingDataInAllBuffers);\n if (remaining > size - i) {\n // chunkSize = size - i\n const end = this.byteOffsetInCurrentBuffer + size - i;\n outBuffers.push(this.buffers[this.bufferIndex].slice(this.byteOffsetInCurrentBuffer, end));\n this.pushedBytesLength += size - i;\n this.byteOffsetInCurrentBuffer = end;\n break;\n } else {\n // chunkSize = remaining\n const end = this.byteOffsetInCurrentBuffer + remaining;\n outBuffers.push(this.buffers[this.bufferIndex].slice(this.byteOffsetInCurrentBuffer, end));\n if (remaining === remainingCapacityInThisBuffer) {\n // this.buffers[this.bufferIndex] used up, shift to next one\n this.byteOffsetInCurrentBuffer = 0;\n this.bufferIndex++;\n } else {\n this.byteOffsetInCurrentBuffer = end;\n }\n this.pushedBytesLength += remaining;\n i += remaining;\n }\n }\n\n if (outBuffers.length > 1) {\n this.push(Buffer.concat(outBuffers));\n } else if (outBuffers.length === 1) {\n this.push(outBuffers[0]);\n }\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,yBAAyB;AAUlB,MAAM,sBAAsB,4BAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuB1C,YACU,SACA,YACR,SACA;AACA,UAAM,OAAO;AAJL;AACA;AAIR,SAAK,4BAA4B;AACjC,SAAK,cAAc;AACnB,SAAK,oBAAoB;AAGzB,QAAI,gBAAgB;AACpB,eAAW,OAAO,KAAK,SAAS;AAC9B,uBAAiB,IAAI;AAAA,IACvB;AACA,QAAI,gBAAgB,KAAK,YAAY;AACnC,YAAM,IAAI,MAAM,iEAAiE;AAAA,IACnF;AAAA,EACF;AAAA,EAjBU;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EArBF;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA,EAKA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCD,MAAM,MAAqB;AAChC,QAAI,KAAK,qBAAqB,KAAK,YAAY;AAC7C,WAAK,KAAK,IAAI;AAAA,IAChB;AAEA,QAAI,CAAC,MAAM;AACT,aAAO,KAAK;AAAA,IACd;AAEA,UAAM,aAAuB,CAAC;AAC9B,QAAI,IAAI;AACR,WAAO,IAAI,QAAQ,KAAK,oBAAoB,KAAK,YAAY;AAE3D,YAAM,4BAA4B,KAAK,aAAa,KAAK;AACzD,YAAM,gCACJ,KAAK,QAAQ,KAAK,WAAW,EAAE,aAAa,KAAK;AACnD,YAAM,YAAY,KAAK,IAAI,+BAA+B,yBAAyB;AACnF,UAAI,YAAY,OAAO,GAAG;AAExB,cAAM,MAAM,KAAK,4BAA4B,OAAO;AACpD,mBAAW,KAAK,KAAK,QAAQ,KAAK,WAAW,EAAE,MAAM,KAAK,2BAA2B,GAAG,CAAC;AACzF,aAAK,qBAAqB,OAAO;AACjC,aAAK,4BAA4B;AACjC;AAAA,MACF,OAAO;AAEL,cAAM,MAAM,KAAK,4BAA4B;AAC7C,mBAAW,KAAK,KAAK,QAAQ,KAAK,WAAW,EAAE,MAAM,KAAK,2BAA2B,GAAG,CAAC;AACzF,YAAI,cAAc,+BAA+B;AAE/C,eAAK,4BAA4B;AACjC,eAAK;AAAA,QACP,OAAO;AACL,eAAK,4BAA4B;AAAA,QACnC;AACA,aAAK,qBAAqB;AAC1B,aAAK;AAAA,MACP;AAAA,IACF;AAEA,QAAI,WAAW,SAAS,GAAG;AACzB,WAAK,KAAK,OAAO,OAAO,UAAU,CAAC;AAAA,IACrC,WAAW,WAAW,WAAW,GAAG;AAClC,WAAK,KAAK,WAAW,CAAC,CAAC;AAAA,IACzB;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export declare const StorageResponseFormat: {
5
5
  /**
6
- * Default. Currently maps to {@link StorageResponseFormat.Xml}, but may be updated in future releases.
6
+ * Default. Currently maps to {@link StorageResponseFormat.Arrow}, but may be updated in future releases.
7
7
  */
8
8
  readonly Auto: "Auto";
9
9
  /**
@@ -22,7 +22,7 @@ __export(StorageResponseFormat_exports, {
22
22
  module.exports = __toCommonJS(StorageResponseFormat_exports);
23
23
  const StorageResponseFormat = {
24
24
  /**
25
- * Default. Currently maps to {@link StorageResponseFormat.Xml}, but may be updated in future releases.
25
+ * Default. Currently maps to {@link StorageResponseFormat.Arrow}, but may be updated in future releases.
26
26
  */
27
27
  Auto: "Auto",
28
28
  /**
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/StorageResponseFormat.ts"],
4
- "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Specifies the format the service should use to return list results.\n */\nexport const StorageResponseFormat = {\n /**\n * Default. Currently maps to {@link StorageResponseFormat.Xml}, but may be updated in future releases.\n */\n Auto: \"Auto\",\n /**\n * Use XML to return list results.\n */\n Xml: \"Xml\",\n /**\n * Use Apache Arrow to return list results.\n */\n Arrow: \"Arrow\",\n} as const;\n\n/**\n * Specifies the format the service should use to return list results.\n */\nexport type StorageResponseFormat =\n (typeof StorageResponseFormat)[keyof typeof StorageResponseFormat];\n"],
4
+ "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n/**\n * Specifies the format the service should use to return list results.\n */\nexport const StorageResponseFormat = {\n /**\n * Default. Currently maps to {@link StorageResponseFormat.Arrow}, but may be updated in future releases.\n */\n Auto: \"Auto\",\n /**\n * Use XML to return list results.\n */\n Xml: \"Xml\",\n /**\n * Use Apache Arrow to return list results.\n */\n Arrow: \"Arrow\",\n} as const;\n\n/**\n * Specifies the format the service should use to return list results.\n */\nexport type StorageResponseFormat =\n (typeof StorageResponseFormat)[keyof typeof StorageResponseFormat];\n"],
5
5
  "mappings": ";;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMO,MAAM,wBAAwB;AAAA;AAAA;AAAA;AAAA,EAInC,MAAM;AAAA;AAAA;AAAA;AAAA,EAIN,KAAK;AAAA;AAAA;AAAA;AAAA,EAIL,OAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -20,6 +20,7 @@ export * from "./policies/StorageCorrectContentLengthPolicy.js";
20
20
  export * from "./policies/StorageRetryPolicyV2.js";
21
21
  export * from "./policies/StorageSharedKeyCredentialPolicy.js";
22
22
  export * from "./policies/StorageSharedKeyCredentialPolicyV2.js";
23
+ export { buildStorageSharedKeyStringToSign } from "./policies/SharedKeySigning.js";
23
24
  export * from "./policies/StorageRedirectRangeHeaderPolicy.js";
24
25
  export * from "./policies/StorageRequestFailureDetailsParserPolicy.js";
25
26
  export * from "./credentials/UserDelegationKeyCredential.js";
@@ -1 +1 @@
1
- {"version":3,"file":"indexPlatform.d.ts","sourceRoot":"","sources":["../../src/indexPlatform.ts"],"names":[],"mappings":"AAGA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,6BAA6B,CAAC;AAC5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACxD,mBAAmB,sBAAsB,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAE3C,cAAc,kCAAkC,CAAC;AACjD,cAAc,sCAAsC,CAAC;AACrD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kDAAkD,CAAC;AAEjE,cAAc,gCAAgC,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,cAAc,yCAAyC,CAAC;AACxD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,sDAAsD,CAAC;AACrE,cAAc,oCAAoC,CAAC;AACnD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,uDAAuD,CAAC;AACtE,cAAc,gDAAgD,CAAC;AAC/D,cAAc,wDAAwD,CAAC;AACvE,cAAc,mDAAmD,CAAC;AAClE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAG5E,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"indexPlatform.d.ts","sourceRoot":"","sources":["../../src/indexPlatform.ts"],"names":[],"mappings":"AAGA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,6BAA6B,CAAC;AAC5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AACxD,mBAAmB,sBAAsB,CAAC;AAC1C,cAAc,4BAA4B,CAAC;AAE3C,cAAc,kCAAkC,CAAC;AACjD,cAAc,sCAAsC,CAAC;AACrD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,kDAAkD,CAAC;AAEjE,cAAc,gCAAgC,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,cAAc,yCAAyC,CAAC;AACxD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2CAA2C,CAAC;AAC1D,cAAc,sDAAsD,CAAC;AACrE,cAAc,oCAAoC,CAAC;AACnD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,uDAAuD,CAAC;AACtE,OAAO,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;AACnF,cAAc,gDAAgD,CAAC;AAC/D,cAAc,wDAAwD,CAAC;AACvE,cAAc,mDAAmD,CAAC;AAClE,YAAY,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AAG5E,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
@@ -19,6 +19,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var indexPlatform_exports = {};
20
20
  __export(indexPlatform_exports, {
21
21
  BaseRequestPolicy: () => import_RequestPolicy.BaseRequestPolicy,
22
+ buildStorageSharedKeyStringToSign: () => import_SharedKeySigning.buildStorageSharedKeyStringToSign,
22
23
  createBlobFromData: () => import_bufferHelpers_common.createBlobFromData,
23
24
  getCachedDefaultHttpClient: () => import_cache.getCachedDefaultHttpClient
24
25
  });
@@ -44,12 +45,14 @@ __reExport(indexPlatform_exports, require("./policies/StorageCorrectContentLengt
44
45
  __reExport(indexPlatform_exports, require("./policies/StorageRetryPolicyV2.js"), module.exports);
45
46
  __reExport(indexPlatform_exports, require("./policies/StorageSharedKeyCredentialPolicy.js"), module.exports);
46
47
  __reExport(indexPlatform_exports, require("./policies/StorageSharedKeyCredentialPolicyV2.js"), module.exports);
48
+ var import_SharedKeySigning = require("./policies/SharedKeySigning.js");
47
49
  __reExport(indexPlatform_exports, require("./policies/StorageRedirectRangeHeaderPolicy.js"), module.exports);
48
50
  __reExport(indexPlatform_exports, require("./policies/StorageRequestFailureDetailsParserPolicy.js"), module.exports);
49
51
  __reExport(indexPlatform_exports, require("./credentials/UserDelegationKeyCredential.js"), module.exports);
50
52
  // Annotate the CommonJS export names for ESM import in node:
51
53
  0 && (module.exports = {
52
54
  BaseRequestPolicy,
55
+ buildStorageSharedKeyStringToSign,
53
56
  createBlobFromData,
54
57
  getCachedDefaultHttpClient,
55
58
  ...require("./BufferScheduler.js"),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/indexPlatform.ts"],
4
- "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nexport * from \"#platform/BufferScheduler\";\nexport * from \"#platform/bufferHelpers\";\nexport { createBlobFromData } from \"./bufferHelpers.common.js\";\nexport * from \"#platform/StructuredMessageEncodingStream\";\nexport * from \"#platform/StructuredMessageDecodingStream\";\nexport * from \"./StorageCRC64Calculator.js\";\nexport { getCachedDefaultHttpClient } from \"./cache.js\";\nexport type * from \"#platform/interfaces\";\nexport * from \"./StorageResponseFormat.js\";\n\nexport * from \"./StorageBrowserPolicyFactory.js\";\nexport * from \"./credentials/AnonymousCredential.js\";\nexport * from \"./credentials/Credential.js\";\nexport * from \"#platform/credentials/StorageSharedKeyCredential\";\n\nexport * from \"./StorageRetryPolicyFactory.js\";\nexport { BaseRequestPolicy } from \"./policies/RequestPolicy.js\";\nexport * from \"./policies/AnonymousCredentialPolicy.js\";\nexport * from \"./policies/CredentialPolicy.js\";\nexport * from \"#platform/policies/StorageBrowserPolicyV2\";\nexport * from \"#platform/policies/StorageCorrectContentLengthPolicy\";\nexport * from \"./policies/StorageRetryPolicyV2.js\";\nexport * from \"./policies/StorageSharedKeyCredentialPolicy.js\";\nexport * from \"#platform/policies/StorageSharedKeyCredentialPolicyV2\";\nexport * from \"./policies/StorageRedirectRangeHeaderPolicy.js\";\nexport * from \"./policies/StorageRequestFailureDetailsParserPolicy.js\";\nexport * from \"#platform/credentials/UserDelegationKeyCredential\";\nexport type { UserDelegationKey } from \"./credentials/UserDelegationKey.js\";\n\n// Re-export Readable stream type for Node.js (never in browser/react-native)\nexport type { Readable } from \"node:stream\";\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kCAAc,sCAHd;AAIA,kCAAc,oCAJd;AAKA,kCAAmC;AACnC,kCAAc,sDANd;AAOA,kCAAc,sDAPd;AAQA,kCAAc,wCARd;AASA,mBAA2C;AAE3C,kCAAc,uCAXd;AAaA,kCAAc,6CAbd;AAcA,kCAAc,iDAdd;AAeA,kCAAc,wCAfd;AAgBA,kCAAc,6DAhBd;AAkBA,kCAAc,2CAlBd;AAmBA,2BAAkC;AAClC,kCAAc,oDApBd;AAqBA,kCAAc,2CArBd;AAsBA,kCAAc,sDAtBd;AAuBA,kCAAc,iEAvBd;AAwBA,kCAAc,+CAxBd;AAyBA,kCAAc,2DAzBd;AA0BA,kCAAc,kEA1Bd;AA2BA,kCAAc,2DA3Bd;AA4BA,kCAAc,mEA5Bd;AA6BA,kCAAc,8DA7Bd;",
4
+ "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nexport * from \"#platform/BufferScheduler\";\nexport * from \"#platform/bufferHelpers\";\nexport { createBlobFromData } from \"./bufferHelpers.common.js\";\nexport * from \"#platform/StructuredMessageEncodingStream\";\nexport * from \"#platform/StructuredMessageDecodingStream\";\nexport * from \"./StorageCRC64Calculator.js\";\nexport { getCachedDefaultHttpClient } from \"./cache.js\";\nexport type * from \"#platform/interfaces\";\nexport * from \"./StorageResponseFormat.js\";\n\nexport * from \"./StorageBrowserPolicyFactory.js\";\nexport * from \"./credentials/AnonymousCredential.js\";\nexport * from \"./credentials/Credential.js\";\nexport * from \"#platform/credentials/StorageSharedKeyCredential\";\n\nexport * from \"./StorageRetryPolicyFactory.js\";\nexport { BaseRequestPolicy } from \"./policies/RequestPolicy.js\";\nexport * from \"./policies/AnonymousCredentialPolicy.js\";\nexport * from \"./policies/CredentialPolicy.js\";\nexport * from \"#platform/policies/StorageBrowserPolicyV2\";\nexport * from \"#platform/policies/StorageCorrectContentLengthPolicy\";\nexport * from \"./policies/StorageRetryPolicyV2.js\";\nexport * from \"./policies/StorageSharedKeyCredentialPolicy.js\";\nexport * from \"#platform/policies/StorageSharedKeyCredentialPolicyV2\";\nexport { buildStorageSharedKeyStringToSign } from \"./policies/SharedKeySigning.js\";\nexport * from \"./policies/StorageRedirectRangeHeaderPolicy.js\";\nexport * from \"./policies/StorageRequestFailureDetailsParserPolicy.js\";\nexport * from \"#platform/credentials/UserDelegationKeyCredential\";\nexport type { UserDelegationKey } from \"./credentials/UserDelegationKey.js\";\n\n// Re-export Readable stream type for Node.js (never in browser/react-native)\nexport type { Readable } from \"node:stream\";\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kCAAc,sCAHd;AAIA,kCAAc,oCAJd;AAKA,kCAAmC;AACnC,kCAAc,sDANd;AAOA,kCAAc,sDAPd;AAQA,kCAAc,wCARd;AASA,mBAA2C;AAE3C,kCAAc,uCAXd;AAaA,kCAAc,6CAbd;AAcA,kCAAc,iDAdd;AAeA,kCAAc,wCAfd;AAgBA,kCAAc,6DAhBd;AAkBA,kCAAc,2CAlBd;AAmBA,2BAAkC;AAClC,kCAAc,oDApBd;AAqBA,kCAAc,2CArBd;AAsBA,kCAAc,sDAtBd;AAuBA,kCAAc,iEAvBd;AAwBA,kCAAc,+CAxBd;AAyBA,kCAAc,2DAzBd;AA0BA,kCAAc,kEA1Bd;AA2BA,8BAAkD;AAClD,kCAAc,2DA5Bd;AA6BA,kCAAc,mEA7Bd;AA8BA,kCAAc,8DA9Bd;",
6
6
  "names": []
7
7
  }
@@ -1,3 +1,8 @@
1
1
  {
2
- "type": "commonjs"
2
+ "name": "@azure/storage-common",
3
+ "version": "12.6.0-beta.1",
4
+ "type": "commonjs",
5
+ "exports": {
6
+ "./package.json": "./package.json"
7
+ }
3
8
  }
@@ -0,0 +1,32 @@
1
+ import type { PipelineRequest } from "@azure/core-rest-pipeline";
2
+ /**
3
+ * Sets the request headers that participate in the Shared Key signature and are derived from
4
+ * the request itself: `x-ms-date`, and `Content-Length` for a string or Buffer body.
5
+ *
6
+ * `Content-Length` is a signed field: a request with a body whose `Content-Length` isn't set
7
+ * gets a signature the service rejects.
8
+ */
9
+ export declare function prepareSharedKeyHeaders(request: PipelineRequest): void;
10
+ /**
11
+ * Builds the string to sign for the Azure Storage Shared Key authorization scheme.
12
+ *
13
+ * Before building it, sets the request headers that the signature covers and that come from
14
+ * the request itself: `x-ms-date`, and `Content-Length` for a string or Buffer body. Send the
15
+ * request with these headers, since the signature depends on them.
16
+ *
17
+ * @param request - The request to sign. Its `x-ms-date` header is set, and so is its
18
+ * `Content-Length` header when the body is a string or a Buffer.
19
+ * @param accountName - The storage account name used to build the canonicalized resource.
20
+ * @returns The string to sign, ready to be signed with HMAC-SHA256.
21
+ * @see https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key
22
+ */
23
+ export declare function buildStorageSharedKeyStringToSign(request: PipelineRequest, accountName: string): string;
24
+ /**
25
+ * Builds the string to sign from the request as it is, without setting any header. For a caller
26
+ * that sets the signed headers itself on the request it sends.
27
+ *
28
+ * @param request - The request whose headers and URL form the string to sign.
29
+ * @param accountName - The storage account name used to build the canonicalized resource.
30
+ */
31
+ export declare function buildStringToSign(request: PipelineRequest, accountName: string): string;
32
+ //# sourceMappingURL=SharedKeySigning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SharedKeySigning.d.ts","sourceRoot":"","sources":["../../../src/policies/SharedKeySigning.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAmHjE;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAUtE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,eAAe,EACxB,WAAW,EAAE,MAAM,GAClB,MAAM,CAGR;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAqBvF"}
@@ -0,0 +1,125 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var SharedKeySigning_exports = {};
19
+ __export(SharedKeySigning_exports, {
20
+ buildStorageSharedKeyStringToSign: () => buildStorageSharedKeyStringToSign,
21
+ buildStringToSign: () => buildStringToSign,
22
+ prepareSharedKeyHeaders: () => prepareSharedKeyHeaders
23
+ });
24
+ module.exports = __toCommonJS(SharedKeySigning_exports);
25
+ var import_constants = require("../utils/constants.js");
26
+ var import_utils_common = require("../utils/utils.common.js");
27
+ var import_SharedKeyComparator = require("../utils/SharedKeyComparator.js");
28
+ function getHeaderValueToSign(request, headerName) {
29
+ const value = request.headers.get(headerName);
30
+ if (!value) {
31
+ return "";
32
+ }
33
+ if (headerName === import_constants.HeaderConstants.CONTENT_LENGTH && value === "0") {
34
+ return "";
35
+ }
36
+ return value;
37
+ }
38
+ function getCanonicalizedHeadersString(request) {
39
+ let headersArray = [];
40
+ for (const [name, value] of request.headers) {
41
+ if (name.toLowerCase().startsWith(import_constants.HeaderConstants.PREFIX_FOR_STORAGE)) {
42
+ headersArray.push({ name, value });
43
+ }
44
+ }
45
+ headersArray.sort((a, b) => {
46
+ return (0, import_SharedKeyComparator.compareHeader)(a.name.toLowerCase(), b.name.toLowerCase());
47
+ });
48
+ headersArray = headersArray.filter((value, index, array) => {
49
+ if (index > 0 && value.name.toLowerCase() === array[index - 1].name.toLowerCase()) {
50
+ return false;
51
+ }
52
+ return true;
53
+ });
54
+ let canonicalizedHeadersStringToSign = "";
55
+ headersArray.forEach((header) => {
56
+ canonicalizedHeadersStringToSign += `${header.name.toLowerCase().trimRight()}:${header.value.trimLeft()}
57
+ `;
58
+ });
59
+ return canonicalizedHeadersStringToSign;
60
+ }
61
+ function getCanonicalizedResourceString(request, accountName) {
62
+ const path = (0, import_utils_common.getURLPath)(request.url) || "/";
63
+ let canonicalizedResourceString = "";
64
+ canonicalizedResourceString += `/${accountName}${path}`;
65
+ const valuesByKey = getCanonicalizedQueryValues(request.url);
66
+ for (const key of [...valuesByKey.keys()].sort()) {
67
+ canonicalizedResourceString += `
68
+ ${key}:${valuesByKey.get(key).sort().join(",")}`;
69
+ }
70
+ return canonicalizedResourceString;
71
+ }
72
+ function getCanonicalizedQueryValues(url) {
73
+ const valuesByKey = /* @__PURE__ */ new Map();
74
+ const queryString = new URL(url).search.replace(/^\?/, "").trim();
75
+ if (!queryString) {
76
+ return valuesByKey;
77
+ }
78
+ for (const pair of queryString.split("&")) {
79
+ if (!pair) {
80
+ continue;
81
+ }
82
+ const separator = pair.indexOf("=");
83
+ const key = decodeURIComponent(
84
+ separator === -1 ? pair : pair.substring(0, separator)
85
+ ).toLowerCase();
86
+ const values = valuesByKey.get(key) ?? [];
87
+ values.push(separator === -1 ? "" : decodeURIComponent(pair.substring(separator + 1)));
88
+ valuesByKey.set(key, values);
89
+ }
90
+ return valuesByKey;
91
+ }
92
+ function prepareSharedKeyHeaders(request) {
93
+ request.headers.set(import_constants.HeaderConstants.X_MS_DATE, (/* @__PURE__ */ new Date()).toUTCString());
94
+ if (request.body && (typeof request.body === "string" || Buffer.isBuffer(request.body)) && request.body.length > 0) {
95
+ request.headers.set(import_constants.HeaderConstants.CONTENT_LENGTH, Buffer.byteLength(request.body));
96
+ }
97
+ }
98
+ function buildStorageSharedKeyStringToSign(request, accountName) {
99
+ prepareSharedKeyHeaders(request);
100
+ return buildStringToSign(request, accountName);
101
+ }
102
+ function buildStringToSign(request, accountName) {
103
+ return [
104
+ request.method.toUpperCase(),
105
+ getHeaderValueToSign(request, import_constants.HeaderConstants.CONTENT_ENCODING),
106
+ getHeaderValueToSign(request, import_constants.HeaderConstants.CONTENT_LANGUAGE),
107
+ getHeaderValueToSign(request, import_constants.HeaderConstants.CONTENT_LENGTH),
108
+ getHeaderValueToSign(request, import_constants.HeaderConstants.CONTENT_MD5),
109
+ getHeaderValueToSign(request, import_constants.HeaderConstants.CONTENT_TYPE),
110
+ // Signed requests always carry x-ms-date, which requires this slot to stay empty.
111
+ "",
112
+ getHeaderValueToSign(request, import_constants.HeaderConstants.IF_MODIFIED_SINCE),
113
+ getHeaderValueToSign(request, import_constants.HeaderConstants.IF_MATCH),
114
+ getHeaderValueToSign(request, import_constants.HeaderConstants.IF_NONE_MATCH),
115
+ getHeaderValueToSign(request, import_constants.HeaderConstants.IF_UNMODIFIED_SINCE),
116
+ getHeaderValueToSign(request, import_constants.HeaderConstants.RANGE)
117
+ ].join("\n") + "\n" + getCanonicalizedHeadersString(request) + getCanonicalizedResourceString(request, accountName);
118
+ }
119
+ // Annotate the CommonJS export names for ESM import in node:
120
+ 0 && (module.exports = {
121
+ buildStorageSharedKeyStringToSign,
122
+ buildStringToSign,
123
+ prepareSharedKeyHeaders
124
+ });
125
+ //# sourceMappingURL=SharedKeySigning.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/policies/SharedKeySigning.ts"],
4
+ "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { PipelineRequest } from \"@azure/core-rest-pipeline\";\nimport { HeaderConstants } from \"../utils/constants.js\";\nimport { getURLPath } from \"../utils/utils.common.js\";\nimport { compareHeader } from \"../utils/SharedKeyComparator.js\";\n\n/**\n * Retrieve header value according to shared key sign rules.\n * @see https://learn.microsoft.com/rest/api/storageservices/authenticate-with-shared-key\n */\nfunction getHeaderValueToSign(request: PipelineRequest, headerName: string): string {\n const value = request.headers.get(headerName);\n\n if (!value) {\n return \"\";\n }\n\n // When using version 2015-02-21 or later, if Content-Length is zero, then\n // set the Content-Length part of the StringToSign to an empty string.\n // https://learn.microsoft.com/rest/api/storageservices/authenticate-with-shared-key\n if (headerName === HeaderConstants.CONTENT_LENGTH && value === \"0\") {\n return \"\";\n }\n\n return value;\n}\n\n/**\n * To construct the CanonicalizedHeaders portion of the signature string, follow these steps:\n * 1. Retrieve all headers for the resource that begin with x-ms-, including the x-ms-date header.\n * 2. Convert each HTTP header name to lowercase.\n * 3. Sort the headers lexicographically by header name, in ascending order.\n * Each header may appear only once in the string.\n * 4. Replace any linear whitespace in the header value with a single space.\n * 5. Trim any whitespace around the colon in the header.\n * 6. Finally, append a new-line character to each canonicalized header in the resulting list.\n * Construct the CanonicalizedHeaders string by concatenating all headers in this list into a single string.\n *\n */\nfunction getCanonicalizedHeadersString(request: PipelineRequest): string {\n let headersArray: Array<{ name: string; value: string }> = [];\n for (const [name, value] of request.headers) {\n if (name.toLowerCase().startsWith(HeaderConstants.PREFIX_FOR_STORAGE)) {\n headersArray.push({ name, value });\n }\n }\n\n headersArray.sort((a, b): number => {\n return compareHeader(a.name.toLowerCase(), b.name.toLowerCase());\n });\n\n // Remove duplicate headers\n headersArray = headersArray.filter((value, index, array) => {\n if (index > 0 && value.name.toLowerCase() === array[index - 1].name.toLowerCase()) {\n return false;\n }\n return true;\n });\n\n let canonicalizedHeadersStringToSign: string = \"\";\n headersArray.forEach((header) => {\n canonicalizedHeadersStringToSign += `${header.name\n .toLowerCase()\n .trimRight()}:${header.value.trimLeft()}\\n`;\n });\n\n return canonicalizedHeadersStringToSign;\n}\n\nfunction getCanonicalizedResourceString(request: PipelineRequest, accountName: string): string {\n const path = getURLPath(request.url) || \"/\";\n\n let canonicalizedResourceString: string = \"\";\n canonicalizedResourceString += `/${accountName}${path}`;\n\n // A name that repeats, whether spelled identically or differing only by case, contributes all\n // of its values as one sorted, comma-joined line.\n const valuesByKey = getCanonicalizedQueryValues(request.url);\n for (const key of [...valuesByKey.keys()].sort()) {\n canonicalizedResourceString += `\\n${key}:${valuesByKey.get(key)!.sort().join(\",\")}`;\n }\n\n return canonicalizedResourceString;\n}\n\n/**\n * Groups query parameter values by lowercased name. Parses the raw query rather than reusing\n * `getURLQueries`, which keeps only the last value for a repeated name and discards parameters\n * that the service still canonicalizes.\n */\nfunction getCanonicalizedQueryValues(url: string): Map<string, string[]> {\n const valuesByKey = new Map<string, string[]>();\n const queryString = new URL(url).search.replace(/^\\?/, \"\").trim();\n if (!queryString) {\n return valuesByKey;\n }\n\n for (const pair of queryString.split(\"&\")) {\n if (!pair) {\n continue;\n }\n\n // Split at the first \"=\" only: \"=\" is legal inside a value, and a name carried without one\n // still participates in the signature.\n const separator = pair.indexOf(\"=\");\n const key = decodeURIComponent(\n separator === -1 ? pair : pair.substring(0, separator),\n ).toLowerCase();\n const values = valuesByKey.get(key) ?? [];\n values.push(separator === -1 ? \"\" : decodeURIComponent(pair.substring(separator + 1)));\n valuesByKey.set(key, values);\n }\n\n return valuesByKey;\n}\n\n/**\n * Sets the request headers that participate in the Shared Key signature and are derived from\n * the request itself: `x-ms-date`, and `Content-Length` for a string or Buffer body.\n *\n * `Content-Length` is a signed field: a request with a body whose `Content-Length` isn't set\n * gets a signature the service rejects.\n */\nexport function prepareSharedKeyHeaders(request: PipelineRequest): void {\n request.headers.set(HeaderConstants.X_MS_DATE, new Date().toUTCString());\n\n if (\n request.body &&\n (typeof request.body === \"string\" || Buffer.isBuffer(request.body)) &&\n request.body.length > 0\n ) {\n request.headers.set(HeaderConstants.CONTENT_LENGTH, Buffer.byteLength(request.body));\n }\n}\n\n/**\n * Builds the string to sign for the Azure Storage Shared Key authorization scheme.\n *\n * Before building it, sets the request headers that the signature covers and that come from\n * the request itself: `x-ms-date`, and `Content-Length` for a string or Buffer body. Send the\n * request with these headers, since the signature depends on them.\n *\n * @param request - The request to sign. Its `x-ms-date` header is set, and so is its\n * `Content-Length` header when the body is a string or a Buffer.\n * @param accountName - The storage account name used to build the canonicalized resource.\n * @returns The string to sign, ready to be signed with HMAC-SHA256.\n * @see https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key\n */\nexport function buildStorageSharedKeyStringToSign(\n request: PipelineRequest,\n accountName: string,\n): string {\n prepareSharedKeyHeaders(request);\n return buildStringToSign(request, accountName);\n}\n\n/**\n * Builds the string to sign from the request as it is, without setting any header. For a caller\n * that sets the signed headers itself on the request it sends.\n *\n * @param request - The request whose headers and URL form the string to sign.\n * @param accountName - The storage account name used to build the canonicalized resource.\n */\nexport function buildStringToSign(request: PipelineRequest, accountName: string): string {\n return (\n [\n request.method.toUpperCase(),\n getHeaderValueToSign(request, HeaderConstants.CONTENT_ENCODING),\n getHeaderValueToSign(request, HeaderConstants.CONTENT_LANGUAGE),\n getHeaderValueToSign(request, HeaderConstants.CONTENT_LENGTH),\n getHeaderValueToSign(request, HeaderConstants.CONTENT_MD5),\n getHeaderValueToSign(request, HeaderConstants.CONTENT_TYPE),\n // Signed requests always carry x-ms-date, which requires this slot to stay empty.\n \"\",\n getHeaderValueToSign(request, HeaderConstants.IF_MODIFIED_SINCE),\n getHeaderValueToSign(request, HeaderConstants.IF_MATCH),\n getHeaderValueToSign(request, HeaderConstants.IF_NONE_MATCH),\n getHeaderValueToSign(request, HeaderConstants.IF_UNMODIFIED_SINCE),\n getHeaderValueToSign(request, HeaderConstants.RANGE),\n ].join(\"\\n\") +\n \"\\n\" +\n getCanonicalizedHeadersString(request) +\n getCanonicalizedResourceString(request, accountName)\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -116,7 +116,7 @@ class StorageRetryPolicy extends import_RequestPolicy.BaseRequestPolicy {
116
116
  }
117
117
  }
118
118
  await this.delay(isPrimaryRetry, attempt, request.abortSignal);
119
- return this.attemptSendRequest(request, secondaryHas404, ++attempt);
119
+ return this.attemptSendRequest(request, secondaryHas404, attempt + 1);
120
120
  }
121
121
  /**
122
122
  * Decide whether to retry according to last HTTP response and retry counters.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/policies/StorageRetryPolicy.ts"],
4
- "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { AbortError } from \"@azure/abort-controller\";\nimport type {\n RequestPolicy,\n RequestPolicyOptionsLike as RequestPolicyOptions,\n RequestPolicyFactory,\n WebResourceLike as WebResource,\n CompatResponse as HttpOperationResponse,\n} from \"@azure/core-http-compat\";\nimport { BaseRequestPolicy } from \"./RequestPolicy.js\";\nimport type { RestError } from \"@azure/core-rest-pipeline\";\n\nimport type { StorageRetryOptions } from \"../StorageRetryPolicyFactory.js\";\nimport { HeaderConstants, URLConstants } from \"../utils/constants.js\";\nimport { delay, setURLHost, setURLParameter } from \"../utils/utils.common.js\";\nimport { logger } from \"../log.js\";\nimport { StorageRetryPolicyType } from \"./StorageRetryPolicyType.js\";\n\n/**\n * A factory method used to generated a RetryPolicy factory.\n *\n * @param retryOptions -\n */\nexport function NewRetryPolicyFactory(retryOptions?: StorageRetryOptions): RequestPolicyFactory {\n return {\n create: (nextPolicy: RequestPolicy, options: RequestPolicyOptions): StorageRetryPolicy => {\n return new StorageRetryPolicy(nextPolicy, options, retryOptions);\n },\n };\n}\n\n// Default values of StorageRetryOptions\nconst DEFAULT_RETRY_OPTIONS: StorageRetryOptions = {\n maxRetryDelayInMs: 120 * 1000,\n maxTries: 4,\n retryDelayInMs: 4 * 1000,\n retryPolicyType: StorageRetryPolicyType.EXPONENTIAL,\n secondaryHost: \"\",\n tryTimeoutInMs: undefined, // Use server side default timeout strategy\n};\n\nconst RETRY_ABORT_ERROR = new AbortError(\"The operation was aborted.\");\n\n/**\n * Retry policy with exponential retry and linear retry implemented.\n */\nexport class StorageRetryPolicy extends BaseRequestPolicy {\n /**\n * RetryOptions.\n */\n private readonly retryOptions: StorageRetryOptions;\n\n /**\n * Creates an instance of RetryPolicy.\n *\n * @param nextPolicy -\n * @param options -\n * @param retryOptions -\n */\n constructor(\n nextPolicy: RequestPolicy,\n options: RequestPolicyOptions,\n retryOptions: StorageRetryOptions = DEFAULT_RETRY_OPTIONS,\n ) {\n super(nextPolicy, options);\n\n // Initialize retry options\n this.retryOptions = {\n retryPolicyType: retryOptions.retryPolicyType\n ? retryOptions.retryPolicyType\n : DEFAULT_RETRY_OPTIONS.retryPolicyType,\n\n maxTries:\n retryOptions.maxTries && retryOptions.maxTries >= 1\n ? Math.floor(retryOptions.maxTries)\n : DEFAULT_RETRY_OPTIONS.maxTries,\n\n tryTimeoutInMs:\n retryOptions.tryTimeoutInMs && retryOptions.tryTimeoutInMs >= 0\n ? retryOptions.tryTimeoutInMs\n : DEFAULT_RETRY_OPTIONS.tryTimeoutInMs,\n\n retryDelayInMs:\n retryOptions.retryDelayInMs && retryOptions.retryDelayInMs >= 0\n ? Math.min(\n retryOptions.retryDelayInMs,\n retryOptions.maxRetryDelayInMs\n ? retryOptions.maxRetryDelayInMs\n : DEFAULT_RETRY_OPTIONS.maxRetryDelayInMs!,\n )\n : DEFAULT_RETRY_OPTIONS.retryDelayInMs,\n\n maxRetryDelayInMs:\n retryOptions.maxRetryDelayInMs && retryOptions.maxRetryDelayInMs >= 0\n ? retryOptions.maxRetryDelayInMs\n : DEFAULT_RETRY_OPTIONS.maxRetryDelayInMs,\n\n secondaryHost: retryOptions.secondaryHost\n ? retryOptions.secondaryHost\n : DEFAULT_RETRY_OPTIONS.secondaryHost,\n };\n }\n\n /**\n * Sends request.\n *\n * @param request -\n */\n public async sendRequest(request: WebResource): Promise<HttpOperationResponse> {\n return this.attemptSendRequest(request, false, 1);\n }\n\n /**\n * Decide and perform next retry. Won't mutate request parameter.\n *\n * @param request -\n * @param secondaryHas404 - If attempt was against the secondary & it returned a StatusNotFound (404), then\n * the resource was not found. This may be due to replication delay. So, in this\n * case, we'll never try the secondary again for this operation.\n * @param attempt - How many retries has been attempted to performed, starting from 1, which includes\n * the attempt will be performed by this method call.\n */\n protected async attemptSendRequest(\n request: WebResource,\n secondaryHas404: boolean,\n attempt: number,\n ): Promise<HttpOperationResponse> {\n const newRequest: WebResource = request.clone();\n\n const isPrimaryRetry =\n secondaryHas404 ||\n !this.retryOptions.secondaryHost ||\n !(request.method === \"GET\" || request.method === \"HEAD\" || request.method === \"OPTIONS\") ||\n attempt % 2 === 1;\n\n if (!isPrimaryRetry) {\n newRequest.url = setURLHost(newRequest.url, this.retryOptions.secondaryHost!);\n }\n\n // Set the server-side timeout query parameter \"timeout=[seconds]\"\n if (this.retryOptions.tryTimeoutInMs) {\n newRequest.url = setURLParameter(\n newRequest.url,\n URLConstants.Parameters.TIMEOUT,\n Math.floor(this.retryOptions.tryTimeoutInMs! / 1000).toString(),\n );\n }\n\n let response: HttpOperationResponse | undefined;\n try {\n logger.info(`RetryPolicy: =====> Try=${attempt} ${isPrimaryRetry ? \"Primary\" : \"Secondary\"}`);\n response = await this._nextPolicy.sendRequest(newRequest);\n if (!this.shouldRetry(isPrimaryRetry, attempt, response)) {\n return response;\n }\n\n secondaryHas404 = secondaryHas404 || (!isPrimaryRetry && response.status === 404);\n } catch (err: any) {\n logger.error(`RetryPolicy: Caught error, message: ${err.message}, code: ${err.code}`);\n if (!this.shouldRetry(isPrimaryRetry, attempt, response, err)) {\n throw err;\n }\n }\n\n await this.delay(isPrimaryRetry, attempt, request.abortSignal);\n return this.attemptSendRequest(request, secondaryHas404, ++attempt);\n }\n\n /**\n * Decide whether to retry according to last HTTP response and retry counters.\n *\n * @param isPrimaryRetry -\n * @param attempt -\n * @param response -\n * @param err -\n */\n protected shouldRetry(\n isPrimaryRetry: boolean,\n attempt: number,\n response?: HttpOperationResponse,\n err?: RestError,\n ): boolean {\n if (attempt >= this.retryOptions.maxTries!) {\n logger.info(\n `RetryPolicy: Attempt(s) ${attempt} >= maxTries ${\n this.retryOptions.maxTries!\n }, no further try.`,\n );\n return false;\n }\n\n // Handle network failures, you may need to customize the list when you implement\n // your own http client\n const retriableErrors = [\n \"ETIMEDOUT\",\n \"ESOCKETTIMEDOUT\",\n \"ECONNREFUSED\",\n \"ECONNRESET\",\n \"ENOENT\",\n \"ENOTFOUND\",\n \"TIMEOUT\",\n \"EPIPE\",\n \"REQUEST_SEND_ERROR\", // For default xhr based http client provided in ms-rest-js\n ];\n if (err) {\n for (const retriableError of retriableErrors) {\n if (\n err.name.toUpperCase().includes(retriableError) ||\n err.message.toUpperCase().includes(retriableError) ||\n (err.code && err.code.toString().toUpperCase() === retriableError)\n ) {\n logger.info(`RetryPolicy: Network error ${retriableError} found, will retry.`);\n return true;\n }\n }\n }\n\n // If attempt was against the secondary & it returned a StatusNotFound (404), then\n // the resource was not found. This may be due to replication delay. So, in this\n // case, we'll never try the secondary again for this operation.\n if (response || err) {\n const statusCode = response ? response.status : err ? err.statusCode : 0;\n if (!isPrimaryRetry && statusCode === 404) {\n logger.info(`RetryPolicy: Secondary access with 404, will retry.`);\n return true;\n }\n\n // Server internal error or server timeout\n if (statusCode === 503 || statusCode === 500) {\n logger.info(`RetryPolicy: Will retry for status code ${statusCode}.`);\n return true;\n }\n }\n\n if (response) {\n // Retry select Copy Source Error Codes.\n if (response?.status >= 400) {\n const copySourceError = response.headers.get(HeaderConstants.X_MS_CopySourceErrorCode);\n if (copySourceError !== undefined) {\n switch (copySourceError) {\n case \"InternalError\":\n case \"OperationTimedOut\":\n case \"ServerBusy\":\n return true;\n }\n }\n }\n }\n\n if (err?.code === \"PARSE_ERROR\" && err?.message.startsWith(`Error \"Error: Unclosed root tag`)) {\n logger.info(\n \"RetryPolicy: Incomplete XML response likely due to service timeout, will retry.\",\n );\n return true;\n }\n\n return false;\n }\n\n /**\n * Delay a calculated time between retries.\n *\n * @param isPrimaryRetry -\n * @param attempt -\n * @param abortSignal -\n */\n private async delay(\n isPrimaryRetry: boolean,\n attempt: number,\n abortSignal?: AbortSignalLike,\n ): Promise<void> {\n let delayTimeInMs: number = 0;\n\n if (isPrimaryRetry) {\n switch (this.retryOptions.retryPolicyType) {\n case StorageRetryPolicyType.EXPONENTIAL:\n delayTimeInMs = Math.min(\n (Math.pow(2, attempt - 1) - 1) * this.retryOptions.retryDelayInMs!,\n this.retryOptions.maxRetryDelayInMs!,\n );\n break;\n case StorageRetryPolicyType.FIXED:\n delayTimeInMs = this.retryOptions.retryDelayInMs!;\n break;\n }\n } else {\n delayTimeInMs = Math.random() * 1000;\n }\n\n logger.info(`RetryPolicy: Delay for ${delayTimeInMs}ms`);\n return delay(delayTimeInMs, abortSignal, RETRY_ABORT_ERROR);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AbortSignalLike } from \"@azure/abort-controller\";\nimport { AbortError } from \"@azure/abort-controller\";\nimport type {\n RequestPolicy,\n RequestPolicyOptionsLike as RequestPolicyOptions,\n RequestPolicyFactory,\n WebResourceLike as WebResource,\n CompatResponse as HttpOperationResponse,\n} from \"@azure/core-http-compat\";\nimport { BaseRequestPolicy } from \"./RequestPolicy.js\";\nimport type { RestError } from \"@azure/core-rest-pipeline\";\n\nimport type { StorageRetryOptions } from \"../StorageRetryPolicyFactory.js\";\nimport { HeaderConstants, URLConstants } from \"../utils/constants.js\";\nimport { delay, setURLHost, setURLParameter } from \"../utils/utils.common.js\";\nimport { logger } from \"../log.js\";\nimport { StorageRetryPolicyType } from \"./StorageRetryPolicyType.js\";\n\n/**\n * A factory method used to generated a RetryPolicy factory.\n *\n * @param retryOptions -\n */\nexport function NewRetryPolicyFactory(retryOptions?: StorageRetryOptions): RequestPolicyFactory {\n return {\n create: (nextPolicy: RequestPolicy, options: RequestPolicyOptions): StorageRetryPolicy => {\n return new StorageRetryPolicy(nextPolicy, options, retryOptions);\n },\n };\n}\n\n// Default values of StorageRetryOptions\nconst DEFAULT_RETRY_OPTIONS: StorageRetryOptions = {\n maxRetryDelayInMs: 120 * 1000,\n maxTries: 4,\n retryDelayInMs: 4 * 1000,\n retryPolicyType: StorageRetryPolicyType.EXPONENTIAL,\n secondaryHost: \"\",\n tryTimeoutInMs: undefined, // Use server side default timeout strategy\n};\n\nconst RETRY_ABORT_ERROR = new AbortError(\"The operation was aborted.\");\n\n/**\n * Retry policy with exponential retry and linear retry implemented.\n */\nexport class StorageRetryPolicy extends BaseRequestPolicy {\n /**\n * RetryOptions.\n */\n private readonly retryOptions: StorageRetryOptions;\n\n /**\n * Creates an instance of RetryPolicy.\n *\n * @param nextPolicy -\n * @param options -\n * @param retryOptions -\n */\n constructor(\n nextPolicy: RequestPolicy,\n options: RequestPolicyOptions,\n retryOptions: StorageRetryOptions = DEFAULT_RETRY_OPTIONS,\n ) {\n super(nextPolicy, options);\n\n // Initialize retry options\n this.retryOptions = {\n retryPolicyType: retryOptions.retryPolicyType\n ? retryOptions.retryPolicyType\n : DEFAULT_RETRY_OPTIONS.retryPolicyType,\n\n maxTries:\n retryOptions.maxTries && retryOptions.maxTries >= 1\n ? Math.floor(retryOptions.maxTries)\n : DEFAULT_RETRY_OPTIONS.maxTries,\n\n tryTimeoutInMs:\n retryOptions.tryTimeoutInMs && retryOptions.tryTimeoutInMs >= 0\n ? retryOptions.tryTimeoutInMs\n : DEFAULT_RETRY_OPTIONS.tryTimeoutInMs,\n\n retryDelayInMs:\n retryOptions.retryDelayInMs && retryOptions.retryDelayInMs >= 0\n ? Math.min(\n retryOptions.retryDelayInMs,\n retryOptions.maxRetryDelayInMs\n ? retryOptions.maxRetryDelayInMs\n : DEFAULT_RETRY_OPTIONS.maxRetryDelayInMs!,\n )\n : DEFAULT_RETRY_OPTIONS.retryDelayInMs,\n\n maxRetryDelayInMs:\n retryOptions.maxRetryDelayInMs && retryOptions.maxRetryDelayInMs >= 0\n ? retryOptions.maxRetryDelayInMs\n : DEFAULT_RETRY_OPTIONS.maxRetryDelayInMs,\n\n secondaryHost: retryOptions.secondaryHost\n ? retryOptions.secondaryHost\n : DEFAULT_RETRY_OPTIONS.secondaryHost,\n };\n }\n\n /**\n * Sends request.\n *\n * @param request -\n */\n public async sendRequest(request: WebResource): Promise<HttpOperationResponse> {\n return this.attemptSendRequest(request, false, 1);\n }\n\n /**\n * Decide and perform next retry. Won't mutate request parameter.\n *\n * @param request -\n * @param secondaryHas404 - If attempt was against the secondary & it returned a StatusNotFound (404), then\n * the resource was not found. This may be due to replication delay. So, in this\n * case, we'll never try the secondary again for this operation.\n * @param attempt - How many retries has been attempted to performed, starting from 1, which includes\n * the attempt will be performed by this method call.\n */\n protected async attemptSendRequest(\n request: WebResource,\n secondaryHas404: boolean,\n attempt: number,\n ): Promise<HttpOperationResponse> {\n const newRequest: WebResource = request.clone();\n\n const isPrimaryRetry =\n secondaryHas404 ||\n !this.retryOptions.secondaryHost ||\n !(request.method === \"GET\" || request.method === \"HEAD\" || request.method === \"OPTIONS\") ||\n attempt % 2 === 1;\n\n if (!isPrimaryRetry) {\n newRequest.url = setURLHost(newRequest.url, this.retryOptions.secondaryHost!);\n }\n\n // Set the server-side timeout query parameter \"timeout=[seconds]\"\n if (this.retryOptions.tryTimeoutInMs) {\n newRequest.url = setURLParameter(\n newRequest.url,\n URLConstants.Parameters.TIMEOUT,\n Math.floor(this.retryOptions.tryTimeoutInMs! / 1000).toString(),\n );\n }\n\n let response: HttpOperationResponse | undefined;\n try {\n logger.info(`RetryPolicy: =====> Try=${attempt} ${isPrimaryRetry ? \"Primary\" : \"Secondary\"}`);\n response = await this._nextPolicy.sendRequest(newRequest);\n if (!this.shouldRetry(isPrimaryRetry, attempt, response)) {\n return response;\n }\n\n secondaryHas404 = secondaryHas404 || (!isPrimaryRetry && response.status === 404);\n } catch (err: any) {\n logger.error(`RetryPolicy: Caught error, message: ${err.message}, code: ${err.code}`);\n if (!this.shouldRetry(isPrimaryRetry, attempt, response, err)) {\n throw err;\n }\n }\n\n await this.delay(isPrimaryRetry, attempt, request.abortSignal);\n return this.attemptSendRequest(request, secondaryHas404, attempt + 1);\n }\n\n /**\n * Decide whether to retry according to last HTTP response and retry counters.\n *\n * @param isPrimaryRetry -\n * @param attempt -\n * @param response -\n * @param err -\n */\n protected shouldRetry(\n isPrimaryRetry: boolean,\n attempt: number,\n response?: HttpOperationResponse,\n err?: RestError,\n ): boolean {\n if (attempt >= this.retryOptions.maxTries!) {\n logger.info(\n `RetryPolicy: Attempt(s) ${attempt} >= maxTries ${\n this.retryOptions.maxTries!\n }, no further try.`,\n );\n return false;\n }\n\n // Handle network failures, you may need to customize the list when you implement\n // your own http client\n const retriableErrors = [\n \"ETIMEDOUT\",\n \"ESOCKETTIMEDOUT\",\n \"ECONNREFUSED\",\n \"ECONNRESET\",\n \"ENOENT\",\n \"ENOTFOUND\",\n \"TIMEOUT\",\n \"EPIPE\",\n \"REQUEST_SEND_ERROR\", // For default xhr based http client provided in ms-rest-js\n ];\n if (err) {\n for (const retriableError of retriableErrors) {\n if (\n err.name.toUpperCase().includes(retriableError) ||\n err.message.toUpperCase().includes(retriableError) ||\n (err.code && err.code.toString().toUpperCase() === retriableError)\n ) {\n logger.info(`RetryPolicy: Network error ${retriableError} found, will retry.`);\n return true;\n }\n }\n }\n\n // If attempt was against the secondary & it returned a StatusNotFound (404), then\n // the resource was not found. This may be due to replication delay. So, in this\n // case, we'll never try the secondary again for this operation.\n if (response || err) {\n const statusCode = response ? response.status : err ? err.statusCode : 0;\n if (!isPrimaryRetry && statusCode === 404) {\n logger.info(`RetryPolicy: Secondary access with 404, will retry.`);\n return true;\n }\n\n // Server internal error or server timeout\n if (statusCode === 503 || statusCode === 500) {\n logger.info(`RetryPolicy: Will retry for status code ${statusCode}.`);\n return true;\n }\n }\n\n if (response) {\n // Retry select Copy Source Error Codes.\n if (response?.status >= 400) {\n const copySourceError = response.headers.get(HeaderConstants.X_MS_CopySourceErrorCode);\n if (copySourceError !== undefined) {\n switch (copySourceError) {\n case \"InternalError\":\n case \"OperationTimedOut\":\n case \"ServerBusy\":\n return true;\n }\n }\n }\n }\n\n if (err?.code === \"PARSE_ERROR\" && err?.message.startsWith(`Error \"Error: Unclosed root tag`)) {\n logger.info(\n \"RetryPolicy: Incomplete XML response likely due to service timeout, will retry.\",\n );\n return true;\n }\n\n return false;\n }\n\n /**\n * Delay a calculated time between retries.\n *\n * @param isPrimaryRetry -\n * @param attempt -\n * @param abortSignal -\n */\n private async delay(\n isPrimaryRetry: boolean,\n attempt: number,\n abortSignal?: AbortSignalLike,\n ): Promise<void> {\n let delayTimeInMs: number = 0;\n\n if (isPrimaryRetry) {\n switch (this.retryOptions.retryPolicyType) {\n case StorageRetryPolicyType.EXPONENTIAL:\n delayTimeInMs = Math.min(\n (Math.pow(2, attempt - 1) - 1) * this.retryOptions.retryDelayInMs!,\n this.retryOptions.maxRetryDelayInMs!,\n );\n break;\n case StorageRetryPolicyType.FIXED:\n delayTimeInMs = this.retryOptions.retryDelayInMs!;\n break;\n }\n } else {\n delayTimeInMs = Math.random() * 1000;\n }\n\n logger.info(`RetryPolicy: Delay for ${delayTimeInMs}ms`);\n return delay(delayTimeInMs, abortSignal, RETRY_ABORT_ERROR);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"StorageRetryPolicyV2.d.ts","sourceRoot":"","sources":["../../../src/policies/StorageRetryPolicyV2.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAKnG;;GAEG;AACH,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AA0B3D;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,cAAc,CA+JpF"}
1
+ {"version":3,"file":"StorageRetryPolicyV2.d.ts","sourceRoot":"","sources":["../../../src/policies/StorageRetryPolicyV2.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EAIf,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAKnG;;GAEG;AACH,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAwD3D;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,cAAc,CAkKpF"}
@@ -50,6 +50,19 @@ const retriableErrors = [
50
50
  "REQUEST_SEND_ERROR"
51
51
  ];
52
52
  const RETRY_ABORT_ERROR = new import_abort_controller.AbortError("The operation was aborted.");
53
+ async function releaseResponseBody(nodeBody, browserBody) {
54
+ if (nodeBody) {
55
+ nodeBody.on("error", (e) => {
56
+ import_log.logger.warning(`RetryPolicy: Failed to drain the response body: ${(0, import_core_util.getErrorMessage)(e)}`);
57
+ });
58
+ nodeBody.resume();
59
+ }
60
+ try {
61
+ await browserBody?.cancel();
62
+ } catch (e) {
63
+ import_log.logger.warning(`RetryPolicy: Failed to cancel the response body: ${(0, import_core_util.getErrorMessage)(e)}`);
64
+ }
65
+ }
53
66
  function storageRetryPolicy(options = {}) {
54
67
  const retryPolicyType = options.retryPolicyType ?? DEFAULT_RETRY_OPTIONS.retryPolicyType;
55
68
  const maxTries = options.maxTries ?? DEFAULT_RETRY_OPTIONS.maxTries;
@@ -166,6 +179,9 @@ function storageRetryPolicy(options = {}) {
166
179
  }
167
180
  retryAgain = shouldRetry({ isPrimaryRetry, attempt, response, error });
168
181
  if (retryAgain) {
182
+ if (response) {
183
+ await releaseResponseBody(response.readableStreamBody, response.browserStreamBody);
184
+ }
169
185
  await (0, import_utils_common.delay)(
170
186
  calculateDelay(isPrimaryRetry, attempt),
171
187
  request.abortSignal,