<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: João Neto</title>
    <description>The latest articles on Forem by João Neto (@joao_neto).</description>
    <link>https://forem.com/joao_neto</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F468635%2Fdb215303-5a7e-4181-b684-011977939af5.jpeg</url>
      <title>Forem: João Neto</title>
      <link>https://forem.com/joao_neto</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/joao_neto"/>
    <language>en</language>
    <item>
      <title>Simplificando verificações de flags binárias</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Wed, 01 Oct 2025 20:02:41 +0000</pubDate>
      <link>https://forem.com/joao_neto/simplificando-verificacoes-de-flags-binarias-31np</link>
      <guid>https://forem.com/joao_neto/simplificando-verificacoes-de-flags-binarias-31np</guid>
      <description>&lt;p&gt;Se você já lidou com &lt;strong&gt;flags binárias&lt;/strong&gt;, sabe como é fácil perder o fio da meada quando o código começa a ter muitos &lt;code&gt;&amp;amp;&lt;/code&gt; e &lt;code&gt;|&lt;/code&gt;. A lógica funciona, mas a leitura rápida já se torna um desafio.&lt;/p&gt;

&lt;p&gt;A função &lt;code&gt;compareBitwise()&lt;/code&gt; proposta aqui, surge justamente para esse ponto: &lt;strong&gt;ela não elimina a complexidade, mas organiza de forma que seja mais fácil entender o que está sendo verificado&lt;/strong&gt;. Adicionando um nível de abstração para ganhar clareza e legibilidade.&lt;/p&gt;




&lt;h2&gt;
  
  
  A função compareBitwise()
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;compareBitwise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;flagsBuild&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;compareBitwise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;flagsBuild&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;flagsBuild&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;flagsBuild&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flags&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;flagsBuild&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cada &lt;code&gt;match&lt;/code&gt; adiciona uma flag ao "contexto" interno, sem precisar mexer diretamente nos bits. Depois, &lt;code&gt;all()&lt;/code&gt; ou &lt;code&gt;any()&lt;/code&gt; retornam se todos ou alguma das flags batem.&lt;/p&gt;




&lt;h2&gt;
  
  
  Exemplo de uso
&lt;/h2&gt;

&lt;p&gt;Vamos criar uma constante de permissões:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;READ&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mb"&gt;0b0001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;WRITE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mb"&gt;0b0010&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;DELETE&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mb"&gt;0b0100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;ADMIN&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mb"&gt;0b1000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userPermissions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;READ&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DELETE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ADMIN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Verificar se o usuário pode editar e deletar&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canEditAndDelete&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;compareBitwise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userPermissions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WRITE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DELETE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;

&lt;span class="c1"&gt;// Verificar se o usuário tem pelo menos uma permissão crítica&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hasCriticalPermission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;compareBitwise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userPermissions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DELETE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ADMIN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare com a forma tradicional usando apenas operadores bitwise:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;canEditAndDeleteTraditional&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userPermissions&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WRITE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DELETE&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WRITE&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DELETE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com &lt;code&gt;compareBitwise()&lt;/code&gt;, a intenção do código fica explícita sem precisar interpretar operadores binários mentalmente.&lt;/p&gt;




&lt;h2&gt;
  
  
  Sugestões de melhoria
&lt;/h2&gt;

&lt;p&gt;Hoje, o &lt;code&gt;match&lt;/code&gt; só aceita &lt;strong&gt;uma flag por vez&lt;/strong&gt;. Um desafio interessante é pensar em como permitir múltiplas flags de uma só vez, seja com múltiplos argumentos ou um array:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Ideia de sintaxe desejada&lt;/span&gt;
&lt;span class="nf"&gt;compareBitwise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userPermissions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WRITE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DELETE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// ou&lt;/span&gt;
&lt;span class="nf"&gt;compareBitwise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userPermissions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;WRITE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PERMISSIONS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DELETE&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;A função &lt;code&gt;compareBitwise()&lt;/code&gt; não substitui o operador bitwise, nem pretende ser a solução para tudo.&lt;br&gt;
Mas, quando o código precisa deixar explícito &lt;strong&gt;quem pode fazer o quê&lt;/strong&gt;, ele transforma uma expressão difícil de ler em algo que praticamente "fala por si só".&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>node</category>
    </item>
    <item>
      <title>SVGs para ReactComponent com Plugin SWC - Minha Jornada com Rust e Um Pouco de Teimosia</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Thu, 03 Jul 2025 22:38:00 +0000</pubDate>
      <link>https://forem.com/joao_neto/svgs-para-reactcomponent-com-plugin-swc-minha-jornada-com-rust-e-um-pouco-de-teimosia-212b</link>
      <guid>https://forem.com/joao_neto/svgs-para-reactcomponent-com-plugin-swc-minha-jornada-com-rust-e-um-pouco-de-teimosia-212b</guid>
      <description>&lt;p&gt;Há umas semanas me peguei pensando em como poderia &lt;strong&gt;otimizar um fluxo de build de SVGs&lt;/strong&gt; para React, sem depender de soluções gigantes ou plugins engessados. Foi aí que nasceu a ideia de escrever meu próprio plugin para o &lt;a href="https://swc.rs" rel="noopener noreferrer"&gt;SWC&lt;/a&gt;, um compilador escrito em Rust que, convenhamos, intimida bastante quem só encostou de leve na linguagem.&lt;/p&gt;

&lt;p&gt;Minha meta era simples no papel:&lt;br&gt;
&lt;strong&gt;Pegar um svg, passar pelo swc e gerar um componente React limpo, válido.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A realidade, claro, foi um pouco mais tortuosa, por que eu queria fazer isso sem depender do svgr e outras libs que já fazem isso.&lt;/p&gt;




&lt;h2&gt;
  
  
  Entendendo o monstro (ou tentando)
&lt;/h2&gt;

&lt;p&gt;Primeiro veio o Rust. Embora eu já estivesse brincando com a linguagem, foi a primeira vez que precisei realmente encarar &lt;strong&gt;o ecossistema do &lt;code&gt;swc_core&lt;/code&gt;&lt;/strong&gt;, entender o mínimo sobre a árvore de sintaxe (AST), a forma como &lt;code&gt;Visit&lt;/code&gt; e &lt;code&gt;VisitMut&lt;/code&gt; funcionam e como a arquitetura modular (e brutal) do SWC exige que você entenda &lt;em&gt;exatamente&lt;/em&gt; onde quer mexer.&lt;/p&gt;

