Bump artifact dependencies if CODEQL_ACTION_ARTIFACT_V2_UPGRADE enabled (#2482)

Co-authored-by: Andrew Eisenberg <aeisenberg@github.com>
Co-authored-by: Henry Mercer <henrymercer@github.com>
This commit is contained in:
Angela P Wen 2024-10-01 09:59:05 -07:00 committed by GitHub
parent cf5b0a9041
commit a196a714b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5388 changed files with 2176737 additions and 71701 deletions

View file

@ -0,0 +1,40 @@
import type { AccessToken } from "@azure/core-auth";
/**
* Defines the default token refresh buffer duration.
*/
export declare const DefaultTokenRefreshBufferMs: number;
/**
* Provides a cache for an AccessToken that was that
* was returned from a TokenCredential.
*/
export interface AccessTokenCache {
/**
* Sets the cached token.
*
* @param accessToken - The AccessToken to be cached or null to
* clear the cached token.
*/
setCachedToken(accessToken: AccessToken | undefined): void;
/**
* Returns the cached AccessToken or undefined if nothing is cached.
*/
getCachedToken(): AccessToken | undefined;
}
/**
* Provides an AccessTokenCache implementation which clears
* the cached AccessToken's after the expiresOnTimestamp has
* passed.
* @internal
*/
export declare class ExpiringAccessTokenCache implements AccessTokenCache {
private tokenRefreshBufferMs;
private cachedToken?;
/**
* Constructs an instance of ExpiringAccessTokenCache with
* an optional expiration buffer time.
*/
constructor(tokenRefreshBufferMs?: number);
setCachedToken(accessToken: AccessToken | undefined): void;
getCachedToken(): AccessToken | undefined;
}
//# sourceMappingURL=accessTokenCache.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"accessTokenCache.d.ts","sourceRoot":"","sources":["../../src/accessTokenCache.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD;;GAEG;AACH,eAAO,MAAM,2BAA2B,QAAgB,CAAC;AAEzD;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAAC;IAE3D;;OAEG;IACH,cAAc,IAAI,WAAW,GAAG,SAAS,CAAC;CAC3C;AAED;;;;;GAKG;AACH,qBAAa,wBAAyB,YAAW,gBAAgB;IAC/D,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,WAAW,CAAC,CAAc;IAElC;;;OAGG;gBACS,oBAAoB,GAAE,MAAoC;IAItE,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI;IAI1D,cAAc,IAAI,WAAW,GAAG,SAAS;CAU1C"}

View file

@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/**
* Defines the default token refresh buffer duration.
*/
export const DefaultTokenRefreshBufferMs = 2 * 60 * 1000; // 2 Minutes
/**
* Provides an AccessTokenCache implementation which clears
* the cached AccessToken's after the expiresOnTimestamp has
* passed.
* @internal
*/
export class ExpiringAccessTokenCache {
/**
* Constructs an instance of ExpiringAccessTokenCache with
* an optional expiration buffer time.
*/
constructor(tokenRefreshBufferMs = DefaultTokenRefreshBufferMs) {
this.tokenRefreshBufferMs = tokenRefreshBufferMs;
}
setCachedToken(accessToken) {
this.cachedToken = accessToken;
}
getCachedToken() {
if (this.cachedToken &&
Date.now() + this.tokenRefreshBufferMs >= this.cachedToken.expiresOnTimestamp) {
this.cachedToken = undefined;
}
return this.cachedToken;
}
}
//# sourceMappingURL=accessTokenCache.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"accessTokenCache.js","sourceRoot":"","sources":["../../src/accessTokenCache.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC;;GAEG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AAqBtE;;;;;GAKG;AACH,MAAM,OAAO,wBAAwB;IAInC;;;OAGG;IACH,YAAY,uBAA+B,2BAA2B;QACpE,IAAI,CAAC,oBAAoB,GAAG,oBAAoB,CAAC;IACnD,CAAC;IAED,cAAc,CAAC,WAAoC;QACjD,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;IAED,cAAc;QACZ,IACE,IAAI,CAAC,WAAW;YAChB,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,oBAAoB,IAAI,IAAI,CAAC,WAAW,CAAC,kBAAkB,EAC7E,CAAC;YACD,IAAI,CAAC,WAAW,GAAG,SAAS,CAAC;QAC/B,CAAC;QAED,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken } from \"@azure/core-auth\";\n\n/**\n * Defines the default token refresh buffer duration.\n */\nexport const DefaultTokenRefreshBufferMs = 2 * 60 * 1000; // 2 Minutes\n\n/**\n * Provides a cache for an AccessToken that was that\n * was returned from a TokenCredential.\n */\nexport interface AccessTokenCache {\n /**\n * Sets the cached token.\n *\n * @param accessToken - The AccessToken to be cached or null to\n * clear the cached token.\n */\n setCachedToken(accessToken: AccessToken | undefined): void;\n\n /**\n * Returns the cached AccessToken or undefined if nothing is cached.\n */\n getCachedToken(): AccessToken | undefined;\n}\n\n/**\n * Provides an AccessTokenCache implementation which clears\n * the cached AccessToken's after the expiresOnTimestamp has\n * passed.\n * @internal\n */\nexport class ExpiringAccessTokenCache implements AccessTokenCache {\n private tokenRefreshBufferMs: number;\n private cachedToken?: AccessToken;\n\n /**\n * Constructs an instance of ExpiringAccessTokenCache with\n * an optional expiration buffer time.\n */\n constructor(tokenRefreshBufferMs: number = DefaultTokenRefreshBufferMs) {\n this.tokenRefreshBufferMs = tokenRefreshBufferMs;\n }\n\n setCachedToken(accessToken: AccessToken | undefined): void {\n this.cachedToken = accessToken;\n }\n\n getCachedToken(): AccessToken | undefined {\n if (\n this.cachedToken &&\n Date.now() + this.tokenRefreshBufferMs >= this.cachedToken.expiresOnTimestamp\n ) {\n this.cachedToken = undefined;\n }\n\n return this.cachedToken;\n }\n}\n"]}

View file

@ -0,0 +1,3 @@
export declare const SDK_VERSION: string;
export declare const DEFAULT_RETRY_POLICY_COUNT = 3;
//# sourceMappingURL=constants.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,EAAE,MAAiB,CAAC;AAE5C,eAAO,MAAM,0BAA0B,IAAI,CAAC"}

View file

@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
export const SDK_VERSION = "1.17.0";
export const DEFAULT_RETRY_POLICY_COUNT = 3;
//# sourceMappingURL=constants.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,MAAM,CAAC,MAAM,WAAW,GAAW,QAAQ,CAAC;AAE5C,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nexport const SDK_VERSION: string = \"1.17.0\";\n\nexport const DEFAULT_RETRY_POLICY_COUNT = 3;\n"]}

View file

@ -0,0 +1,58 @@
import { type LogPolicyOptions } from "./policies/logPolicy.js";
import { type Pipeline } from "./pipeline.js";
import type { PipelineRetryOptions, TlsSettings, ProxySettings } from "./interfaces.js";
import { type RedirectPolicyOptions } from "./policies/redirectPolicy.js";
import { type UserAgentPolicyOptions } from "./policies/userAgentPolicy.js";
/**
* Defines options that are used to configure the HTTP pipeline for
* an SDK client.
*/
export interface PipelineOptions {
/**
* Options that control how to retry failed requests.
*/
retryOptions?: PipelineRetryOptions;
/**
* Options to configure a proxy for outgoing requests.
*/
proxyOptions?: ProxySettings;
/** Options for configuring TLS authentication */
tlsOptions?: TlsSettings;
/**
* Options for how redirect responses are handled.
*/
redirectOptions?: RedirectPolicyOptions;
/**
* Options for adding user agent details to outgoing requests.
*/
userAgentOptions?: UserAgentPolicyOptions;
/**
* Options for setting common telemetry and tracing info to outgoing requests.
*/
telemetryOptions?: TelemetryOptions;
}
/**
* Defines options that are used to configure common telemetry and tracing info
*/
export interface TelemetryOptions {
/**
* The name of the header to pass the request ID to.
*/
clientRequestIdHeaderName?: string;
}
/**
* Defines options that are used to configure internal options of
* the HTTP pipeline for an SDK client.
*/
export interface InternalPipelineOptions extends PipelineOptions {
/**
* Options to configure request/response logging.
*/
loggingOptions?: LogPolicyOptions;
}
/**
* Create a new pipeline with a default set of customizable policies.
* @param options - Options to configure a custom pipeline.
*/
export declare function createPipelineFromOptions(options: InternalPipelineOptions): Pipeline;
//# sourceMappingURL=createPipelineFromOptions.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"createPipelineFromOptions.d.ts","sourceRoot":"","sources":["../../src/createPipelineFromOptions.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,gBAAgB,EAAa,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,KAAK,QAAQ,EAAuB,MAAM,eAAe,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACxF,OAAO,EAAE,KAAK,qBAAqB,EAAkB,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAAE,KAAK,sBAAsB,EAAmB,MAAM,+BAA+B,CAAC;AAW7F;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,YAAY,CAAC,EAAE,oBAAoB,CAAC;IAEpC;;OAEG;IACH,YAAY,CAAC,EAAE,aAAa,CAAC;IAE7B,iDAAiD;IACjD,UAAU,CAAC,EAAE,WAAW,CAAC;IAEzB;;OAEG;IACH,eAAe,CAAC,EAAE,qBAAqB,CAAC;IAExC;;OAEG;IACH,gBAAgB,CAAC,EAAE,sBAAsB,CAAC;IAE1C;;OAEG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAwB,SAAQ,eAAe;IAC9D;;OAEG;IACH,cAAc,CAAC,EAAE,gBAAgB,CAAC;CACnC;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,uBAAuB,GAAG,QAAQ,CA8BpF"}

View file

@ -0,0 +1,49 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { logPolicy } from "./policies/logPolicy.js";
import { createEmptyPipeline } from "./pipeline.js";
import { redirectPolicy } from "./policies/redirectPolicy.js";
import { userAgentPolicy } from "./policies/userAgentPolicy.js";
import { multipartPolicy, multipartPolicyName } from "./policies/multipartPolicy.js";
import { decompressResponsePolicy } from "./policies/decompressResponsePolicy.js";
import { defaultRetryPolicy } from "./policies/defaultRetryPolicy.js";
import { formDataPolicy } from "./policies/formDataPolicy.js";
import { isNodeLike } from "@azure/core-util";
import { proxyPolicy } from "./policies/proxyPolicy.js";
import { setClientRequestIdPolicy } from "./policies/setClientRequestIdPolicy.js";
import { tlsPolicy } from "./policies/tlsPolicy.js";
import { tracingPolicy } from "./policies/tracingPolicy.js";
/**
* Create a new pipeline with a default set of customizable policies.
* @param options - Options to configure a custom pipeline.
*/
export function createPipelineFromOptions(options) {
var _a;
const pipeline = createEmptyPipeline();
if (isNodeLike) {
if (options.tlsOptions) {
pipeline.addPolicy(tlsPolicy(options.tlsOptions));
}
pipeline.addPolicy(proxyPolicy(options.proxyOptions));
pipeline.addPolicy(decompressResponsePolicy());
}
pipeline.addPolicy(formDataPolicy(), { beforePolicies: [multipartPolicyName] });
pipeline.addPolicy(userAgentPolicy(options.userAgentOptions));
pipeline.addPolicy(setClientRequestIdPolicy((_a = options.telemetryOptions) === null || _a === void 0 ? void 0 : _a.clientRequestIdHeaderName));
// The multipart policy is added after policies with no phase, so that
// policies can be added between it and formDataPolicy to modify
// properties (e.g., making the boundary constant in recorded tests).
pipeline.addPolicy(multipartPolicy(), { afterPhase: "Deserialize" });
pipeline.addPolicy(defaultRetryPolicy(options.retryOptions), { phase: "Retry" });
pipeline.addPolicy(tracingPolicy(Object.assign(Object.assign({}, options.userAgentOptions), options.loggingOptions)), {
afterPhase: "Retry",
});
if (isNodeLike) {
// Both XHR and Fetch expect to handle redirects automatically,
// so only include this policy when we're in Node.
pipeline.addPolicy(redirectPolicy(options.redirectOptions), { afterPhase: "Retry" });
}
pipeline.addPolicy(logPolicy(options.loggingOptions), { afterPhase: "Sign" });
return pipeline;
}
//# sourceMappingURL=createPipelineFromOptions.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"version":3,"file":"defaultHttpClient-browser.d.mts","sourceRoot":"","sources":["../../src/defaultHttpClient-browser.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAGlD;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,UAAU,CAEpD"}

View file

@ -0,0 +1 @@
{"version":3,"file":"defaultHttpClient-browser.mjs","sourceRoot":"","sources":["../../src/defaultHttpClient-browser.mts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO,qBAAqB,EAAE,CAAC;AACjC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { HttpClient } from \"./interfaces.js\";\nimport { createFetchHttpClient } from \"./fetchHttpClient.js\";\n\n/**\n * Create the correct HttpClient for the current environment.\n */\nexport function createDefaultHttpClient(): HttpClient {\n return createFetchHttpClient();\n}\n"]}

View file

@ -0,0 +1,6 @@
import type { HttpClient } from "./interfaces.js";
/**
* Create the correct HttpClient for the current environment.
*/
export declare function createDefaultHttpClient(): HttpClient;
//# sourceMappingURL=defaultHttpClient-browser.d.mts.map

View file

@ -0,0 +1,10 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { createFetchHttpClient } from "./fetchHttpClient.js";
/**
* Create the correct HttpClient for the current environment.
*/
export function createDefaultHttpClient() {
return createFetchHttpClient();
}
//# sourceMappingURL=defaultHttpClient-browser.mjs.map

View file

@ -0,0 +1,7 @@
import type { HttpClient } from "./interfaces.js";
/**
* Create a new HttpClient instance for the browser environment.
* @internal
*/
export declare function createFetchHttpClient(): HttpClient;
//# sourceMappingURL=fetchHttpClient.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"fetchHttpClient.d.ts","sourceRoot":"","sources":["../../src/fetchHttpClient.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,iBAAiB,CAAC;AA6SzB;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,UAAU,CAElD"}

View file

@ -0,0 +1,256 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { AbortError } from "@azure/abort-controller";
import { RestError } from "./restError.js";
import { createHttpHeaders } from "./httpHeaders.js";
import { isNodeReadableStream, isWebReadableStream } from "./util/typeGuards.js";
/**
* Checks if the body is a Blob or Blob-like
*/
function isBlob(body) {
// File objects count as a type of Blob, so we want to use instanceof explicitly
return (typeof Blob === "function" || typeof Blob === "object") && body instanceof Blob;
}
/**
* A HttpClient implementation that uses window.fetch to send HTTP requests.
* @internal
*/
class FetchHttpClient {
/**
* Makes a request over an underlying transport layer and returns the response.
* @param request - The request to be made.
*/
async sendRequest(request) {
const url = new URL(request.url);
const isInsecure = url.protocol !== "https:";
if (isInsecure && !request.allowInsecureConnection) {
throw new Error(`Cannot connect to ${request.url} while allowInsecureConnection is false.`);
}
if (request.proxySettings) {
throw new Error("HTTP proxy is not supported in browser environment");
}
try {
return await makeRequest(request);
}
catch (e) {
throw getError(e, request);
}
}
}
/**
* Sends a request
*/
async function makeRequest(request) {
const { abortController, abortControllerCleanup } = setupAbortSignal(request);
try {
const headers = buildFetchHeaders(request.headers);
const { streaming, body: requestBody } = buildRequestBody(request);
const requestInit = Object.assign(Object.assign({ body: requestBody, method: request.method, headers: headers, signal: abortController.signal }, ("credentials" in Request.prototype
? { credentials: request.withCredentials ? "include" : "same-origin" }
: {})), ("cache" in Request.prototype ? { cache: "no-store" } : {}));
// According to https://fetch.spec.whatwg.org/#fetch-method,
// init.duplex must be set when body is a ReadableStream object.
// currently "half" is the only valid value.
if (streaming) {
requestInit.duplex = "half";
}
/**
* Developers of the future:
* Do not set redirect: "manual" as part
* of request options.
* It will not work as you expect.
*/
const response = await fetch(request.url, requestInit);
// If we're uploading a blob, we need to fire the progress event manually
if (isBlob(request.body) && request.onUploadProgress) {
request.onUploadProgress({ loadedBytes: request.body.size });
}
return buildPipelineResponse(response, request, abortControllerCleanup);
}
catch (e) {
abortControllerCleanup === null || abortControllerCleanup === void 0 ? void 0 : abortControllerCleanup();
throw e;
}
}
/**
* Creates a pipeline response from a Fetch response;
*/
async function buildPipelineResponse(httpResponse, request, abortControllerCleanup) {
var _a, _b;
const headers = buildPipelineHeaders(httpResponse);
const response = {
request,
headers,
status: httpResponse.status,
};
const bodyStream = isWebReadableStream(httpResponse.body)
? buildBodyStream(httpResponse.body, {
onProgress: request.onDownloadProgress,
onEnd: abortControllerCleanup,
})
: httpResponse.body;
if (
// Value of POSITIVE_INFINITY in streamResponseStatusCodes is considered as any status code
((_a = request.streamResponseStatusCodes) === null || _a === void 0 ? void 0 : _a.has(Number.POSITIVE_INFINITY)) ||
((_b = request.streamResponseStatusCodes) === null || _b === void 0 ? void 0 : _b.has(response.status))) {
if (request.enableBrowserStreams) {
response.browserStreamBody = bodyStream !== null && bodyStream !== void 0 ? bodyStream : undefined;
}
else {
const responseStream = new Response(bodyStream);
response.blobBody = responseStream.blob();
abortControllerCleanup === null || abortControllerCleanup === void 0 ? void 0 : abortControllerCleanup();
}
}
else {
const responseStream = new Response(bodyStream);
response.bodyAsText = await responseStream.text();
abortControllerCleanup === null || abortControllerCleanup === void 0 ? void 0 : abortControllerCleanup();
}
return response;
}
function setupAbortSignal(request) {
const abortController = new AbortController();
// Cleanup function
let abortControllerCleanup;
/**
* Attach an abort listener to the request
*/
let abortListener;
if (request.abortSignal) {
if (request.abortSignal.aborted) {
throw new AbortError("The operation was aborted.");
}
abortListener = (event) => {
if (event.type === "abort") {
abortController.abort();
}
};
request.abortSignal.addEventListener("abort", abortListener);
abortControllerCleanup = () => {
var _a;
if (abortListener) {
(_a = request.abortSignal) === null || _a === void 0 ? void 0 : _a.removeEventListener("abort", abortListener);
}
};
}
// If a timeout was passed, call the abort signal once the time elapses
if (request.timeout > 0) {
setTimeout(() => {
abortController.abort();
}, request.timeout);
}
return { abortController, abortControllerCleanup };
}
/**
* Gets the specific error
*/
// eslint-disable-next-line @azure/azure-sdk/ts-use-interface-parameters
function getError(e, request) {
var _a;
if (e && (e === null || e === void 0 ? void 0 : e.name) === "AbortError") {
return e;
}
else {
return new RestError(`Error sending request: ${e.message}`, {
code: (_a = e === null || e === void 0 ? void 0 : e.code) !== null && _a !== void 0 ? _a : RestError.REQUEST_SEND_ERROR,
request,
});
}
}
/**
* Converts PipelineRequest headers to Fetch headers
*/
function buildFetchHeaders(pipelineHeaders) {
const headers = new Headers();
for (const [name, value] of pipelineHeaders) {
headers.append(name, value);
}
return headers;
}
function buildPipelineHeaders(httpResponse) {
const responseHeaders = createHttpHeaders();
for (const [name, value] of httpResponse.headers) {
responseHeaders.set(name, value);
}
return responseHeaders;
}
function buildRequestBody(request) {
const body = typeof request.body === "function" ? request.body() : request.body;
if (isNodeReadableStream(body)) {
throw new Error("Node streams are not supported in browser environment.");
}
return isWebReadableStream(body)
? { streaming: true, body: buildBodyStream(body, { onProgress: request.onUploadProgress }) }
: { streaming: false, body };
}
/**
* Reads the request/response original stream and stream it through a new
* ReadableStream, this is done to be able to report progress in a way that
* all modern browsers support. TransformStreams would be an alternative,
* however they are not yet supported by all browsers i.e Firefox
*/
function buildBodyStream(readableStream, options = {}) {
let loadedBytes = 0;
const { onProgress, onEnd } = options;
// If the current browser supports pipeThrough we use a TransformStream
// to report progress
if (isTransformStreamSupported(readableStream)) {
return readableStream.pipeThrough(new TransformStream({
transform(chunk, controller) {
if (chunk === null) {
controller.terminate();
return;
}
controller.enqueue(chunk);
loadedBytes += chunk.length;
if (onProgress) {
onProgress({ loadedBytes });
}
},
flush() {
onEnd === null || onEnd === void 0 ? void 0 : onEnd();
},
}));
}
else {
// If we can't use transform streams, wrap the original stream in a new readable stream
// and use pull to enqueue each chunk and report progress.
const reader = readableStream.getReader();
return new ReadableStream({
async pull(controller) {
var _a;
const { done, value } = await reader.read();
// When no more data needs to be consumed, break the reading
if (done || !value) {
onEnd === null || onEnd === void 0 ? void 0 : onEnd();
// Close the stream
controller.close();
reader.releaseLock();
return;
}
loadedBytes += (_a = value === null || value === void 0 ? void 0 : value.length) !== null && _a !== void 0 ? _a : 0;
// Enqueue the next data chunk into our target stream
controller.enqueue(value);
if (onProgress) {
onProgress({ loadedBytes });
}
},
cancel(reason) {
onEnd === null || onEnd === void 0 ? void 0 : onEnd();
return reader.cancel(reason);
},
});
}
}
/**
* Create a new HttpClient instance for the browser environment.
* @internal
*/
export function createFetchHttpClient() {
return new FetchHttpClient();
}
function isTransformStreamSupported(readableStream) {
return readableStream.pipeThrough !== undefined && self.TransformStream !== undefined;
}
//# sourceMappingURL=fetchHttpClient.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,7 @@
import type { HttpHeaders, RawHttpHeadersInput } from "./interfaces.js";
/**
* Creates an object that satisfies the `HttpHeaders` interface.
* @param rawHeaders - A simple object representing initial headers
*/
export declare function createHttpHeaders(rawHeaders?: RawHttpHeadersInput): HttpHeaders;
//# sourceMappingURL=httpHeaders.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"httpHeaders.d.ts","sourceRoot":"","sources":["../../src/httpHeaders.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAkB,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAiGxF;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,CAAC,EAAE,mBAAmB,GAAG,WAAW,CAE/E"}

View file

@ -0,0 +1,89 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
function normalizeName(name) {
return name.toLowerCase();
}
function* headerIterator(map) {
for (const entry of map.values()) {
yield [entry.name, entry.value];
}
}
class HttpHeadersImpl {
constructor(rawHeaders) {
this._headersMap = new Map();
if (rawHeaders) {
for (const headerName of Object.keys(rawHeaders)) {
this.set(headerName, rawHeaders[headerName]);
}
}
}
/**
* Set a header in this collection with the provided name and value. The name is
* case-insensitive.
* @param name - The name of the header to set. This value is case-insensitive.
* @param value - The value of the header to set.
*/
set(name, value) {
this._headersMap.set(normalizeName(name), { name, value: String(value).trim() });
}
/**
* Get the header value for the provided header name, or undefined if no header exists in this
* collection with the provided name.
* @param name - The name of the header. This value is case-insensitive.
*/
get(name) {
var _a;
return (_a = this._headersMap.get(normalizeName(name))) === null || _a === void 0 ? void 0 : _a.value;
}
/**
* Get whether or not this header collection contains a header entry for the provided header name.
* @param name - The name of the header to set. This value is case-insensitive.
*/
has(name) {
return this._headersMap.has(normalizeName(name));
}
/**
* Remove the header with the provided headerName.
* @param name - The name of the header to remove.
*/
delete(name) {
this._headersMap.delete(normalizeName(name));
}
/**
* Get the JSON object representation of this HTTP header collection.
*/
toJSON(options = {}) {
const result = {};
if (options.preserveCase) {
for (const entry of this._headersMap.values()) {
result[entry.name] = entry.value;
}
}
else {
for (const [normalizedName, entry] of this._headersMap) {
result[normalizedName] = entry.value;
}
}
return result;
}
/**
* Get the string representation of this HTTP header collection.
*/
toString() {
return JSON.stringify(this.toJSON({ preserveCase: true }));
}
/**
* Iterate over tuples of header [name, value] pairs.
*/
[Symbol.iterator]() {
return headerIterator(this._headersMap);
}
}
/**
* Creates an object that satisfies the `HttpHeaders` interface.
* @param rawHeaders - A simple object representing initial headers
*/
export function createHttpHeaders(rawHeaders) {
return new HttpHeadersImpl(rawHeaders);
}
//# sourceMappingURL=httpHeaders.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,40 @@
declare global {
interface FormData {
}
interface Blob {
}
interface File {
}
interface ReadableStream<R = any> {
}
interface TransformStream<I = any, O = any> {
}
}
export type { Agent, BodyPart, FormDataMap, FormDataValue, HttpClient, HttpHeaders, HttpMethods, KeyObject, MultipartRequestBody, PipelineRequest, PipelineResponse, PipelineRetryOptions, ProxySettings, PxfObject, RawHttpHeaders, RawHttpHeadersInput, RequestBodyType, SendRequest, TlsSettings, TransferProgressEvent, } from "./interfaces.js";
export { type AddPolicyOptions as AddPipelineOptions, type PipelinePhase, type PipelinePolicy, type Pipeline, createEmptyPipeline, } from "./pipeline.js";
export { createPipelineFromOptions, type TelemetryOptions, type InternalPipelineOptions, type PipelineOptions, } from "./createPipelineFromOptions.js";
export { createDefaultHttpClient } from "./defaultHttpClient.js";
export { createHttpHeaders } from "./httpHeaders.js";
export { createPipelineRequest, type PipelineRequestOptions } from "./pipelineRequest.js";
export { RestError, type RestErrorOptions, isRestError } from "./restError.js";
export { decompressResponsePolicy, decompressResponsePolicyName, } from "./policies/decompressResponsePolicy.js";
export { exponentialRetryPolicy, type ExponentialRetryPolicyOptions, exponentialRetryPolicyName, } from "./policies/exponentialRetryPolicy.js";
export { setClientRequestIdPolicy, setClientRequestIdPolicyName, } from "./policies/setClientRequestIdPolicy.js";
export { logPolicy, logPolicyName, type LogPolicyOptions } from "./policies/logPolicy.js";
export { multipartPolicy, multipartPolicyName } from "./policies/multipartPolicy.js";
export { proxyPolicy, proxyPolicyName, getDefaultProxySettings } from "./policies/proxyPolicy.js";
export { redirectPolicy, redirectPolicyName, type RedirectPolicyOptions, } from "./policies/redirectPolicy.js";
export { systemErrorRetryPolicy, type SystemErrorRetryPolicyOptions, systemErrorRetryPolicyName, } from "./policies/systemErrorRetryPolicy.js";
export { throttlingRetryPolicy, throttlingRetryPolicyName, type ThrottlingRetryPolicyOptions, } from "./policies/throttlingRetryPolicy.js";
export { retryPolicy, type RetryPolicyOptions } from "./policies/retryPolicy.js";
export type { RetryStrategy, RetryInformation, RetryModifiers, } from "./retryStrategies/retryStrategy.js";
export { tracingPolicy, tracingPolicyName, type TracingPolicyOptions, } from "./policies/tracingPolicy.js";
export { defaultRetryPolicy, type DefaultRetryPolicyOptions, } from "./policies/defaultRetryPolicy.js";
export { userAgentPolicy, userAgentPolicyName, type UserAgentPolicyOptions, } from "./policies/userAgentPolicy.js";
export { tlsPolicy, tlsPolicyName } from "./policies/tlsPolicy.js";
export { formDataPolicy, formDataPolicyName } from "./policies/formDataPolicy.js";
export { bearerTokenAuthenticationPolicy, type BearerTokenAuthenticationPolicyOptions, bearerTokenAuthenticationPolicyName, type ChallengeCallbacks, type AuthorizeRequestOptions, type AuthorizeRequestOnChallengeOptions, } from "./policies/bearerTokenAuthenticationPolicy.js";
export { ndJsonPolicy, ndJsonPolicyName } from "./policies/ndJsonPolicy.js";
export { auxiliaryAuthenticationHeaderPolicy, type AuxiliaryAuthenticationHeaderPolicyOptions, auxiliaryAuthenticationHeaderPolicyName, } from "./policies/auxiliaryAuthenticationHeaderPolicy.js";
export { createFile, createFileFromStream, type CreateFileOptions, type CreateFileFromStreamOptions, } from "./util/file.js";
//# sourceMappingURL=index.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,QAAQ;KAAG;IACrB,UAAU,IAAI;KAAG;IACjB,UAAU,IAAI;KAAG;IACjB,UAAU,cAAc,CAAC,CAAC,GAAG,GAAG;KAAI;IACpC,UAAU,eAAe,CAAC,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,GAAG;KAAI;CAC/C;AAGD,YAAY,EACV,KAAK,EACL,QAAQ,EACR,WAAW,EACX,aAAa,EACb,UAAU,EACV,WAAW,EACX,WAAW,EACX,SAAS,EACT,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,oBAAoB,EACpB,aAAa,EACb,SAAS,EACT,cAAc,EACd,mBAAmB,EACnB,eAAe,EACf,WAAW,EACX,WAAW,EACX,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,gBAAgB,IAAI,kBAAkB,EAC3C,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,QAAQ,EACb,mBAAmB,GACpB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,yBAAyB,EACzB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,EAC5B,KAAK,eAAe,GACrB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EACL,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,sBAAsB,EACtB,KAAK,6BAA6B,EAClC,0BAA0B,GAC3B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,wBAAwB,EACxB,4BAA4B,GAC7B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAClG,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,KAAK,qBAAqB,GAC3B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,sBAAsB,EACtB,KAAK,6BAA6B,EAClC,0BAA0B,GAC3B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,qBAAqB,EACrB,yBAAyB,EACzB,KAAK,4BAA4B,GAClC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACjF,YAAY,EACV,aAAa,EACb,gBAAgB,EAChB,cAAc,GACf,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EACL,aAAa,EACb,iBAAiB,EACjB,KAAK,oBAAoB,GAC1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,kBAAkB,EAClB,KAAK,yBAAyB,GAC/B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EACL,eAAe,EACf,mBAAmB,EACnB,KAAK,sBAAsB,GAC5B,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClF,OAAO,EACL,+BAA+B,EAC/B,KAAK,sCAAsC,EAC3C,mCAAmC,EACnC,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC5B,KAAK,kCAAkC,GACxC,MAAM,+CAA+C,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC5E,OAAO,EACL,mCAAmC,EACnC,KAAK,0CAA0C,EAC/C,uCAAuC,GACxC,MAAM,mDAAmD,CAAC;AAC3D,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,2BAA2B,GACjC,MAAM,gBAAgB,CAAC"}

View file

@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
export { createEmptyPipeline, } from "./pipeline.js";
export { createPipelineFromOptions, } from "./createPipelineFromOptions.js";
export { createDefaultHttpClient } from "./defaultHttpClient.js";
export { createHttpHeaders } from "./httpHeaders.js";
export { createPipelineRequest } from "./pipelineRequest.js";
export { RestError, isRestError } from "./restError.js";
export { decompressResponsePolicy, decompressResponsePolicyName, } from "./policies/decompressResponsePolicy.js";
export { exponentialRetryPolicy, exponentialRetryPolicyName, } from "./policies/exponentialRetryPolicy.js";
export { setClientRequestIdPolicy, setClientRequestIdPolicyName, } from "./policies/setClientRequestIdPolicy.js";
export { logPolicy, logPolicyName } from "./policies/logPolicy.js";
export { multipartPolicy, multipartPolicyName } from "./policies/multipartPolicy.js";
export { proxyPolicy, proxyPolicyName, getDefaultProxySettings } from "./policies/proxyPolicy.js";
export { redirectPolicy, redirectPolicyName, } from "./policies/redirectPolicy.js";
export { systemErrorRetryPolicy, systemErrorRetryPolicyName, } from "./policies/systemErrorRetryPolicy.js";
export { throttlingRetryPolicy, throttlingRetryPolicyName, } from "./policies/throttlingRetryPolicy.js";
export { retryPolicy } from "./policies/retryPolicy.js";
export { tracingPolicy, tracingPolicyName, } from "./policies/tracingPolicy.js";
export { defaultRetryPolicy, } from "./policies/defaultRetryPolicy.js";
export { userAgentPolicy, userAgentPolicyName, } from "./policies/userAgentPolicy.js";
export { tlsPolicy, tlsPolicyName } from "./policies/tlsPolicy.js";
export { formDataPolicy, formDataPolicyName } from "./policies/formDataPolicy.js";
export { bearerTokenAuthenticationPolicy, bearerTokenAuthenticationPolicyName, } from "./policies/bearerTokenAuthenticationPolicy.js";
export { ndJsonPolicy, ndJsonPolicyName } from "./policies/ndJsonPolicy.js";
export { auxiliaryAuthenticationHeaderPolicy, auxiliaryAuthenticationHeaderPolicyName, } from "./policies/auxiliaryAuthenticationHeaderPolicy.js";
export { createFile, createFileFromStream, } from "./util/file.js";
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,445 @@
import type { AbortSignalLike } from "@azure/abort-controller";
import type { OperationTracingOptions } from "@azure/core-tracing";
/**
* A HttpHeaders collection represented as a simple JSON object.
*/
export type RawHttpHeaders = {
[headerName: string]: string;
};
/**
* A HttpHeaders collection for input, represented as a simple JSON object.
*/
export type RawHttpHeadersInput = Record<string, string | number | boolean>;
/**
* Represents a set of HTTP headers on a request/response.
* Header names are treated as case insensitive.
*/
export interface HttpHeaders extends Iterable<[string, string]> {
/**
* Returns the value of a specific header or undefined if not set.
* @param name - The name of the header to retrieve.
*/
get(name: string): string | undefined;
/**
* Returns true if the specified header exists.
* @param name - The name of the header to check.
*/
has(name: string): boolean;
/**
* Sets a specific header with a given value.
* @param name - The name of the header to set.
* @param value - The value to use for the header.
*/
set(name: string, value: string | number | boolean): void;
/**
* Removes a specific header from the collection.
* @param name - The name of the header to delete.
*/
delete(name: string): void;
/**
* Accesses a raw JS object that acts as a simple map
* of header names to values.
*/
toJSON(options?: {
preserveCase?: boolean;
}): RawHttpHeaders;
}
/**
* A part of the request body in a multipart request.
*/
export interface BodyPart {
/**
* The headers for this part of the multipart request.
*/
headers: HttpHeaders;
/**
* The body of this part of the multipart request.
*/
body: ((() => ReadableStream<Uint8Array>) | (() => NodeJS.ReadableStream)) | ReadableStream<Uint8Array> | NodeJS.ReadableStream | Uint8Array | Blob;
}
/**
* A request body consisting of multiple parts.
*/
export interface MultipartRequestBody {
/**
* The parts of the request body.
*/
parts: BodyPart[];
/**
* The boundary separating each part of the request body.
* If not specified, a random boundary will be generated.
*
* When specified, '--' will be prepended to the boundary in the request to ensure the boundary follows the specification.
*/
boundary?: string;
}
/**
* Types of bodies supported on the request.
* NodeJS.ReadableStream and () =\> NodeJS.ReadableStream is Node only.
* Blob, ReadableStream<Uint8Array>, and () =\> ReadableStream<Uint8Array> are browser only.
*/
export type RequestBodyType = NodeJS.ReadableStream | (() => NodeJS.ReadableStream) | ReadableStream<Uint8Array> | (() => ReadableStream<Uint8Array>) | Blob | ArrayBuffer | ArrayBufferView | FormData | string | null;
/**
* An interface compatible with NodeJS's `http.Agent`.
* We want to avoid publicly re-exporting the actual interface,
* since it might vary across runtime versions.
*/
export interface Agent {
/**
* Destroy any sockets that are currently in use by the agent.
*/
destroy(): void;
/**
* For agents with keepAlive enabled, this sets the maximum number of sockets that will be left open in the free state.
*/
maxFreeSockets: number;
/**
* Determines how many concurrent sockets the agent can have open per origin.
*/
maxSockets: number;
/**
* An object which contains queues of requests that have not yet been assigned to sockets.
*/
requests: unknown;
/**
* An object which contains arrays of sockets currently in use by the agent.
*/
sockets: unknown;
}
/**
* Metadata about a request being made by the pipeline.
*/
export interface PipelineRequest {
/**
* The URL to make the request to.
*/
url: string;
/**
* The HTTP method to use when making the request.
*/
method: HttpMethods;
/**
* The HTTP headers to use when making the request.
*/
headers: HttpHeaders;
/**
* The number of milliseconds a request can take before automatically being terminated.
* If the request is terminated, an `AbortError` is thrown.
* Defaults to 0, which disables the timeout.
*/
timeout: number;
/**
* Indicates whether the user agent should send cookies from the other domain in the case of cross-origin requests.
* Defaults to false.
*/
withCredentials: boolean;
/**
* A unique identifier for the request. Used for logging and tracing.
*/
requestId: string;
/**
* The HTTP body content (if any)
*/
body?: RequestBodyType;
/**
* Body for a multipart request.
*/
multipartBody?: MultipartRequestBody;
/**
* To simulate a browser form post
*/
formData?: FormDataMap;
/**
* A list of response status codes whose corresponding PipelineResponse body should be treated as a stream.
* When streamResponseStatusCodes contains the value Number.POSITIVE_INFINITY any status would be treated as a stream.
*/
streamResponseStatusCodes?: Set<number>;
/**
* Proxy configuration.
*/
proxySettings?: ProxySettings;
/**
* If the connection should not be reused.
*/
disableKeepAlive?: boolean;
/**
* Used to abort the request later.
*/
abortSignal?: AbortSignalLike;
/**
* Tracing options to use for any created Spans.
*/
tracingOptions?: OperationTracingOptions;
/**
* Callback which fires upon upload progress.
*/
onUploadProgress?: (progress: TransferProgressEvent) => void;
/** Callback which fires upon download progress. */
onDownloadProgress?: (progress: TransferProgressEvent) => void;
/** Set to true if the request is sent over HTTP instead of HTTPS */
allowInsecureConnection?: boolean;
/**
* NODEJS ONLY
*
* A Node-only option to provide a custom `http.Agent`/`https.Agent`.
* Does nothing when running in the browser.
*/
agent?: Agent;
/**
* BROWSER ONLY
*
* A browser only option to enable browser Streams. If this option is set and a response is a stream
* the response will have a property `browserStream` instead of `blobBody` which will be undefined.
*
* Default value is false
*/
enableBrowserStreams?: boolean;
/** Settings for configuring TLS authentication */
tlsSettings?: TlsSettings;
}
/**
* Metadata about a response received by the pipeline.
*/
export interface PipelineResponse {
/**
* The request that generated this response.
*/
request: PipelineRequest;
/**
* The HTTP status code of the response.
*/
status: number;
/**
* The HTTP response headers.
*/
headers: HttpHeaders;
/**
* The response body as text (string format)
*/
bodyAsText?: string | null;
/**
* BROWSER ONLY
*
* The response body as a browser Blob.
* Always undefined in node.js.
*/
blobBody?: Promise<Blob>;
/**
* BROWSER ONLY
*
* The response body as a browser ReadableStream.
* Always undefined in node.js.
*/
browserStreamBody?: ReadableStream<Uint8Array>;
/**
* NODEJS ONLY
*
* The response body as a node.js Readable stream.
* Always undefined in the browser.
*/
readableStreamBody?: NodeJS.ReadableStream;
}
/**
* A simple interface for making a pipeline request and receiving a response.
*/
export type SendRequest = (request: PipelineRequest) => Promise<PipelineResponse>;
/**
* The required interface for a client that makes HTTP requests
* on behalf of a pipeline.
*/
export interface HttpClient {
/**
* The method that makes the request and returns a response.
*/
sendRequest: SendRequest;
}
/**
* Fired in response to upload or download progress.
*/
export type TransferProgressEvent = {
/**
* The number of bytes loaded so far.
*/
loadedBytes: number;
};
/**
* Supported HTTP methods to use when making requests.
*/
export type HttpMethods = "GET" | "PUT" | "POST" | "DELETE" | "PATCH" | "HEAD" | "OPTIONS" | "TRACE";
/**
* Options to configure a proxy for outgoing requests (Node.js only).
*/
export interface ProxySettings {
/**
* The proxy's host address.
*/
host: string;
/**
* The proxy host's port.
*/
port: number;
/**
* The user name to authenticate with the proxy, if required.
*/
username?: string;
/**
* The password to authenticate with the proxy, if required.
*/
password?: string;
}
/**
* Each form data entry can be a string, Blob, or a File. If you wish to pass a file with a name but do not have
* access to the File class, you can use the createFile helper to create one.
*/
export type FormDataValue = string | Blob | File;
/**
* A simple object that provides form data, as if from a browser form.
*/
export type FormDataMap = {
[key: string]: FormDataValue | FormDataValue[];
};
/**
* Options that control how to retry failed requests.
*/
export interface PipelineRetryOptions {
/**
* The maximum number of retry attempts. Defaults to 3.
*/
maxRetries?: number;
/**
* The amount of delay in milliseconds between retry attempts. Defaults to 1000
* (1 second). The delay increases exponentially with each retry up to a maximum
* specified by maxRetryDelayInMs.
*/
retryDelayInMs?: number;
/**
* The maximum delay in milliseconds allowed before retrying an operation. Defaults
* to 64000 (64 seconds).
*/
maxRetryDelayInMs?: number;
}
/**
* Represents a certificate credential for authentication.
*/
export interface CertificateCredential {
/**
* Optionally override the trusted CA certificates. Default is to trust
* the well-known CAs curated by Mozilla. Mozilla's CAs are completely
* replaced when CAs are explicitly specified using this option.
*/
ca?: string | Buffer | Array<string | Buffer> | undefined;
/**
* Cert chains in PEM format. One cert chain should be provided per
* private key. Each cert chain should consist of the PEM formatted
* certificate for a provided private key, followed by the PEM
* formatted intermediate certificates (if any), in order, and not
* including the root CA (the root CA must be pre-known to the peer,
* see ca). When providing multiple cert chains, they do not have to
* be in the same order as their private keys in key. If the
* intermediate certificates are not provided, the peer will not be
* able to validate the certificate, and the handshake will fail.
*/
cert?: string | Buffer | Array<string | Buffer> | undefined;
/**
* Private keys in PEM format. PEM allows the option of private keys
* being encrypted. Encrypted keys will be decrypted with
* options.passphrase. Multiple keys using different algorithms can be
* provided either as an array of unencrypted key strings or buffers,
* or an array of objects in the form `{pem: <string|buffer>[,passphrase: <string>]}`.
* The object form can only occur in an array.object.passphrase is optional.
* Encrypted keys will be decrypted with object.passphrase if provided, or options.passphrase if it is not.
*/
key?: string | Buffer | Array<Buffer | KeyObject> | undefined;
/**
* Shared passphrase used for a single private key and/or a PFX.
*/
passphrase?: string | undefined;
/**
* PFX or PKCS12 encoded private key and certificate chain. pfx is an
* alternative to providing key and cert individually. PFX is usually
* encrypted, if it is, passphrase will be used to decrypt it. Multiple
* PFX can be provided either as an array of unencrypted PFX buffers,
* or an array of objects in the form `{buf: <string|buffer>[,passphrase: <string>]}`.
* The object form can only occur in an array.object.passphrase is optional.
* Encrypted PFX will be decrypted with object.passphrase if provided, or options.passphrase if it is not.
*/
pfx?: string | Buffer | Array<string | Buffer | PxfObject> | undefined;
}
/**
* Represents a certificate for TLS authentication.
*/
export interface TlsSettings {
/**
* Optionally override the trusted CA certificates. Default is to trust
* the well-known CAs curated by Mozilla. Mozilla's CAs are completely
* replaced when CAs are explicitly specified using this option.
*/
ca?: string | Buffer | Array<string | Buffer> | undefined;
/**
* Cert chains in PEM format. One cert chain should be provided per
* private key. Each cert chain should consist of the PEM formatted
* certificate for a provided private key, followed by the PEM
* formatted intermediate certificates (if any), in order, and not
* including the root CA (the root CA must be pre-known to the peer,
* see ca). When providing multiple cert chains, they do not have to
* be in the same order as their private keys in key. If the
* intermediate certificates are not provided, the peer will not be
* able to validate the certificate, and the handshake will fail.
*/
cert?: string | Buffer | Array<string | Buffer> | undefined;
/**
* Private keys in PEM format. PEM allows the option of private keys
* being encrypted. Encrypted keys will be decrypted with
* options.passphrase. Multiple keys using different algorithms can be
* provided either as an array of unencrypted key strings or buffers,
* or an array of objects in the form `{pem: <string|buffer>[,passphrase: <string>]}`.
* The object form can only occur in an array.object.passphrase is optional.
* Encrypted keys will be decrypted with object.passphrase if provided, or options.passphrase if it is not.
*/
key?: string | Buffer | Array<Buffer | KeyObject> | undefined;
/**
* Shared passphrase used for a single private key and/or a PFX.
*/
passphrase?: string | undefined;
/**
* PFX or PKCS12 encoded private key and certificate chain. pfx is an
* alternative to providing key and cert individually. PFX is usually
* encrypted, if it is, passphrase will be used to decrypt it. Multiple
* PFX can be provided either as an array of unencrypted PFX buffers,
* or an array of objects in the form `{buf: <string|buffer>[,passphrase: <string>]}`.
* The object form can only occur in an array.object.passphrase is optional.
* Encrypted PFX will be decrypted with object.passphrase if provided, or options.passphrase if it is not.
*/
pfx?: string | Buffer | Array<string | Buffer | PxfObject> | undefined;
}
/**
* An interface compatible with NodeJS's `tls.KeyObject`.
* We want to avoid publicly re-exporting the actual interface,
* since it might vary across runtime versions.
*/
export interface KeyObject {
/**
* Private keys in PEM format.
*/
pem: string | Buffer;
/**
* Optional passphrase.
*/
passphrase?: string | undefined;
}
/**
* An interface compatible with NodeJS's `tls.PxfObject`.
* We want to avoid publicly re-exporting the actual interface,
* since it might vary across runtime versions.
*/
export interface PxfObject {
/**
* PFX or PKCS12 encoded private key and certificate chain.
*/
buf: string | Buffer;
/**
* Optional passphrase.
*/
passphrase?: string | undefined;
}
//# sourceMappingURL=interfaces.d.ts.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
export {};
//# sourceMappingURL=interfaces.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,2 @@
export declare const logger: import("@azure/logger").AzureLogger;
//# sourceMappingURL=log.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/log.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,MAAM,qCAA2C,CAAC"}

View file

@ -0,0 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { createClientLogger } from "@azure/logger";
export const logger = createClientLogger("core-rest-pipeline");
//# sourceMappingURL=log.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/log.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,MAAM,CAAC,MAAM,MAAM,GAAG,kBAAkB,CAAC,oBAAoB,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport { createClientLogger } from \"@azure/logger\";\nexport const logger = createClientLogger(\"core-rest-pipeline\");\n"]}

View file

@ -0,0 +1,9 @@
import type { HttpClient, RequestBodyType } from "./interfaces.js";
/** @internal */
export declare function getBodyLength(body: RequestBodyType): number | null;
/**
* Create a new HttpClient instance for the NodeJS environment.
* @internal
*/
export declare function createNodeHttpClient(): HttpClient;
//# sourceMappingURL=nodeHttpClient.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"nodeHttpClient.d.ts","sourceRoot":"","sources":["../../src/nodeHttpClient.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,UAAU,EAIV,eAAe,EAGhB,MAAM,iBAAiB,CAAC;AA4VzB,gBAAgB;AAChB,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAclE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,IAAI,UAAU,CAEjD"}

View file

@ -0,0 +1,338 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import * as http from "node:http";
import * as https from "node:https";
import * as zlib from "node:zlib";
import { Transform } from "node:stream";
import { AbortError } from "@azure/abort-controller";
import { createHttpHeaders } from "./httpHeaders.js";
import { RestError } from "./restError.js";
import { logger } from "./log.js";
const DEFAULT_TLS_SETTINGS = {};
function isReadableStream(body) {
return body && typeof body.pipe === "function";
}
function isStreamComplete(stream) {
return new Promise((resolve) => {
const handler = () => {
resolve();
stream.removeListener("close", handler);
stream.removeListener("end", handler);
stream.removeListener("error", handler);
};
stream.on("close", handler);
stream.on("end", handler);
stream.on("error", handler);
});
}
function isArrayBuffer(body) {
return body && typeof body.byteLength === "number";
}
class ReportTransform extends Transform {
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
_transform(chunk, _encoding, callback) {
this.push(chunk);
this.loadedBytes += chunk.length;
try {
this.progressCallback({ loadedBytes: this.loadedBytes });
callback();
}
catch (e) {
callback(e);
}
}
constructor(progressCallback) {
super();
this.loadedBytes = 0;
this.progressCallback = progressCallback;
}
}
/**
* A HttpClient implementation that uses Node's "https" module to send HTTPS requests.
* @internal
*/
class NodeHttpClient {
constructor() {
this.cachedHttpsAgents = new WeakMap();
}
/**
* Makes a request over an underlying transport layer and returns the response.
* @param request - The request to be made.
*/
async sendRequest(request) {
var _a, _b, _c;
const abortController = new AbortController();
let abortListener;
if (request.abortSignal) {
if (request.abortSignal.aborted) {
throw new AbortError("The operation was aborted.");
}
abortListener = (event) => {
if (event.type === "abort") {
abortController.abort();
}
};
request.abortSignal.addEventListener("abort", abortListener);
}
if (request.timeout > 0) {
setTimeout(() => {
abortController.abort();
}, request.timeout);
}
const acceptEncoding = request.headers.get("Accept-Encoding");
const shouldDecompress = (acceptEncoding === null || acceptEncoding === void 0 ? void 0 : acceptEncoding.includes("gzip")) || (acceptEncoding === null || acceptEncoding === void 0 ? void 0 : acceptEncoding.includes("deflate"));
let body = typeof request.body === "function" ? request.body() : request.body;
if (body && !request.headers.has("Content-Length")) {
const bodyLength = getBodyLength(body);
if (bodyLength !== null) {
request.headers.set("Content-Length", bodyLength);
}
}
let responseStream;
try {
if (body && request.onUploadProgress) {
const onUploadProgress = request.onUploadProgress;
const uploadReportStream = new ReportTransform(onUploadProgress);
uploadReportStream.on("error", (e) => {
logger.error("Error in upload progress", e);
});
if (isReadableStream(body)) {
body.pipe(uploadReportStream);
}
else {
uploadReportStream.end(body);
}
body = uploadReportStream;
}
const res = await this.makeRequest(request, abortController, body);
const headers = getResponseHeaders(res);
const status = (_a = res.statusCode) !== null && _a !== void 0 ? _a : 0;
const response = {
status,
headers,
request,
};
// Responses to HEAD must not have a body.
// If they do return a body, that body must be ignored.
if (request.method === "HEAD") {
// call resume() and not destroy() to avoid closing the socket
// and losing keep alive
res.resume();
return response;
}
responseStream = shouldDecompress ? getDecodedResponseStream(res, headers) : res;
const onDownloadProgress = request.onDownloadProgress;
if (onDownloadProgress) {
const downloadReportStream = new ReportTransform(onDownloadProgress);
downloadReportStream.on("error", (e) => {
logger.error("Error in download progress", e);
});
responseStream.pipe(downloadReportStream);
responseStream = downloadReportStream;
}
if (
// Value of POSITIVE_INFINITY in streamResponseStatusCodes is considered as any status code
((_b = request.streamResponseStatusCodes) === null || _b === void 0 ? void 0 : _b.has(Number.POSITIVE_INFINITY)) ||
((_c = request.streamResponseStatusCodes) === null || _c === void 0 ? void 0 : _c.has(response.status))) {
response.readableStreamBody = responseStream;
}
else {
response.bodyAsText = await streamToText(responseStream);
}
return response;
}
finally {
// clean up event listener
if (request.abortSignal && abortListener) {
let uploadStreamDone = Promise.resolve();
if (isReadableStream(body)) {
uploadStreamDone = isStreamComplete(body);
}
let downloadStreamDone = Promise.resolve();
if (isReadableStream(responseStream)) {
downloadStreamDone = isStreamComplete(responseStream);
}
Promise.all([uploadStreamDone, downloadStreamDone])
.then(() => {
var _a;
// eslint-disable-next-line promise/always-return
if (abortListener) {
(_a = request.abortSignal) === null || _a === void 0 ? void 0 : _a.removeEventListener("abort", abortListener);
}
})
.catch((e) => {
logger.warning("Error when cleaning up abortListener on httpRequest", e);
});
}
}
}
makeRequest(request, abortController, body) {
var _a;
const url = new URL(request.url);
const isInsecure = url.protocol !== "https:";
if (isInsecure && !request.allowInsecureConnection) {
throw new Error(`Cannot connect to ${request.url} while allowInsecureConnection is false.`);
}
const agent = (_a = request.agent) !== null && _a !== void 0 ? _a : this.getOrCreateAgent(request, isInsecure);
const options = {
agent,
hostname: url.hostname,
path: `${url.pathname}${url.search}`,
port: url.port,
method: request.method,
headers: request.headers.toJSON({ preserveCase: true }),
};
return new Promise((resolve, reject) => {
const req = isInsecure ? http.request(options, resolve) : https.request(options, resolve);
req.once("error", (err) => {
var _a;
reject(new RestError(err.message, { code: (_a = err.code) !== null && _a !== void 0 ? _a : RestError.REQUEST_SEND_ERROR, request }));
});
abortController.signal.addEventListener("abort", () => {
const abortError = new AbortError("The operation was aborted.");
req.destroy(abortError);
reject(abortError);
});
if (body && isReadableStream(body)) {
body.pipe(req);
}
else if (body) {
if (typeof body === "string" || Buffer.isBuffer(body)) {
req.end(body);
}
else if (isArrayBuffer(body)) {
req.end(ArrayBuffer.isView(body) ? Buffer.from(body.buffer) : Buffer.from(body));
}
else {
logger.error("Unrecognized body type", body);
reject(new RestError("Unrecognized body type"));
}
}
else {
// streams don't like "undefined" being passed as data
req.end();
}
});
}
getOrCreateAgent(request, isInsecure) {
var _a;
const disableKeepAlive = request.disableKeepAlive;
// Handle Insecure requests first
if (isInsecure) {
if (disableKeepAlive) {
// keepAlive:false is the default so we don't need a custom Agent
return http.globalAgent;
}
if (!this.cachedHttpAgent) {
// If there is no cached agent create a new one and cache it.
this.cachedHttpAgent = new http.Agent({ keepAlive: true });
}
return this.cachedHttpAgent;
}
else {
if (disableKeepAlive && !request.tlsSettings) {
// When there are no tlsSettings and keepAlive is false
// we don't need a custom agent
return https.globalAgent;
}
// We use the tlsSettings to index cached clients
const tlsSettings = (_a = request.tlsSettings) !== null && _a !== void 0 ? _a : DEFAULT_TLS_SETTINGS;
// Get the cached agent or create a new one with the
// provided values for keepAlive and tlsSettings
let agent = this.cachedHttpsAgents.get(tlsSettings);
if (agent && agent.options.keepAlive === !disableKeepAlive) {
return agent;
}
logger.info("No cached TLS Agent exist, creating a new Agent");
agent = new https.Agent(Object.assign({
// keepAlive is true if disableKeepAlive is false.
keepAlive: !disableKeepAlive }, tlsSettings));
this.cachedHttpsAgents.set(tlsSettings, agent);
return agent;
}
}
}
function getResponseHeaders(res) {
const headers = createHttpHeaders();
for (const header of Object.keys(res.headers)) {
const value = res.headers[header];
if (Array.isArray(value)) {
if (value.length > 0) {
headers.set(header, value[0]);
}
}
else if (value) {
headers.set(header, value);
}
}
return headers;
}
function getDecodedResponseStream(stream, headers) {
const contentEncoding = headers.get("Content-Encoding");
if (contentEncoding === "gzip") {
const unzip = zlib.createGunzip();
stream.pipe(unzip);
return unzip;
}
else if (contentEncoding === "deflate") {
const inflate = zlib.createInflate();
stream.pipe(inflate);
return inflate;
}
return stream;
}
function streamToText(stream) {
return new Promise((resolve, reject) => {
const buffer = [];
stream.on("data", (chunk) => {
if (Buffer.isBuffer(chunk)) {
buffer.push(chunk);
}
else {
buffer.push(Buffer.from(chunk));
}
});
stream.on("end", () => {
resolve(Buffer.concat(buffer).toString("utf8"));
});
stream.on("error", (e) => {
if (e && (e === null || e === void 0 ? void 0 : e.name) === "AbortError") {
reject(e);
}
else {
reject(new RestError(`Error reading response as text: ${e.message}`, {
code: RestError.PARSE_ERROR,
}));
}
});
});
}
/** @internal */
export function getBodyLength(body) {
if (!body) {
return 0;
}
else if (Buffer.isBuffer(body)) {
return body.length;
}
else if (isReadableStream(body)) {
return null;
}
else if (isArrayBuffer(body)) {
return body.byteLength;
}
else if (typeof body === "string") {
return Buffer.from(body).length;
}
else {
return null;
}
}
/**
* Create a new HttpClient instance for the NodeJS environment.
* @internal
*/
export function createNodeHttpClient() {
return new NodeHttpClient();
}
//# sourceMappingURL=nodeHttpClient.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,3 @@
{
"type": "module"
}

View file

@ -0,0 +1,93 @@
import type { HttpClient, PipelineRequest, PipelineResponse, SendRequest } from "./interfaces.js";
/**
* Policies are executed in phases.
* The execution order is:
* 1. Serialize Phase
* 2. Policies not in a phase
* 3. Deserialize Phase
* 4. Retry Phase
* 5. Sign Phase
*/
export type PipelinePhase = "Deserialize" | "Serialize" | "Retry" | "Sign";
/**
* Options when adding a policy to the pipeline.
* Used to express dependencies on other policies.
*/
export interface AddPolicyOptions {
/**
* Policies that this policy must come before.
*/
beforePolicies?: string[];
/**
* Policies that this policy must come after.
*/
afterPolicies?: string[];
/**
* The phase that this policy must come after.
*/
afterPhase?: PipelinePhase;
/**
* The phase this policy belongs to.
*/
phase?: PipelinePhase;
}
/**
* A pipeline policy manipulates a request as it travels through the pipeline.
* It is conceptually a middleware that is allowed to modify the request before
* it is made as well as the response when it is received.
*/
export interface PipelinePolicy {
/**
* The policy name. Must be a unique string in the pipeline.
*/
name: string;
/**
* The main method to implement that manipulates a request/response.
* @param request - The request being performed.
* @param next - The next policy in the pipeline. Must be called to continue the pipeline.
*/
sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse>;
}
/**
* Represents a pipeline for making a HTTP request to a URL.
* Pipelines can have multiple policies to manage manipulating each request
* before and after it is made to the server.
*/
export interface Pipeline {
/**
* Add a new policy to the pipeline.
* @param policy - A policy that manipulates a request.
* @param options - A set of options for when the policy should run.
*/
addPolicy(policy: PipelinePolicy, options?: AddPolicyOptions): void;
/**
* Remove a policy from the pipeline.
* @param options - Options that let you specify which policies to remove.
*/
removePolicy(options: {
name?: string;
phase?: PipelinePhase;
}): PipelinePolicy[];
/**
* Uses the pipeline to make a HTTP request.
* @param httpClient - The HttpClient that actually performs the request.
* @param request - The request to be made.
*/
sendRequest(httpClient: HttpClient, request: PipelineRequest): Promise<PipelineResponse>;
/**
* Returns the current set of policies in the pipeline in the order in which
* they will be applied to the request. Later in the list is closer to when
* the request is performed.
*/
getOrderedPolicies(): PipelinePolicy[];
/**
* Duplicates this pipeline to allow for modifying an existing one without mutating it.
*/
clone(): Pipeline;
}
/**
* Creates a totally empty pipeline.
* Useful for testing or creating a custom one.
*/
export declare function createEmptyPipeline(): Pipeline;
//# sourceMappingURL=pipeline.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../../src/pipeline.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAElG;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAI3E;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB;;OAEG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAC3B;;OAEG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,WAAW,CAAC,OAAO,EAAE,eAAe,EAAE,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACrF;AAED;;;;GAIG;AACH,MAAM,WAAW,QAAQ;IACvB;;;;OAIG;IACH,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpE;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,aAAa,CAAA;KAAE,GAAG,cAAc,EAAE,CAAC;IAClF;;;;OAIG;IACH,WAAW,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACzF;;;;OAIG;IACH,kBAAkB,IAAI,cAAc,EAAE,CAAC;IACvC;;OAEG;IACH,KAAK,IAAI,QAAQ,CAAC;CACnB;AA0SD;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,CAE9C"}

View file

@ -0,0 +1,262 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
const ValidPhaseNames = new Set(["Deserialize", "Serialize", "Retry", "Sign"]);
/**
* A private implementation of Pipeline.
* Do not export this class from the package.
* @internal
*/
class HttpPipeline {
constructor(policies) {
var _a;
this._policies = [];
this._policies = (_a = policies === null || policies === void 0 ? void 0 : policies.slice(0)) !== null && _a !== void 0 ? _a : [];
this._orderedPolicies = undefined;
}
addPolicy(policy, options = {}) {
if (options.phase && options.afterPhase) {
throw new Error("Policies inside a phase cannot specify afterPhase.");
}
if (options.phase && !ValidPhaseNames.has(options.phase)) {
throw new Error(`Invalid phase name: ${options.phase}`);
}
if (options.afterPhase && !ValidPhaseNames.has(options.afterPhase)) {
throw new Error(`Invalid afterPhase name: ${options.afterPhase}`);
}
this._policies.push({
policy,
options,
});
this._orderedPolicies = undefined;
}
removePolicy(options) {
const removedPolicies = [];
this._policies = this._policies.filter((policyDescriptor) => {
if ((options.name && policyDescriptor.policy.name === options.name) ||
(options.phase && policyDescriptor.options.phase === options.phase)) {
removedPolicies.push(policyDescriptor.policy);
return false;
}
else {
return true;
}
});
this._orderedPolicies = undefined;
return removedPolicies;
}
sendRequest(httpClient, request) {
const policies = this.getOrderedPolicies();
const pipeline = policies.reduceRight((next, policy) => {
return (req) => {
return policy.sendRequest(req, next);
};
}, (req) => httpClient.sendRequest(req));
return pipeline(request);
}
getOrderedPolicies() {
if (!this._orderedPolicies) {
this._orderedPolicies = this.orderPolicies();
}
return this._orderedPolicies;
}
clone() {
return new HttpPipeline(this._policies);
}
static create() {
return new HttpPipeline();
}
orderPolicies() {
/**
* The goal of this method is to reliably order pipeline policies
* based on their declared requirements when they were added.
*
* Order is first determined by phase:
*
* 1. Serialize Phase
* 2. Policies not in a phase
* 3. Deserialize Phase
* 4. Retry Phase
* 5. Sign Phase
*
* Within each phase, policies are executed in the order
* they were added unless they were specified to execute
* before/after other policies or after a particular phase.
*
* To determine the final order, we will walk the policy list
* in phase order multiple times until all dependencies are
* satisfied.
*
* `afterPolicies` are the set of policies that must be
* executed before a given policy. This requirement is
* considered satisfied when each of the listed policies
* have been scheduled.
*
* `beforePolicies` are the set of policies that must be
* executed after a given policy. Since this dependency
* can be expressed by converting it into a equivalent
* `afterPolicies` declarations, they are normalized
* into that form for simplicity.
*
* An `afterPhase` dependency is considered satisfied when all
* policies in that phase have scheduled.
*
*/
const result = [];
// Track all policies we know about.
const policyMap = new Map();
function createPhase(name) {
return {
name,
policies: new Set(),
hasRun: false,
hasAfterPolicies: false,
};
}
// Track policies for each phase.
const serializePhase = createPhase("Serialize");
const noPhase = createPhase("None");
const deserializePhase = createPhase("Deserialize");
const retryPhase = createPhase("Retry");
const signPhase = createPhase("Sign");
// a list of phases in order
const orderedPhases = [serializePhase, noPhase, deserializePhase, retryPhase, signPhase];
// Small helper function to map phase name to each Phase
function getPhase(phase) {
if (phase === "Retry") {
return retryPhase;
}
else if (phase === "Serialize") {
return serializePhase;
}
else if (phase === "Deserialize") {
return deserializePhase;
}
else if (phase === "Sign") {
return signPhase;
}
else {
return noPhase;
}
}
// First walk each policy and create a node to track metadata.
for (const descriptor of this._policies) {
const policy = descriptor.policy;
const options = descriptor.options;
const policyName = policy.name;
if (policyMap.has(policyName)) {
throw new Error("Duplicate policy names not allowed in pipeline");
}
const node = {
policy,
dependsOn: new Set(),
dependants: new Set(),
};
if (options.afterPhase) {
node.afterPhase = getPhase(options.afterPhase);
node.afterPhase.hasAfterPolicies = true;
}
policyMap.set(policyName, node);
const phase = getPhase(options.phase);
phase.policies.add(node);
}
// Now that each policy has a node, connect dependency references.
for (const descriptor of this._policies) {
const { policy, options } = descriptor;
const policyName = policy.name;
const node = policyMap.get(policyName);
if (!node) {
throw new Error(`Missing node for policy ${policyName}`);
}
if (options.afterPolicies) {
for (const afterPolicyName of options.afterPolicies) {
const afterNode = policyMap.get(afterPolicyName);
if (afterNode) {
// Linking in both directions helps later
// when we want to notify dependants.
node.dependsOn.add(afterNode);
afterNode.dependants.add(node);
}
}
}
if (options.beforePolicies) {
for (const beforePolicyName of options.beforePolicies) {
const beforeNode = policyMap.get(beforePolicyName);
if (beforeNode) {
// To execute before another node, make it
// depend on the current node.
beforeNode.dependsOn.add(node);
node.dependants.add(beforeNode);
}
}
}
}
function walkPhase(phase) {
phase.hasRun = true;
// Sets iterate in insertion order
for (const node of phase.policies) {
if (node.afterPhase && (!node.afterPhase.hasRun || node.afterPhase.policies.size)) {
// If this node is waiting on a phase to complete,
// we need to skip it for now.
// Even if the phase is empty, we should wait for it
// to be walked to avoid re-ordering policies.
continue;
}
if (node.dependsOn.size === 0) {
// If there's nothing else we're waiting for, we can
// add this policy to the result list.
result.push(node.policy);
// Notify anything that depends on this policy that
// the policy has been scheduled.
for (const dependant of node.dependants) {
dependant.dependsOn.delete(node);
}
policyMap.delete(node.policy.name);
phase.policies.delete(node);
}
}
}
function walkPhases() {
for (const phase of orderedPhases) {
walkPhase(phase);
// if the phase isn't complete
if (phase.policies.size > 0 && phase !== noPhase) {
if (!noPhase.hasRun) {
// Try running noPhase to see if that unblocks this phase next tick.
// This can happen if a phase that happens before noPhase
// is waiting on a noPhase policy to complete.
walkPhase(noPhase);
}
// Don't proceed to the next phase until this phase finishes.
return;
}
if (phase.hasAfterPolicies) {
// Run any policies unblocked by this phase
walkPhase(noPhase);
}
}
}
// Iterate until we've put every node in the result list.
let iteration = 0;
while (policyMap.size > 0) {
iteration++;
const initialResultLength = result.length;
// Keep walking each phase in order until we can order every node.
walkPhases();
// The result list *should* get at least one larger each time
// after the first full pass.
// Otherwise, we're going to loop forever.
if (result.length <= initialResultLength && iteration > 1) {
throw new Error("Cannot satisfy policy dependencies due to requirements cycle.");
}
}
return result;
}
}
/**
* Creates a totally empty pipeline.
* Useful for testing or creating a custom one.
*/
export function createEmptyPipeline() {
return HttpPipeline.create();
}
//# sourceMappingURL=pipeline.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,93 @@
import type { FormDataMap, HttpHeaders, HttpMethods, MultipartRequestBody, PipelineRequest, ProxySettings, RequestBodyType, TransferProgressEvent } from "./interfaces.js";
import type { AbortSignalLike } from "@azure/abort-controller";
import type { OperationTracingOptions } from "@azure/core-tracing";
/**
* Settings to initialize a request.
* Almost equivalent to Partial<PipelineRequest>, but url is mandatory.
*/
export interface PipelineRequestOptions {
/**
* The URL to make the request to.
*/
url: string;
/**
* The HTTP method to use when making the request.
*/
method?: HttpMethods;
/**
* The HTTP headers to use when making the request.
*/
headers?: HttpHeaders;
/**
* The number of milliseconds a request can take before automatically being terminated.
* If the request is terminated, an `AbortError` is thrown.
* Defaults to 0, which disables the timeout.
*/
timeout?: number;
/**
* If credentials (cookies) should be sent along during an XHR.
* Defaults to false.
*/
withCredentials?: boolean;
/**
* A unique identifier for the request. Used for logging and tracing.
*/
requestId?: string;
/**
* The HTTP body content (if any)
*/
body?: RequestBodyType;
/**
* Body for a multipart request.
*/
multipartBody?: MultipartRequestBody;
/**
* To simulate a browser form post
*/
formData?: FormDataMap;
/**
* A list of response status codes whose corresponding PipelineResponse body should be treated as a stream.
*/
streamResponseStatusCodes?: Set<number>;
/**
* BROWSER ONLY
*
* A browser only option to enable use of the Streams API. If this option is set and streaming is used
* (see `streamResponseStatusCodes`), the response will have a property `browserStream` instead of
* `blobBody` which will be undefined.
*
* Default value is false
*/
enableBrowserStreams?: boolean;
/**
* Proxy configuration.
*/
proxySettings?: ProxySettings;
/**
* If the connection should not be reused.
*/
disableKeepAlive?: boolean;
/**
* Used to abort the request later.
*/
abortSignal?: AbortSignalLike;
/**
* Options used to create a span when tracing is enabled.
*/
tracingOptions?: OperationTracingOptions;
/**
* Callback which fires upon upload progress.
*/
onUploadProgress?: (progress: TransferProgressEvent) => void;
/** Callback which fires upon download progress. */
onDownloadProgress?: (progress: TransferProgressEvent) => void;
/** Set to true if the request is sent over HTTP instead of HTTPS */
allowInsecureConnection?: boolean;
}
/**
* Creates a new pipeline request with the given options.
* This method is to allow for the easy setting of default values and not required.
* @param options - The options to create the request with.
*/
export declare function createPipelineRequest(options: PipelineRequestOptions): PipelineRequest;
//# sourceMappingURL=pipelineRequest.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"pipelineRequest.d.ts","sourceRoot":"","sources":["../../src/pipelineRequest.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,aAAa,EACb,eAAe,EACf,qBAAqB,EACtB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB;;OAEG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,IAAI,CAAC,EAAE,eAAe,CAAC;IAEvB;;OAEG;IACH,aAAa,CAAC,EAAE,oBAAoB,CAAC;IAErC;;OAEG;IACH,QAAQ,CAAC,EAAE,WAAW,CAAC;IAEvB;;OAEG;IACH,yBAAyB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAExC;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B;;OAEG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,WAAW,CAAC,EAAE,eAAe,CAAC;IAE9B;;OAEG;IACH,cAAc,CAAC,EAAE,uBAAuB,CAAC;IAEzC;;OAEG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAE7D,mDAAmD;IACnD,kBAAkB,CAAC,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,IAAI,CAAC;IAE/D,oEAAoE;IACpE,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AA6CD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,GAAG,eAAe,CAEtF"}

View file

@ -0,0 +1,36 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { createHttpHeaders } from "./httpHeaders.js";
import { randomUUID } from "@azure/core-util";
class PipelineRequestImpl {
constructor(options) {
var _a, _b, _c, _d, _e, _f, _g;
this.url = options.url;
this.body = options.body;
this.headers = (_a = options.headers) !== null && _a !== void 0 ? _a : createHttpHeaders();
this.method = (_b = options.method) !== null && _b !== void 0 ? _b : "GET";
this.timeout = (_c = options.timeout) !== null && _c !== void 0 ? _c : 0;
this.multipartBody = options.multipartBody;
this.formData = options.formData;
this.disableKeepAlive = (_d = options.disableKeepAlive) !== null && _d !== void 0 ? _d : false;
this.proxySettings = options.proxySettings;
this.streamResponseStatusCodes = options.streamResponseStatusCodes;
this.withCredentials = (_e = options.withCredentials) !== null && _e !== void 0 ? _e : false;
this.abortSignal = options.abortSignal;
this.tracingOptions = options.tracingOptions;
this.onUploadProgress = options.onUploadProgress;
this.onDownloadProgress = options.onDownloadProgress;
this.requestId = options.requestId || randomUUID();
this.allowInsecureConnection = (_f = options.allowInsecureConnection) !== null && _f !== void 0 ? _f : false;
this.enableBrowserStreams = (_g = options.enableBrowserStreams) !== null && _g !== void 0 ? _g : false;
}
}
/**
* Creates a new pipeline request with the given options.
* This method is to allow for the easy setting of default values and not required.
* @param options - The options to create the request with.
*/
export function createPipelineRequest(options) {
return new PipelineRequestImpl(options);
}
//# sourceMappingURL=pipelineRequest.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,33 @@
import type { TokenCredential } from "@azure/core-auth";
import type { AzureLogger } from "@azure/logger";
import type { PipelinePolicy } from "../pipeline.js";
/**
* The programmatic identifier of the auxiliaryAuthenticationHeaderPolicy.
*/
export declare const auxiliaryAuthenticationHeaderPolicyName = "auxiliaryAuthenticationHeaderPolicy";
/**
* Options to configure the auxiliaryAuthenticationHeaderPolicy
*/
export interface AuxiliaryAuthenticationHeaderPolicyOptions {
/**
* TokenCredential list used to get token from auxiliary tenants and
* one credential for each tenant the client may need to access
*/
credentials?: TokenCredential[];
/**
* Scopes depend on the cloud your application runs in
*/
scopes: string | string[];
/**
* A logger can be sent for debugging purposes.
*/
logger?: AzureLogger;
}
/**
* A policy for external tokens to `x-ms-authorization-auxiliary` header.
* This header will be used when creating a cross-tenant application we may need to handle authentication requests
* for resources that are in different tenants.
* You could see [ARM docs](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/authenticate-multi-tenant) for a rundown of how this feature works
*/
export declare function auxiliaryAuthenticationHeaderPolicy(options: AuxiliaryAuthenticationHeaderPolicyOptions): PipelinePolicy;
//# sourceMappingURL=auxiliaryAuthenticationHeaderPolicy.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"auxiliaryAuthenticationHeaderPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/auxiliaryAuthenticationHeaderPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAmB,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKrD;;GAEG;AACH,eAAO,MAAM,uCAAuC,wCAAwC,CAAC;AAG7F;;GAEG;AACH,MAAM,WAAW,0CAA0C;IACzD;;;OAGG;IACH,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;IAChC;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAYD;;;;;GAKG;AACH,wBAAgB,mCAAmC,CACjD,OAAO,EAAE,0CAA0C,GAClD,cAAc,CAmDhB"}

View file

@ -0,0 +1,63 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { createTokenCycler } from "../util/tokenCycler.js";
import { logger as coreLogger } from "../log.js";
/**
* The programmatic identifier of the auxiliaryAuthenticationHeaderPolicy.
*/
export const auxiliaryAuthenticationHeaderPolicyName = "auxiliaryAuthenticationHeaderPolicy";
const AUTHORIZATION_AUXILIARY_HEADER = "x-ms-authorization-auxiliary";
async function sendAuthorizeRequest(options) {
var _a, _b;
const { scopes, getAccessToken, request } = options;
const getTokenOptions = {
abortSignal: request.abortSignal,
tracingOptions: request.tracingOptions,
};
return (_b = (_a = (await getAccessToken(scopes, getTokenOptions))) === null || _a === void 0 ? void 0 : _a.token) !== null && _b !== void 0 ? _b : "";
}
/**
* A policy for external tokens to `x-ms-authorization-auxiliary` header.
* This header will be used when creating a cross-tenant application we may need to handle authentication requests
* for resources that are in different tenants.
* You could see [ARM docs](https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/authenticate-multi-tenant) for a rundown of how this feature works
*/
export function auxiliaryAuthenticationHeaderPolicy(options) {
const { credentials, scopes } = options;
const logger = options.logger || coreLogger;
const tokenCyclerMap = new WeakMap();
return {
name: auxiliaryAuthenticationHeaderPolicyName,
async sendRequest(request, next) {
if (!request.url.toLowerCase().startsWith("https://")) {
throw new Error("Bearer token authentication for auxiliary header is not permitted for non-TLS protected (non-https) URLs.");
}
if (!credentials || credentials.length === 0) {
logger.info(`${auxiliaryAuthenticationHeaderPolicyName} header will not be set due to empty credentials.`);
return next(request);
}
const tokenPromises = [];
for (const credential of credentials) {
let getAccessToken = tokenCyclerMap.get(credential);
if (!getAccessToken) {
getAccessToken = createTokenCycler(credential);
tokenCyclerMap.set(credential, getAccessToken);
}
tokenPromises.push(sendAuthorizeRequest({
scopes: Array.isArray(scopes) ? scopes : [scopes],
request,
getAccessToken,
logger,
}));
}
const auxiliaryTokens = (await Promise.all(tokenPromises)).filter((token) => Boolean(token));
if (auxiliaryTokens.length === 0) {
logger.warning(`None of the auxiliary tokens are valid. ${AUTHORIZATION_AUXILIARY_HEADER} header will not be set.`);
return next(request);
}
request.headers.set(AUTHORIZATION_AUXILIARY_HEADER, auxiliaryTokens.map((token) => `Bearer ${token}`).join(", "));
return next(request);
},
};
}
//# sourceMappingURL=auxiliaryAuthenticationHeaderPolicy.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,99 @@
import type { AccessToken, GetTokenOptions, TokenCredential } from "@azure/core-auth";
import type { AzureLogger } from "@azure/logger";
import type { PipelineRequest, PipelineResponse } from "../interfaces.js";
import type { PipelinePolicy } from "../pipeline.js";
/**
* The programmatic identifier of the bearerTokenAuthenticationPolicy.
*/
export declare const bearerTokenAuthenticationPolicyName = "bearerTokenAuthenticationPolicy";
/**
* Options sent to the authorizeRequest callback
*/
export interface AuthorizeRequestOptions {
/**
* The scopes for which the bearer token applies.
*/
scopes: string[];
/**
* Function that retrieves either a cached access token or a new access token.
*/
getAccessToken: (scopes: string[], options: GetTokenOptions) => Promise<AccessToken | null>;
/**
* Request that the policy is trying to fulfill.
*/
request: PipelineRequest;
/**
* A logger, if one was sent through the HTTP pipeline.
*/
logger?: AzureLogger;
}
/**
* Options sent to the authorizeRequestOnChallenge callback
*/
export interface AuthorizeRequestOnChallengeOptions {
/**
* The scopes for which the bearer token applies.
*/
scopes: string[];
/**
* Function that retrieves either a cached access token or a new access token.
*/
getAccessToken: (scopes: string[], options: GetTokenOptions) => Promise<AccessToken | null>;
/**
* Request that the policy is trying to fulfill.
*/
request: PipelineRequest;
/**
* Response containing the challenge.
*/
response: PipelineResponse;
/**
* A logger, if one was sent through the HTTP pipeline.
*/
logger?: AzureLogger;
}
/**
* Options to override the processing of [Continuous Access Evaluation](https://docs.microsoft.com/azure/active-directory/conditional-access/concept-continuous-access-evaluation) challenges.
*/
export interface ChallengeCallbacks {
/**
* Allows for the authorization of the main request of this policy before it's sent.
*/
authorizeRequest?(options: AuthorizeRequestOptions): Promise<void>;
/**
* Allows to handle authentication challenges and to re-authorize the request.
* The response containing the challenge is `options.response`.
* If this method returns true, the underlying request will be sent once again.
* The request may be modified before being sent.
*/
authorizeRequestOnChallenge?(options: AuthorizeRequestOnChallengeOptions): Promise<boolean>;
}
/**
* Options to configure the bearerTokenAuthenticationPolicy
*/
export interface BearerTokenAuthenticationPolicyOptions {
/**
* The TokenCredential implementation that can supply the bearer token.
*/
credential?: TokenCredential;
/**
* The scopes for which the bearer token applies.
*/
scopes: string | string[];
/**
* Allows for the processing of [Continuous Access Evaluation](https://docs.microsoft.com/azure/active-directory/conditional-access/concept-continuous-access-evaluation) challenges.
* If provided, it must contain at least the `authorizeRequestOnChallenge` method.
* If provided, after a request is sent, if it has a challenge, it can be processed to re-send the original request with the relevant challenge information.
*/
challengeCallbacks?: ChallengeCallbacks;
/**
* A logger can be sent for debugging purposes.
*/
logger?: AzureLogger;
}
/**
* A policy that can request a token from a TokenCredential implementation and
* then apply it to the Authorization header of a request as a Bearer token.
*/
export declare function bearerTokenAuthenticationPolicy(options: BearerTokenAuthenticationPolicyOptions): PipelinePolicy;
//# sourceMappingURL=bearerTokenAuthenticationPolicy.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"bearerTokenAuthenticationPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/bearerTokenAuthenticationPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAe,MAAM,kBAAkB,CAAC;AACvF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAIrD;;GAEG;AACH,eAAO,MAAM,mCAAmC,oCAAoC,CAAC;AAErF;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;OAEG;IACH,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC5F;;OAEG;IACH,OAAO,EAAE,eAAe,CAAC;IACzB;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,kCAAkC;IACjD;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;OAEG;IACH,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;IAC5F;;OAEG;IACH,OAAO,EAAE,eAAe,CAAC;IACzB;;OAEG;IACH,QAAQ,EAAE,gBAAgB,CAAC;IAC3B;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,gBAAgB,CAAC,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnE;;;;;OAKG;IACH,2BAA2B,CAAC,CAAC,OAAO,EAAE,kCAAkC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7F;AAED;;GAEG;AACH,MAAM,WAAW,sCAAsC;IACrD;;OAEG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B;;OAEG;IACH,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;IACxC;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AA8BD;;;GAGG;AACH,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,sCAAsC,GAC9C,cAAc,CAkFhB"}

View file

@ -0,0 +1,108 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { createTokenCycler } from "../util/tokenCycler.js";
import { logger as coreLogger } from "../log.js";
/**
* The programmatic identifier of the bearerTokenAuthenticationPolicy.
*/
export const bearerTokenAuthenticationPolicyName = "bearerTokenAuthenticationPolicy";
/**
* Default authorize request handler
*/
async function defaultAuthorizeRequest(options) {
const { scopes, getAccessToken, request } = options;
const getTokenOptions = {
abortSignal: request.abortSignal,
tracingOptions: request.tracingOptions,
};
const accessToken = await getAccessToken(scopes, getTokenOptions);
if (accessToken) {
options.request.headers.set("Authorization", `Bearer ${accessToken.token}`);
}
}
/**
* We will retrieve the challenge only if the response status code was 401,
* and if the response contained the header "WWW-Authenticate" with a non-empty value.
*/
function getChallenge(response) {
const challenge = response.headers.get("WWW-Authenticate");
if (response.status === 401 && challenge) {
return challenge;
}
return;
}
/**
* A policy that can request a token from a TokenCredential implementation and
* then apply it to the Authorization header of a request as a Bearer token.
*/
export function bearerTokenAuthenticationPolicy(options) {
var _a;
const { credential, scopes, challengeCallbacks } = options;
const logger = options.logger || coreLogger;
const callbacks = Object.assign({ authorizeRequest: (_a = challengeCallbacks === null || challengeCallbacks === void 0 ? void 0 : challengeCallbacks.authorizeRequest) !== null && _a !== void 0 ? _a : defaultAuthorizeRequest, authorizeRequestOnChallenge: challengeCallbacks === null || challengeCallbacks === void 0 ? void 0 : challengeCallbacks.authorizeRequestOnChallenge }, challengeCallbacks);
// This function encapsulates the entire process of reliably retrieving the token
// The options are left out of the public API until there's demand to configure this.
// Remember to extend `BearerTokenAuthenticationPolicyOptions` with `TokenCyclerOptions`
// in order to pass through the `options` object.
const getAccessToken = credential
? createTokenCycler(credential /* , options */)
: () => Promise.resolve(null);
return {
name: bearerTokenAuthenticationPolicyName,
/**
* If there's no challenge parameter:
* - It will try to retrieve the token using the cache, or the credential's getToken.
* - Then it will try the next policy with or without the retrieved token.
*
* It uses the challenge parameters to:
* - Skip a first attempt to get the token from the credential if there's no cached token,
* since it expects the token to be retrievable only after the challenge.
* - Prepare the outgoing request if the `prepareRequest` method has been provided.
* - Send an initial request to receive the challenge if it fails.
* - Process a challenge if the response contains it.
* - Retrieve a token with the challenge information, then re-send the request.
*/
async sendRequest(request, next) {
if (!request.url.toLowerCase().startsWith("https://")) {
throw new Error("Bearer token authentication is not permitted for non-TLS protected (non-https) URLs.");
}
await callbacks.authorizeRequest({
scopes: Array.isArray(scopes) ? scopes : [scopes],
request,
getAccessToken,
logger,
});
let response;
let error;
try {
response = await next(request);
}
catch (err) {
error = err;
response = err.response;
}
if (callbacks.authorizeRequestOnChallenge &&
(response === null || response === void 0 ? void 0 : response.status) === 401 &&
getChallenge(response)) {
// processes challenge
const shouldSendRequest = await callbacks.authorizeRequestOnChallenge({
scopes: Array.isArray(scopes) ? scopes : [scopes],
request,
response,
getAccessToken,
logger,
});
if (shouldSendRequest) {
return next(request);
}
}
if (error) {
throw error;
}
else {
return response;
}
},
};
}
//# sourceMappingURL=bearerTokenAuthenticationPolicy.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1 @@
{"version":3,"file":"decompressResponsePolicy-browser.d.mts","sourceRoot":"","sources":["../../../src/policies/decompressResponsePolicy-browser.mts"],"names":[],"mappings":"AAOA,eAAO,MAAM,4BAA4B,6BAA6B,CAAC;AAEvE;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,KAAK,CAEhD"}

View file

@ -0,0 +1 @@
{"version":3,"file":"decompressResponsePolicy-browser.mjs","sourceRoot":"","sources":["../../../src/policies/decompressResponsePolicy-browser.mts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC;;GAEG;AAEH,MAAM,CAAC,MAAM,4BAA4B,GAAG,0BAA0B,CAAC;AAEvE;;;GAGG;AACH,MAAM,UAAU,wBAAwB;IACtC,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;AACtF,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 decompressResponsePolicyName = \"decompressResponsePolicy\";\n\n/**\n * decompressResponsePolicy is not supported in the browser and attempting\n * to use it will raise an error.\n */\nexport function decompressResponsePolicy(): never {\n throw new Error(\"decompressResponsePolicy is not supported in browser environment\");\n}\n"]}

View file

@ -0,0 +1,7 @@
export declare const decompressResponsePolicyName = "decompressResponsePolicy";
/**
* decompressResponsePolicy is not supported in the browser and attempting
* to use it will raise an error.
*/
export declare function decompressResponsePolicy(): never;
//# sourceMappingURL=decompressResponsePolicy-browser.d.mts.map

View file

@ -0,0 +1,14 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/*
* NOTE: When moving this file, please update "browser" section in package.json
*/
export const decompressResponsePolicyName = "decompressResponsePolicy";
/**
* decompressResponsePolicy is not supported in the browser and attempting
* to use it will raise an error.
*/
export function decompressResponsePolicy() {
throw new Error("decompressResponsePolicy is not supported in browser environment");
}
//# sourceMappingURL=decompressResponsePolicy-browser.mjs.map

View file

@ -0,0 +1,19 @@
import type { PipelineRetryOptions } from "../interfaces.js";
import type { PipelinePolicy } from "../pipeline.js";
/**
* Name of the {@link defaultRetryPolicy}
*/
export declare const defaultRetryPolicyName = "defaultRetryPolicy";
/**
* Options that control how to retry failed requests.
*/
export interface DefaultRetryPolicyOptions extends PipelineRetryOptions {
}
/**
* A policy that retries according to three strategies:
* - When the server sends a 429 response with a Retry-After header.
* - When there are errors in the underlying transport layer (e.g. DNS lookup failures).
* - Or otherwise if the outgoing request fails, it will retry with an exponentially increasing delay.
*/
export declare function defaultRetryPolicy(options?: DefaultRetryPolicyOptions): PipelinePolicy;
//# sourceMappingURL=defaultRetryPolicy.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"defaultRetryPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/defaultRetryPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAMrD;;GAEG;AACH,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAE3D;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,oBAAoB;CAAG;AAE1E;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,yBAA8B,GAAG,cAAc,CAO1F"}

View file

@ -0,0 +1,26 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy.js";
import { throttlingRetryStrategy } from "../retryStrategies/throttlingRetryStrategy.js";
import { retryPolicy } from "./retryPolicy.js";
import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js";
/**
* Name of the {@link defaultRetryPolicy}
*/
export const defaultRetryPolicyName = "defaultRetryPolicy";
/**
* A policy that retries according to three strategies:
* - When the server sends a 429 response with a Retry-After header.
* - When there are errors in the underlying transport layer (e.g. DNS lookup failures).
* - Or otherwise if the outgoing request fails, it will retry with an exponentially increasing delay.
*/
export function defaultRetryPolicy(options = {}) {
var _a;
return {
name: defaultRetryPolicyName,
sendRequest: retryPolicy([throttlingRetryStrategy(), exponentialRetryStrategy(options)], {
maxRetries: (_a = options.maxRetries) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_POLICY_COUNT,
}).sendRequest,
};
}
//# sourceMappingURL=defaultRetryPolicy.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"defaultRetryPolicy.js","sourceRoot":"","sources":["../../../src/policies/defaultRetryPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,wBAAwB,EAAE,MAAM,gDAAgD,CAAC;AAC1F,OAAO,EAAE,uBAAuB,EAAE,MAAM,+CAA+C,CAAC;AACxF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAO3D;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAqC,EAAE;;IACxE,OAAO;QACL,IAAI,EAAE,sBAAsB;QAC5B,WAAW,EAAE,WAAW,CAAC,CAAC,uBAAuB,EAAE,EAAE,wBAAwB,CAAC,OAAO,CAAC,CAAC,EAAE;YACvF,UAAU,EAAE,MAAA,OAAO,CAAC,UAAU,mCAAI,0BAA0B;SAC7D,CAAC,CAAC,WAAW;KACf,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { PipelineRetryOptions } from \"../interfaces.js\";\nimport type { PipelinePolicy } from \"../pipeline.js\";\nimport { exponentialRetryStrategy } from \"../retryStrategies/exponentialRetryStrategy.js\";\nimport { throttlingRetryStrategy } from \"../retryStrategies/throttlingRetryStrategy.js\";\nimport { retryPolicy } from \"./retryPolicy.js\";\nimport { DEFAULT_RETRY_POLICY_COUNT } from \"../constants.js\";\n\n/**\n * Name of the {@link defaultRetryPolicy}\n */\nexport const defaultRetryPolicyName = \"defaultRetryPolicy\";\n\n/**\n * Options that control how to retry failed requests.\n */\nexport interface DefaultRetryPolicyOptions extends PipelineRetryOptions {}\n\n/**\n * A policy that retries according to three strategies:\n * - When the server sends a 429 response with a Retry-After header.\n * - When there are errors in the underlying transport layer (e.g. DNS lookup failures).\n * - Or otherwise if the outgoing request fails, it will retry with an exponentially increasing delay.\n */\nexport function defaultRetryPolicy(options: DefaultRetryPolicyOptions = {}): PipelinePolicy {\n return {\n name: defaultRetryPolicyName,\n sendRequest: retryPolicy([throttlingRetryStrategy(), exponentialRetryStrategy(options)], {\n maxRetries: options.maxRetries ?? DEFAULT_RETRY_POLICY_COUNT,\n }).sendRequest,\n };\n}\n"]}

View file

@ -0,0 +1,31 @@
import type { PipelinePolicy } from "../pipeline.js";
/**
* The programmatic identifier of the exponentialRetryPolicy.
*/
export declare const exponentialRetryPolicyName = "exponentialRetryPolicy";
/**
* Options that control how to retry failed requests.
*/
export interface ExponentialRetryPolicyOptions {
/**
* The maximum number of retry attempts. Defaults to 3.
*/
maxRetries?: number;
/**
* The amount of delay in milliseconds between retry attempts. Defaults to 1000
* (1 second.) The delay increases exponentially with each retry up to a maximum
* specified by maxRetryDelayInMs.
*/
retryDelayInMs?: number;
/**
* The maximum delay in milliseconds allowed before retrying an operation. Defaults
* to 64000 (64 seconds).
*/
maxRetryDelayInMs?: number;
}
/**
* A policy that attempts to retry requests while introducing an exponentially increasing delay.
* @param options - Options that configure retry logic.
*/
export declare function exponentialRetryPolicy(options?: ExponentialRetryPolicyOptions): PipelinePolicy;
//# sourceMappingURL=exponentialRetryPolicy.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"exponentialRetryPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/exponentialRetryPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAKrD;;GAEG;AACH,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,6BAAkC,GAC1C,cAAc,CAYhB"}

View file

@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { exponentialRetryStrategy } from "../retryStrategies/exponentialRetryStrategy.js";
import { retryPolicy } from "./retryPolicy.js";
import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js";
/**
* The programmatic identifier of the exponentialRetryPolicy.
*/
export const exponentialRetryPolicyName = "exponentialRetryPolicy";
/**
* A policy that attempts to retry requests while introducing an exponentially increasing delay.
* @param options - Options that configure retry logic.
*/
export function exponentialRetryPolicy(options = {}) {
var _a;
return retryPolicy([
exponentialRetryStrategy(Object.assign(Object.assign({}, options), { ignoreSystemErrors: true })),
], {
maxRetries: (_a = options.maxRetries) !== null && _a !== void 0 ? _a : DEFAULT_RETRY_POLICY_COUNT,
});
}
//# sourceMappingURL=exponentialRetryPolicy.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"exponentialRetryPolicy.js","sourceRoot":"","sources":["../../../src/policies/exponentialRetryPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,wBAAwB,EAAE,MAAM,gDAAgD,CAAC;AAC1F,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAE7D;;GAEG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,wBAAwB,CAAC;AAyBnE;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CACpC,UAAyC,EAAE;;IAE3C,OAAO,WAAW,CAChB;QACE,wBAAwB,iCACnB,OAAO,KACV,kBAAkB,EAAE,IAAI,IACxB;KACH,EACD;QACE,UAAU,EAAE,MAAA,OAAO,CAAC,UAAU,mCAAI,0BAA0B;KAC7D,CACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { PipelinePolicy } from \"../pipeline.js\";\nimport { exponentialRetryStrategy } from \"../retryStrategies/exponentialRetryStrategy.js\";\nimport { retryPolicy } from \"./retryPolicy.js\";\nimport { DEFAULT_RETRY_POLICY_COUNT } from \"../constants.js\";\n\n/**\n * The programmatic identifier of the exponentialRetryPolicy.\n */\nexport const exponentialRetryPolicyName = \"exponentialRetryPolicy\";\n\n/**\n * Options that control how to retry failed requests.\n */\nexport interface ExponentialRetryPolicyOptions {\n /**\n * The maximum number of retry attempts. Defaults to 3.\n */\n maxRetries?: number;\n\n /**\n * The amount of delay in milliseconds between retry attempts. Defaults to 1000\n * (1 second.) The delay increases exponentially with each retry up to a maximum\n * specified by maxRetryDelayInMs.\n */\n retryDelayInMs?: number;\n\n /**\n * The maximum delay in milliseconds allowed before retrying an operation. Defaults\n * to 64000 (64 seconds).\n */\n maxRetryDelayInMs?: number;\n}\n\n/**\n * A policy that attempts to retry requests while introducing an exponentially increasing delay.\n * @param options - Options that configure retry logic.\n */\nexport function exponentialRetryPolicy(\n options: ExponentialRetryPolicyOptions = {},\n): PipelinePolicy {\n return retryPolicy(\n [\n exponentialRetryStrategy({\n ...options,\n ignoreSystemErrors: true,\n }),\n ],\n {\n maxRetries: options.maxRetries ?? DEFAULT_RETRY_POLICY_COUNT,\n },\n );\n}\n"]}

View file

@ -0,0 +1,10 @@
import type { PipelinePolicy } from "../pipeline.js";
/**
* The programmatic identifier of the formDataPolicy.
*/
export declare const formDataPolicyName = "formDataPolicy";
/**
* A policy that encodes FormData on the request into the body.
*/
export declare function formDataPolicy(): PipelinePolicy;
//# sourceMappingURL=formDataPolicy.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"formDataPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/formDataPolicy.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AAWnD;;GAEG;AACH,wBAAgB,cAAc,IAAI,cAAc,CAsB/C"}

View file

@ -0,0 +1,96 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { isNodeLike, stringToUint8Array } from "@azure/core-util";
import { createHttpHeaders } from "../httpHeaders.js";
/**
* The programmatic identifier of the formDataPolicy.
*/
export const formDataPolicyName = "formDataPolicy";
function formDataToFormDataMap(formData) {
var _a;
const formDataMap = {};
for (const [key, value] of formData.entries()) {
(_a = formDataMap[key]) !== null && _a !== void 0 ? _a : (formDataMap[key] = []);
formDataMap[key].push(value);
}
return formDataMap;
}
/**
* A policy that encodes FormData on the request into the body.
*/
export function formDataPolicy() {
return {
name: formDataPolicyName,
async sendRequest(request, next) {
if (isNodeLike && typeof FormData !== "undefined" && request.body instanceof FormData) {
request.formData = formDataToFormDataMap(request.body);
request.body = undefined;
}
if (request.formData) {
const contentType = request.headers.get("Content-Type");
if (contentType && contentType.indexOf("application/x-www-form-urlencoded") !== -1) {
request.body = wwwFormUrlEncode(request.formData);
}
else {
await prepareFormData(request.formData, request);
}
request.formData = undefined;
}
return next(request);
},
};
}
function wwwFormUrlEncode(formData) {
const urlSearchParams = new URLSearchParams();
for (const [key, value] of Object.entries(formData)) {
if (Array.isArray(value)) {
for (const subValue of value) {
urlSearchParams.append(key, subValue.toString());
}
}
else {
urlSearchParams.append(key, value.toString());
}
}
return urlSearchParams.toString();
}
async function prepareFormData(formData, request) {
// validate content type (multipart/form-data)
const contentType = request.headers.get("Content-Type");
if (contentType && !contentType.startsWith("multipart/form-data")) {
// content type is specified and is not multipart/form-data. Exit.
return;
}
request.headers.set("Content-Type", contentType !== null && contentType !== void 0 ? contentType : "multipart/form-data");
// set body to MultipartRequestBody using content from FormDataMap
const parts = [];
for (const [fieldName, values] of Object.entries(formData)) {
for (const value of Array.isArray(values) ? values : [values]) {
if (typeof value === "string") {
parts.push({
headers: createHttpHeaders({
"Content-Disposition": `form-data; name="${fieldName}"`,
}),
body: stringToUint8Array(value, "utf-8"),
});
}
else if (value === undefined || value === null || typeof value !== "object") {
throw new Error(`Unexpected value for key ${fieldName}: ${value}. Value should be serialized to string first.`);
}
else {
// using || instead of ?? here since if value.name is empty we should create a file name
const fileName = value.name || "blob";
const headers = createHttpHeaders();
headers.set("Content-Disposition", `form-data; name="${fieldName}"; filename="${fileName}"`);
// again, || is used since an empty value.type means the content type is unset
headers.set("Content-Type", value.type || "application/octet-stream");
parts.push({
headers,
body: value,
});
}
}
}
request.multipartBody = { parts };
}
//# sourceMappingURL=formDataPolicy.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,35 @@
import type { Debugger } from "@azure/logger";
import type { PipelinePolicy } from "../pipeline.js";
/**
* The programmatic identifier of the logPolicy.
*/
export declare const logPolicyName = "logPolicy";
/**
* Options to configure the logPolicy.
*/
export interface LogPolicyOptions {
/**
* Header names whose values will be logged when logging is enabled.
* Defaults include a list of well-known safe headers. Any headers
* specified in this field will be added to that list. Any other values will
* be written to logs as "REDACTED".
*/
additionalAllowedHeaderNames?: string[];
/**
* Query string names whose values will be logged when logging is enabled. By default no
* query string values are logged.
*/
additionalAllowedQueryParameters?: string[];
/**
* The log function to use for writing pipeline logs.
* Defaults to core-http's built-in logger.
* Compatible with the `debug` library.
*/
logger?: Debugger;
}
/**
* A policy that logs all requests and responses.
* @param options - Options to configure logPolicy.
*/
export declare function logPolicy(options?: LogPolicyOptions): PipelinePolicy;
//# sourceMappingURL=logPolicy.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"logPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/logPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAIrD;;GAEG;AACH,eAAO,MAAM,aAAa,cAAc,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,4BAA4B,CAAC,EAAE,MAAM,EAAE,CAAC;IAExC;;;OAGG;IACH,gCAAgC,CAAC,EAAE,MAAM,EAAE,CAAC;IAE5C;;;;OAIG;IACH,MAAM,CAAC,EAAE,QAAQ,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB,GAAG,cAAc,CAuBxE"}

View file

@ -0,0 +1,34 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { logger as coreLogger } from "../log.js";
import { Sanitizer } from "../util/sanitizer.js";
/**
* The programmatic identifier of the logPolicy.
*/
export const logPolicyName = "logPolicy";
/**
* A policy that logs all requests and responses.
* @param options - Options to configure logPolicy.
*/
export function logPolicy(options = {}) {
var _a;
const logger = (_a = options.logger) !== null && _a !== void 0 ? _a : coreLogger.info;
const sanitizer = new Sanitizer({
additionalAllowedHeaderNames: options.additionalAllowedHeaderNames,
additionalAllowedQueryParameters: options.additionalAllowedQueryParameters,
});
return {
name: logPolicyName,
async sendRequest(request, next) {
if (!logger.enabled) {
return next(request);
}
logger(`Request: ${sanitizer.sanitize(request)}`);
const response = await next(request);
logger(`Response status code: ${response.status}`);
logger(`Headers: ${sanitizer.sanitize(response.headers)}`);
return response;
},
};
}
//# sourceMappingURL=logPolicy.js.map

View file

@ -0,0 +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,WAAW,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD;;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,CAAC;gBACpB,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;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 type { Debugger } from \"@azure/logger\";\nimport type { PipelineRequest, PipelineResponse, SendRequest } from \"../interfaces.js\";\nimport type { PipelinePolicy } from \"../pipeline.js\";\nimport { logger as coreLogger } from \"../log.js\";\nimport { Sanitizer } from \"../util/sanitizer.js\";\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"]}

