<?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: Michal Bryxí</title>
    <description>The latest articles on DEV Community by Michal Bryxí (@michalbryxi).</description>
    <link>https://dev.to/michalbryxi</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%2F56039%2F53e1a70f-faf9-4fb9-bb44-bc0e7f00501c.png</url>
      <title>DEV Community: Michal Bryxí</title>
      <link>https://dev.to/michalbryxi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/michalbryxi"/>
    <language>en</language>
    <item>
      <title>ember-template-lint recommended rules that I disable</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Tue, 05 Aug 2025 16:49:09 +0000</pubDate>
      <link>https://dev.to/michalbryxi/ember-template-lint-recommended-rules-that-i-disable-3ne5</link>
      <guid>https://dev.to/michalbryxi/ember-template-lint-recommended-rules-that-i-disable-3ne5</guid>
      <description>&lt;p&gt;&lt;a href="https://emberjs.com" rel="noopener noreferrer"&gt;EmberJS&lt;/a&gt; comes with great set of default tooling. One of them is &lt;a href="https://github.com/ember-template-lint/ember-template-lint" rel="noopener noreferrer"&gt;ember-template-lint&lt;/a&gt; which helps making sure that our &lt;code&gt;*.hbs&lt;/code&gt;, &lt;code&gt;*.gjs&lt;/code&gt; and &lt;code&gt;*.gts&lt;/code&gt; files are following one format.&lt;/p&gt;

&lt;p&gt;Sadly template-linter has no awareness of JS-scope at the moment and so sometimes it complains about things that are not really an issue.&lt;/p&gt;

&lt;p&gt;I'm a big fan of &lt;a href="https://frontile.dev/docs/forms/input" rel="noopener noreferrer"&gt;frontile.dev&lt;/a&gt; for my forms and so I use their &lt;code&gt;&amp;lt;Input /&amp;gt;&lt;/code&gt; element a lot. This confuses template linter which shouts at me various not so helpful things. So I found out that following set of "recommended" rules is actually good to disable:&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="c1"&gt;// template-lintrc.js&lt;/span&gt;

&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;use strict&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;recommended&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;rules&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;require-input-label&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-builtin-form-components&lt;/span&gt;&lt;span class="dl"&gt;'&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-unknown-arguments-for-builtin-components&lt;/span&gt;&lt;span class="dl"&gt;'&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="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ember</category>
      <category>linting</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Swiss trail closures in Locus</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Mon, 07 Apr 2025 19:05:11 +0000</pubDate>
      <link>https://dev.to/michalbryxi/swiss-trail-closures-to-locus-3e71</link>
      <guid>https://dev.to/michalbryxi/swiss-trail-closures-to-locus-3e71</guid>
      <description>&lt;p&gt;&lt;a href="https://www.locusmap.app/" rel="noopener noreferrer"&gt;Locus&lt;/a&gt; is the mapping app of choice for me for &lt;em&gt;any&lt;/em&gt; use-case on &lt;a href="https://www.android.com" rel="noopener noreferrer"&gt;Android&lt;/a&gt; and for most use-cases on desktop as well.&lt;/p&gt;

&lt;p&gt;Although Locus does have &lt;a href="https://www.locusmap.app/free-swisstopo-maps-and-other-news-in-the-current-locus-map-4-3/" rel="noopener noreferrer"&gt;Swisstopo layers&lt;/a&gt;, it does &lt;em&gt;not&lt;/em&gt; have direct access to some of the extra &lt;a href="https://en.wikipedia.org/wiki/Web_Map_Service" rel="noopener noreferrer"&gt;WMS layers&lt;/a&gt; that are provided by the Swiss authorities.&lt;/p&gt;

&lt;p&gt;This specifically hit me back when I planned my hike (using Locus) through a &lt;a href="https://map.geo.admin.ch/#/map?lang=de&amp;amp;center=2632104.19,1173080.25&amp;amp;z=5&amp;amp;topic=ech&amp;amp;layers=ch.swisstopo.zeitreihen@year=1864,f;ch.bfs.gebaeude_wohnungs_register,f;ch.bav.haltestellen-oev,f;ch.swisstopo.swisstlm3d-wanderwege,f;ch.vbs.schiessanzeigen,f;ch.astra.wanderland-sperrungen_umleitungen&amp;amp;bgLayer=ch.swisstopo.pixelkarte-farbe" rel="noopener noreferrer"&gt;Sperrungen Wanderwege&lt;/a&gt; (closed trails), because I did not see those trails as (temporarily) closed on Locus.&lt;/p&gt;

