<?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>DEV Community: PURISTA</title>
    <description>The latest articles on DEV Community by PURISTA (@purista).</description>
    <link>https://dev.to/purista</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%2Forganization%2Fprofile_image%2F6998%2F08b3c023-77e6-48ff-8c99-e5f510e88784.png</url>
      <title>DEV Community: PURISTA</title>
      <link>https://dev.to/purista</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/purista"/>
    <language>en</language>
    <item>
      <title>PURISTA - Tests with Jest, Sinon.js and Testcontainers</title>
      <dc:creator>Sebastian Wessel</dc:creator>
      <pubDate>Tue, 12 Sep 2023 08:48:46 +0000</pubDate>
      <link>https://dev.to/purista/purista-tests-with-jest-sinonjs-and-testcontainers-31lh</link>
      <guid>https://dev.to/purista/purista-tests-with-jest-sinonjs-and-testcontainers-31lh</guid>
      <description>&lt;p&gt;In the journey of crafting the &lt;a href="https://purista.dev"&gt;PURISTA TypeScript backend framework&lt;/a&gt;, the need for automated software testing became increasingly apparent.&lt;br&gt;
PURISTA's extensive amount of adapters and integrations with third-party solutions makes it impractical to conduct manual testing repeatedly.&lt;br&gt;
In this article, we dive into the pivotal role of automated testing in ensuring the reliability and stability of PURISTA's offerings.&lt;/p&gt;

&lt;p&gt;Moreover, enabling developers to effortlessly test their code built on top of PURISTA stands as a pivotal aspect of the framework.&lt;/p&gt;
&lt;h2&gt;
  
  
  Jest
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://jestjs.io"&gt;Jest&lt;/a&gt; offers a comprehensive test suite where you can efficiently organize, implement, and execute your tests. With approximately &lt;strong&gt;1490 contributors&lt;/strong&gt;, Jest has played a pivotal role in simplifying the process of writing tests, as demonstrated below:&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;asyncOperation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;syncOperation&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;mytestfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My testfile works&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;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;is exected to be 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="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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;syncOperation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;works with async await&lt;/span&gt;&lt;span class="dl"&gt;'&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="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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;asyncOperation&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;resolves&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&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="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the number on GitHub shows: This awesome tool is &lt;strong&gt;used by 10.4 millions&lt;/strong&gt;!&lt;br&gt;
This unbelievable number shows, how important it is.&lt;/p&gt;

&lt;p&gt;A massive shout-out to Jest and all its dedicated contributors! Consider starring it on GitHub, giving a shout-out on social media, or mentioning it in your readme file to show your appreciation. 🌟👏&lt;/p&gt;

&lt;p&gt;We use Jest together with &lt;a href="https://swc.rs/docs/usage/jest"&gt;@swc/jest&lt;/a&gt;, which speeds up our test runs dramatically.&lt;br&gt;
They don't lie with "Super-fast alternative for babel-jest or ts-jest without type checking".&lt;br&gt;
It's the second great tool by &lt;a href="https://vercel.com"&gt;Vercel&lt;/a&gt; we use at PURISTA.&lt;/p&gt;
&lt;h2&gt;
  
  
  Sinon.js
&lt;/h2&gt;

&lt;p&gt;When writing tests, you probably will come to the point where you need to mock, fake or spy on something. Even if the test framework is providing some helpers for it, you should have a look at &lt;a href="https://sinonjs.org"&gt;Sinon.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At PURISTA, we primarily leverage Sinon.js to deliver a seamless testing experience for developers.&lt;br&gt;
We provide for example the &lt;code&gt;getLoggerMock&lt;/code&gt; function, which returns an easy way to test logging, without poluting the test runner output.&lt;/p&gt;

&lt;p&gt;This function looks like this:&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;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getLoggerMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sandbox&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="nx"&gt;SinonSandbox&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;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sandbox&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;stub&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;error&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sandbox&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;stub&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;warn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sandbox&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;stub&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;debug&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sandbox&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;stub&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;trace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sandbox&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;stub&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;fatal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;sandbox&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Logger&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;info&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;warn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;fatal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;getChildLogger&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;mock&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;stubs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;info&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;warn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;debug&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;trace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;fatal&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;mock&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;As you can see, we've created stubs, which are a form of mock implementations. You can use them to check whether a stub is called, how many times it's called, if it's called with specific parameters, and more. Additionally, Sinon.js offers sandboxing, a highly recommended feature. It prevents your tests from interfering with each other, ensuring clean and reliable results.&lt;/p&gt;

