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