Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions sdk/core/abort-controller/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

declare global {
interface Event {}
}

export { AbortError } from "./AbortError.js";
export type { AbortSignalLike } from "./AbortSignalLike.js";
140 changes: 2 additions & 138 deletions sdk/core/core-amqp/src/util/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,6 @@ import type { AbortSignalLike } from "@azure/abort-controller";
import type { WebSocketImpl } from "rhea-promise";
import { delay as wrapperDelay } from "@azure/core-util";

/**
* @internal
*
* Describes the options that can be provided to create an async lock.
*/
export interface AsyncLockOptions {
/**
* The max timeout. Default is: 0 (never timeout).
*/
timeout?: number;
/**
* Maximum pending tasks. Default is: 1000.
*/
maxPending?: number;
/**
* Whether lock can reenter in the same domain.
* Default is: false.
*/
domainReentrant?: boolean;
/**
* Your implementation of the promise. Default is: global promise.
*/
Promise?: any;
}

/**
* Options to configure the channelling of the AMQP connection over Web Sockets.
*/
Expand Down Expand Up @@ -72,7 +47,7 @@ export type ParsedOutput<T> = { [P in keyof T]: T[P] };
* @returns ParsedOutput<T>.
*/
export function parseConnectionString<T>(connectionString: string): ParsedOutput<T> {
const output: { [k: string]: string } = {};
const output: Record<string, string> = {};
const parts = connectionString.trim().split(";");

for (let part of parts) {
Expand Down Expand Up @@ -100,64 +75,14 @@ export function parseConnectionString<T>(connectionString: string): ParsedOutput
output[key] = value;
}

return output as any;
return output as ParsedOutput<T>;
}

/**
* The cancellable async lock instance.
*/
export const defaultCancellableLock: CancellableAsyncLock = new CancellableAsyncLockImpl();

/**
* @internal
*
* Describes a Timeout class that can wait for the specified amount of time and then resolve/reject
* the promise with the given value.
*/
export class Timeout {
Comment thread
xirzec marked this conversation as resolved.
private _timer?: number | NodeJS.Timeout;

set<T>(t: number, value?: T): Promise<T> {
return new Promise<T>((resolve, reject) => {
this.clear();
const callback: (args: any) => void = value ? () => reject(new Error(`${value}`)) : resolve;
this._timer = setTimeout(callback, t);
});
}

clear(): void {
if (this._timer) {
clearTimeout(this._timer);
}
}

wrap<T>(promise: Promise<T>, t: number, value?: T): Promise<T> {
const wrappedPromise = this._promiseFinally(promise, () => this.clear());
const timer = this.set(t, value);
return Promise.race([wrappedPromise, timer]);
}

private _promiseFinally<T>(promise: Promise<T>, fn: (...args: any[]) => void): Promise<T> {
const success = (result: T): T => {
fn();
return result;
};
const error = (e: Error): Promise<never> => {
fn();
return Promise.reject(e);
};
return Promise.resolve(promise).then(success, error);
}

static set<T>(t: number, value?: T): Promise<T> {
return new Timeout().set(t, value);
}

static wrap<T>(promise: Promise<T>, t: number, value?: T): Promise<T> {
return new Timeout().wrap(promise, t, value);
}
}

/**
* A wrapper for setTimeout that resolves a promise after t milliseconds.
* @param delayInMs - The number of milliseconds to be delayed.
Expand Down Expand Up @@ -190,67 +115,6 @@ export function isLoopbackAddress(address: string): boolean {
return /^(.*:\/\/)?(127\.[\d.]+|[0:]+1|localhost)/.test(address.toLowerCase());
}

/**
* @internal
*
* Generates a random number between the given interval
* @param min - Min number of the range (inclusive).
* @param max - Max number of the range (inclusive).
*/
export function randomNumberFromInterval(min: number, max: number): number {
return Math.floor(Math.random() * (max - min + 1) + min);
}

/**
* @internal
*
* Type declaration for a Function type where T is the input to the function and V is the output
* of the function.
*/
export type Func<T, V> = (a: T) => V;