&lt;p&gt;The solution for this is to &lt;a href="https://docs.locusmap.app/doku.php?id=manual:user_guide:maps_wms" rel="noopener noreferrer"&gt;add a WMS layer to Locus&lt;/a&gt; using following URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://wms.geo.admin.ch? SERVICE=WMS&amp;amp;VERSION=1.3.0&amp;amp;REQUEST=GetMap&amp;amp;layers=ch.astra.wanderland-sperrungen_umleitungen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The argument &lt;code&gt;layers=ch.astra.wanderland-sperrungen_umleitungen&lt;/code&gt; is there so that we're importing only the trail closures layer. Otherwise there will be hundreds of them. List of &lt;a href="https://api3.geo.admin.ch/api/faq/index.html#which-layers-are-available" rel="noopener noreferrer"&gt;all available WMS layers for geo.admin.ch&lt;/a&gt; is a useful reference.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmmydl8riuck3baj46a5z.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmmydl8riuck3baj46a5z.jpeg" alt="Locus map with geo.admin.ch layer for wanderland-sperrungen_umleitungen" width="576" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>locus</category>
      <category>swisstopo</category>
      <category>maps</category>
    </item>
    <item>
      <title>Embroider &amp; Vite &amp; net::ERR_ABORTED 504 (Outdated Optimize Dep)</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Sun, 30 Mar 2025 15:38:13 +0000</pubDate>
      <link>https://dev.to/michalbryxi/embroider-vite-neterraborted-504-outdated-optimize-dep-4c90</link>
      <guid>https://dev.to/michalbryxi/embroider-vite-neterraborted-504-outdated-optimize-dep-4c90</guid>
      <description>&lt;p&gt;While working on &lt;a href="https://emberjs.com" rel="noopener noreferrer"&gt;EmberJS&lt;/a&gt; projects, I've been using pre-alpha version of &lt;a href="https://github.com/embroider-build/app-blueprint" rel="noopener noreferrer"&gt;@embroider/app-blueprint&lt;/a&gt; quite a lot lately and I hit a baffling error:&lt;/p&gt;

&lt;p&gt;1) App builds and everything works&lt;br&gt;
2) Sometimes, when the dev server is restarted (&lt;code&gt;ctrl+c&lt;/code&gt; &amp;amp; &lt;code&gt;pnpm start&lt;/code&gt;), the network tab of the app fails many requests with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET
http://localhost:4200/node_modules/.vite/deps/ember-source_@ember_application_index__js.js?v=4536db21
net::ERR_ABORTED 504 (Outdated Optimize Dep)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Nothing helps: Wiping &lt;code&gt;node_modules&lt;/code&gt;; Setting the server to run with &lt;code&gt;vite --force&lt;/code&gt;; Getting earlier versions of the app;&lt;br&gt;
4) Sometimes everything builds fine and I can develop without any issue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0e6rggbhzjhzjsx882n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl0e6rggbhzjhzjsx882n.png" alt="Image description" width="800" height="790"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I discussed &lt;a href="https://discord.com/channels/480462759797063690/568935504288940056/1355811390450958356" rel="noopener noreferrer"&gt;this very issue on EmberJS Discord&lt;/a&gt; and was pointed to pay attention at the console build errors, which actually &lt;em&gt;did&lt;/em&gt; have some weird messages in it. I just never paid attention, because initially everything built fine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pnpm start

&amp;gt; nuudel-to-ics@0.0.0 start /Users/michal/pudr.com/nuudel-to-ics
&amp;gt; vite --force

- Building

Environment: development

- Building

- building... 



Build successful (276ms)

9:45:36 AM [vite] (client) Forced re-optimization of dependencies

Slowest Nodes (totalTime &amp;gt;= 5%) | Total (avg)
-+-
Babel: ember-tracked-storage-polyfill (1) | 115ms
Funnel (109) | 33ms (0 ms)
BroccoliMergeTrees (202) | 31ms (0 ms)
Babel: ember-intl (2) | 21ms (10 ms)
@embroider/compat/addons (1) | 15ms



  VITE v6.2.3  ready in 2638 ms

  ➜  Local:   http://localhost:4200/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
✘ [ERROR] Cannot read file: /Users/michal/pudr.com/nuudel-to-ics/node_modules/.pnpm/object-inspect@1.13.4/node_modules/object-inspect/util.inspect

    node_modules/.pnpm/object-inspect@1.13.4/node_modules/object-inspect/index.js:54:26:
      54 │ var utilInspect = require('./util.inspect');
         ╵                           ~~~~~~~~~~~~~~~~

