Skip to content
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@

export { AzureAppConfiguration } from "./AzureAppConfiguration";
export { Disposable } from "./common/disposable";
export { load } from "./load";
export { load, loadCdn } from "./load";
export { KeyFilter, LabelFilter } from "./types";
48 changes: 48 additions & 0 deletions src/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,54 @@ export async function load(
}
}

/**
* Loads the data from a CDN and returns an instance of AzureAppConfiguration.
* @param endpoint The URL to the CDN.
* @param options Optional parameters.
*/
export async function loadCdn(endpoint: URL | string, options?: AzureAppConfigurationOptions): Promise<AzureAppConfiguration>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if it makes more sense to name it loadFromCDN insead.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will use camelCase, so it will be loadFromCdn


export async function loadCdn(
endpoint: string | URL,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it will be too much to call it cdnEndpoint or it's clearer? The reason I'm asking is because we also have the other parameter appConfigOptions. Will that confuse users that it's appconfig endpoint?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am ok with cdnEndpoint. Updated.

appConfigOptions?: AzureAppConfigurationOptions
): Promise<AzureAppConfiguration> {
const startTimestamp = Date.now();
if (typeof endpoint === "string") {
try {
endpoint = new URL(endpoint);
} catch (error) {
if (error.code === "ERR_INVALID_URL") {
throw new Error("Invalid endpoint URL.", { cause: error });
} else {
throw error;
}
}
}
const emptyTokenCredential: TokenCredential = {
getToken: async () => ({ token: "", expiresOnTimestamp: 0 })
};
const options = appConfigOptions;
const clientOptions = getClientOptions(options);
// App Configuration SDK will not distinguish between CDN and App Configuration endpoints. The SDK will just send request to the endpoint with the given token credential.
// CDN should be the front door of App Configuration and forward the request to the App Configuration service.
const client = new AppConfigurationClient(endpoint.toString(), emptyTokenCredential, clientOptions);

try {
const appConfiguration = new AzureAppConfigurationImpl(client, options);
await appConfiguration.load();
return appConfiguration;
} catch (error) {
// load() method is called in the application's startup code path.
// Unhandled exceptions cause application crash which can result in crash loops as orchestrators attempt to restart the application.
// Knowing the intended usage of the provider in startup code path, we mitigate back-to-back crash loops from overloading the server with requests by waiting a minimum time to propagate fatal errors.
const delay = MIN_DELAY_FOR_UNHANDLED_ERROR - (Date.now() - startTimestamp);
if (delay > 0) {
await new Promise((resolve) => setTimeout(resolve, delay));
}
throw error;
}
}

function instanceOfTokenCredential(obj: unknown) {
return obj && typeof obj === "object" && "getToken" in obj && typeof obj.getToken === "function";
}
Expand Down
Loading