Skip to content

Merge main to release/preview/v1 #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from 15 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
38 changes: 25 additions & 13 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,47 @@ These examples show how to use the JavaScript Provider for Azure App Configurati

## Prerequisites

The sample programs are compatible with [LTS versions of Node.js](https://github.com/nodejs/release#release-schedule).
The examples are compatible with [LTS versions of Node.js](https://github.com/nodejs/release#release-schedule).

You need [an Azure subscription](https://azure.microsoft.com/free/) and the following Azure resources to run these sample programs:
You need [an Azure subscription](https://azure.microsoft.com/free/) and the following Azure resources to run the examples:

- [Azure App Configuration store](https://learn.microsoft.com/en-us/azure/azure-app-configuration/quickstart-azure-app-configuration-create?tabs=azure-portal)

Samples retrieve credentials to access your App Configuration store from environment variables.
The examples retrieve credentials to access your App Configuration store from environment variables.
Alternatively, edit the source code to include the appropriate credentials.
See each individual sample for details on which environment variables/credentials it requires to function.
See each individual example for details on which environment variables/credentials it requires to function.

## Setup
## Add a key-value
Add the following key-value to the App Configuration store and leave **Label** and **Content Type** with their default values. For more information about how to add key-values to a store using the Azure portal or the CLI, go to [Create a key-value](./quickstart-azure-app-configuration-create.md#create-a-key-value).

To run the samples using the published version of the package:
| Key | Value |
|------------------------|----------------|
| *app.settings.message* | *Hello World!* |

## Setup & Run

To run the examples using the published version of the package:

1. Install the dependencies using `npm`:

```bash
npm install
```

2. There are two ways to run the samples using correct credentials:
2. There are two ways to run the examples using correct credentials:

- Edit the file `.env.template`, adding the access keys to your App Configuration store. and rename the file from `.env.template` to just `.env`. The examples will read this file automatically.

- Edit the file `.env.template`, adding the correct credentials to access your Azure App Configuration store and rename the file from `.env.template` to just `.env`.
Then run the samples, it will read this file automatically.
- Alternatively, you can set the environment variables to the access keys to your App Configuration store. In this case, setting up the `.env` file is not required.
```bash
npx cross-env APPCONFIG_CONNECTION_STRING="<appconfig connection string>"
```

3. Run the examples:
```bash
node helloworld.mjs
```

- Alternatively, run a single sample with the correct environment variables set (setting up the `.env` file is not required if you do this), for example (cross-platform):
```bash
npx cross-env APPCONFIG_CONNECTION_STRING="<appconfig connection string>" node helloworld.mjs
You should see the following output:
```Output
Message from Azure App Configuration: Hello World!
```
2 changes: 1 addition & 1 deletion examples/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"dependencies": {
"@azure/app-configuration-provider": "latest",
"@azure/identity": "^3.3.0",
"@azure/identity": "^4.0.0",
"dotenv": "^16.3.1"
}
}
44 changes: 44 additions & 0 deletions examples/refresh.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import * as dotenv from "dotenv";
import { promisify } from "util";
dotenv.config();
const sleepInMs = promisify(setTimeout);

/**
* This example retrives all settings with key following pattern "app.settings.*", i.e. starting with "app.settings.".
* With the option `trimKeyPrefixes`, it trims the prefix "app.settings." from keys for simplicity.
* Value of config "app.settings.message" will be printed.
* It also watches for changes to the key "app.settings.sentinel" and refreshes the configuration when it changes.
*
* Below environment variables are required for this example:
* - APPCONFIG_CONNECTION_STRING
*/

import { load } from "@azure/app-configuration-provider";
const connectionString = process.env.APPCONFIG_CONNECTION_STRING;
const settings = await load(connectionString, {
selectors: [{
keyFilter: "app.settings.*"
}],
trimKeyPrefixes: ["app.settings."],
refreshOptions: {
watchedSettings: [{ key: "app.settings.sentinel" }],
refreshIntervalInMs: 10 * 1000 // Default value is 30 seconds, shorted for this sample
}
});

console.log("Using Azure portal or CLI, update the `app.settings.message` value, and then update the `app.settings.sentinel` value in your App Configuration store.")

// eslint-disable-next-line no-constant-condition
while (true) {
// Refreshing the configuration setting
await settings.refresh();

// Current value of message
console.log(settings.get("message"));

// Waiting before the next refresh
await sleepInMs(5000);
}
93 changes: 37 additions & 56 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"dev": "rollup --config --watch",
"lint": "eslint src/ test/",
"fix-lint": "eslint src/ test/ --fix",
"test": "mocha out/test/*.test.{js,cjs,mjs} --timeout 10000"
"test": "mocha out/test/*.test.{js,cjs,mjs} --parallel"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -56,7 +56,7 @@
},
"dependencies": {
"@azure/app-configuration": "^1.5.0",
"@azure/identity": "^3.3.2",
"@azure/identity": "^4.0.0",
"@azure/keyvault-secrets": "^4.7.0"
}
}
27 changes: 27 additions & 0 deletions scripts/build-and-pack.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash

# Stop on error.
set -e

# Get the directory of the script.
SCRIPT_DIR=$(dirname $(readlink -f $0))

# Get the directory of the project.
PROJECT_BASE_DIR=$(dirname $SCRIPT_DIR)

# Change to the project directory.
cd $PROJECT_BASE_DIR

# Install dependencies, build, and test.
echo "npm clean install"
npm ci

echo "npm run build"
npm run build

echo "npm run test"
npm run test

# Create a tarball.
echo "npm pack"
npm pack
42 changes: 40 additions & 2 deletions src/AzureAppConfiguration.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,44 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

import { Disposable } from "./common/disposable";

export type AzureAppConfiguration = {
// methods for advanced features, e.g. refresh()
} & ReadonlyMap<string, any>;
/**
* API to trigger refresh operation.
*/
refresh(): Promise<void>;

/**
* API to register callback listeners, which will be called only when a refresh operation successfully updates key-values.
*
* @param listener - Callback funtion to be registered.
* @param thisArg - Optional. Value to use as `this` when executing callback.
*/
onRefresh(listener: () => any, thisArg?: any): Disposable;
} & IGettable & IConfigurationObject;

interface IConfigurationObject {
/**
* Construct configuration object based on Map-styled data structure and hierarchical keys.
* @param options - The options to control the conversion behavior.
*/
constructConfigurationObject(options?: ConfigurationObjectConstructionOptions): Record<string, any>;
}

export interface ConfigurationObjectConstructionOptions {
/**
* The separator to use when converting hierarchical keys to object properties.
* Supported values: '.', ',', ';', '-', '_', '__', '/', ':'.
* If separator is undefined, '.' will be used by default.
*/
separator?: "." | "," | ";" | "-" | "_" | "__" | "/" | ":";
}

interface IGettable {
/**
* Get the value of a key-value from the Map-styled data structure.
* @param key - The key of the key-value to be retrieved.
*/
get<T>(key: string): T | undefined;
}
Loading