9:45:44 AM [vite] (client) error while updating dependencies:
Error: Build failed with 1 error:
node_modules/.pnpm/object-inspect@1.13.4/node_modules/object-inspect/index.js:54:26: ERROR: Cannot read file: /Users/michal/pudr.com/nuudel-to-ics/node_modules/.pnpm/object-inspect@1.13.4/node_modules/object-inspect/util.inspect
    at failureErrorWithLog (/Users/michal/pudr.com/nuudel-to-ics/node_modules/.pnpm/esbuild@0.25.1/node_modules/esbuild/lib/main.js:1477:15)
    at /Users/michal/pudr.com/nuudel-to-ics/node_modules/.pnpm/esbuild@0.25.1/node_modules/esbuild/lib/main.js:946:25
    at /Users/michal/pudr.com/nuudel-to-ics/node_modules/.pnpm/esbuild@0.25.1/node_modules/esbuild/lib/main.js:1355:9
    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now the issue is actually about &lt;code&gt;✘ [ERROR] Cannot read file: /Users/michal/pudr.com/nuudel-to-ics/node_modules/.pnpm/object-inspect@1.13.4/node_modules/object-inspect/util.inspect&lt;/code&gt; resp. the package &lt;code&gt;object-inspect&lt;/code&gt; itself. And the advice I got is to &lt;a href="https://vite.dev/config/dep-optimization-options" rel="noopener noreferrer"&gt;exclude it from optimisations&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So that's what I did by adding few lines to &lt;code&gt;vite.config.mjs&lt;/code&gt;:&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="c1"&gt;// vite.config.mjs&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;optimizeDeps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;exclude&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;object-inspect&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;And since then the app builds and I seem to never get this error.&lt;/p&gt;

</description>
      <category>ember</category>
      <category>vite</category>
      <category>embroider</category>
    </item>
    <item>
      <title>How to disable ember/no-empty-glimmer-component-classes</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Sat, 29 Mar 2025 12:46:47 +0000</pubDate>
      <link>https://dev.to/michalbryxi/how-to-disable-emberno-empty-glimmer-component-classes-5fnc</link>
      <guid>https://dev.to/michalbryxi/how-to-disable-emberno-empty-glimmer-component-classes-5fnc</guid>
      <description>&lt;p&gt;Well technically in any &lt;code&gt;*.js/*.ts&lt;/code&gt; file, but my 🧠 just got stuck on "this has to be part of ember-template-lint config", because I've seen a component that is basically &lt;em&gt;just HTML&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;At the end of the day, the linter rule is about &lt;em&gt;JavaScript&lt;/em&gt; classes.&lt;/p&gt;

&lt;p&gt;So if anyone bumps into this, the answer is NOT to put the config in &lt;code&gt;.template-lintrc.js&lt;/code&gt;, but to &lt;code&gt;eslint.config.mjs&lt;/code&gt; (or equivalent), in following way:&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="c1"&gt;// eslint.config.mjs&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;files&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;**/*.{ts,gts}&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;languageOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ember&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;parserOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parserOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;esm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;ts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;recommendedTypeChecked&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ember&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gts&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;rules&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;ember/no-empty-glimmer-component-classes&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="s1"&gt;off&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="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ember</category>
      <category>linting</category>
      <category>eslint</category>
    </item>
    <item>
      <title>ResponsiveImage &amp; EmberJS &amp; glob vite imports</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Fri, 07 Mar 2025 10:08:18 +0000</pubDate>
      <link>https://dev.to/michalbryxi/responsiveimage-emberjs-glob-vite-imports-o9i</link>
      <guid>https://dev.to/michalbryxi/responsiveimage-emberjs-glob-vite-imports-o9i</guid>
      <description>&lt;p&gt;&lt;a href="https://responsive-image.dev" rel="noopener noreferrer"&gt;ResponsiveImage&lt;/a&gt; is a:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Multi-framework JavaScript library for responsive images.  Responsive images made easy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://github.com/embroider-build/app-blueprint" rel="noopener noreferrer"&gt;embroider-build/app-blueprint&lt;/a&gt; is a:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Very experimental blueprint for scaffolding Ember v2 apps with Vite.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I had a need to &lt;strong&gt;dynamically&lt;/strong&gt; load a folder images in my &lt;a href="https://emberjs.com" rel="noopener noreferrer"&gt;EmberJS app&lt;/a&gt; that is using &lt;code&gt;embroider-build/app-blueprint&lt;/code&gt; and &lt;code&gt;ResponsiveImage&lt;/code&gt;. Turns out I could use &lt;a href="https://vite.dev/guide/features.html#glob-import" rel="noopener noreferrer"&gt;vite glob imports&lt;/a&gt; and resulting code looked something like:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Component&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;@glimmer/component&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;ResponsiveImage&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;@responsive-image/ember&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;images&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;values&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;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;glob&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/photos/*.jpg&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="na"&gt;eager&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;query&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;?lqip=inline&amp;amp;widths=1920,1280,640&amp;amp;responsive&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;import&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;default&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;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyComponent&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;each&lt;/span&gt; &lt;span class="nx"&gt;images&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ResponsiveImage&lt;/span&gt;
          &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;src&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="nx"&gt;image&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
        &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;{{&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;}}&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/template&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ember</category>
      <category>vite</category>
      <category>responsiveimage</category>
    </item>
    <item>
      <title>How I Manage Node &amp; Package Manager Versions in 2025</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Thu, 23 Jan 2025 06:53:03 +0000</pubDate>
      <link>https://dev.to/michalbryxi/how-i-manage-node-package-manager-versions-in-2025-97d</link>
      <guid>https://dev.to/michalbryxi/how-i-manage-node-package-manager-versions-in-2025-97d</guid>
      <description>&lt;p&gt;Some time has passed since I wrote &lt;a href="https://dev.to/michalbryxi/how-am-i-managing-node-package-manager-versions-3904"&gt;How I Manage Node &amp;amp; Package Manager Versions in 2024&lt;/a&gt; and few things have changed. So let's see what has changed and what are still goals:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Things works seamlessly. I switch projects = correct (versions) of tools are automatically used.&lt;/li&gt;