/**
* @internal
*
* Executes an array of promises sequentially. Inspiration of this method is here:
* https://pouchdb.com/2015/05/18/we-have-a-problem-with-promises.html. An awesome blog on promises!
*
* @param promiseFactories - An array of promise factories(A function that return a promise)
*
* @param kickstart - Input to the first promise that is used to kickstart the promise chain.
* If not provided then the promise chain starts with undefined.
*
* @returns A chain of resolved or rejected promises
*/
export function executePromisesSequentially(
promiseFactories: Array<any>,
kickstart?: unknown,
): Promise<any> {
let result = Promise.resolve(kickstart);
promiseFactories.forEach((promiseFactory) => {
result = result.then(promiseFactory);
});
return result;
}

/**
* @internal
*
* Determines whether the given connection string is an iothub connection string.
* @param connectionString - The connection string.
* @returns boolean.
*/
export function isIotHubConnectionString(connectionString: string): boolean {
const cs = String(connectionString);

let result: boolean = false;
const model: any = parseConnectionString<any>(cs);
if (model && model.HostName && model.SharedAccessKey && model.SharedAccessKeyName) {
result = true;
}
return result;
}

/**
* @internal
*/
Expand Down
18 changes: 0 additions & 18 deletions sdk/core/core-auth/src/tokenCredential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,24 +107,6 @@ export interface AccessToken {
tokenType?: "Bearer" | "pop";
}

/**
* @internal
* @param accessToken - Access token
* @returns Whether a token is bearer type or not
*/
export function isBearerToken(accessToken: AccessToken): boolean {
return !accessToken.tokenType || accessToken.tokenType === "Bearer";
}

/**
* @internal
* @param accessToken - Access token
* @returns Whether a token is Pop token or not
*/
export function isPopToken(accessToken: AccessToken): boolean {
return accessToken.tokenType === "pop";
}

/**
* Tests an object to determine whether it implements TokenCredential.
*
Expand Down
10 changes: 10 additions & 0 deletions sdk/core/core-client-rest/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Release History

## 2.6.1 (Unreleased)

### Features Added

### Breaking Changes

### Bugs Fixed

### Other Changes

Comment thread
xirzec marked this conversation as resolved.
## 2.6.0 (2026-04-07)

### Features Added
Expand Down
2 changes: 1 addition & 1 deletion sdk/core/core-client-rest/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@azure-rest/core-client",
"version": "2.6.0",
"version": "2.6.1",
"description": "Core library for interfacing with Azure Rest Clients",
"sdk-type": "client",
"type": "module",
Expand Down
4 changes: 1 addition & 3 deletions sdk/core/core-client-rest/src/apiVersionPolicy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ export function apiVersionPolicy(options: ClientOptions): PipelinePolicy {
// Append one if there is no apiVesion and we have one at client options
const url = new URL(req.url);
if (!url.searchParams.get("api-version") && options.apiVersion) {
req.url = `${req.url}${
Array.from(url.searchParams.keys()).length > 0 ? "&" : "?"
}api-version=${options.apiVersion}`;
req.url = `${req.url}${url.searchParams.size > 0 ? "&" : "?"}api-version=${options.apiVersion}`;
}

return next(req);
Expand Down
22 changes: 8 additions & 14 deletions sdk/core/core-client-rest/src/clientHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

import type { HttpClient, Pipeline } from "@azure/core-rest-pipeline";
import type { Pipeline } from "@azure/core-rest-pipeline";
import {
bearerTokenAuthenticationPolicy,
createDefaultHttpClient,
createPipelineFromOptions,
} from "@azure/core-rest-pipeline";
import type { KeyCredential, TokenCredential } from "@azure/core-auth";
Expand All @@ -14,8 +13,6 @@ import type { ClientOptions } from "./common.js";
import { apiVersionPolicy } from "./apiVersionPolicy.js";
import { keyCredentialAuthenticationPolicy } from "./keyCredentialAuthenticationPolicy.js";

let cachedHttpClient: HttpClient | undefined;

/**
* Optional parameters for adding a credential policy to the pipeline.
*/
Expand Down Expand Up @@ -77,14 +74,11 @@ export function createDefaultPipeline(
return pipeline;
}

function isKeyCredential(credential: any): credential is KeyCredential {
return (credential as KeyCredential).key !== undefined;
}

