diff --git a/docs/feature-overview.md b/docs/feature-overview.md index 2756be7..78dc7bc 100644 --- a/docs/feature-overview.md +++ b/docs/feature-overview.md @@ -41,29 +41,3 @@ export const ComponentB = () => { return ; }; ``` - -## Good to Know - -You can't use the same name for things. Otherwise, the compiler will break. - -### Correct - -```ts -// fileA.ts -const MyValue = 2; - -// fileB.ts -const MyValueB = 5; -``` - -### Incorrect - -The example below will break up the app because both consts are using the same name. - -```ts -// fileA.ts -const MyValue = 2; - -// fileB.ts -const MyValue = 5; -``` diff --git a/lib/actions/handleNames.js b/lib/actions/handleNames.js new file mode 100644 index 0000000..19b4b3e --- /dev/null +++ b/lib/actions/handleNames.js @@ -0,0 +1,465 @@ +/** + * Handle const/var/let names to avoid duplicates + */ + +const { + BETWEEN_EXPORT_CONST_AND_EQUAL, + SPACES, + BETWEEN_EXPORT_DEFAULT_FUNCTION_AND_OPEN_PARENTHESE, + AFTER_EXPORT_DEFAULT, + SPECIAL_CHARACTERS_AND_SPACES, + BETWEEN_EXPORT_LET_AND_EQUAL, + BETWEEN_EXPORT_VAR_AND_EQUAL, + BETWEEN_EXPORT_FUNCTION_AND_OPEN_PARENTHESE, +} = require("../regexp"); +const { + capitalize_first_letter, + get_randon_hexadecimal, + get_random_character, +} = require("../utils"); + +/** + * Get "export const" items + * @param {string} content + */ +const getExportConsts = (content) => { + let foundItems = content.match(BETWEEN_EXPORT_CONST_AND_EQUAL); + + // Remove spaces + if (foundItems) { + foundItems = foundItems.map((item) => item.replaceAll(SPACES, "")); + } + + return foundItems || []; +}; + +/** + * Get "export let" items + * @param {string} content + */ +const getExportLets = (content) => { + let foundItems = content.match(BETWEEN_EXPORT_LET_AND_EQUAL); + + // Remove spaces + if (foundItems) { + foundItems = foundItems.map((item) => item.replaceAll(SPACES, "")); + } + + return foundItems || []; +}; + +/** + * Get "export var" items + * @param {string} content + */ +const getExportVars = (content) => { + let foundItems = content.match(BETWEEN_EXPORT_VAR_AND_EQUAL); + + // Remove spaces + if (foundItems) { + foundItems = foundItems.map((item) => item.replaceAll(SPACES, "")); + } + + return foundItems || []; +}; + +/** + * Get "export function" items + * @param {string} content + */ +const getExportFunction = (content) => { + let foundItems = content.match(BETWEEN_EXPORT_FUNCTION_AND_OPEN_PARENTHESE); + + // Remove spaces + if (foundItems) { + foundItems = foundItems.map((item) => item.replaceAll(SPACES, "")); + } + + return foundItems || []; +}; + +/** + * Get "export default function" items + * @param {string} content + */ +const getExportDefaultFunction = (content) => { + let foundItems = content.match( + BETWEEN_EXPORT_DEFAULT_FUNCTION_AND_OPEN_PARENTHESE, + ); + + // Remove spaces + if (foundItems) { + foundItems = foundItems.map((item) => item.replaceAll(SPACES, "")); + } + + return foundItems || []; +}; + +/** + * Get "export default" items + * @param {string} content + */ +const getExportDefault = (content) => { + // Remove all "export default function" + const _content = content.replaceAll("export default function", ""); + + let foundItems = _content.match(AFTER_EXPORT_DEFAULT); + + // Remove spaces + if (foundItems) { + foundItems = foundItems.map((item) => + item.replaceAll(SPACES, "").replaceAll(SPECIAL_CHARACTERS_AND_SPACES, ""), + ); + } + + return foundItems || []; +}; + +/** + * Generates the exports schema + * + * + * exports organizer - original state + * { + * "caminho/do/arquivo.jsx": [{MyVar: "MyVar"}, {MyVar2: "MyVar2"}] + * } + * + * exports organizer - when the item needs to be changed + * { + * "caminho/do/arquivo.jsx": [{MyVar: "MyVar_newName"}, {MyVar2: "MyVar2_nameName"}] + * } + * + * + * @param {{filePath: string, toImport: string[], content: string}[]} fileSchemas + * @returns {Record}[]>} + */ +const getExportsOrganizer = (fileSchemas) => { + const exportsOrganizer = []; + + fileSchemas.forEach((schema) => { + // Cria lista de exports + exportsOrganizer[schema.filePath] = []; + + let exports = []; + // Verifica se já tem os nomes de elementos no conteúdo anterior + // exports = [...exports, ...getExportConsts(schema.content)]; + + exports = [ + ...getExportConsts(schema.content), + ...getExportLets(schema.content), + ...getExportVars(schema.content), + ...getExportFunction(schema.content), + ...getExportDefaultFunction(schema.content), + ...getExportDefault(schema.content), + ]; + + exports.forEach((exportItem) => + exportsOrganizer[schema.filePath].push({ [exportItem]: exportItem }), + ); + }); + + return exportsOrganizer; +}; + +/** + * Generate new name + * @param {string} currentName + */ +const createNewName = () => { + let randomHexName = get_randon_hexadecimal(6); + return capitalize_first_letter( + `${get_random_character()}${get_random_character()}_${randomHexName}`, + ); +}; + +/** + * Change the fileSchema.content in other files when a dependent item gets its name changed + * @param {string} contentFilePath + * @param {string} itemName + * @param {string} newItemName + * @param {{filePath: string, toImport: string[], content: string}[]} fileSchemas schemas to change the files content when a item gets its name changed + */ +const replaceItemNamesInOtherFilesContent = ( + contentFilePath, + itemName, + newItemName, + fileSchemas, +) => { + /** + * 1 - quando trocar o nome do item, tem que checar pra ser exato para evitar essa situacao + * App.fooBaar + * AppRoute.blabla + * + * Quero trocar o "App" por "App__2", se nao verificar o valor exato, o "AppRoute" + * também vai ser alterado erroneamente. ex: "App__2Route". + */ + + fileSchemas.forEach((fileSchema, fileSchemaIndex) => { + // Verifica se esse fileSchema depende do arquivo atual + if (fileSchema.toImport.includes(contentFilePath)) { + // Se tiver, altera o conteúdo deste arquivo para usar o novo nome do item importado + // do arquivo atual + let fileSchemaContent = fileSchema.content; + + // RegExp aqui + // Regex: Troca somente e tão somente o item, nem mais nem menos, evitando assim + // trocar items erronamente como na descricao acima. + const replaceItemRegexp = new RegExp("\\b" + itemName + "\\b", "gm"); + + fileSchemaContent = fileSchemaContent.replaceAll( + replaceItemRegexp, + newItemName, + ); + + // Seta novo valor + fileSchemas[fileSchemaIndex].content = fileSchemaContent; + } + }); + + return fileSchemas; +}; + +/** + * Replace content in current file (inside the fileSchema) + * @param {string} contentFilePath + * @param {string} content + * @param {{filePath: string, toImport: string[], content: string}[]} fileSchemas schemas to change the files content when a item gets its name changed + */ +const replaceContentInCurrentFile = (contentFilePath, content, fileSchemas) => { + const currentFileSchema = fileSchemas.find( + (item) => item.filePath === contentFilePath, + ); + const fileSchemaIndex = fileSchemas.indexOf(currentFileSchema); + + // Update content + currentFileSchema.content = content; + + fileSchemas[fileSchemaIndex] = currentFileSchema; + + return fileSchemas; +}; + +/** + * Replace the item name inside the content + * @param {string} content + * @param {string} itemName + * @param {string} newItemName + * @param {string} contentFilePath + * @param {{filePath: string, toImport: string[], content: string}[]} fileSchemas schemas to change the files content when a item gets its name changed + */ +const replaceNamesInContent = ( + content, + itemName, + newItemName, + contentFilePath, + fileSchemas, +) => { + // Replace const values + // ex: const App + // nao pega: const AppRoute + // O mesmo para os proximos + // (const App)[^a-zA-Z0-9=] + // TODO: reutilizar os do checkIfItemExistInContent + const constRegExp = new RegExp(`(const ${itemName})[^a-zA-Z0-9=]`, "gm"); + const letRegExp = new RegExp(`(let ${itemName})[^a-zA-Z0-9=]`, "gm"); + const varRegExp = new RegExp(`(var ${itemName})[^a-zA-Z0-9=]`, "gm"); + const functionRegExp = new RegExp( + `(function ${itemName})[^a-zA-Z0-9=]`, + "gm", + ); + + // 1 - Testa, se aprovado, mudar o nome dos items no corpo do arquivo atual + // 2 - Ir em todos arquivos que dependem deste arquivo e mudar o nome do item lá + + // Const + const testConst = content.match(constRegExp); + if (testConst) { + const constName = testConst.join(""); + const newConstName = constName.replaceAll(itemName, newItemName); + content = content.replaceAll(constName, newConstName); + + // Replace content (with updated item names) in current file + fileSchemas = replaceContentInCurrentFile( + contentFilePath, + content, + fileSchemas, + ); + + // Replace item names in other files content + fileSchemas = replaceItemNamesInOtherFilesContent( + contentFilePath, + itemName, + newItemName, + fileSchemas, + ); + } + + // Let + const testLet = content.match(letRegExp); + if (testLet) { + const letName = testLet.join(""); + const newLetName = letName.replaceAll(itemName, newItemName); + content = content.replaceAll(letName, newLetName); + + // Replace content (with updated item names) in current file + fileSchemas = replaceContentInCurrentFile( + contentFilePath, + content, + fileSchemas, + ); + + // Replace item names in other files content + fileSchemas = replaceItemNamesInOtherFilesContent( + contentFilePath, + itemName, + newItemName, + fileSchemas, + ); + } + + // Var + const testVar = content.match(varRegExp); + if (testVar) { + const varName = testVar.join(""); + const newVarName = varName.replaceAll(itemName, newItemName); + content = content.replaceAll(varName, newVarName); + + // Replace content (with updated item names) in current file + fileSchemas = replaceContentInCurrentFile( + contentFilePath, + content, + fileSchemas, + ); + + // Replace item names in other files content + fileSchemas = replaceItemNamesInOtherFilesContent( + contentFilePath, + itemName, + newItemName, + fileSchemas, + ); + } + + // Function + const testFunction = content.match(functionRegExp); + if (testFunction) { + const functionName = testFunction.join(""); + const newFunctionName = functionName.replaceAll(itemName, newItemName); + content = content.replaceAll(functionName, newFunctionName); + + // Replace content (with updated item names) in current file + fileSchemas = replaceContentInCurrentFile( + contentFilePath, + content, + fileSchemas, + ); + + // Replace item names in other files content + fileSchemas = replaceItemNamesInOtherFilesContent( + contentFilePath, + itemName, + newItemName, + fileSchemas, + ); + } + + return { content, fileSchemas }; +}; + +/** + * Verifica se o item (const, let, var, function) existe no content + * @param {string} content + * @param {string} itemName + */ +const checkIfItemExistInContent = (content, itemName) => { + // Replace const values + // ex: const App + // nao pega: const AppRoute + // O mesmo para os proximos + // (const App)[^a-zA-Z0-9=] + const constRegExp = new RegExp(`(const ${itemName})[^a-zA-Z0-9=]`, "gm"); + const letRegExp = new RegExp(`(let ${itemName})[^a-zA-Z0-9=]`, "gm"); + const varRegExp = new RegExp(`(var ${itemName})[^a-zA-Z0-9=]`, "gm"); + const functionRegExp = new RegExp( + `(function ${itemName})[^a-zA-Z0-9=]`, + "gm", + ); + + return Boolean( + content.match(constRegExp) || + content.match(letRegExp) || + content.match(varRegExp) || + content.match(functionRegExp), + ); +}; + +/** + * Handle const/var/let names to avoid duplicates + * @param {{filePath: string, toImport: string[], content: string}[]} fileSchemas + */ +const handleNames = (fileSchemas) => { + let tempBundle = ""; + + /** + * exports organizer - original state + * { + * "caminho/do/arquivo.jsx": [{MyVar: "MyVar"}, {MyVar2: "MyVar2"}] + * } + * + * exports organizer - when the item needs to be changed + * { + * "caminho/do/arquivo.jsx": [{MyVar: "MyVar_newName"}, {MyVar2: "MyVar2_nameName"}] + * } + */ + const exportsOrganizer = getExportsOrganizer(fileSchemas); + + // Observe and changes duplicated names + // reverse (need to load deepest content first) + const itemsToProcess = Object.keys(exportsOrganizer).reverse(); + // ex: itemKey = caminho/para/arquivo.tsx + itemsToProcess.forEach((itemKey) => { + const fileSchema = fileSchemas.find( + (fileSchema) => fileSchema.filePath === itemKey, + ); + + let fileContent = fileSchema?.content || ""; + + // Checa se o nome dos exports do arquivo já existem no bundle + // Exports do arquivo atual + exportsOrganizer[itemKey].forEach((exportObj, objIndex) => { + const exportKeyName = Object.keys(exportObj)[0]; + + // Verifica se ja tem um recurso (const, var, let, function) usando esse nome + if (checkIfItemExistInContent(tempBundle, exportKeyName)) { + // Se tiver, troca o nome no arquivo/conteudo atual... + + // Troca nome do item no organizer + /** + * = {"caminho/arquivo.tsx": [index of export key][key name]} + */ + const newName = createNewName(exportKeyName); + exportsOrganizer[itemKey][objIndex][exportKeyName] = newName; + // exportsOrganizer[itemKey][importKeyName] = 'NewName' + + // atualiza o fileContent com os novos items + // ...e atualiza o nome do item nos arquivos que dependem dele + const result = replaceNamesInContent( + fileContent, + exportKeyName, + newName, + itemKey, + fileSchemas, + ); + + fileContent = result.content; + fileSchemas = result.fileSchemas; + } + }); + + tempBundle += fileContent; + }); + + return fileSchemas; +}; + +module.exports = handleNames; diff --git a/lib/actions/loadFilesContent.js b/lib/actions/loadFilesContent.js index 6b7b177..e93adb1 100644 --- a/lib/actions/loadFilesContent.js +++ b/lib/actions/loadFilesContent.js @@ -1,4 +1,4 @@ -const { process_file } = require("../parse"); +const { process_file, process_file_content } = require("../parse"); // Load App Files Content based on files schema // const loadFilesContent = (orderedFilesToImport) => { @@ -11,13 +11,31 @@ const { process_file } = require("../parse"); // }; /** - * (Recommended) * Load files based on the filePath sequence */ -const loadFilesContent = (filesToLoad) => { +// const loadFilesContent = (filesToLoad) => { +// let bundleFile = ""; +// filesToLoad.forEach((filePath) => { +// bundleFile += process_file(filePath); +// }); + +// return bundleFile; +// }; + +/** + * (Recommended) + * Load files based on the fileSchemas sequence + * @param {{filePath: string, toImport: string[], content: string}[]} fileSchemas + */ +const loadFilesContentByFileSchemas = (fileSchemas) => { let bundleFile = ""; - filesToLoad.forEach((filePath) => { - bundleFile += process_file(filePath); + // Reverse sequence to load the deepest first + fileSchemas = fileSchemas.reverse(); + fileSchemas.forEach((fileSchema) => { + const transpileTypescript = + fileSchema.filePath.endsWith(".ts") || + fileSchema.filePath.endsWith(".tsx"); + bundleFile += process_file_content(fileSchema.content, transpileTypescript); }); return bundleFile; @@ -77,4 +95,6 @@ const loadFilesContent = (filesToLoad) => { // return bundleFile; // }; -module.exports = loadFilesContent; +module.exports = { + loadFilesContentByFileSchemas, +}; diff --git a/lib/actions/loadFilesInfo.js b/lib/actions/loadFilesInfo.js index 2692904..ccc8e19 100644 --- a/lib/actions/loadFilesInfo.js +++ b/lib/actions/loadFilesInfo.js @@ -2,6 +2,7 @@ const path = require("path"); const fs = require("fs"); const helpers = require("../helpers"); const { removeComments } = require("../parse"); +const handleNames = require("./handleNames"); /** * To be like: @@ -10,7 +11,8 @@ const { removeComments } = require("../parse"); * [ * { * filePath: "file/path/ModuleFile.tsx", - * toImport: ["path/moduleFile1.tsx", "path/moduleFile2.tsx"] + * toImport: ["path/moduleFile1.tsx", "path/moduleFile2.tsx"], + * content: " ..." * nextFilesToLoad: [ * "path/to/import/ModuleFile1.tsx", * "path/to/import/ModuleFile2.tsx", @@ -34,8 +36,7 @@ const processFileSchema = (filePath) => { if (orderedFilesToImport.length === 0) { orderedFilesToImport.push(filePath); } - // console.log("\n\n"); - // console.log("Processando:", filePath, "||"); + let parentFolder = "."; if (filePath) { const parentPathParts = filePath.split("/"); @@ -55,6 +56,7 @@ const processFileSchema = (filePath) => { // pode ser deletado no final do processo nextFilesToLoad: [], toImport: [], + content: fileContent, }; fileImportsPath.forEach((importPath) => { // Usa src para inicio ou o caminho do pai do arquivo sendo processado atualmente @@ -89,7 +91,6 @@ const processFileSchema = (filePath) => { contentOrderer.push(currentFileSchema); // Recursividade - // console.log("RECURSIVIDADE:"); currentFileSchema.nextFilesToLoad.forEach((fileToImport) => { processFileSchema(fileToImport); }); @@ -108,13 +109,21 @@ const loadFilesInfo = (entryFile) => { // Finaliza o processo do contentOrderer deletando o campo "filesToImport" // de todos os filhos, já que agora náo são mais necessarios - contentOrderer.map((item) => { - delete item.filesToImport; - return item; + contentOrderer = contentOrderer.map((item) => { + const newItem = { + filePath: item.filePath, + toImport: item.toImport, + content: item.content, + }; + delete newItem.filesToImport; + return newItem; }); + // Handle names -> remove const duplicates + contentOrderer = handleNames(contentOrderer); + return { - filesSchema: contentOrderer, + fileSchemas: contentOrderer, // orderedFilesToImport: orderedFilesToImport.reverse(), orderedFilesToImport: contentOrderer .map((schema) => schema.filePath) diff --git a/lib/compiler.js b/lib/compiler.js index 33b1f9a..8d28e29 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -9,7 +9,7 @@ const { removeBlankLines, applyEnvironment, parseOptions, - mimify, + minify, } = require("./parse"); const saveFinalBundleFile = require("./actions/saveFinalBundleFile"); const addSignatures = require("./actions/addSignatures"); @@ -35,23 +35,14 @@ function compile_files() { const filesInfo = loadFilesInfo(entryFile); - // console.log("Files Schema:"); - // console.log(filesInfo.filesSchema); - - // NOTE - /** - * Se essa ordem abaixo nao funcionar, mudar a hierarquia de carga pra carregar - * linearmente todo os items do arquivo sendo processado. - */ - // console.log("\n\n"); - // console.log("Ordered Files to Import:"); - // console.log(filesInfo.orderedFilesToImport); - // Tools -> Header contents let bundleContent = toolsFiles.loadHeaderFilesContent(); // Load App files content - bundleContent += loadFilesContent(filesInfo.orderedFilesToImport); + // bundleContent += loadFilesContent(filesInfo.orderedFilesToImport); + bundleContent += loadFilesContent.loadFilesContentByFileSchemas( + filesInfo.fileSchemas, + ); // Tools -> Indexer bundleContent += toolsFiles.loadIndexerContent(); @@ -71,7 +62,7 @@ function compile_files() { bundleContent = parseOptions(bundleContent); // Mimify - bundleContent = mimify(bundleContent); + bundleContent = minify(bundleContent); // Add sinatures bundleContent = addSignatures(bundleContent); diff --git a/lib/helpers.js b/lib/helpers.js index 2034362..8ba0118 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -35,7 +35,7 @@ const getFileImportsElements = (fileContent) => { * @returns */ const getImportStatements = (fileContent) => - fileContent.match(regexp.IMPORT_STATEMENT); + fileContent.match(regexp.GET_ALL_IMPORT_STATEMENT); /** * Get Import's path @@ -47,7 +47,7 @@ const getImportStatements = (fileContent) => */ const getImportsPath = (fileContent) => { let result = []; - const importStatements = fileContent.match(regexp.IMPORT_STATEMENT_2); + const importStatements = fileContent.match(regexp.GET_ALL_IMPORT_STATEMENT); if (importStatements) { importStatements.forEach((value) => diff --git a/lib/parse.js b/lib/parse.js index 84bf73b..e80872c 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1,6 +1,7 @@ const fs = require("fs"); const sucrase = require("sucrase"); const { read_bos_config } = require("./config"); +const { EXPORT_AND_EXPORT_DEFAULT } = require("./regexp"); const sucraseOptions = { transforms: ["typescript", "jsx"], @@ -9,7 +10,21 @@ const sucraseOptions = { disableESTransforms: true, }; -// process each file +// process file content +function process_file_content(fileContent, shouldTranspileTypescript) { + if (shouldTranspileTypescript) { + fileContent = transpileTypescript(fileContent); + } + + // Remove imports and exports + fileContent = removeImports(fileContent); + fileContent = removeExports(fileContent); + + // return file content + return fileContent; +} + +// process each file (using its path) // function process_file(filePath, { aliases, account }) { function process_file(filePath) { let fileContent = fs.readFileSync(filePath, "utf8"); @@ -41,11 +56,7 @@ const ignoreFiles = (c) => /\/\*__@ignore__\*\//.test(c); // no stringify json files // const noStringifyJsonFiles = (c) => /\/\*__@noStringify__\*\//.test(c); -const removeExports = (c) => - c - .replaceAll("export const", "const") - .replaceAll("export default function", "function") - .replaceAll(/^(export)(?:.*?(default))*.*$/gm, ""); // TODO: Test export default with multiple lines +const removeExports = (c) => c.replaceAll(EXPORT_AND_EXPORT_DEFAULT, ""); const removeImports = (c) => { // Remove line breaks @@ -93,7 +104,7 @@ const parseOptions = (c) => { return c; }; -const mimify = (c) => +const minify = (c) => c .replace(/\r?\n|\r/gm, "") .replace(/\s+/gm, " ") @@ -120,6 +131,7 @@ const injectHTML = (html, injections) => { }; module.exports = { + process_file_content, process_file, ignoreFiles, removeComments, @@ -127,7 +139,7 @@ module.exports = { removeExports, removeImports, removeBlankLines, - mimify, + minify, applyEnvironment, parseOptions, }; diff --git a/lib/regexp.js b/lib/regexp.js index 79bcdb0..60ca4b7 100644 --- a/lib/regexp.js +++ b/lib/regexp.js @@ -9,20 +9,64 @@ const GET_ALL_BETWEEN_IMPORT_AND_FROM = /(?<=import)(.*?)(?=from)/gm; const SPACES = /\s/g; // # LINE BREAKS const LINE_BREAKS = /\r?\n|\r/g; -// # IMPORT STATEMENT. ex: import { AppBackground, AppContainer } from "./styles"; -const IMPORT_STATEMENT = /^(import)(?:.*?(as))?(?:.*?(as))?(?:.*?(from))*.*$/gm; -const IMPORT_STATEMENT_2 = - /^[ \t]*(import)\s+(?:\{[^}]*\}|\w+)\s+(from\s+)?["']([^"']+)["'];?$/gm; // USAR ESSE! +// # Pega todos os import statements, inclusive aqueles com quebra de linha +const GET_ALL_IMPORT_STATEMENT = + /(import\s+.*?\s+from\s+['"].*?['"])|(import\s+({[\s\S]+?}|[^{}]+)\s+from\s+['"].*?['"])/g; // # BETWEEN quotation marks const BETWEEN_QUOTES = /(?<=")(.*?)(?=")/gm; +// ENTRE export const e = +const BETWEEN_EXPORT_CONST_AND_EQUAL = /(?<=export const)(.*?)(?==)/gm; + +// ENTRE export let e = +const BETWEEN_EXPORT_LET_AND_EQUAL = /(?<=export let)(.*?)(?==)/gm; + +// ENTRE export var e = +const BETWEEN_EXPORT_VAR_AND_EQUAL = /(?<=export var)(.*?)(?==)/gm; + +// ENTRE export function e ( +const BETWEEN_EXPORT_FUNCTION_AND_OPEN_PARENTHESE = + /(?<=export function)(.*?)(?=\()/gm; + +// ENTRE export default function e ( +const BETWEEN_EXPORT_DEFAULT_FUNCTION_AND_OPEN_PARENTHESE = + /(?<=export default function)(.*?)(?=\()/gm; + +// VALOR DEPOIS DE export default +const AFTER_EXPORT_DEFAULT = /(?<=export default).*/gm; + +const EXPORT_AND_EXPORT_DEFAULT = /export\s+default|export(?!\s+default)/g; + module.exports = { SPECIAL_CHARACTERS, SPECIAL_CHARACTERS_AND_SPACES, GET_ALL_BETWEEN_IMPORT_AND_FROM, SPACES, LINE_BREAKS, - IMPORT_STATEMENT, - IMPORT_STATEMENT_2, + GET_ALL_IMPORT_STATEMENT, BETWEEN_QUOTES, + BETWEEN_EXPORT_CONST_AND_EQUAL, + BETWEEN_EXPORT_LET_AND_EQUAL, + BETWEEN_EXPORT_VAR_AND_EQUAL, + BETWEEN_EXPORT_FUNCTION_AND_OPEN_PARENTHESE, + BETWEEN_EXPORT_DEFAULT_FUNCTION_AND_OPEN_PARENTHESE, + AFTER_EXPORT_DEFAULT, + EXPORT_AND_EXPORT_DEFAULT, }; + +// ENTRE export const e = +// util para +// export const Bla = .... +// ENCONTRA Bla +// (?<=export const)(.*?)(?=\=) + +// ENTRE export default function e ( +// util para +// export default function Bla(){....} +// ENCONTRA Bla +// (?<=export default function)(.*?)(?=\() + +// export default Bla +// remover todos os "export default function" +// PROCURAR POR: "export default" +// (?<=export default function)(.*?)(?=\n|\r) diff --git a/lib/utils.js b/lib/utils.js index 21d386f..d60f8a7 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -141,9 +141,39 @@ const log = { }, }; +/** + * Generates random hexadecimal value + * @param {number} size + * @returns + */ +const get_randon_hexadecimal = function (size) { + let maxlen = 8; + let min = Math.pow(16, Math.min(size, maxlen) - 1); + let max = Math.pow(16, Math.min(size, maxlen)) - 1; + let n = Math.floor(Math.random() * (max - min + 1)) + min; + let r = n.toString(16); + while (r.length < size) { + r = r + get_randon_hexadecimal(size - maxlen); + } + return r; +}; + +const get_random_character = () => { + const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + const randomIndex = Math.floor(Math.random() * characters.length); + return characters.charAt(randomIndex); +}; + +const capitalize_first_letter = (word) => { + return word.charAt(0).toUpperCase() + word.slice(1); +}; + module.exports = { create_dist, for_rfile, for_folder, log, + get_randon_hexadecimal, + get_random_character, + capitalize_first_letter, }; diff --git a/package.json b/package.json index 7abe461..30a2d9e 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "alem", "description": "Create web3 applications for NEAR BOS with a focus on performance and friendly development.", - "version": "0.0.1-alpha.20", + "version": "0.0.1-alpha.21", "main": "main.js", "types": "index.d.ts", "author": "Wenderson Pires - wendersonpires.near", diff --git a/roadmap.md b/roadmap.md index 05b4cfa..5ee6b45 100644 --- a/roadmap.md +++ b/roadmap.md @@ -4,4 +4,4 @@ - Add parameter `parameterName` for `Routes` component. This is going to allow changing the default route param name ("path") that's used to control and watch all routes. - ✔ - Implement feature to the compiler that changes the consts/lets/vars names to avoid conflicts. - Add support to tsconfig.json `baseUrl` and `paths`. -- Support to using the same const names in different files. +- Support to using the same const names in different files. - ✔