@lightnet/cli 4.8.1 → 4.9.0

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 CHANGED
@@ -1,5 +1,21 @@
1
1
  # @lightnet/cli
2
2
 
3
+ ## 4.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#469](https://github.com/LightNetDev/LightNet/pull/469) [`a0961c4`](https://github.com/LightNetDev/LightNet/commit/a0961c40fdc30a93d3d5c814343f9c12ec26b2ef) - Add repeatable --exclude to check-translations for space-separated exact keys to ignore during completeness checks.
8
+
9
+ ### Patch Changes
10
+
11
+ - [#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.
12
+
13
+ ## 4.8.2
14
+
15
+ ### Patch Changes
16
+
17
+ - [#456](https://github.com/LightNetDev/LightNet/pull/456) [`2c49737`](https://github.com/LightNetDev/LightNet/commit/2c4973792aa695a2b19acc04744aca39bb7f868d) - Update dependencies.
18
+
3
19
  ## 4.8.1
4
20
 
5
21
  ### Patch Changes
package/README.md CHANGED
@@ -8,6 +8,19 @@ Command-line tools for working with LightNet sites. The CLI currently includes t
8
8
  pnpm add --D @lightnet/cli
9
9
  ```
10
10
 
11
+ ## Exclude translation keys
12
+
13
+ Pass a space-separated list of exact keys to skip their completeness checks:
14
+
15
+ ```bash
16
+ pnpm exec lightnet check-translations --exclude ln.details.edit custom.title
17
+ ```
18
+
19
+ You can repeat `--exclude` to add more keys. Matching is case-sensitive and does
20
+ not support wildcards. Exclusions apply to built-in keys, user keys, and inline
21
+ translation-map paths. Stale override warnings are still reported for excluded
22
+ keys. Use `--build` to refresh the cache or `--no-build` to check the last build.
23
+
11
24
  ## LightNet CLI reference
12
25
 
13
26
  See command-line tools reference documentation at:
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "CLI for managing LightNet projects",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
- "version": "4.8.1",
6
+ "version": "4.9.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -25,16 +25,16 @@
25
25
  "CHANGELOG.md"
26
26
  ],
27
27
  "dependencies": {
28
- "@clack/prompts": "^1.8.0",
28
+ "@clack/prompts": "^1.8.1",
29
29
  "commander": "^15.0.0"
30
30
  },
31
31
  "devDependencies": {
32
- "vitest": "^5.0.0"
32
+ "vitest": "^5.0.5"
33
33
  },
34
34
  "engines": {
35
35
  "node": ">=22"
36
36
  },
37
37
  "scripts": {
38
- "test": "vitest"
38
+ "test": "vitest run"
39
39
  }
40
40
  }
@@ -27,6 +27,7 @@ import { cancelPrompt } from "./support/prompt-cancel.js"
27
27
  /**
28
28
  * @typedef {{
29
29
  * build?: boolean
30
+ * exclude?: string[]
30
31
  * }} CheckTranslationsOptions
31
32
  */
32
33
 
@@ -88,10 +89,24 @@ export async function checkTranslations(options = {}, runtime = {}) {
88
89
 
89
90
  const translations = await readTranslations(lightnetCachePath, output)
90
91
  const languages = await readLanguages(lightnetCachePath, output)
92
+ const staleOverrides = await readStaleOverrides(lightnetCachePath)
93
+ if (staleOverrides.length > 0) {
94
+ output.warn("Stale LightNet translation overrides")
95
+ for (const { key, path } of staleOverrides.toSorted(
96
+ (a, b) => a.key.localeCompare(b.key) || a.path.localeCompare(b.path),
97
+ )) {
98
+ output.message(`• ${key} — ${path}`)
99
+ }
100
+ output.message(
101
+ "Action: Remove these overrides or rename custom keys without the reserved ln. prefix.",
102
+ )
103
+ }
91
104
  if (!translations || !languages || translations.length === 0) {
92
105
  return false
93
106
  }
107
+ const excludedKeys = new Set(options.exclude ?? [])
94
108
  const incompleteTranslations = translations
109
+ .filter((translation) => !excludedKeys.has(translation.key))
95
110
  .map((translation) => ({
96
111
  ...translation,
97
112
  missingLocales: getMissingLocales(translation, languages),
@@ -99,7 +114,11 @@ export async function checkTranslations(options = {}, runtime = {}) {
99
114
  .filter((translation) => translation.missingLocales.length > 0)
100
115
 
101
116
  if (incompleteTranslations.length === 0) {
102
- output.outro("No issues found. 🎉")
117
+ output.outro(
118
+ staleOverrides.length > 0
119
+ ? "No missing translations. Stale overrides found."
120
+ : "No issues found. 🎉",
121
+ )
103
122
  return true
104
123
  }
105
124
 
@@ -236,6 +255,32 @@ function getMissingLocales(translation, languages) {
236
255
  return languages.locales.filter((locale) => !translation.values[locale])
237
256
  }
238
257
 
258
+ /**
259
+ * @param {string} lightnetCachePath
260
+ * @returns {Promise<{key: string, path: string}[]>}
261
+ */
262
+ async function readStaleOverrides(lightnetCachePath) {
263
+ try {
264
+ return JSON.parse(
265
+ await readFile(
266
+ resolve(lightnetCachePath, "stale-translation-overrides.json"),
267
+ "utf-8",
268
+ ),
269
+ )
270
+ } catch (error) {
271
+ // Older builds do not include stale override metadata.
272
+ if (
273
+ error &&
274
+ typeof error === "object" &&
275
+ "code" in error &&
276
+ error.code === "ENOENT"
277
+ ) {
278
+ return []
279
+ }
280
+ throw error
281
+ }
282
+ }
283
+
239
284
  /**
240
285
  * @param {string} lightnetCachePath
241
286
  * @param {ReturnType<typeof createOutput>} output
package/src/index.js CHANGED
@@ -25,6 +25,11 @@ program
25
25
  .description("check if last build has been missing any translations")
26
26
  .option("--build", "run pnpm build before checking translations")
27
27
  .option("--no-build", "skip the build prompt and use the latest dist/ output")
28
+ .option(
29
+ "--exclude <keys...>",
30
+ "exclude exact translation keys from completeness checks (repeatable)",
31
+ [],
32
+ )
28
33
  .action(async (options) => {
29
34
  try {
30
35
  const checkSuccessful = await checkTranslations(options)