Skip to content
2,459 changes: 1,193 additions & 1,266 deletions package-lock.json

Large diffs are not rendered by default.

19 changes: 10 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@azure/app-configuration-provider",
"version": "2.4.2",
"version": "2.5.0",
"description": "The JavaScript configuration provider for Azure App Configuration",
"files": [
"dist/",
Expand Down Expand Up @@ -45,27 +45,28 @@
"@types/chai-as-promised": "8.0.2",
"@types/mocha": "^10.0.10",
"@types/node": "^22.18.0",
"@types/sinon": "^17.0.4",
"@types/sinon": "^21.0.1",
"@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^8.41.0",
"@typescript-eslint/parser": "^8.41.0",
"@vitest/browser": "^4.1.8",
"@vitest/browser-playwright": "^4.1.8",
"chai": "^4.5.0",
"chai-as-promised": "^7.1.2",
"cpy-cli": "^6.0.0",
"dotenv": "^17.2.1",
"eslint": "^9.34.0",
"mocha": "^11.7.1",
"mocha": "^11.7.6",
"nock": "^14.0.10",
"playwright": "^1.60.0",
"rimraf": "^6.0.1",
"rollup": "^4.50.0",
"rollup": "^4.59.0",
"rollup-plugin-dts": "^6.2.3",
"sinon": "^21.0.0",
"sinon": "^21.1.2",
"tslib": "^2.8.1",
"typescript": "^5.9.2",
"uuid": "^11.1.0",
"vitest": "^3.2.4",
"@vitest/browser": "^3.2.4",
"playwright": "^1.55.0"
"uuid": "^14.0.0",
"vitest": "^4.1.8"
},
"dependencies": {
"@azure/app-configuration": "^1.11.0",
Expand Down
25 changes: 13 additions & 12 deletions src/appConfigurationImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,18 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
#sentinels: Map<WatchedSetting, SettingWatcher> = new Map();
#watchAll: boolean = false;
#kvRefreshInterval: number = DEFAULT_REFRESH_INTERVAL_IN_MS;
#kvRefreshTimer: RefreshTimer;
#kvRefreshTimer: RefreshTimer | undefined = undefined;

// Feature flags
#featureFlagEnabled: boolean = false;
#featureFlagRefreshEnabled: boolean = false;
#ffRefreshInterval: number = DEFAULT_REFRESH_INTERVAL_IN_MS;
#ffRefreshTimer: RefreshTimer;
#ffRefreshTimer: RefreshTimer | undefined = undefined;

// Key Vault references
#secretRefreshEnabled: boolean = false;
#secretReferences: ConfigurationSetting[] = []; // cached key vault references
#secretRefreshTimer: RefreshTimer;
#secretRefreshTimer: RefreshTimer | undefined = undefined;
#resolveSecretsInParallel: boolean = false;

/**
Expand All @@ -126,7 +126,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {

constructor(
clientManager: ConfigurationClientManager,
options: AzureAppConfigurationOptions | undefined,
options?: AzureAppConfigurationOptions,
) {
this.#options = options;
this.#clientManager = clientManager;
Expand Down Expand Up @@ -415,7 +415,8 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
postAttempts += 1;
backoffDuration = getExponentialBackoffDuration(postAttempts);
}
console.warn(`Failed to load. Error message: ${error.message}. Retrying in ${backoffDuration} ms.`);
const errorMessage = error instanceof Error ? error.message : String(error);
console.warn(`Failed to load. Error message: ${errorMessage}. Retrying in ${backoffDuration} ms.`);
await new Promise(resolve => setTimeout(resolve, backoffDuration));
}
} while (!abortSignal.aborted);
Expand Down Expand Up @@ -690,7 +691,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
*/
async #refreshFeatureFlags(): Promise<boolean> {
// if still within refresh interval/backoff, return
if (this.#ffRefreshInterval === undefined || !this.#ffRefreshTimer.canRefresh()) {
if (this.#ffRefreshInterval === undefined || !this.#ffRefreshTimer!.canRefresh()) {
return Promise.resolve(false);
}

Expand All @@ -699,7 +700,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
await this.#loadFeatureFlags();
}

this.#ffRefreshTimer.reset();
this.#ffRefreshTimer!.reset();
return Promise.resolve(needRefresh);
}

