UNPKG

@microsoft/windows-admin-center-sdk

Version:

Microsoft - Windows Admin Center Shell

202 lines (200 loc) 9.11 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const buffer_1 = require("buffer"); const fs_1 = tslib_1.__importDefault(require("fs")); const fancy_log_1 = tslib_1.__importDefault(require("fancy-log")); const plugin_error_1 = tslib_1.__importDefault(require("plugin-error")); const through2_1 = tslib_1.__importDefault(require("through2")); const vinyl_1 = tslib_1.__importDefault(require("vinyl")); const util = tslib_1.__importStar(require("../utilities")); const PLUGIN_NAME = 'gulp-update-notes-resource'; function gulpUpdateNotesResources(options) { function findResourceKey(node, results) { const match = 'resources:strings:'; const keys = Object.keys(node); if (keys && keys.length > 0) { keys.forEach(key => { const target = node[key]; if (target) { if (typeof target === 'string') { if (target.indexOf(match) === 0) { const value = target.substring(match.length); if (results.indexOf(value) < 0) { results.push(value); } } } else { findResourceKey(target, results); } } }); } } // override options settings if not specified. options = Object.assign({ updateNotes: 'packages/shell/src/assets/updates/update-notes.json', localeOffset: 1 }, options || {}); const resources = {}; const keyToResources = {}; return through2_1.default.obj( /** * Transform */ function (file, encoding, callback) { let locale = 'default'; if (resources.default) { // if default is set already, find current locale from the file path. const pathSegments = file.history[0].split('\\'); locale = pathSegments[pathSegments.length - (2 + options.localeOffset)]; } resources[locale] = {}; if (resources.default) { // if default is set already, pre-fill all resource items from default. for (const resourceId in resources.default) { if (resources.default.hasOwnProperty(resourceId)) { resources[locale][resourceId] = resources.default[resourceId]; } } } // remove comments, /* multiline comment */ and // one line comment and "//": "JSON element comment" const content = file.contents.toString('utf8') .replace(/(\/\*([^*]|[\n]|(\*+([^*/]|[\n])))*\*\/+)|( +\/\/.*)|( +\"\/\/\".*)/g, ''); const object = JSON.parse(content); if (object[options.resourceName] && object[options.resourceName]['App']['UpdateNotes']) { // supports <ResourceName>.Manifest.<KeyName> format. const items = object[options.resourceName]['App']['UpdateNotes']; for (const key in items) { if (items.hasOwnProperty(key)) { // Each key will have two children, title and description // no need to separate in JSON form resources[locale][key] = items[key]; // Used to keep an alternate mapping we use later if (!keyToResources.hasOwnProperty(key)) { keyToResources[key] = {}; } if (keyToResources.hasOwnProperty(key) && !keyToResources[key].hasOwnProperty(locale)) { keyToResources[key][locale] = {}; } keyToResources[key][locale] = items[key]; } } } else { // supports <ResourceName>_App_UpdateNotes format. const resourceUpdateNotes = options.resourceName + '_App_UpdateNotes_'; for (const name in object) { if (object.hasOwnProperty(name)) { const index = name.indexOf(resourceUpdateNotes); if (index === 0) { // Check if this resource has the specific substring or not const value = object[name]; // If it contains '_' we split it so we keep only the key const resourceId2 = name.substring(resourceUpdateNotes.length); // Split to separate <KeyValue>_<type> // Possible types are title or description const splitText = resourceId2.split('_'); const key = splitText[0]; const type = splitText[1]; if (!resources[locale].hasOwnProperty(key)) { resources[locale][key] = {}; } resources[locale][key][type] = value; // Used to keep a mapping of keys to resources for faster // processing later if (!keyToResources.hasOwnProperty(key)) { keyToResources[key] = {}; } if (keyToResources.hasOwnProperty(key) && !keyToResources[key].hasOwnProperty(locale)) { keyToResources[key][locale] = {}; } keyToResources[key][locale][type] = value; } } } } return callback(); }, /** * Flush */ function (callback) { try { const updateNotesObject = JSON.parse(fs_1.default.readFileSync(options.updateNotes, 'utf8')); const keys = []; findResourceKey(updateNotesObject, keys); const missingType = []; const missing = []; const unused = Object.keys(resources.default); keys.forEach(function (key) { const index = unused.indexOf(key); if (index >= 0) { // If the item exists, remove it from the unused set unused.splice(index, 1); // We have to check each item has a title and description const typeKeys = Object.keys(keyToResources[key].default); const requiredTypesSet = new Set(); requiredTypesSet.add('title'); requiredTypesSet.add('description'); typeKeys.forEach(item => { if (requiredTypesSet.has(item)) { requiredTypesSet.delete(item); } }); // If it did not have we save it throw error later if (requiredTypesSet.size > 0) { missingType.push(key); } } else { missing.push(key); } }); if (missing.length > 0) { missing.forEach(item => { fancy_log_1.default.error('Missing resource: ' + item); }); throw new Error('Missing resource found in manifest.json!'); } if (unused.length > 0) { unused.forEach(item => { fancy_log_1.default.error('Unused resource: ' + item); }); throw new Error('Unused resource found in strings.resjson!'); } if (missingType.length > 0) { missingType.forEach(item => { fancy_log_1.default.error('Missing title or description: ' + item); }); throw new Error('Key without title or description found in strings.resjson!'); } updateNotesObject.map((item, index) => { if (item.hasOwnProperty('stringJsonKey')) { const key = item.stringJsonKey.replace('resources:strings:', ''); // Key to resource maps key -> all locales item.resources = keyToResources[key]; } updateNotesObject[index] = item; }); const updateNotesFile = new vinyl_1.default({ cwd: '.', base: '.', path: './update-notes.json', contents: buffer_1.Buffer.from(JSON.stringify(updateNotesObject, null, 2), 'utf8') }); this.push(updateNotesFile); } catch (e) { const error = (!e.plugin || (e.plugin !== PLUGIN_NAME)) ? util.extendError(new plugin_error_1.default({ plugin: PLUGIN_NAME, message: e.message }), e) : e; fancy_log_1.default.error(error); } callback(); }); } module.exports = gulpUpdateNotesResources; //# sourceMappingURL=index.js.map