<?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: Mehrad Rousta</title>
    <description>The latest articles on DEV Community by Mehrad Rousta (@mehrad77).</description>
    <link>https://dev.to/mehrad77</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%2F76721%2F9838c291-1041-4132-9866-5a04c2ec44dc.jpg</url>
      <title>DEV Community: Mehrad Rousta</title>
      <link>https://dev.to/mehrad77</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mehrad77"/>
    <language>en</language>
    <item>
      <title>Have an offline version of a website</title>
      <dc:creator>Mehrad Rousta</dc:creator>
      <pubDate>Thu, 02 Apr 2020 15:57:48 +0000</pubDate>
      <link>https://dev.to/mehrad77/have-an-offline-version-of-a-website-1ml9</link>
      <guid>https://dev.to/mehrad77/have-an-offline-version-of-a-website-1ml9</guid>
      <description>&lt;p&gt;Originally posted at &lt;a href="https://jourlog.xyz/blog/have-an-offline-version-of-a-website"&gt;my blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At the beginning of 2017, &lt;a href="https://irandestina.github.io/website/index.html%3Fp=1269.html"&gt;Shamim&lt;/a&gt;, &lt;a href="https://irandestina.github.io/website/index.html%3Fp=1273.html"&gt;Maryam&lt;/a&gt;, and &lt;a href="https://likeaswallow.com/"&gt;Parastoo&lt;/a&gt; met each other at the university, when they were passing master of tourism management course. Years of friendship and traveling made them closer to each other. And one day they decided to share this wonderful feeling with others. the result was &lt;a href="https://irandestina.github.io/website/"&gt;Irandestina group&lt;/a&gt;. Irandestina was the space to experience the good filling of traveling. friendly, creative and adventurous trips with respect to the environment and the lives of host communities. later they've also pivoted to accessible tourism but with the fall of Iran economy now 2 of them are migrated and Irandestina stopped here.&lt;/p&gt;

&lt;p&gt;then around July of 2019 Parastoo asked me if I can find a way to keep Irandestina website content without the need to pay for hosting. and I said "Yes!". my plan was to download the whole website and put it over &lt;strong&gt;Github/Gitlab Pages&lt;/strong&gt; for free and point the domain to there too.&lt;/p&gt;

&lt;p&gt;I remembered as a child there was some softwares on windows OS to do that. so we had a Dial-up connection and sometimes I would download all of a website so I won't need Internet access to browse it. but now I was on Linux and knew there must be an easier way to do this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Wget"&gt;&lt;em&gt;And it is! it's called &lt;strong&gt;WGET&lt;/strong&gt;!&lt;/em&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;wget &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--recursive&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--no-clobber&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--page-requisites&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--html-extension&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--convert-links&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--domains&lt;/span&gt; irandestina.com &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;--no-parent&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
         www.irandestina.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;all you I had to do was this.&lt;/p&gt;