View file

@ -0,0 +1,10 @@
import type { PipelinePolicy } from "../pipeline.js";
/**
* Name of multipart policy
*/
export declare const multipartPolicyName = "multipartPolicy";
/**
* Pipeline policy for multipart requests
*/
export declare function multipartPolicy(): PipelinePolicy;
//# sourceMappingURL=multipartPolicy.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"multipartPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/multipartPolicy.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAkFrD;;GAEG;AACH,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AAiBrD;;GAEG;AACH,wBAAgB,eAAe,IAAI,cAAc,CA2ChD"}

View file

@ -0,0 +1,111 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { randomUUID, stringToUint8Array } from "@azure/core-util";
import { concat } from "../util/concat.js";
import { isBlob } from "../util/typeGuards.js";
function generateBoundary() {
return `----AzSDKFormBoundary${randomUUID()}`;
}
function encodeHeaders(headers) {
let result = "";
for (const [key, value] of headers) {
result += `${key}: ${value}\r\n`;
}
return result;
}
function getLength(source) {
if (source instanceof Uint8Array) {
return source.byteLength;
}
else if (isBlob(source)) {
// if was created using createFile then -1 means we have an unknown size
return source.size === -1 ? undefined : source.size;
}
else {
return undefined;
}
}
function getTotalLength(sources) {
let total = 0;
for (const source of sources) {
const partLength = getLength(source);
if (partLength === undefined) {
return undefined;
}
else {
total += partLength;
}
}
return total;
}
async function buildRequestBody(request, parts, boundary) {
const sources = [
stringToUint8Array(`--${boundary}`, "utf-8"),
...parts.flatMap((part) => [
stringToUint8Array("\r\n", "utf-8"),
stringToUint8Array(encodeHeaders(part.headers), "utf-8"),
stringToUint8Array("\r\n", "utf-8"),
part.body,
stringToUint8Array(`\r\n--${boundary}`, "utf-8"),
]),
stringToUint8Array("--\r\n\r\n", "utf-8"),
];
const contentLength = getTotalLength(sources);
if (contentLength) {
request.headers.set("Content-Length", contentLength);
}
request.body = await concat(sources);
}
/**
* Name of multipart policy
*/
export const multipartPolicyName = "multipartPolicy";
const maxBoundaryLength = 70;
const validBoundaryCharacters = new Set(`abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'()+,-./:=?`);
function assertValidBoundary(boundary) {
if (boundary.length > maxBoundaryLength) {
throw new Error(`Multipart boundary "${boundary}" exceeds maximum length of 70 characters`);
}
if (Array.from(boundary).some((x) => !validBoundaryCharacters.has(x))) {
throw new Error(`Multipart boundary "${boundary}" contains invalid characters`);
}
}
/**
* Pipeline policy for multipart requests
*/
export function multipartPolicy() {
return {
name: multipartPolicyName,
async sendRequest(request, next) {
var _a;
if (!request.multipartBody) {
return next(request);
}
if (request.body) {
throw new Error("multipartBody and regular body cannot be set at the same time");
}
let boundary = request.multipartBody.boundary;
const contentTypeHeader = (_a = request.headers.get("Content-Type")) !== null && _a !== void 0 ? _a : "multipart/mixed";
const parsedHeader = contentTypeHeader.match(/^(multipart\/[^ ;]+)(?:; *boundary=(.+))?$/);
if (!parsedHeader) {
throw new Error(`Got multipart request body, but content-type header was not multipart: ${contentTypeHeader}`);
}
const [, contentType, parsedBoundary] = parsedHeader;
if (parsedBoundary && boundary && parsedBoundary !== boundary) {
throw new Error(`Multipart boundary was specified as ${parsedBoundary} in the header, but got ${boundary} in the request body`);
}
boundary !== null && boundary !== void 0 ? boundary : (boundary = parsedBoundary);
if (boundary) {
assertValidBoundary(boundary);
}
else {
boundary = generateBoundary();
}
request.headers.set("Content-Type", `${contentType}; boundary=${boundary}`);
await buildRequestBody(request, request.multipartBody.parts, boundary);
request.multipartBody = undefined;
return next(request);
},
};
}
//# sourceMappingURL=multipartPolicy.js.map

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,10 @@
import type { PipelinePolicy } from "../pipeline.js";
/**
* The programmatic identifier of the ndJsonPolicy.
*/
export declare const ndJsonPolicyName = "ndJsonPolicy";
/**
* ndJsonPolicy is a policy used to control keep alive settings for every request.
*/
export declare function ndJsonPolicy(): PipelinePolicy;
//# sourceMappingURL=ndJsonPolicy.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"ndJsonPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/ndJsonPolicy.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,gBAAgB,iBAAiB,CAAC;AAE/C;;GAEG;AACH,wBAAgB,YAAY,IAAI,cAAc,CAc7C"}