&lt;p&gt;Não sou especialista em compiladores, nem pretendo ser, mas foi gratificante ver como as peças se encaixam, mesmo que de forma amadora. Tive que desenhar árvore por árvore, pra criar o componente react com base no svg e debugar no contexto do WASM que não tem ~"console.log"~ de maneira tão fácil, e principalmente aceitar que erros de tipo em Rust não perdoam ninguém.&lt;/p&gt;




&lt;h2&gt;
  
  
  Modularidade que empodera (e atrapalha)
&lt;/h2&gt;

&lt;p&gt;O legal (e assustador) de criar um plugin pro SWC é perceber que tudo é feito pra ser plugável, performático e modular. Isso é libertador, mas também não extremamente complicado: se você não entende bem o que está mexendo, vai quebrar seu AST todo e nada vai compilar.&lt;/p&gt;

&lt;p&gt;Depois de alguns dias errando e recompilando e olhado os plugin prontos do SWC, consegui fazer um &lt;code&gt;VisitMut&lt;/code&gt; que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Troca &lt;code&gt;class&lt;/code&gt; por &lt;code&gt;className&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Converte &lt;code&gt;style="..."&lt;/code&gt; em objeto React.&lt;/li&gt;
&lt;li&gt;Transforma atributos com hífen (&lt;code&gt;stroke-width&lt;/code&gt;) em &lt;code&gt;strokeWidth&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Empacota tudo em um componente export default, bonitinho.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  CLI, build e WASM
&lt;/h2&gt;

&lt;p&gt;A parte boa: depois de pronto, compilar tudo pra WASM e rodar com o &lt;code&gt;swc cli&lt;/code&gt; é praticamente mágico. Ter &lt;strong&gt;Rust + SWC + WASM&lt;/strong&gt; rodando em &lt;code&gt;npm run build&lt;/code&gt; te dá a sensação de ter controle sobre o compilador inteiro.&lt;/p&gt;

&lt;p&gt;Hoje, com esse plugin, eu já consigo montar uma &lt;strong&gt;biblioteca de ícones SVG&lt;/strong&gt; que viram componentes React no build. É brutalmente rápido e sem dependências extras.&lt;/p&gt;




&lt;h2&gt;
  
  
  Limites e próximos passos
&lt;/h2&gt;

&lt;p&gt;Por enquanto, é um experimento — &lt;strong&gt;funciona bem no React para web&lt;/strong&gt;, mas ainda não daria pra usar direto no React Native. Quem sabe numa &lt;code&gt;v0.2&lt;/code&gt; eu consiga estender isso pra gerar algo compatível com &lt;code&gt;react-native-svg&lt;/code&gt; ou outra lib parecida.&lt;/p&gt;




&lt;h2&gt;
  
  
  Para quem quiser explorar
&lt;/h2&gt;

&lt;p&gt;O repo é: &lt;a href="https://github.com/joaoneto/swc-plugin-svg-component" rel="noopener noreferrer"&gt;https://github.com/joaoneto/swc-plugin-svg-component&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se quiser ver como funciona, clona, compila, brinca com &lt;code&gt;cargo build&lt;/code&gt; e &lt;code&gt;swc cli&lt;/code&gt;. Se surgir bug, abre issue. Se quiser mexer junto, manda PR. Se achar tudo isso insano demais pra rodar em produção, concordo. É um plugin &lt;strong&gt;experimental&lt;/strong&gt; no sentido mais radical possível da palavra.&lt;/p&gt;

&lt;p&gt;No fim das contas, foi uma experiência que me aproximou mais do Rust, do SWC e do Next.js com Turbopack.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>nextjs</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>SVGs para ReactComponent com Plugin SWC - Minha Jornada com Rust e Um Pouco de Teimosia</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Thu, 03 Jul 2025 22:38:00 +0000</pubDate>
      <link>https://forem.com/joao_neto/svgs-para-reactcomponent-com-plugin-swc-minha-jornada-com-rust-e-um-pouco-de-teimosia-3ai5</link>
      <guid>https://forem.com/joao_neto/svgs-para-reactcomponent-com-plugin-swc-minha-jornada-com-rust-e-um-pouco-de-teimosia-3ai5</guid>
      <description>&lt;p&gt;Há umas semanas me peguei pensando em como poderia &lt;strong&gt;otimizar um fluxo de build de SVGs&lt;/strong&gt; para React, sem depender de soluções gigantes ou plugins engessados. Foi aí que nasceu a ideia de escrever meu próprio plugin para o &lt;a href="https://swc.rs" rel="noopener noreferrer"&gt;SWC&lt;/a&gt;, um compilador escrito em Rust que, convenhamos, intimida bastante quem só encostou de leve na linguagem.&lt;/p&gt;

&lt;p&gt;Minha meta era simples no papel:&lt;br&gt;
&lt;strong&gt;Pegar um svg, passar pelo swc e gerar um componente React limpo, válido.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A realidade, claro, foi um pouco mais tortuosa, por que eu queria fazer isso sem depender do svgr e outras libs que já fazem isso.&lt;/p&gt;




&lt;h2&gt;
  
  
  Entendendo o monstro (ou tentando)
&lt;/h2&gt;

&lt;p&gt;Primeiro veio o Rust. Embora eu já estivesse brincando com a linguagem, foi a primeira vez que precisei realmente encarar &lt;strong&gt;o ecossistema do &lt;code&gt;swc_core&lt;/code&gt;&lt;/strong&gt;, entender o mínimo sobre a árvore de sintaxe (AST), a forma como &lt;code&gt;Visit&lt;/code&gt; e &lt;code&gt;VisitMut&lt;/code&gt; funcionam e como a arquitetura modular (e brutal) do SWC exige que você entenda &lt;em&gt;exatamente&lt;/em&gt; onde quer mexer.&lt;/p&gt;

&lt;p&gt;Não sou especialista em compiladores, nem pretendo ser, mas foi gratificante ver como as peças se encaixam, mesmo que de forma amadora. Tive que desenhar árvore por árvore, pra criar o componente react com base no svg e debugar no contexto do WASM que não tem ~"console.log"~ de maneira tão fácil, e principalmente aceitar que erros de tipo em Rust não perdoam ninguém.&lt;/p&gt;




