// //#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, }