uppy/packages/@uppy/locales/script/test.mjs
Prakash 1427add64a
@uppy/upgrade-devdeps-v1 (#6317)
Part of the dev-dependency major-version upgrades. These required code
changes so they're split out from the no-code-change batch (#6315).

**AI Disclaimer** : AI Used

- **glob 8 → 13** — `@uppy/locales` scripts: the callback API was
removed, so `getPaths()` uses the promise form and `test.mjs` uses the
named `globSync`.
- **npm-packlist 5 → 11** — `upload-to-cdn.js`: v7+ takes an
`@npmcli/arborist` tree instead of `{ path }`; loads the tree and passes
it to `packlist()`. Adds `@npmcli/arborist` as a devDependency.
- **nock 13 → 14** (`@uppy/companion`) — the v14 @mswjs/interceptors
rewrite crashed the SSRF tests in `http-agent.test.ts`; nock
interception is now kept off by default and only activated for the one
test that mocks a host.
- **@types/use-sync-external-store 0 → 1** — `@uppy/react`: v1's exports
map only exposes extensionless subpaths, so imports use
`use-sync-external-store/shim` and `/with-selector` (runtime supports
both).
2026-06-03 14:38:14 +05:30

144 lines
3.8 KiB
JavaScript

/* eslint-disable no-console, prefer-arrow-callback */
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'
import chalk from 'chalk'
import { globSync } from 'glob'
import { getLocales, getPaths, omit } from './helpers.mjs'
const root = fileURLToPath(new URL('../../../../', import.meta.url))
const leadingLocaleName = 'en_US'
const mode = process.argv[2]
const pluginLocaleDependencies = {
core: ['provider-views', 'companion-client'],
}
function getAllFilesPerPlugin(pluginNames) {
const filesPerPlugin = {}
function getFiles(name) {
return globSync(`${root}/packages/@uppy/${name}/lib/**/*.js`)
.filter((filePath) => !filePath.includes('locale.js'))
.map((filePath) => fs.readFileSync(filePath, 'utf-8'))
}
for (const name of pluginNames) {
filesPerPlugin[name] = getFiles(name)
if (name in pluginLocaleDependencies) {
for (const subDeb of pluginLocaleDependencies[name]) {
filesPerPlugin[name].push(...getFiles(subDeb))
}
}
}
return filesPerPlugin
}
async function unused(filesPerPlugin, data) {
for (const [name, fileStrings] of Object.entries(filesPerPlugin)) {
const fileString = fileStrings.join('\n')
const localePath = path.join(
root,
'packages',
'@uppy',
name,
'src',
'locale.js',
)
const locale = (await import(localePath)).default
for (const key of Object.keys(locale.strings)) {
const regPat = new RegExp(
`(i18n|i18nArray)\\([^\\)]*['\`"]${key}['\`"]`,
'g',
)
if (!fileString.match(regPat)) {
return Promise.reject(
new Error(`Unused locale key "${key}" in @uppy/${name}`),
)
}
}
}
return data
}
function warnings({ leadingLocale, followerLocales }) {
const entries = Object.entries(followerLocales)
const logs = []
for (const [name, locale] of entries) {
const missing = Object.keys(leadingLocale).filter((key) => !(key in locale))
const excess = Object.keys(locale).filter((key) => !(key in leadingLocale))
logs.push('\n')
logs.push(`--> Keys from ${leadingLocaleName} missing in ${name}`)
logs.push('\n')
for (const key of missing) {
let value = leadingLocale[key]
if (typeof value === 'object') {
// For values with plural forms, just take the first one right now
value = value[Object.keys(value)[0]]
}
logs.push(
[
`${chalk.cyan(name)} locale has missing string: '${chalk.red(key)}'`,
`that is present in ${chalk.cyan(leadingLocaleName)}`,
`with value: ${chalk.yellow(value)}`,
].join(' '),
)
}
logs.push('\n')
logs.push(`--> Keys from ${name} missing in ${leadingLocaleName}`)
logs.push('\n')
for (const key of excess) {
logs.push(
[
`${chalk.cyan(name)} locale has excess string:`,
`'${chalk.yellow(key)}' that is not present`,
`in ${chalk.cyan(leadingLocaleName)}.`,
].join(' '),
)
}
}
console.log(logs.join('\n'))
}
function test() {
switch (mode) {
case 'unused':
return getPaths(`${root}/packages/@uppy/**/src/locale.js`).then((paths) =>
unused(
getAllFilesPerPlugin(
paths.map((filePath) =>
path.basename(path.join(filePath, '..', '..')),
),
),
),
)
case 'warnings':
return getLocales(`${root}/packages/@uppy/locales/src/*.js`).then(
(locales) =>
warnings({
leadingLocale: locales[leadingLocaleName],
followerLocales: omit(locales, leadingLocaleName),
}),
)
default:
return Promise.reject(new Error(`Invalid mode "${mode}"`))
}
}
await test()