&lt;h2&gt;
  
  
  Modularidade que empodera (e atrapalha)
&lt;/h2&gt;

&lt;p&gt;O legal (e assustador) de criar um plugin pro SWC é perceber que tudo é feito pra ser plugável, performático e modular. Isso é libertador, mas também não extremamente complicado: se você não entende bem o que está mexendo, vai quebrar seu AST todo e nada vai compilar.&lt;/p&gt;

&lt;p&gt;Depois de alguns dias errando e recompilando e olhado os plugin prontos do SWC, consegui fazer um &lt;code&gt;VisitMut&lt;/code&gt; que:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Troca &lt;code&gt;class&lt;/code&gt; por &lt;code&gt;className&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Converte &lt;code&gt;style="..."&lt;/code&gt; em objeto React.&lt;/li&gt;
&lt;li&gt;Transforma atributos com hífen (&lt;code&gt;stroke-width&lt;/code&gt;) em &lt;code&gt;strokeWidth&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Empacota tudo em um componente export default, bonitinho.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  CLI, build e WASM
&lt;/h2&gt;

&lt;p&gt;A parte boa: depois de pronto, compilar tudo pra WASM e rodar com o &lt;code&gt;swc cli&lt;/code&gt; é praticamente mágico. Ter &lt;strong&gt;Rust + SWC + WASM&lt;/strong&gt; rodando em &lt;code&gt;npm run build&lt;/code&gt; te dá a sensação de ter controle sobre o compilador inteiro.&lt;/p&gt;

&lt;p&gt;Hoje, com esse plugin, eu já consigo montar uma &lt;strong&gt;biblioteca de ícones SVG&lt;/strong&gt; que viram componentes React no build. É brutalmente rápido e sem dependências extras.&lt;/p&gt;




&lt;h2&gt;
  
  
  Limites e próximos passos
&lt;/h2&gt;

&lt;p&gt;Por enquanto, é um experimento — &lt;strong&gt;funciona bem no React para web&lt;/strong&gt;, mas ainda não daria pra usar direto no React Native. Quem sabe numa &lt;code&gt;v0.2&lt;/code&gt; eu consiga estender isso pra gerar algo compatível com &lt;code&gt;react-native-svg&lt;/code&gt; ou outra lib parecida.&lt;/p&gt;




&lt;h2&gt;
  
  
  Para quem quiser explorar
&lt;/h2&gt;

&lt;p&gt;O repo é: &lt;a href="https://github.com/joaoneto/swc-plugin-svg-component" rel="noopener noreferrer"&gt;https://github.com/joaoneto/swc-plugin-svg-component&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Se quiser ver como funciona, clona, compila, brinca com &lt;code&gt;cargo build&lt;/code&gt; e &lt;code&gt;swc cli&lt;/code&gt;. Se surgir bug, abre issue. Se quiser mexer junto, manda PR. Se achar tudo isso insano demais pra rodar em produção, concordo. É um plugin &lt;strong&gt;experimental&lt;/strong&gt; no sentido mais radical possível da palavra.&lt;/p&gt;

&lt;p&gt;No fim das contas, foi uma experiência que me aproximou mais do Rust, do SWC e do Next.js com Turbopack.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O repo: &lt;a href="https://github.com/joaoneto/swc-plugin-svg-component" rel="noopener noreferrer"&gt;https://github.com/joaoneto/swc-plugin-svg-component&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>nextjs</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>libuv e Lua</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Tue, 28 Jan 2025 01:00:09 +0000</pubDate>
      <link>https://forem.com/joao_neto/libuv-e-lua-3d30</link>
      <guid>https://forem.com/joao_neto/libuv-e-lua-3d30</guid>
      <description>&lt;p&gt;Criei um projeto chamado &lt;a href="https://github.com/joaoneto/lua-libuv" rel="noopener noreferrer"&gt;lua-libuv&lt;/a&gt; e gostaria de compartilhar minha experiência. A ideia inicial era testar as possibilidades de usar a biblioteca &lt;a href="https://libuv.org/" rel="noopener noreferrer"&gt;libuv&lt;/a&gt; (uma biblioteca de I/O assíncrono escrita em C) para criar um servidor HTTP extremamente simples, sem utilizar todo o poder da libuv, já que não sei nada da linguagem C.&lt;/p&gt;

&lt;p&gt;Com a ajuda do ChatGPT, gerei a base do que atualmente é o &lt;code&gt;http.c&lt;/code&gt; e, com um pouco de perseverança, consegui fechar as conexões e liberar memória na hora certa, pois enfrentei vários problemas, como o servidor simplesmente fechar a conexão e quebrar o programa principal. Tentei criar um streaming para enviar chunks, que funcionou (mas esse foi o ponto que quebrava a thread principal hehehe), só que acabei abandonando para chegar a um fim, pois meu objetivo não era me aprofundar em C.&lt;/p&gt;

&lt;p&gt;Acabei criando um ambiente onde é possível executar scripts Lua dentro de um servidor HTTP, utilizando a libuv para gerenciar as operações assíncronas. O objetivo inicial era apenas criar o servidor HTTP, mas acabei criando uma estrutura para rodar scripts Lua, o que foi uma boa evolução do projeto.&lt;/p&gt;

&lt;p&gt;Ainda não testei no Linux, então não sei se funcionará com apenas o comando &lt;code&gt;make&lt;/code&gt;, mas, de qualquer forma, é muito satisfatório ver o progresso e o objetivo alcançado até aqui. Além disso, o projeto pode servir como um ponto de partida para quem quiser construir algo mais elaborado utilizando libuv e Lua.&lt;/p&gt;

&lt;p&gt;Se alguém se interessar ou quiser colaborar, sinta-se à vontade para testar ou dar sugestões. A ideia é ajudar quem quer explorar mais essas tecnologias.&lt;/p&gt;

&lt;p&gt;O código está disponível no &lt;a href="https://github.com/joaoneto/lua-libuv" rel="noopener noreferrer"&gt;repositório&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;[update]&lt;br&gt;
Corrigido build e execução dos scripts lua para ambiente linux, testado no Ubuntu.&lt;/p&gt;

