Skip to content

Commit a5fedcf

Browse files
committed
fix(dom): Allow string keys in .formatMessages() and .formatValues() (#180)
1 parent e72a75f commit a5fedcf

2 files changed

Lines changed: 43 additions & 18 deletions

File tree

fluent-dom/src/localization.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ import { CachedAsyncIterable } from "cached-iterable";
66

77
import type { FluentBundle, FluentVariable, Message } from "@fluent/bundle";
88

9-
export type MessageKey = { id: string; args?: Record<string, FluentVariable> };
9+
export type MessageKey =
10+
| string
11+
| { id: string; args?: Record<string, FluentVariable> };
1012
export type FormatMethod<T> = (
1113
bundle: FluentBundle,
1214
messageErrors: Error[],
@@ -286,11 +288,21 @@ function keysFromBundle<T>(
286288
const messageErrors: Error[] = [];
287289
const missingIds = new Set<string>();
288290

289-
keys.forEach(({ id, args }, i) => {
291+
keys.forEach((key, i) => {
290292
if (translations[i] !== undefined) {
291293
return;
292294
}
293295

296+
let id: string;
297+
let args: Record<string, FluentVariable> | undefined;
298+
if (typeof key === "string") {
299+
id = key;
300+
args = undefined;
301+
} else {
302+
id = key.id;
303+
args = key.args;
304+
}
305+
294306
let message = bundle.getMessage(id);
295307
if (message) {
296308
messageErrors.length = 0;
Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import assert from "assert";
21
import { FluentBundle, FluentResource } from "@fluent/bundle";
2+
import { afterEach, beforeAll, expect, vi } from "vitest";
33
import { Localization } from "../src/localization.ts";
4-
import { vi } from "vitest";
54

65
async function* mockGenerateMessages() {
76
const bundle = new FluentBundle(["en-US"]);
@@ -10,21 +9,35 @@ async function* mockGenerateMessages() {
109
yield bundle;
1110
}
1211

13-
suite("formatMessages", function () {
14-
test("returns a translation", async function () {
15-
const loc = new Localization(["test.ftl"], mockGenerateMessages);
16-
const translations = await loc.formatMessages([{ id: "key1" }]);
12+
beforeAll(() => vi.spyOn(console, "warn").mockImplementation(() => {}));
13+
afterEach(vi.clearAllMocks);
1714

18-
assert.strictEqual(translations[0].value, "Key 1");
19-
});
15+
for (const [name, keys] of [
16+
["string keys", ["missing_key", "key1"]],
17+
["object keys", [{ id: "missing_key" }, { id: "key1" }]],
18+
]) {
19+
suite(name, () => {
20+
test("formatMessages", async function () {
21+
const loc = new Localization(["test.ftl"], mockGenerateMessages);
22+
const translations = await loc.formatMessages(keys);
23+
24+
expect(translations).toEqual([
25+
undefined,
26+
{ value: "Key 1", attributes: null },
27+
]);
28+
expect(console.warn.mock.calls).toEqual([
29+
["[fluent] Missing translations in en-US: missing_key"],
30+
]);
31+
});
2032

21-
test("returns undefined for a missing translation", async function () {
22-
vi.spyOn(console, "warn").mockImplementation(() => {});
23-
const loc = new Localization(["test.ftl"], mockGenerateMessages);
24-
const translations = await loc.formatMessages([{ id: "missing_key" }]);
33+
test("formatValues", async function () {
34+
const loc = new Localization(["test.ftl"], mockGenerateMessages);
35+
const translations = await loc.formatValues(keys);
2536

26-
// Make sure that the returned value here is `undefined`.
27-
// This allows bindings to handle missing translations.
28-
assert.strictEqual(translations[1], undefined);
37+
expect(translations).toEqual([undefined, "Key 1"]);
38+
expect(console.warn.mock.calls).toEqual([
39+
["[fluent] Missing translations in en-US: missing_key"],
40+
]);
41+
});
2942
});
30-
});
43+
}

0 commit comments

Comments
 (0)