alapa
Version:
A cutting-edge web development framework designed to revolutionize the way developers build modern web applications.
214 lines (213 loc) • 8.88 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.Component = void 0;
/* eslint-disable @typescript-eslint/no-explicit-any */
const utils_1 = require("../../../utils");
const interface_1 = require("../../../interface");
const misc_1 = require("../../regex/misc");
const imports_1 = require("../../imports");
const render_1 = require("../../render");
const path_resolver_1 = require("../../path-resolver");
class Component {
static modules = {};
static components = [];
static context = {};
static template = "";
static templatePath = "";
static loadModule(module) {
const { filePath, defaultModule, components, componentsAlias, defaultAlias, } = module;
const moduleContents = render_1.TemplateEngine.getTemplate(filePath);
this.validateModuleContents(moduleContents, filePath);
if (defaultModule != "" && defaultModule != "*") {
this.parseModules(moduleContents, "default", defaultAlias, defaultModule);
}
if (components.length > 0) {
const regex = (0, misc_1.moduleRegex)(false, ...components);
this.parseModules(moduleContents, regex, componentsAlias, components);
}
else if (defaultModule == "*") {
this.parseModules(moduleContents, "all", defaultAlias);
}
if (defaultModule.length == 0 && components.length == 0) {
this.parseModules(moduleContents, "all");
}
}
static validateModuleContents(contents, filePath) {
const defaultComponents = Array.from(contents.matchAll((0, misc_1.moduleRegex)(true)));
if (defaultComponents.length > 1) {
utils_1.Logger.error(`${defaultComponents.length} components are defined in ${filePath}`);
return;
}
}
static handleDefaultModule(defaultModule, alias, moduleContents) {
if (defaultModule === "*" || defaultModule === "") {
this.parseModules(moduleContents, "all", alias);
}
else if (defaultModule) {
this.parseModules(moduleContents, "default", undefined, defaultModule);
}
}
static parseModules(contents, regex = "all", alias, components) {
if (typeof components === "string")
components = [components];
const componentList = new interface_1.List(...(components || []));
const [isDefault, allAlias] = this.initializeFlags(regex, alias);
regex = this.determineRegex(regex, components);
const definedModulesSearch = contents.matchAll(regex);
this.processDefinedModules(definedModulesSearch, componentList, isDefault, allAlias);
}
static initializeFlags(regex, alias) {
const isDefault = regex === "default";
const allAlias = typeof alias === "string" && regex === "all" ? alias : "";
return [isDefault, allAlias];
}
static determineRegex(regex, components) {
if (!components)
components = [];
if (regex === "all" || regex === undefined)
return (0, misc_1.moduleRegex)("all");
if (regex === "default")
return (0, misc_1.moduleRegex)(true, ...components);
return regex;
}
static processDefinedModules(definedModulesSearch, componentList, isDefault, allAlias) {
let foundLength = 0;
for (const match of definedModulesSearch) {
foundLength++;
const { name, propsName, content } = this.extractModuleDetails(match);
componentList.remove(name);
const alias = this.getAlias(name, allAlias);
this.modules[name] = { propsName, name, alias, content };
}
this.logErrors(foundLength, componentList, isDefault);
}
static extractModuleDetails(match) {
let name = match[1] || "";
let propsName = match[2] || "props";
let content = match[3] || "";
if (match[4] && match[2]) {
name = match[2] || "";
propsName = match[3] || "props";
content = match[4] || "";
}
return {
name,
propsName,
content,
};
}
static getAlias(name, allAlias) {
return allAlias.length > 0 ? `${allAlias}.${name}` : name;
}
static logErrors(foundLength, componentList, isDefault) {
if (foundLength === 0) {
const errorMessage = isDefault
? `No default component found${componentList.length > 0 ? `: ${componentList.join()}` : ""}`
: `No components found in: ${componentList.join()}`;
utils_1.Logger.error(errorMessage);
}
else if (componentList.length > 0) {
utils_1.Logger.error(`${componentList.join(", ")} ${componentList.length > 1 ? "components are" : "component is"} not found`);
}
}
static parseComponent(template) {
template = template.replace((0, misc_1.moduleRegex)(), "");
this.components.push(...this.parser(template));
}
static parser(template, getAttribute = true) {
const htmlTags = Array.from(template.matchAll(misc_1.htmlTagsRegex)).map((match) => ({
name: match[1],
attributes: getAttribute ? this.parseAtrAttributes(match[2] || "") : {},
input: match[0],
content: match[3] ?? "",
attributeValue: match[2] ?? "",
}));
const htmlInlineTags = Array.from(template.matchAll(misc_1.htmlInlineTagsRegex)).map((match) => ({
name: match[1],
attributes: getAttribute ? this.parseAtrAttributes(match[2] || "") : {},
input: match[0],
content: "",
attributeValue: match[2] ?? "",
}));
return htmlTags.concat(htmlInlineTags);
}
static parseAtrAttributes(template) {
const attributes = {};
const matches = template.matchAll(misc_1.attributeRegex);
for (const match of matches) {
attributes[match[1]] = match[4] ?? match[1];
}
return attributes;
}
static bundle(template) {
this.parseComponent(template);
let moduleFiles = [];
try {
moduleFiles = imports_1.ImportParser.getFiles(this.templatePath);
}
catch (e) {
throw new Error(`${e.message} in ${this.templatePath}`);
}
this.loadModules(moduleFiles);
}
static compileString(template, context) {
this.context = context || {};
this.bundle(template);
return this.preCompile(template, this.components);
}
static preCompile(template, components) {
for (const component of components) {
const { attributes, content, name, input, attributeValue } = component;
const module = this.modules[name];
if (module) {
const compiled = this.compileComponent(module.content, attributes, content, attributeValue, module.propsName);
template = template.replace(input, compiled.trim());
}
else {
utils_1.Logger.error(`Module '${name}' not found`);
}
}
return template;
}
static compileComponent(content, attributes, componentContent, attributeValue, propsName) {
const context = {
...attributes,
stringAttribute: attributeValue,
content: componentContent,
};
context["attributes"] = attributes;
let compiled = this.engine(content, propsName, context);
const templateParse = this.parser(compiled.trim());
if (templateParse.length > 0) {
compiled = this.preCompile(compiled.trim(), templateParse);
}
return compiled;
}
static compileFile(templatePath, context) {
templatePath = path_resolver_1.PathResolver.resolve(templatePath);
const template = render_1.TemplateEngine.getTemplate(templatePath);
this.template = template;
this.templatePath = templatePath;
return this.compileString(template, context);
}
static engine(component, propsName, context) {
context = context || {};
const key = (0, utils_1.md5)((0, utils_1.randomNumber)());
global["component" + key] = context;
const code = `{% (function () { %}
{% const ${propsName} = {...component${key},...(component${key}['attributes'])} %}
{% delete global["component${key}"]; %}
{% const content = ${propsName}['content'] %}
{% const stringAttribute =${propsName}['stringAttribute'] %}
{% const attributes = ${propsName}['attributes'] %}
${component}
{% }()) %}`;
return render_1.TemplateEngine.compile(code, this.context);
}
static loadModules(modules) {
for (const module of modules) {
this.loadModule(module);
}
}
}
exports.Component = Component;
;