@typespec/ts-http-runtime 1.0.0-alpha.20231110.2 → 1.0.0-alpha.20231115.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/index.js +500 -250
  2. package/dist/index.js.map +1 -1
  3. package/dist-esm/src/client/sendRequest.js +1 -1
  4. package/dist-esm/src/client/sendRequest.js.map +1 -1
  5. package/dist-esm/src/createPipelineFromOptions.js +5 -0
  6. package/dist-esm/src/createPipelineFromOptions.js.map +1 -1
  7. package/dist-esm/src/fetchHttpClient.js +1 -14
  8. package/dist-esm/src/fetchHttpClient.js.map +1 -1
  9. package/dist-esm/src/index.js +2 -0
  10. package/dist-esm/src/index.js.map +1 -1
  11. package/dist-esm/src/interfaces.js.map +1 -1
  12. package/dist-esm/src/pipelineRequest.js +1 -0
  13. package/dist-esm/src/pipelineRequest.js.map +1 -1
  14. package/dist-esm/src/policies/formDataPolicy.js +34 -32
  15. package/dist-esm/src/policies/formDataPolicy.js.map +1 -1
  16. package/dist-esm/src/policies/multipartPolicy.js +112 -0
  17. package/dist-esm/src/policies/multipartPolicy.js.map +1 -0
  18. package/dist-esm/src/util/file.js +51 -0
  19. package/dist-esm/src/util/file.js.map +1 -0
  20. package/dist-esm/src/util/stream.browser.js +64 -0
  21. package/dist-esm/src/util/stream.browser.js.map +1 -0
  22. package/dist-esm/src/util/stream.js +81 -0
  23. package/dist-esm/src/util/stream.js.map +1 -0
  24. package/dist-esm/src/util/typeGuards.js +14 -0
  25. package/dist-esm/src/util/typeGuards.js.map +1 -1
  26. package/dist-esm/src/xhrHttpClient.js +2 -12
  27. package/dist-esm/src/xhrHttpClient.js.map +1 -1
  28. package/package.json +2 -3
  29. package/types/ts-http-runtime.d.ts +116 -2
  30. package/dist-esm/src/client/helpers/isReadableStream.browser.js +0 -12
  31. package/dist-esm/src/client/helpers/isReadableStream.browser.js.map +0 -1
  32. package/dist-esm/src/client/helpers/isReadableStream.js +0 -10
  33. package/dist-esm/src/client/helpers/isReadableStream.js.map +0 -1
  34. package/dist-esm/src/policies/formDataPolicy.browser.js +0 -43
  35. package/dist-esm/src/policies/formDataPolicy.browser.js.map +0 -1
package/dist/index.js CHANGED
@@ -4,14 +4,14 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var os = require('os');
6
6
  var util = require('util');
7
- var FormData = require('form-data');
8
7
  var httpsProxyAgent = require('https-proxy-agent');
9
8
  var httpProxyAgent = require('http-proxy-agent');
9
+ var tslib = require('tslib');
10
+ var stream = require('stream');
11
+ var crypto = require('crypto');
10
12
  var http = require('http');
11
13
  var https = require('https');
12
14
  var zlib = require('zlib');
13
- var stream = require('stream');
14
- var crypto = require('crypto');
15
15
 
16
16
  function _interopNamespaceDefault(e) {
17
17
  var n = Object.create(null);
@@ -1194,6 +1194,116 @@ function defaultRetryPolicy(options = {}) {
1194
1194
  };
1195
1195
  }
