@typespec/ts-http-runtime 1.0.0-alpha.20240108.2 → 1.0.0-alpha.20240117.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.
package/dist/index.js CHANGED
@@ -4,11 +4,11 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var os = require('os');
6
6
  var util = require('util');
7
- var httpsProxyAgent = require('https-proxy-agent');
8
- var httpProxyAgent = require('http-proxy-agent');
9
7
  var tslib = require('tslib');
10
8
  var stream = require('stream');
11
9
  var crypto = require('crypto');
10
+ var httpsProxyAgent = require('https-proxy-agent');
11
+ var httpProxyAgent = require('http-proxy-agent');
12
12
  var http = require('http');
13
13
  var https = require('https');
14
14
  var zlib = require('zlib');
@@ -393,6 +393,7 @@ function extend(namespace) {
393
393
  newDebugger.log = this.log;
394
394
  return newDebugger;
395
395
  }
396
+ var debug = debugObj;
396
397
 
397
398
  // Copyright (c) Microsoft Corporation.
398
399
  // Licensed under the MIT license.
@@ -405,9 +406,9 @@ let typeSpecRuntimeLogLevel;
405
406
  * By default, logs are sent to stderr.
406
407
  * Override the `log` method to redirect logs to another location.
407
408
  */
408
- const TypeSpecRuntimeLogger = debugObj("typeSpecRuntime");
409
+ const TypeSpecRuntimeLogger = debug("typeSpecRuntime");
409
410
  TypeSpecRuntimeLogger.log = (...args) => {
410
- debugObj.log(...args);
411
+ debug.log(...args);
411
412
  };
412
413
  const TYPESPEC_RUNTIME_LOG_LEVELS = ["verbose", "info", "warning", "error"];
413
414
  if (logLevelFromEnv) {
@@ -439,7 +440,7 @@ function setLogLevel(level) {
439
440
  enabledNamespaces.push(logger.namespace);
440
441
  }
441
442
  }
442
- debugObj.enable(enabledNamespaces.join(","));
443
+ debug.enable(enabledNamespaces.join(","));
443
444
  }
444
445
  const levelMap = {
445
446
  verbose: 400,
@@ -473,8 +474,8 @@ function createLogger(parent, level) {
473
474
  });
474
475
  patchLogMethod(parent, logger);
475
476
  if (shouldEnable(logger)) {
476
- const enabledNamespaces = debugObj.disable();
477
- debugObj.enable(enabledNamespaces + "," + logger.namespace);
477
+ const enabledNamespaces = debug.disable();
478
+ debug.enable(enabledNamespaces + "," + logger.namespace);
478
479
  }
479
480
  registeredLoggers.add(logger);
480
481
  return logger;