View file

@ -0,0 +1,25 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/**
* The programmatic identifier of the ndJsonPolicy.
*/
export const ndJsonPolicyName = "ndJsonPolicy";
/**
* ndJsonPolicy is a policy used to control keep alive settings for every request.
*/
export function ndJsonPolicy() {
return {
name: ndJsonPolicyName,
async sendRequest(request, next) {
// There currently isn't a good way to bypass the serializer
if (typeof request.body === "string" && request.body.startsWith("[")) {
const body = JSON.parse(request.body);
if (Array.isArray(body)) {
request.body = body.map((item) => JSON.stringify(item) + "\n").join("");
}
}
return next(request);
},
};
}
//# sourceMappingURL=ndJsonPolicy.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"ndJsonPolicy.js","sourceRoot":"","sources":["../../../src/policies/ndJsonPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAKlC;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAE/C;;GAEG;AACH,MAAM,UAAU,YAAY;IAC1B,OAAO;QACL,IAAI,EAAE,gBAAgB;QACtB,KAAK,CAAC,WAAW,CAAC,OAAwB,EAAE,IAAiB;YAC3D,4DAA4D;YAC5D,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;gBACtC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;oBACxB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC1E,CAAC;YACH,CAAC;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 type { PipelineRequest, PipelineResponse, SendRequest } from \"../interfaces.js\";\nimport type { PipelinePolicy } from \"../pipeline.js\";\n\n/**\n * The programmatic identifier of the ndJsonPolicy.\n */\nexport const ndJsonPolicyName = \"ndJsonPolicy\";\n\n/**\n * ndJsonPolicy is a policy used to control keep alive settings for every request.\n */\nexport function ndJsonPolicy(): PipelinePolicy {\n return {\n name: ndJsonPolicyName,\n async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {\n // There currently isn't a good way to bypass the serializer\n if (typeof request.body === \"string\" && request.body.startsWith(\"[\")) {\n const body = JSON.parse(request.body);\n if (Array.isArray(body)) {\n request.body = body.map((item) => JSON.stringify(item) + \"\\n\").join(\"\");\n }\n }\n return next(request);\n },\n };\n}\n"]}