&lt;p&gt;The options are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;--recursive:&lt;/strong&gt; the most important flag, download sub URLs in given address.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--domains irandestina.com:&lt;/strong&gt; don't follow links outside irandestina.com.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--no-parent:&lt;/strong&gt; don't follow the links outside of provided URL, can b used to download only one sub URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--page-requisites:&lt;/strong&gt; get all the elements (images, CSS, JS and others) of the page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--html-extension:&lt;/strong&gt; save files with the .html extension.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--convert-links:&lt;/strong&gt; convert HTML links to local version so site is navigable offline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;--no-clobber:&lt;/strong&gt; don't overwrite the already downloaded files (used when the download is interrupted and resumed).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;for more options you can check out &lt;a href="https://www.gnu.org/software/wget/manual/html_node/Recursive-Retrieval-Options.html"&gt;it's manual page&lt;/a&gt;. also &lt;a href="https://www.thegeekstuff.com/2009/09/the-ultimate-wget-download-guide-with-15-awesome-examples/"&gt;read more at thegeekstuff.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;so now let's ship this static website we just downloaded. I hope you know how to work with Git. create a new repository, go inside the downloaded directory and do this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add *&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit -m "add static content"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git remote add origin git@github.com:m[REPOSITORY ADDRESS]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push -u origin master&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;great! now open the repository setting and make the &lt;code&gt;master&lt;/code&gt; branch the Source for Github Pages. you can also add a &lt;code&gt;cname&lt;/code&gt; file to the repo so you can have your custom domain. &lt;a href="https://help.github.com/en/github/working-with-github-pages/configuring-a-custom-domain-for-your-github-pages-site"&gt;read more at Github Help.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--UswxL0eE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jourlog.xyz/assets/2020/github-pages.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UswxL0eE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jourlog.xyz/assets/2020/github-pages.jpg" alt="image-20200402172636792"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>wget</category>
      <category>staticwebsites</category>
    </item>
    <item>
      <title>Nested Queries in Prisma Client </title>
      <dc:creator>Mehrad Rousta</dc:creator>
      <pubDate>Wed, 06 Nov 2019 03:03:26 +0000</pubDate>
      <link>https://dev.to/mehrad77/how-to-query-subfields-in-prisma-client-4i1d</link>
      <guid>https://dev.to/mehrad77/how-to-query-subfields-in-prisma-client-4i1d</guid>
      <description>&lt;p&gt;These days I'm working on a new project in the workplace which is the first project I work on that is built on Prisma and Yoga. I worked with Prisma before on the days that the only way to access Prisma was &lt;a href="https://www.prisma.io/features/bindings"&gt;Prisma Bindings&lt;/a&gt;. but at this new project, we were using &lt;a href="https://www.prisma.io/docs/prisma-client/"&gt;Prisma Client&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Imagine this project we have here is a social media app with these models:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;type User {
  id: ID! @id
  email: String! @unique
  password: String!
  username: String @unique
  fullName: String!
  role: [UserRole]!
  settings: UserSetting @relation(name: "UserSettings" link: INLINE)
  following: [User] @relation(name: "UserFollowings" link: INLINE)
  createdAt: DateTime! @createdAt
  updatedAt: DateTime! @updatedAt
}

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



&lt;p&gt;As it's &lt;a href="https://www.prisma.io/forum/t/query-returns-null-when-query-to-the-prisma-server-works/7092"&gt;mentioned here&lt;/a&gt; and &lt;a href="https://www.prisma.io/forum/t/how-to-write-nested-relation-connection-subfield-resolvers/3768"&gt;here&lt;/a&gt;, with Prisma Bindings we could use something like this for our queries to get all the nested queries we wanted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Prisma Bindings&lt;/span&gt;
&lt;span class="nx"&gt;me&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getUserId&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;prisma&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userId&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nx"&gt;info&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;which by passing &lt;code&gt;info&lt;/code&gt;, the Prisma query would notice what fields it must fetch from the database. &lt;/p&gt;

&lt;p&gt;but when I was looking in my code, my Prisma query only had one parameter which was the filter/sort object. so I handled it this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Prisma Client&lt;/span&gt;
 &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="c1"&gt;// Getting userSettings because apparently `ctx.db.user` won't give it&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;userSettings&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userSettings&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userSettings&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;But there is a problem, this method is ok on single queries but won't work on list queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&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;In my front-end, when I was using this &lt;code&gt;users&lt;/code&gt; query, I wasn't getting for example &lt;code&gt;user.following&lt;/code&gt; relational data. &lt;/p&gt;

&lt;p&gt;the workaround for this is &lt;strong&gt;&lt;code&gt;$fragment&lt;/code&gt; API&lt;/strong&gt; explained in &lt;a href="https://www.prisma.io/docs/prisma-client/basic-data-access/reading-data-JAVASCRIPT-rsc2/#selecting-fields"&gt;Prisma docs&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Instead of querying all scalar fields of a record (which is the default behavior), you can specify which fields you'd like to retrieve by using the $fragment API. This is useful to exclude large unneeded fields (like BLOB values or huge strings). It also lets you fetch arbitrary relations.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;so the code would be rewritten like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fragment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
    fragment UserWithFollowings on User {
      id
      fullName
      email
      following {
        id
        email
      }
    }
  `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;$fragment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fragment&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;The docs is saying there will be a &lt;em&gt;next version of the Prisma client API that has an improved and type-safe API to select fields&lt;/em&gt; but I couldn't find more information about it. if you have any information about it and want to share, i would be very happy!&lt;/p&gt;

</description>
      <category>prisma</category>
      <category>graphql</category>
    </item>
  </channel>
</rss>