</description>
      <category>libuv</category>
      <category>lua</category>
      <category>c</category>
    </item>
    <item>
      <title>Desvendando a Monad Result em JavaScript</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Thu, 28 Mar 2024 22:13:29 +0000</pubDate>
      <link>https://forem.com/joao_neto/desvendando-a-monad-result-em-javascript-31dk</link>
      <guid>https://forem.com/joao_neto/desvendando-a-monad-result-em-javascript-31dk</guid>
      <description>&lt;h2&gt;
  
  
  Introdução:
&lt;/h2&gt;

&lt;p&gt;Ao desenvolver em JavaScript, frequentemente nos deparamos com situações em que precisamos lidar com operações que podem ter sucesso ou falhar. Para facilitar esse cenário, podemos recorrer à monad &lt;code&gt;Result&lt;/code&gt;, uma ferramenta poderosa que nos permite lidar com essas situações de forma elegante e segura. Neste artigo, vamos explorar como criar e usar a classe &lt;code&gt;Result&lt;/code&gt; em JavaScript, inspirada no &lt;code&gt;Result&lt;/code&gt; do Rust, e entender como ela se encaixa no conceito de monad.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que é a Monad Result?
&lt;/h2&gt;

&lt;p&gt;A monad &lt;code&gt;Result&lt;/code&gt; encapsula um valor que pode representar um resultado bem-sucedido ou um erro. É como uma caixinha que nos permite tratar operações que podem falhar de forma mais estruturada e previsível. Se você já está familiarizado com o &lt;code&gt;Result&lt;/code&gt; em Rust, vai perceber que a ideia é bem similar.&lt;/p&gt;

&lt;h2&gt;
  
  
  Criando a Classe Result em JavaScript:
&lt;/h2&gt;

&lt;p&gt;Vamos dar uma olhada na implementação básica da classe &lt;code&gt;Result&lt;/code&gt; em JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Result&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;andThen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Definindo uma função para dividir dois números&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;dividir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Verificando se o divisor é zero&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Se for, retornamos um Result.Err com uma mensagem de erro&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Não é possível dividir por zero.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Caso contrário, retornamos um Result.Ok com o resultado da divisão&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Exemplo de uso da função dividir&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultadoDivisao&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dividir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Multiplicando o resultado por 3&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;andThen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Adicionando 5 ao resultado&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Desembrulhando o valor final&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultadoDivisao&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Resultado = 20&lt;/span&gt;

&lt;span class="c1"&gt;// Tentativa de dividir por zero, erro propagado&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultadoVoid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dividir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Não será executado devido ao erro&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;andThen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Não será executado devido ao erro&lt;/span&gt;

&lt;span class="c1"&gt;// Como não foi feito unwrap, o erro não foi tratado e permanece no objeto Result.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultadoVoid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Result { value: null, error: 'Não é possível dividir por zero.' }&lt;/span&gt;

&lt;span class="c1"&gt;// Tentativa de dividir por zero, erro propagado e tratado com try-catch&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;dividir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Não será executado devido ao erro&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;andThen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Não será executado devido ao erro&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unwrap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// A mensagem de erro é capturada e exibida: "Não é possível dividir por zero."&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Tentativa de dividir por zero, erro capturado e manipulado&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultadoDivisaoPorZero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;dividir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Não será executado devido ao erro&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;andThen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultado&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// Não será executado devido ao erro&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Err&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Ocorreu um erro: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// O erro é capturado e uma mensagem personalizada é retornada&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultadoDivisaoPorZero&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Result { value: null, error: 'Ocorreu um erro: Não é possível dividir por zero.' }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusão:
&lt;/h2&gt;

&lt;p&gt;A monad &lt;code&gt;Result&lt;/code&gt; em JavaScript é uma ferramenta valiosa para lidar com situações de sucesso ou falha de forma estruturada e controlada. Ao entender como criar e usar essa classe, podemos escrever código mais robusto e previsível em nossos projetos.&lt;/p&gt;

&lt;p&gt;Se você quiser saber mais sobre monads e programação funcional, recomendo dar uma olhada nestes links:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.treinaweb.com.br/blog/conceitos-de-linguagens-funcionais-uma-breve-introducao-aos-monads/"&gt;https://www.treinaweb.com.br/blog/conceitos-de-linguagens-funcionais-uma-breve-introducao-aos-monads/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/tableless/programa%C3%A7%C3%A3o-funcional-avan%C3%A7ada-monads-em-javascript-862e8588fcdf"&gt;https://medium.com/tableless/programa%C3%A7%C3%A3o-funcional-avan%C3%A7ada-monads-em-javascript-862e8588fcdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>functional</category>
      <category>programming</category>
    </item>
    <item>
      <title>Simplificando o Desenvolvimento: Como Injeção de Dependências e Contêineres Transformam o Código</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Thu, 21 Mar 2024 15:52:23 +0000</pubDate>
      <link>https://forem.com/joao_neto/simplificando-o-desenvolvimento-como-injecao-de-dependencias-e-conteineres-transformam-o-codigo-o9f</link>
      <guid>https://forem.com/joao_neto/simplificando-o-desenvolvimento-como-injecao-de-dependencias-e-conteineres-transformam-o-codigo-o9f</guid>
      <description>&lt;p&gt;Quer simplificar o desenvolvimento de software e tornar seu código mais robusto? Descubra como a Injeção de Dependências e os Contêineres podem revolucionar sua abordagem de codificação.&lt;/p&gt;

&lt;p&gt;Modularidade e manutenção de código é essencial para garantir um sistema robusto e escalável. Uma técnica poderosa para alcançar esses objetivos é a Injeção de Dependências (DI), combinada com o uso de Contêineres de Injeção de Dependências.&lt;/p&gt;

&lt;h2&gt;
  
  
  O Que é Injeção de Dependências?
&lt;/h2&gt;

&lt;p&gt;Injeção de Dependências (DI) é um princípio de design que visa reduzir o acoplamento entre componentes, permitindo que suas dependências sejam fornecidas por uma fonte externa. Isso promove a reutilização, teste e manutenção do código.&lt;br&gt;
Para entender mais sobre DI e seus benefícios, você pode conferir este link.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contêiner de Injeção de Dependências?
&lt;/h2&gt;

