diff --git a/index-gerar.ts b/index-gerar.ts index 4ce6800..8f19112 100644 --- a/index-gerar.ts +++ b/index-gerar.ts @@ -3,7 +3,9 @@ import prompts from 'prompts'; import { Classe } from '@designliquido/delegua/fontes/declaracoes'; import { pluralizar } from '@designliquido/flexoes'; -import { criarDiretorioSeNaoExiste, criarNovaVisao, criarNovoControlador, importarModelos, obterTodosModelos } from './interface-linha-comando/gerar'; +import { criarDiretorioSeNaoExiste, importarModelos, obterTodosModelos } from './interface-linha-comando/gerar'; +import { GeradorVisoes } from './interface-linha-comando/gerar/gerador-visoes'; +import { GeradorRotas } from './interface-linha-comando/gerar/gerador-rotas'; const pontoDeEntradaGerar = async (argumentos: string[]) => { // argumentos[0] normalmente é o nome do executável, seja Node, Bun, etc. @@ -25,29 +27,32 @@ const pontoDeEntradaGerar = async (argumentos: string[]) => { } const declaracoes = importarModelos(nomeModelo); - criarDiretorioSeNaoExiste('controladores'); + criarDiretorioSeNaoExiste('rotas'); + + const geradorVisoes = new GeradorVisoes(); + const geradorRotas = new GeradorRotas(); // Aqui apenas aceitamos declarações de classes. Pode ser mais de uma. for (const declaracao of declaracoes.filter((d) => d instanceof Classe)) { - const declaracaoClasse = declaracao; - const nomeBaseModelo = declaracaoClasse.simbolo.lexema.toLocaleLowerCase('pt'); - const nomeControladorPlural = pluralizar(nomeBaseModelo).toLocaleLowerCase('pt'); + const declaracaoModelo = declaracao; + const nomeBaseModelo = declaracaoModelo.simbolo.lexema.toLocaleLowerCase('pt'); + const nomeModeloPlural = pluralizar(nomeBaseModelo).toLocaleLowerCase('pt'); - const caminhoControlador = criarNovoControlador(nomeControladorPlural); + const caminhoControlador = geradorRotas.criarNovasRotas(declaracaoModelo); console.info(`Controlador ${caminhoControlador}`); // Visões - criarDiretorioSeNaoExiste('visoes', nomeControladorPlural); + criarDiretorioSeNaoExiste('visoes', nomeModeloPlural); - const visaoSelecionarTudo = criarNovaVisao(nomeControladorPlural, 'selecionarTudo'); + const visaoSelecionarTudo = geradorVisoes.criarNovaVisao(nomeModeloPlural, declaracaoModelo, 'selecionarTudo'); console.info(`Visão ${visaoSelecionarTudo}`); - const visaoSelecionarUm = criarNovaVisao(nomeControladorPlural, 'selecionarUm'); + const visaoSelecionarUm = geradorVisoes.criarNovaVisao(nomeModeloPlural, declaracaoModelo, 'selecionarUm'); console.info(`Visão ${visaoSelecionarUm}`); - const visaoAdicionar = criarNovaVisao(nomeControladorPlural, 'adicionar'); + const visaoAdicionar = geradorVisoes.criarNovaVisao(nomeModeloPlural, declaracaoModelo, 'adicionar'); console.info(`Visão ${visaoAdicionar}`); - const visaoAtualizar = criarNovaVisao(nomeControladorPlural, 'atualizar'); + const visaoAtualizar = geradorVisoes.criarNovaVisao(nomeModeloPlural, declaracaoModelo, 'atualizar'); console.info(`Visão ${visaoAtualizar}`); - const visaoExcluir = criarNovaVisao(nomeControladorPlural, 'excluir'); + const visaoExcluir = geradorVisoes.criarNovaVisao(nomeModeloPlural, declaracaoModelo, 'excluir'); console.info(`Visão ${visaoExcluir}`); } }; diff --git a/interface-linha-comando/gerar/gerador-rotas.ts b/interface-linha-comando/gerar/gerador-rotas.ts new file mode 100644 index 0000000..650aa9e --- /dev/null +++ b/interface-linha-comando/gerar/gerador-rotas.ts @@ -0,0 +1,66 @@ +import * as sistemaArquivos from 'fs'; +import * as caminho from 'path'; + +import { Classe } from '@designliquido/delegua/fontes/declaracoes'; +import { pluralizar } from '@designliquido/flexoes'; +import { criarDiretorioSeNaoExiste } from '.'; + +export class GeradorRotas { + indentacao: number; + + constructor() { + this.indentacao = 4; + } + + /** + * Cria arquivos `.delegua` no diretório 'rotas/' com cinco rotas: + * - Arquivo `inicial.delegua` + * - rotaGet (para selecionar vários registros na base de dados) + * - rotaPost (para gravar 1 registro na base de dados) + * - Arquivo `[id].delegua` + * - rotaGet (para selecionar 1 registro por id na base de dados) + * - rotaPut (para alterar 1 registro na base de dados) + * - rotaDelete (para excluir 1 registro na base de dados) + * @param {Classe} declaracaoModelo O nome do diretório das rotas: o nome do modelo no plural. + * @returns {string} O caminho completo onde os arquivos de rotas foram criados. + */ + criarNovasRotas(declaracaoModelo: Classe): string { + const nomeBaseModelo = declaracaoModelo.simbolo.lexema.toLocaleLowerCase('pt'); + const nomeModeloPlural = pluralizar(nomeBaseModelo).toLocaleLowerCase('pt'); + const diretorioRotas = caminho.join(process.cwd(), 'rotas', nomeModeloPlural); + + const conteudoSelecionarTudo = this.criarRotaSelecionarTudo(declaracaoModelo); + const conteudoAdicionar = `liquido.rotaPost(funcao(requisicao, resposta) {\n resposta.lmht({ "titulo": "Liquido" })\n})\n\n`; + const conteudoAtualizar = `liquido.rotaPut(funcao(requisicao, resposta) {\n resposta.lmht({ "titulo": "Liquido" })\n})\n\n`; + const conteudoExcluir = `liquido.rotaDelete(funcao(requisicao, resposta) {\n resposta.lmht({ "titulo": "Liquido" })\n})\n\n`; + const conteudoControlador = `${conteudoSelecionarTudo}${conteudoAdicionar}${conteudoAtualizar}${conteudoExcluir}`; + + criarDiretorioSeNaoExiste('rotas', nomeModeloPlural); + const caminhoRotas = caminho.join(diretorioRotas, 'inicial.delegua'); + sistemaArquivos.writeFileSync( + caminhoRotas, + conteudoControlador + ); + + return caminhoRotas; + } + + private criarRotaSelecionarTudo(declaracaoModelo: Classe) { + // Isso aqui não vai ficar assim. + // É preciso montar as partes de dados antes. + const dadosTestes = []; + for (const propriedade of declaracaoModelo.propriedades) { + dadosTestes.push(`"${propriedade.nome.lexema}": "Teste"`); + } + + return `liquido.rotaGet(funcao(requisicao, resposta) {\n` + + `${" ".repeat(this.indentacao)}resposta.lmht({\n` + + `${" ".repeat(this.indentacao * 2)}"linhas": [\n` + + `${" ".repeat(this.indentacao * 3)}{${dadosTestes.reduce( + (acumulador, elemento) => acumulador + ', ' + elemento + )}}\n` + + `${" ".repeat(this.indentacao * 2)}]\n` + + `${" ".repeat(this.indentacao)}})\n` + + `})\n\n`; + } +} \ No newline at end of file diff --git a/interface-linha-comando/gerar/gerador-visoes.ts b/interface-linha-comando/gerar/gerador-visoes.ts new file mode 100644 index 0000000..563c1bb --- /dev/null +++ b/interface-linha-comando/gerar/gerador-visoes.ts @@ -0,0 +1,97 @@ +import * as sistemaArquivos from 'fs'; +import * as caminho from 'path'; + +import { Classe } from '@designliquido/delegua/fontes/declaracoes'; + +import { TipoVisao } from './tipo-visao'; + +export class GeradorVisoes { + indentacao: number; + + constructor() { + this.indentacao = 4; + } + + /** + * Cria uma nova visão, de acordo com o nome do controlador e o tipo de visão desejado. + * @param {string} nomeControlador O nome do controlador. + * @param {TipoVisao} tipoVisao O tipo da visão. + * @returns O caminho completo onde a visão foi criada. + */ + criarNovaVisao(nomeControlador: string, declaracaoModelo: Classe, tipoVisao: TipoVisao) { + let caminhoVisao: string; + let corpo: string; + const diretorioVisoes = caminho.join(process.cwd(), 'visoes', nomeControlador); + const cabecalhoComum = " ".repeat(this.indentacao) + 'Teste\n'; + + switch (tipoVisao) { + case 'selecionarTudo': + caminhoVisao = caminho.join(diretorioVisoes, 'inicial.lmht'); + corpo = `${" ".repeat(this.indentacao)}\n${this.corpoInicial(declaracaoModelo)}\n${" ".repeat(this.indentacao)}\n`; + break; + case 'selecionarUm': + caminhoVisao = caminho.join(diretorioVisoes, 'detalhes.lmht'); + corpo = ' Teste\n'; + break; + case 'adicionar': + caminhoVisao = caminho.join(diretorioVisoes, 'adicionar.lmht'); + corpo = ' Teste\n'; + break; + case 'atualizar': + caminhoVisao = caminho.join(diretorioVisoes, 'atualizar.lmht'); + corpo = ' Teste\n'; + break; + case 'excluir': + caminhoVisao = caminho.join(diretorioVisoes, 'excluir.lmht'); + corpo = ' Teste\n'; + break; + } + + const conteudoVisao: string = `\n${cabecalhoComum}${corpo}`; + + sistemaArquivos.writeFileSync(caminhoVisao, conteudoVisao); + + return caminhoVisao; + } + + /** + * Função que gera o corpo de `inicial.lmht` de cada visão gerada por linha de comando. + * @param {Classe} declaracaoModelo A declaração do modelo de dados, com suas propriedades e definições. + * @returns {string} Um trecho em LMHT com a estrutura do corpo da página. + */ + private corpoInicial(declaracaoModelo: Classe): string { + // Colunas de cabeçalho + const colunasCabecaTabela: string[] = []; + for (const propriedade of declaracaoModelo.propriedades) { + colunasCabecaTabela.push(" ".repeat(this.indentacao * 5) + `${propriedade.nome.lexema}`); + } + + const linhaCabecaTabela = " ".repeat(this.indentacao * 4) + '\n' + + colunasCabecaTabela.reduce( + (acumulador, elemento) => acumulador + '\n' + elemento + ) + + '\n' + " ".repeat(this.indentacao * 4) + ''; + + const cabecaTabela = `${" ".repeat(this.indentacao * 3)}\n${linhaCabecaTabela}\n${" ".repeat(this.indentacao * 3)}`; + + // Colunas do corpo da tabela + const colunasCorpoTabela: string[] = []; + for (const propriedade of declaracaoModelo.propriedades) { + colunasCorpoTabela.push(" ".repeat(this.indentacao * 5) + `{{${propriedade.nome.lexema}}}`); + } + + const linhaCorpoTabela = " ".repeat(this.indentacao * 4) + '\n' + + colunasCorpoTabela.reduce( + (acumulador, elemento) => acumulador + '\n' + elemento + ) + + '\n' + " ".repeat(this.indentacao * 4) + ''; + + const corpoTabela = `${" ".repeat(this.indentacao * 3)}\n` + + `${" ".repeat(this.indentacao * 3)}{{#cada linhas}}\n` + + `${linhaCorpoTabela}\n` + + `${" ".repeat(this.indentacao * 3)}{{/cada}}\n` + + `${" ".repeat(this.indentacao * 3)}`; + + return `${" ".repeat(this.indentacao * 2)}\n${cabecaTabela}\n${corpoTabela}\n${" ".repeat(this.indentacao * 2)}`; + } +} diff --git a/interface-linha-comando/gerar/index.ts b/interface-linha-comando/gerar/index.ts index ed94314..29865bf 100644 --- a/interface-linha-comando/gerar/index.ts +++ b/interface-linha-comando/gerar/index.ts @@ -6,8 +6,6 @@ import { AvaliadorSintatico } from '@designliquido/delegua/fontes/avaliador-sint import { Importador } from '@designliquido/delegua-node/fontes/importador'; import { Declaracao } from '@designliquido/delegua/fontes/declaracoes'; -import { TipoVisao } from './tipo-visao'; - /** * Obtém todos os modelos do diretório 'modelos' do projeto. * @returns {{ title: string, value: string }[]} Um vetor com todos os arquivos de modelos encontrados. @@ -53,67 +51,3 @@ export function criarDiretorioSeNaoExiste(...partesDiretorio: string[]) { sistemaArquivos.mkdirSync(caminhoDiretorio); } } - -/** - * Cria um arquivo `.delegua` no diretório 'controladores' com quatro rotas: - * - rotaGet (para selecionar 1 ou vários registros na base de dados) - * - rotaPost (para gravar 1 registro na base de dados) - * - rotaPut (para alterar 1 registro na base de dados) - * - rotaDelete (para excluir 1 registro na base de dados) - * @param {string} nome O nome do controlador. - * @returns {string} O caminho completo onde o controlador foi criado. - */ -export function criarNovoControlador(nome: string): string { - const diretorioControladores = caminho.join(process.cwd(), 'controladores'); - - const conteudoControlador = `liquido.rotaGet(funcao(requisicao, resposta) {\n resposta.lmht({ "titulo": "Liquido" })\n})`; - const caminhoControlador = caminho.join(diretorioControladores, nome + '.delegua'); - sistemaArquivos.writeFileSync( - caminhoControlador, - conteudoControlador - ); - - return caminhoControlador; -} - -/** - * Cria uma nova visão, de acordo com o nome do controlador e o tipo de visão desejado. - * @param {string} nomeControlador O nome do controlador. - * @param {TipoVisao} tipoVisao O tipo da visão. - * @returns O caminho completo onde a visão foi criada. - */ -export function criarNovaVisao(nomeControlador: string, tipoVisao: TipoVisao) { - let caminhoVisao: string; - let conteudoVisao: string; - const diretorioVisoes = caminho.join(process.cwd(), 'visoes', nomeControlador); - - switch (tipoVisao) { - case 'selecionarTudo': - caminhoVisao = caminho.join(diretorioVisoes, 'inicial.lmht'); - conteudoVisao = `\n Teste\nTeste\n`; - break; - case 'selecionarUm': - caminhoVisao = caminho.join(diretorioVisoes, 'detalhes.lmht'); - conteudoVisao = `\n Teste\nTeste\n`; - break; - case 'adicionar': - caminhoVisao = caminho.join(diretorioVisoes, 'adicionar.lmht'); - conteudoVisao = `\n Teste\nTeste\n`; - break; - case 'atualizar': - caminhoVisao = caminho.join(diretorioVisoes, 'atualizar.lmht'); - conteudoVisao = `\n Teste\nTeste\n`; - break; - case 'excluir': - caminhoVisao = caminho.join(diretorioVisoes, 'excluir.lmht'); - conteudoVisao = `\n Teste\nTeste\n`; - break; - } - - sistemaArquivos.writeFileSync( - caminhoVisao, - conteudoVisao - ); - - return caminhoVisao; -} \ No newline at end of file diff --git a/interface-linha-comando/index.ts b/interface-linha-comando/index.ts index d2ffbcb..7083a95 100644 --- a/interface-linha-comando/index.ts +++ b/interface-linha-comando/index.ts @@ -1 +1,2 @@ +export * from './gerar'; export * from './novo'; \ No newline at end of file diff --git a/liquido.ts b/liquido.ts index 73b5944..085f2ea 100644 --- a/liquido.ts +++ b/liquido.ts @@ -356,20 +356,20 @@ export class Liquido implements LiquidoInterface { const { valor } = JSON.parse(retornoInterpretador.resultado.pop()); let statusHttp: number = 200; - if (valor.campos.statusHttp) { - statusHttp = valor.campos.statusHttp; + if (valor.propriedades.statusHttp) { + statusHttp = valor.propriedades.statusHttp; } try { - if (valor.campos.lmht) { - const resultadoFormatacaoLmht = await this.formatadorLmht.formatar(caminhoRota, valor.campos.valores); + if (valor.propriedades.lmht) { + const resultadoFormatacaoLmht = await this.formatadorLmht.formatar(caminhoRota, valor.propriedades.valores); return { corpoRetorno: resultadoFormatacaoLmht, statusHttp: statusHttp }; - } else if (valor.campos.mensagem) { + } else if (valor.propriedades.mensagem) { return { - corpoRetorno: valor.campos.mensagem, + corpoRetorno: valor.propriedades.mensagem, statusHttp: statusHttp }; } diff --git a/package.json b/package.json index f509eb6..ca86a50 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ }, "dependencies": { "@designliquido/delegua-node": "^0.29.1", - "@designliquido/flexoes": "^0.0.1", + "@designliquido/flexoes": "^0.1.0", "@designliquido/foles": "^0.6.1", "@designliquido/lincones-sqlite": "^0.0.2", "@designliquido/lmht-js": "^0.4.4", diff --git a/yarn.lock b/yarn.lock index cb54b8b..abd8600 100644 --- a/yarn.lock +++ b/yarn.lock @@ -325,10 +325,10 @@ esprima "^4.0.1" lodash.clonedeep "^4.5.0" -"@designliquido/flexoes@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@designliquido/flexoes/-/flexoes-0.0.1.tgz#7e98904dbb4aec2cabc1c0879fe57b2015ef4604" - integrity sha512-zbl8Vofb4Dh97SiMyvjwLMfFaBRnUPuL9mJkj7REHWwcWxAxKMrnjLfpBtBfGg46Rq6R1XRFcV3IWWp9y4w4IA== +"@designliquido/flexoes@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@designliquido/flexoes/-/flexoes-0.1.0.tgz#59bc4c872f49f51ceca9fa4b8554697b82065000" + integrity sha512-5CpBpoeU4UgfwAV08pxJrJt5qljPqNQQdEU0DXkOsYcmDi0JcIBRjS/308stDuhsxuYH0AyeKn2wge+McynnoA== "@designliquido/foles@^0.6.1": version "0.6.1"