&lt;p&gt;As an example on how it might look:&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;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="s1"&gt;@purista/core&lt;/span&gt;&lt;span class="dl"&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;createSandbox&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;sinon&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;syncOperation&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;Logger&lt;/span&gt;&lt;span class="p"&gt;)&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;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;info log&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My testfile works&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sandbox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createSandbox&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="nx"&gt;afterEach&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;sandbox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reset&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;is exected to be 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="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;loggerMock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getLoggerMock&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;syncOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loggerMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mock&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;OK&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;loggerMock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stub&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;calledOnceWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;info log&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBeTruthy&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;Sinon.js is unbelievably helpful, and the 328 contributors are doing an incredible job. It's no surprise that Sinon.js is trusted by over 574k developers. Show them some love with a big shout-out and a star on GitHub!&lt;/p&gt;

&lt;p&gt;If you haven't used Sinon.js before, it's definitely worth giving it a try.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testcontainers
&lt;/h2&gt;

&lt;p&gt;To be honest, &lt;a href="https://node.testcontainers.org"&gt;Testcontainers&lt;/a&gt; wasn't on our radar initially.&lt;br&gt;
However, we soon realized the need for a viable solution to conduct integration tests for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rabbitmq.com"&gt;RabbitMQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mosquitto.org/"&gt;Mosquitto&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.emqx.com/en/products/nanomq"&gt;NanoMQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.hivemq.com/"&gt;HiveMQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://vernemq.com/"&gt;VerneMQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://activemq.apache.org/"&gt;ActiveMQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nats.io/"&gt;NATS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://redis.io"&gt;Redis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://infisical.com"&gt;Infisical&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;...and much more&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Testcontainers was the gamechanger here.&lt;br&gt;
It is super easy to spin up a docker container and run tests against a real running system.&lt;/p&gt;

&lt;p&gt;To show you, how simple it is:&lt;/p&gt;

&lt;p&gt;Here is the example, on how start a full RabbitMQ before we run our tests:&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;GenericContainer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;StartedTestContainer&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;testcontainers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AMQP_PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5672&lt;/span&gt;

&lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@purista/amqpbridge&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="kd"&gt;let&lt;/span&gt; &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;StartedTestContainer&lt;/span&gt;

  &lt;span class="nx"&gt;beforeAll&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;GenericContainer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rabbitmq:alpine&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;withExposedPorts&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AMQP_PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;AMQP_PORT&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;afterAll&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stop&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;It significantly enhanced our local testing process. Furthermore, Testcontainers is a versatile tool available for multiple programming languages.&lt;/p&gt;

&lt;p&gt;A heartfelt thank you to all the contributors of Testcontainers for this incredible project! We deeply appreciate the outstanding work you've put into it.&lt;/p&gt;

&lt;p&gt;If you're searching for content ideas for the next article, consider crafting a cool piece about Testcontainers and its practical applications. Dive into how to harness its power effectively.&lt;/p&gt;




&lt;p&gt;Now that we've explored the powerful tooling required to build PURISTA itself, let's shift our focus to the components under the hood that make PURISTA tick.&lt;/p&gt;

&lt;p&gt;Be sure to check out the upcoming article in this series!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>testing</category>
      <category>opensource</category>
    </item>
    <item>
      <title>PURISTA: Build with rimraf, esbuild, Turbo &amp; git-cliff</title>
      <dc:creator>Sebastian Wessel</dc:creator>
      <pubDate>Mon, 11 Sep 2023 21:15:26 +0000</pubDate>
      <link>https://dev.to/purista/purista-build-with-rimraf-esbuild-turbo-git-cliff-5h5e</link>
      <guid>https://dev.to/purista/purista-build-with-rimraf-esbuild-turbo-git-cliff-5h5e</guid>
      <description>&lt;p&gt;In our previous article, we laid the foundation with a glimpse of our coding setup.&lt;/p&gt;

&lt;p&gt;It's now time to spotlight the indispensable build tools that power its development.&lt;/p&gt;

&lt;h2&gt;
  
  
  rimraf
&lt;/h2&gt;