&lt;p&gt;É uma estrutura que gerencia e fornece dependências em todo o sistema. Ele atua como um repositório centralizado para todas as dependências do aplicativo, eliminando a necessidade de configurar manualmente as dependências em cada componente.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementando um Contêiner
&lt;/h2&gt;

&lt;p&gt;A implementação de um Contêiner de Injeção de Dependências pode variar de acordo com a linguagem de programação e o ambiente de desenvolvimento. No entanto, o princípio básico permanece o mesmo: configurar todas as dependências do aplicativo em um local centralizado e fornecê-las conforme necessário.&lt;/p&gt;

&lt;p&gt;Com o uso de Contêineres de Injeção de Dependências, podemos simplificar o desenvolvimento de software, tornando nosso código mais modular, testável e fácil de manter.&lt;/p&gt;

&lt;p&gt;Espero que este conteúdo seja útil para entender a importância da Injeção de Dependências e dos Contêineres de Injeção de Dependências no desenvolvimento de software moderno.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplo de Implementação do Contêiner em JavaScript
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dependency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;dependency&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;function&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Se a dependência for uma função, invocamos ela, passando o próprio contêiner para possível injeção de dependências internas&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;dependency&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;dependency&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Exemplo de uso:&lt;/span&gt;

&lt;span class="c1"&gt;// Configurando o contêiner&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;appContainer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Container&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Configurando dependências&lt;/span&gt;
&lt;span class="nx"&gt;appContainer&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apiService&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Obtendo dependências&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ApiService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Obtendo dependências&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;logger&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;apiService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;apiService&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, estamos implementando um contêiner de injeção de dependências simples em JavaScript. Ele possui métodos set para definir dependências e get para obter dependências. Quando uma dependência é uma função, o contêiner a invoca, permitindo a injeção de dependências internas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefícios do Uso de Contêineres
&lt;/h2&gt;

&lt;p&gt;O uso de Contêineres de Injeção de Dependências proporciona diversos benefícios para o desenvolvimento de software:&lt;/p&gt;

&lt;p&gt;Desacoplamento: Os componentes do sistema se tornam independentes de suas implementações de dependência, facilitando a substituição e a manutenção do código.&lt;/p&gt;

&lt;p&gt;Teste: A DI simplifica os testes unitários, permitindo a injeção de dependências de teste em vez de dependências reais durante os testes.&lt;/p&gt;

&lt;p&gt;Reutilização de Código: Os componentes se tornam mais reutilizáveis, pois suas dependências são fornecidas externamente, não estando vinculadas a uma implementação específica.&lt;/p&gt;

&lt;p&gt;Manutenção: A modularidade promovida pelos Contêineres torna o código mais fácil de entender, modificar e manter ao longo do tempo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão:
&lt;/h2&gt;

&lt;p&gt;Agora que você entende a importância da Injeção de Dependências e dos Contêineres de Injeção de Dependências, está pronto para simplificar seu processo de desenvolvimento de software. Experimente esses conceitos em seu próximo projeto e compartilhe suas experiências aqui.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>APIs com Guarapi e HTTP/2</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Thu, 15 Feb 2024 17:35:24 +0000</pubDate>
      <link>https://forem.com/guarapi/apis-com-guarapi-e-http2-58f2</link>
      <guid>https://forem.com/guarapi/apis-com-guarapi-e-http2-58f2</guid>
      <description>&lt;p&gt;O HTTP/2 é uma evolução significativa em relação ao seu predecessor, o HTTP/1.1, proporcionando melhorias notáveis na eficiência da comunicação entre clientes e servidores. Neste artigo, exploraremos como o Guarapi, um servidor HTTP para Node.js, oferece suporte ao HTTP/2 e por que a utilização do TLS é fundamental nesse contexto.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Motivos para o Uso do TLS com HTTP/2&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O HTTP/2, por padrão, é projetado para ser seguro, e é altamente recomendável utilizar o TLS (Transport Layer Security) para garantir a integridade e a confidencialidade dos dados durante a comunicação. Além disso, muitos navegadores modernos só permitem o uso do HTTP/2 sobre TLS, tornando essencial a implementação desse protocolo de segurança.&lt;/p&gt;

&lt;p&gt;No código abaixo, observe como o Guarapi configura o servidor para utilizar o TLS, fornecendo os certificados necessários:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;certs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./cert/key.pem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="na"&gt;cert&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./cert/cert.pem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;guarapi&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;serverOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;isSSL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;isHTTP2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;allowHTTP1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;certs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Suporte ao HTTP/2 no Guarapi&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;O Guarapi simplifica a implementação do HTTP/2, oferecendo uma configuração clara e direta para habilitar esse protocolo de comunicação eficiente. Ao estabelecer o servidor com &lt;code&gt;isHTTP2: true&lt;/code&gt;, você coloca sua aplicação na vanguarda das tecnologias web, proporcionando uma experiência mais ágil aos usuários finais.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Servindo Arquivos Estáticos com HTTP/2: Melhores Práticas&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ao considerar a entrega de arquivos estáticos via HTTP/2, é importante explorar alternativas que otimizem o desempenho. Uma abordagem comum é evitar a transmissão desses arquivos no mesmo socket do servidor Guarapi, buscando soluções mais eficientes. Isso pode ser particularmente crucial em ambientes de produção com alto tráfego.&lt;/p&gt;

&lt;p&gt;Uma possível abordagem para aprimorar a entrega de arquivos estáticos no Guarapi é o desenvolvimento de um plugin específico. Esse plugin pode ser projetado para lidar com a transmissão de arquivos estáticos de maneira performática, aproveitando os benefícios do HTTP/2.&lt;/p&gt;

&lt;p&gt;Explorar essas otimizações pode resultar em uma experiência de usuário mais rápida e eficiente, aproveitando ao máximo as vantagens do HTTP/2. Lembre-se de adaptar essas práticas conforme as necessidades específicas do seu projeto.&lt;/p&gt;

