lightnet 4.7.0 → 4.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/package.json +1 -1
- package/src/i18n/record-translation.ts +14 -0
- package/src/i18n/translate.ts +13 -37
- package/src/i18n/translations.ts +40 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# lightnet
|
|
2
2
|
|
|
3
|
+
## 4.7.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#469](https://github.com/LightNetDev/LightNet/pull/469) [`a0961c4`](https://github.com/LightNetDev/LightNet/commit/a0961c40fdc30a93d3d5c814343f9c12ec26b2ef) - Warn about user-defined ln.* translation overrides that no longer match a built-in English key. Include source filenames and check unused keys without failing check-translations for stale overrides alone.
|
|
8
|
+
|
|
9
|
+
- [#469](https://github.com/LightNetDev/LightNet/pull/469) [`a0961c4`](https://github.com/LightNetDev/LightNet/commit/a0961c40fdc30a93d3d5c814343f9c12ec26b2ef) - Only record translation keys requested during the build, so check-translations no longer reports missing translations for unused built-in or user keys.
|
|
10
|
+
|
|
3
11
|
## 4.7.0
|
|
4
12
|
|
|
5
13
|
### Minor Changes
|
package/package.json
CHANGED
|
@@ -25,6 +25,20 @@ const recordedTranslations = new Set<string>()
|
|
|
25
25
|
|
|
26
26
|
const translationStore = lazy(() => createTranslationStore())
|
|
27
27
|
|
|
28
|
+
export async function writeStaleTranslationOverrides(
|
|
29
|
+
overrides: { key: string; path: string }[],
|
|
30
|
+
) {
|
|
31
|
+
if (!import.meta.env.PROD) {
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
await mkdir(lightnetCachePath, { recursive: true })
|
|
35
|
+
await writeFile(
|
|
36
|
+
resolve(lightnetCachePath, "stale-translation-overrides.json"),
|
|
37
|
+
JSON.stringify(overrides),
|
|
38
|
+
"utf-8",
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
28
42
|
const writeLanguagesManifest = async () => {
|
|
29
43
|
const manifestPath = resolve(lightnetCachePath, "languages.json")
|
|
30
44
|
const { defaultLocale, locales } = config
|
package/src/i18n/translate.ts
CHANGED
|
@@ -68,7 +68,6 @@ export async function useTranslate(
|
|
|
68
68
|
const resolvedLocale = bcp47 ?? config.defaultLocale
|
|
69
69
|
const translations = await i18nextTranslations.get()
|
|
70
70
|
const availableTranslationKeys = new Set(await translationKeys.get())
|
|
71
|
-
recordAllTranslations()
|
|
72
71
|
|
|
73
72
|
const i18n = i18next.createInstance()
|
|
74
73
|
|
|
@@ -87,6 +86,19 @@ export async function useTranslate(
|
|
|
87
86
|
"en",
|
|
88
87
|
]
|
|
89
88
|
return (input, options) => {
|
|
89
|
+
if (import.meta.env.PROD) {
|
|
90
|
+
recordTranslation({
|
|
91
|
+
key: input,
|
|
92
|
+
type: input.startsWith("ln.") ? "lightnet" : "user",
|
|
93
|
+
values: Object.fromEntries(
|
|
94
|
+
config.locales.map((locale) => [
|
|
95
|
+
locale,
|
|
96
|
+
translations[locale]?.translation[input],
|
|
97
|
+
]),
|
|
98
|
+
),
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
90
102
|
const t = i18n.getFixedT(resolvedLocale) as (
|
|
91
103
|
key: TranslationKey,
|
|
92
104
|
options?: TOptions,
|
|
@@ -101,39 +113,3 @@ export async function useTranslate(
|
|
|
101
113
|
return value
|
|
102
114
|
}
|
|
103
115
|
}
|
|
104
|
-
|
|
105
|
-
async function recordAllTranslations() {
|
|
106
|
-
if (!import.meta.env.PROD) {
|
|
107
|
-
// only record translations during build time
|
|
108
|
-
return
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const { locales } = config
|
|
112
|
-
const localesIncludingEnglish = [...locales.filter((l) => l !== "en"), "en"]
|
|
113
|
-
const keys = await translationKeys.get()
|
|
114
|
-
const translations = await i18nextTranslations.get()
|
|
115
|
-
|
|
116
|
-
const collectValues = (key: string, locales: string[]) => {
|
|
117
|
-
const values = {} as Record<string, string | undefined>
|
|
118
|
-
for (const locale of locales) {
|
|
119
|
-
values[locale] = translations[locale]?.translation[key]
|
|
120
|
-
}
|
|
121
|
-
return values
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
for (const key of keys) {
|
|
125
|
-
if (key.startsWith("ln.")) {
|
|
126
|
-
recordTranslation({
|
|
127
|
-
key,
|
|
128
|
-
values: collectValues(key, localesIncludingEnglish),
|
|
129
|
-
type: "lightnet",
|
|
130
|
-
})
|
|
131
|
-
} else {
|
|
132
|
-
recordTranslation({
|
|
133
|
-
key,
|
|
134
|
-
values: collectValues(key, locales),
|
|
135
|
-
type: "user",
|
|
136
|
-
})
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
package/src/i18n/translations.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { z } from "astro/zod"
|
|
2
2
|
import YAML from "yaml"
|
|
3
3
|
|
|
4
|
+
import { lazy } from "../utils/lazy"
|
|
5
|
+
import { writeStaleTranslationOverrides } from "./record-translation"
|
|
6
|
+
|
|
4
7
|
const builtInTranslations = {
|
|
5
8
|
ar: () => import("./translations/ar.yml?raw"),
|
|
6
9
|
bn: () => import("./translations/bn.yml?raw"),
|
|
@@ -22,24 +25,52 @@ type BuiltInLanguage = keyof typeof builtInTranslations
|
|
|
22
25
|
|
|
23
26
|
const translationFileSchema = z.record(z.string(), z.string())
|
|
24
27
|
|
|
28
|
+
const userTranslationFiles = import.meta.glob<string>(
|
|
29
|
+
["/src/translations/*.(yml|yaml)"],
|
|
30
|
+
{ query: "?raw", import: "default" },
|
|
31
|
+
)
|
|
32
|
+
|
|
25
33
|
const userTranslations = Object.fromEntries(
|
|
26
|
-
Object.entries(
|
|
27
|
-
import.meta.glob(["/src/translations/*.(yml|yaml)"], {
|
|
28
|
-
query: "?raw",
|
|
29
|
-
import: "default",
|
|
30
|
-
}),
|
|
31
|
-
).map(([path, translationImport]) => {
|
|
34
|
+
Object.entries(userTranslationFiles).map(([path, translationImport]) => {
|
|
32
35
|
const [fileName] = path.split("/").slice(-1)
|
|
33
36
|
const lang = fileName.replace(/\.ya?ml/, "")
|
|
34
37
|
return [lang, translationImport]
|
|
35
38
|
}),
|
|
36
39
|
)
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
+
const staleOverrides = lazy(async () => {
|
|
42
|
+
const english = await loadBuiltInTranslations(builtInTranslations, "en")
|
|
43
|
+
await writeStaleTranslationOverrides(
|
|
44
|
+
await findStaleTranslationOverrides(english, userTranslationFiles),
|
|
45
|
+
)
|
|
41
46
|
})
|
|
42
47
|
|
|
48
|
+
export async function findStaleTranslationOverrides(
|
|
49
|
+
english: Record<string, string>,
|
|
50
|
+
files: Record<string, () => Promise<string>>,
|
|
51
|
+
) {
|
|
52
|
+
const overrides: { key: string; path: string }[] = []
|
|
53
|
+
for (const [path, load] of Object.entries(files)) {
|
|
54
|
+
const translations = translationFileSchema.parse(YAML.parse(await load()))
|
|
55
|
+
for (const key of Object.keys(translations)) {
|
|
56
|
+
if (key.startsWith("ln.") && !Object.hasOwn(english, key)) {
|
|
57
|
+
overrides.push({ key, path: path.replace(/^\//, "") })
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return overrides
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export const loadTranslations = async (bcp47: string) => {
|
|
65
|
+
if (import.meta.env.PROD) {
|
|
66
|
+
await staleOverrides.get()
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
...(await loadBuiltInTranslations(builtInTranslations, bcp47)),
|
|
70
|
+
...(await loadUserTranslations(bcp47)),
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
43
74
|
function hasTranslations(
|
|
44
75
|
translationMap: Record<string, unknown>,
|
|
45
76
|
bcp47: string,
|