// //#region Imports ... const XFileTools = require('../tools/x-file.tools'); const XValueTools = require('../tools/x-value.tools'); const XBaseDescriptor = require('./x-base.descriptor'); const XConstDescriptor = require('./x-const.descriptor'); const XContentDescriptor = require('./x-content.descriptor'); //#endregion // //#region Constants ... /** * all possible usage of localeResources ... */ const LocalizationResourceIdentifiers = { ResourceIDs: 'ResourceIDs.', XResourceIDs: 'XResourceIDs.', XAppResourceIDs: 'AppResourceIDs.', ThisResourceIDs: 'this.ResourceIDs.', ThisAppResourceIDs: 'this.AppResourceIDs.', }; //#endregion // //#region ResourceIDsDescriptor ... /** * check an object instance is ResourceIDsDescriptor or not ... * * @param {any} object proposed object to check ... * @returns */ function isResourceIDsDescriptor(object) { // if (!object) { return false; } // let result = false; result = object.hasOwnProperty('resourceIds') && object.hasOwnProperty('appResourceIds') && Array.isArray(object.resourceIds) && Array.isArray(object.appResourceIds); // return result; } /** * retrieve base or filled ResourceIDsDescriptor object instance ... * * @param {any} value a value provider object ... * @returns an instance of ResourceIDsDescriptor object ... */ function createResourceIDsDescriptor(value) { // let result = { resourceIds: [''], appResourceIds: [''] } result.resourceIds.pop(); result.appResourceIds.pop(); // //#region Apply Value ... if (value) { // //#region ResourceIDs ... if (XValueTools.hasChildArray(value.resourceIds)) { result.resourceIds = [ ...value.resourceIds ]; } //#endregion // //#region appResourceIds ... if (XValueTools.hasChildArray(value.appResourceIds)) { result.appResourceIds = [ ...value.appResourceIds ]; } //#endregion } //#endregion // return result; } /** * extract exists used ResourceIds form files ... * * @param {string|string[]} files a file(s) path ... * @returns an instance of ResourceIDsDescriptor ... */ async function extractResourceIDsDescriptor(files) { // // Prepare Result ... let result = createResourceIDsDescriptor(); // // Normalize Files ... const normalFiles = XValueTools.toNormalArray(files); // // Validate Args ... if ( !XValueTools.hasChildArray(normalFiles) || !normalFiles.every(file => XFileTools.isFileExists(file)) ) { return result; } // const readFileContentTasks = normalFiles.map(file => XFileTools.readFile(file)); const fileContents = await Promise.all(readFileContentTasks); if (!XValueTools.hasChildArray(fileContents)) { return result; } // result = extractResourceIDsDescriptorFromContent(fileContents); // return result; } /** * extract exists ResourceIDsDescriptor from file contents ... * * @param {string|string[]} contents a file(s) content(s) ... * @returns an instance of ResourceIDsDescriptor ... */ function extractResourceIDsDescriptorFromContent(contents) { // // Prepare Result ... let result = createResourceIDsDescriptor(); // // Validate Args ... if (!contents) { return result; } // // Normalize Contents ... const normalContents = XValueTools .toNormalArray(contents) .map(c => c.trim()) .filter(c => XValueTools.isValidArg(c)); if (!XValueTools.hasChildArray(normalContents)) { return result; } // // Loop through all normal contents and extract result ... for (const content of normalContents) { // // Find all indexes in File for eachType ... const indexes = XValueTools.findAllIndexes( Object.values(LocalizationResourceIdentifiers), content ); if (!XValueTools.hasChildArray(indexes)) { continue; } // // Try to Parse Content by indexes ... for (const idx of indexes) { // let identifierToken = content.substring(idx, idx + LocalizationResourceIdentifiers.ThisAppResourceIDs.length); if (identifierToken.includes(LocalizationResourceIdentifiers.ThisAppResourceIDs)) { identifierToken = identifierToken.includes(LocalizationResourceIdentifiers.ThisAppResourceIDs); } else if (identifierToken.includes(LocalizationResourceIdentifiers.ThisResourceIDs)) { identifierToken = LocalizationResourceIdentifiers.ThisResourceIDs; } else if (identifierToken.includes(LocalizationResourceIdentifiers.XAppResourceIDs)) { identifierToken = LocalizationResourceIdentifiers.XAppResourceIDs; } else if (identifierToken.includes(LocalizationResourceIdentifiers.XResourceIDs)) { identifierToken = LocalizationResourceIdentifiers.XResourceIDs; } else if (identifierToken.includes(LocalizationResourceIdentifiers.ResourceIDs)) { identifierToken = LocalizationResourceIdentifiers.ResourceIDs; } else { identifierToken = undefined; } // if (!XValueTools.isValidArg(identifierToken)) { continue; } // let endIndex = XValueTools.findNearestIndex( [ ';', '\"', ',', ' ', ')', '\n' ], content, idx, true ); // const identifier = content .substring(idx, endIndex) .replace(identifierToken, ''); if (XValueTools.isValidArg(identifier)) { // switch (identifierToken) { // // ResourceIDs ... case LocalizationResourceIdentifiers.ResourceIDs: case LocalizationResourceIdentifiers.XResourceIDs: case LocalizationResourceIdentifiers.ThisResourceIDs: if (!result.resourceIds.includes(identifier)) { result.resourceIds.push(identifier); } break; // // AppResourceIDs ... case LocalizationResourceIdentifiers.XAppResourceIDs: case LocalizationResourceIdentifiers.ThisAppResourceIDs: if (!result.appResourceIds.includes(identifier)) { result.appResourceIds.push(identifier); } break; } } } } // return result; } //#endregion // //#region LocaleResourceItemDescriptor ... function isLocaleResourceItemDescriptor(value) { // let result = false; // result = value && value.hasOwnProperty('id') && value.hasOwnProperty('value'); // return result; } function createLocaleResourceItemDescriptor(value) { // let result = { id: '', value: '' }; // //#region Apply Value ... if (value) { // //#region id ... if (XValueTools.isValidArg(value.id)) { result.id = value.id; } //#endregion // //#region value ... if (XValueTools.isValidArg(value.value)) { result.value = value.value; } //#endregion } //#endregion // return result; } //#endregion // //#region LocalizationDescriptor ... function isLocalizationDescriptor(value) { // let result = false; // result = value && value.hasOwnProperty('name') && value.hasOwnProperty('locale') && value.hasOwnProperty('language') && value.hasOwnProperty('direction') && value.hasOwnProperty('resources') && Array.isArray(value.resources) && (XValueTools.hasChildArray(value.resources) ? value.resources.every(r => isLocaleResourceItemDescriptor(r)) : true); // return result; } function createLocalizationDescriptor(value) { // let result = { name: '', locale: '', language: '', direction: '', resources: [ createLocaleResourceItemDescriptor() ] }; result.resources.pop(); // //#region Apply Value ... if (value) { // //#region name ... if (XValueTools.isValidArg(value.name)) { result.name = value.name; } //#endregion // //#region locale ... if (XValueTools.isValidArg(value.locale)) { result.locale = value.locale; } //#endregion // //#region language ... if (XValueTools.isValidArg(value.language)) { result.language = value.language; } //#endregion // //#region direction ... if (XValueTools.isValidArg(value.direction)) { result.direction = value.direction; } //#endregion // //#region resources ... if ( XValueTools.hasChildArray(value.resources) && value.resources.every(r => isLocaleResourceItemDescriptor(r)) ) { result.resources = [ ...value.resources ]; } //#endregion } //#endregion // return result; } function extractLocalizationDescriptors( constDescriptor = XConstDescriptor.createDescriptor() ) { // let result = [ createLocalizationDescriptor() ]; result.pop(); // // Validate Args ... if ( !constDescriptor || !XConstDescriptor.isDescriptor(constDescriptor) || !XValueTools.hasChildArray(constDescriptor.content.childs) ) { return result; } // // extract childs of content ... for (const child of constDescriptor.content.childs) { // const localizationDescriptor = createLocalizationDescriptor(); for (const value of child.value) { // if (value.key !== 'resources') { localizationDescriptor[value.key] = XValueTools.toStringExpression(value.value); } else { localizationDescriptor[value.key] = value.value.map(v => { // const id = XValueTools .toStringExpression( v.value.find( vv => vv.key === 'id')?.value ); // const value = XValueTools .toStringExpression( v.value.find( vv => vv.key === 'value')?.value ); // const result = createLocaleResourceItemDescriptor({ id, value, }); // return result; }); } } // result.push(localizationDescriptor); } // return result; } //#endregion // //#region ResourceIDUsedCase ... /** * create an empty/filled LocaleResourceIDUsedCaseDescriptor object instance ... * * @param {any} value value provider for filling ... * @returns an instance of Specific Descriptor ... */ function createLocaleResourceIDUsedCaseDescriptor(value) { // // Prepare Result ... let result = { resourceID: '', usedCases: [ '' ], }; result.usedCases.pop(); // //#region Apply Value ... if (value) { // //#region resourceID ... if (XValueTools.isValidArg(value.resourceID)) { result.resourceID = value.resourceID; } //#endregion // //#region usedCases ... if (XValueTools.hasChildArray(value.usedCases)) { result.usedCases = [ ...value.usedCases ]; } //#endregion } //#endregion // return result; } /** * check an object is LocaleResourceIDUsedCaseDescriptor instance or not ... * * @param {any} value proposed object to check ... * @returns */ function isLocaleResourceIDUsedCaseDescriptor(value) { // let result = false; // result = value && value.hasOwnProperty('resourceID') && value.hasOwnProperty('usedCases') && Array.isArray(value.usedCases); // return result; } //#endregion // // Moduile Exports ... module.exports = { // LocalizationResourceIdentifiers, // isResourceIDsDescriptor, createResourceIDsDescriptor, extractResourceIDsDescriptor, extractResourceIDsDescriptorFromContent, // isLocaleResourceItemDescriptor, createLocaleResourceItemDescriptor, // isLocalizationDescriptor, createLocalizationDescriptor, extractLocalizationDescriptors, // isLocaleResourceIDUsedCaseDescriptor, createLocaleResourceIDUsedCaseDescriptor, }