&lt;p&gt;Huge thanks to &lt;a href="http://blog.izs.me/"&gt;Isaacs&lt;/a&gt;!&lt;br&gt;
&lt;a href="https://github.com/isaacs/rimraf"&gt;Rimraf&lt;/a&gt; comes to the rescue, providing a reliable solution for deep, recursive removal of folders and files.&lt;br&gt;
At PURISTA, we rely on rimraf to maintain pristine build output directories. &lt;/p&gt;
&lt;h2&gt;
  
  
  Turbo
&lt;/h2&gt;

&lt;p&gt;PURISTA is organized in a monorepo.&lt;br&gt;
During the development and build process, &lt;a href="https://turbo.build"&gt;Turbo&lt;/a&gt; is used to execute different tasks and steps on multiple packages with one command.&lt;/p&gt;

&lt;p&gt;We aren't harnessing the full potential and capabilities of Turbo at the moment since PURISTA currently requires only a few straightforward build tasks.&lt;/p&gt;

&lt;p&gt;If you have more complex tasks, especially those with interdependencies between steps, it's worth exploring &lt;a href="https://turbo.build"&gt;https://turbo.build&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Esbuild
&lt;/h2&gt;

&lt;p&gt;In its early stages, PURISTA was built using the standard TypeScript compiler.&lt;br&gt;
However, this approach excelled in creating CommonJS packages but turned into a nightmare when it came to generating ESM builds.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://esbuild.github.io"&gt;esbuild&lt;/a&gt; - the rescue!&lt;br&gt;
No longer struggling with configs, file extensions or similar.&lt;/p&gt;

&lt;p&gt;With esbuild, it was becoming simple and fast.&lt;/p&gt;

&lt;p&gt;We created a small script:&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;const&lt;/span&gt; &lt;span class="nx"&gt;esbuild&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;esbuild&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;esbuild&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/index.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;outfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./lib/esm/index.mjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;bundle&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;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;esm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;splitting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;sourcemap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node18&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;minify&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;packages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;external&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;catch&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="nx"&gt;esbuild&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;entryPoints&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/index.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;outfile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./lib/cjs/index.cjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;bundle&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;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;splitting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;sourcemap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node18&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;minify&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;packages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;external&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;catch&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;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since this approach only generates JavaScript files, and we aim to provide proper TypeScript types to PURISTA users, we utilize the TypeScript compiler specifically for building types.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tsc --emitDeclarationOnly --declarationMap false --declaration --outDir lib/types
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;package.json&lt;/code&gt;, only these additions were necessary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"directories"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"lib"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lib/index.js"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./lib/cjs/index.cjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"module"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./lib/esm/index.mjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"exports"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"."&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"import"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./lib/esm/index.mjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"require"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./lib/cjs/index.cjs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"types"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./lib/types/index.d.ts"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lib/types/index.d.ts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"lib"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A big thank you ❤️ to all contributors and maintainers of esbuild!&lt;br&gt;
It solved the issue with CommonJS/ESM for us and produces size optimized outputs for all PURISTA packages.&lt;/p&gt;
&lt;h2&gt;
  
  
  git-cliff
&lt;/h2&gt;

&lt;p&gt;Changelogs are nice and everybody likes them, but nobody wants to maintain them 😜.&lt;br&gt;
Here, &lt;a href="https://git-cliff.org/"&gt;git-cliff&lt;/a&gt; by &lt;a href="https://blog.orhun.dev"&gt;Orhun Parmaksız&lt;/a&gt; is one simple to use solution.&lt;/p&gt;

&lt;p&gt;One simple command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git-cliff &amp;gt; CHANGELOG.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And your changelog gets generated from your git history.&lt;/p&gt;

&lt;p&gt;Undoubtedly one of the time-saving tools, you should check out at &lt;a href="https://git-cliff.org"&gt;https://git-cliff.org&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;In the upcoming article of this series, we will delve deeper into the test setup. Stay tuned!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>programming</category>
      <category>opensource</category>
    </item>
    <item>
      <title>PURISTA - Thanks to amazing open-source software</title>
      <dc:creator>Sebastian Wessel</dc:creator>
      <pubDate>Mon, 11 Sep 2023 20:17:57 +0000</pubDate>
      <link>https://dev.to/purista/purista-thanks-to-amazing-open-source-software-4k2e</link>
      <guid>https://dev.to/purista/purista-thanks-to-amazing-open-source-software-4k2e</guid>
      <description>&lt;p&gt;Welcome to our series on the unsung heroes behind PURISTA!&lt;/p&gt;