1196
1196
 
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
+ // Copyright (c) Microsoft Corporation.
1219
+ // Licensed under the MIT license.
1220
+ function normalizeName(name) {
1221
+ return name.toLowerCase();
1222
+ }
1223
+ function* headerIterator(map) {
1224
+ for (const entry of map.values()) {
1225
+ yield [entry.name, entry.value];
1226
+ }
1227
+ }
1228
+ class HttpHeadersImpl {
1229
+ constructor(rawHeaders) {
1230
+ this._headersMap = new Map();
1231
+ if (rawHeaders) {
1232
+ for (const headerName of Object.keys(rawHeaders)) {
1233
+ this.set(headerName, rawHeaders[headerName]);
1234
+ }
1235
+ }
1236
+ }
1237
+ /**
1238
+ * Set a header in this collection with the provided name and value. The name is
1239
+ * case-insensitive.
1240
+ * @param name - The name of the header to set. This value is case-insensitive.
1241
+ * @param value - The value of the header to set.
1242
+ */
1243
+ set(name, value) {
1244
+ this._headersMap.set(normalizeName(name), { name, value: String(value).trim() });
1245
+ }
1246
+ /**
1247
+ * Get the header value for the provided header name, or undefined if no header exists in this
1248
+ * collection with the provided name.
1249
+ * @param name - The name of the header. This value is case-insensitive.
1250
+ */
1251
+ get(name) {
1252
+ var _a;
1253
+ return (_a = this._headersMap.get(normalizeName(name))) === null || _a === void 0 ? void 0 : _a.value;
1254
+ }
1255
+ /**
1256
+ * Get whether or not this header collection contains a header entry for the provided header name.
1257
+ * @param name - The name of the header to set. This value is case-insensitive.
1258
+ */
1259
+ has(name) {
1260
+ return this._headersMap.has(normalizeName(name));
1261
+ }
1262
+ /**
1263
+ * Remove the header with the provided headerName.
1264
+ * @param name - The name of the header to remove.
1265
+ */
1266
+ delete(name) {
1267
+ this._headersMap.delete(normalizeName(name));
1268
+ }
1269
+ /**
1270
+ * Get the JSON object representation of this HTTP header collection.
1271
+ */
1272
+ toJSON(options = {}) {
1273
+ const result = {};
1274
+ if (options.preserveCase) {
1275
+ for (const entry of this._headersMap.values()) {
1276
+ result[entry.name] = entry.value;
1277
+ }
1278
+ }
1279
+ else {
1280
+ for (const [normalizedName, entry] of this._headersMap) {
1281
+ result[normalizedName] = entry.value;
1282
+ }
1283
+ }
1284
+ return result;
1285
+ }
1286
+ /**
1287
+ * Get the string representation of this HTTP header collection.
1288
+ */
1289
+ toString() {
1290
+ return JSON.stringify(this.toJSON({ preserveCase: true }));
1291
+ }
1292
+ /**
1293
+ * Iterate over tuples of header [name, value] pairs.
1294
+ */
1295
+ [Symbol.iterator]() {
1296
+ return headerIterator(this._headersMap);
1297
+ }
1298
+ }
1299
+ /**
1300
+ * Creates an object that satisfies the `HttpHeaders` interface.
1301
+ * @param rawHeaders - A simple object representing initial headers
1302
+ */
1303
+ function createHttpHeaders(rawHeaders) {
1304
+ return new HttpHeadersImpl(rawHeaders);
1305
+ }
1306
+
1197
1307
  // Copyright (c) Microsoft Corporation.
1198
1308
  // Licensed under the MIT license.
