@typespec/ts-http-runtime 1.0.0-alpha.20231023.3

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 (181) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +159 -0
  3. package/dist/index.js +3509 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist-esm/src/abort-controller/AbortError.js +27 -0
  6. package/dist-esm/src/abort-controller/AbortError.js.map +1 -0
  7. package/dist-esm/src/abort-controller/AbortSignalLike.js +4 -0
  8. package/dist-esm/src/abort-controller/AbortSignalLike.js.map +1 -0
  9. package/dist-esm/src/accessTokenCache.js +32 -0
  10. package/dist-esm/src/accessTokenCache.js.map +1 -0
  11. package/dist-esm/src/auth/keyCredential.js +4 -0
  12. package/dist-esm/src/auth/keyCredential.js.map +1 -0
  13. package/dist-esm/src/auth/tokenCredential.js +19 -0
  14. package/dist-esm/src/auth/tokenCredential.js.map +1 -0
  15. package/dist-esm/src/client/apiVersionPolicy.js +23 -0
  16. package/dist-esm/src/client/apiVersionPolicy.js.map +1 -0
  17. package/dist-esm/src/client/clientHelpers.js +52 -0
  18. package/dist-esm/src/client/clientHelpers.js.map +1 -0
  19. package/dist-esm/src/client/common.js +4 -0
  20. package/dist-esm/src/client/common.js.map +1 -0
  21. package/dist-esm/src/client/getClient.js +86 -0
  22. package/dist-esm/src/client/getClient.js.map +1 -0
  23. package/dist-esm/src/client/helpers/getBinaryBody.js +13 -0
  24. package/dist-esm/src/client/helpers/getBinaryBody.js.map +1 -0
  25. package/dist-esm/src/client/helpers/isReadableStream.browser.js +12 -0
  26. package/dist-esm/src/client/helpers/isReadableStream.browser.js.map +1 -0
  27. package/dist-esm/src/client/helpers/isReadableStream.js +10 -0
  28. package/dist-esm/src/client/helpers/isReadableStream.js.map +1 -0
  29. package/dist-esm/src/client/keyCredentialAuthenticationPolicy.js +16 -0
  30. package/dist-esm/src/client/keyCredentialAuthenticationPolicy.js.map +1 -0
  31. package/dist-esm/src/client/operationOptionHelpers.js +22 -0
  32. package/dist-esm/src/client/operationOptionHelpers.js.map +1 -0
  33. package/dist-esm/src/client/restError.js +27 -0
  34. package/dist-esm/src/client/restError.js.map +1 -0
  35. package/dist-esm/src/client/sendRequest.js +195 -0
  36. package/dist-esm/src/client/sendRequest.js.map +1 -0
  37. package/dist-esm/src/client/urlHelpers.js +100 -0
  38. package/dist-esm/src/client/urlHelpers.js.map +1 -0
  39. package/dist-esm/src/constants.js +5 -0
  40. package/dist-esm/src/constants.js.map +1 -0
  41. package/dist-esm/src/createPipelineFromOptions.js +39 -0
  42. package/dist-esm/src/createPipelineFromOptions.js.map +1 -0
  43. package/dist-esm/src/defaultHttpClient.browser.js +10 -0
  44. package/dist-esm/src/defaultHttpClient.browser.js.map +1 -0
  45. package/dist-esm/src/defaultHttpClient.js +10 -0
  46. package/dist-esm/src/defaultHttpClient.js.map +1 -0
  47. package/dist-esm/src/defaultHttpClient.native.js +10 -0
  48. package/dist-esm/src/defaultHttpClient.native.js.map +1 -0
  49. package/dist-esm/src/fetchHttpClient.js +268 -0
  50. package/dist-esm/src/fetchHttpClient.js.map +1 -0
  51. package/dist-esm/src/httpHeaders.js +89 -0
  52. package/dist-esm/src/httpHeaders.js.map +1 -0
  53. package/dist-esm/src/index.js +41 -0
  54. package/dist-esm/src/index.js.map +1 -0
  55. package/dist-esm/src/interfaces.js +4 -0
  56. package/dist-esm/src/interfaces.js.map +1 -0
  57. package/dist-esm/src/log.js +5 -0
  58. package/dist-esm/src/log.js.map +1 -0
  59. package/dist-esm/src/logger/debug.js +93 -0
  60. package/dist-esm/src/logger/debug.js.map +1 -0
  61. package/dist-esm/src/logger/log.browser.js +23 -0
  62. package/dist-esm/src/logger/log.browser.js.map +1 -0
  63. package/dist-esm/src/logger/log.js +8 -0
  64. package/dist-esm/src/logger/log.js.map +1 -0
  65. package/dist-esm/src/logger/logger.js +99 -0
  66. package/dist-esm/src/logger/logger.js.map +1 -0
  67. package/dist-esm/src/nodeHttpClient.js +332 -0
  68. package/dist-esm/src/nodeHttpClient.js.map +1 -0
  69. package/dist-esm/src/pipeline.js +262 -0
  70. package/dist-esm/src/pipeline.js.map +1 -0
  71. package/dist-esm/src/pipelineRequest.js +35 -0
  72. package/dist-esm/src/pipelineRequest.js.map +1 -0
  73. package/dist-esm/src/policies/bearerTokenAuthenticationPolicy.js +108 -0
  74. package/dist-esm/src/policies/bearerTokenAuthenticationPolicy.js.map +1 -0
  75. package/dist-esm/src/policies/decompressResponsePolicy.browser.js +14 -0
  76. package/dist-esm/src/policies/decompressResponsePolicy.browser.js.map +1 -0
  77. package/dist-esm/src/policies/decompressResponsePolicy.js +23 -0
  78. package/dist-esm/src/policies/decompressResponsePolicy.js.map +1 -0
  79. package/dist-esm/src/policies/defaultRetryPolicy.js +26 -0
  80. package/dist-esm/src/policies/defaultRetryPolicy.js.map +1 -0
  81. package/dist-esm/src/policies/exponentialRetryPolicy.js +22 -0
  82. package/dist-esm/src/policies/exponentialRetryPolicy.js.map +1 -0
  83. package/dist-esm/src/policies/formDataPolicy.browser.js +43 -0
  84. package/dist-esm/src/policies/formDataPolicy.browser.js.map +1 -0
  85. package/dist-esm/src/policies/formDataPolicy.js +79 -0
  86. package/dist-esm/src/policies/formDataPolicy.js.map +1 -0
  87. package/dist-esm/src/policies/logPolicy.js +34 -0
  88. package/dist-esm/src/policies/logPolicy.js.map +1 -0
  89. package/dist-esm/src/policies/proxyPolicy.browser.js +27 -0
  90. package/dist-esm/src/policies/proxyPolicy.browser.js.map +1 -0
  91. package/dist-esm/src/policies/proxyPolicy.js +190 -0
  92. package/dist-esm/src/policies/proxyPolicy.js.map +1 -0
  93. package/dist-esm/src/policies/redirectPolicy.js +52 -0
  94. package/dist-esm/src/policies/redirectPolicy.js.map +1 -0
  95. package/dist-esm/src/policies/retryPolicy.js +106 -0
  96. package/dist-esm/src/policies/retryPolicy.js.map +1 -0
  97. package/dist-esm/src/policies/systemErrorRetryPolicy.js +27 -0
  98. package/dist-esm/src/policies/systemErrorRetryPolicy.js.map +1 -0
  99. package/dist-esm/src/policies/throttlingRetryPolicy.js +29 -0
  100. package/dist-esm/src/policies/throttlingRetryPolicy.js.map +1 -0
  101. package/dist-esm/src/policies/tlsPolicy.js +22 -0
  102. package/dist-esm/src/policies/tlsPolicy.js.map +1 -0
  103. package/dist-esm/src/policies/tracingPolicy.js +120 -0
  104. package/dist-esm/src/policies/tracingPolicy.js.map +1 -0
  105. package/dist-esm/src/policies/userAgentPolicy.js +26 -0
  106. package/dist-esm/src/policies/userAgentPolicy.js.map +1 -0
  107. package/dist-esm/src/restError.js +48 -0
  108. package/dist-esm/src/restError.js.map +1 -0
  109. package/dist-esm/src/retryStrategies/exponentialRetryStrategy.js +70 -0
  110. package/dist-esm/src/retryStrategies/exponentialRetryStrategy.js.map +1 -0
  111. package/dist-esm/src/retryStrategies/retryStrategy.js +4 -0
  112. package/dist-esm/src/retryStrategies/retryStrategy.js.map +1 -0
  113. package/dist-esm/src/retryStrategies/throttlingRetryStrategy.js +74 -0
  114. package/dist-esm/src/retryStrategies/throttlingRetryStrategy.js.map +1 -0
  115. package/dist-esm/src/tracing/instrumenter.js +61 -0
  116. package/dist-esm/src/tracing/instrumenter.js.map +1 -0
  117. package/dist-esm/src/tracing/interfaces.js +4 -0
  118. package/dist-esm/src/tracing/interfaces.js.map +1 -0
  119. package/dist-esm/src/tracing/tracingClient.js +74 -0
  120. package/dist-esm/src/tracing/tracingClient.js.map +1 -0
  121. package/dist-esm/src/tracing/tracingContext.js +47 -0
  122. package/dist-esm/src/tracing/tracingContext.js.map +1 -0
  123. package/dist-esm/src/util/aborterUtils.js +21 -0
  124. package/dist-esm/src/util/aborterUtils.js.map +1 -0
  125. package/dist-esm/src/util/base64.browser.js +35 -0
  126. package/dist-esm/src/util/base64.browser.js.map +1 -0
  127. package/dist-esm/src/util/bytesEncoding.browser.js +82 -0
  128. package/dist-esm/src/util/bytesEncoding.browser.js.map +1 -0
  129. package/dist-esm/src/util/bytesEncoding.js +77 -0
  130. package/dist-esm/src/util/bytesEncoding.js.map +1 -0
  131. package/dist-esm/src/util/checkEnvironment.js +36 -0
  132. package/dist-esm/src/util/checkEnvironment.js.map +1 -0
  133. package/dist-esm/src/util/createAbortablePromise.js +42 -0
  134. package/dist-esm/src/util/createAbortablePromise.js.map +1 -0
  135. package/dist-esm/src/util/delay.js +22 -0
  136. package/dist-esm/src/util/delay.js.map +1 -0
  137. package/dist-esm/src/util/error.js +42 -0
  138. package/dist-esm/src/util/error.js.map +1 -0
  139. package/dist-esm/src/util/helpers.js +58 -0
  140. package/dist-esm/src/util/helpers.js.map +1 -0
  141. package/dist-esm/src/util/hex.js +21 -0
  142. package/dist-esm/src/util/hex.js.map +1 -0
  143. package/dist-esm/src/util/inspect.browser.js +4 -0
  144. package/dist-esm/src/util/inspect.browser.js.map +1 -0
  145. package/dist-esm/src/util/inspect.js +5 -0
  146. package/dist-esm/src/util/inspect.js.map +1 -0
  147. package/dist-esm/src/util/object.js +14 -0
  148. package/dist-esm/src/util/object.js.map +1 -0
  149. package/dist-esm/src/util/random.js +21 -0
  150. package/dist-esm/src/util/random.js.map +1 -0
  151. package/dist-esm/src/util/sanitizer.js +139 -0
  152. package/dist-esm/src/util/sanitizer.js.map +1 -0
  153. package/dist-esm/src/util/sha256.browser.js +61 -0
  154. package/dist-esm/src/util/sha256.browser.js.map +1 -0
  155. package/dist-esm/src/util/sha256.js +22 -0
  156. package/dist-esm/src/util/sha256.js.map +1 -0
  157. package/dist-esm/src/util/tokenCycler.js +149 -0
  158. package/dist-esm/src/util/tokenCycler.js.map +1 -0
  159. package/dist-esm/src/util/typeGuards.js +34 -0
  160. package/dist-esm/src/util/typeGuards.js.map +1 -0
  161. package/dist-esm/src/util/userAgent.js +30 -0
  162. package/dist-esm/src/util/userAgent.js.map +1 -0
  163. package/dist-esm/src/util/userAgentPlatform.browser.js +20 -0
  164. package/dist-esm/src/util/userAgentPlatform.browser.js.map +1 -0
  165. package/dist-esm/src/util/userAgentPlatform.js +17 -0
  166. package/dist-esm/src/util/userAgentPlatform.js.map +1 -0
  167. package/dist-esm/src/util/userAgentPlatform.native.js +24 -0
  168. package/dist-esm/src/util/userAgentPlatform.native.js.map +1 -0
  169. package/dist-esm/src/util/utf8.browser.js +26 -0
  170. package/dist-esm/src/util/utf8.browser.js.map +1 -0
  171. package/dist-esm/src/util/uuidUtils.browser.js +17 -0
  172. package/dist-esm/src/util/uuidUtils.browser.js.map +1 -0
  173. package/dist-esm/src/util/uuidUtils.js +22 -0
  174. package/dist-esm/src/util/uuidUtils.js.map +1 -0
  175. package/dist-esm/src/util/uuidUtils.native.js +43 -0
  176. package/dist-esm/src/util/uuidUtils.native.js.map +1 -0
  177. package/dist-esm/src/xhrHttpClient.js +177 -0
  178. package/dist-esm/src/xhrHttpClient.js.map +1 -0
  179. package/package.json +134 -0
  180. package/ts-http-runtime.shims.d.ts +12 -0
  181. package/types/ts-http-runtime.d.ts +2062 -0
