feat: add check for localization keys between package.json and package.nls.json#1222
feat: add check for localization keys between package.json and package.nls.json#1222joaomoreno wants to merge 1 commit intomainfrom
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR adds a validation tool to ensure localization consistency between package.json and package.nls.json files. The tool checks that all localization keys referenced in package.json (using the %key% pattern) have corresponding entries in the package.nls.json file.
- Creates a TypeScript script that recursively scans
package.jsonfor localization key references - Validates that all referenced keys exist in
package.nls.json - Integrates the validation check into CI/CD pipelines to catch localization issues early
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| script/checkPackageNls.ts | New validation script that finds localization keys in package.json and verifies they exist in package.nls.json |
| package.json | Adds npm script "check-package-nls" to run the validation tool |
| build/release.yml | Integrates the localization check into the release build pipeline |
| build/pre-release.yml | Integrates the localization check into the pre-release build pipeline |
| .github/workflows/pr.yml | Adds the localization check to both PR validation jobs |
| /** | ||
| * Recursively finds all strings matching the pattern %key% in a JSON object | ||
| */ | ||
| function findLocalizationKeys(obj: any, keys: Set<string> = new Set()): Set<string> { |
There was a problem hiding this comment.
Using any type reduces type safety. Consider using a more specific type like unknown or a union type for better type checking.
| function findLocalizationKeys(obj: any, keys: Set<string> = new Set()): Set<string> { | |
| function findLocalizationKeys(obj: unknown, keys: Set<string> = new Set()): Set<string> { |
| const packageJsonContent = await fs.promises.readFile(packageJsonPath, 'utf-8'); | ||
| const packageJson = JSON.parse(packageJsonContent); | ||
|
|
||
| // Read package.nls.json | ||
| const packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); | ||
| const packageNls = JSON.parse(packageNlsContent); |
There was a problem hiding this comment.
Missing error handling for file read operations. If either file doesn't exist or can't be read, the script will crash with an unhelpful error message.
| const packageJsonContent = await fs.promises.readFile(packageJsonPath, 'utf-8'); | |
| const packageJson = JSON.parse(packageJsonContent); | |
| // Read package.nls.json | |
| const packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); | |
| const packageNls = JSON.parse(packageNlsContent); | |
| let packageJson; | |
| try { | |
| const packageJsonContent = await fs.promises.readFile(packageJsonPath, 'utf-8'); | |
| packageJson = JSON.parse(packageJsonContent); | |
| } catch (err) { | |
| console.error(`Failed to read or parse package.json: ${err.message}`); | |
| process.exit(1); | |
| } | |
| // Read package.nls.json | |
| let packageNls; | |
| try { | |
| const packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); | |
| packageNls = JSON.parse(packageNlsContent); | |
| } catch (err) { | |
| console.error(`Failed to read or parse package.nls.json: ${err.message}`); | |
| process.exit(1); | |
| } |
| const packageJsonContent = await fs.promises.readFile(packageJsonPath, 'utf-8'); | ||
| const packageJson = JSON.parse(packageJsonContent); | ||
|
|
||
| // Read package.nls.json | ||
| const packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); |
There was a problem hiding this comment.
Missing error handling for file read operations. If either file doesn't exist or can't be read, the script will crash with an unhelpful error message.
| const packageJsonContent = await fs.promises.readFile(packageJsonPath, 'utf-8'); | |
| const packageJson = JSON.parse(packageJsonContent); | |
| // Read package.nls.json | |
| const packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); | |
| let packageJsonContent: string; | |
| try { | |
| packageJsonContent = await fs.promises.readFile(packageJsonPath, 'utf-8'); | |
| } catch (err: any) { | |
| console.error(`❌ ERROR: Failed to read ${packageJsonPath}: ${err.message}`); | |
| process.exit(1); | |
| } | |
| const packageJson = JSON.parse(packageJsonContent); | |
| // Read package.nls.json | |
| let packageNlsContent: string; | |
| try { | |
| packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); | |
| } catch (err: any) { | |
| console.error(`❌ ERROR: Failed to read ${packageNlsPath}: ${err.message}`); | |
| process.exit(1); | |
| } |
| const packageJson = JSON.parse(packageJsonContent); | ||
|
|
||
| // Read package.nls.json | ||
| const packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); | ||
| const packageNls = JSON.parse(packageNlsContent); |
There was a problem hiding this comment.
Missing error handling for JSON parsing. If either file contains invalid JSON, the script will crash with an unhelpful error message.
| const packageJson = JSON.parse(packageJsonContent); | |
| // Read package.nls.json | |
| const packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); | |
| const packageNls = JSON.parse(packageNlsContent); | |
| let packageJson; | |
| try { | |
| packageJson = JSON.parse(packageJsonContent); | |
| } catch (err) { | |
| console.error(`❌ ERROR: Failed to parse package.json as valid JSON.`); | |
| console.error(err instanceof Error ? err.message : err); | |
| process.exit(1); | |
| } | |
| // Read package.nls.json | |
| const packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); | |
| let packageNls; | |
| try { | |
| packageNls = JSON.parse(packageNlsContent); | |
| } catch (err) { | |
| console.error(`❌ ERROR: Failed to parse package.nls.json as valid JSON.`); | |
| console.error(err instanceof Error ? err.message : err); | |
| process.exit(1); | |
| } |
| const packageJson = JSON.parse(packageJsonContent); | ||
|
|
||
| // Read package.nls.json | ||
| const packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); | ||
| const packageNls = JSON.parse(packageNlsContent); |
There was a problem hiding this comment.
Missing error handling for JSON parsing. If either file contains invalid JSON, the script will crash with an unhelpful error message.
| const packageJson = JSON.parse(packageJsonContent); | |
| // Read package.nls.json | |
| const packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); | |
| const packageNls = JSON.parse(packageNlsContent); | |
| let packageJson; | |
| try { | |
| packageJson = JSON.parse(packageJsonContent); | |
| } catch (err) { | |
| console.error(`❌ ERROR: Failed to parse ${packageJsonPath}:`, err.message); | |
| process.exit(1); | |
| } | |
| // Read package.nls.json | |
| const packageNlsContent = await fs.promises.readFile(packageNlsPath, 'utf-8'); | |
| let packageNls; | |
| try { | |
| packageNls = JSON.parse(packageNlsContent); | |
| } catch (err) { | |
| console.error(`❌ ERROR: Failed to parse ${packageNlsPath}:`, err.message); | |
| process.exit(1); | |
| } |
No description provided.