View file

@ -0,0 +1 @@
{"version":3,"file":"proxyPolicy-browser.d.mts","sourceRoot":"","sources":["../../../src/policies/proxyPolicy-browser.mts"],"names":[],"mappings":"AAGA,cAAc,yBAAyB,CAAC"}

View file

@ -0,0 +1 @@
{"version":3,"file":"proxyPolicy-browser.mjs","sourceRoot":"","sources":["../../../src/policies/proxyPolicy-browser.mts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,cAAc,yBAAyB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nexport * from \"./proxyPolicy.common.js\";\n"]}

View file

@ -0,0 +1,15 @@
export declare const proxyPolicyName = "proxyPolicy";
export declare function getDefaultProxySettings(): never;
/**
* proxyPolicy is not supported in the browser and attempting
* to use it will raise an error.
*/
export declare function proxyPolicy(): never;
/**
* A function to reset the cached agents.
* proxyPolicy is not supported in the browser and attempting
* to use it will raise an error.
* @internal
*/
export declare function resetCachedProxyAgents(): never;
//# sourceMappingURL=proxyPolicy.common.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"proxyPolicy.common.d.ts","sourceRoot":"","sources":["../../../src/policies/proxyPolicy.common.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAG7C,wBAAgB,uBAAuB,IAAI,KAAK,CAE/C;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,KAAK,CAEnC;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,IAAI,KAAK,CAE9C"}