1199
1309
  /**
@@ -1211,11 +1321,11 @@ function formDataPolicy() {
1211
1321
  const contentType = request.headers.get("Content-Type");
1212
1322
  if (contentType && contentType.indexOf("application/x-www-form-urlencoded") !== -1) {
1213
1323
  request.body = wwwFormUrlEncode(request.formData);
1214
- request.formData = undefined;
1215
1324
  }
1216
1325
  else {
1217
1326
  await prepareFormData(request.formData, request);
1218
1327
  }
1328
+ request.formData = undefined;
1219
1329
  }
1220
1330
  return next(request);
1221
1331
  },
@@ -1236,39 +1346,40 @@ function wwwFormUrlEncode(formData) {
1236
1346
  return urlSearchParams.toString();
1237
1347
  }
1238
1348
  async function prepareFormData(formData, request) {
1239
- const requestForm = new FormData();
1240
- for (const formKey of Object.keys(formData)) {
1241
- const formValue = formData[formKey];
1242
- if (Array.isArray(formValue)) {
1243
- for (const subValue of formValue) {
1244
- requestForm.append(formKey, subValue);
1245
- }
1246
- }
1247
- else {
1248
- requestForm.append(formKey, formValue);
1249
- }
1250
- }
1251
- request.body = requestForm;
1252
- request.formData = undefined;
1349
+ // validate content type (multipart/form-data)
1253
1350
  const contentType = request.headers.get("Content-Type");
1254
- if (contentType && contentType.indexOf("multipart/form-data") !== -1) {
1255
- request.headers.set("Content-Type", `multipart/form-data; boundary=${requestForm.getBoundary()}`);
1351
+ if (contentType && !contentType.startsWith("multipart/form-data")) {
1352
+ // content type is specified and is not multipart/form-data. Exit.
1353
+ return;
1256
1354
  }
1257
- try {
1258
- const contentLength = await new Promise((resolve, reject) => {
1259
- requestForm.getLength((err, length) => {
1260
- if (err) {
1261
- reject(err);
1262
- }
1263
- else {
1264
- resolve(length);
1355
+ request.headers.set("Content-Type", contentType !== null && contentType !== void 0 ? contentType : "multipart/form-data");
1356
+ // set body to MultipartRequestBody using content from FormDataMap
1357
+ const parts = [];
1358
+ for (const [fieldName, values] of Object.entries(formData)) {
1359
+ for (const value of Array.isArray(values) ? values : [values]) {
1360
+ if (typeof value === "string") {
1361
+ parts.push({
1362
+ headers: createHttpHeaders({
1363
+ "Content-Disposition": `form-data; name="${fieldName}"`,
1364
+ }),
1365
+ body: stringToUint8Array(value, "utf-8"),
1366
+ });
1367
+ }
1368
+ else {
1369
+ // using || instead of ?? here since if value.name is empty we should create a file name
1370
+ const fileName = value.name || "blob";
1371
+ const headers = createHttpHeaders();
1372
+ headers.set("Content-Disposition", `form-data; name="${fieldName}"; filename="${fileName}"`);
1373
+ if (value.type) {
1374
+ headers.set("Content-Type", value.type);
1265
1375
  }
1266
- });
1267
- });
1268
- request.headers.set("Content-Length", contentLength);
1269
- }
1270
- catch (e) {
1271
- // ignore setting the length if this fails
1376
+ parts.push({
1377
+ headers,
1378
+ body: value,
1379
+ });
1380
+ }
1381
+ }
1382
+ request.multipartBody = { parts };
1272
1383
  }
1273
1384
  }
1274
1385
 
@@ -1903,124 +2014,328 @@ function tryProcessResponse(span, response) {
1903
2014
  // Copyright (c) Microsoft Corporation.
1904
2015
  // Licensed under the MIT license.
1905
2016
  /**
1906
- * Create a new pipeline with a default set of customizable policies.
1907
- * @param options - Options to configure a custom pipeline.
2017
+ * Helper TypeGuard that checks if something is defined or not.
2018
+ * @param thing - Anything
1908
2019
  */
1909
- function createPipelineFromOptions(options) {
1910
- const pipeline = createEmptyPipeline();
1911
- if (isNode) {
1912
- if (options.tlsOptions) {
1913
- pipeline.addPolicy(tlsPolicy(options.tlsOptions));
1914
- }
1915
- pipeline.addPolicy(proxyPolicy(options.proxyOptions));
1916
- pipeline.addPolicy(decompressResponsePolicy());
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;
1917
2031
  }
1918
- pipeline.addPolicy(formDataPolicy());
1919
- pipeline.addPolicy(userAgentPolicy(options.userAgentOptions));
1920
- pipeline.addPolicy(defaultRetryPolicy(options.retryOptions), { phase: "Retry" });
1921
- pipeline.addPolicy(tracingPolicy(options.userAgentOptions), { afterPhase: "Retry" });
1922
- if (isNode) {
1923
- // Both XHR and Fetch expect to handle redirects automatically,
1924
- // so only include this policy when we're in Node.
1925
- pipeline.addPolicy(redirectPolicy(options.redirectOptions), { afterPhase: "Retry" });
2032
+ for (const property of properties) {
2033
+ if (!objectHasProperty(thing, property)) {
2034
+ return false;
2035
+ }
1926
2036
  }
1927
- pipeline.addPolicy(logPolicy(options.loggingOptions), { afterPhase: "Sign" });
1928
- return pipeline;
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";
1929
2060
  }
1930
2061
 
1931
2062
  // Copyright (c) Microsoft Corporation.
1932
2063
  // Licensed under the MIT license.
1933
- function normalizeName(name) {
1934
- return name.toLowerCase();
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
+ });
1935
2080
  }