export function getCachedDefaultHttpsClient(): HttpClient {
if (!cachedHttpClient) {
cachedHttpClient = createDefaultHttpClient();
}

return cachedHttpClient;
function isKeyCredential(credential: unknown): credential is KeyCredential {
return (
typeof credential === "object" &&
credential !== null &&
"key" in credential &&
typeof credential.key === "string"
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export function keyCredentialAuthenticationPolicy(
): PipelinePolicy {
return {
name: keyCredentialAuthenticationPolicyName,
async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {
sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {
request.headers.set(apiKeyHeaderName, credential.key);
return next(request);
},
Expand Down
4 changes: 2 additions & 2 deletions sdk/core/core-client-rest/src/restError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ export function createRestError(
response?: PathUncheckedResponse,
): RestError {
if (typeof messageOrResponse === "string") {
return tspCreateRestError(messageOrResponse, response! as TspPathUncheckedResponse);
return tspCreateRestError(messageOrResponse, response as unknown as TspPathUncheckedResponse);
} else {
return tspCreateRestError(messageOrResponse as TspPathUncheckedResponse);
return tspCreateRestError(messageOrResponse as unknown as TspPathUncheckedResponse);
Comment thread
deyaaeldeen marked this conversation as resolved.
}
}
10 changes: 10 additions & 0 deletions sdk/core/core-client-rest/test/internal/clientHelpers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ describe("clientHelpers", () => {
);
});

it("should not treat a non-string key property as a KeyCredential", () => {
const pipeline = createDefaultPipeline(mockBaseUrl, { key: 123 } as any);
const policies = pipeline.getOrderedPolicies();

assert.isUndefined(
policies.find((p) => p.name === keyCredentialAuthenticationPolicyName),
"pipeline should not have keyCredentialAuthenticationPolicyName for non-string key",
);
});

it("should create a default pipeline with TokenCredential", () => {
const mockCredential: TokenCredential = {
getToken: async () => ({ expiresOnTimestamp: 0, token: "mockToken" }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ function buildScopes(
}

const challengeScopes = new URL(challengeInfo.resource_id);
challengeScopes.pathname = Constants.DefaultScope;
let scope = challengeScopes.toString();
let scope = new URL(Constants.DefaultScope, challengeScopes.origin).toString();
if (scope === "https://disk.azure.com/.default") {
// the extra slash is required by the service
scope = "https://disk.azure.com//.default";
Expand Down
2 changes: 1 addition & 1 deletion sdk/core/core-client/src/serializationPolicy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export function serializationPolicy(options: SerializationPolicyOptions = {}): P

return {
name: serializationPolicyName,
async sendRequest(request: OperationRequest, next: SendRequest): Promise<PipelineResponse> {
sendRequest(request: OperationRequest, next: SendRequest): Promise<PipelineResponse> {
const operationInfo = getOperationRequestInfo(request);
const operationSpec = operationInfo?.operationSpec;
const operationArguments = operationInfo?.operationArguments;
Expand Down
4 changes: 2 additions & 2 deletions sdk/core/core-client/src/serviceClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export class ServiceClient {
/**
* Send the provided httpRequest.
*/
async sendRequest(request: PipelineRequest): Promise<PipelineResponse> {
sendRequest(request: PipelineRequest): Promise<PipelineResponse> {
return this.pipeline.sendRequest(this._httpClient, request);
}

Expand Down Expand Up @@ -255,7 +255,7 @@ function getCredentialScopes(options: ServiceClientOptions): string | string[] |
return `${options.baseUri}/.default`;
}

if (options.credential && !options.credentialScopes) {
if (options.credential) {
throw new Error(
`When using credentials, the ServiceClientOptions must contain either a endpoint or a credentialScopes. Unable to create a bearerTokenAuthenticationPolicy`,
);
Expand Down
10 changes: 10 additions & 0 deletions sdk/core/core-http-compat/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
# Release History

## 2.4.1 (Unreleased)

### Features Added

### Breaking Changes

### Bugs Fixed

### Other Changes

## 2.4.0 (2026-04-07)

### Features Added
Expand Down
2 changes: 1 addition & 1 deletion sdk/core/core-http-compat/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@azure/core-http-compat",
"version": "2.4.0",
"version": "2.4.1",
"description": "Core HTTP Compatibility Library to bridge the gap between Core V1 & V2 packages.",
"sdk-type": "client",
"type": "module",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const disableKeepAlivePolicyName = "DisableKeepAlivePolicy";
export function createDisableKeepAlivePolicy(): PipelinePolicy {
return {
name: disableKeepAlivePolicyName,
async sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {
sendRequest(request: PipelineRequest, next: SendRequest): Promise<PipelineResponse> {
request.disableKeepAlive = true;
return next(request);
},
Expand Down
Loading