npm package diff
Package: @forge/manifest
Versions: 7.6.1-next.0 - 7.6.1-next.1
File: package/out/validators/translations-validator.js
Index: package/out/validators/translations-validator.js
===================================================================
--- package/out/validators/translations-validator.js
+++ package/out/validators/translations-validator.js
@@ -0,0 +1,160 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.TranslationsValidator = void 0;
+const tslib_1 = require("tslib");
+const fs_1 = tslib_1.__importDefault(require("fs"));
+const path_1 = require("path");
+const text_1 = require("../text");
+const text_2 = require("../text");
+const utils_1 = require("../utils");
+class TranslationsValidator {
+ ensureValidResourcesDefinition(validationErrors, manifest) {
+ const { resources, fallback } = manifest.yamlContent.translations;
+ const resourcesMap = new Map();
+ resources.forEach(({ key, path }) => {
+ if (resourcesMap.has(key)) {
+ validationErrors.push({
+ message: text_1.errors.translations.duplicateResourceKey(key),
+ reference: text_2.References.SchemaError,
+ level: 'error',
+ ...(0, utils_1.findPosition)(`key: ${key}`, manifest.yamlContentByLine)
+ });
+ }
+ else {
+ resourcesMap.set(key, path);
+ }
+ });
+ let defaultLanguageLookup = {};
+ resourcesMap.forEach((path, key) => {
+ const resourcePath = (0, path_1.resolve)(path);
+ try {
+ if (fs_1.default.lstatSync(resourcePath).isFile()) {
+ const data = JSON.parse(fs_1.default.readFileSync((0, path_1.resolve)(path), 'utf8'));
+ if (fallback?.default === key) {
+ defaultLanguageLookup = data;
+ }
+ }
+ }
+ catch (e) {
+ validationErrors.push({
+ message: text_1.errors.translations.invalidLanguageFile(key, path),
+ reference: text_2.References.SchemaError,
+ level: 'error',
+ ...(0, utils_1.findPosition)(`path: ${path}`, manifest?.yamlContentByLine)
+ });
+ }
+ });
+ return defaultLanguageLookup;
+ }
+ ensureValidFallbackDefinition(validationErrors, manifest) {
+ const { resources, fallback } = manifest.yamlContent.translations;
+ const defaultLanguage = fallback.default;
+ const resourcesSet = new Set(resources.map((resource) => resource.key));
+ const fallbackLanguages = Object.keys(fallback).filter((fallbackLanguage) => fallbackLanguage !== 'default');
+ const allFallbackLanguagesSet = new Set([defaultLanguage, ...fallbackLanguages]);
+ allFallbackLanguagesSet.forEach((fallbackLanguage) => {
+ if (!resourcesSet.has(fallbackLanguage)) {
+ validationErrors.push({
+ message: text_1.errors.translations.missingTranslationsJsonFile(fallbackLanguage),
+ reference: text_2.References.SchemaError,
+ level: 'error',
+ ...(0, utils_1.findPosition)(fallbackLanguage === defaultLanguage ? `default: ${fallbackLanguage}` : `${fallbackLanguage}:`, manifest.yamlContentByLine)
+ });
+ }
+ });
+ const allLanguagesList = [
+ defaultLanguage,
+ ...fallbackLanguages,
+ ...fallbackLanguages.flatMap((language) => fallback[language])
+ ];
+ const [, duplicates] = allLanguagesList.reduce(([languageSet, duplicates], language) => {
+ languageSet.has(language) ? duplicates.add(language) : languageSet.add(language);
+ return [languageSet, duplicates];
+ }, [new Set(), new Set()]);
+ duplicates.forEach((duplicate) => {
+ validationErrors.push({
+ message: text_1.errors.translations.duplicateFallbackConfig(duplicate),
+ reference: text_2.References.SchemaError,
+ level: 'error',
+ ...(0, utils_1.findPosition)(duplicate, manifest.yamlContentByLine)
+ });
+ });
+ }
+ ensureI18nKeysExistInDefaultJson(validationErrors, i18nKeys, defaultLanguageLookup, manifest) {
+ const i18nKeysSet = new Set(i18nKeys);
+ const defaultLocalCode = manifest.yamlContent.translations.fallback.default;
+ const languageLookUp = { [defaultLocalCode]: defaultLanguageLookup };
+ i18nKeysSet.forEach((key) => {
+ const i18nValue = (0, utils_1.getTranslationValue)(languageLookUp, key, defaultLocalCode);
+ if (!i18nValue) {
+ validationErrors.push({
+ message: text_1.errors.translations.i18nKeyNotFound(key),
+ reference: text_2.References.SchemaError,
+ level: 'error',
+ ...(0, utils_1.findPosition)(`i18n: ${key}`, manifest.yamlContentByLine)
+ });
+ }
+ });
+ }
+ validateManifestWithoutI18nConfig(manifest, i18nKeys) {
+ if (i18nKeys.length === 0) {
+ return {
+ success: true,
+ manifestObject: manifest
+ };
+ }
+ const missingTranslationsPropertyError = [
+ {
+ message: text_1.errors.translations.missingTranslationsPropertyError,
+ reference: text_2.References.SchemaError,
+ level: 'error',
+ ...(0, utils_1.findPosition)('i18n', manifest?.yamlContentByLine)
+ }
+ ];
+ return {
+ success: false,
+ manifestObject: manifest,
+ errors: missingTranslationsPropertyError
+ };
+ }
+ validateManifestI18nConfig(manifest, i18nKeys) {
+ const validationErrors = [];
+ const defaultLanguageLookup = this.ensureValidResourcesDefinition(validationErrors, manifest);
+ this.ensureValidFallbackDefinition(validationErrors, manifest);
+ this.ensureI18nKeysExistInDefaultJson(validationErrors, i18nKeys, defaultLanguageLookup, manifest);
+ return validationErrors;
+ }
+ validateInternalI18nPropertyKeysNotInModules(manifest) {
+ const modules = manifest?.typedContent?.modules ?? {};
+ const internalI18nPropertyKeys = (0, utils_1.extractInternalI18nPropertyKeysFromModules)(modules);
+ return internalI18nPropertyKeys.map(([propertyKey, moduleKey]) => ({
+ message: text_1.errors.translations.internalI18nPropertyKeyFound(propertyKey, moduleKey),
+ reference: text_2.References.SchemaError,
+ level: 'error',
+ ...(0, utils_1.findPosition)(propertyKey, manifest.yamlContentByLine, moduleKey)
+ }));
+ }
+ async validate(manifest) {
+ if (!manifest || !manifest.typedContent || !manifest.filePath) {
+ return {
+ success: false,
+ manifestObject: manifest
+ };
+ }
+ const i18nKeys = (0, utils_1.extractI18nKeysFromModules)(manifest?.typedContent?.modules ?? {});
+ const i18nConfig = manifest?.yamlContent?.translations;
+ if (!i18nConfig) {
+ return this.validateManifestWithoutI18nConfig(manifest, i18nKeys);
+ }
+ const validationErrors = [
+ ...this.validateManifestI18nConfig(manifest, i18nKeys),
+ ...this.validateInternalI18nPropertyKeysNotInModules(manifest)
+ ];
+ return {
+ success: validationErrors.length === 0,
+ manifestObject: manifest,
+ errors: validationErrors
+ };
+ }
+}
+exports.TranslationsValidator = TranslationsValidator;