Expand Down Expand Up @@ -728,7 +729,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
* @returns true if key-value collection has changed, false otherwise.
*/
async #checkConfigurationSettingsChange(selectors: PagedSettingsWatcher[]): Promise<boolean> {
const funcToExecute = async (client) => {
const funcToExecute = async (client: AppConfigurationClient) => {
for (const selector of selectors) {
if (selector.snapshotName) { // skip snapshot selector
continue;
Expand Down Expand Up @@ -765,7 +766,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
* Gets a configuration setting by key and label.If the setting is not found, return undefine instead of throwing an error.
*/
async #getConfigurationSetting(configurationSettingId: ConfigurationSettingId, getOptions?: GetConfigurationSettingOptions): Promise<GetConfigurationSettingResponse | undefined> {
const funcToExecute = async (client) => {
const funcToExecute = async (client: AppConfigurationClient) => {
return getConfigurationSettingWithTrace(
this.#requestTraceOptions,
client,
Expand All @@ -788,7 +789,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
}

async #listConfigurationSettings(listOptions: ListConfigurationSettingsOptions): Promise<{ items: ConfigurationSetting[]; pageWatchers: SettingWatcher[] }> {
const funcToExecute = async (client) => {
const funcToExecute = async (client: AppConfigurationClient) => {
const pageWatchers: SettingWatcher[] = [];
const pageIterator = listConfigurationSettingsWithTrace(
this.#requestTraceOptions,
Expand All @@ -808,7 +809,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
}

async #getSnapshot(snapshotName: string, getOptions?: GetSnapshotOptions): Promise<GetSnapshotResponse | undefined> {
const funcToExecute = async (client) => {
const funcToExecute = async (client: AppConfigurationClient) => {
return getSnapshotWithTrace(
this.#requestTraceOptions,
client,
Expand All @@ -831,7 +832,7 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
}

async #listConfigurationSettingsForSnapshot(snapshotName: string, listOptions?: ListConfigurationSettingsForSnapshotOptions): Promise<ConfigurationSetting[]> {
const funcToExecute = async (client) => {
const funcToExecute = async (client: AppConfigurationClient) => {
const pageIterator = listConfigurationSettingsForSnapshotWithTrace(
this.#requestTraceOptions,
client,
Expand Down
8 changes: 4 additions & 4 deletions src/common/contentType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type ContentType = {
parameters: Record<string, string>;
}

export function parseContentType(contentTypeValue: string | undefined): ContentType | undefined {
export function parseContentType(contentTypeValue?: string): ContentType | undefined {
if (!contentTypeValue) {
return undefined;
}
Expand All @@ -27,7 +27,7 @@ export function parseContentType(contentTypeValue: string | undefined): ContentT

// Determine whether a content type string is a valid JSON content type.
// https://docs.microsoft.com/en-us/azure/azure-app-configuration/howto-leverage-json-content-type
export function isJsonContentType(contentType: ContentType | undefined): boolean {
export function isJsonContentType(contentType?: ContentType): boolean {
const mediaType = contentType?.mediaType;
if (!mediaType) {
return false;
Expand All @@ -45,15 +45,15 @@ export function isJsonContentType(contentType: ContentType | undefined): boolean
return typeParts[1].split("+").includes("json");
}

export function isFeatureFlagContentType(contentType: ContentType | undefined): boolean {
export function isFeatureFlagContentType(contentType?: ContentType): boolean {
const mediaType = contentType?.mediaType;
if (!mediaType) {
return false;
}
return mediaType === featureFlagContentType;
}

export function isSecretReferenceContentType(contentType: ContentType | undefined): boolean {
export function isSecretReferenceContentType(contentType?: ContentType): boolean {
const mediaType = contentType?.mediaType;
if (!mediaType) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/keyvault/keyVaultKeyValueAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export class AzureKeyVaultKeyValueAdapter implements IKeyValueAdapter {
#keyVaultOptions: KeyVaultOptions | undefined;
#keyVaultSecretProvider: AzureKeyVaultSecretProvider;

constructor(keyVaultOptions: KeyVaultOptions | undefined, refreshTimer?: RefreshTimer) {
constructor(keyVaultOptions?: KeyVaultOptions, refreshTimer?: RefreshTimer) {
this.#keyVaultOptions = keyVaultOptions;
this.#keyVaultSecretProvider = new AzureKeyVaultSecretProvider(keyVaultOptions, refreshTimer);
}
Expand Down
4 changes: 2 additions & 2 deletions src/keyvault/keyVaultOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ export interface KeyVaultOptions {
/**
* Specifies the callback used to resolve key vault references that have no applied SecretClient.
* @param keyVaultReference The Key Vault reference to resolve.
* @returns The secret value.
* @returns The secret value, which can be of any type.
*/
secretResolver?: (keyVaultReference: URL) => string | Promise<string>;
secretResolver?: (keyVaultReference: URL) => any | Promise<any>;

/**
* Specifies whether to resolve the secret value in parallel.
Expand Down
2 changes: 1 addition & 1 deletion src/keyvault/keyVaultSecretProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class AzureKeyVaultSecretProvider {
#secretClients: Map<string, SecretClient>; // map key vault hostname to corresponding secret client
#cachedSecretValues: Map<string, any> = new Map<string, any>(); // map secret identifier to secret value

constructor(keyVaultOptions: KeyVaultOptions | undefined, refreshTimer?: RefreshTimer) {
constructor(keyVaultOptions?: KeyVaultOptions, refreshTimer?: RefreshTimer) {
if (keyVaultOptions?.secretRefreshIntervalInMs !== undefined) {
if (refreshTimer === undefined) {
throw new ArgumentError("Refresh timer must be specified when Key Vault secret refresh is enabled.");
Expand Down
2 changes: 1 addition & 1 deletion src/version.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

export const VERSION = "2.4.2";
export const VERSION = "2.5.0";
3 changes: 2 additions & 1 deletion vitest.browser.config.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { playwright } from "@vitest/browser-playwright";
import { defineConfig } from "vitest/config";

export default defineConfig({
test: {
browser: {
enabled: true,
provider: "playwright",
provider: playwright(),
headless: true,
instances: [
{ browser: "chromium" },
Expand Down
Loading