&lt;li&gt;Minimal process to setup new projects is needed.&lt;/li&gt;
&lt;li&gt;Local development environment and CI use the same ways to ensure consistency.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My stack of choice is &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;node&lt;/a&gt; and &lt;a href="https://pnpm.io" rel="noopener noreferrer"&gt;pnpm&lt;/a&gt;, but this should work for most commonly used tools.&lt;/p&gt;

&lt;p&gt;In the past I've used &lt;a href="https://github.com/nvm-sh/nvm" rel="noopener noreferrer"&gt;nvm&lt;/a&gt;, &lt;a href="https://github.com/tj/n" rel="noopener noreferrer"&gt;n&lt;/a&gt;, &lt;a href="https://volta.sh" rel="noopener noreferrer"&gt;volta&lt;/a&gt;, &lt;a href="https://github.com/nodejs/corepack" rel="noopener noreferrer"&gt;corepack&lt;/a&gt;, &lt;a href="https://ekalinin.github.io/nodeenv/" rel="noopener noreferrer"&gt;nodeenv&lt;/a&gt;. While they all have their own strength, I converged to using &lt;a href="https://moonrepo.dev/proto" rel="noopener noreferrer"&gt;proto&lt;/a&gt; as the tool of choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;If possible, remove all previously versions of &lt;code&gt;node&lt;/code&gt; or &lt;code&gt;pnpm&lt;/code&gt; to make sure no conflicts occur.&lt;/li&gt;
&lt;li&gt;Install &lt;code&gt;proto&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; brew &lt;span class="nb"&gt;install &lt;/span&gt;proto
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; proto setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Project setup
&lt;/h2&gt;

&lt;p&gt;Once you're in your &lt;code&gt;my-app&lt;/code&gt; directory, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; proto pin node 20.18.0
&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; proto pin pnpm 9.14.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will create &lt;code&gt;my-app/.prototools&lt;/code&gt; file with equivalent content, which can be commited to the repo to ensure that every single machine uses the same tool versions when running &lt;code&gt;my-app&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="py"&gt;node&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"20.18.0"&lt;/span&gt;
&lt;span class="py"&gt;pnpm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"9.14.2"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And this setup will be automatically honoured every time you run &lt;code&gt;node&lt;/code&gt; or &lt;code&gt;pnpm&lt;/code&gt; commands inside your project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; node &lt;span class="nt"&gt;--version&lt;/span&gt;
v20.18.0

&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; pnpm &lt;span class="nt"&gt;--version&lt;/span&gt;
9.14.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>node</category>
      <category>pnpm</category>
      <category>proto</category>
    </item>
    <item>
      <title>Unlocking your SSH key through OSX keychain</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Fri, 08 Nov 2024 19:02:15 +0000</pubDate>
      <link>https://dev.to/michalbryxi/unlocking-your-ssh-key-through-osx-keychain-fj4</link>
      <guid>https://dev.to/michalbryxi/unlocking-your-ssh-key-through-osx-keychain-fj4</guid>
      <description>&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Using &lt;a href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/working-with-ssh-key-passphrases" rel="noopener noreferrer"&gt;passphrases for SSH keys&lt;/a&gt; is a very good idea, but since UX is inherent part of security I would advise on &lt;a href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/working-with-ssh-key-passphrases" rel="noopener noreferrer"&gt;adding your SSH key to the ssh-agent&lt;/a&gt; to prevent password re-type fatigue &amp;amp; mishaps.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;Follow along the documents above or try this shortened version:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add following line to your &lt;code&gt;~/.zshrc&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh-add &lt;span class="nt"&gt;--apple-use-keychain&lt;/span&gt; ~/.ssh/id_rsa 2&amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add following lines to yours &lt;code&gt;~/.ssh/config&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Host &lt;span class="k"&gt;*&lt;/span&gt;
    UseKeychain &lt;span class="nb"&gt;yes
    &lt;/span&gt;AddKeysToAgent &lt;span class="nb"&gt;yes
    &lt;/span&gt;IdentityFile ~/.ssh/id_rsa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>ssh</category>
      <category>osx</category>
    </item>
    <item>
      <title>Microsoft 365 Outlook calendar in Todoist</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Fri, 08 Nov 2024 13:14:00 +0000</pubDate>
      <link>https://dev.to/michalbryxi/microsoft-365-outlook-calendar-in-todoist-5gbl</link>
      <guid>https://dev.to/michalbryxi/microsoft-365-outlook-calendar-in-todoist-5gbl</guid>
      <description>&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;At the time of writing this article, one can &lt;a href="https://todoist.com/help/articles/use-the-calendar-integration-rCqwLCt3G#h_01HXS15SKB1BTJDPEGCG6GCQB0" rel="noopener noreferrer"&gt;connect &lt;em&gt;only one&lt;/em&gt; calendar provided by only one company (Google) to Todoist&lt;/a&gt;. So if you want to connect &lt;em&gt;Microsoft 365 Outlook&lt;/em&gt; calendar or second &lt;em&gt;Google Calendar&lt;/em&gt;, you're out of luck.&lt;/p&gt;