View file

@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
export const proxyPolicyName = "proxyPolicy";
const errorMessage = "proxyPolicy is not supported in browser environment";
export function getDefaultProxySettings() {
throw new Error(errorMessage);
}
/**
* proxyPolicy is not supported in the browser and attempting
* to use it will raise an error.
*/
export function proxyPolicy() {
throw new Error(errorMessage);
}
/**
* A function to reset the cached agents.
* proxyPolicy is not supported in the browser and attempting
* to use it will raise an error.
* @internal
*/
export function resetCachedProxyAgents() {
throw new Error(errorMessage);
}
//# sourceMappingURL=proxyPolicy.common.js.map

View file

@ -0,0 +1 @@
{"version":3,"file":"proxyPolicy.common.js","sourceRoot":"","sources":["../../../src/policies/proxyPolicy.common.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,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\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"]}

View file

@ -0,0 +1,2 @@
export * from "./proxyPolicy.common.js";
//# sourceMappingURL=proxyPolicy-browser.d.mts.map

View file

@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
export * from "./proxyPolicy.common.js";
//# sourceMappingURL=proxyPolicy-browser.mjs.map

View file

@ -0,0 +1,23 @@
import type { PipelinePolicy } from "../pipeline.js";
/**
* The programmatic identifier of the redirectPolicy.
*/
export declare const redirectPolicyName = "redirectPolicy";
/**
* Options for how redirect responses are handled.
*/
export interface RedirectPolicyOptions {
/**
* The maximum number of times the redirect URL will be tried before
* failing. Defaults to 20.
*/
maxRetries?: number;
}
/**
* A policy to follow Location headers from the server in order
* to support server-side redirection.
* In the browser, this policy is not used.
* @param options - Options to control policy behavior.
*/
export declare function redirectPolicy(options?: RedirectPolicyOptions): PipelinePolicy;
//# sourceMappingURL=redirectPolicy.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"redirectPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/redirectPolicy.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD;;GAEG;AACH,eAAO,MAAM,kBAAkB,mBAAmB,CAAC;AAOnD;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,cAAc,CASlF"}