&lt;p&gt;Ao adotar o HTTP/2 com Guarapi e TLS, você estará preparando sua aplicação para um desempenho maior e alinhada às melhores práticas da web moderna.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Recomendações e Recursos Adicionais&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Recomendamos a consulta à documentação do Node.js sobre a compatibilidade do HTTP/2, fornecendo links específicos para as seções relevantes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/api/http2.html#compatibility-api"&gt;Compatibilidade API do HTTP/2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nodejs.org/api/http2.html#alpn-negotiation"&gt;Negociação de Protocolo ALPN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Essas referências são inestimáveis para aprofundar o entendimento sobre as nuances do HTTP/2 no contexto do Node.js. Elas oferecem insights adicionais aos desenvolvedores que desejam explorar a fundo as melhores práticas e otimizações. Ao incorporar o HTTP/2 com Guarapi e TLS, você estará preparando sua aplicação para um desempenho excepcional, alinhado às práticas mais recentes da web moderna.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nossas redes:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plataforma&lt;/th&gt;
&lt;th&gt;Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reddit&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.reddit.com/r/Guarapi/"&gt;Guarapi Subreddit&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daily.dev&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dly.to/BAbWhWqJ7cs"&gt;Daily.dev Invite&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discord&lt;/td&gt;
&lt;td&gt;&lt;a href="https://discord.com/invite/KQwZtsTF"&gt;Discord Invite&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repositório&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/guarapi/guarapi"&gt;Guarapi no GitHub&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>guarapi</category>
      <category>node</category>
    </item>
    <item>
      <title>Os Bastidores do Guarapi - Framework Modular</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Thu, 08 Feb 2024 14:08:50 +0000</pubDate>
      <link>https://forem.com/guarapi/os-bastidores-do-guarapi-framework-modular-24d9</link>
      <guid>https://forem.com/guarapi/os-bastidores-do-guarapi-framework-modular-24d9</guid>
      <description>&lt;h2&gt;
  
  
  Navegando no Futuro: Frameworks Modulares e as Engrenagens das Prioridades
&lt;/h2&gt;

&lt;p&gt;Vamos explorar mais a fundo a onda dos frameworks modulares, focando especialmente no Guarapi, que está na dianteira dessa revolução. Vamos entender por que a ordem dos plugins não é automática e como isso abre portas para um controle dinâmico via CLI ou até mesmo um admin frontend que ainda está na mesa de ideias.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Flexibilidade nos Trilhos com o Guarapi:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No universo dos frameworks modulares, o Guarapi é tipo o maestro da flexibilidade. Com sua abordagem modular, é possível moldar a aplicação conforme o projeto pede, e os plugins entram em cena para um upgrade personalizado.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Controle Manual dos Plugins:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A não ordenação automática de plugins no Guarapi é como ter o controle total do palco. Cada desenvolvedor decide a ordem de entrada dos plugins, garantindo que a performance seja um espetáculo otimizado. Isso é puro controle criativo!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Reuso de Plugins com a Vibe do Guarapi:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A comunidade Guarapi compartilha a visão de reuso e troca de ideias. Os plugins podem ser como peças valiosas que você pode encaixar conforme o necessário, tudo alinhado com a proposta modular e expansível do Guarapi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Testabilidade na Prática:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A proposta do Guarapi, com seus plugins sob controle, facilita a testabilidade. Os testes unitários podem ser afiados para cada plugin, garantindo uma execução suave e sem tropeços.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Admin Frontend em Potencial:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A cereja no bolo é a ideia de um admin frontend para controlar plugins em tempo de execução. Imagina só, conectar e desconectar plugins como quem troca de figurino no backstage. O Guarapi está semeando a ideia de um controle dinâmico para os devs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Rumo ao Futuro:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O Guarapi, com sua abordagem modular e controle manual de plugins, está apontando para o futuro. A visão de um admin frontend adiciona um toque extra de inovação. O controle em tempo de execução é como ter as rédeas da experiência de desenvolvimento nas mãos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusão: Conduzindo a Orquestra do Desenvolvimento&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Os frameworks modulares, especialmente o Guarapi, abrem portas para uma era de controle e personalização no desenvolvimento. Controlar manualmente a ordem dos plugins é uma jogada inteligente, proporcionando um espetáculo de performance otimizado. E a visão de um admin frontend no Guarapi? Isso pode ser um divisor de águas na flexibilidade e no controle em tempo real. Vamos ficar de olho nesse enredo emocionante!&lt;/p&gt;

&lt;h3&gt;
  
  
  Nossas redes:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plataforma&lt;/th&gt;
&lt;th&gt;Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reddit&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.reddit.com/r/Guarapi/"&gt;Guarapi Subreddit&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daily.dev&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dly.to/BAbWhWqJ7cs"&gt;Daily.dev Invite&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discord&lt;/td&gt;
&lt;td&gt;&lt;a href="https://discord.com/invite/KQwZtsTF"&gt;Discord Invite&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repositório&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/guarapi/guarapi"&gt;Guarapi no GitHub&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>webdev</category>
      <category>guarapi</category>
      <category>javascript</category>
      <category>igotroasted</category>
    </item>
    <item>
      <title>Implementando um Plugin de Autenticação para Guarapi</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Wed, 10 Jan 2024 18:31:58 +0000</pubDate>
      <link>https://forem.com/guarapi/implementando-um-plugin-de-autenticacao-para-guarapi-h2l</link>
      <guid>https://forem.com/guarapi/implementando-um-plugin-de-autenticacao-para-guarapi-h2l</guid>
      <description>&lt;p&gt;Olá!&lt;/p&gt;

&lt;p&gt;Gostaria de compartilhar uma Prova de Conceito (POC) de um plugin de autenticação em desenvolvimento para o Guarapi. Este plugin visa oferecer funcionalidades de autenticação e renovação de tokens JWT.&lt;/p&gt;

&lt;p&gt;Para mais informações e para colaborar, acesse nosso Discord &lt;a href="https://discord.gg/bs3Upnw5"&gt;Guarapi Development&lt;/a&gt; e confira o &lt;a href="https://github.com/guarapi/guarapi"&gt;GitHub do Guarapi&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Aqui está uma breve amostra do código do plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Plugin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;guarapi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Methods&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;guarapi/dist/lib/router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sign&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsonwebtoken&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SingConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;getJWTPayload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;GuarapiAuthPluginConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;SingConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;SingConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;tokenExpiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;refreshTokenExpiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;issuer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;audience&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;guarapiAuthPlugin&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;guarapiAuthPluginConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GuarapiAuthPluginConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;audience&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;issuer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tokenExpiresIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refreshTokenExpiresIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
    &lt;span class="nx"&gt;guarapiAuthPluginConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;routesMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SingConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SingConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;P&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;jwtPayload&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getJWTPayload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;jwtPayload&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;signIn&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;tokenExpiresIn&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;refreshTokenExpiresIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;audience&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;issuer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;

      &lt;span class="na"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;jwtPayload&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;expiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;refreshTokenExpiresIn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;audience&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;issuer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Plugin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;routesMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
      &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;method&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;method&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;Methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokens&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;getTokens&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;

      &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;guarapiAuthPlugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este plugin permite configurar rotas de autenticação e renovação de tokens JWT, adaptáveis às necessidades do projeto. Ele utiliza o pacote jsonwebtoken para gerar os tokens com base nas configurações fornecidas.&lt;/p&gt;