@@ -803,282 +804,592 @@ function userAgentPolicy(options = {}) {
803
804
  // Copyright (c) Microsoft Corporation.
804
805
  // Licensed under the MIT license.
805
806
  /**
806
- * The programmatic identifier of the decompressResponsePolicy.
807
+ * The helper that transforms bytes with specific character encoding into string
808
+ * @param bytes - the uint8array bytes
809
+ * @param format - the format we use to encode the byte
810
+ * @returns a string of the encoded string
807
811
  */
808
- const decompressResponsePolicyName = "decompressResponsePolicy";
812
+ function uint8ArrayToString(bytes, format) {
813
+ return Buffer.from(bytes).toString(format);
814
+ }
809
815
  /**
810
- * A policy to enable response decompression according to Accept-Encoding header
811
- * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding
816
+ * The helper that transforms string to specific character encoded bytes array.
817
+ * @param value - the string to be converted
818
+ * @param format - the format we use to decode the value
819
+ * @returns a uint8array
812
820
  */
813
- function decompressResponsePolicy() {
814
- return {
815
- name: decompressResponsePolicyName,
816
- async sendRequest(request, next) {
817
- // HEAD requests have no body
818
- if (request.method !== "HEAD") {
819
- request.headers.set("Accept-Encoding", "gzip,deflate");
820
- }
821
- return next(request);
822
- },
823
- };
821
+ function stringToUint8Array(value, format) {
822
+ return Buffer.from(value, format);
824
823
  }
825
824
 
826
825
  // Copyright (c) Microsoft Corporation.
827
826
  // Licensed under the MIT license.
828
827
  /**
829
- * Returns a random integer value between a lower and upper bound,
830
- * inclusive of both bounds.
831
- * Note that this uses Math.random and isn't secure. If you need to use
832
- * this for any kind of security purpose, find a better source of random.
833
- * @param min - The smallest integer value allowed.
834
- * @param max - The largest integer value allowed.
828
+ * Helper TypeGuard that checks if something is defined or not.
829
+ * @param thing - Anything
835
830
  */
836
- function getRandomIntegerInclusive(min, max) {
837
- // Make sure inputs are integers.
838
- min = Math.ceil(min);
839
- max = Math.floor(max);
840
- // Pick a random offset from zero to the size of the range.
841
- // Since Math.random() can never return 1, we have to make the range one larger
842
- // in order to be inclusive of the maximum value after we take the floor.
843
- const offset = Math.floor(Math.random() * (max - min + 1));
844
- return offset + min;
831
+ function isDefined(thing) {
832
+ return typeof thing !== "undefined" && thing !== null;
845
833
  }
846
-
847
- // Copyright (c) Microsoft Corporation.
848
- // Licensed under the MIT license.
849
834
  /**
850
- * This error is thrown when an asynchronous operation has been aborted.
851
- * Check for this error by testing the `name` that the name property of the
852
- * error matches `"AbortError"`.
853
- *
854
- * @example
855
- * ```ts
856
- * const controller = new AbortController();
857
- * controller.abort();
858
- * try {
859
- * doAsyncWork(controller.signal)
860
- * } catch (e) {
861
- * if (e.name === 'AbortError') {
862
- * // handle abort error here.
863
- * }
864
- * }
865
- * ```
835
+ * Helper TypeGuard that checks if the input is an object with the specified properties.
836
+ * @param thing - Anything.
837
+ * @param properties - The name of the properties that should appear in the object.
866
838
  */
867
- class AbortError extends Error {
868
- constructor(message) {
869
- super(message);
870
- this.name = "AbortError";
839
+ function isObjectWithProperties(thing, properties) {
840
+ if (!isDefined(thing) || typeof thing !== "object") {
841
+ return false;
871
842
  }
843
+ for (const property of properties) {
844
+ if (!objectHasProperty(thing, property)) {
845
+ return false;
846
+ }
847
+ }
848
+ return true;
849
+ }
850
+ /**
851
+ * Helper TypeGuard that checks if the input is an object with the specified property.
852
+ * @param thing - Any object.
853
+ * @param property - The name of the property that should appear in the object.
854
+ */
855
+ function objectHasProperty(thing, property) {
856
+ return (isDefined(thing) && typeof thing === "object" && property in thing);
857
+ }
858
+ function isNodeReadableStream(x) {
859
+ return Boolean(x && typeof x["pipe"] === "function");
860
+ }
861
+ function isWebReadableStream(x) {
862
+ return Boolean(x &&
863
+ typeof x.getReader === "function" &&
864
+ typeof x.tee === "function");
865
+ }
866
+ function isReadableStream$1(x) {
867
+ return isNodeReadableStream(x) || isWebReadableStream(x);
868
+ }
869
+ function isBlob(x) {
870
+ return typeof x.stream === "function";
872
871
  }
873
872
 
874
873
  // Copyright (c) Microsoft Corporation.
875
874
  // Licensed under the MIT license.
876
- const StandardAbortMessage$1 = "The operation was aborted.";
877
- /**
878
- * A wrapper for setTimeout that resolves a promise after delayInMs milliseconds.
879
- * @param delayInMs - The number of milliseconds to be delayed.
880
- * @param value - The value to be resolved with after a timeout of t milliseconds.
881
- * @param options - The options for delay - currently abort options
882
- * - abortSignal - The abortSignal associated with containing operation.
883
- * - abortErrorMsg - The abort error message associated with containing operation.
884
- * @returns Resolved promise
885
- */
886
- function delay$1(delayInMs, value, options) {
887
- return new Promise((resolve, reject) => {
888
- let timer = undefined;
889
- let onAborted = undefined;
890
- const rejectOnAbort = () => {
891
- return reject(new AbortError((options === null || options === void 0 ? void 0 : options.abortErrorMsg) ? options === null || options === void 0 ? void 0 : options.abortErrorMsg : StandardAbortMessage$1));
892
- };
893
- const removeListeners = () => {
894
- if ((options === null || options === void 0 ? void 0 : options.abortSignal) && onAborted) {
895
- options.abortSignal.removeEventListener("abort", onAborted);
896
- }
897
- };
898
- onAborted = () => {
899
- if (timer) {
900
- clearTimeout(timer);
875
+ function streamAsyncIterator() {
876
+ return tslib.__asyncGenerator(this, arguments, function* streamAsyncIterator_1() {
877
+ const reader = this.getReader();
878
+ try {
879
+ while (true) {
880
+ const { done, value } = yield tslib.__await(reader.read());
881
+ if (done) {
882
+ return yield tslib.__await(void 0);
883
+ }
884
+ yield yield tslib.__await(value);
901
885
  }
902
- removeListeners();
903
- return rejectOnAbort();
904
- };
905
- if ((options === null || options === void 0 ? void 0 : options.abortSignal) && options.abortSignal.aborted) {
906
- return rejectOnAbort();
907
886
  }
908
- timer = setTimeout(() => {
909
- removeListeners();
910
- resolve(value);
911
- }, delayInMs);
912
- if (options === null || options === void 0 ? void 0 : options.abortSignal) {
913
- options.abortSignal.addEventListener("abort", onAborted);
887
+ finally {
888
+ reader.releaseLock();
914
889
  }
915
890
  });
916
891
  }
917
- /**
918
- * @internal
919
- * @returns the parsed value or undefined if the parsed value is invalid.
920
- */
921
- function parseHeaderValueAsNumber(response, headerName) {
922
- const value = response.headers.get(headerName);
923
- if (!value)
924
- return;
925
- const valueAsNum = Number(value);
926
- if (Number.isNaN(valueAsNum))
927
- return;
928
- return valueAsNum;
892
+ function makeAsyncIterable(webStream) {
893
+ if (!webStream[Symbol.asyncIterator]) {
894
+ webStream[Symbol.asyncIterator] = streamAsyncIterator.bind(webStream);
895
+ }
896
+ if (!webStream.values) {
897
+ webStream.values = streamAsyncIterator.bind(webStream);
898
+ }
899
+ }
900
+ function nodeStreamFromWebStream(webStream) {
901
+ makeAsyncIterable(webStream);
902
+ return stream.Readable.fromWeb(webStream);
903
+ }
904
+ function toWebStream(stream$1) {
905
+ return isWebReadableStream(stream$1)
906
+ ? stream$1
907
+ : stream.Readable.toWeb(stream.Readable.from(stream$1));
908
+ }
909
+ function toStream(source) {
910
+ if (source instanceof Uint8Array) {
911
+ return stream.Readable.from(Buffer.from(source));
912
+ }
913
+ else if (isBlob(source)) {
914
+ return nodeStreamFromWebStream(source.stream());
915
+ }
916
+ else if (isNodeReadableStream(source)) {
917
+ return source;
918
+ }
919
+ else {
920
+ return nodeStreamFromWebStream(source);
921
+ }
922
+ }
923
+ function concatenateStreams(sources) {
924
+ if (sources.some(isWebReadableStream)) {
925
+ throw new Error("Was not expecting a Web stream here");
926
+ }
927
+ return stream.Readable.from((function () {
928
+ return tslib.__asyncGenerator(this, arguments, function* () {
929
+ var _a, e_1, _b, _c;
930
+ for (const stream of sources) {
931
+ try {
932
+ for (var _d = true, stream_1 = (e_1 = void 0, tslib.__asyncValues(stream)), stream_1_1; stream_1_1 = yield tslib.__await(stream_1.next()), _a = stream_1_1.done, !_a; _d = true) {
933
+ _c = stream_1_1.value;
934
+ _d = false;
935
+ const chunk = _c;
936
+ yield yield tslib.__await(chunk);
937
+ }
938
+ }
939
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
940
+ finally {
941
+ try {
942
+ if (!_d && !_a && (_b = stream_1.return)) yield tslib.__await(_b.call(stream_1));
943
+ }
944
+ finally { if (e_1) throw e_1.error; }
945
+ }
946
+ }
947
+ });
948
+ })());
929
949
  }
930
950
 
931
951
  // Copyright (c) Microsoft Corporation.
932
952
  // Licensed under the MIT license.
933
- /**
934
- * The header that comes back from services representing
935
- * the amount of time (minimum) to wait to retry (in seconds or timestamp after which we can retry).
936
- */
937
- const RetryAfterHeader = "Retry-After";
938
- /**
939
- * The headers that come back from services representing
940
- * the amount of time (minimum) to wait to retry.
941
- *
942
- * "retry-after-ms", "x-ms-retry-after-ms" : milliseconds
943
- * "Retry-After" : seconds or timestamp
953
+ /*
954
+ * NOTE: When moving this file, please update "react-native" section in package.json.
944
955
  */
945
- const AllRetryAfterHeaders = ["retry-after-ms", "x-ms-retry-after-ms", RetryAfterHeader];
946
956
  /**
947
- * A response is a throttling retry response if it has a throttling status code (429 or 503),
948
- * as long as one of the [ "Retry-After" or "retry-after-ms" or "x-ms-retry-after-ms" ] headers has a valid value.
949
- *
950
- * Returns the `retryAfterInMs` value if the response is a throttling retry response.
951
- * If not throttling retry response, returns `undefined`.
957
+ * Generated Universally Unique Identifier
952
958
  *
953
- * @internal
959
+ * @returns RFC4122 v4 UUID.
954
960
  */
955
- function getRetryAfterInMs(response) {
956
- if (!(response && [429, 503].includes(response.status)))
957
- return undefined;
958
- try {
959
- // Headers: "retry-after-ms", "x-ms-retry-after-ms", "Retry-After"
960
- for (const header of AllRetryAfterHeaders) {
961
- const retryAfterValue = parseHeaderValueAsNumber(response, header);
962
- if (retryAfterValue === 0 || retryAfterValue) {
963
- // "Retry-After" header ==> seconds
964
- // "retry-after-ms", "x-ms-retry-after-ms" headers ==> milli-seconds
965
- const multiplyingFactor = header === RetryAfterHeader ? 1000 : 1;
966
- return retryAfterValue * multiplyingFactor; // in milli-seconds
967
- }
961
+ function generateUUID() {
962
+ let uuid = "";
963
+ for (let i = 0; i < 32; i++) {
964
+ // Generate a random number between 0 and 15
965
+ const randomNumber = Math.floor(Math.random() * 16);
966
+ // Set the UUID version to 4 in the 13th position
967
+ if (i === 12) {
968
+ uuid += "4";
969
+ }
970
+ else if (i === 16) {
971
+ // Set the UUID variant to "10" in the 17th position
972
+ uuid += (randomNumber & 0x3) | 0x8;
973
+ }
974
+ else {
975
+ // Add a random hexadecimal digit to the UUID string
976
+ uuid += randomNumber.toString(16);
977
+ }
978
+ // Add hyphens to the UUID string at the appropriate positions
979
+ if (i === 7 || i === 11 || i === 15 || i === 19) {
980
+ uuid += "-";
968
981
  }
969
- // RetryAfterHeader ("Retry-After") has a special case where it might be formatted as a date instead of a number of seconds
970
- const retryAfterHeader = response.headers.get(RetryAfterHeader);
971
- if (!retryAfterHeader)
972
- return;
973
- const date = Date.parse(retryAfterHeader);
974
- const diff = date - Date.now();
975
- // negative diff would mean a date in the past, so retry asap with 0 milliseconds
976
- return Number.isFinite(diff) ? Math.max(0, diff) : undefined;
977
982
  }
978
- catch (e) {
983
+ return uuid;
984
+ }
985
+
986
+ // Copyright (c) Microsoft Corporation.
987
+ // Licensed under the MIT license.
988
+ var _a$1;
989
+ // NOTE: This is a workaround until we can use `globalThis.crypto.randomUUID` in Node.js 19+.
990
+ let uuidFunction = typeof ((_a$1 = globalThis === null || globalThis === void 0 ? void 0 : globalThis.crypto) === null || _a$1 === void 0 ? void 0 : _a$1.randomUUID) === "function"
991
+ ? globalThis.crypto.randomUUID.bind(globalThis.crypto)
992
+ : crypto.randomUUID;
993
+ // Not defined in earlier versions of Node.js 14
994
+ if (!uuidFunction) {
995
+ uuidFunction = generateUUID;
996
+ }
997
+ /**
998
+ * Generated Universally Unique Identifier
999
+ *
1000
+ * @returns RFC4122 v4 UUID.
1001
+ */
1002
+ function randomUUID() {
1003
+ return uuidFunction();
1004
+ }
1005
+
1006
+ // Copyright (c) Microsoft Corporation.
1007
+ // Licensed under the MIT license.
1008
+ function generateBoundary() {
1009
+ return `----AzSDKFormBoundary${randomUUID()}`;
1010
+ }
1011
+ function encodeHeaders(headers) {
1012
+ let result = "";
1013
+ for (const [key, value] of headers) {
1014
+ result += `${key}: ${value}\r\n`;
1015
+ }
1016
+ return result;
1017
+ }
1018
+ function getLength(source) {
1019
+ if (source instanceof Uint8Array) {
1020
+ return source.byteLength;
1021
+ }
1022
+ else if (isBlob(source)) {
1023
+ // if was created using createFile then -1 means we have an unknown size
1024
+ return source.size === -1 ? undefined : source.size;
1025
+ }
1026
+ else {
979
1027
  return undefined;
980
1028
  }
981
1029
  }
1030
+ function getTotalLength(sources) {
1031
+ let total = 0;
1032
+ for (const source of sources) {
1033
+ const partLength = getLength(source);
1034
+ if (partLength === undefined) {
1035
+ return undefined;
1036
+ }
1037
+ else {
1038
+ total += partLength;
1039
+ }
1040
+ }
1041
+ return total;
1042
+ }
1043
+ function buildRequestBody(request, parts, boundary) {
1044
+ const sources = [
1045
+ stringToUint8Array(`--${boundary}`, "utf-8"),
1046
+ ...parts.flatMap((part) => [
1047
+ stringToUint8Array("\r\n", "utf-8"),
1048
+ stringToUint8Array(encodeHeaders(part.headers), "utf-8"),
1049
+ stringToUint8Array("\r\n", "utf-8"),
1050
+ part.body,
1051
+ stringToUint8Array(`\r\n--${boundary}`, "utf-8"),
1052
+ ]),
1053
+ stringToUint8Array("--\r\n\r\n", "utf-8"),
1054
+ ];
1055
+ const contentLength = getTotalLength(sources);
1056
+ if (contentLength) {
1057
+ request.headers.set("Content-Length", contentLength);
1058
+ }
1059
+ request.body = (() => concatenateStreams(sources.map((source) => (typeof source === "function" ? source() : source)).map(toStream)));
1060
+ }
982
1061
  /**
983
- * A response is a retry response if it has a throttling status code (429 or 503),
984
- * as long as one of the [ "Retry-After" or "retry-after-ms" or "x-ms-retry-after-ms" ] headers has a valid value.
1062
+ * Name of multipart policy
985
1063
  */
986
- function isThrottlingRetryResponse(response) {
987
- return Number.isFinite(getRetryAfterInMs(response));
1064
+ const multipartPolicyName = "multipartPolicy";
1065
+ const maxBoundaryLength = 70;
1066
+ const validBoundaryCharacters = new Set(`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'()+,-./:=?`);
1067
+ function assertValidBoundary(boundary) {
1068
+ if (boundary.length > maxBoundaryLength) {
1069
+ throw new Error(`Multipart boundary "${boundary}" exceeds maximum length of 70 characters`);
1070
+ }
1071
+ if (Array.from(boundary).some((x) => !validBoundaryCharacters.has(x))) {
1072
+ throw new Error(`Multipart boundary "${boundary}" contains invalid characters`);
1073
+ }
988
1074
  }
989
- function throttlingRetryStrategy() {
1075
+ /**
1076
+ * Pipeline policy for multipart requests
1077
+ */
1078
+ function multipartPolicy() {
990
1079
  return {
991
- name: "throttlingRetryStrategy",
992
- retry({ response }) {
993
- const retryAfterInMs = getRetryAfterInMs(response);
994
- if (!Number.isFinite(retryAfterInMs)) {
995
- return { skipStrategy: true };
1080
+ name: multipartPolicyName,
1081
+ sendRequest(request, next) {
1082
+ var _a;
1083
+ if (!request.multipartBody) {
1084
+ return next(request);
996
1085
  }
997
- return {
998
- retryAfterInMs,
999
- };
1086
+ if (request.body) {
1087
+ throw new Error("multipartBody and regular body cannot be set at the same time");
1088
+ }
1089
+ let boundary = request.multipartBody.boundary;
1090
+ const contentTypeHeader = (_a = request.headers.get("Content-Type")) !== null && _a !== void 0 ? _a : "multipart/mixed";
1091
+ const parsedHeader = contentTypeHeader.match(/^(multipart\/[^ ;]+)(?:; *boundary=(.+))?$/);
1092
+ if (!parsedHeader) {
1093
+ throw new Error(`Got multipart request body, but content-type header was not multipart: ${contentTypeHeader}`);
1094
+ }
1095
+ const [, contentType, parsedBoundary] = parsedHeader;
1096
+ if (parsedBoundary && boundary && parsedBoundary !== boundary) {
1097
+ throw new Error(`Multipart boundary was specified as ${parsedBoundary} in the header, but got ${boundary} in the request body`);
1098
+ }
1099
+ boundary !== null && boundary !== void 0 ? boundary : (boundary = parsedBoundary);
1100
+ if (boundary) {
1101
+ assertValidBoundary(boundary);
1102
+ }
1103
+ else {
1104
+ boundary = generateBoundary();
1105
+ }
1106
+ request.headers.set("Content-Type", `${contentType}; boundary=${boundary}`);
1107
+ buildRequestBody(request, request.multipartBody.parts, boundary);
1108
+ request.multipartBody = undefined;
1109
+ return next(request);
1000
1110
  },
1001
1111
  };
1002
1112
  }
1003
1113
 
1004
1114
  // Copyright (c) Microsoft Corporation.
1005
1115
  // Licensed under the MIT license.
1006
- // intervals are in milliseconds
1007
- const DEFAULT_CLIENT_RETRY_INTERVAL = 1000;
1008
- const DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 64;
1009
1116
  /**
1010
- * A retry strategy that retries with an exponentially increasing delay in these two cases:
1011
- * - When there are errors in the underlying transport layer (e.g. DNS lookup failures).
1012
- * - Or otherwise if the outgoing request fails (408, greater or equal than 500, except for 501 and 505).
1117
+ * The programmatic identifier of the decompressResponsePolicy.
1013
1118
  */
1014
- function exponentialRetryStrategy(options = {}) {
1015
- var _a, _b;
1016
- const retryInterval = (_a = options.retryDelayInMs) !== null && _a !== void 0 ? _a : DEFAULT_CLIENT_RETRY_INTERVAL;
1017
- const maxRetryInterval = (_b = options.maxRetryDelayInMs) !== null && _b !== void 0 ? _b : DEFAULT_CLIENT_MAX_RETRY_INTERVAL;
1018
- let retryAfterInMs = retryInterval;
1119
+ const decompressResponsePolicyName = "decompressResponsePolicy";
1120
+ /**
1121
+ * A policy to enable response decompression according to Accept-Encoding header
1122
+ * https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Encoding
1123
+ */
1124
+ function decompressResponsePolicy() {
1019
1125
  return {
1020
- name: "exponentialRetryStrategy",
1021
- retry({ retryCount, response, responseError }) {
1022
- const matchedSystemError = isSystemError(responseError);
1023
- const ignoreSystemErrors = matchedSystemError && options.ignoreSystemErrors;
1024
- const isExponential = isExponentialRetryResponse(response);
1025
- const ignoreExponentialResponse = isExponential && options.ignoreHttpStatusCodes;
1026
- const unknownResponse = response && (isThrottlingRetryResponse(response) || !isExponential);
1027
- if (unknownResponse || ignoreExponentialResponse || ignoreSystemErrors) {
1028
- return { skipStrategy: true };
1029
- }
1030
- if (responseError && !matchedSystemError && !isExponential) {
1031
- return { errorToThrow: responseError };
1126
+ name: decompressResponsePolicyName,
1127
+ async sendRequest(request, next) {
1128
+ // HEAD requests have no body
1129
+ if (request.method !== "HEAD") {
1130
+ request.headers.set("Accept-Encoding", "gzip,deflate");
1032
1131
  }
1033
- // Exponentially increase the delay each time
1034
- const exponentialDelay = retryAfterInMs * Math.pow(2, retryCount);
1035
- // Don't let the delay exceed the maximum
1036
- const clampedExponentialDelay = Math.min(maxRetryInterval, exponentialDelay);
1037
- // Allow the final value to have some "jitter" (within 50% of the delay size) so
1038
- // that retries across multiple clients don't occur simultaneously.
1039
- retryAfterInMs =
1040
- clampedExponentialDelay / 2 + getRandomIntegerInclusive(0, clampedExponentialDelay / 2);
1041
- return { retryAfterInMs };
1132
+ return next(request);
1042
1133
  },
1043
1134
  };
1044
1135
  }
1136
+
1137
+ // Copyright (c) Microsoft Corporation.
1138
+ // Licensed under the MIT license.
1045
1139
  /**
1046
- * A response is a retry response if it has status codes:
1047
- * - 408, or
1048
- * - Greater or equal than 500, except for 501 and 505.
1049
- */
1050
- function isExponentialRetryResponse(response) {
1051
- return Boolean(response &&
1052
- response.status !== undefined &&
1053
- (response.status >= 500 || response.status === 408) &&
1054
- response.status !== 501 &&
1055
- response.status !== 505);
1056
- }
1057
- /**
1058
- * Determines whether an error from a pipeline response was triggered in the network layer.
1140
+ * Returns a random integer value between a lower and upper bound,
1141
+ * inclusive of both bounds.
1142
+ * Note that this uses Math.random and isn't secure. If you need to use
1143
+ * this for any kind of security purpose, find a better source of random.
1144
+ * @param min - The smallest integer value allowed.
1145
+ * @param max - The largest integer value allowed.
1059
1146
  */
1060
- function isSystemError(err) {
1061
- if (!err) {
1062
- return false;
1063
- }
1064
- return (err.code === "ETIMEDOUT" ||
1065
- err.code === "ESOCKETTIMEDOUT" ||
1066
- err.code === "ECONNREFUSED" ||
1067
- err.code === "ECONNRESET" ||
1068
- err.code === "ENOENT" ||
1069
- err.code === "ENOTFOUND");
1147
+ function getRandomIntegerInclusive(min, max) {
1148
+ // Make sure inputs are integers.
1149
+ min = Math.ceil(min);
1150
+ max = Math.floor(max);
1151
+ // Pick a random offset from zero to the size of the range.
1152
+ // Since Math.random() can never return 1, we have to make the range one larger
1153
+ // in order to be inclusive of the maximum value after we take the floor.
1154
+ const offset = Math.floor(Math.random() * (max - min + 1));
1155
+ return offset + min;
1070
1156
  }
1071
1157
 
1072
1158
  // Copyright (c) Microsoft Corporation.
1073
1159
  // Licensed under the MIT license.
1074
- const retryPolicyLogger = createClientLogger("core-rest-pipeline retryPolicy");
1075
- /**
1076
- * The programmatic identifier of the retryPolicy.
1077
- */
1078
- const retryPolicyName = "retryPolicy";
1079
1160
  /**
1080
- * retryPolicy is a generic policy to enable retrying requests when certain conditions are met
1081
- */
1161
+ * This error is thrown when an asynchronous operation has been aborted.
1162
+ * Check for this error by testing the `name` that the name property of the
1163
+ * error matches `"AbortError"`.
1164
+ *
1165
+ * @example
1166
+ * ```ts
1167
+ * const controller = new AbortController();
1168
+ * controller.abort();
1169
+ * try {
1170
+ * doAsyncWork(controller.signal)
1171
+ * } catch (e) {
1172
+ * if (e.name === 'AbortError') {
1173
+ * // handle abort error here.
1174
+ * }
1175
+ * }
1176
+ * ```
1177
+ */
1178
+ class AbortError extends Error {
1179
+ constructor(message) {
1180
+ super(message);
1181
+ this.name = "AbortError";
1182
+ }
1183
+ }
1184
+
1185
+ // Copyright (c) Microsoft Corporation.
1186
+ // Licensed under the MIT license.
1187
+ const StandardAbortMessage$1 = "The operation was aborted.";
1188
+ /**
1189
+ * A wrapper for setTimeout that resolves a promise after delayInMs milliseconds.
1190
+ * @param delayInMs - The number of milliseconds to be delayed.
1191
+ * @param value - The value to be resolved with after a timeout of t milliseconds.
1192
+ * @param options - The options for delay - currently abort options
1193
+ * - abortSignal - The abortSignal associated with containing operation.
1194
+ * - abortErrorMsg - The abort error message associated with containing operation.
1195
+ * @returns Resolved promise
1196
+ */
1197
+ function delay$1(delayInMs, value, options) {
1198
+ return new Promise((resolve, reject) => {
1199
+ let timer = undefined;
1200
+ let onAborted = undefined;
1201
+ const rejectOnAbort = () => {
1202
+ return reject(new AbortError((options === null || options === void 0 ? void 0 : options.abortErrorMsg) ? options === null || options === void 0 ? void 0 : options.abortErrorMsg : StandardAbortMessage$1));
1203
+ };
1204
+ const removeListeners = () => {
1205
+ if ((options === null || options === void 0 ? void 0 : options.abortSignal) && onAborted) {
1206
+ options.abortSignal.removeEventListener("abort", onAborted);
1207
+ }
1208
+ };
1209
+ onAborted = () => {
1210
+ if (timer) {
1211
+ clearTimeout(timer);
1212
+ }
1213
+ removeListeners();
1214
+ return rejectOnAbort();
1215
+ };
1216
+ if ((options === null || options === void 0 ? void 0 : options.abortSignal) && options.abortSignal.aborted) {
1217
+ return rejectOnAbort();
1218
+ }
1219
+ timer = setTimeout(() => {
1220
+ removeListeners();
1221
+ resolve(value);
1222
+ }, delayInMs);
1223
+ if (options === null || options === void 0 ? void 0 : options.abortSignal) {
1224
+ options.abortSignal.addEventListener("abort", onAborted);
1225
+ }
1226
+ });
1227
+ }
1228
+ /**
1229
+ * @internal
1230
+ * @returns the parsed value or undefined if the parsed value is invalid.
1231
+ */
1232
+ function parseHeaderValueAsNumber(response, headerName) {
1233
+ const value = response.headers.get(headerName);
1234
+ if (!value)
1235
+ return;
1236
+ const valueAsNum = Number(value);
1237
+ if (Number.isNaN(valueAsNum))
1238
+ return;
1239
+ return valueAsNum;
1240
+ }
1241
+
1242
+ // Copyright (c) Microsoft Corporation.
1243
+ // Licensed under the MIT license.
1244
+ /**
1245
+ * The header that comes back from services representing
1246
+ * the amount of time (minimum) to wait to retry (in seconds or timestamp after which we can retry).
1247
+ */
1248
+ const RetryAfterHeader = "Retry-After";
1249
+ /**
1250
+ * The headers that come back from services representing
1251
+ * the amount of time (minimum) to wait to retry.
1252
+ *
1253
+ * "retry-after-ms", "x-ms-retry-after-ms" : milliseconds
1254
+ * "Retry-After" : seconds or timestamp
1255
+ */
1256
+ const AllRetryAfterHeaders = ["retry-after-ms", "x-ms-retry-after-ms", RetryAfterHeader];
1257
+ /**
1258
+ * A response is a throttling retry response if it has a throttling status code (429 or 503),
1259
+ * as long as one of the [ "Retry-After" or "retry-after-ms" or "x-ms-retry-after-ms" ] headers has a valid value.
1260
+ *
1261
+ * Returns the `retryAfterInMs` value if the response is a throttling retry response.
1262
+ * If not throttling retry response, returns `undefined`.
1263
+ *
1264
+ * @internal
1265
+ */
1266
+ function getRetryAfterInMs(response) {
1267
+ if (!(response && [429, 503].includes(response.status)))
1268
+ return undefined;
1269
+ try {
1270
+ // Headers: "retry-after-ms", "x-ms-retry-after-ms", "Retry-After"
1271
+ for (const header of AllRetryAfterHeaders) {
1272
+ const retryAfterValue = parseHeaderValueAsNumber(response, header);
1273
+ if (retryAfterValue === 0 || retryAfterValue) {
1274
+ // "Retry-After" header ==> seconds
1275
+ // "retry-after-ms", "x-ms-retry-after-ms" headers ==> milli-seconds
1276
+ const multiplyingFactor = header === RetryAfterHeader ? 1000 : 1;
1277
+ return retryAfterValue * multiplyingFactor; // in milli-seconds
1278
+ }
1279
+ }
1280
+ // RetryAfterHeader ("Retry-After") has a special case where it might be formatted as a date instead of a number of seconds
1281
+ const retryAfterHeader = response.headers.get(RetryAfterHeader);
1282
+ if (!retryAfterHeader)
1283
+ return;
1284
+ const date = Date.parse(retryAfterHeader);
1285
+ const diff = date - Date.now();
1286
+ // negative diff would mean a date in the past, so retry asap with 0 milliseconds
1287
+ return Number.isFinite(diff) ? Math.max(0, diff) : undefined;
1288
+ }
1289
+ catch (e) {
1290
+ return undefined;
1291
+ }
1292
+ }
1293
+ /**
1294
+ * A response is a retry response if it has a throttling status code (429 or 503),
1295
+ * as long as one of the [ "Retry-After" or "retry-after-ms" or "x-ms-retry-after-ms" ] headers has a valid value.
1296
+ */
1297
+ function isThrottlingRetryResponse(response) {
1298
+ return Number.isFinite(getRetryAfterInMs(response));
1299
+ }
1300
+ function throttlingRetryStrategy() {
1301
+ return {
1302
+ name: "throttlingRetryStrategy",
1303
+ retry({ response }) {
1304
+ const retryAfterInMs = getRetryAfterInMs(response);
1305
+ if (!Number.isFinite(retryAfterInMs)) {
1306
+ return { skipStrategy: true };
1307
+ }
1308
+ return {
1309
+ retryAfterInMs,
1310
+ };
1311
+ },
1312
+ };
1313
+ }
1314
+
1315
+ // Copyright (c) Microsoft Corporation.
1316
+ // Licensed under the MIT license.
1317
+ // intervals are in milliseconds
1318
+ const DEFAULT_CLIENT_RETRY_INTERVAL = 1000;
1319
+ const DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 64;
1320
+ /**
1321
+ * A retry strategy that retries with an exponentially increasing delay in these two cases:
1322
+ * - When there are errors in the underlying transport layer (e.g. DNS lookup failures).
1323
+ * - Or otherwise if the outgoing request fails (408, greater or equal than 500, except for 501 and 505).
1324
+ */
1325
+ function exponentialRetryStrategy(options = {}) {
1326
+ var _a, _b;
1327
+ const retryInterval = (_a = options.retryDelayInMs) !== null && _a !== void 0 ? _a : DEFAULT_CLIENT_RETRY_INTERVAL;
1328
+ const maxRetryInterval = (_b = options.maxRetryDelayInMs) !== null && _b !== void 0 ? _b : DEFAULT_CLIENT_MAX_RETRY_INTERVAL;
1329
+ let retryAfterInMs = retryInterval;
1330
+ return {
1331
+ name: "exponentialRetryStrategy",
1332
+ retry({ retryCount, response, responseError }) {
1333
+ const matchedSystemError = isSystemError(responseError);
1334
+ const ignoreSystemErrors = matchedSystemError && options.ignoreSystemErrors;
1335
+ const isExponential = isExponentialRetryResponse(response);
1336
+ const ignoreExponentialResponse = isExponential && options.ignoreHttpStatusCodes;
1337
+ const unknownResponse = response && (isThrottlingRetryResponse(response) || !isExponential);
1338
+ if (unknownResponse || ignoreExponentialResponse || ignoreSystemErrors) {
1339
+ return { skipStrategy: true };
1340
+ }
1341
+ if (responseError && !matchedSystemError && !isExponential) {
1342
+ return { errorToThrow: responseError };
1343
+ }
1344
+ // Exponentially increase the delay each time
1345
+ const exponentialDelay = retryAfterInMs * Math.pow(2, retryCount);
1346
+ // Don't let the delay exceed the maximum
1347
+ const clampedExponentialDelay = Math.min(maxRetryInterval, exponentialDelay);
1348
+ // Allow the final value to have some "jitter" (within 50% of the delay size) so
1349
+ // that retries across multiple clients don't occur simultaneously.
1350
+ retryAfterInMs =
1351
+ clampedExponentialDelay / 2 + getRandomIntegerInclusive(0, clampedExponentialDelay / 2);
1352
+ return { retryAfterInMs };
1353
+ },
1354
+ };
1355
+ }
1356
+ /**
1357
+ * A response is a retry response if it has status codes:
1358
+ * - 408, or
1359
+ * - Greater or equal than 500, except for 501 and 505.
1360
+ */
1361
+ function isExponentialRetryResponse(response) {
1362
+ return Boolean(response &&
1363
+ response.status !== undefined &&
1364
+ (response.status >= 500 || response.status === 408) &&
1365
+ response.status !== 501 &&
1366
+ response.status !== 505);
1367
+ }
1368
+ /**
1369
+ * Determines whether an error from a pipeline response was triggered in the network layer.
1370
+ */
1371
+ function isSystemError(err) {
1372
+ if (!err) {
1373
+ return false;
1374
+ }
1375
+ return (err.code === "ETIMEDOUT" ||
1376
+ err.code === "ESOCKETTIMEDOUT" ||
1377
+ err.code === "ECONNREFUSED" ||
1378
+ err.code === "ECONNRESET" ||
1379
+ err.code === "ENOENT" ||
1380
+ err.code === "ENOTFOUND");
1381
+ }
1382
+
1383
+ // Copyright (c) Microsoft Corporation.
1384
+ // Licensed under the MIT license.
1385
+ const retryPolicyLogger = createClientLogger("core-rest-pipeline retryPolicy");
1386
+ /**
1387
+ * The programmatic identifier of the retryPolicy.
1388
+ */
1389
+ const retryPolicyName = "retryPolicy";
1390
+ /**
1391
+ * retryPolicy is a generic policy to enable retrying requests when certain conditions are met
1392
+ */
1082
1393
  function retryPolicy(strategies, options = { maxRetries: DEFAULT_RETRY_POLICY_COUNT }) {
1083
1394
  const logger = options.logger || retryPolicyLogger;
1084
1395
  return {
@@ -1193,27 +1504,6 @@ function defaultRetryPolicy(options = {}) {
1193
1504
  };
1194
1505
  }
1195
1506
 
1196
- // Copyright (c) Microsoft Corporation.
1197
- // Licensed under the MIT license.
1198
- /**
1199
- * The helper that transforms bytes with specific character encoding into string
1200
- * @param bytes - the uint8array bytes
1201
- * @param format - the format we use to encode the byte
1202
- * @returns a string of the encoded string
1203
- */
1204
- function uint8ArrayToString(bytes, format) {
1205
- return Buffer.from(bytes).toString(format);
1206
- }
1207
- /**
1208
- * The helper that transforms string to specific character encoded bytes array.
1209
- * @param value - the string to be converted
1210
- * @param format - the format we use to decode the value
1211
- * @returns a uint8array
1212
- */
1213
- function stringToUint8Array(value, format) {
1214
- return Buffer.from(value, format);
1215
- }
1216
-
1217
1507
  // Copyright (c) Microsoft Corporation.
1218
1508
  // Licensed under the MIT license.
1219
1509
  function normalizeName(name) {
@@ -1378,13 +1668,13 @@ async function prepareFormData(formData, request) {
1378
1668
  });
1379
1669
  }
1380
1670
  }
1381
- request.multipartBody = { parts };
1382
1671
  }
1672
+ request.multipartBody = { parts };
1383
1673
  }
1384
1674
 
1385
1675
  // Copyright (c) Microsoft Corporation.
1386
1676
  // Licensed under the MIT license.
1387
- var _a$1, _b, _c, _d;
1677
+ var _a, _b, _c, _d;
1388
1678
  /**
1389
1679
  * A constant that indicates whether the environment the code is running is a Web Browser.
1390
1680
  */
@@ -1395,7 +1685,7 @@ const isBrowser = typeof window !== "undefined" && typeof window.document !== "u
1395
1685
  */
1396
1686
  const isWebWorker = typeof self === "object" &&
1397
1687
  typeof (self === null || self === void 0 ? void 0 : self.importScripts) === "function" &&
1398
- (((_a$1 = self.constructor) === null || _a$1 === void 0 ? void 0 : _a$1.name) === "DedicatedWorkerGlobalScope" ||
1688
+ (((_a = self.constructor) === null || _a === void 0 ? void 0 : _a.name) === "DedicatedWorkerGlobalScope" ||
1399
1689
  ((_b = self.constructor) === null || _b === void 0 ? void 0 : _b.name) === "ServiceWorkerGlobalScope" ||
1400
1690
  ((_c = self.constructor) === null || _c === void 0 ? void 0 : _c.name) === "SharedWorkerGlobalScope");
1401
1691
  /**
@@ -2010,295 +2300,6 @@ function tryProcessResponse(span, response) {
2010
2300
  }
2011
2301
  }
2012
2302
 
2013
- // Copyright (c) Microsoft Corporation.
2014
- // Licensed under the MIT license.
2015
- /**
2016
- * Helper TypeGuard that checks if something is defined or not.
2017
- * @param thing - Anything
2018
- */
2019
- function isDefined(thing) {
2020
- return typeof thing !== "undefined" && thing !== null;
2021
- }
2022
- /**
2023
- * Helper TypeGuard that checks if the input is an object with the specified properties.
2024
- * @param thing - Anything.
2025
- * @param properties - The name of the properties that should appear in the object.
2026
- */
2027
- function isObjectWithProperties(thing, properties) {
2028
- if (!isDefined(thing) || typeof thing !== "object") {
2029
- return false;
2030
- }
2031
- for (const property of properties) {
2032
- if (!objectHasProperty(thing, property)) {
2033
- return false;
2034
- }
2035
- }
2036
- return true;
2037
- }
2038
- /**
2039
- * Helper TypeGuard that checks if the input is an object with the specified property.
2040
- * @param thing - Any object.
2041
- * @param property - The name of the property that should appear in the object.
2042
- */
2043
- function objectHasProperty(thing, property) {
2044
- return (isDefined(thing) && typeof thing === "object" && property in thing);
2045
- }
2046
- function isNodeReadableStream(x) {
2047
- return Boolean(x && typeof x["pipe"] === "function");
2048
- }
2049
- function isWebReadableStream(x) {
2050
- return Boolean(x &&
2051
- typeof x.getReader === "function" &&
2052
- typeof x.tee === "function");
2053
- }
2054
- function isReadableStream$1(x) {
2055
- return isNodeReadableStream(x) || isWebReadableStream(x);
2056
- }
2057
- function isBlob(x) {
2058
- return typeof x.stream === "function";
2059
- }
2060
-
2061
- // Copyright (c) Microsoft Corporation.
2062
- // Licensed under the MIT license.
2063
- function streamAsyncIterator() {
2064
- return tslib.__asyncGenerator(this, arguments, function* streamAsyncIterator_1() {
2065
- const reader = this.getReader();
2066
- try {
2067
- while (true) {
2068
- const { done, value } = yield tslib.__await(reader.read());
2069
- if (done) {
2070
- return yield tslib.__await(void 0);
2071
- }
2072
- yield yield tslib.__await(value);
2073
- }
2074
- }
2075
- finally {
2076
- reader.releaseLock();
2077
- }
2078
- });
2079
- }
2080
- function makeAsyncIterable(webStream) {
2081
- if (!webStream[Symbol.asyncIterator]) {
2082
- webStream[Symbol.asyncIterator] = streamAsyncIterator.bind(webStream);
2083
- }
2084
- if (!webStream.values) {
2085
- webStream.values = streamAsyncIterator.bind(webStream);
2086
- }
2087
- }
2088
- function nodeStreamFromWebStream(webStream) {
2089
- makeAsyncIterable(webStream);
2090
- return stream.Readable.fromWeb(webStream);
2091
- }
2092
- function toWebStream(stream$1) {
2093
- return isWebReadableStream(stream$1)
2094
- ? stream$1
2095
- : stream.Readable.toWeb(stream.Readable.from(stream$1));
2096
- }
2097
- function toStream(source) {
2098
- if (source instanceof Uint8Array) {
2099
- return stream.Readable.from(Buffer.from(source));
2100
- }
2101
- else if (isBlob(source)) {
2102
- return nodeStreamFromWebStream(source.stream());
2103
- }
2104
- else if (isNodeReadableStream(source)) {
2105
- return source;
2106
- }
2107
- else {
2108
- return nodeStreamFromWebStream(source);
2109
- }
2110
- }
2111
- function concatenateStreams(sources) {
2112
- if (sources.some(isWebReadableStream)) {
2113
- throw new Error("Was not expecting a Web stream here");
2114
- }
2115
- return stream.Readable.from((function () {
2116
- return tslib.__asyncGenerator(this, arguments, function* () {
2117
- var _a, e_1, _b, _c;
2118
- for (const stream of sources) {
2119
- try {
2120
- for (var _d = true, stream_1 = (e_1 = void 0, tslib.__asyncValues(stream)), stream_1_1; stream_1_1 = yield tslib.__await(stream_1.next()), _a = stream_1_1.done, !_a; _d = true) {
2121
- _c = stream_1_1.value;
2122
- _d = false;
2123
- const chunk = _c;
2124
- yield yield tslib.__await(chunk);
2125
- }
2126
- }
2127
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2128
- finally {
2129
- try {
2130
- if (!_d && !_a && (_b = stream_1.return)) yield tslib.__await(_b.call(stream_1));
2131
- }
2132
- finally { if (e_1) throw e_1.error; }
2133
- }
2134
- }
2135
- });
2136
- })());
2137
- }
2138
-
2139
- // Copyright (c) Microsoft Corporation.
2140
- // Licensed under the MIT license.
2141
- /*
2142
- * NOTE: When moving this file, please update "react-native" section in package.json.
2143
- */
2144
- /**
2145
- * Generated Universally Unique Identifier
2146
- *
2147
- * @returns RFC4122 v4 UUID.
2148
- */
2149
- function generateUUID() {
2150
- let uuid = "";
2151
- for (let i = 0; i < 32; i++) {
2152
- // Generate a random number between 0 and 15
2153
- const randomNumber = Math.floor(Math.random() * 16);
2154
- // Set the UUID version to 4 in the 13th position
2155
- if (i === 12) {
2156
- uuid += "4";
2157
- }
2158
- else if (i === 16) {
2159
- // Set the UUID variant to "10" in the 17th position
2160
- uuid += (randomNumber & 0x3) | 0x8;
2161
- }
2162
- else {
2163
- // Add a random hexadecimal digit to the UUID string
2164
- uuid += randomNumber.toString(16);
2165
- }
2166
- // Add hyphens to the UUID string at the appropriate positions
2167
- if (i === 7 || i === 11 || i === 15 || i === 19) {
2168
- uuid += "-";
2169
- }
2170
- }
2171
- return uuid;
2172
- }
2173
-
2174
- // Copyright (c) Microsoft Corporation.
2175
- // Licensed under the MIT license.
2176
- var _a;
2177
- // NOTE: This is a workaround until we can use `globalThis.crypto.randomUUID` in Node.js 19+.
2178
- let uuidFunction = typeof ((_a = globalThis === null || globalThis === void 0 ? void 0 : globalThis.crypto) === null || _a === void 0 ? void 0 : _a.randomUUID) === "function"
2179
- ? globalThis.crypto.randomUUID.bind(globalThis.crypto)
2180
- : crypto.randomUUID;
2181
- // Not defined in earlier versions of Node.js 14
2182
- if (!uuidFunction) {
2183
- uuidFunction = generateUUID;
2184
- }
2185
- /**
2186
- * Generated Universally Unique Identifier
2187
- *
2188
- * @returns RFC4122 v4 UUID.
2189
- */
2190
- function randomUUID() {
2191
- return uuidFunction();
2192
- }
2193
-
2194
- // Copyright (c) Microsoft Corporation.
2195
- // Licensed under the MIT license.
2196
- function generateBoundary() {
2197
- return `----AzSDKFormBoundary${randomUUID()}`;
2198
- }
2199
- function encodeHeaders(headers) {
2200
- let result = "";
2201
- for (const [key, value] of headers) {
2202
- result += `${key}: ${value}\r\n`;
2203
- }
2204
- return result;
2205
- }
2206
- function getLength(source) {
2207
- if (source instanceof Uint8Array) {
2208
- return source.byteLength;
2209
- }
2210
- else if (isBlob(source)) {
2211
- // if was created using createFile then -1 means we have an unknown size
2212
- return source.size === -1 ? undefined : source.size;
2213
- }
2214
- else {
2215
- return undefined;
2216
- }
2217
- }
2218
- function getTotalLength(sources) {
2219
- let total = 0;
2220
- for (const source of sources) {
2221
- const partLength = getLength(source);
2222
- if (partLength === undefined) {
2223
- return undefined;
2224
- }
2225
- else {
2226
- total += partLength;
2227
- }
2228
- }
2229
- return total;
2230
- }
2231
- function buildRequestBody(request, parts, boundary) {
2232
- const sources = [
2233
- stringToUint8Array(`--${boundary}`, "utf-8"),
2234
- ...parts.flatMap((part) => [
2235
- stringToUint8Array("\r\n", "utf-8"),
2236
- stringToUint8Array(encodeHeaders(part.headers), "utf-8"),
2237
- stringToUint8Array("\r\n", "utf-8"),
2238
- part.body,
2239
- stringToUint8Array(`\r\n--${boundary}`, "utf-8"),
2240
- ]),
2241
- stringToUint8Array("--\r\n\r\n", "utf-8"),
2242
- ];
2243
- const contentLength = getTotalLength(sources);
2244
- if (contentLength) {
2245
- request.headers.set("Content-Length", contentLength);
2246
- }
2247
- request.body = (() => concatenateStreams(sources.map((source) => (typeof source === "function" ? source() : source)).map(toStream)));
2248
- }
2249
- /**
2250
- * Name of multipart policy
2251
- */
2252
- const multipartPolicyName = "multipartPolicy";
2253
- const maxBoundaryLength = 70;
2254
- const validBoundaryCharacters = new Set(`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'()+,-./:=?`);
2255
- function assertValidBoundary(boundary) {
2256
- if (boundary.length > maxBoundaryLength) {
2257
- throw new Error(`Multipart boundary "${boundary}" exceeds maximum length of 70 characters`);
2258
- }
2259
- if (Array.from(boundary).some((x) => !validBoundaryCharacters.has(x))) {
2260
- throw new Error(`Multipart boundary "${boundary}" contains invalid characters`);
2261
- }
2262
- }
2263
- /**
2264
- * Pipeline policy for multipart requests
2265
- */
2266
- function multipartPolicy() {
2267
- return {
2268
- name: multipartPolicyName,
2269
- sendRequest(request, next) {
2270
- var _a;
2271
- if (!request.multipartBody) {
2272
- return next(request);
2273
- }
2274
- if (request.body) {
2275
- throw new Error("multipartBody and regular body cannot be set at the same time");
2276
- }
2277
- let boundary = request.multipartBody.boundary;
2278
- const contentTypeHeader = (_a = request.headers.get("Content-Type")) !== null && _a !== void 0 ? _a : "multipart/mixed";
2279
- const parsedHeader = contentTypeHeader.match(/^(multipart\/[^ ;]+)(?:; *boundary=(.+))?$/);
2280
- if (!parsedHeader) {
2281
- throw new Error(`Got multipart request body, but content-type header was not multipart: ${contentTypeHeader}`);
2282
- }
2283
- const [, contentType, parsedBoundary] = parsedHeader;
2284
- if (parsedBoundary && boundary && parsedBoundary !== boundary) {
2285
- throw new Error(`Multipart boundary was specified as ${parsedBoundary} in the header, but got ${boundary} in the request body`);
2286
- }
2287
- boundary !== null && boundary !== void 0 ? boundary : (boundary = parsedBoundary);
2288
- if (boundary) {
2289
- assertValidBoundary(boundary);
2290
- }
2291
- else {
2292
- boundary = generateBoundary();
2293
- }
2294
- request.headers.set("Content-Type", `${contentType}; boundary=${boundary}`);
2295
- buildRequestBody(request, request.multipartBody.parts, boundary);
2296
- request.multipartBody = undefined;
2297
- return next(request);
2298
- },
2299
- };
2300
- }
2301
-
2302
2303
  // Copyright (c) Microsoft Corporation.
2303
2304
  // Licensed under the MIT license.
2304
2305
  /**
@@ -2314,7 +2315,7 @@ function createPipelineFromOptions(options) {
2314
2315
  pipeline.addPolicy(proxyPolicy(options.proxyOptions));
2315
2316
  pipeline.addPolicy(decompressResponsePolicy());
2316
2317
  }
2317
- pipeline.addPolicy(formDataPolicy());
2318
+ pipeline.addPolicy(formDataPolicy(), { beforePolicies: [multipartPolicyName] });
2318
2319
  pipeline.addPolicy(userAgentPolicy(options.userAgentOptions));
2319
2320
  // The multipart policy is added after policies with no phase, so that
2320
2321
  // policies can be added between it and formDataPolicy to modify