&lt;p&gt;There is, however, a trick that one can use to make both of the cases above work.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;First make sure that one of your &lt;a href="https://todoist.com/help/articles/use-the-calendar-integration-rCqwLCt3G#h_01HXS0VCY6C5VKNADNE10DA0QV" rel="noopener noreferrer"&gt;Google Calendars is connected to your Todoist account&lt;/a&gt;. We will call it a &lt;em&gt;Primary Google Calendar&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  For Microsoft 365 Outlook
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In Microsoft 365 Outlook find the calendar you want to share, and select &lt;strong&gt;Sharing and permissions&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm4mie3f5tp92p2l29wet.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm4mie3f5tp92p2l29wet.png" alt=" Microsoft 365 Outlook " width="385" height="348"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Send the invite to your &lt;em&gt;Primary Google Calendar account&lt;/em&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxvwlyl6ivbp3wje2xecj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxvwlyl6ivbp3wje2xecj.png" alt="Microsoft 365 Outlook sharing screen" width="686" height="567"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After that you will receive an email inviting you to said calendar. Click on &lt;strong&gt;Accept and view calendar&lt;/strong&gt; button.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New page opens and you should see &lt;strong&gt;Add calendar&lt;/strong&gt; modal. When you select &lt;strong&gt;Subscribe from web&lt;/strong&gt; you should be able to see an input box with &lt;code&gt;webcal://...&lt;/code&gt; URI. This will be your &lt;em&gt;New Calendar&lt;/em&gt; in next steps.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpz5nm3h5si8t3bcd3t04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpz5nm3h5si8t3bcd3t04.png" alt="Microsoft 365 Outlook Add Calendar modal" width="800" height="569"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;As described in the &lt;a href="https://support.google.com/calendar/answer/37100?hl=en&amp;amp;co=GENIE.Platform=Desktop" rel="noopener noreferrer"&gt;use a link to add a public calendar documentation&lt;/a&gt; one has to: Open Primary Google Calendar and then on the left, next to &lt;strong&gt;Other calendars,&lt;/strong&gt; click on the little &lt;strong&gt;+&lt;/strong&gt; symbol and then select &lt;strong&gt;From URL&lt;/strong&gt;:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zpixhz26seo644y5xzo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0zpixhz26seo644y5xzo.png" alt="Google calendar add other calendar select box" width="388" height="233"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fill in your New Calendar URI into the &lt;strong&gt;From URL&lt;/strong&gt; input box and hit &lt;strong&gt;Add calendar&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  For 2nd Google Calendar
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Following the &lt;a href="https://support.google.com/calendar/answer/37100?hl=en&amp;amp;co=GENIE.Platform=Desktop" rel="noopener noreferrer"&gt;ask to subscribe to calendar&lt;/a&gt; help page make sure that your 2nd calendar is shared to your Primary Google Calendar. This will be your &lt;em&gt;New Calendar&lt;/em&gt; in next steps.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Displaying New Calendar in your Todoist
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;Settings -&amp;gt; Calendars -&amp;gt; Show events in Todoist&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Find your New Calendar and toggle the little eye icon on the right.&lt;/li&gt;
&lt;li&gt;After this you should be able to see your New Calendar in Todoist:
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5neits28lao525vx8xmd.png" alt="Example of second calendar being shown in Todoist" width="506" height="630"&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>todoist</category>
      <category>googlecalendar</category>
      <category>outlook</category>
    </item>
    <item>
      <title>OSX Sequoia &amp; Operation not permitted (os error 1)</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Fri, 01 Nov 2024 15:52:00 +0000</pubDate>
      <link>https://dev.to/michalbryxi/osx-sequoia-operation-not-permitted-os-error-1-n6b</link>
      <guid>https://dev.to/michalbryxi/osx-sequoia-operation-not-permitted-os-error-1-n6b</guid>
      <description>&lt;p&gt;With new, granular set of permission rights comes ... a bit of pain.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;After upgrading to &lt;a href="https://www.apple.com/macos/macos-sequoia/" rel="noopener noreferrer"&gt;OSX Sequoia&lt;/a&gt; my terminal of choice - &lt;a href="https://www.warp.dev" rel="noopener noreferrer"&gt;Warp&lt;/a&gt; started having weird seemingly permission-like issues. Even simple operations like &lt;code&gt;ls&lt;/code&gt; sometimes failed with &lt;code&gt;Operation not permitted (os error 1)&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /Volumes/BACKUP/