&lt;p&gt;A configuração básica para este plugin é a seguinte:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Guarapi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bodyParserPlugin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;middlewarePlugin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;guarapi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;guarapiAuthPlugin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GuarapiAuthPluginConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./guarapi-auth-plugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;PayloadRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;initPlugins&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Guarapi&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;GuarapiAuthPluginConfig&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;signIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/auth/signin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;getJWTPayload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;teste&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;PayloadRequest&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;refreshToken&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/auth/refresh&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;getJWTPayload&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;teste&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;PayloadRequest&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;audience&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;teste&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;issuer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;issuer-1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secret&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;refreshTokenExpiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;24h&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;tokenExpiresIn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1h&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParserPlugin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;middlewarePlugin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;guarapiAuthPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;authConfig&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Estou buscando feedback da comunidade sobre a estrutura, a lógica de funcionamento e possíveis melhorias que podem ser implementadas neste plugin. Sintam-se à vontade para discutir e compartilhar suas opiniões, sugestões ou dúvidas relacionadas a esta POC.&lt;/p&gt;

&lt;p&gt;Agradeço antecipadamente por qualquer contribuição ou feedback que possam oferecer!&lt;/p&gt;

&lt;h3&gt;
  
  
  Nossas redes:
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plataforma&lt;/th&gt;
&lt;th&gt;Link&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reddit&lt;/td&gt;
&lt;td&gt;&lt;a href="https://www.reddit.com/r/Guarapi/"&gt;Guarapi Subreddit&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Daily.dev&lt;/td&gt;
&lt;td&gt;&lt;a href="https://dly.to/BAbWhWqJ7cs"&gt;Daily.dev Invite&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Discord&lt;/td&gt;
&lt;td&gt;&lt;a href="https://discord.com/invite/KQwZtsTF"&gt;Discord Invite&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repositório&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/guarapi/guarapi"&gt;Guarapi no GitHub&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
    </item>
    <item>
      <title>🚀 Crie Aplicativos Web com o Guarapi Rapidamente!</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Sun, 22 Oct 2023 04:39:15 +0000</pubDate>
      <link>https://forem.com/guarapi/crie-aplicativos-com-o-guarapi-rapidamente-2n9g</link>
      <guid>https://forem.com/guarapi/crie-aplicativos-com-o-guarapi-rapidamente-2n9g</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introdução:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Olá! Temos o prazer de anunciar o lançamento da Versão 1.0 do Guarapi e o starter kit &lt;code&gt;@guarapi/create-guarapi-app&lt;/code&gt;, uma ferramenta que simplifica o processo de criação de aplicativos web com o Guarapi framework. Se você é um desenvolvedor em busca de uma estrutura eficaz e elegante para criar aplicativos Node.js, esta é a notícia que você estava esperando!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como Começar:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Usar o &lt;code&gt;@guarapi/create-guarapi-app&lt;/code&gt; é fácil. Basta criar um novo aplicativo Guarapi com este único comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm create @guarapi/guarapi-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Escolha um exemplo de projeto de nossos &lt;a href="https://github.com/guarapi/guarapi/tree/main/examples"&gt;exemplos Guarapi&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Como Contribuir:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Estamos sempre abertos a contribuições e feedback da comunidade. Se você encontrar problemas ou tiver sugestões para melhorias, não hesite em &lt;a href="https://dev.toURL_DO_REPOSIT%C3%93RIO"&gt;abrirmos uma issue no GitHub&lt;/a&gt;. Valorizamos sua opinião!&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>guarapi</category>
    </item>
    <item>
      <title>Guarapi v0.1.0: Revolucionando o Desenvolvimento Web com Node.js</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Wed, 13 Sep 2023 05:07:00 +0000</pubDate>
      <link>https://forem.com/guarapi/guarapi-v010-revolucionando-o-desenvolvimento-web-com-nodejs-26am</link>
      <guid>https://forem.com/guarapi/guarapi-v010-revolucionando-o-desenvolvimento-web-com-nodejs-26am</guid>
      <description>&lt;p&gt;É com grande empolgação que compartilho as últimas atualizações do Guarapi. Estamos comprometidos em tornar o desenvolvimento web mais simples e eficiente, e nossa mais recente versão, a &lt;a href="https://github.com/joaoneto/guarapi/releases/tag/v0.1.0"&gt;v0.1.0&lt;/a&gt;, traz algumas melhorias empolgantes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Novidades em Destaque
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Plugin de Rotas Integrado
&lt;/h3&gt;

&lt;p&gt;A principal adição nesta versão é a integração de um plugin de rotas robusto. Agora, você pode definir rotas para sua aplicação web de maneira flexível e intuitiva. Lida com diferentes métodos HTTP e padrões de URL com facilidade, economizando tempo e esforço no desenvolvimento de rotas complexas. Dê uma olhada na nossa &lt;a href="https://github.com/joaoneto/guarapi#routing"&gt;documentação&lt;/a&gt; para aprender como começar a usar esse novo recurso!&lt;/p&gt;

&lt;h3&gt;
  
  
  Hook de Erro
&lt;/h3&gt;

&lt;p&gt;Outra grande melhoria é a inclusão do hook de erro. Ele permite que você gerencie erros de maneira elegante durante o processamento de solicitações. Seja para registrar erros ou fornecer respostas de erro adequadas, o hook de erro é uma ferramenta essencial para tornar suas aplicações mais robustas e confiáveis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Próximos Passos
&lt;/h2&gt;

