480 lines
11 KiB
JavaScript
480 lines
11 KiB
JavaScript
//
|
|
//#region Imports ...
|
|
const XFileTools = require('../tools/x-file.tools');
|
|
const XValueTools = require('../tools/x-value.tools');
|
|
const XBaseDescriptor = require('./x-base.descriptor');
|
|
//#endregion
|
|
|
|
/**
|
|
* check an object instance is ExportDescriptor or not ...
|
|
*
|
|
* @param {any} object proposed object to check ...
|
|
* @returns
|
|
*/
|
|
function isDescriptor(object) {
|
|
//
|
|
if (!object) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
let result = false;
|
|
result = Array.isArray(object.objects) &&
|
|
object.hasOwnProperty('raw') &&
|
|
object.hasOwnProperty('type') &&
|
|
object.hasOwnProperty('module') &&
|
|
object.hasOwnProperty('objects');
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* retrieve base or filled ExportDescriptor object instance ...
|
|
*
|
|
* @param {any} value a value provider object ...
|
|
* @returns an instance of ExportDescriptor object ...
|
|
*/
|
|
function createDescriptor(value) {
|
|
//
|
|
let result = {
|
|
raw: '',
|
|
type: '',
|
|
module: '',
|
|
objects: ['']
|
|
}
|
|
result.objects.pop();
|
|
|
|
//
|
|
//#region Apply Value ...
|
|
if (value) {
|
|
//
|
|
//#region raw ...
|
|
if (XValueTools.isValidArg(value.raw)) {
|
|
result.raw = value.raw;
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region type ...
|
|
if (
|
|
XValueTools.isValidArg(value.type) ||
|
|
XBaseDescriptor.isValidContentType(value.type)
|
|
) {
|
|
result.type = value.type;
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region module ..
|
|
if (XValueTools.isValidArg(value.module)) {
|
|
result.module = value.module;
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region objects ...
|
|
if (XValueTools.hasChildArray(value.objects)) {
|
|
result.objects = [
|
|
...value.objects
|
|
];
|
|
}
|
|
//#endregion
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* converts an instance of Descriptor to Expression ...
|
|
*
|
|
* @param descriptor an instance of ExportDescriptor ...
|
|
* @returns creator string ...
|
|
*/
|
|
function toExpression(descriptor = createDescriptor()) {
|
|
//
|
|
let result = '';
|
|
|
|
//
|
|
// Validate Arg ...
|
|
if (!isDescriptor(descriptor)) {
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result += XBaseDescriptor.ExpressionKeys.Export +
|
|
' ';
|
|
|
|
//
|
|
//#region objects ...
|
|
//
|
|
if (descriptor.type === XBaseDescriptor.ContentTypes.Object) {
|
|
//
|
|
let objectsIdentifier = descriptor.objects.join(', ');
|
|
objectsIdentifier = `{ ${objectsIdentifier} }`;
|
|
|
|
//
|
|
result += objectsIdentifier;
|
|
} else {
|
|
result += descriptor.objects[0];
|
|
}
|
|
|
|
//
|
|
result += ' ';
|
|
//#endregion
|
|
|
|
//
|
|
//#region module ...
|
|
result += XBaseDescriptor.ExpressionKeys.From +
|
|
' ' +
|
|
XValueTools.surroundBy('\'', descriptor.module);
|
|
//#endregion
|
|
|
|
//
|
|
result += ';'
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* extract all exists ExportDescriptor ...
|
|
*
|
|
* @param {string} file a file path ...
|
|
* @returns a collection of ExportDescriptor ...
|
|
*/
|
|
async function extractDescriptors(file = '') {
|
|
//
|
|
if (!XFileTools.isFileExists(file)) {
|
|
return [];
|
|
}
|
|
|
|
//
|
|
const fileContent = await XFileTools.readFile(file);
|
|
if (!XValueTools.isValidArg(fileContent)) {
|
|
return [];
|
|
}
|
|
|
|
//
|
|
let result = [
|
|
createDescriptor()
|
|
];
|
|
result.pop();
|
|
|
|
//
|
|
result = extractDescriptorsFromContent(fileContent);
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* extract all exists ExportDescriptor ...
|
|
*
|
|
* @param {string} content a file content ...
|
|
* @returns a collection of ExportDescriptor ...
|
|
*/
|
|
function extractDescriptorsFromContent(content = '') {
|
|
//
|
|
// Prepare Result ...
|
|
let result = [
|
|
createDescriptor()
|
|
];
|
|
result.pop();
|
|
|
|
//
|
|
// Validate Args ...
|
|
if (
|
|
!XValueTools.isValidArg(content) ||
|
|
!content.includes(XBaseDescriptor.ExpressionKeys.Export)
|
|
) {
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Extract all key Indexes ...
|
|
const keyIndexes = XBaseDescriptor.
|
|
extractValidIdentifierIndexes(XBaseDescriptor.ExpressionKeys.Export, content)
|
|
.filter(i => {
|
|
//
|
|
// Exports ...
|
|
let startIndex = i;
|
|
let key = XBaseDescriptor.ExpressionKeys.Exports;
|
|
let endIndex = startIndex + key.length;
|
|
let subStr = content.substring(startIndex, endIndex);
|
|
if (subStr === key) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Const ...
|
|
startIndex = i + XBaseDescriptor.ExpressionKeys.Export.length + 1;
|
|
key = XBaseDescriptor.ExpressionKeys.Const;
|
|
endIndex = startIndex + key.length;
|
|
subStr = content.substring(startIndex, endIndex);
|
|
if (subStr === key) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Enum ...
|
|
key = XBaseDescriptor.ExpressionKeys.Enum;
|
|
endIndex = startIndex + key.length;
|
|
subStr = content.substring(startIndex, endIndex);
|
|
if (subStr === key) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Type ...
|
|
key = XBaseDescriptor.ExpressionKeys.Type;
|
|
endIndex = startIndex + key.length;
|
|
subStr = content.substring(startIndex, endIndex);
|
|
if (subStr === key) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Class ...
|
|
key = XBaseDescriptor.ExpressionKeys.Class;
|
|
endIndex = startIndex + key.length;
|
|
subStr = content.substring(startIndex, endIndex);
|
|
if (subStr === key) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
// Interface ...
|
|
key = XBaseDescriptor.ExpressionKeys.Interface;
|
|
endIndex = startIndex + key.length;
|
|
subStr = content.substring(startIndex, endIndex);
|
|
if (subStr === key) {
|
|
return false;
|
|
}
|
|
|
|
//
|
|
return true;
|
|
});
|
|
|
|
//
|
|
// Validate them ...
|
|
if (!XValueTools.hasChildArray(keyIndexes)) {
|
|
return result;
|
|
}
|
|
|
|
//
|
|
// Loop through indexes ...
|
|
for (const index of keyIndexes) {
|
|
//
|
|
// create an empty instance of descriptor ...
|
|
let descriptor = {
|
|
...createDescriptor()
|
|
}
|
|
|
|
//
|
|
let startIndex = index;
|
|
let endIndex = XValueTools.findNearestIndex(
|
|
[
|
|
';',
|
|
'\n'
|
|
],
|
|
content,
|
|
startIndex
|
|
);
|
|
const nearestChar = content.charAt(endIndex);
|
|
if (nearestChar === ';') {
|
|
endIndex++;
|
|
}
|
|
|
|
//
|
|
let identifier = content
|
|
.substring(startIndex, endIndex)
|
|
.trim();
|
|
|
|
//
|
|
// Check Identifier must includes FROM ...
|
|
if (!identifier.includes(XBaseDescriptor.ExpressionKeys.From)) {
|
|
continue;
|
|
}
|
|
|
|
//
|
|
//#region raw ...
|
|
const raw = identifier;
|
|
descriptor.raw = raw;
|
|
//#endregion
|
|
|
|
//
|
|
const fromIndex = identifier.indexOf(XBaseDescriptor.ExpressionKeys.From);
|
|
|
|
//
|
|
//#region extracts Objects ...
|
|
startIndex = XBaseDescriptor.ExpressionKeys.Import.length;
|
|
endIndex = fromIndex;
|
|
identifier = identifier
|
|
.substring(startIndex, endIndex)
|
|
.trim();
|
|
|
|
//
|
|
// Clear Unused Content ...
|
|
identifier = XBaseDescriptor.clearContent(identifier);
|
|
|
|
//
|
|
// Clear Also \n ...
|
|
identifier = XValueTools.clearContent('\n', identifier);
|
|
|
|
//
|
|
if (XValueTools.isSurroundedObject(identifier)) {
|
|
//
|
|
// Clear Object Surround ...
|
|
identifier = XValueTools.clearObjectSurround(identifier);
|
|
|
|
//
|
|
// Extract Imported Objects ...
|
|
let importedObjects = identifier
|
|
.split(',')
|
|
.map(o => o.trim())
|
|
.filter(o => XValueTools.isValidArg(o));
|
|
|
|
//
|
|
descriptor.type = XBaseDescriptor.ContentTypes.Object;
|
|
descriptor.objects = [
|
|
...importedObjects
|
|
];
|
|
} else {
|
|
//
|
|
descriptor.type = XBaseDescriptor.ContentTypes.String;
|
|
descriptor.objects.push(identifier)
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
//#region Module ...
|
|
startIndex = fromIndex + XBaseDescriptor.ExpressionKeys.From.length;
|
|
identifier = raw
|
|
.substring(startIndex)
|
|
.trim();
|
|
identifier = XValueTools.findClosedStrings(identifier)[0].content;
|
|
if (XValueTools.isSurroundedString(identifier)) {
|
|
//
|
|
const surroundSymbol = identifier.charAt(0);
|
|
identifier = XValueTools.clearSurround(surroundSymbol, identifier);
|
|
}
|
|
|
|
//
|
|
descriptor.module = identifier;
|
|
//#endregion
|
|
|
|
//
|
|
result.push(descriptor);
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
|
|
//
|
|
//#region Custom Actions ...
|
|
function update(
|
|
descriptors,
|
|
addOrUpdates
|
|
) {
|
|
//
|
|
// Prepare Result ...
|
|
let result = [createDescriptor()];
|
|
result.pop();
|
|
|
|
//
|
|
//#region Validate Args ...
|
|
//
|
|
// Validate Descriptors ...
|
|
if (XValueTools.hasChildArray(descriptors)) {
|
|
//
|
|
// Validate All Objects is Descriptor ...
|
|
const isAllIsImport = descriptors.every(d => isDescriptor(d));
|
|
if (!isAllIsImport) {
|
|
return result;
|
|
}
|
|
|
|
//
|
|
result = [
|
|
...descriptors
|
|
];
|
|
}
|
|
|
|
//
|
|
// Validate addOrUpdates ...
|
|
if (XValueTools.hasChildArray(addOrUpdates)) {
|
|
//
|
|
// Validate All Objects is Descriptor ...
|
|
const isAllIsImport = addOrUpdates.every(d => isDescriptor(d));
|
|
if (!isAllIsImport) {
|
|
return result;
|
|
}
|
|
} else {
|
|
return result;
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
for (const desc of addOrUpdates) {
|
|
//
|
|
// Find same Module if exists ...
|
|
//
|
|
let descriptor = createDescriptor(desc);
|
|
|
|
//
|
|
let existsModuleIndex = result.findIndex(d => descriptor.module === d.module);
|
|
if (existsModuleIndex >= 0) {
|
|
//
|
|
descriptor = result[existsModuleIndex];
|
|
let mustAddObjects = desc.objects.filter(o => o.includes('*') ||
|
|
!descriptor.objects.includes(o));
|
|
if (XValueTools.hasChildArray(mustAddObjects)) {
|
|
descriptor.objects = [
|
|
...descriptor.objects,
|
|
...mustAddObjects
|
|
];
|
|
}
|
|
|
|
//
|
|
result[existsModuleIndex] = {
|
|
...descriptor
|
|
};
|
|
} else {
|
|
//
|
|
let mustAddObjects = descriptor.objects.filter(o => o.includes('*') ||
|
|
result
|
|
.map(d => d.objects)
|
|
.every(objects => !objects.includes(o))
|
|
);
|
|
|
|
//
|
|
descriptor.objects = [
|
|
...mustAddObjects
|
|
];
|
|
|
|
//
|
|
result.push(descriptor);
|
|
}
|
|
}
|
|
|
|
//
|
|
return result;
|
|
}
|
|
//#endregion
|
|
|
|
//
|
|
// Moduile Exports ...
|
|
module.exports = {
|
|
//
|
|
isDescriptor,
|
|
toExpression,
|
|
createDescriptor,
|
|
extractDescriptors,
|
|
extractDescriptorsFromContent,
|
|
|
|
//
|
|
update,
|
|
} |