Skip to content

Commit dd32e8c

Browse files
committed
stage
1 parent 86bf702 commit dd32e8c

3 files changed

Lines changed: 118 additions & 0 deletions

File tree

packages/scaffold/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
}
7070
},
7171
"dependencies": {
72+
"@fluent/syntax": "^0.19.0",
7273
"@swc/core": "^1.11.16",
7374
"adm-zip": "^0.5.16",
7475
"bumpp": "^10.1.0",
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import type { BaseNode, Message, MessageReference, Resource } from "@fluent/syntax";
2+
import type { BuildConfig } from "../../types/config.js";
3+
import { readFile, writeFile } from "node:fs/promises";
4+
import { basename, dirname } from "node:path";
5+
import { parse, serialize, Transformer } from "@fluent/syntax";
6+
import { move } from "fs-extra/esm";
7+
import { glob } from "tinyglobby";
8+
import { logger } from "../../utils/logger.js";
9+
10+
export async function buildLocale(
11+
dist: string,
12+
namespace: string,
13+
options: BuildConfig["fluent"],
14+
) {
15+
const locales = (await glob(`${dist}/addon/locale/*`, { onlyDirectories: true }))
16+
.map(locale => basename(locale));
17+
18+
const allMessages = new Set<string>();
19+
const messagesByLocale = new Map<string, Set<string>>();
20+
21+
for (const locale of locales) {
22+
// Prefix Fluent messages in each ftl, add message to set.
23+
const localeMessages = new Set<string>();
24+
const ftlPaths = await glob(`${dist}/addon/locale/${locale}/**/*.ftl`);
25+
26+
await Promise.all(ftlPaths.map(async (ftlPath: string) => {
27+
const ftlContent = await readFile(ftlPath, "utf-8");
28+
const messages = getMessages(ftlContent);
29+
messages.forEach((message) => {
30+
localeMessages.add(message);
31+
allMessages.add(message);
32+
});
33+
34+
// If prefixFluentMessages===true, we save the changed ftl file,
35+
// otherwise discard the changes
36+
if (options.prefixFluentMessages) {
37+
const newFtlContent = transformFluent(ftlContent, namespace);
38+
await writeFile(ftlPath, newFtlContent);
39+
}
40+
41+
// rename *.ftl to addonRef-*.ftl
42+
if (options.prefixLocaleFiles === true) {
43+
await move(ftlPath, `${dirname(ftlPath)}/${namespace}-${basename(ftlPath)}`);
44+
logger.debug(`FTL file '${ftlPath}' is renamed to '${namespace}-${basename(ftlPath)}'.`);
45+
}
46+
}));
47+
48+
messagesByLocale.set(locale, localeMessages);
49+
}
50+
}
51+
52+
export function parseFluent(source: string): Resource {
53+
const resource = parse(source, {});
54+
return resource;
55+
}
56+
57+
export function getMessages(source: string) {
58+
const resource = parseFluent(source);
59+
return resource.body
60+
.filter(entry => entry.type === "Message")
61+
.map(message => message.id.name);
62+
}
63+
64+
export function serializeFluent(resource: Resource): string {
65+
const output = serialize(resource, {});
66+
return output;
67+
}
68+
69+
export function transformFluent(source: string, prefix: string | false): string {
70+
const resource = parseFluent(source);
71+
new _Transformer(prefix).genericVisit(resource);
72+
return serializeFluent(resource);
73+
}
74+
75+
class _Transformer extends Transformer {
76+
namespace: string | false;
77+
constructor(namespace: string | false) {
78+
super();
79+
this.namespace = namespace;
80+
}
81+
82+
private needPrefix(name: string): boolean {
83+
if (!this.namespace)
84+
return false;
85+
else if (name.startsWith(this.namespace))
86+
return false;
87+
else
88+
return true;
89+
}
90+
91+
private doPrefix(name: string): string {
92+
return `${this.namespace}-${name}`;
93+
}
94+
95+
visitMessage(node: Message): BaseNode | undefined {
96+
if (this.needPrefix(node.id.name)) {
97+
node.id.name = this.doPrefix(node.id.name);
98+
}
99+
return node;
100+
}
101+
102+
visitMessageReference(node: MessageReference): BaseNode | undefined {
103+
if (this.needPrefix(node.id.name)) {
104+
node.id.name = this.doPrefix(node.id.name);
105+
}
106+
return node;
107+
}
108+
}

pnpm-lock.yaml

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)