Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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