1936
- function* headerIterator(map) {
1937
- for (const entry of map.values()) {
1938
- yield [entry.name, entry.value];
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);
1939
2087
  }
1940
2088
  }
1941
- class HttpHeadersImpl {
1942
- constructor(rawHeaders) {
1943
- this._headersMap = new Map();
1944
- if (rawHeaders) {
1945
- for (const headerName of Object.keys(rawHeaders)) {
1946
- this.set(headerName, rawHeaders[headerName]);
1947
- }
1948
- }
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));
1949
2101
  }
1950
- /**
1951
- * Set a header in this collection with the provided name and value. The name is
1952
- * case-insensitive.
1953
- * @param name - The name of the header to set. This value is case-insensitive.
1954
- * @param value - The value of the header to set.
1955
- */
1956
- set(name, value) {
1957
- this._headersMap.set(normalizeName(name), { name, value: String(value).trim() });
2102
+ else if (isBlob(source)) {
2103
+ return nodeStreamFromWebStream(source.stream());
1958
2104
  }
1959
- /**
1960
- * Get the header value for the provided header name, or undefined if no header exists in this
1961
- * collection with the provided name.
1962
- * @param name - The name of the header. This value is case-insensitive.
1963
- */
1964
- get(name) {
1965
- var _a;
1966
- return (_a = this._headersMap.get(normalizeName(name))) === null || _a === void 0 ? void 0 : _a.value;
2105
+ else if (isNodeReadableStream(source)) {
2106
+ return source;
1967
2107
  }
1968
- /**
1969
- * Get whether or not this header collection contains a header entry for the provided header name.
1970
- * @param name - The name of the header to set. This value is case-insensitive.
1971
- */
1972
- has(name) {
1973
- return this._headersMap.has(normalizeName(name));
2108
+ else {
2109
+ return nodeStreamFromWebStream(source);
1974
2110
  }
1975
- /**
1976
- * Remove the header with the provided headerName.
1977
- * @param name - The name of the header to remove.
1978
- */
1979
- delete(name) {
1980
- this._headersMap.delete(normalizeName(name));
2111
+ }
2112
+ function concatenateStreams(sources) {
2113
+ if (sources.some(isWebReadableStream)) {
2114
+ throw new Error("Was not expecting a Web stream here");
1981
2115
  }
1982
- /**
1983
- * Get the JSON object representation of this HTTP header collection.
1984
- */
1985
- toJSON(options = {}) {
1986
- const result = {};
1987
- if (options.preserveCase) {
1988
- for (const entry of this._headersMap.values()) {
1989
- result[entry.name] = entry.value;
1990
- }
1991
- }
1992
- else {
1993
- for (const [normalizedName, entry] of this._headersMap) {
1994
- result[normalizedName] = entry.value;
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
+ }
1995
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 += "-";
1996
2170
  }
1997
- return result;
1998
2171
  }
1999
- /**
2000
- * Get the string representation of this HTTP header collection.
2001
- */
2002
- toString() {
2003
- return JSON.stringify(this.toJSON({ preserveCase: true }));
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`;
2004
2204
  }
2005
- /**
2006
- * Iterate over tuples of header [name, value] pairs.
2007
- */
2008
- [Symbol.iterator]() {
2009
- return headerIterator(this._headersMap);
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;
2010
2217
  }
2011
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
+ }
2012
2250
  /**
2013
- * Creates an object that satisfies the `HttpHeaders` interface.
2014
- * @param rawHeaders - A simple object representing initial headers
2251
+ * Name of multipart policy
2015
2252
  */
2016
- function createHttpHeaders(rawHeaders) {
2017
- return new HttpHeadersImpl(rawHeaders);
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
+ // Copyright (c) Microsoft Corporation.
2304
+ // Licensed under the MIT license.
2305
+ /**
2306
+ * Create a new pipeline with a default set of customizable policies.
2307
+ * @param options - Options to configure a custom pipeline.
2308
+ */
2309
+ function createPipelineFromOptions(options) {
2310
+ const pipeline = createEmptyPipeline();
2311
+ if (isNode) {
2312
+ if (options.tlsOptions) {
2313
+ pipeline.addPolicy(tlsPolicy(options.tlsOptions));
2314
+ }
2315
+ pipeline.addPolicy(proxyPolicy(options.proxyOptions));
2316
+ pipeline.addPolicy(decompressResponsePolicy());
2317
+ }
2318
+ pipeline.addPolicy(formDataPolicy());
2319
+ pipeline.addPolicy(userAgentPolicy(options.userAgentOptions));
2320
+ // The multipart policy is added after policies with no phase, so that
2321
+ // policies can be added between it and formDataPolicy to modify
2322
+ // properties (e.g., making the boundary constant in recorded tests).
2323
+ pipeline.addPolicy(multipartPolicy(), { afterPhase: "Deserialize" });
2324
+ pipeline.addPolicy(defaultRetryPolicy(options.retryOptions), { phase: "Retry" });
2325
+ pipeline.addPolicy(tracingPolicy(options.userAgentOptions), { afterPhase: "Retry" });
2326
+ if (isNode) {
2327
+ // Both XHR and Fetch expect to handle redirects automatically,
2328
+ // so only include this policy when we're in Node.
2329
+ pipeline.addPolicy(redirectPolicy(options.redirectOptions), { afterPhase: "Retry" });
2330
+ }
2331
+ pipeline.addPolicy(logPolicy(options.loggingOptions), { afterPhase: "Sign" });
2332
+ return pipeline;
2018
2333
  }
2019
2334
 
2020
2335
  // Copyright (c) Microsoft Corporation.
2021
2336
  // Licensed under the MIT license.
2022
2337
  const DEFAULT_TLS_SETTINGS = {};
2023
- function isReadableStream$1(body) {
2338
+ function isReadableStream(body) {
2024
2339
  return body && typeof body.pipe === "function";
2025
2340
  }
2026
2341
  function isStreamComplete(stream) {
@@ -2101,7 +2416,7 @@ class NodeHttpClient {
2101
2416
  uploadReportStream.on("error", (e) => {
2102
2417
  logger.error("Error in upload progress", e);
2103
2418
  });
2104
- if (isReadableStream$1(body)) {
2419
+ if (isReadableStream(body)) {
2105
2420
  body.pipe(uploadReportStream);
2106
2421
  }
2107
2422
  else {
@@ -2150,11 +2465,11 @@ class NodeHttpClient {
2150
2465
  // clean up event listener
2151
2466
  if (request.abortSignal && abortListener) {
2152
2467
  let uploadStreamDone = Promise.resolve();
2153
- if (isReadableStream$1(body)) {
2468
+ if (isReadableStream(body)) {
2154
2469
  uploadStreamDone = isStreamComplete(body);
2155
2470
  }
2156
2471
  let downloadStreamDone = Promise.resolve();
2157
- if (isReadableStream$1(responseStream)) {
2472
+ if (isReadableStream(responseStream)) {
2158
2473
  downloadStreamDone = isStreamComplete(responseStream);
2159
2474
  }
2160
2475
  Promise.all([uploadStreamDone, downloadStreamDone])
@@ -2198,7 +2513,7 @@ class NodeHttpClient {
2198
2513
  req.destroy(abortError);
2199
2514
  reject(abortError);
2200
2515
  });
2201
- if (body && isReadableStream$1(body)) {
2516
+ if (body && isReadableStream(body)) {
2202
2517
  body.pipe(req);
2203
2518
  }
2204
2519
  else if (body) {
@@ -2320,7 +2635,7 @@ function getBodyLength(body) {
2320
2635
  else if (Buffer.isBuffer(body)) {
2321
2636
  return body.length;
2322
2637
  }
2323
- else if (isReadableStream$1(body)) {
2638
+ else if (isReadableStream(body)) {
2324
2639
  return null;
2325
2640
  }
2326
2641
  else if (isArrayBuffer(body)) {
@@ -2350,61 +2665,6 @@ function createDefaultHttpClient() {
2350
2665
  return createNodeHttpClient();
2351
2666
  }
2352
2667
 
2353
- // Copyright (c) Microsoft Corporation.
2354
- // Licensed under the MIT license.
2355
- /*
2356
- * NOTE: When moving this file, please update "react-native" section in package.json.
2357
- */
2358
- /**
2359
- * Generated Universally Unique Identifier
2360
- *
2361
- * @returns RFC4122 v4 UUID.
2362
- */
2363
- function generateUUID() {
2364
- let uuid = "";
2365
- for (let i = 0; i < 32; i++) {
2366
- // Generate a random number between 0 and 15
2367
- const randomNumber = Math.floor(Math.random() * 16);
2368
- // Set the UUID version to 4 in the 13th position
2369
- if (i === 12) {
2370
- uuid += "4";
2371
- }
2372
- else if (i === 16) {
2373
- // Set the UUID variant to "10" in the 17th position
2374
- uuid += (randomNumber & 0x3) | 0x8;
2375
- }
2376
- else {
2377
- // Add a random hexadecimal digit to the UUID string
2378
- uuid += randomNumber.toString(16);
2379
- }
2380
- // Add hyphens to the UUID string at the appropriate positions
2381
- if (i === 7 || i === 11 || i === 15 || i === 19) {
2382
- uuid += "-";
2383
- }
2384
- }
2385
- return uuid;
2386
- }
2387
-
2388
- // Copyright (c) Microsoft Corporation.
2389
- // Licensed under the MIT license.
2390
- var _a;
2391
- // NOTE: This is a workaround until we can use `globalThis.crypto.randomUUID` in Node.js 19+.
2392
- let uuidFunction = typeof ((_a = globalThis === null || globalThis === void 0 ? void 0 : globalThis.crypto) === null || _a === void 0 ? void 0 : _a.randomUUID) === "function"
2393
- ? globalThis.crypto.randomUUID.bind(globalThis.crypto)
2394
- : crypto.randomUUID;
2395
- // Not defined in earlier versions of Node.js 14
2396
- if (!uuidFunction) {
2397
- uuidFunction = generateUUID;
2398
- }
2399
- /**
2400
- * Generated Universally Unique Identifier
2401
- *
2402
- * @returns RFC4122 v4 UUID.
2403
- */
2404
- function randomUUID() {
2405
- return uuidFunction();
2406
- }
2407
-
2408
2668
  // Copyright (c) Microsoft Corporation.
2409
2669
  // Licensed under the MIT license.
2410
2670
  class PipelineRequestImpl {
@@ -2415,6 +2675,7 @@ class PipelineRequestImpl {
2415
2675
  this.headers = (_a = options.headers) !== null && _a !== void 0 ? _a : createHttpHeaders();
2416
2676
  this.method = (_b = options.method) !== null && _b !== void 0 ? _b : "GET";
2417
2677
  this.timeout = (_c = options.timeout) !== null && _c !== void 0 ? _c : 0;
2678
+ this.multipartBody = options.multipartBody;
2418
2679
  this.formData = options.formData;
2419
2680
  this.disableKeepAlive = (_d = options.disableKeepAlive) !== null && _d !== void 0 ? _d : false;
2420
2681
  this.proxySettings = options.proxySettings;
@@ -2775,6 +3036,56 @@ async function cancelablePromiseRace(abortablePromiseBuilders, options) {
2775
3036
  }
2776
3037
  }
2777
3038
 
3039
+ // Copyright (c) Microsoft Corporation.
3040
+ // Licensed under the MIT license.
3041
+ const unimplementedMethods = {
3042
+ arrayBuffer: () => {
3043
+ throw new Error("Not implemented");
3044
+ },
3045
+ slice: () => {
3046
+ throw new Error("Not implemented");
3047
+ },
3048
+ text: () => {
3049
+ throw new Error("Not implemented");
3050
+ },
3051
+ };
3052
+ /**
3053
+ * Create an object that implements the File interface. This object is intended to be
3054
+ * passed into RequestBodyType.formData, and is not guaranteed to work as expected in
3055
+ * other situations.
3056
+ *
3057
+ * Use this function to:
3058
+ * - Create a File object for use in RequestBodyType.formData in environments where the
3059
+ * global File object is unavailable.
3060
+ * - Create a File-like object from a readable stream without reading the stream into memory.
3061
+ *
3062
+ * @param stream - the content of the file as a callback returning a stream. When a File object made using createFile is
3063
+ * passed in a request's form data map, the stream will not be read into memory
3064
+ * and instead will be streamed when the request is made. In the event of a retry, the
3065
+ * stream needs to be read again, so this callback SHOULD return a fresh stream if possible.
3066
+ * @param name - the name of the file.
3067
+ * @param options - optional metadata about the file, e.g. file name, file size, MIME type.
3068
+ */
3069
+ function createFileFromStream(stream, name, options = {}) {
3070
+ var _a, _b, _c, _d;
3071
+ return Object.assign(Object.assign({}, unimplementedMethods), { type: (_a = options.type) !== null && _a !== void 0 ? _a : "", lastModified: (_b = options.lastModified) !== null && _b !== void 0 ? _b : new Date().getTime(), webkitRelativePath: (_c = options.webkitRelativePath) !== null && _c !== void 0 ? _c : "", size: (_d = options.size) !== null && _d !== void 0 ? _d : -1, name, stream: () => toWebStream(stream()) });
3072
+ }
3073
+ /**
3074
+ * Create an object that implements the File interface. This object is intended to be
3075
+ * passed into RequestBodyType.formData, and is not guaranteed to work as expected in
3076
+ * other situations.
3077
+ *
3078
+ * Use this function create a File object for use in RequestBodyType.formData in environments where the global File object is unavailable.
3079
+ *
3080
+ * @param content - the content of the file as a Uint8Array in memory.
3081
+ * @param name - the name of the file.
3082
+ * @param options - optional metadata about the file, e.g. file name, file size, MIME type.
3083
+ */
3084
+ function createFile(content, name, options = {}) {
3085
+ var _a, _b, _c;
3086
+ return Object.assign(Object.assign({}, unimplementedMethods), { type: (_a = options.type) !== null && _a !== void 0 ? _a : "", lastModified: (_b = options.lastModified) !== null && _b !== void 0 ? _b : new Date().getTime(), webkitRelativePath: (_c = options.webkitRelativePath) !== null && _c !== void 0 ? _c : "", size: content.byteLength, name, arrayBuffer: async () => content.buffer, stream: () => new Blob([content]).stream() });
3087
+ }
3088
+
2778
3089
  // Copyright (c) Microsoft Corporation.
2779
3090
  // Licensed under the MIT license.
2780
3091
  /**
@@ -2796,61 +3107,6 @@ async function computeSha256Hash(content, encoding) {
2796
3107
  return crypto.createHash("sha256").update(content).digest(encoding);
2797
3108
  }
2798
3109
 
2799
- // Copyright (c) Microsoft Corporation.
2800
- // Licensed under the MIT license.
2801
- /**
2802
- * Helper TypeGuard that checks if something is defined or not.
2803
- * @param thing - Anything
2804
- */
2805
- function isDefined(thing) {
2806
- return typeof thing !== "undefined" && thing !== null;
2807
- }
2808
- /**
2809
- * Helper TypeGuard that checks if the input is an object with the specified properties.
2810
- * @param thing - Anything.
2811
- * @param properties - The name of the properties that should appear in the object.
2812
- */
2813
- function isObjectWithProperties(thing, properties) {
2814
- if (!isDefined(thing) || typeof thing !== "object") {
2815
- return false;
2816
- }
2817
- for (const property of properties) {
2818
- if (!objectHasProperty(thing, property)) {
2819
- return false;
2820
- }
2821
- }
2822
- return true;
2823
- }
2824
- /**
2825
- * Helper TypeGuard that checks if the input is an object with the specified property.
2826
- * @param thing - Any object.
2827
- * @param property - The name of the property that should appear in the object.
2828
- */
2829
- function objectHasProperty(thing, property) {
2830
- return (isDefined(thing) && typeof thing === "object" && property in thing);
2831
- }
2832
-
2833
- // Copyright (c) Microsoft Corporation.
2834
- // Licensed under the MIT license.
2835
- /**
2836
- * The helper that transforms bytes with specific character encoding into string
2837
- * @param bytes - the uint8array bytes
2838
- * @param format - the format we use to encode the byte
2839
- * @returns a string of the encoded string
2840
- */
2841
- function uint8ArrayToString(bytes, format) {
2842
- return Buffer.from(bytes).toString(format);
2843
- }
2844
- /**
2845
- * The helper that transforms string to specific character encoded bytes array.
2846
- * @param value - the string to be converted
2847
- * @param format - the format we use to decode the value
2848
- * @returns a uint8array
2849
- */
2850
- function stringToUint8Array(value, format) {
2851
- return Buffer.from(value, format);
2852
- }
2853
-
2854
3110
  // Copyright (c) Microsoft Corporation.
2855
3111
  // Licensed under the MIT license.
2856
3112
  /**
@@ -3002,16 +3258,6 @@ function operationOptionsToRequestParameters(options) {
3002
3258
  };
3003
3259
  }
3004
3260
 
3005
- // Copyright (c) Microsoft Corporation.
3006
- // Licensed under the MIT license.
3007
- /**
3008
- * Checks if the body is a ReadableStream supported by Node
3009
- * @internal
3010
- */
3011
- function isReadableStream(body) {
3012
- return Boolean(body) && typeof body.pipe === "function";
3013
- }
3014
-
3015
3261
  // Copyright (c) Microsoft Corporation.
3016
3262
  // Licensed under the MIT license.
3017
3263
  /**
@@ -3120,7 +3366,7 @@ function getRequestBody(body, contentType = "") {
3120
3366
  if (body === undefined) {
3121
3367
  return { body: undefined };
3122
3368
  }
3123
- if (isReadableStream(body)) {
3369
+ if (isReadableStream$1(body)) {
3124
3370
  return { body };
3125
3371
  }
3126
3372
  if (!contentType && typeof body === "string") {
@@ -3408,6 +3654,8 @@ exports.computeSha256Hmac = computeSha256Hmac;
3408
3654
  exports.createAbortablePromise = createAbortablePromise;
3409
3655
  exports.createDefaultHttpClient = createDefaultHttpClient;
3410
3656
  exports.createEmptyPipeline = createEmptyPipeline;
3657
+ exports.createFile = createFile;
3658
+ exports.createFileFromStream = createFileFromStream;
3411
3659
  exports.createHttpHeaders = createHttpHeaders;
3412
3660
  exports.createPipelineFromOptions = createPipelineFromOptions;
3413
3661
  exports.createPipelineRequest = createPipelineRequest;
@@ -3436,6 +3684,8 @@ exports.isRestError = isRestError;
3436
3684
  exports.isWebWorker = isWebWorker;
3437
3685
  exports.logPolicy = logPolicy;
3438
3686
  exports.logPolicyName = logPolicyName;
3687
+ exports.multipartPolicy = multipartPolicy;
3688
+ exports.multipartPolicyName = multipartPolicyName;
3439
3689
  exports.objectHasProperty = objectHasProperty;
3440
3690
  exports.operationOptionsToRequestParameters = operationOptionsToRequestParameters;
3441
3691
  exports.proxyPolicy = proxyPolicy;