View file

@ -0,0 +1,52 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
/**
* The programmatic identifier of the redirectPolicy.
*/
export const redirectPolicyName = "redirectPolicy";
/**
* Methods that are allowed to follow redirects 301 and 302
*/
const allowedRedirect = ["GET", "HEAD"];
/**
* A policy to follow Location headers from the server in order
* to support server-side redirection.
* In the browser, this policy is not used.
* @param options - Options to control policy behavior.
*/
export function redirectPolicy(options = {}) {
const { maxRetries = 20 } = options;
return {
name: redirectPolicyName,
async sendRequest(request, next) {
const response = await next(request);
return handleRedirect(next, response, maxRetries);
},
};
}
async function handleRedirect(next, response, maxRetries, currentRetries = 0) {
const { request, status, headers } = response;
const locationHeader = headers.get("location");
if (locationHeader &&
(status === 300 ||
(status === 301 && allowedRedirect.includes(request.method)) ||
(status === 302 && allowedRedirect.includes(request.method)) ||
(status === 303 && request.method === "POST") ||
status === 307) &&
currentRetries < maxRetries) {
const url = new URL(locationHeader, request.url);
request.url = url.toString();
// POST request with Status code 303 should be converted into a
// redirected GET request if the redirect url is present in the location header
if (status === 303) {
request.method = "GET";
request.headers.delete("Content-Length");
delete request.body;
}
request.headers.delete("Authorization");
const res = await next(request);
return handleRedirect(next, res, maxRetries, currentRetries + 1);
}
return response;
}
//# sourceMappingURL=redirectPolicy.js.map

