82 lines
3.1 KiB
JavaScript
82 lines
3.1 KiB
JavaScript
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
const pluginsRoot = path.join(root, 'plugins');
|
|
const contributionFields = {
|
|
views: 'title',
|
|
commands: 'title',
|
|
settingsPanels: 'title',
|
|
sidebarItems: 'title',
|
|
fileActions: 'label',
|
|
noteActions: 'label',
|
|
contextMenuEntries: 'label',
|
|
searchProviders: 'label',
|
|
statusBarItems: 'label',
|
|
openProviders: 'title',
|
|
workspaceItems: 'title',
|
|
};
|
|
const problems = [];
|
|
|
|
for (const entry of fs.readdirSync(pluginsRoot, { withFileTypes: true })) {
|
|
if (!entry.isDirectory()) continue;
|
|
const pluginRoot = path.join(pluginsRoot, entry.name);
|
|
const manifestPath = path.join(pluginRoot, 'plugin.json');
|
|
if (!fs.existsSync(manifestPath)) continue;
|
|
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
const localization = manifest.localization;
|
|
if (!localization || localization.defaultLocale !== 'en') {
|
|
problems.push(`${manifest.id}: localization.defaultLocale must be en`);
|
|
continue;
|
|
}
|
|
if (!localization.locales || !localization.locales.en || !localization.locales.ru) {
|
|
problems.push(`${manifest.id}: en and ru catalogs must be declared`);
|
|
continue;
|
|
}
|
|
|
|
const catalogs = {};
|
|
for (const locale of ['en', 'ru']) {
|
|
const relative = localization.locales[locale];
|
|
const catalogPath = path.resolve(pluginRoot, relative);
|
|
if (!catalogPath.startsWith(pluginRoot + path.sep) || !fs.existsSync(catalogPath)) {
|
|
problems.push(`${manifest.id}: missing safe ${locale} catalog at ${relative}`);
|
|
continue;
|
|
}
|
|
try {
|
|
catalogs[locale] = JSON.parse(fs.readFileSync(catalogPath, 'utf8'));
|
|
} catch (error) {
|
|
problems.push(`${manifest.id}: invalid ${locale} catalog: ${error.message}`);
|
|
continue;
|
|
}
|
|
for (const [key, value] of Object.entries(catalogs[locale])) {
|
|
if (typeof value !== 'string') problems.push(`${manifest.id}: ${locale}.${key} must be a string`);
|
|
}
|
|
}
|
|
if (!catalogs.en || !catalogs.ru) continue;
|
|
|
|
const enKeys = Object.keys(catalogs.en).sort();
|
|
const ruKeys = Object.keys(catalogs.ru).sort();
|
|
if (JSON.stringify(enKeys) !== JSON.stringify(ruKeys)) {
|
|
problems.push(`${manifest.id}: en/ru catalog keys differ`);
|
|
}
|
|
|
|
const required = ['manifest.name'];
|
|
if (manifest.description) required.push('manifest.description');
|
|
for (const [point, field] of Object.entries(contributionFields)) {
|
|
for (const item of manifest.contributes?.[point] || []) {
|
|
required.push(`contributions.${point}.${item.id}.${field}`);
|
|
}
|
|
}
|
|
for (const key of required) {
|
|
if (!Object.prototype.hasOwnProperty.call(catalogs.en, key)) problems.push(`${manifest.id}: en catalog missing ${key}`);
|
|
if (!Object.prototype.hasOwnProperty.call(catalogs.ru, key)) problems.push(`${manifest.id}: ru catalog missing ${key}`);
|
|
}
|
|
}
|
|
|
|
if (problems.length > 0) {
|
|
problems.forEach((problem) => console.error(` FAIL ${problem}`));
|
|
process.exit(1);
|
|
}
|
|
console.log(' OK official plugin locale catalogs are complete and aligned');
|