527 lines
13 KiB
JavaScript
527 lines
13 KiB
JavaScript
//
|
|
//#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,
|
|
} |