&lt;p&gt;Estamos empolgados com o progresso do Guarapi até agora, mas nosso trabalho está longe de terminar. Aqui estão alguns dos próximos passos que planejamos:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Melhorias Contínuas&lt;/strong&gt;: Continuaremos aprimorando o Guarapi para oferecer uma experiência de desenvolvimento ainda melhor. Esperamos adicionar mais recursos úteis e aprimorar a usabilidade.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adicionar Testes&lt;/strong&gt;: A qualidade é nossa prioridade. Estamos planejando adicionar testes abrangentes para garantir que o Guarapi seja confiável e estável em todos os cenários.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Novas Funcionalidades&lt;/strong&gt;: Estamos sempre abertos a ideias e contribuições da comunidade. Se você tiver sugestões ou desejar adicionar novos recursos, fique à vontade para contribuir para o projeto.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Estamos entusiasmados com o que o futuro reserva para o Guarapi e mal podemos esperar para ver o que você construirá com essa ferramenta poderosa.&lt;/p&gt;

&lt;p&gt;Junte-se a nós na jornada do Guarapi, explore nossa &lt;a href="https://github.com/joaoneto/guarapi"&gt;documentação&lt;/a&gt; e fique à vontade para contribuir para o projeto no &lt;a href="https://github.com/joaoneto/guarapi"&gt;GitHub&lt;/a&gt;. Seja parte desta comunidade amigável e inclusiva.&lt;/p&gt;

&lt;p&gt;Fique atento às atualizações e evoluções deste framework. Juntos, podemos fazer a diferença no mundo do desenvolvimento web!&lt;/p&gt;

</description>
      <category>guarapi</category>
      <category>node</category>
      <category>javascript</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Guarapi - Framework Brasileiro</title>
      <dc:creator>João Neto</dc:creator>
      <pubDate>Tue, 29 Aug 2023 02:48:43 +0000</pubDate>
      <link>https://forem.com/guarapi/guarapi-framework-brasileiro-275l</link>
      <guid>https://forem.com/guarapi/guarapi-framework-brasileiro-275l</guid>
      <description>&lt;h2&gt;
  
  
  Guarapi - Framework Brasileiro
&lt;/h2&gt;

&lt;p&gt;Descubra o Guarapi, um framework revolucionário para desenvolvimento web em Node.js. Neste artigo, mergulhamos fundo no estágio atual de desenvolvimento do Guarapi, explorando funcionalidades emocionantes e oportunidades de colaboração. Acompanhe o progresso deste projeto de código aberto e saiba como fazer parte dessa jornada.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repositório no GitHub&lt;/strong&gt;: &lt;a href="https://github.com/joaoneto/guarapi"&gt;Guarapi GitHub Repository&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplo
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;IncomingMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ServerResponse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;guarapi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;logger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;guarapi&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;guarapi&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;middleware&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;info&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My debug msg&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IncomingMessage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ServerResponse&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ok&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0.0.0.0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;&amp;gt; Running: http://localhost:3000&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O código de exemplo demonstra a estrutura básica de um aplicativo Guarapi. Vamos dar uma olhada nos principais componentes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Imports&lt;/strong&gt;: O código começa importando os módulos &lt;code&gt;http&lt;/code&gt; e o próprio &lt;code&gt;guarapi&lt;/code&gt;. Ele também importa os módulos de middleware e logger.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Criação de uma instância Guarapi&lt;/strong&gt;: O código cria uma instância do Guarapi chamada &lt;code&gt;app&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adição de Middleware&lt;/strong&gt;: O código adiciona dois plugins ao Guarapi: &lt;code&gt;middleware&lt;/code&gt; e &lt;code&gt;logger&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Definição de Rotas&lt;/strong&gt;: Duas rotas são definidas usando o método &lt;code&gt;app.use()&lt;/code&gt;. A primeira rota registra uma mensagem de log usando o logger do Guarapi e, em seguida, chama o próximo middleware. A segunda rota simplesmente envia uma resposta "ok" para o cliente. Posteriormente, teremos mais formas de definir rotas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Inicialização do Servidor&lt;/strong&gt;: O código inicia o servidor na porta 3000 e no endereço "0.0.0.0".&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Funcionalidades Principais
&lt;/h2&gt;

&lt;p&gt;Podemos destacar as seguintes funcionalidades principais do Guarapi até o momento:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Middleware&lt;/strong&gt;: O Guarapi suporta a inclusão de middleware, como demonstrado pela adição dos plugins &lt;code&gt;middleware&lt;/code&gt; e &lt;code&gt;logger&lt;/code&gt;. Isso permite que desenvolvedores personalizem o processamento de solicitações HTTP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Logging&lt;/strong&gt;: O framework possui um sistema de registro integrado. O exemplo mostra como registrar mensagens de log com diferentes níveis (no caso, "info").&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Middleware (Tratamento de Rotas raiz)&lt;/strong&gt;: Rotas são definidas usando o método &lt;code&gt;app.use()&lt;/code&gt;, permitindo que os desenvolvedores definam como as solicitações HTTP devem ser manipuladas.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Próximos Passos
&lt;/h2&gt;

&lt;p&gt;Agora, imagine as possibilidades! Você pode fazer parte do futuro deste framework emocionante:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adição de Recursos&lt;/strong&gt;: Expandir a funcionalidade do framework adicionando mais recursos, como suporte a autenticação, validação de entrada e roteamento avançado.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Documentação Detalhada&lt;/strong&gt;: Criar documentação detalhada para que outros desenvolvedores possam entender e utilizar facilmente o Guarapi.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testes Unitários e de Integração&lt;/strong&gt;: Implementar testes para garantir a robustez e confiabilidade do framework.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Comunidade e Colaboração&lt;/strong&gt;: Encorajar a participação da comunidade e receber contribuições para o projeto. Vamos construir algo incrível juntos!&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;O Guarapi é mais do que um framework - é uma oportunidade de inovação e colaboração. Com um compromisso com a flexibilidade e uma visão ambiciosa, o Guarapi promete simplificar o desenvolvimento de aplicativos web em Node.js. Junte-se a nós nesta emocionante jornada de criação e transformação!&lt;/p&gt;

&lt;p&gt;Fique atento às atualizações e evoluções deste framework. Juntos, podemos fazer a diferença no mundo do desenvolvimento web!&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
