// //#region Imports ... const XFileTools = require('../tools/x-file.tools'); const XValueTools = require('../tools/x-value.tools'); const XBaseDescriptor = require('./x-base.descriptor'); const XContentDescriptor = require('./x-content.descriptor'); //#endregion /** * check an object instance is ConstDescriptor or not ... * * @param {any} object proposed object to check ... * @returns */ function isDescriptor(object) { // if (!object) { return false; } // let result = false; result = object.hasOwnProperty('raw') && object.hasOwnProperty('name') && object.hasOwnProperty('content') && object.hasOwnProperty('isExported'); // return result; } /** * retrieve base or filled ConstDescriptor object instance ... * * @param {any} value a value provider object ... * @returns an instance of ConstDescriptor object ... */ function createDescriptor(value) { // let result = { raw: '', name: '', type: '', content: { ...XContentDescriptor.createDescriptor() }, isExported: false, }; // //#region Apply Value ... if (value) { // //#region raw ... if (XValueTools.isValidArg(value.raw)) { result.raw = value.raw; } //#endregion // //#region name ... if (XValueTools.isValidArg(value.name)) { result.name = value.name; } //#endregion // //#region type ... if (XValueTools.isValidArg(value.type)) { result.type = value.type; } //#endregion // //#region content ... if ( value.content && XContentDescriptor.isDescriptor(value.content) ) { result.content = { ...value.content }; } //#endregion // //#region isExported ... if (!!value.isExported) { result.isExported = value.isExported; } //#endregion } //#endregion // return result; } /** * converts an instance of Descriptor to Expression ... * * @param descriptor an instance of ConstDescriptor ... * @returns creator string ... */ function toExpression(descriptor = createDescriptor()) { // let result = ''; // // Validate Arg ... if (!isDescriptor(descriptor)) { return result; } // result += ( !!descriptor.isExported ? XBaseDescriptor.ExpressionKeys.Export + ' ' : '' ) + XBaseDescriptor.ExpressionKeys.Const + ' ' + descriptor.name + ( XValueTools.isValidArg(descriptor.type) ? ': ' + descriptor.type : '' ) + ' = '; // let contentExpression = XContentDescriptor.toExpression(descriptor.content, ':'); if (XValueTools.isValidArg(contentExpression)) { result += contentExpression; } // result += ';'; // return result; } /** * extract all exists ConstDescriptors ... * * @param {string} file a file path ... * @returns a collection of ConstDescriptors ... */ 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 ConstDescriptors ... * * @param {string} content a file content ... * @returns a collection of ConstDescriptors ... */ function extractDescriptorsFromContent(content = '') { // // Prepare result ... let result = [ createDescriptor() ]; result.pop(); // // Validate Args ... if ( !XValueTools.isValidArg(content) || !content.includes(XBaseDescriptor.ExpressionKeys.Const) ) { return result; } // // Extract all Key Indexes ... const keyIndexes = XBaseDescriptor. extractValidIdentifierIndexes(XBaseDescriptor.ExpressionKeys.Const, content); // // Validate Keys Exists on Content ... if (!XValueTools.hasChildArray(keyIndexes)) { return result; } // // Loop through indexes ... for (let index of keyIndexes) { // let startIndex = index - 1; let endIndex = index + XBaseDescriptor.ExpressionKeys.Const.length + 1; // // create an empty instance of descriptor ... let descriptor = { ...createDescriptor() } // //#region Name and Type extractor ... const nameEndIndex = content.indexOf('=', index); identifier = content .substring(index + XBaseDescriptor.ExpressionKeys.Const.length, nameEndIndex) .trim(); if (XValueTools.isValidArg(identifier)) { // // Check to Extract Type ... if (identifier.includes(':')) { // startIndex = 0; endIndex = identifier.indexOf(':', startIndex); // descriptor.name = identifier .substring(startIndex, endIndex) .trim(); // // Type extraction ... startIndex = endIndex + 1; descriptor.type = identifier .substring(startIndex) .trim(); } else { descriptor.name = identifier; } } //#endregion // //#region Extract isExported ... const isExported = XBaseDescriptor.checkIsExported(index, content); descriptor.isExported = isExported; if (isExported) { startIndex = index - XBaseDescriptor.ExpressionKeys.Export.length - 1; } else { startIndex = index; } //#endregion // //#region Extract raw content ... identifier = content.substring(startIndex); startIndex = 0; endIndex = XValueTools.findNearestIndex( [ ';', '{', '[', '\n' ], identifier, 0 // nameEndIndex - startIndex ); const nearestChar = identifier.charAt(endIndex); if (nearestChar === '{') { // const closedItemsIndexes = XValueTools.findClosedContent('{', '}', identifier, endIndex); if (!XValueTools.hasChildArray(closedItemsIndexes)) { continue; } // endIndex = closedItemsIndexes[0].end; } else if (nearestChar === '[') { // const closedItemsIndexes = XValueTools.findClosedContent('[', ']', identifier, endIndex); if (!XValueTools.hasChildArray(closedItemsIndexes)) { continue; } // endIndex = closedItemsIndexes[0].end; } // identifier = identifier .substring(startIndex, endIndex + 1) .trim(); if (XValueTools.isValidArg(identifier)) { descriptor.raw = identifier; } //#endregion // //#region Parse Content ... startIndex = identifier.indexOf('=', 0); let contentContainer = identifier .substring(startIndex + 1) .trim() // // Clear Content ... contentContainer = XBaseDescriptor .clearContent(contentContainer); // const contentType = XBaseDescriptor.getContentType(contentContainer); const parsedContents = XBaseDescriptor.parseContent(contentContainer) || []; const contentDescriptor = XContentDescriptor.createDescriptor(); // contentDescriptor.type = contentType; contentDescriptor.childs = [ ...parsedContents ]; // descriptor.content = { ...contentDescriptor }; //#endregion // result.push(descriptor); } // return result; } // // Module Exports ... module.exports = { // isDescriptor, toExpression, createDescriptor, extractDescriptors, extractDescriptorsFromContent, }