&lt;p&gt;Ever wondered about PURISTA?&lt;br&gt;
It's not just another Typescript backend framework for simply building HTTP-endpoints.&lt;br&gt;
It's a versatile solution that embraces diverse techniques for highly distributed deployments, taking inspiration from event-driven architecture.&lt;br&gt;
If you're interested, you're invited to take a look at the official website &lt;a href="//purista.dev"&gt;http://purista.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But hold on, this series isn't about the framework itself. Instead, we're here to shine a spotlight on the incredible libraries, tools, software, and passionate contributors that make PURISTA possible. &lt;/p&gt;

&lt;p&gt;In this series, we will introduce all the tools, explain how we use them, why we find them essential, and endeavor to illustrate why they might also be a suitable solution for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  General setup
&lt;/h2&gt;

&lt;p&gt;Most developers should be more or less familiar with the basic setup.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com"&gt;VSCode&lt;/a&gt; as a code editor with  ESLint plugin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/sebastianwessel/purista"&gt;GitHub&lt;/a&gt; is uses as repository, issue &amp;amp; project tracker, and also for hosting the &lt;a href="https://purista.dev/"&gt;official website&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coding Setup
&lt;/h2&gt;

&lt;p&gt;In addition to &lt;a href="https://nodejs.org/"&gt;Node.js&lt;/a&gt; and &lt;a href="https://www.typescriptlang.org"&gt;TypeScript&lt;/a&gt;, we rely on two indispensable tools available as npm modules:&lt;/p&gt;

&lt;h3&gt;
  
  
  ESLint and Prettier
&lt;/h3&gt;

&lt;p&gt;Maintaining a clean, readable, and consistent codebase is essential, and ESLint and Prettier are the perfect tools for the job.&lt;br&gt;
Just enable "lint on save" in VSCode, and you won't have to worry about it. They're a "must-have," even for small personal projects.&lt;/p&gt;

&lt;p&gt;See &lt;a href="//eslint.org"&gt;https://eslint.org&lt;/a&gt; and &lt;a href="//prettier.io"&gt;https://prettier.io&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ESLint is extended by some awesome plugins and extensions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/lydell/eslint-plugin-simple-import-sort"&gt;eslint-plugin-simple-import-sort&lt;/a&gt; by Simon Lydell &lt;a href="https://twitter.com/SimonLydell"&gt;@SimonLydell&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/mysticatea/eslint-plugin-node"&gt;eslint-plugin-node&lt;/a&gt; by Toru Nagashima - Dev.to: &lt;a class="mentioned-user" href="https://dev.to/mysticatea"&gt;@mysticatea&lt;/a&gt; &amp;amp;  Twitter: &lt;a href="https://twitter.com/mysticatea"&gt;@mysticatea&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/azeemba/eslint-plugin-json"&gt;eslint-plugin-json&lt;/a&gt; by &lt;a href="https://azeemba.com"&gt;Azeem Bande-Ali&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/import-js/eslint-plugin-import"&gt;eslint-plugin-import&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/standard/eslint-config-standard"&gt;eslint-config-standard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;In our upcoming article, we'll delve deep into the inner workings of PURISTA's build pipeline. Stay tuned for an in-depth exploration!&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>programming</category>
      <category>opensource</category>
      <category>coding</category>
    </item>
    <item>
      <title>The power of PURISTA TypeScript Framework v1.7</title>
      <dc:creator>Sebastian Wessel</dc:creator>
      <pubDate>Thu, 01 Jun 2023 14:09:29 +0000</pubDate>
      <link>https://dev.to/purista/the-power-of-purista-typescript-framework-v17-k25</link>
      <guid>https://dev.to/purista/the-power-of-purista-typescript-framework-v17-k25</guid>
      <description>&lt;p&gt;Are you looking for a robust and versatile framework to streamline your application development process? &lt;br&gt;
Look no further than PURISTA TypeScript Framework v1.7! &lt;/p&gt;

&lt;p&gt;With its latest release, PURISTA introduces a range of exciting features and improvements that empower developers to build efficient and scalable applications.&lt;br&gt;
Let's explore how PURISTA v1.7 can revolutionize your development workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seamless Messaging with NATS
&lt;/h2&gt;