&lt;span class="s2"&gt;"/Volumes/BACKUP/"&lt;/span&gt;: Operation not permitted &lt;span class="o"&gt;(&lt;/span&gt;os error 1&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But other apps like &lt;code&gt;Finder&lt;/code&gt; had no problem accessing said folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;Eventually I noticed that the issue happened always when I tried to access data on an &lt;em&gt;USB thumb drive&lt;/em&gt;. Remembering that apps in newer OSX do &lt;em&gt;not&lt;/em&gt; have permission to just access disk willy nilly, I opened: &lt;code&gt;System Settings -&amp;gt; Privacy &amp;amp; Security -&amp;gt; Full Disk Access&lt;/code&gt;, changed the toggle for &lt;code&gt;Warp&lt;/code&gt; to &lt;code&gt;enabled&lt;/code&gt; and let the app reboot. And voila! Now it works again.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4j3a8939zxmdy8mjvbqj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4j3a8939zxmdy8mjvbqj.png" alt="OSX settings - Privacy &amp;amp; Security - Full Disk Access" width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>osx</category>
      <category>sequoia</category>
      <category>warp</category>
    </item>
    <item>
      <title>Installing EmberJS v2 addons from GitHub forks using PNPM</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Mon, 16 Sep 2024 11:54:27 +0000</pubDate>
      <link>https://dev.to/michalbryxi/installing-emberjs-v2-addons-from-github-forks-using-pnpm-556</link>
      <guid>https://dev.to/michalbryxi/installing-emberjs-v2-addons-from-github-forks-using-pnpm-556</guid>
      <description>&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;If you're using &lt;a href="https://pnpm.io/" rel="noopener noreferrer"&gt;PNPM&lt;/a&gt; as a package manager for your &lt;a href="https://emberjs.com/" rel="noopener noreferrer"&gt;EmberJS&lt;/a&gt; project and you find yourself in a need to install a &lt;a href="https://github.com/embroider-build/addon-blueprint" rel="noopener noreferrer"&gt;v2 addon&lt;/a&gt; from git(hub) fork (because you have a branch with patched version), then you might find that &lt;a href="https://dev.to/michalbryxi/github-urls-in-package-json-5412"&gt;GitHub URLs in package.json&lt;/a&gt; tricks don't work for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  The analysis
&lt;/h2&gt;

&lt;p&gt;Reason for this is because &lt;a href="https://github.com/embroider-build/embroider/blob/main/docs/porting-addons-to-v2.md#monorepo-organization" rel="noopener noreferrer"&gt;v2 addons are a monorepo&lt;/a&gt; and we're still in the phase where pretty much every tool out there lacks &lt;em&gt;good&lt;/em&gt; support/DX for monorepos.&lt;/p&gt;

&lt;p&gt;There are different possible solutions for different cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://gitpkg.vercel.app" rel="noopener noreferrer"&gt;gitpkg.vercel.app&lt;/a&gt; - Using sub folders of a repo as yarn/npm dependencies made easy.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://pnpm.io/cli/patch" rel="noopener noreferrer"&gt;pnpm patch&lt;/a&gt; - Prepare a package for patching&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.npmjs.com/package/patch-package" rel="noopener noreferrer"&gt;patch-package&lt;/a&gt; - Lets app authors instantly make and keep fixes to npm dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But if you happen to use &lt;code&gt;PNPM&lt;/code&gt; in your project you might get away with providing &lt;a href="https://github.com/pnpm/pnpm.io/pull/578/files" rel="noopener noreferrer"&gt;a customised git URL&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution
&lt;/h2&gt;

&lt;p&gt;Let's assume I have a patch branch of &lt;a href="https://www.npmjs.com/package/ember-highcharts" rel="noopener noreferrer"&gt;ember-highcharts&lt;/a&gt; that has latest commit of SHA: &lt;code&gt;7995a3e7d2203ce174c39e186acc9257d883bf61&lt;/code&gt;. The web URL is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://github.com/MichalBryxi/ember-highcharts/tree/7995a3e7d2203ce174c39e186acc9257d883bf61
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I can add this patched fork to my project as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm add &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="s1"&gt;'github:MichalBryxi/ember-highcharts#7995a3e7d2203ce174c39e186acc9257d883bf61&amp;amp;path:ember-highcharts'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Where:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;github:&lt;/code&gt; Shorthand for pnpm to know where the code is hosted&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;MichalBryxi&lt;/code&gt; - My github namespace&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ember-highcharts&lt;/code&gt; - Name of the repo (my fork)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;7995a3e7d2203ce174c39e186acc9257d883bf61&lt;/code&gt; - respective commit that contains the patch I'm interested in&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;path:ember-highcharts&lt;/code&gt; - In this v2 addon the ember-highcharts subdirectory contains the &lt;a href="https://github.com/MichalBryxi/ember-highcharts/tree/7995a3e7d2203ce174c39e186acc9257d883bf61/ember-highcharts" rel="noopener noreferrer"&gt;code for the addon&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With &lt;code&gt;PNPM&lt;/code&gt; it is possible to install EmberJS v2 addons, or any other packages living in monorepos, from GitHub forks.&lt;/p&gt;

</description>
      <category>ember</category>
      <category>pnpm</category>
      <category>monorepo</category>
    </item>
    <item>
      <title>Google Photos &amp; undismissable notification in Utilities</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Wed, 11 Sep 2024 12:01:23 +0000</pubDate>
      <link>https://dev.to/michalbryxi/google-photos-utilities-undismissable-notifications-22h6</link>
      <guid>https://dev.to/michalbryxi/google-photos-utilities-undismissable-notifications-22h6</guid>
      <description>&lt;p&gt;There are few things more frustrating than misbehaving tech with easy to reproduce bugs that, for some reason, are ignored for years.&lt;/p&gt;

&lt;p&gt;One of those for me is Google Photos "Utilities notification" that simply keeps re-appearing cards with automated creations that I dismissed twenty times before.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbvkpahv8vbnlqtr888fs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbvkpahv8vbnlqtr888fs.png" alt="Utilities with number one as notification next to it" width="250" height="75"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have the same issue, then you can pop open developer tools console (&lt;code&gt;command + option i&lt;/code&gt;) and paste following code there:&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="nx"&gt;$&lt;/span&gt;&lt;span class="nf"&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;[aria-label="Dismiss"]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;element&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;click&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will find all the "dismiss" buttons on all the cards and press them. You will probably need to do few full page reloads and repeat the command, as Google Photos is even bad at the "infinite scrolling" load implementation, but this alone should save you few dozens of clicks.&lt;/p&gt;

</description>
      <category>googlephotos</category>
      <category>hacks</category>
      <category>fix</category>
    </item>
    <item>
      <title>How I Manage Node &amp; Package Manager Versions in 2024</title>
      <dc:creator>Michal Bryxí</dc:creator>
      <pubDate>Fri, 06 Sep 2024 06:11:23 +0000</pubDate>
      <link>https://dev.to/michalbryxi/how-am-i-managing-node-package-manager-versions-3904</link>
      <guid>https://dev.to/michalbryxi/how-am-i-managing-node-package-manager-versions-3904</guid>
      <description>&lt;h1&gt;
  
  
  The problem
&lt;/h1&gt;

&lt;p&gt;On OSX, when it comes to managing version of things in &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt; world, there are many options &lt;a href="https://github.com/nvm-sh/nvm" rel="noopener noreferrer"&gt;nvm&lt;/a&gt;, &lt;a href="https://github.com/tj/n" rel="noopener noreferrer"&gt;n&lt;/a&gt;, &lt;a href="https://github.com/nodenv/nodenv" rel="noopener noreferrer"&gt;nodenv&lt;/a&gt;, &lt;a href="https://volta.sh/" rel="noopener noreferrer"&gt;volta&lt;/a&gt;, &lt;a href="https://brew.sh/" rel="noopener noreferrer"&gt;homebrew&lt;/a&gt; for NodeJS management and other heap for package manager versions.&lt;/p&gt;

&lt;p&gt;This process in this article tries to achieve &lt;em&gt;only&lt;/em&gt; those things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Things works seamlessly. I switch projects, &lt;em&gt;correct&lt;/em&gt; (versions) of tools are &lt;em&gt;automatically&lt;/em&gt; used.&lt;/li&gt;
&lt;li&gt;Minimal process to setup new projects is needed.&lt;/li&gt;
&lt;li&gt;Local development environment and CI both use the same ways to ensure consistency.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  NodeJS version management
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Homebrew
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;No&lt;/strong&gt;. Although it's super fast, reliable and stable, you will very quickly run into many problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One project needs version A, while other needs version B.&lt;/li&gt;
&lt;li&gt;Your local environment uses A, while CI uses B.&lt;/li&gt;
&lt;li&gt;Switching versions is manual, slow and costly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  nvm, n, nodenv, ...
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Maybe&lt;/strong&gt;. I don't have anything against any of those projects. I just happened to land on the next one. Might work for you just ok.&lt;/p&gt;

&lt;h2&gt;
  
  
  volta
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;. The nice thing about &lt;a href="https://volta.sh/" rel="noopener noreferrer"&gt;volta&lt;/a&gt; is that it's super fast to install, works reliably and lets you know when something is :sus:.&lt;/p&gt;

&lt;h1&gt;
  
  
  Package manager version management
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Corepack
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;No&lt;/strong&gt;. &lt;a href="https://nodejs.org/api/corepack.html" rel="noopener noreferrer"&gt;Corepack&lt;/a&gt; is natively present in Node since version &lt;code&gt;16.9.0&lt;/code&gt;, so more recent systems you won't have to do too much. But as per &lt;a href="https://socket.dev/blog/node-js-takes-steps-towards-removing-corepack" rel="noopener noreferrer"&gt;this blogpost on socket.dev&lt;/a&gt; and &lt;a href="https://github.com/nodejs/node/pull/51981" rel="noopener noreferrer"&gt;this pull request in node&lt;/a&gt; corepack &lt;em&gt;is likely&lt;/em&gt; to be removed from node and additional steps will be necessary to install it.&lt;/p&gt;

&lt;h2&gt;
  
  
  volta
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Yes&lt;/strong&gt;. My package manager of choice &lt;a href="https://pnpm.io/" rel="noopener noreferrer"&gt;pnpm&lt;/a&gt; is &lt;a href="https://docs.volta.sh/advanced/pnpm" rel="noopener noreferrer"&gt;partially supported&lt;/a&gt;, so with a little bit of (temporary) configuration, this is a perfect solution. Also we have to use only &lt;em&gt;one&lt;/em&gt; tool for managing node and package manager versions..&lt;/p&gt;

&lt;h1&gt;
  
  
  The solution
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Prepare
&lt;/h2&gt;

&lt;p&gt;You will need to do these steps only once.&lt;/p&gt;

&lt;p&gt;If you want to follow along, first, you'd want to remove all the other tools you might have installed as there is high chance that they will interfere with your new stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew uninstall pnpm &lt;span class="c"&gt;# do not use brew to manage pnpm&lt;/span&gt;
brew uninstall node &lt;span class="c"&gt;# do not use brew to manage node&lt;/span&gt;
brew uninstall nvm &lt;span class="c"&gt;# do not use nvm/n/nodenv/...&lt;/span&gt;
corepack disable &lt;span class="c"&gt;# do not use corepack&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we will install &lt;a href="https://volta.sh/" rel="noopener noreferrer"&gt;volta&lt;/a&gt; (I will copy&amp;amp;paste below, but better if you just follow the official guide):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://get.volta.sh | bash

volta &lt;span class="nb"&gt;install &lt;/span&gt;node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now to enable &lt;a href="https://pnpm.io/" rel="noopener noreferrer"&gt;PNPM&lt;/a&gt; support in Volta you will need to add &lt;code&gt;VOLTA_FEATURE_PNPM=1&lt;/code&gt; to your environment variables. If you're using &lt;a href="https://www.zsh.org/" rel="noopener noreferrer"&gt;zsh&lt;/a&gt; like me, you might want to add it in following way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# ~/.zshenv&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;VOLTA_FEATURE_PNPM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="c"&gt;# Your new line&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;VOLTA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.volta"&lt;/span&gt; &lt;span class="c"&gt;# Already added by volta installation&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VOLTA_HOME&lt;/span&gt;&lt;span class="s2"&gt;/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="c"&gt;#Already added by volta installation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point most of the manuals will tell you to start a new shell. To prevent stepping on a rake, I would recommend doing a quick system reboot. I think it's worth the little wait.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project modifications
&lt;/h2&gt;

&lt;p&gt;Ton pin down the versions in your project &lt;a href="https://docs.volta.sh/guide/understanding#managing-your-project" rel="noopener noreferrer"&gt;use volta pin command&lt;/a&gt; in directory of your &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;volta pin node@18
volta pin pnpm@9.9.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GitLab CI
&lt;/h2&gt;

&lt;p&gt;I battled a bit with &lt;a href="https://docs.gitlab.com/ee/ci/" rel="noopener noreferrer"&gt;GitLab CI&lt;/a&gt; to make this work nicely, but following should work for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# .gitlab-ci.yml
image: node:18

before_script:
  # There is an ugly catch-22 situation that GitLab CI
  # does not have a good way to modify all the needed
  # environment variables in the correct way
  # and at the right time, so this will have to do.
  - source .gitlab-ci-env.sh

stages:
  - build
  - test

cache:
  paths:
    # Make sure to persist our volta installation 
    # between individual stages.
    - .volta
install_dependencies:
  stage: build
  script:
    - apt-get update
    - apt-get install -y curl
    - curl https://get.volta.sh | bash
    - pnpm install

testing_testing:
  stage: test
  script:
    - pnpm test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then put this file next to &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# .gitlab-ci-env.sh&lt;/span&gt;

&lt;span class="c"&gt;# Enable support for PNPM&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;VOLTA_FEATURE_PNPM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1

&lt;span class="c"&gt;# We want volta to be installed into our project dir,&lt;/span&gt;
&lt;span class="c"&gt;# otherwise GitLab won't be able to cache it.&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;VOLTA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CI_PROJECT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/.volta"&lt;/span&gt;

&lt;span class="c"&gt;# Adjust $PATH so we can call volta executable.&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VOLTA_HOME&lt;/span&gt;&lt;span class="s2"&gt;/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There are many ways to do version management. I &lt;em&gt;think&lt;/em&gt; that this one is the simplest, while allowing the greatest level of flexibility. But happy to adjust the article (already did :)) if someone shows me a better way.&lt;/p&gt;

</description>
      <category>osx</category>
      <category>node</category>
      <category>volta</category>
    </item>
  </channel>
</rss>
