Skip to content

Commit d65cf65

Browse files
authored
Enable useAwait and noFloatingPromises biome rules
- Adds `suspicious/useAwait` and `nursery/noFloatingPromises` as errors in biome.json for SDK-level async correctness. - Removes redundant `async` modifiers from wrapper methods in ConfigClient and ConfigWatcher that delegated directly to Promise-returning helpers. - Adds biome-ignore suppressions for `await using` IIFEs in tests (Biome does not recognise `await using` as an await expression). Closes #66
1 parent fb776fb commit d65cf65

5 files changed

Lines changed: 24 additions & 14 deletions

File tree

biome.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
{
2-
"$schema": "https://biomejs.dev/schemas/2.4.13/schema.json",
2+
"$schema": "https://biomejs.dev/schemas/2.4.15/schema.json",
33
"assist": { "actions": { "source": { "organizeImports": "on" } } },
44
"linter": {
55
"enabled": true,
66
"rules": {
7-
"recommended": true
7+
"recommended": true,
8+
"suspicious": {
9+
"useAwait": "error"
10+
},
11+
"nursery": {
12+
"noFloatingPromises": "error"
13+
}
814
}
915
},
1016
"formatter": {

src/client.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ export class ConfigClient {
222222
*
223223
* @returns A record mapping field paths to their string values.
224224
*/
225-
async getAll(
225+
getAll(
226226
tenantId: string,
227227
options?: { timeout?: number; signal?: AbortSignal },
228228
): Promise<Record<string, string>> {
@@ -250,7 +250,7 @@ export class ConfigClient {
250250
* coerces it to the schema-defined type. For type-safe writes, prefer
251251
* setNumber(), setBool(), setTime(), or setDuration().
252252
*/
253-
async set(
253+
set(
254254
tenantId: string,
255255
fieldPath: string,
256256
value: string,
@@ -281,7 +281,7 @@ export class ConfigClient {
281281
}
282282

283283
/** Set a numeric config value. Sends the native number as a proto numberValue. */
284-
async setNumber(
284+
setNumber(
285285
tenantId: string,
286286
fieldPath: string,
287287
value: number,
@@ -296,7 +296,7 @@ export class ConfigClient {
296296
}
297297

298298
/** Set a boolean config value. Sends the native boolean as a proto boolValue. */
299-
async setBool(
299+
setBool(
300300
tenantId: string,
301301
fieldPath: string,
302302
value: boolean,
@@ -311,7 +311,7 @@ export class ConfigClient {
311311
}
312312

313313
/** Set a timestamp config value. Sends the Date as a proto timeValue. */
314-
async setTime(
314+
setTime(
315315
tenantId: string,
316316
fieldPath: string,
317317
value: Date,
@@ -329,7 +329,7 @@ export class ConfigClient {
329329
* Set a duration config value. The value must be a duration string
330330
* (e.g. "1h30m", "300s") — the server parses and validates the format.
331331
*/
332-
async setDuration(
332+
setDuration(
333333
tenantId: string,
334334
fieldPath: string,
335335
value: string,
@@ -350,7 +350,7 @@ export class ConfigClient {
350350
* @param options - Optional description for the audit log, idempotency key for safe DEADLINE_EXCEEDED retries,
351351
* and per-field expected checksums for optimistic concurrency control.
352352
*/
353-
async setMany(
353+
setMany(
354354
tenantId: string,
355355
values: Record<string, SetValue>,
356356
options?: {
@@ -383,7 +383,7 @@ export class ConfigClient {
383383
/**
384384
* Set a config field to null.
385385
*/
386-
async setNull(
386+
setNull(
387387
tenantId: string,
388388
fieldPath: string,
389389
options?: {
@@ -462,13 +462,14 @@ export class ConfigClient {
462462
/**
463463
* Async dispose pattern support — use with `await using`.
464464
*/
465-
async [Symbol.asyncDispose](): Promise<void> {
465+
[Symbol.asyncDispose](): Promise<void> {
466466
this.close();
467+
return Promise.resolve();
467468
}
468469

469470
// --- Private helpers ---
470471

471-
private async setTyped(
472+
private setTyped(
472473
tenantId: string,
473474
fieldPath: string,
474475
value: SetValue,

src/watcher.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -389,9 +389,9 @@ export class ConfigWatcher extends EventEmitter {
389389
* Safe to call multiple times. After stopping, registered WatchedField
390390
* async iterators will complete.
391391
*/
392-
async stop(): Promise<void> {
392+
stop(): Promise<void> {
393393
if (this.stopped) {
394-
return;
394+
return Promise.resolve();
395395
}
396396
this.stopped = true;
397397

@@ -408,6 +408,7 @@ export class ConfigWatcher extends EventEmitter {
408408
for (const field of this.fields.values()) {
409409
field._stop();
410410
}
411+
return Promise.resolve();
411412
}
412413

413414
/**

test/client.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,7 @@ describe("ConfigClient", () => {
645645
});
646646

647647
it("works with await using", async () => {
648+
// biome-ignore lint/suspicious/useAwait: await using satisfies the await requirement but biome doesn't recognise it yet
648649
await (async () => {
649650
await using c = client;
650651
void c;

test/watcher.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ describe("ConfigWatcher", () => {
502502
watcher.field("payments.fee", Number, { default: 0.01 });
503503
await watcher.start();
504504

505+
// biome-ignore lint/suspicious/useAwait: await using satisfies the await requirement but biome doesn't recognise it yet
505506
await (async () => {
506507
await using w = watcher;
507508
void w;

0 commit comments

Comments
 (0)