&lt;p&gt;Communication between microservices is essential for building complex applications.&lt;/p&gt;

&lt;p&gt;PURISTA v1.7 integrates &lt;a href="https://nats.io"&gt;NATS&lt;/a&gt;, a lightweight and high-performance messaging system, as a message broker option.&lt;br&gt;&lt;br&gt;
This integration simplifies message transmission and enhances the overall messaging capabilities of your application.&lt;br&gt;&lt;br&gt;
Say goodbye to communication bottlenecks and hello to seamless microservice interactions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enhanced State and Configuration Management
&lt;/h2&gt;

&lt;p&gt;PURISTA v1.7 introduces two powerful features for state and configuration management.&lt;/p&gt;

&lt;p&gt;The NATS State Store allows you to store and retrieve application-specific data within the JetStream enabled NATS server.&lt;br&gt;&lt;br&gt;
This feature enables efficient state management and simplifies data access, resulting in improved performance and scalability.&lt;/p&gt;

&lt;p&gt;In addition, the NATS Config Store provides a centralized solution for managing configuration data in your JetStream enabled NATS server.&lt;br&gt;&lt;br&gt;
Store and retrieve application configurations effortlessly, ensuring consistency and flexibility across your deployment environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But that's not all!&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
PURISTA v1.7 also offers &lt;a href="https://redis.io"&gt;Redis&lt;/a&gt; Config Store integration, leveraging the robustness and speed of Redis to manage your application configurations effectively.&lt;br&gt;&lt;br&gt;
With multiple options for configuration storage, you have the freedom to choose the solution that best fits your needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enhanced Security with Infisical Secret Store
&lt;/h2&gt;

&lt;p&gt;Data security is paramount in modern applications.&lt;br&gt;&lt;br&gt;
PURISTA v1.7 introduces the &lt;a href="https://infisical.com"&gt;Infisical Secret Store&lt;/a&gt; feature, providing a secure vault for storing and accessing sensitive information.&lt;br&gt;&lt;br&gt;
Safeguard your API keys, authentication tokens, and other confidential data with ease.&lt;br&gt;&lt;br&gt;
Rest easy knowing your application's secrets are protected by PURISTA's robust security measures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking Changes for Enhanced Messaging
&lt;/h2&gt;

&lt;p&gt;PURISTA v1.7 brings significant improvements to the messaging structure.&lt;br&gt;&lt;br&gt;
Previously, messages only contained the instanceId of the sender.&lt;br&gt;&lt;br&gt;
However, with the latest release, PURISTA enhances the messaging architecture by moving the instanceId of the sender to the sender property.&lt;br&gt;&lt;br&gt;
Additionally, the instanceId of the receiver (if available) is now included in the receiver property.&lt;br&gt;&lt;br&gt;
This change simplifies subscription targeting and eliminates the need for redundant message publications, resulting in a more efficient and streamlined messaging experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Improved Stability and Documentation
&lt;/h2&gt;

&lt;p&gt;PURISTA v1.7 focuses on improving stability and usability.&lt;br&gt;&lt;br&gt;
The framework comes with a slew of bug fixes, ensuring a smoother development experience.&lt;br&gt;&lt;br&gt;
Additionally, the documentation has been extensively enhanced, providing comprehensive guidance and examples to help you make the most of PURISTA's features. Whether you're a seasoned PURISTA user or new to the framework, the updated documentation serves as a valuable resource for mastering the framework's capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embrace PURISTA TypeScript Framework v1.7 Today
&lt;/h2&gt;

&lt;p&gt;If you're looking to build robust, scalable, and efficient applications, PURISTA TypeScript Framework v1.7 is your ultimate solution.&lt;br&gt;&lt;br&gt;
Harness the power of NATS as a message broker, leverage state and configuration management features, ensure data security with the Infisical Secret Store, and benefit from the enhanced messaging structure.&lt;br&gt;&lt;br&gt;
Take advantage of the improved stability and comprehensive documentation to accelerate your development process.&lt;/p&gt;

&lt;p&gt;Visit the official PURISTA website &lt;a href="https://purista.dev"&gt;purista.dev&lt;/a&gt; to learn more about PURISTA v1.7 and embark on a new era of application development. &lt;br&gt;
Unleash your creativity, enhance collaboration, and deliver exceptional software solutions with PURISTA TypeScript Framework v1.7.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>backend</category>
      <category>framework</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
