@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 +538 -537
- 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,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 =
|
|
409
|
+
const TypeSpecRuntimeLogger = debug("typeSpecRuntime");
|
|
409
410
|
TypeSpecRuntimeLogger.log = (...args) => {
|
|
410
|
-
|
|
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
|
-
|
|
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 =
|
|
477
|
-
|
|
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
|
|
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
|
-
|
|
812
|
+
function uint8ArrayToString(bytes, format) {
|
|
813
|
+
return Buffer.from(bytes).toString(format);
|
|
814
|
+
}
|
|
809
815
|
/**
|
|
810
|
-
*
|
|
811
|
-
*
|
|
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
|
|
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
|
-
*
|
|
830
|
-
*
|
|
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
|
|
837
|
-
|
|
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
|
-
*
|
|
851
|
-
*
|
|
852
|
-
*
|
|
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
|
-
|
|
868
|
-
|
|
869
|
-
|
|
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
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
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
|
-
|
|
909
|
-
|
|
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
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
* @
|
|
959
|
+
* @returns RFC4122 v4 UUID.
|
|
954
960
|
*/
|
|
955
|
-
function
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
987
|
-
|
|
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
|
-
|
|
1075
|
+
/**
|
|
1076
|
+
* Pipeline policy for multipart requests
|
|
1077
|
+
*/
|
|
1078
|
+
function multipartPolicy() {
|
|
990
1079
|
return {
|
|
991
|
-
name:
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
if (!
|
|
995
|
-
return
|
|
1080
|
+
name: multipartPolicyName,
|
|
1081
|
+
sendRequest(request, next) {
|
|
1082
|
+
var _a;
|
|
1083
|
+
if (!request.multipartBody) {
|
|
1084
|
+
return next(request);
|
|
996
1085
|
}
|
|
997
|
-
|
|
998
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
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:
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
1047
|
-
*
|
|
1048
|
-
*
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
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
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
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
|
-
*
|
|
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
|
|
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
|
|
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
|