UNPKG

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
"use strict"; 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;