@@ -0,0 +1,43 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+ /**
4
+ * The programmatic identifier of the formDataPolicy.
5
+ */
6
+ export const formDataPolicyName = "formDataPolicy";
7
+ /**
8
+ * A policy that encodes FormData on the request into the body.
9
+ */
10
+ export function formDataPolicy() {
11
+ return {
12
+ name: formDataPolicyName,
13
+ async sendRequest(request, next) {
14
+ if (request.formData) {
15
+ const formData = request.formData;
16
+ const requestForm = new FormData();
17
+ for (const formKey of Object.keys(formData)) {
18
+ const formValue = formData[formKey];
19
+ if (Array.isArray(formValue)) {
20
+ for (const subValue of formValue) {
21
+ requestForm.append(formKey, subValue);
22
+ }
23
+ }
24
+ else {
25
+ requestForm.append(formKey, formValue);
26
+ }
27
+ }
28
+ request.body = requestForm;
29
+ request.formData = undefined;
30
+ const contentType = request.headers.get("Content-Type");
31
+ if (contentType && contentType.indexOf("application/x-www-form-urlencoded") !== -1) {
32
+ request.body = new URLSearchParams(requestForm).toString();
33
+ }
34
+ else if (contentType && contentType.indexOf("multipart/form-data") !== -1) {
35
+ // browser will automatically apply a suitable content-type header
36
+ request.headers.delete("Content-Type");
37
+ }
38
+ }
39
+ return next(request);
40
+ },
41
+ };
42
+ }
43
+ //# sourceMappingURL=formDataPolicy.browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formDataPolicy.browser.js","sourceRoot":"","sources":["../../../src/policies/formDataPolicy.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAEnD;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,KAAK,CAAC,WAAW,CAAC,OAAwB,EAAE,IAAiB;YAC3D,IAAI,OAAO,CAAC,QAAQ,EAAE;gBACpB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;gBAClC,MAAM,WAAW,GAAG,IAAI,QAAQ,EAAE,CAAC;gBACnC,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE;oBAC3C,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;oBACpC,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;wBAC5B,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE;4BAChC,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;yBACvC;qBACF;yBAAM;wBACL,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;qBACxC;iBACF;gBAED,OAAO,CAAC,IAAI,GAAG,WAAW,CAAC;gBAC3B,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;gBAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBACxD,IAAI,WAAW,IAAI,WAAW,CAAC,OAAO,CAAC,mCAAmC,CAAC,KAAK,CAAC,CAAC,EAAE;oBAClF,OAAO,CAAC,IAAI,GAAG,IAAI,eAAe,CAAC,WAAkB,CAAC,CAAC,QAAQ,EAAE,CAAC;iBACnE;qBAAM,IAAI,WAAW,IAAI,WAAW,CAAC,OAAO,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,EAAE;oBAC3E,kEAAkE;oBAClE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;iBACxC;aACF;YACD,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;QACvB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { PipelineRequest, PipelineResponse, SendRequest } from \"../interfaces\";\nimport { PipelinePolicy } from \"../pipeline\";\n\n/**\n * The programmatic identifier of the formDataPolicy.\n */\nexport const formDataPolicyName = \"formDataPolicy\";\n\n/**\n * A policy that encodes FormData on the request into the body.\n */\nexport function formDataPolicy(): PipelinePolicy {\n return {\n name: formDataPolicyName,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n if (request.formData) {\n const formData = request.formData;\n const requestForm = new FormData();\n for (const formKey of Object.keys(formData)) {\n const formValue = formData[formKey];\n if (Array.isArray(formValue)) {\n for (const subValue of formValue) {\n requestForm.append(formKey, subValue);\n }\n } else {\n requestForm.append(formKey, formValue);\n }\n }\n\n request.body = requestForm;\n request.formData = undefined;\n const contentType = request.headers.get(\"Content-Type\");\n if (contentType && contentType.indexOf(\"application/x-www-form-urlencoded\") !== -1) {\n request.body = new URLSearchParams(requestForm as any).toString();\n } else if (contentType && contentType.indexOf(\"multipart/form-data\") !== -1) {\n // browser will automatically apply a suitable content-type header\n request.headers.delete(\"Content-Type\");\n }\n }\n return next(request);\n },\n };\n}\n"]}
@@ -0,0 +1,79 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+ import FormData from "form-data";
4
+ /**
5
+ * The programmatic identifier of the formDataPolicy.
6
+ */
7
+ export const formDataPolicyName = "formDataPolicy";
8
+ /**
9
+ * A policy that encodes FormData on the request into the body.
10
+ */
11
+ export function formDataPolicy() {
12
+ return {
13
+ name: formDataPolicyName,
14
+ async sendRequest(request, next) {
15
+ if (request.formData) {
16
+ const contentType = request.headers.get("Content-Type");
17
+ if (contentType && contentType.indexOf("application/x-www-form-urlencoded") !== -1) {
18
+ request.body = wwwFormUrlEncode(request.formData);
19
+ request.formData = undefined;
20
+ }
21
+ else {
22
+ await prepareFormData(request.formData, request);
23
+ }
24
+ }
25
+ return next(request);
26
+ },
27
+ };
28
+ }
29
+ function wwwFormUrlEncode(formData) {
30
+ const urlSearchParams = new URLSearchParams();
31
+ for (const [key, value] of Object.entries(formData)) {
32
+ if (Array.isArray(value)) {
33
+ for (const subValue of value) {
34
+ urlSearchParams.append(key, subValue.toString());
35
+ }
36
+ }
37
+ else {
38
+ urlSearchParams.append(key, value.toString());
39
+ }
40
+ }
41
+ return urlSearchParams.toString();
42
+ }
43
+ async function prepareFormData(formData, request) {
44
+ const requestForm = new FormData();
45
+ for (const formKey of Object.keys(formData)) {
46
+ const formValue = formData[formKey];
47
+ if (Array.isArray(formValue)) {
48
+ for (const subValue of formValue) {
49
+ requestForm.append(formKey, subValue);
50
+ }
51
+ }
52
+ else {
53
+ requestForm.append(formKey, formValue);
54
+ }
55
+ }
56
+ request.body = requestForm;
57
+ request.formData = undefined;
58
+ const contentType = request.headers.get("Content-Type");
59
+ if (contentType && contentType.indexOf("multipart/form-data") !== -1) {
60
+ request.headers.set("Content-Type", `multipart/form-data; boundary=${requestForm.getBoundary()}`);
61
+ }
62
+ try {
63
+ const contentLength = await new Promise((resolve, reject) => {
64
+ requestForm.getLength((err, length) => {
65
+ if (err) {
66
+ reject(err);
67
+ }
68
+ else {
69
+ resolve(length);
70
+ }
71
+ });
72
+ });
73
+ request.headers.set("Content-Length", contentLength);
74
+ }
75
+ catch (e) {
76
+ // ignore setting the length if this fails
77
+ }
78
+ }
79
+ //# sourceMappingURL=formDataPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formDataPolicy.js","sourceRoot":"","sources":["../../../src/policies/formDataPolicy.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport FormData from \"form-data\";\nimport { FormDataMap, PipelineRequest, PipelineResponse, SendRequest } from \"../interfaces\";\nimport { PipelinePolicy } from \"../pipeline\";\n\n/**\n * The programmatic identifier of the formDataPolicy.\n */\nexport const formDataPolicyName = \"formDataPolicy\";\n\n/**\n * A policy that encodes FormData on the request into the body.\n */\nexport function formDataPolicy(): PipelinePolicy {\n return {\n name: formDataPolicyName,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n if (request.formData) {\n const contentType = request.headers.get(\"Content-Type\");\n if (contentType && contentType.indexOf(\"application/x-www-form-urlencoded\") !== -1) {\n request.body = wwwFormUrlEncode(request.formData);\n request.formData = undefined;\n } else {\n await prepareFormData(request.formData, request);\n }\n }\n return next(request);\n },\n };\n}\n\nfunction wwwFormUrlEncode(formData: FormDataMap): string {\n const urlSearchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(formData)) {\n if (Array.isArray(value)) {\n for (const subValue of value) {\n urlSearchParams.append(key, subValue.toString());\n }\n } else {\n urlSearchParams.append(key, value.toString());\n }\n }\n return urlSearchParams.toString();\n}\n\nasync function prepareFormData(formData: FormDataMap, request: PipelineRequest): Promise<void> {\n const requestForm = new FormData();\n for (const formKey of Object.keys(formData)) {\n const formValue = formData[formKey];\n if (Array.isArray(formValue)) {\n for (const subValue of formValue) {\n requestForm.append(formKey, subValue);\n }\n } else {\n requestForm.append(formKey, formValue);\n }\n }\n\n request.body = requestForm;\n request.formData = undefined;\n const contentType = request.headers.get(\"Content-Type\");\n if (contentType && contentType.indexOf(\"multipart/form-data\") !== -1) {\n request.headers.set(\n \"Content-Type\",\n `multipart/form-data; boundary=${requestForm.getBoundary()}`\n );\n }\n try {\n const contentLength = await new Promise<number>((resolve, reject) => {\n requestForm.getLength((err, length) => {\n if (err) {\n reject(err);\n } else {\n resolve(length);\n }\n });\n });\n request.headers.set(\"Content-Length\", contentLength);\n } catch (e: any) {\n // ignore setting the length if this fails\n }\n}\n"]}
@@ -0,0 +1,34 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+ import { logger as coreLogger } from "../log";
4
+ import { Sanitizer } from "../util/sanitizer";
5
+ /**
6
+ * The programmatic identifier of the logPolicy.
7
+ */
8
+ export const logPolicyName = "logPolicy";
9
+ /**
10
+ * A policy that logs all requests and responses.
11
+ * @param options - Options to configure logPolicy.
12
+ */
13
+ export function logPolicy(options = {}) {
14
+ var _a;
15
+ const logger = (_a = options.logger) !== null && _a !== void 0 ? _a : coreLogger.info;
16
+ const sanitizer = new Sanitizer({
17
+ additionalAllowedHeaderNames: options.additionalAllowedHeaderNames,
18
+ additionalAllowedQueryParameters: options.additionalAllowedQueryParameters,
19
+ });
20
+ return {
21
+ name: logPolicyName,
22
+ async sendRequest(request, next) {
23
+ if (!logger.enabled) {
24
+ return next(request);
25
+ }
26
+ logger(`Request: ${sanitizer.sanitize(request)}`);
27
+ const response = await next(request);
28
+ logger(`Response status code: ${response.status}`);
29
+ logger(`Headers: ${sanitizer.sanitize(response.headers)}`);
30
+ return response;
31
+ },
32
+ };
33
+ }
34
+ //# sourceMappingURL=logPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logPolicy.js","sourceRoot":"","sources":["../../../src/policies/logPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AA4BzC;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,UAA4B,EAAE;;IACtD,MAAM,MAAM,GAAG,MAAA,OAAO,CAAC,MAAM,mCAAI,UAAU,CAAC,IAAI,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,SAAS,CAAC;QAC9B,4BAA4B,EAAE,OAAO,CAAC,4BAA4B;QAClE,gCAAgC,EAAE,OAAO,CAAC,gCAAgC;KAC3E,CAAC,CAAC;IACH,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,KAAK,CAAC,WAAW,CAAC,OAAwB,EAAE,IAAiB;YAC3D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE;gBACnB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;aACtB;YAED,MAAM,CAAC,YAAY,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAElD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;YAErC,MAAM,CAAC,yBAAyB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YACnD,MAAM,CAAC,YAAY,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAE3D,OAAO,QAAQ,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { Debugger } from \"../logger/logger\";\nimport { PipelineRequest, PipelineResponse, SendRequest } from \"../interfaces\";\nimport { PipelinePolicy } from \"../pipeline\";\nimport { logger as coreLogger } from \"../log\";\nimport { Sanitizer } from \"../util/sanitizer\";\n\n/**\n * The programmatic identifier of the logPolicy.\n */\nexport const logPolicyName = \"logPolicy\";\n\n/**\n * Options to configure the logPolicy.\n */\nexport interface LogPolicyOptions {\n /**\n * Header names whose values will be logged when logging is enabled.\n * Defaults include a list of well-known safe headers. Any headers\n * specified in this field will be added to that list. Any other values will\n * be written to logs as \"REDACTED\".\n */\n additionalAllowedHeaderNames?: string[];\n\n /**\n * Query string names whose values will be logged when logging is enabled. By default no\n * query string values are logged.\n */\n additionalAllowedQueryParameters?: string[];\n\n /**\n * The log function to use for writing pipeline logs.\n * Defaults to core-http's built-in logger.\n * Compatible with the `debug` library.\n */\n logger?: Debugger;\n}\n\n/**\n * A policy that logs all requests and responses.\n * @param options - Options to configure logPolicy.\n */\nexport function logPolicy(options: LogPolicyOptions = {}): PipelinePolicy {\n const logger = options.logger ?? coreLogger.info;\n const sanitizer = new Sanitizer({\n additionalAllowedHeaderNames: options.additionalAllowedHeaderNames,\n additionalAllowedQueryParameters: options.additionalAllowedQueryParameters,\n });\n return {\n name: logPolicyName,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n if (!logger.enabled) {\n return next(request);\n }\n\n logger(`Request: ${sanitizer.sanitize(request)}`);\n\n const response = await next(request);\n\n logger(`Response status code: ${response.status}`);\n logger(`Headers: ${sanitizer.sanitize(response.headers)}`);\n\n return response;\n },\n };\n}\n"]}
@@ -0,0 +1,27 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+ /*
4
+ * NOTE: When moving this file, please update "browser" section in package.json
5
+ */
6
+ export const proxyPolicyName = "proxyPolicy";
7
+ const errorMessage = "proxyPolicy is not supported in browser environment";
8
+ export function getDefaultProxySettings() {
9
+ throw new Error(errorMessage);
10
+ }
11
+ /**
12
+ * proxyPolicy is not supported in the browser and attempting
13
+ * to use it will raise an error.
14
+ */
15
+ export function proxyPolicy() {
16
+ throw new Error(errorMessage);
17
+ }
18
+ /**
19
+ * A function to reset the cached agents.
20
+ * proxyPolicy is not supported in the browser and attempting
21
+ * to use it will raise an error.
22
+ * @internal
23
+ */
24
+ export function resetCachedProxyAgents() {
25
+ throw new Error(errorMessage);
26
+ }
27
+ //# sourceMappingURL=proxyPolicy.browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxyPolicy.browser.js","sourceRoot":"","sources":["../../../src/policies/proxyPolicy.browser.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAAC;AAC7C,MAAM,YAAY,GAAG,qDAAqD,CAAC;AAE3E,MAAM,UAAU,uBAAuB;IACrC,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;AAChC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC;AAChC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\n/*\n * NOTE: When moving this file, please update \"browser\" section in package.json\n */\n\nexport const proxyPolicyName = \"proxyPolicy\";\nconst errorMessage = \"proxyPolicy is not supported in browser environment\";\n\nexport function getDefaultProxySettings(): never {\n throw new Error(errorMessage);\n}\n\n/**\n * proxyPolicy is not supported in the browser and attempting\n * to use it will raise an error.\n */\nexport function proxyPolicy(): never {\n throw new Error(errorMessage);\n}\n\n/**\n * A function to reset the cached agents.\n * proxyPolicy is not supported in the browser and attempting\n * to use it will raise an error.\n * @internal\n */\nexport function resetCachedProxyAgents(): never {\n throw new Error(errorMessage);\n}\n"]}
@@ -0,0 +1,190 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+ import { HttpsProxyAgent } from "https-proxy-agent";
4
+ import { HttpProxyAgent } from "http-proxy-agent";
5
+ import { logger } from "../log";
6
+ const HTTPS_PROXY = "HTTPS_PROXY";
7
+ const HTTP_PROXY = "HTTP_PROXY";
8
+ const ALL_PROXY = "ALL_PROXY";
9
+ const NO_PROXY = "NO_PROXY";
10
+ /**
11
+ * The programmatic identifier of the proxyPolicy.
12
+ */
13
+ export const proxyPolicyName = "proxyPolicy";
14
+ /**
15
+ * Stores the patterns specified in NO_PROXY environment variable.
16
+ * @internal
17
+ */
18
+ export const globalNoProxyList = [];
19
+ let noProxyListLoaded = false;
20
+ /** A cache of whether a host should bypass the proxy. */
21
+ const globalBypassedMap = new Map();
22
+ function getEnvironmentValue(name) {
23
+ if (process.env[name]) {
24
+ return process.env[name];
25
+ }
26
+ else if (process.env[name.toLowerCase()]) {
27
+ return process.env[name.toLowerCase()];
28
+ }
29
+ return undefined;
30
+ }
31
+ function loadEnvironmentProxyValue() {
32
+ if (!process) {
33
+ return undefined;
34
+ }
35
+ const httpsProxy = getEnvironmentValue(HTTPS_PROXY);
36
+ const allProxy = getEnvironmentValue(ALL_PROXY);
37
+ const httpProxy = getEnvironmentValue(HTTP_PROXY);
38
+ return httpsProxy || allProxy || httpProxy;
39
+ }
40
+ /**
41
+ * Check whether the host of a given `uri` matches any pattern in the no proxy list.
42
+ * If there's a match, any request sent to the same host shouldn't have the proxy settings set.
43
+ * This implementation is a port of https://github.com/Azure/azure-sdk-for-net/blob/8cca811371159e527159c7eb65602477898683e2/sdk/core/Azure.Core/src/Pipeline/Internal/HttpEnvironmentProxy.cs#L210
44
+ */
45
+ function isBypassed(uri, noProxyList, bypassedMap) {
46
+ if (noProxyList.length === 0) {
47
+ return false;
48
+ }
49
+ const host = new URL(uri).hostname;
50
+ if (bypassedMap === null || bypassedMap === void 0 ? void 0 : bypassedMap.has(host)) {
51
+ return bypassedMap.get(host);
52
+ }
53
+ let isBypassedFlag = false;
54
+ for (const pattern of noProxyList) {
55
+ if (pattern[0] === ".") {
56
+ // This should match either domain it self or any subdomain or host
57
+ // .foo.com will match foo.com it self or *.foo.com
58
+ if (host.endsWith(pattern)) {
59
+ isBypassedFlag = true;
60
+ }
61
+ else {
62
+ if (host.length === pattern.length - 1 && host === pattern.slice(1)) {
63
+ isBypassedFlag = true;
64
+ }
65
+ }
66
+ }
67
+ else {
68
+ if (host === pattern) {
69
+ isBypassedFlag = true;
70
+ }
71
+ }
72
+ }
73
+ bypassedMap === null || bypassedMap === void 0 ? void 0 : bypassedMap.set(host, isBypassedFlag);
74
+ return isBypassedFlag;
75
+ }
76
+ export function loadNoProxy() {
77
+ const noProxy = getEnvironmentValue(NO_PROXY);
78
+ noProxyListLoaded = true;
79
+ if (noProxy) {
80
+ return noProxy
81
+ .split(",")
82
+ .map((item) => item.trim())
83
+ .filter((item) => item.length);
84
+ }
85
+ return [];
86
+ }
87
+ /**
88
+ * This method converts a proxy url into `ProxySettings` for use with ProxyPolicy.
89
+ * If no argument is given, it attempts to parse a proxy URL from the environment
90
+ * variables `HTTPS_PROXY` or `HTTP_PROXY`.
91
+ * @param proxyUrl - The url of the proxy to use. May contain authentication information.
92
+ */
93
+ export function getDefaultProxySettings(proxyUrl) {
94
+ if (!proxyUrl) {
95
+ proxyUrl = loadEnvironmentProxyValue();
96
+ if (!proxyUrl) {
97
+ return undefined;
98
+ }
99
+ }
100
+ const parsedUrl = new URL(proxyUrl);
101
+ const schema = parsedUrl.protocol ? parsedUrl.protocol + "//" : "";
102
+ return {
103
+ host: schema + parsedUrl.hostname,
104
+ port: Number.parseInt(parsedUrl.port || "80"),
105
+ username: parsedUrl.username,
106
+ password: parsedUrl.password,
107
+ };
108
+ }
109
+ /**
110
+ * @internal
111
+ */
112
+ export function getProxyAgentOptions(proxySettings, { headers, tlsSettings }) {
113
+ let parsedProxyUrl;
114
+ try {
115
+ parsedProxyUrl = new URL(proxySettings.host);
116
+ }
117
+ catch (_error) {
118
+ throw new Error(`Expecting a valid host string in proxy settings, but found "${proxySettings.host}".`);
119
+ }
120
+ if (tlsSettings) {
121
+ logger.warning("TLS settings are not supported in combination with custom Proxy, certificates provided to the client will be ignored.");
122
+ }
123
+ const proxyAgentOptions = {
124
+ hostname: parsedProxyUrl.hostname,
125
+ port: proxySettings.port,
126
+ protocol: parsedProxyUrl.protocol,
127
+ headers: headers.toJSON(),
128
+ };
129
+ if (proxySettings.username && proxySettings.password) {
130
+ proxyAgentOptions.auth = `${proxySettings.username}:${proxySettings.password}`;
131
+ }
132
+ else if (proxySettings.username) {
133
+ proxyAgentOptions.auth = `${proxySettings.username}`;
134
+ }
135
+ return proxyAgentOptions;
136
+ }
137
+ function setProxyAgentOnRequest(request, cachedAgents) {
138
+ // Custom Agent should take precedence so if one is present
139
+ // we should skip to avoid overwriting it.
140
+ if (request.agent) {
141
+ return;
142
+ }
143
+ const url = new URL(request.url);
144
+ const isInsecure = url.protocol !== "https:";
145
+ const proxySettings = request.proxySettings;
146
+ if (proxySettings) {
147
+ if (isInsecure) {
148
+ if (!cachedAgents.httpProxyAgent) {
149
+ const proxyAgentOptions = getProxyAgentOptions(proxySettings, request);
150
+ cachedAgents.httpProxyAgent = new HttpProxyAgent(proxyAgentOptions);
151
+ }
152
+ request.agent = cachedAgents.httpProxyAgent;
153
+ }
154
+ else {
155
+ if (!cachedAgents.httpsProxyAgent) {
156
+ const proxyAgentOptions = getProxyAgentOptions(proxySettings, request);
157
+ cachedAgents.httpsProxyAgent = new HttpsProxyAgent(proxyAgentOptions);
158
+ }
159
+ request.agent = cachedAgents.httpsProxyAgent;
160
+ }
161
+ }
162
+ }
163
+ /**
164
+ * A policy that allows one to apply proxy settings to all requests.
165
+ * If not passed static settings, they will be retrieved from the HTTPS_PROXY
166
+ * or HTTP_PROXY environment variables.
167
+ * @param proxySettings - ProxySettings to use on each request.
168
+ * @param options - additional settings, for example, custom NO_PROXY patterns
169
+ */
170
+ export function proxyPolicy(proxySettings = getDefaultProxySettings(), options) {
171
+ if (!noProxyListLoaded) {
172
+ globalNoProxyList.push(...loadNoProxy());
173
+ }
174
+ const cachedAgents = {};
175
+ return {
176
+ name: proxyPolicyName,
177
+ async sendRequest(request, next) {
178
+ var _a;
179
+ if (!request.proxySettings &&
180
+ !isBypassed(request.url, (_a = options === null || options === void 0 ? void 0 : options.customNoProxyList) !== null && _a !== void 0 ? _a : globalNoProxyList, (options === null || options === void 0 ? void 0 : options.customNoProxyList) ? undefined : globalBypassedMap)) {
181
+ request.proxySettings = proxySettings;
182
+ }
183
+ if (request.proxySettings) {
184
+ setProxyAgentOnRequest(request, cachedAgents);
185
+ }
186
+ return next(request);
187
+ },
188
+ };
189
+ }
190
+ //# sourceMappingURL=proxyPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxyPolicy.js","sourceRoot":"","sources":["../../../src/policies/proxyPolicy.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport * as http from \"http\";\nimport * as https from \"https\";\nimport { HttpsProxyAgent, HttpsProxyAgentOptions } from \"https-proxy-agent\";\nimport { HttpProxyAgent, HttpProxyAgentOptions } from \"http-proxy-agent\";\nimport { PipelineRequest, PipelineResponse, ProxySettings, SendRequest } from \"../interfaces\";\nimport { PipelinePolicy } from \"../pipeline\";\nimport { logger } from \"../log\";\n\nconst HTTPS_PROXY = \"HTTPS_PROXY\";\nconst HTTP_PROXY = \"HTTP_PROXY\";\nconst ALL_PROXY = \"ALL_PROXY\";\nconst NO_PROXY = \"NO_PROXY\";\n\n/**\n * The programmatic identifier of the proxyPolicy.\n */\nexport const proxyPolicyName = \"proxyPolicy\";\n\n/**\n * Stores the patterns specified in NO_PROXY environment variable.\n * @internal\n */\nexport const globalNoProxyList: string[] = [];\nlet noProxyListLoaded: boolean = false;\n\n/** A cache of whether a host should bypass the proxy. */\nconst globalBypassedMap: Map<string, boolean> = new Map();\n\nfunction getEnvironmentValue(name: string): string | undefined {\n if (process.env[name]) {\n return process.env[name];\n } else if (process.env[name.toLowerCase()]) {\n return process.env[name.toLowerCase()];\n }\n return undefined;\n}\n\nfunction loadEnvironmentProxyValue(): string | undefined {\n if (!process) {\n return undefined;\n }\n\n const httpsProxy = getEnvironmentValue(HTTPS_PROXY);\n const allProxy = getEnvironmentValue(ALL_PROXY);\n const httpProxy = getEnvironmentValue(HTTP_PROXY);\n\n return httpsProxy || allProxy || httpProxy;\n}\n\n/**\n * Check whether the host of a given `uri` matches any pattern in the no proxy list.\n * If there's a match, any request sent to the same host shouldn't have the proxy settings set.\n * This implementation is a port of https://github.com/Azure/azure-sdk-for-net/blob/8cca811371159e527159c7eb65602477898683e2/sdk/core/Azure.Core/src/Pipeline/Internal/HttpEnvironmentProxy.cs#L210\n */\nfunction isBypassed(\n uri: string,\n noProxyList: string[],\n bypassedMap?: Map<string, boolean>\n): boolean | undefined {\n if (noProxyList.length === 0) {\n return false;\n }\n const host = new URL(uri).hostname;\n if (bypassedMap?.has(host)) {\n return bypassedMap.get(host);\n }\n let isBypassedFlag = false;\n for (const pattern of noProxyList) {\n if (pattern[0] === \".\") {\n // This should match either domain it self or any subdomain or host\n // .foo.com will match foo.com it self or *.foo.com\n if (host.endsWith(pattern)) {\n isBypassedFlag = true;\n } else {\n if (host.length === pattern.length - 1 && host === pattern.slice(1)) {\n isBypassedFlag = true;\n }\n }\n } else {\n if (host === pattern) {\n isBypassedFlag = true;\n }\n }\n }\n bypassedMap?.set(host, isBypassedFlag);\n return isBypassedFlag;\n}\n\nexport function loadNoProxy(): string[] {\n const noProxy = getEnvironmentValue(NO_PROXY);\n noProxyListLoaded = true;\n if (noProxy) {\n return noProxy\n .split(\",\")\n .map((item) => item.trim())\n .filter((item) => item.length);\n }\n\n return [];\n}\n\n/**\n * This method converts a proxy url into `ProxySettings` for use with ProxyPolicy.\n * If no argument is given, it attempts to parse a proxy URL from the environment\n * variables `HTTPS_PROXY` or `HTTP_PROXY`.\n * @param proxyUrl - The url of the proxy to use. May contain authentication information.\n */\nexport function getDefaultProxySettings(proxyUrl?: string): ProxySettings | undefined {\n if (!proxyUrl) {\n proxyUrl = loadEnvironmentProxyValue();\n if (!proxyUrl) {\n return undefined;\n }\n }\n\n const parsedUrl = new URL(proxyUrl);\n const schema = parsedUrl.protocol ? parsedUrl.protocol + \"//\" : \"\";\n return {\n host: schema + parsedUrl.hostname,\n port: Number.parseInt(parsedUrl.port || \"80\"),\n username: parsedUrl.username,\n password: parsedUrl.password,\n };\n}\n\n/**\n * @internal\n */\nexport function getProxyAgentOptions(\n proxySettings: ProxySettings,\n { headers, tlsSettings }: PipelineRequest\n): HttpProxyAgentOptions {\n let parsedProxyUrl: URL;\n try {\n parsedProxyUrl = new URL(proxySettings.host);\n } catch (_error) {\n throw new Error(\n `Expecting a valid host string in proxy settings, but found \"${proxySettings.host}\".`\n );\n }\n\n if (tlsSettings) {\n logger.warning(\n \"TLS settings are not supported in combination with custom Proxy, certificates provided to the client will be ignored.\"\n );\n }\n\n const proxyAgentOptions: HttpsProxyAgentOptions = {\n hostname: parsedProxyUrl.hostname,\n port: proxySettings.port,\n protocol: parsedProxyUrl.protocol,\n headers: headers.toJSON(),\n };\n if (proxySettings.username && proxySettings.password) {\n proxyAgentOptions.auth = `${proxySettings.username}:${proxySettings.password}`;\n } else if (proxySettings.username) {\n proxyAgentOptions.auth = `${proxySettings.username}`;\n }\n return proxyAgentOptions;\n}\n\nfunction setProxyAgentOnRequest(request: PipelineRequest, cachedAgents: CachedAgents): void {\n // Custom Agent should take precedence so if one is present\n // we should skip to avoid overwriting it.\n if (request.agent) {\n return;\n }\n\n const url = new URL(request.url);\n\n const isInsecure = url.protocol !== \"https:\";\n\n const proxySettings = request.proxySettings;\n if (proxySettings) {\n if (isInsecure) {\n if (!cachedAgents.httpProxyAgent) {\n const proxyAgentOptions = getProxyAgentOptions(proxySettings, request);\n cachedAgents.httpProxyAgent = new HttpProxyAgent(proxyAgentOptions);\n }\n request.agent = cachedAgents.httpProxyAgent;\n } else {\n if (!cachedAgents.httpsProxyAgent) {\n const proxyAgentOptions = getProxyAgentOptions(proxySettings, request);\n cachedAgents.httpsProxyAgent = new HttpsProxyAgent(proxyAgentOptions);\n }\n request.agent = cachedAgents.httpsProxyAgent;\n }\n }\n}\n\ninterface CachedAgents {\n httpsProxyAgent?: https.Agent;\n httpProxyAgent?: http.Agent;\n}\n\n/**\n * A policy that allows one to apply proxy settings to all requests.\n * If not passed static settings, they will be retrieved from the HTTPS_PROXY\n * or HTTP_PROXY environment variables.\n * @param proxySettings - ProxySettings to use on each request.\n * @param options - additional settings, for example, custom NO_PROXY patterns\n */\nexport function proxyPolicy(\n proxySettings = getDefaultProxySettings(),\n options?: {\n /** a list of patterns to override those loaded from NO_PROXY environment variable. */\n customNoProxyList?: string[];\n }\n): PipelinePolicy {\n if (!noProxyListLoaded) {\n globalNoProxyList.push(...loadNoProxy());\n }\n\n const cachedAgents: CachedAgents = {};\n\n return {\n name: proxyPolicyName,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n if (\n !request.proxySettings &&\n !isBypassed(\n request.url,\n options?.customNoProxyList ?? globalNoProxyList,\n options?.customNoProxyList ? undefined : globalBypassedMap\n )\n ) {\n request.proxySettings = proxySettings;\n }\n\n if (request.proxySettings) {\n setProxyAgentOnRequest(request, cachedAgents);\n }\n return next(request);\n },\n };\n}\n"]}
@@ -0,0 +1,52 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+ /**
4
+ * The programmatic identifier of the redirectPolicy.
5
+ */
6
+ export const redirectPolicyName = "redirectPolicy";
7
+ /**
8
+ * Methods that are allowed to follow redirects 301 and 302
9
+ */
10
+ const allowedRedirect = ["GET", "HEAD"];
11
+ /**
12
+ * A policy to follow Location headers from the server in order
13
+ * to support server-side redirection.
14
+ * In the browser, this policy is not used.
15
+ * @param options - Options to control policy behavior.
16
+ */
17
+ export function redirectPolicy(options = {}) {
18
+ const { maxRetries = 20 } = options;
19
+ return {
20
+ name: redirectPolicyName,
21
+ async sendRequest(request, next) {
22
+ const response = await next(request);
23
+ return handleRedirect(next, response, maxRetries);
24
+ },
25
+ };
26
+ }
27
+ async function handleRedirect(next, response, maxRetries, currentRetries = 0) {
28
+ const { request, status, headers } = response;
29
+ const locationHeader = headers.get("location");
30
+ if (locationHeader &&
31
+ (status === 300 ||
32
+ (status === 301 && allowedRedirect.includes(request.method)) ||
33
+ (status === 302 && allowedRedirect.includes(request.method)) ||
34
+ (status === 303 && request.method === "POST") ||
35
+ status === 307) &&
36
+ currentRetries < maxRetries) {
37
+ const url = new URL(locationHeader, request.url);
38
+ request.url = url.toString();
39
+ // POST request with Status code 303 should be converted into a
40
+ // redirected GET request if the redirect url is present in the location header
41
+ if (status === 303) {
42
+ request.method = "GET";
43
+ request.headers.delete("Content-Length");
44
+ delete request.body;
45
+ }
46
+ request.headers.delete("Authorization");
47
+ const res = await next(request);
48
+ return handleRedirect(next, res, maxRetries, currentRetries + 1);
49
+ }
50
+ return response;
51
+ }
52
+ //# sourceMappingURL=redirectPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redirectPolicy.js","sourceRoot":"","sources":["../../../src/policies/redirectPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAEnD;;GAEG;AACH,MAAM,eAAe,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;AAaxC;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAAC,UAAiC,EAAE;IAChE,MAAM,EAAE,UAAU,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IACpC,OAAO;QACL,IAAI,EAAE,kBAAkB;QACxB,KAAK,CAAC,WAAW,CAAC,OAAwB,EAAE,IAAiB;YAC3D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,OAAO,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QACpD,CAAC;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,IAAiB,EACjB,QAA0B,EAC1B,UAAkB,EAClB,iBAAyB,CAAC;IAE1B,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;IAC9C,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC/C,IACE,cAAc;QACd,CAAC,MAAM,KAAK,GAAG;YACb,CAAC,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC5D,CAAC,MAAM,KAAK,GAAG,IAAI,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC5D,CAAC,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,CAAC;YAC7C,MAAM,KAAK,GAAG,CAAC;QACjB,cAAc,GAAG,UAAU,EAC3B;QACA,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAE7B,+DAA+D;QAC/D,+EAA+E;QAC/E,IAAI,MAAM,KAAK,GAAG,EAAE;YAClB,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC;YACvB,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACzC,OAAO,OAAO,CAAC,IAAI,CAAC;SACrB;QAED,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAExC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,OAAO,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,cAAc,GAAG,CAAC,CAAC,CAAC;KAClE;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { PipelineRequest, PipelineResponse, SendRequest } from \"../interfaces\";\nimport { PipelinePolicy } from \"../pipeline\";\n\n/**\n * The programmatic identifier of the redirectPolicy.\n */\nexport const redirectPolicyName = \"redirectPolicy\";\n\n/**\n * Methods that are allowed to follow redirects 301 and 302\n */\nconst allowedRedirect = [\"GET\", \"HEAD\"];\n\n/**\n * Options for how redirect responses are handled.\n */\nexport interface RedirectPolicyOptions {\n /**\n * The maximum number of times the redirect URL will be tried before\n * failing. Defaults to 20.\n */\n maxRetries?: number;\n}\n\n/**\n * A policy to follow Location headers from the server in order\n * to support server-side redirection.\n * In the browser, this policy is not used.\n * @param options - Options to control policy behavior.\n */\nexport function redirectPolicy(options: RedirectPolicyOptions = {}): PipelinePolicy {\n const { maxRetries = 20 } = options;\n return {\n name: redirectPolicyName,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n const response = await next(request);\n return handleRedirect(next, response, maxRetries);\n },\n };\n}\n\nasync function handleRedirect(\n next: SendRequest,\n response: PipelineResponse,\n maxRetries: number,\n currentRetries: number = 0\n): Promise<PipelineResponse> {\n const { request, status, headers } = response;\n const locationHeader = headers.get(\"location\");\n if (\n locationHeader &&\n (status === 300 ||\n (status === 301 && allowedRedirect.includes(request.method)) ||\n (status === 302 && allowedRedirect.includes(request.method)) ||\n (status === 303 && request.method === \"POST\") ||\n status === 307) &&\n currentRetries < maxRetries\n ) {\n const url = new URL(locationHeader, request.url);\n request.url = url.toString();\n\n // POST request with Status code 303 should be converted into a\n // redirected GET request if the redirect url is present in the location header\n if (status === 303) {\n request.method = \"GET\";\n request.headers.delete(\"Content-Length\");\n delete request.body;\n }\n\n request.headers.delete(\"Authorization\");\n\n const res = await next(request);\n return handleRedirect(next, res, maxRetries, currentRetries + 1);\n }\n\n return response;\n}\n"]}
@@ -0,0 +1,106 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT license.
3
+ import { delay } from "../util/helpers";
4
+ import { AbortError } from "../abort-controller/AbortError";
5
+ import { createClientLogger } from "../logger/logger";
6
+ import { DEFAULT_RETRY_POLICY_COUNT } from "../constants";
7
+ const retryPolicyLogger = createClientLogger("core-rest-pipeline retryPolicy");
8
+ /**
9
+ * The programmatic identifier of the retryPolicy.
10
+ */
11
+ const retryPolicyName = "retryPolicy";
12
+ /**
13
+ * retryPolicy is a generic policy to enable retrying requests when certain conditions are met
14
+ */
15
+ export function retryPolicy(strategies, options = { maxRetries: DEFAULT_RETRY_POLICY_COUNT }) {
16
+ const logger = options.logger || retryPolicyLogger;
17
+ return {
18
+ name: retryPolicyName,
19
+ async sendRequest(request, next) {
20
+ var _a, _b;
21
+ let response;
22
+ let responseError;
23
+ let retryCount = -1;
24
+ // eslint-disable-next-line no-constant-condition
25
+ retryRequest: while (true) {
26
+ retryCount += 1;
27
+ response = undefined;
28
+ responseError = undefined;
29
+ try {
30
+ logger.info(`Retry ${retryCount}: Attempting to send request`, request.requestId);
31
+ response = await next(request);
32
+ logger.info(`Retry ${retryCount}: Received a response from request`, request.requestId);
33
+ }
34
+ catch (e) {
35
+ logger.error(`Retry ${retryCount}: Received an error from request`, request.requestId);
36
+ // RestErrors are valid targets for the retry strategies.
37
+ // If none of the retry strategies can work with them, they will be thrown later in this policy.
38
+ // If the received error is not a RestError, it is immediately thrown.
39
+ responseError = e;
40
+ if (!e || responseError.name !== "RestError") {
41
+ throw e;
42
+ }
43
+ response = responseError.response;
44
+ }
45
+ if ((_a = request.abortSignal) === null || _a === void 0 ? void 0 : _a.aborted) {
46
+ logger.error(`Retry ${retryCount}: Request aborted.`);
47
+ const abortError = new AbortError();
48
+ throw abortError;
49
+ }
50
+ if (retryCount >= ((_b = options.maxRetries) !== null && _b !== void 0 ? _b : DEFAULT_RETRY_POLICY_COUNT)) {
51
+ logger.info(`Retry ${retryCount}: Maximum retries reached. Returning the last received response, or throwing the last received error.`);
52
+ if (responseError) {
53
+ throw responseError;
54
+ }
55
+ else if (response) {
56
+ return response;
57
+ }
58
+ else {
59
+ throw new Error("Maximum retries reached with no response or error to throw");
60
+ }
61
+ }
62
+ logger.info(`Retry ${retryCount}: Processing ${strategies.length} retry strategies.`);
63
+ strategiesLoop: for (const strategy of strategies) {
64
+ const strategyLogger = strategy.logger || retryPolicyLogger;
65
+ strategyLogger.info(`Retry ${retryCount}: Processing retry strategy ${strategy.name}.`);
66
+ const modifiers = strategy.retry({
67
+ retryCount,
68
+ response,
69
+ responseError,
70
+ });
71
+ if (modifiers.skipStrategy) {
72
+ strategyLogger.info(`Retry ${retryCount}: Skipped.`);
73
+ continue strategiesLoop;
74
+ }
75
+ const { errorToThrow, retryAfterInMs, redirectTo } = modifiers;
76
+ if (errorToThrow) {
77
+ strategyLogger.error(`Retry ${retryCount}: Retry strategy ${strategy.name} throws error:`, errorToThrow);
78
+ throw errorToThrow;
79
+ }
80
+ if (retryAfterInMs || retryAfterInMs === 0) {
81
+ strategyLogger.info(`Retry ${retryCount}: Retry strategy ${strategy.name} retries after ${retryAfterInMs}`);
82
+ await delay(retryAfterInMs, undefined, { abortSignal: request.abortSignal });
83
+ continue retryRequest;
84
+ }
85
+ if (redirectTo) {
86
+ strategyLogger.info(`Retry ${retryCount}: Retry strategy ${strategy.name} redirects to ${redirectTo}`);
87
+ request.url = redirectTo;
88
+ continue retryRequest;
89
+ }
90
+ }
91
+ if (responseError) {
92
+ logger.info(`None of the retry strategies could work with the received error. Throwing it.`);
93
+ throw responseError;
94
+ }
95
+ if (response) {
96
+ logger.info(`None of the retry strategies could work with the received response. Returning it.`);
97
+ return response;
98
+ }
99
+ // If all the retries skip and there's no response,
100
+ // we're still in the retry loop, so a new request will be sent
101
+ // until `maxRetries` is reached.
102
+ }
103
+ },
104
+ };
105
+ }
106
+ //# sourceMappingURL=retryPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retryPolicy.js","sourceRoot":"","sources":["../../../src/policies/retryPolicy.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { PipelineRequest, PipelineResponse, SendRequest } from \"../interfaces\";\nimport { PipelinePolicy } from \"../pipeline\";\nimport { delay } from \"../util/helpers\";\nimport { RetryStrategy } from \"../retryStrategies/retryStrategy\";\nimport { RestError } from \"../restError\";\nimport { AbortError } from \"../abort-controller/AbortError\";\nimport { TypeSpecRuntimeLogger, createClientLogger } from \"../logger/logger\";\nimport { DEFAULT_RETRY_POLICY_COUNT } from \"../constants\";\n\nconst retryPolicyLogger = createClientLogger(\"core-rest-pipeline retryPolicy\");\n\n/**\n * The programmatic identifier of the retryPolicy.\n */\nconst retryPolicyName = \"retryPolicy\";\n\n/**\n * Options to the {@link retryPolicy}\n */\nexport interface RetryPolicyOptions {\n /**\n * Maximum number of retries. If not specified, it will limit to 3 retries.\n */\n maxRetries?: number;\n /**\n * Logger. If it's not provided, a default logger is used.\n */\n logger?: TypeSpecRuntimeLogger;\n}\n\n/**\n * retryPolicy is a generic policy to enable retrying requests when certain conditions are met\n */\nexport function retryPolicy(\n strategies: RetryStrategy[],\n options: RetryPolicyOptions = { maxRetries: DEFAULT_RETRY_POLICY_COUNT }\n): PipelinePolicy {\n const logger = options.logger || retryPolicyLogger;\n return {\n name: retryPolicyName,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n let response: PipelineResponse | undefined;\n let responseError: RestError | undefined;\n let retryCount = -1;\n\n // eslint-disable-next-line no-constant-condition\n retryRequest: while (true) {\n retryCount += 1;\n response = undefined;\n responseError = undefined;\n\n try {\n logger.info(`Retry ${retryCount}: Attempting to send request`, request.requestId);\n response = await next(request);\n logger.info(`Retry ${retryCount}: Received a response from request`, request.requestId);\n } catch (e: any) {\n logger.error(`Retry ${retryCount}: Received an error from request`, request.requestId);\n\n // RestErrors are valid targets for the retry strategies.\n // If none of the retry strategies can work with them, they will be thrown later in this policy.\n // If the received error is not a RestError, it is immediately thrown.\n responseError = e as RestError;\n if (!e || responseError.name !== \"RestError\") {\n throw e;\n }\n\n response = responseError.response;\n }\n\n if (request.abortSignal?.aborted) {\n logger.error(`Retry ${retryCount}: Request aborted.`);\n const abortError = new AbortError();\n throw abortError;\n }\n\n if (retryCount >= (options.maxRetries ?? DEFAULT_RETRY_POLICY_COUNT)) {\n logger.info(\n `Retry ${retryCount}: Maximum retries reached. Returning the last received response, or throwing the last received error.`\n );\n if (responseError) {\n throw responseError;\n } else if (response) {\n return response;\n } else {\n throw new Error(\"Maximum retries reached with no response or error to throw\");\n }\n }\n\n logger.info(`Retry ${retryCount}: Processing ${strategies.length} retry strategies.`);\n\n strategiesLoop: for (const strategy of strategies) {\n const strategyLogger = strategy.logger || retryPolicyLogger;\n strategyLogger.info(`Retry ${retryCount}: Processing retry strategy ${strategy.name}.`);\n\n const modifiers = strategy.retry({\n retryCount,\n response,\n responseError,\n });\n\n if (modifiers.skipStrategy) {\n strategyLogger.info(`Retry ${retryCount}: Skipped.`);\n continue strategiesLoop;\n }\n\n const { errorToThrow, retryAfterInMs, redirectTo } = modifiers;\n\n if (errorToThrow) {\n strategyLogger.error(\n `Retry ${retryCount}: Retry strategy ${strategy.name} throws error:`,\n errorToThrow\n );\n throw errorToThrow;\n }\n\n if (retryAfterInMs || retryAfterInMs === 0) {\n strategyLogger.info(\n `Retry ${retryCount}: Retry strategy ${strategy.name} retries after ${retryAfterInMs}`\n );\n await delay(retryAfterInMs, undefined, { abortSignal: request.abortSignal });\n continue retryRequest;\n }\n\n if (redirectTo) {\n strategyLogger.info(\n `Retry ${retryCount}: Retry strategy ${strategy.name} redirects to ${redirectTo}`\n );\n request.url = redirectTo;\n continue retryRequest;\n }\n }\n\n if (responseError) {\n logger.info(\n `None of the retry strategies could work with the received error. Throwing it.`\n );\n throw responseError;\n }\n if (response) {\n logger.info(\n `None of the retry strategies could work with the received response. Returning it.`\n );\n return response;\n }\n\n // If all the retries skip and there's no response,\n // we're still in the retry loop, so a new request will be sent\n // until `maxRetries` is reached.\n }\n },\n };\n}\n"]}