Skip to content

Commit 87b0dbc

Browse files
authored
Add back ReadonlyMap APIs (#52)
1 parent 28a5c69 commit 87b0dbc

File tree

3 files changed

+98
-1
lines changed

3 files changed

+98
-1
lines changed

src/AzureAppConfiguration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export type AzureAppConfiguration = {
1616
* @param thisArg - Optional. Value to use as `this` when executing callback.
1717
*/
1818
onRefresh(listener: () => any, thisArg?: any): Disposable;
19-
} & IGettable & IConfigurationObject;
19+
} & IGettable & ReadonlyMap<string, any> & IConfigurationObject;
2020

2121
interface IConfigurationObject {
2222
/**

src/AzureAppConfigurationImpl.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,39 @@ export class AzureAppConfigurationImpl implements AzureAppConfiguration {
9191
this.#adapters.push(new JsonKeyValueAdapter());
9292
}
9393

94+
// ReadonlyMap APIs
9495
get<T>(key: string): T | undefined {
9596
return this.#configMap.get(key);
9697
}
9798

99+
forEach(callbackfn: (value: any, key: string, map: ReadonlyMap<string, any>) => void, thisArg?: any): void {
100+
this.#configMap.forEach(callbackfn, thisArg);
101+
}
102+
103+
has(key: string): boolean {
104+
return this.#configMap.has(key);
105+
}
106+
107+
get size(): number {
108+
return this.#configMap.size;
109+
}
110+
111+
entries(): IterableIterator<[string, any]> {
112+
return this.#configMap.entries();
113+
}
114+
115+
keys(): IterableIterator<string> {
116+
return this.#configMap.keys();
117+
}
118+
119+
values(): IterableIterator<any> {
120+
return this.#configMap.values();
121+
}
122+
123+
[Symbol.iterator](): IterableIterator<[string, any]> {
124+
return this.#configMap[Symbol.iterator]();
125+
}
126+
98127
get #refreshEnabled(): boolean {
99128
return !!this.#options?.refreshOptions?.enabled;
100129
}

test/load.test.ts

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,74 @@ describe("load", function () {
110110
return expect(load("invalid-endpoint-url", credential)).eventually.rejectedWith("Invalid endpoint URL.");
111111
});
112112

113+
it("should filter by key and label, has(key) and get(key) should work", async () => {
114+
const connectionString = createMockedConnectionString();
115+
const settings = await load(connectionString, {
116+
selectors: [{
117+
keyFilter: "app.settings.*",
118+
labelFilter: "\0"
119+
}]
120+
});
121+
expect(settings).not.undefined;
122+
expect(settings.has("app.settings.fontColor")).true;
123+
expect(settings.has("app.settings.fontSize")).true;
124+
expect(settings.has("app.settings.fontFamily")).false;
125+
expect(settings.get("app.settings.fontColor")).eq("red");
126+
expect(settings.get("app.settings.fontSize")).eq("40");
127+
expect(settings.get("app.settings.fontFamily")).undefined;
128+
});
129+
130+
it("should also work with other ReadonlyMap APIs", async () => {
131+
const connectionString = createMockedConnectionString();
132+
const settings = await load(connectionString, {
133+
selectors: [{
134+
keyFilter: "app.settings.*",
135+
labelFilter: "\0"
136+
}]
137+
});
138+
expect(settings).not.undefined;
139+
// size
140+
expect(settings.size).eq(2);
141+
// keys()
142+
expect(Array.from(settings.keys())).deep.eq(["app.settings.fontColor", "app.settings.fontSize"]);
143+
// values()
144+
expect(Array.from(settings.values())).deep.eq(["red", "40"]);
145+
// entries()
146+
expect(Array.from(settings.entries())).deep.eq([["app.settings.fontColor", "red"], ["app.settings.fontSize", "40"]]);
147+
// forEach()
148+
const keys: string[] = [];
149+
const values: string[] = [];
150+
settings.forEach((value, key) => {
151+
keys.push(key);
152+
values.push(value);
153+
});
154+
expect(keys).deep.eq(["app.settings.fontColor", "app.settings.fontSize"]);
155+
expect(values).deep.eq(["red", "40"]);
156+
// [Symbol.iterator]()
157+
const entries: [string, string][] = [];
158+
for (const [key, value] of settings) {
159+
entries.push([key, value]);
160+
}
161+
expect(entries).deep.eq([["app.settings.fontColor", "red"], ["app.settings.fontSize", "40"]]);
162+
});
163+
164+
it("should be read-only, set(key, value) should not work", async () => {
165+
const connectionString = createMockedConnectionString();
166+
const settings = await load(connectionString, {
167+
selectors: [{
168+
keyFilter: "app.settings.*",
169+
labelFilter: "\0"
170+
}]
171+
});
172+
expect(settings).not.undefined;
173+
expect(() => {
174+
// Here force to turn if off for testing purpose, as JavaScript does not have type checking.
175+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
176+
// @ts-ignore
177+
settings.set("app.settings.fontColor", "blue");
178+
}).to.throw("settings.set is not a function");
179+
});
180+
113181
it("should trim key prefix if applicable", async () => {
114182
const connectionString = createMockedConnectionString();
115183
const settings = await load(connectionString, {

0 commit comments

Comments
 (0)