UNPKG

pwabuilder-edgeextension

Version:
197 lines (155 loc) 10.3 kB
'use strict'; var fs = require('fs'), Q = require('q'), path = require('path'); var lib = require('pwabuilder-lib'), CustomError = lib.CustomError, log = lib.log; var constants = require('./constants'), MsgKey = '__MSG_'; var acceptedLanguageCodes = ['ar', 'ar-sa', 'ar-ae', 'ar-bh', 'ar-dz', 'ar-eg', 'ar-iq', 'ar-jo', 'ar-kw', 'ar-lb', 'ar-ly', 'ar-ma', 'ar-om', 'ar-qa', 'ar-sy', 'ar-tn', 'ar-ye', 'af', 'af-za', 'sq', 'sq-al', 'am', 'am-et', 'hy', 'hy-am', 'as', 'as-in', 'az', 'az-arab', 'az-arab-az', 'az-cyrl', 'az-cyrl-az', 'az-latn', 'az-latn-az', 'eu', 'eu-es', 'be', 'be-by', 'bn', 'bn-bd', 'bn-in', 'bs', 'bs-cyrl', 'bs-cyrl-ba', 'bs-latn', 'bs-latn-ba', 'bg', 'bg-bg', 'ca', 'ca-es', 'ca-es-valencia', 'chr-cher', 'chr-cher-us', 'chr-latn', 'zh', 'zh-Hans', 'zh-cn', 'zh-hans-cn', 'zh-sg', 'zh-hans-sg', 'zh-Hant', 'zh-hk', 'zh-mo', 'zh-tw', 'zh-hant-hk', 'zh-hant-mo', 'zh-hant-tw', 'hr', 'hr-hr', 'hr-ba', 'cs', 'cs-cz', 'da', 'da-dk', 'prs', 'prs-af', 'prs-arab', 'nl', 'nl-nl', 'nl-be', 'en', 'en-au', 'en-ca', 'en-gb', 'en-ie', 'en-in', 'en-nz', 'en-sg', 'en-us', 'en-za', 'en-bz', 'en-hk', 'en-id', 'en-jm', 'en-kz', 'en-mt', 'en-my', 'en-ph', 'en-pk', 'en-tt', 'en-vn', 'en-zw', 'en-053', 'en-021', 'en-029', 'en-011', 'en-018', 'en-014', 'et', 'et-ee', 'fil', 'fil-latn', 'fil-ph', 'fi', 'fi-fi', 'fr', 'fr-be', 'fr-ca', 'fr-ch', 'fr-fr', 'fr-lu', 'fr-015', 'fr-cd', 'fr-ci', 'fr-cm', 'fr-ht', 'fr-ma', 'fr-mc', 'fr-ml', 'fr-re', 'frc-latn', 'frp-latn', 'fr-155', 'fr-029', 'fr-021', 'fr-011', 'gl', 'gl-es', 'ka', 'ka-ge', 'de', 'de-at', 'de-ch', 'de-de', 'de-lu', 'de-li', 'el', 'el-gr', 'gu', 'gu-in', 'ha', 'ha-latn', 'ha-latn-ng', 'he', 'he-il', 'hi', 'hi-in', 'hu', 'hu-hu', 'is', 'is-is', 'ig-latn', 'ig-ng', 'id', 'id-id', 'iu-cans', 'iu-latn', 'iu-latn-ca', 'ga', 'ga-ie', 'xh', 'xh-za', 'zu', 'zu-za', 'it', 'it-it', 'it-ch', 'ja', 'ja-jp', 'kn', 'kn-in', 'kk', 'kk-kz', 'km', 'km-kh', 'quc-latn', 'qut-gt', 'qut-latn', 'rw', 'rw-rw', 'sw', 'sw-ke', 'kok', 'kok-in', 'ko', 'ko-kr', 'ku-arab', 'ku-arab-iq', 'ky-kg', 'ky-cyrl', 'lo', 'lo-la', 'lv', 'lv-lv', 'lt', 'lt-lt', 'lb', 'lb-lu', 'mk', 'mk-mk', 'ms', 'ms-bn', 'ms-my', 'ml', 'ml-in', 'mt', 'mt-mt', 'mi', 'mi-latn', 'mi-nz', 'mr', 'mr-in', 'mn-cyrl', 'mn-mong', 'mn-mn', 'mn-phag', 'ne', 'ne-np', 'nb', 'nb-no', 'nn', 'nn-no', 'no', 'no-no,', 'or', 'or-in', 'fa', 'fa-ir', 'pl', 'pl-pl', 'pt-br', 'pt', 'pt-pt', 'pa', 'pa-arab', 'pa-arab-pk', 'pa-deva', 'pa-in', 'quz', 'quz-bo', 'quz-ec', 'quz-pe', 'ro', 'ro-ro', 'ru', 'ru-ru', 'gd-gb', 'gd-latn', 'sr-Latn', 'sr-latn-cs', 'sr-latn-ba', 'sr-latn-me', 'sr-latn-rs', 'sr-cyrl', 'sr-cyrl-ba', 'sr-cyrl-cs', 'sr-cyrl-me', 'sr-cyrl-rs', 'nso', 'nso-za', 'tn', 'tn-bw', 'tn-za', 'sd-arab', 'sd-arab-pk', 'sd-deva', 'si', 'si-lk', 'sk', 'sk-sk', 'sl', 'sl-si', 'es', 'es-cl', 'es-co', 'es-es', 'es-mx', 'es-ar', 'es-bo', 'es-cr', 'es-do', 'es-ec', 'es-gt', 'es-hn', 'es-ni', 'es-pa', 'es-pe', 'es-pr', 'es-py', 'es-sv', 'es-us', 'es-uy', 'es-ve', 'es-019', 'es-419', 'sv', 'sv-se', 'sv-fi', 'tg-arab', 'tg-cyrl', 'tg-cyrl-tj', 'tg-latn', 'ta', 'ta-in', 'tt-arab', 'tt-cyrl', 'tt-latn', 'tt-ru', 'te', 'te-in', 'th', 'th-th', 'ti', 'ti-et', 'tr', 'tr-tr', 'tk-cyrl', 'tk-latn', 'tk-tm', 'tk-latn-tr', 'tk-cyrl-tr', 'uk', 'uk-ua', 'ur', 'ur-pk', 'ug-arab', 'ug-cn', 'ug-cyrl', 'ug-latn', 'uz', 'uz-cyrl', 'uz-latn', 'uz-latn-uz', 'vi', 'vi-vn', 'cy', 'cy-gb', 'wo', 'wo-sn', 'yo-latn', 'yo-ng']; function shouldLocalize(extManifest) { var localizeResources = false; if (!extManifest.hasOwnProperty('default_locale')) { return false; } if (extManifest.name.indexOf(MsgKey) === 0) { localizeResources = true; } if (extManifest.description.indexOf(MsgKey) === 0) { localizeResources = true; } return localizeResources; } function mapLocalesFromI18nToUWP(locale) { locale = locale.toLowerCase(); if (acceptedLanguageCodes.indexOf(locale) > -1) { return locale; } if (locale.indexOf('_') > -1) { var underscoreToHyphenLocale = locale.replace('_', '-'); if (acceptedLanguageCodes.indexOf(underscoreToHyphenLocale) > -1) { return underscoreToHyphenLocale; } } log.warn('The language code "' + locale + '" is not supported by the store. Skipping...', constants.platform.id); } function getResources(extManifest, localesList) { var resourceKey = '{LanguageCode}'; var resourceTemplate = '<Resource Language="' + resourceKey + '" />'; var resourceString = ''; if (shouldLocalize(extManifest)) { var defaultLocale = mapLocalesFromI18nToUWP(extManifest.default_locale); if (typeof defaultLocale === 'undefined') { throw new Error('Default Locale cannot be mapped to a store locale.'); } resourceString = resourceTemplate.replace(resourceKey, defaultLocale); for (var index = 0; index < localesList.length; index++) { var currentLocale = mapLocalesFromI18nToUWP(localesList[index]); if (currentLocale === defaultLocale || typeof currentLocale === 'undefined') { continue; } resourceString += '\r\n\t\t'; resourceString += resourceTemplate.replace(resourceKey, currentLocale); } } else { resourceString = resourceTemplate.replace(resourceKey, 'en-us'); } resourceString += '\r\n\t\t<Resource uap:Scale="200"/>'; return resourceString; } function localizeAppxManifest(extManifest, content, extensionLocalesList) { if (extManifest.name.indexOf(MsgKey) === 0) { content = content.replace(/{DisplayName}/g, 'ms-resource:DisplayName'); } if (extManifest.description.indexOf(MsgKey) === 0) { content = content.replace(/{Description}/g, 'ms-resource:Description'); } var resources = getResources(extManifest, extensionLocalesList); return content.replace(/{Resources}/g, resources); } function getResObjFromLocale(extManifest, localeMessagesFile) { var resObj = {}; var localeJsonString; var localeJson; try { localeJsonString = fs.readFileSync(localeMessagesFile).toString(); var bomRemovedlocaleJsonString = localeJsonString.replace('\ufeff', '').replace('\uffef', ''); if (bomRemovedlocaleJsonString !== localeJsonString) { log.warn('Removing Invalid BOM in file: ' + localeMessagesFile, constants.platform.id); } localeJson = JSON.parse(bomRemovedlocaleJsonString); } catch(e) { log.warn('Invalid JSON in file: ' + localeMessagesFile, constants.platform.id); return resObj; } var nameKey = ''; if (extManifest.name.indexOf(MsgKey) === 0) { nameKey = extManifest.name.replace(MsgKey, ''); nameKey = nameKey.substring(0, nameKey.length - 2); if (localeJson[nameKey] && localeJson[nameKey].message && localeJson[nameKey].message.length > 0) { resObj['DisplayName'] = localeJson[nameKey].message; resObj['_DisplayName.comment'] = localeJson[nameKey].description || ''; } } var descriptionKey = ''; if (extManifest.description.indexOf(MsgKey) === 0) { descriptionKey = extManifest.description.replace(MsgKey, ''); descriptionKey = descriptionKey.substring(0, descriptionKey.length - 2); if (localeJson[descriptionKey] && localeJson[descriptionKey].message && localeJson[descriptionKey].message.length > 0) { resObj['Description'] = localeJson[descriptionKey].message; resObj['_Description.comment'] = localeJson[descriptionKey].description || ''; } } return resObj; } function createResJsonFiles(extManifest, localesList, manifestLocalesDir, resjsonRootDir) { if (extManifest.hasOwnProperty('default_locale')) { for (var index = 0; index < localesList.length; index++) { var current_locale = localesList[index]; var localeMessagesFile = path.join(manifestLocalesDir, current_locale, 'messages.json'); var resObj = getResObjFromLocale(extManifest, localeMessagesFile); if (typeof resObj['DisplayName'] === 'undefined' && typeof resObj['Description'] === 'undefined') { continue; } var resjsonString = JSON.stringify(resObj, null, '\t'); var uwpLocale = mapLocalesFromI18nToUWP(current_locale); if (!uwpLocale) { continue; } var resjsonCurrentLocaleDir = path.join(resjsonRootDir, mapLocalesFromI18nToUWP(current_locale)); var resjsonFilePath = path.join(resjsonCurrentLocaleDir, 'resources.resjson'); fs.mkdirSync(resjsonCurrentLocaleDir, { clobber: true }); fs.writeFileSync(resjsonFilePath, resjsonString, { clobber: true }); // create resjson file for this locale } } } function copyPriConfigTemplate(priConfigFilePath, extManifest) { if (!extManifest.hasOwnProperty('default_locale')) { return Q.reject(new Error('No defualt_local in the extension manifest: CopyPriConfigTemplate failed')); } var priConfigTemplatePath = path.join(__dirname, 'assets', 'priconfig-template.xml'); return Q.nfcall(fs.readFile, priConfigTemplatePath).then(function (data) { var defaultLocale = mapLocalesFromI18nToUWP(extManifest.default_locale); var rawPriConfig = data.toString(); return rawPriConfig .replace(/{default_locale}/g, defaultLocale); }) .catch(function (err) { return Q.reject(new CustomError('Could not read the priconfig template', err)); }) .then(function (priConfigText) { return Q.nfcall(fs.writeFile, priConfigFilePath, priConfigText).catch(function (err) { return Q.reject(new CustomError('Could not write the priconfig file', err)); }); }); } module.exports = { shouldLocalize: shouldLocalize, localizeAppxManifest: localizeAppxManifest, createResJsonFiles: createResJsonFiles, copyPriConfigTemplate: copyPriConfigTemplate };