Files
xSaherElmClient/platforms/electron/modules/models/x-interface.descriptor.js
T
2026-04-17 17:04:44 +03:30

380 lines
9.0 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 XContentDescriptor = require('./x-content.descriptor');
//#endregion
/**
* check an object instance is InterfaceDescriptor 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') &&
Array.isArray(object.extends) &&
object.hasOwnProperty('extends') &&
object.hasOwnProperty('isExtended') &&
object.hasOwnProperty('isExported');
//
return result;
}
/**
* retrieve base or filled InterfaceDescriptor object instance ...
*
* @param {any} value a value provider object ...
* @returns an instance of InterfaceDescriptor object ...
*/
function createDescriptor(value) {
//
let result = {
raw: '',
name: '',
extends: [''],
isExtended: false,
isExported: false,
properties: {
...XContentDescriptor.createDescriptor()
},
};
result.extends.pop();
//
//#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 isExported ...
if (!!value.isExported) {
result.isExported = value.isExported;
}
//#endregion
//
//#region isExtended ...
if (!!value.isExtended) {
result.isExtended = value.isExtended;
}
//#endregion
//
//#region extends ...
if (XValueTools.hasChildArray(value.extends)) {
result.extends = [
...value.extends
];
}
//#endregion
//
//#region properties ...
if (
value.properties &&
XContentDescriptor.isDescriptor(value.properties)
) {
result.properties = {
...value.properties
};
}
//#endregion
}
//#endregion
//
return result;
}
/**
* converts an instance of Descriptor to Expression ...
*
* @param descriptor an instance of InterfaceDescriptor ...
* @returns creator string ...
*/
function toExpression(descriptor = createDescriptor()) {
//
let result = '';
//
// Validate Arg ...
if (!isDescriptor(descriptor)) {
return result;
}
//
result += (
!!descriptor.isExported ?
XBaseDescriptor.ExpressionKeys.Export + ' ' :
''
) +
XBaseDescriptor.ExpressionKeys.Interface +
' ' +
descriptor.name +
' ' +
(
!!descriptor.isExtended &&
XValueTools.hasChildArray(descriptor.extends) ?
XBaseDescriptor.ExpressionKeys.Extends +
' ' +
descriptor.extends.join(', ') +
' ' :
''
);
//
let contentExpression = XContentDescriptor.toExpression(descriptor.properties, ':', ';');
if (XValueTools.isValidArg(contentExpression)) {
result += contentExpression;
}
//
return result;
}
/**
* extract all exists InterfaceDescriptors ...
*
* @param {string} file a file path ...
* @returns a collection of InterfaceDescriptors ...
*/
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 InterfaceDescriptors ...
*
* @param {string} content a file content ...
* @returns a collection of InterfaceDescriptors ...
*/
function extractDescriptorsFromContent(content = '') {
//
// Prepare result ...
let result = [
createDescriptor()
];
result.pop();
//
// Validate Args ...
if (
!XValueTools.isValidArg(content) ||
!content.includes(XBaseDescriptor.ExpressionKeys.Interface)
) {
return result;
}
//
// Extract all Key Indexes ...
const keyIndexes = XBaseDescriptor.
extractValidIdentifierIndexes(XBaseDescriptor.ExpressionKeys.Interface, 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.Interface.length + 1;
//
// create an empty instance of descriptor ...
let descriptor = {
...createDescriptor()
}
//
//#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
//
// Closed Item ...
let closedContents = XValueTools.findClosedContent('{', '}', content, index);
if (!XValueTools.hasChildArray(closedContents)) {
continue;
}
//
let interfaceContentIndexer = closedContents[0];
endIndex = interfaceContentIndexer.start - 1;
//
identifier = content
.substring(startIndex, endIndex)
.trim();
//
//#region extract Name, Extends ...
let name = '';
let nameCandidate = identifier
.replace(XBaseDescriptor.ExpressionKeys.Export, '')
.replace(XBaseDescriptor.ExpressionKeys.Interface, '')
.trim();
let extendsIdentifiers = nameCandidate;
if (nameCandidate.includes(XBaseDescriptor.ExpressionKeys.Extends)) {
//
// Name ...
let nameEndIndex = nameCandidate.indexOf(XBaseDescriptor.ExpressionKeys.Extends);
nameCandidate = nameCandidate
.substring(0, nameEndIndex)
.trim();
//
//isExtended ...
descriptor.isExtended = true;
extendsIdentifiers = extendsIdentifiers
.substring(nameEndIndex + XBaseDescriptor.ExpressionKeys.Extends.length)
.trim();
//
if (
!XValueTools.isValidArg(nameCandidate) ||
!XValueTools.isValidArg(extendsIdentifiers)
) {
continue;
}
//
// Extends ...
descriptor.extends = [
...extendsIdentifiers
.split(',')
.map(e => e.trim())
.filter(e => XValueTools.isValidArg(e))
];
//
name = nameCandidate;
} else {
name = nameCandidate;
}
//
if (!XValueTools.isValidArg(name)) {
continue;
}
//
descriptor.name = name;
//#endregion
//
//#region extract Content ...
let contentContainer = interfaceContentIndexer.content;
//
// Clear Content ...
contentContainer = XBaseDescriptor
.clearContent(contentContainer);
//
const contentType = XBaseDescriptor.getContentType(contentContainer);
const parsedContents = XBaseDescriptor.parseContent(
contentContainer,
true
);
const contentDescriptor = XContentDescriptor.createDescriptor();
//
contentDescriptor.type = contentType;
contentDescriptor.childs = [
...parsedContents
];
//
descriptor.properties = {
...contentDescriptor
}
//#endregion
//
//#region Extract raw content ...
//
endIndex = interfaceContentIndexer.end + 1;
identifier = content
.substring(startIndex, endIndex)
.trim();
if (!XValueTools.isValidArg(identifier)) {
continue;
}
//
descriptor.raw = identifier;
//#endregion
//
result.push(descriptor);
}
//
return result;
}
//
// Module Exports ...
module.exports = {
//
isDescriptor,
toExpression,
createDescriptor,
extractDescriptors,
extractDescriptorsFromContent,
}