View file

@ -0,0 +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,CAAC;QACD,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,CAAC;YACnB,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC;YACvB,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACzC,OAAO,OAAO,CAAC,IAAI,CAAC;QACtB,CAAC;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;IACnE,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { PipelineRequest, PipelineResponse, SendRequest } from \"../interfaces.js\";\nimport type { PipelinePolicy } from \"../pipeline.js\";\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"]}

View file

@ -0,0 +1,21 @@
import type { PipelinePolicy } from "../pipeline.js";
import { type AzureLogger } from "@azure/logger";
import type { RetryStrategy } from "../retryStrategies/retryStrategy.js";
/**
* Options to the {@link retryPolicy}
*/
export interface RetryPolicyOptions {
/**
* Maximum number of retries. If not specified, it will limit to 3 retries.
*/
maxRetries?: number;
/**
* Logger. If it's not provided, a default logger is used.
*/
logger?: AzureLogger;
}
/**
* retryPolicy is a generic policy to enable retrying requests when certain conditions are met
*/
export declare function retryPolicy(strategies: RetryStrategy[], options?: RetryPolicyOptions): PipelinePolicy;
//# sourceMappingURL=retryPolicy.d.ts.map

View file

@ -0,0 +1 @@
{"version":3,"file":"retryPolicy.d.ts","sourceRoot":"","sources":["../../../src/policies/retryPolicy.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,OAAO,EAAE,KAAK,WAAW,EAAsB,MAAM,eAAe,CAAC;AACrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAYzE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,aAAa,EAAE,EAC3B,OAAO,GAAE,kBAA+D,GACvE,cAAc,CAmHhB"}

View file

@ -0,0 +1,106 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { delay } from "../util/helpers.js";
import { createClientLogger } from "@azure/logger";
import { AbortError } from "@azure/abort-controller";
import { DEFAULT_RETRY_POLICY_COUNT } from "../constants.js";
const retryPolicyLogger = createClientLogger("core-rest-pipeline retryPolicy");
/**
* The programmatic identifier of the retryPolicy.
*/
const retryPolicyName = "retryPolicy";
/**
* retryPolicy is a generic policy to enable retrying requests when certain conditions are met
*/
export function retryPolicy(strategies, options = { maxRetries: DEFAULT_RETRY_POLICY_COUNT }) {
const logger = options.logger || retryPolicyLogger;
return {
name: retryPolicyName,
async sendRequest(request, next) {
var _a, _b;
let response;
let responseError;
let retryCount = -1;
// eslint-disable-next-line no-constant-condition
retryRequest: while (true) {
retryCount += 1;
response = undefined;
responseError = undefined;
try {
logger.info(`Retry ${retryCount}: Attempting to send request`, request.requestId);
response = await next(request);
logger.info(`Retry ${retryCount}: Received a response from request`, request.requestId);
}
catch (e) {
logger.error(`Retry ${retryCount}: Received an error from request`, request.requestId);
// RestErrors are valid targets for the retry strategies.
// If none of the retry strategies can work with them, they will be thrown later in this policy.
// If the received error is not a RestError, it is immediately thrown.
responseError = e;
if (!e || responseError.name !== "RestError") {
throw e;
}
response = responseError.response;
}
if ((_a = request.abortSignal) === null || _a === void 0 ? void 0 : _a.aborted) {
logger.error(`Retry ${retryCount}: Request aborted.`);
const abortError = new AbortError();
throw abortError;
}
if (retryCount >= ((_b = options.maxRetries) !== null && _b !== void 0 ? _b : DEFAULT_RETRY_POLICY_COUNT)) {
logger.info(`Retry ${retryCount}: Maximum retries reached. Returning the last received response, or throwing the last received error.`);
if (responseError) {
throw responseError;
}
else if (response) {
return response;
}
else {
throw new Error("Maximum retries reached with no response or error to throw");
}
}
logger.info(`Retry ${retryCount}: Processing ${strategies.length} retry strategies.`);
strategiesLoop: for (const strategy of strategies) {
const strategyLogger = strategy.logger || retryPolicyLogger;
strategyLogger.info(`Retry ${retryCount}: Processing retry strategy ${strategy.name}.`);
const modifiers = strategy.retry({
retryCount,
response,
responseError,
});
if (modifiers.skipStrategy) {
strategyLogger.info(`Retry ${retryCount}: Skipped.`);
continue strategiesLoop;
}
const { errorToThrow, retryAfterInMs, redirectTo } = modifiers;
if (errorToThrow) {
strategyLogger.error(`Retry ${retryCount}: Retry strategy ${strategy.name} throws error:`, errorToThrow);
throw errorToThrow;
}
if (retryAfterInMs || retryAfterInMs === 0) {
strategyLogger.info(`Retry ${retryCount}: Retry strategy ${strategy.name} retries after ${retryAfterInMs}`);
await delay(retryAfterInMs, undefined, { abortSignal: request.abortSignal });
continue retryRequest;
}
if (redirectTo) {
strategyLogger.info(`Retry ${retryCount}: Retry strategy ${strategy.name} redirects to ${redirectTo}`);
request.url = redirectTo;
continue retryRequest;
}
}
if (responseError) {
logger.info(`None of the retry strategies could work with the received error. Throwing it.`);
throw responseError;
}
if (response) {
logger.info(`None of the retry strategies could work with the received response. Returning it.`);
return response;
}
// If all the retries skip and there's no response,
// we're still in the retry loop, so a new request will be sent
// until `maxRetries` is reached.
}
},
};
}
//# sourceMappingURL=retryPolicy.js.map

Some files were not shown because too many files have changed in this diff Show more