From 6ce3d922be92a3eb5c3f8e964b41d3fcc57bd670 Mon Sep 17 00:00:00 2001 From: JuanM04 Date: Mon, 19 Apr 2021 08:04:06 -0300 Subject: [PATCH 01/77] Added a note about broken symlinks --- app/pages/docs/contributing.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/pages/docs/contributing.mdx b/app/pages/docs/contributing.mdx index 6449a50..ff89efa 100644 --- a/app/pages/docs/contributing.mdx +++ b/app/pages/docs/contributing.mdx @@ -269,3 +269,9 @@ If you run into symlink and EPERM errors when trying to run Preconstruct on Windows, you may need to enable [Windows Developer Mode](https://www.howtogeek.com/292914/what-is-developer-mode-in-windows-10/) so that Preconstruct can create symlinks. + +#### Missing files in Windows + +If you have errors about missing files even after you run `yarn build`, +try cloning again your repository win the configuration `core.symlinks` +set to `true` like this: `git clone -c core.symlinks=true `. From fcf53b24eee8eb56f3513283816e87f6bb25dea7 Mon Sep 17 00:00:00 2001 From: JuanM04 Date: Mon, 19 Apr 2021 08:34:13 -0300 Subject: [PATCH 02/77] Typo in contributing.mdx --- app/pages/docs/contributing.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/contributing.mdx b/app/pages/docs/contributing.mdx index ff89efa..8b2645b 100644 --- a/app/pages/docs/contributing.mdx +++ b/app/pages/docs/contributing.mdx @@ -273,5 +273,5 @@ so that Preconstruct can create symlinks. #### Missing files in Windows If you have errors about missing files even after you run `yarn build`, -try cloning again your repository win the configuration `core.symlinks` +try cloning again your repository with the configuration `core.symlinks` set to `true` like this: `git clone -c core.symlinks=true `. From 00986a812eda0a78c0562afd5f37c7cf5e4a2c3e Mon Sep 17 00:00:00 2001 From: Fatih Altinok Date: Mon, 19 Apr 2021 19:43:10 +0300 Subject: [PATCH 03/77] Improve deploy-vercel.mdx consistency and clarity (#450) --- app/pages/docs/deploy-vercel.mdx | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/app/pages/docs/deploy-vercel.mdx b/app/pages/docs/deploy-vercel.mdx index 05fcab9..77348ae 100644 --- a/app/pages/docs/deploy-vercel.mdx +++ b/app/pages/docs/deploy-vercel.mdx @@ -15,7 +15,7 @@ very expensive database to support any amount of scale. ## Serverless Peculiarities for SQL Databases {#peculiarities} -There are two main issues when it comes to using SQL databases in a +There are three main issues when it comes to using SQL databases in a serverless environment: ### Problem 1: Separate Locations for App and Database {#locations} @@ -35,35 +35,34 @@ outside your API handler (this is the default setup in Blitz apps). This optimizes performance because subsequent requests to the same lambda already have an active database connection. -However, this can result in a large number of idle connections. A larger -number than what your database can support. For reference, the lowest -database tier on Digital Ocean has a limit of 22 connections. +However, this can result in a large number of idle connections, larger +than what your database can support. For reference, the lowest database +tier on Digital Ocean has a limit of 22 connections. -**Solution:** The solution to this problem is to use a connection pool in -front of your database. Pgbouncer is the most popular connection pool for -postgres. Both Digital Ocean and Heroku have a feature to simply add -pgbouncer. +**Solution:** Use a connection pool in front of your database. PgBouncer +is the most popular connection pool for PostgreSQL. Both Digital Ocean and +Heroku have a feature to simply add PgBouncer. ### Problem 3: Database Throughput {#database-throughput} -Pgbouncer for PostgreSQL is advertised as allowing you to have +PgBouncer for PostgreSQL is advertised as allowing you to have 5,000-10,000 active database connections, but **it's critical to -understand that those are idle connections.** **Pgbouncer does not +understand that those are idle connections.** **PgBouncer does not increase your core database capacity.** If your database has a max of 22 connections, then you can only have 22 simultaneous transactions, -regardless of whether you have pgbouncer in front of it or not. +regardless of whether you have PgBouncer in front of it or not. **Solution:** Increase your database size to meet the traffic needs for your app. But be aware this can become very expensive. -Note: slow database transactions will greatly decrease your throughput. If -it seems you are running out of connections before you should based on +Note: Slow database transactions will greatly decrease your throughput. If +it seems you are running out of connections before you should, based on your app traffic, then turn on logging for your database queries and look for long transactions. ## Databases to Consider {#databases} -1. PostgreSQL + Pgbouncer +1. PostgreSQL + PgBouncer 2. [PlanetScaleDB](https://www.planetscale.com) - This is MySQL but seems to have solved the connection limit issue for serverless environments @@ -90,7 +89,7 @@ This also assumes you already have a [Vercel](https://vercel.com) account. [read the Prisma docs on this](https://www.prisma.io/docs/reference/database-connectors/postgresql#connection-details). 1. Make sure you get the connection string to your connection pool, not directly to the DB. - 2. If using pgBouncer (default connection pool on Digital Ocean), you + 2. If using PgBouncer (default connection pool on Digital Ocean), you must add `&pgbouncer=true` to the end of your connection string for Prisma to work correctly. 4. Change your build script in package.json to be From 15baf5e316a1a207570357fc5a504903fc427235 Mon Sep 17 00:00:00 2001 From: JuanM04 Date: Mon, 19 Apr 2021 19:11:05 -0300 Subject: [PATCH 04/77] Upgraded dependencies --- package.json | 8 +- ...english-slugify.js => english-slugify.mjs} | 6 +- yarn.lock | 1275 +++++++---------- 3 files changed, 528 insertions(+), 761 deletions(-) rename scripts/{english-slugify.js => english-slugify.mjs} (91%) diff --git a/package.json b/package.json index c83be60..3742b12 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "lint": "yarn lint:code && yarn lint:docs", "lint:code": "eslint --ignore-path .gitignore --ext .js,.ts,.tsx .", "lint:docs": "alex app/pages/docs/**/*.mdx", - "english-slugify": "node scripts/english-slugify.js", + "english-slugify": "node scripts/english-slugify.mjs", "prepare": "husky install" }, "lint-staged": { @@ -20,15 +20,15 @@ "@docsearch/react": "1.0.0-alpha.28", "@octokit/rest": "18.5.2", "@reach/rect": "0.15.0", - "@sindresorhus/slugify": "1.1.0", + "@sindresorhus/slugify": "2.0.0", "@visx/hierarchy": "1.7.0", "@visx/responsive": "1.7.0", - "blitz": "0.33.1", + "blitz": "0.34.0", "clsx": "1.1.1", "dlv": "1.1.3", "fathom-client": "3.0.0", "focus-visible": "5.2.0", - "framer-motion": "4.1.3", + "framer-motion": "4.1.5", "gray-matter": "4.0.2", "just-group-by": "1.0.0", "next-themes": "0.0.14", diff --git a/scripts/english-slugify.js b/scripts/english-slugify.mjs similarity index 91% rename from scripts/english-slugify.js rename to scripts/english-slugify.mjs index 8904b02..bb664f9 100644 --- a/scripts/english-slugify.js +++ b/scripts/english-slugify.mjs @@ -1,6 +1,6 @@ -const slugify = require("@sindresorhus/slugify") -const fs = require("fs/promises") -const path = require("path") +import slugify from "@sindresorhus/slugify" +import fs from "fs/promises" +import path from "path" async function main() { const docsPath = path.resolve(process.cwd(), "app", "pages", "docs") diff --git a/yarn.lock b/yarn.lock index 9305286..744f9aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -137,6 +137,27 @@ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.11.tgz#9c8fe523c206979c9a81b1e12fe50c1254f1aa35" integrity sha512-BwKEkO+2a67DcFeS3RLl0Z3Gs2OvdXewuWjc1Hfokhb5eQWP9YRYH1/+VrVZvql2CfjOiNGqSAFOYt4lsqTHzg== +"@babel/core@7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd" + integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.12.10" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helpers" "^7.12.5" + "@babel/parser" "^7.12.10" + "@babel/template" "^7.12.7" + "@babel/traverse" "^7.12.10" + "@babel/types" "^7.12.10" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.19" + semver "^5.4.1" + source-map "^0.5.0" + "@babel/core@7.12.9": version "7.12.9" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" @@ -159,28 +180,6 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@7.13.1": - version "7.13.1" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.1.tgz#7ddd027176debe40f13bb88bac0c21218c5b1ecf" - integrity sha512-FzeKfFBG2rmFtGiiMdXZPFt/5R5DXubVi82uYhjGX4Msf+pgYQMCFIqFXZWs5vbIYbf14VeBIgdGI03CDOOM1w== - dependencies: - "@babel/code-frame" "^7.12.13" - "@babel/generator" "^7.13.0" - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-transforms" "^7.13.0" - "@babel/helpers" "^7.13.0" - "@babel/parser" "^7.13.0" - "@babel/template" "^7.12.13" - "@babel/traverse" "^7.13.0" - "@babel/types" "^7.13.0" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.1.2" - lodash "^4.17.19" - semver "7.0.0" - source-map "^0.5.0" - "@babel/core@^7.1.0", "@babel/core@^7.7.5": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.10.tgz#07de050bbd8193fcd8a3c27918c0890613a94559" @@ -234,6 +233,15 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.12.10", "@babel/generator@^7.13.0", "@babel/generator@^7.13.9": + version "7.13.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39" + integrity sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw== + dependencies: + "@babel/types" "^7.13.0" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/generator@^7.12.17": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.17.tgz#9ef1dd792d778b32284411df63f4f668a9957287" @@ -243,15 +251,6 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/generator@^7.13.0", "@babel/generator@^7.13.9", "@babel/generator@^7.4.0": - version "7.13.9" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.13.9.tgz#3a7aa96f9efb8e2be42d38d80e2ceb4c64d8de39" - integrity sha512-mHOOmY0Axl/JCTkxTU6Lf5sWOg/v8nUa+Xkt4zMTftX0wqmb6Sh7J8gvcehBw7q0AhrhAR+FDacKjCZ2X8K+Sw== - dependencies: - "@babel/types" "^7.13.0" - jsesc "^2.5.1" - source-map "^0.5.0" - "@babel/helper-annotate-as-pure@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" @@ -614,7 +613,7 @@ "@babel/traverse" "^7.12.17" "@babel/types" "^7.12.17" -"@babel/helpers@^7.13.0", "@babel/helpers@^7.13.10": +"@babel/helpers@^7.13.10": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.13.10.tgz#fd8e2ba7488533cdeac45cc158e9ebca5e3c7df8" integrity sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ== @@ -641,7 +640,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.13.0", "@babel/parser@^7.13.10", "@babel/parser@^7.4.3": +"@babel/parser@^7.1.0", "@babel/parser@^7.13.0", "@babel/parser@^7.13.10": version "7.13.11" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.11.tgz#f93ebfc99d21c1772afbbaa153f47e7ce2f50b88" integrity sha512-PhuoqeHoO9fc4ffMEVk4qb/w/s2iOSWohvbHxLtxui0eBg3Lg5gN1U8wp1V1u61hOWkPQJJyJzGH6Y+grwkq8Q== @@ -651,6 +650,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.5.tgz#b4af32ddd473c0bfa643bd7ff0728b8e71b81ea0" integrity sha512-FVM6RZQ0mn2KCf1VUED7KepYeUWoVShczewOCfm3nzoBybaih51h+sYVVGthW9M6lPByEPTQf+xm27PBdlpwmQ== +"@babel/parser@^7.12.10", "@babel/parser@^7.13.15": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.15.tgz#8e66775fb523599acb6a289e12929fa5ab0954d8" + integrity sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ== + "@babel/parser@^7.12.13", "@babel/parser@^7.12.17", "@babel/parser@^7.12.7": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.17.tgz#bc85d2d47db38094e5bb268fc761716e7d693848" @@ -1419,7 +1423,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.12.5": +"@babel/runtime@^7.12.5", "@babel/runtime@^7.6.2": version "7.13.10" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d" integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw== @@ -1435,7 +1439,7 @@ "@babel/parser" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/template@^7.12.13", "@babel/template@^7.12.7", "@babel/template@^7.3.3", "@babel/template@^7.4.0": +"@babel/template@^7.12.13", "@babel/template@^7.12.7", "@babel/template@^7.3.3": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.13.tgz#530265be8a2589dbb37523844c5bcb55947fb327" integrity sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA== @@ -1444,7 +1448,7 @@ "@babel/parser" "^7.12.13" "@babel/types" "^7.12.13" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0", "@babel/traverse@^7.4.3": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.0.tgz#6d95752475f86ee7ded06536de309a65fc8966cc" integrity sha512-xys5xi5JEhzC3RzEmSGrs/b3pJW/o87SypZ+G/PhaE7uqVQNv/jlmVIBXuoh5atqQ434LfXV+sf23Oxj0bchJQ== @@ -1474,6 +1478,20 @@ globals "^11.1.0" lodash "^4.17.19" +"@babel/traverse@^7.12.10": + version "7.13.15" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.15.tgz#c38bf7679334ddd4028e8e1f7b3aa5019f0dada7" + integrity sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ== + dependencies: + "@babel/code-frame" "^7.12.13" + "@babel/generator" "^7.13.9" + "@babel/helper-function-name" "^7.12.13" + "@babel/helper-split-export-declaration" "^7.12.13" + "@babel/parser" "^7.13.15" + "@babel/types" "^7.13.14" + debug "^4.1.0" + globals "^11.1.0" + "@babel/traverse@^7.12.17", "@babel/traverse@^7.12.9": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.17.tgz#40ec8c7ffb502c4e54c7f95492dc11b88d718619" @@ -1498,7 +1516,7 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" -"@babel/types@^7.0.0", "@babel/types@^7.13.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.0": +"@babel/types@^7.0.0", "@babel/types@^7.13.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.0.tgz#74424d2816f0171b4100f0ab34e9a374efdf7f80" integrity sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA== @@ -1516,6 +1534,15 @@ lodash "^4.17.19" to-fast-properties "^2.0.0" +"@babel/types@^7.12.10", "@babel/types@^7.13.14": + version "7.13.14" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.14.tgz#c35a4abb15c7cd45a2746d78ab328e362cbace0d" + integrity sha512-A2aa3QTkWoyqsZZFl56MLUsfmh7O0gN41IPvXAE/++8ojpbz12SszD7JEGYVdn4f9Kt4amIei07swF1h4AqmmQ== + dependencies: + "@babel/helper-validator-identifier" "^7.12.11" + lodash "^4.17.19" + to-fast-properties "^2.0.0" + "@babel/types@^7.12.13", "@babel/types@^7.12.17", "@babel/types@^7.12.7": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.17.tgz#9d711eb807e0934c90b8b1ca0eb1f7230d150963" @@ -1539,21 +1566,21 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@blitzjs/babel-preset@0.33.1": - version "0.33.1" - resolved "https://registry.yarnpkg.com/@blitzjs/babel-preset/-/babel-preset-0.33.1.tgz#dfbb6fe1d5c989cfb2feb124e70071992c1b660f" - integrity sha512-VjVPUjMFVPZ8MuKKZt8fEF0zzAbIhxCXxkBG5Jh9KHq2TGf+vn1iYp7PqvnoBhzdwhS5PjTXFT11CTPEixOPMQ== +"@blitzjs/babel-preset@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@blitzjs/babel-preset/-/babel-preset-0.34.0.tgz#728f99aa2f85860f5d06fa2a6ab55727b99ca591" + integrity sha512-oFVh7oXb3qh8IAlNLjSS/NeXSnAZYDrXDjRz5C4t6wTIzGkGhbVFBXKX9Jb6mrGJCbWeNo667rmCRZhQB0NxNg== dependencies: "@babel/helper-module-imports" "^7.0.0" babel-plugin-superjson-next "0.2.2" -"@blitzjs/cli@0.33.1": - version "0.33.1" - resolved "https://registry.yarnpkg.com/@blitzjs/cli/-/cli-0.33.1.tgz#8a25202a03bfd99d84f58e5e1041cb760b7fc5ed" - integrity sha512-TZ9m7qIgFqrsG2kIw4ZMQB7nJgV4JUABVEs3aCQ+p9iza4fnb/qx2/5JyRJu7QaqcDdZViDrCU5wfHgAl4pvwQ== +"@blitzjs/cli@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@blitzjs/cli/-/cli-0.34.0.tgz#f81e7d9bf0b8bf1d88d1cdeeb427462399a57c39" + integrity sha512-Qtq5Cyy8QcX0KCzCALaBIloRl00Lp/aaw4hPm5JF+dpzyqhcnmdhq4OonwU6ebx7IYg+Bg2OIPButGBKjHHb9Q== dependencies: - "@blitzjs/display" "0.33.1" - "@blitzjs/repl" "0.33.1" + "@blitzjs/display" "0.34.0" + "@blitzjs/repl" "0.34.0" "@oclif/command" "1.8.0" "@oclif/config" "1.17.0" "@oclif/plugin-autocomplete" "0.3.0" @@ -1582,21 +1609,21 @@ tsconfig-paths "3.9.0" v8-compile-cache "2.2.0" -"@blitzjs/config@0.33.1": - version "0.33.1" - resolved "https://registry.yarnpkg.com/@blitzjs/config/-/config-0.33.1.tgz#6530a5f64c6b8bbdecc2dd59e2bc077e73953f6d" - integrity sha512-zK0y0exmUrPPEclBh9OcXNN3TRA2XpinFFyuonhmLxN4Vh1qw3bx3iiJdP9xN4yCUIXlBAU++dBaHDZOciJsIg== +"@blitzjs/config@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@blitzjs/config/-/config-0.34.0.tgz#72b1f48e3d1b036571635ee84f82f4dbd3afa957" + integrity sha512-7F1zyCeVQA6yr0GVbCK8/NCDCsddmpR8JKWK1SPperbmddVSPUbeHGdYGlF0xzGZdaBEU+uhofmYSRR/KchbQA== dependencies: fs-extra "^9.1.0" pkg-dir "^5.0.0" -"@blitzjs/core@0.33.1": - version "0.33.1" - resolved "https://registry.yarnpkg.com/@blitzjs/core/-/core-0.33.1.tgz#8f98c52e41b6f5f117c46cb719021b5ad9e75cc5" - integrity sha512-TC2K64XjKb1AGMNWfJPJOLGgWYAeLxlTkHFR7IUXn4wnCDcGXbiwUz/2HVTET7INPdDu5v3st7xNmmrBV6DoJA== +"@blitzjs/core@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@blitzjs/core/-/core-0.34.0.tgz#34f639d87f9db673c793df625d36184df8df4932" + integrity sha512-jt92Ui2vPWl/AGmIbPa91A7ULeLVrAntlDnSiqFkrMgd0LwmUOvAP4BAt4EXujiFei7emht49sAt5j2/Z3SyCA== dependencies: - "@blitzjs/config" "0.33.1" - "@blitzjs/display" "0.33.1" + "@blitzjs/config" "0.34.0" + "@blitzjs/display" "0.34.0" "@types/secure-password" "3.1.0" b64-lite "^1.4.0" bad-behavior "^1.0.1" @@ -1608,33 +1635,33 @@ jsonwebtoken "8.5.1" lodash.frompairs "4.0.1" nanoid "^3.1.20" - next "10.0.9" + next "npm:@blitzjs/next@0.34.0" npm-which "^3.0.1" null-loader "4.0.1" passport "0.4.1" - react-query "2.5.12" + react-query "3.13.9" secure-password "4.0.0" superjson "1.7.2" -"@blitzjs/display@0.33.1": - version "0.33.1" - resolved "https://registry.yarnpkg.com/@blitzjs/display/-/display-0.33.1.tgz#cd163a6f3353ba7cc59a8f6e2e82f8d3b1f07d82" - integrity sha512-JCVhqivxjebKJXIzy5rPe6Hv8V5tWPtBOO6DTsE/6FZezI4VYY2sgN20g00Ac2XH14hIzsSu9doHiTIk9tJzvQ== +"@blitzjs/display@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@blitzjs/display/-/display-0.34.0.tgz#f46ed3d3774d0170eb52af71d4c89da09cac9e8f" + integrity sha512-+tHVyEe5umCnwlRoPqzryfZLuDqSORUXNiXP8z3Ufrpjo6hr4Yl0DxGbtcCz4TgBx91OvbVyDI68bkHFePj0Iw== dependencies: - "@blitzjs/config" "0.33.1" - "@blitzjs/display" "0.33.1" + "@blitzjs/config" "0.34.0" + "@blitzjs/display" "0.34.0" chalk "^4.1.0" console-table-printer "^2.7.5" ora "^5.3.0" readline "1.3.0" tslog "^3.1.1" -"@blitzjs/file-pipeline@0.33.1": - version "0.33.1" - resolved "https://registry.yarnpkg.com/@blitzjs/file-pipeline/-/file-pipeline-0.33.1.tgz#73cf82f1337756b608d9b6e72749a4f09eca4ed8" - integrity sha512-E0OWzngW/Y2booHR6DqJNbea2FJYSJAL5KjkS8veYgr1d2NIB2M8gx29B9HdG+ki4IGA0o9S7emCeK0Hl46uog== +"@blitzjs/file-pipeline@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@blitzjs/file-pipeline/-/file-pipeline-0.34.0.tgz#c6c6543e84aae1213529c365c0ac3fcc88e71343" + integrity sha512-nyAT9zTy4xZQlXu4MLC72lbedUVuKQ0pbY/bJeFwcZ8kKHD4tX3YZNGvW5qgBVQPrnk2uUB9uaGnkGpTLfBq7g== dependencies: - "@blitzjs/display" "0.33.1" + "@blitzjs/display" "0.34.0" chalk "^4.1.0" chokidar "3.5.1" flush-write-stream "2.0.0" @@ -1653,21 +1680,20 @@ vinyl-file "3.0.0" vinyl-fs "3.0.3" -"@blitzjs/generator@0.33.1": - version "0.33.1" - resolved "https://registry.yarnpkg.com/@blitzjs/generator/-/generator-0.33.1.tgz#49658c48bad30041d9b53ae15f0c4c56d8a67f37" - integrity sha512-RpnVdu0zzaOGX2PNX2xM3JBu0TdHjukpOPvNNv5jqXED6yUa7GF3nrnFyKbDwNfq4GmRG+yUZIPZUGXFwIvSrA== +"@blitzjs/generator@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@blitzjs/generator/-/generator-0.34.0.tgz#315c8b79e33df1a2cac66b2942d1343cc042d767" + integrity sha512-Bg1mXOMwqbH8yG4Gi7yT9DEOp34ryPs8WaeIi8tBOWf5ULXfz9Py5DQlsMfF3Lg8+yxzWV+xttQ6axueo2wasg== dependencies: - "@babel/core" "7.13.1" + "@babel/core" "7.12.10" "@babel/plugin-transform-typescript" "7.12.1" - "@blitzjs/display" "0.33.1" + "@blitzjs/display" "0.34.0" "@types/jscodeshift" "0.7.2" chalk "^4.1.0" cross-spawn "7.0.3" diff "5.0.0" enquirer "2.3.6" fs-extra "^9.1.0" - fs-readdir-recursive "1.1.0" got "^11.8.1" jscodeshift "0.11.0" mem-fs "1.2.0" @@ -1678,16 +1704,16 @@ username "^5.1.0" vinyl "2.2.1" -"@blitzjs/installer@0.33.1": - version "0.33.1" - resolved "https://registry.yarnpkg.com/@blitzjs/installer/-/installer-0.33.1.tgz#3813ffedc9414d35e09bde3fbd2cd66c1dcb398c" - integrity sha512-15OVfrkPv8uotL1oaJdtoXQtA73VHDGE59fV2fH3hx+/U6qLsBe+i1YNz8hY5ziIW96JxzmfCAl0tq9STkPtaA== +"@blitzjs/installer@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@blitzjs/installer/-/installer-0.34.0.tgz#7731c5040c196c0a8c0717da11ae2a8c1208b3e0" + integrity sha512-fCuLnCcR1mM+FFoVwpdSU/jNZghS/7x0nmGAa3gx/RGN9Q7/quvqY1M6iR5iXRhxYKQGTXLWOWJDcYH4wmkbKQ== dependencies: - "@babel/core" "7.13.1" + "@babel/core" "7.12.10" "@babel/plugin-transform-typescript" "7.12.1" - "@blitzjs/config" "0.33.1" - "@blitzjs/display" "0.33.1" - "@blitzjs/generator" "0.33.1" + "@blitzjs/config" "0.34.0" + "@blitzjs/display" "0.34.0" + "@blitzjs/generator" "0.34.0" "@types/jscodeshift" "0.7.2" cross-spawn "7.0.3" diff "5.0.0" @@ -1702,26 +1728,26 @@ recast "0.20.4" ts-node "^9.1.1" -"@blitzjs/repl@0.33.1": - version "0.33.1" - resolved "https://registry.yarnpkg.com/@blitzjs/repl/-/repl-0.33.1.tgz#2090cef38bced1017fece43943a193c541f029c3" - integrity sha512-Sk2Wsl08lJgpXg+nbNeVVnsjoLsMRm1n6RegbWbrScLXSzEi707BvVQvnGtgJwv4t9m+ab1av/uYPyrz8vcY8Q== +"@blitzjs/repl@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@blitzjs/repl/-/repl-0.34.0.tgz#a9f8244958d1b4b51d234db7e19c9b214661a186" + integrity sha512-xRIfxAzLP5nP3nRHm1WlEPiCaSvYsncuG6JAS9n2SpctwUZGbCORuSTLaLtUPhbNayOm4Qc3Z2sI22fkQRnxag== dependencies: - "@blitzjs/config" "0.33.1" + "@blitzjs/config" "0.34.0" chokidar "3.5.1" globby "11.0.2" pkg-dir "^5.0.0" progress "^2.0.3" -"@blitzjs/server@0.33.1": - version "0.33.1" - resolved "https://registry.yarnpkg.com/@blitzjs/server/-/server-0.33.1.tgz#6efd8a3623afd43a55b4b46d32b15441e8575407" - integrity sha512-BpeOcFjSslskLIKoTc8242xJIsA3vpc9P6ObrHG+5kuo5VsxN1vPjoEnBOemAYRbQiJliEr5pdDE7Bk7h4TiWA== +"@blitzjs/server@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@blitzjs/server/-/server-0.34.0.tgz#180b7fe7a7e49796165fc5bd3e51304a850f98b8" + integrity sha512-mgPgEwUDzvAL+HuyhGo0ns14dxamJxm84Fc1jswq/cXsL77BD2Ta7VH1GYGXDDp0rJMgDlc1KG3eZN4IGIJjFg== dependencies: - "@blitzjs/config" "0.33.1" - "@blitzjs/core" "0.33.1" - "@blitzjs/display" "0.33.1" - "@blitzjs/file-pipeline" "0.33.1" + "@blitzjs/config" "0.34.0" + "@blitzjs/core" "0.34.0" + "@blitzjs/display" "0.34.0" + "@blitzjs/file-pipeline" "0.34.0" cross-spawn "7.0.3" detect-port "1.3.0" expand-tilde "2.0.2" @@ -1910,15 +1936,6 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-24.9.0.tgz#79b1bc06fb74a8cfb01cbdedf945584b1b9707f0" - integrity sha512-Zuj6b8TnKXi3q4ymac8EQfc3ea/uhLeCGThFqXeC8H9/raaH8ARPUTdId+XyGd03Z4In0/VjD2OYFcBF09fNLQ== - dependencies: - "@jest/source-map" "^24.9.0" - chalk "^2.0.1" - slash "^2.0.0" - "@jest/console@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.6.2.tgz#4e04bc464014358b03ab4937805ee36a0aeb98f2" @@ -1965,16 +1982,6 @@ slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^24.3.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-24.9.0.tgz#21e3afa2d65c0586cbd6cbefe208bafade44ab18" - integrity sha512-5A1QluTPhvdIPFYnO3sZC3smkNeXPVELz7ikPbhUj0bQjB07EoE9qtLrem14ZUYWdVayYbsjVwIiL4WBIMV4aQ== - dependencies: - "@jest/fake-timers" "^24.9.0" - "@jest/transform" "^24.9.0" - "@jest/types" "^24.9.0" - jest-mock "^24.9.0" - "@jest/environment@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.6.2.tgz#ba364cc72e221e79cc8f0a99555bf5d7577cf92c" @@ -1985,15 +1992,6 @@ "@types/node" "*" jest-mock "^26.6.2" -"@jest/fake-timers@^24.3.0", "@jest/fake-timers@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-24.9.0.tgz#ba3e6bf0eecd09a636049896434d306636540c93" - integrity sha512-eWQcNa2YSwzXWIMC5KufBh3oWRIijrQFROsIqt6v/NS9Io/gknw1jsAC9c+ih/RQX4A3O7SeWAhQeN0goKhT9A== - dependencies: - "@jest/types" "^24.9.0" - jest-message-util "^24.9.0" - jest-mock "^24.9.0" - "@jest/fake-timers@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.6.2.tgz#459c329bcf70cee4af4d7e3f3e67848123535aad" @@ -2047,15 +2045,6 @@ optionalDependencies: node-notifier "^8.0.0" -"@jest/source-map@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-24.9.0.tgz#0e263a94430be4b41da683ccc1e6bffe2a191714" - integrity sha512-/Xw7xGlsZb4MJzNDgB7PW5crou5JqWiBQaz6xyPd3ArOg2nfn/PunV8+olXbbEZzNl591o5rWKE9BRDaFAuIBg== - dependencies: - callsites "^3.0.0" - graceful-fs "^4.1.15" - source-map "^0.6.0" - "@jest/source-map@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.6.2.tgz#29af5e1e2e324cafccc936f218309f54ab69d535" @@ -2065,15 +2054,6 @@ graceful-fs "^4.2.4" source-map "^0.6.0" -"@jest/test-result@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-24.9.0.tgz#11796e8aa9dbf88ea025757b3152595ad06ba0ca" - integrity sha512-XEFrHbBonBJ8dGp2JmF8kP/nQI/ImPpygKHwQ/SY+es59Z3L5PI4Qb9TQQMAEeYsThG1xF0k6tmG0tIKATNiiA== - dependencies: - "@jest/console" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/istanbul-lib-coverage" "^2.0.0" - "@jest/test-result@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.6.2.tgz#55da58b62df134576cc95476efa5f7949e3f5f18" @@ -2095,28 +2075,6 @@ jest-runner "^26.6.3" jest-runtime "^26.6.3" -"@jest/transform@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-24.9.0.tgz#4ae2768b296553fadab09e9ec119543c90b16c56" - integrity sha512-TcQUmyNRxV94S0QpMOnZl0++6RMiqpbH/ZMccFB/amku6Uwvyb1cjYX7xkp5nGNkbX4QPH/FcB6q1HBTHynLmQ== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^24.9.0" - babel-plugin-istanbul "^5.1.0" - chalk "^2.0.1" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.1.15" - jest-haste-map "^24.9.0" - jest-regex-util "^24.9.0" - jest-util "^24.9.0" - micromatch "^3.1.10" - pirates "^4.0.1" - realpath-native "^1.1.0" - slash "^2.0.0" - source-map "^0.6.1" - write-file-atomic "2.4.1" - "@jest/transform@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" @@ -2138,15 +2096,6 @@ source-map "^0.6.1" write-file-atomic "^3.0.0" -"@jest/types@^24.3.0", "@jest/types@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" - integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^13.0.0" - "@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -2209,20 +2158,20 @@ dependencies: webpack-bundle-analyzer "4.3.0" -"@next/env@10.0.9": - version "10.0.9" - resolved "https://registry.yarnpkg.com/@next/env/-/env-10.0.9.tgz#455fd364c8a5ee012b2cd4406d5294164990706d" - integrity sha512-MERX3DY5u0Ed29eAsXeFBCZlFAGBtmjf7+Nht0hfgB25MPKKkIbC/0MRPcX/PQcAgLHsAHO6ay1u9xKzR4Vzjw== +"@next/env@10.1.3": + version "10.1.3" + resolved "https://registry.yarnpkg.com/@next/env/-/env-10.1.3.tgz#29e5d62919b4a7b1859f8d36169848dc3f5ddebe" + integrity sha512-q7z7NvmRs66lCQmVJtKjDxVtMTjSwP6ExVzaH46pbTH60MHgzEJ9H4jXrFLTihPmCIvpAv6Ai04jbS8dcg1ZMQ== -"@next/polyfill-module@10.0.9": - version "10.0.9" - resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-10.0.9.tgz#0c21442dd73ec31ae30ac560bc5c5fdce068a98f" - integrity sha512-kPOP6ku/e8zdrK8hwxOrjUrPLcdDEj12huLHVz+DZU+20q6VlhMOtR8aKHW1460L4LoLE/DAa7YyIuxtArhDRg== +"@next/polyfill-module@10.1.3": + version "10.1.3" + resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-10.1.3.tgz#beafe89bc4235d436fa0ed02c9d2a5d311fb0238" + integrity sha512-1DtUVcuoBJAn5IrxIZQjUG1KTPkiXMYloykPSkRxawimgvG9dRj2kscU+4KGNSFxHoxW9c68VRCb+7MDz5aGGw== -"@next/react-dev-overlay@10.0.9": - version "10.0.9" - resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-10.0.9.tgz#5162d66c05b2a0ca0d155f7e6663e8134d9d4ac9" - integrity sha512-JsSh2Y004MEuPYqBD9eTl4PVZIjSzSy2GcD7MrW/gQcExYNpeMIJAbh8/OcyO1t+OnQeIHF5s/xTMsDHBGNcew== +"@next/react-dev-overlay@10.1.3": + version "10.1.3" + resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-10.1.3.tgz#ee1c6033b29be9b383e061bd9705021d131ea445" + integrity sha512-vIgUah3bR9+MKzwU1Ni5ONfYM0VdI42i7jZ+Ei1c0wjwkG9anVnDqhSQ3mVg62GP2nt7ExaaFyf9THbsw5KYXg== dependencies: "@babel/code-frame" "7.12.11" anser "1.4.9" @@ -2236,10 +2185,10 @@ stacktrace-parser "0.1.10" strip-ansi "6.0.0" -"@next/react-refresh-utils@10.0.9": - version "10.0.9" - resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.0.9.tgz#cdf9e41f8854c113397853daf78469b0c8140f14" - integrity sha512-LSoKnM+fI9MHHew+mBg1w2e4/gjwPQsI+mDTzmfwdBwje+j9U2Int6XOZftMqBPXSlL04vjC9SRBkp0+3h8cNA== +"@next/react-refresh-utils@10.1.3": + version "10.1.3" + resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-10.1.3.tgz#65b3e1b9846c02452787fde1d54ad9c54b506dbd" + integrity sha512-P4GJZuLKfD/o42JvGZ/xP4Hxg68vd3NeZxOLqIuQKFjjaYgC2IrO+lE5PTwGmRkytjfprJC+9j7Jss/xQAS6QA== "@nodelib/fs.scandir@2.1.3": version "2.1.3" @@ -2669,20 +2618,20 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4" integrity sha512-FyD2meJpDPjyNQejSjvnhpgI/azsQkA4lGbuu5BQZfjvJ9cbRZXzeWL2HceCekW4lixO9JPesIIQkSoLjeJHNQ== -"@sindresorhus/slugify@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/slugify/-/slugify-1.1.0.tgz#2f195365d9b953384305b62664b44b4036c49430" - integrity sha512-ujZRbmmizX26yS/HnB3P9QNlNa4+UvHh+rIse3RbOXLp8yl6n1TxB4t7NHggtVgS8QmmOtzXo48kCxZGACpkPw== +"@sindresorhus/slugify@2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/slugify/-/slugify-2.0.0.tgz#9ccd8f9d29b8187f5b3e33e4423abae8a82ca00c" + integrity sha512-lGRwhzEHTiTlPj8HrSQpZ+YXbFW28pmO7/Xq5XREEt7Xd/JVgszec1I1XFGb2XeMYHKIY/Sc0V45DBGJbFzsoQ== dependencies: - "@sindresorhus/transliterate" "^0.1.1" - escape-string-regexp "^4.0.0" + "@sindresorhus/transliterate" "^1.0.0" + escape-string-regexp "^5.0.0" -"@sindresorhus/transliterate@^0.1.1": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@sindresorhus/transliterate/-/transliterate-0.1.1.tgz#779b31244781d3c898f185b61d58c89e7c782674" - integrity sha512-QSdIQ5keUFAZ3KLbfbsntW39ox0Ym8183RqTwBq/ZEFoN3NQAtGV+qWaNdzKpIDHgj9J2CQ2iNDRVU11Zyr7MQ== +"@sindresorhus/transliterate@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/transliterate/-/transliterate-1.0.0.tgz#7efc60bd347c16f416582eb7d18fee3bbaa3379b" + integrity sha512-5429x9FXQzC8UIav+yeMVOQTL/DdJ3ANJOyuSAvwVSLmPSsw/7KWyXpncvFbJEe4h2MfvINSrjhRgDiltSjTlw== dependencies: - escape-string-regexp "^2.0.0" + escape-string-regexp "^5.0.0" lodash.deburr "^4.1.0" "@sinonjs/commons@^1.7.0": @@ -2863,7 +2812,7 @@ "@types/react" ">=16.9.0" "@types/react-test-renderer" ">=16.9.0" -"@testing-library/react@^11.2.3": +"@testing-library/react@11.2.5": version "11.2.5" resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-11.2.5.tgz#ae1c36a66c7790ddb6662c416c27863d87818eb9" integrity sha512-yEx7oIa/UWLe2F2dqK0FtMF9sJWNXD+2PPtp39BvE0Kh9MJ9Kl0HrZAgEuhUJR+Lx8Di6Xz+rKwSdEPY2UV8ZQ== @@ -2987,14 +2936,6 @@ dependencies: "@types/istanbul-lib-coverage" "*" -"@types/istanbul-reports@^1.1.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2" - integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw== - dependencies: - "@types/istanbul-lib-coverage" "*" - "@types/istanbul-lib-report" "*" - "@types/istanbul-reports@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz#508b13aa344fa4976234e75dddcc34925737d821" @@ -3002,7 +2943,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@*", "@types/jest@26.x", "@types/jest@^26.0.20": +"@types/jest@*", "@types/jest@26.0.20", "@types/jest@26.x": version "26.0.20" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.20.tgz#cd2f2702ecf69e86b586e1f5223a60e454056307" integrity sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA== @@ -3150,11 +3091,6 @@ dependencies: "@types/node" "*" -"@types/stack-utils@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" - integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== - "@types/stack-utils@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.0.tgz#7036640b4e21cc2f259ae826ce843d277dad8cff" @@ -3177,13 +3113,6 @@ resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-20.2.0.tgz#dd3e6699ba3237f0348cd085e4698780204842f9" integrity sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA== -"@types/yargs@^13.0.0": - version "13.0.11" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.11.tgz#def2f0c93e4bdf2c61d7e34899b17e34be28d3b1" - integrity sha512-NRqD6T4gktUrDi1o1wLH3EKC1o2caCr7/wR87ODcbVITQF106OM3sFN92ysZ++wqelOd1CTzatnOBRDYYG6wGQ== - dependencies: - "@types/yargs-parser" "*" - "@types/yargs@^15.0.0": version "15.0.13" resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.13.tgz#34f7fec8b389d7f3c1fd08026a5763e072d3c6dc" @@ -3196,13 +3125,13 @@ resolved "https://registry.yarnpkg.com/@types/yoga-layout/-/yoga-layout-1.9.2.tgz#efaf9e991a7390dc081a0b679185979a83a9639a" integrity sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw== -"@typescript-eslint/eslint-plugin@~4.14.0": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.14.2.tgz#47a15803cfab89580b96933d348c2721f3d2f6fe" - integrity sha512-uMGfG7GFYK/nYutK/iqYJv6K/Xuog/vrRRZX9aEP4Zv1jsYXuvFUMDFLhUnc8WFv3D2R5QhNQL3VYKmvLS5zsQ== +"@typescript-eslint/eslint-plugin@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.17.0.tgz#6f856eca4e6a52ce9cf127dfd349096ad936aa2d" + integrity sha512-/fKFDcoHg8oNan39IKFOb5WmV7oWhQe1K6CDaAVfJaNWEhmfqlA24g+u1lqU5bMH7zuNasfMId4LaYWC5ijRLw== dependencies: - "@typescript-eslint/experimental-utils" "4.14.2" - "@typescript-eslint/scope-manager" "4.14.2" + "@typescript-eslint/experimental-utils" "4.17.0" + "@typescript-eslint/scope-manager" "4.17.0" debug "^4.1.1" functional-red-black-tree "^1.0.1" lodash "^4.17.15" @@ -3210,61 +3139,60 @@ semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/experimental-utils@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.14.2.tgz#9df35049d1d36b6cbaba534d703648b9e1f05cbb" - integrity sha512-mV9pmET4C2y2WlyHmD+Iun8SAEqkLahHGBkGqDVslHkmoj3VnxnGP4ANlwuxxfq1BsKdl/MPieDbohCEQgKrwA== +"@typescript-eslint/experimental-utils@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.17.0.tgz#762c44aaa1a6a3c05b6d63a8648fb89b89f84c80" + integrity sha512-ZR2NIUbnIBj+LGqCFGQ9yk2EBQrpVVFOh9/Kd0Lm6gLpSAcCuLLe5lUCibKGCqyH9HPwYC0GIJce2O1i8VYmWA== dependencies: "@types/json-schema" "^7.0.3" - "@typescript-eslint/scope-manager" "4.14.2" - "@typescript-eslint/types" "4.14.2" - "@typescript-eslint/typescript-estree" "4.14.2" + "@typescript-eslint/scope-manager" "4.17.0" + "@typescript-eslint/types" "4.17.0" + "@typescript-eslint/typescript-estree" "4.17.0" eslint-scope "^5.0.0" eslint-utils "^2.0.0" -"@typescript-eslint/parser@~4.14.0": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.14.2.tgz#31e216e4baab678a56e539f9db9862e2542c98d0" - integrity sha512-ipqSP6EuUsMu3E10EZIApOJgWSpcNXeKZaFeNKQyzqxnQl8eQCbV+TSNsl+s2GViX2d18m1rq3CWgnpOxDPgHg== +"@typescript-eslint/parser@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.17.0.tgz#141b647ffc72ebebcbf9b0fe6087f65b706d3215" + integrity sha512-KYdksiZQ0N1t+6qpnl6JeK9ycCFprS9xBAiIrw4gSphqONt8wydBw4BXJi3C11ywZmyHulvMaLjWsxDjUSDwAw== dependencies: - "@typescript-eslint/scope-manager" "4.14.2" - "@typescript-eslint/types" "4.14.2" - "@typescript-eslint/typescript-estree" "4.14.2" + "@typescript-eslint/scope-manager" "4.17.0" + "@typescript-eslint/types" "4.17.0" + "@typescript-eslint/typescript-estree" "4.17.0" debug "^4.1.1" -"@typescript-eslint/scope-manager@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.14.2.tgz#64cbc9ca64b60069aae0c060b2bf81163243b266" - integrity sha512-cuV9wMrzKm6yIuV48aTPfIeqErt5xceTheAgk70N1V4/2Ecj+fhl34iro/vIssJlb7XtzcaD07hWk7Jk0nKghg== +"@typescript-eslint/scope-manager@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.17.0.tgz#f4edf94eff3b52a863180f7f89581bf963e3d37d" + integrity sha512-OJ+CeTliuW+UZ9qgULrnGpPQ1bhrZNFpfT/Bc0pzNeyZwMik7/ykJ0JHnQ7krHanFN9wcnPK89pwn84cRUmYjw== dependencies: - "@typescript-eslint/types" "4.14.2" - "@typescript-eslint/visitor-keys" "4.14.2" + "@typescript-eslint/types" "4.17.0" + "@typescript-eslint/visitor-keys" "4.17.0" -"@typescript-eslint/types@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.14.2.tgz#d96da62be22dc9dc6a06647f3633815350fb3174" - integrity sha512-LltxawRW6wXy4Gck6ZKlBD05tCHQUj4KLn4iR69IyRiDHX3d3NCAhO+ix5OR2Q+q9bjCrHE/HKt+riZkd1At8Q== +"@typescript-eslint/types@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.17.0.tgz#f57d8fc7f31b348db946498a43050083d25f40ad" + integrity sha512-RN5z8qYpJ+kXwnLlyzZkiJwfW2AY458Bf8WqllkondQIcN2ZxQowAToGSd9BlAUZDB5Ea8I6mqL2quGYCLT+2g== -"@typescript-eslint/typescript-estree@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.14.2.tgz#9c5ebd8cae4d7b014f890acd81e8e17f309c9df9" - integrity sha512-ESiFl8afXxt1dNj8ENEZT12p+jl9PqRur+Y19m0Z/SPikGL6rqq4e7Me60SU9a2M28uz48/8yct97VQYaGl0Vg== +"@typescript-eslint/typescript-estree@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.17.0.tgz#b835d152804f0972b80dbda92477f9070a72ded1" + integrity sha512-lRhSFIZKUEPPWpWfwuZBH9trYIEJSI0vYsrxbvVvNyIUDoKWaklOAelsSkeh3E2VBSZiNe9BZ4E5tYBZbUczVQ== dependencies: - "@typescript-eslint/types" "4.14.2" - "@typescript-eslint/visitor-keys" "4.14.2" + "@typescript-eslint/types" "4.17.0" + "@typescript-eslint/visitor-keys" "4.17.0" debug "^4.1.1" globby "^11.0.1" is-glob "^4.0.1" - lodash "^4.17.15" semver "^7.3.2" tsutils "^3.17.1" -"@typescript-eslint/visitor-keys@4.14.2": - version "4.14.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.14.2.tgz#997cbe2cb0690e1f384a833f64794e98727c70c6" - integrity sha512-KBB+xLBxnBdTENs/rUgeUKO0UkPBRs2vD09oMRRIkj5BEN8PX1ToXV532desXfpQnZsYTyLLviS7JrPhdL154w== +"@typescript-eslint/visitor-keys@4.17.0": + version "4.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.17.0.tgz#9c304cfd20287c14a31d573195a709111849b14d" + integrity sha512-WfuMN8mm5SSqXuAr9NM+fItJ0SVVphobWYkWOwQ1odsfC014Vdxk/92t4JwS1Q6fCA/ABfCKpa3AVtpUKTNKGQ== dependencies: - "@typescript-eslint/types" "4.14.2" + "@typescript-eslint/types" "4.17.0" eslint-visitor-keys "^2.0.0" "@visx/group@1.7.0": @@ -3301,19 +3229,11 @@ prop-types "^15.6.1" resize-observer-polyfill "1.5.1" -abab@^2.0.0, abab@^2.0.3, abab@^2.0.5: +abab@^2.0.3, abab@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a" integrity sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q== -acorn-globals@^4.3.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" - integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== - dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" - acorn-globals@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" @@ -3336,11 +3256,6 @@ acorn-node@^1.6.1: acorn-walk "^7.0.0" xtend "^4.0.2" -acorn-walk@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.2.0.tgz#123cb8f3b84c2171f1f7fb252615b1c78a6b1a8c" - integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA== - acorn-walk@^7.0.0, acorn-walk@^7.1.1: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" @@ -3351,11 +3266,6 @@ acorn-walk@^8.0.0: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.0.2.tgz#d4632bfc63fd93d0f15fd05ea0e984ffd3f5a8c3" integrity sha512-+bpA9MJsHdZ4bgfDcpk0ozQyhhVct7rzOmO0s1IIr0AGGgKBljss8n2zp11rRP2wid5VGeh04CgeKzgat5/25A== -acorn@^6.0.1, acorn@^6.0.4: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== - acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" @@ -3620,10 +3530,10 @@ array-differ@^3.0.0: resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== -array-equal@^1.0.0: +array-filter@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-1.0.0.tgz#baf79e62e6ef4c2a4c0b831232daffec251f9d83" + integrity sha1-uveeYubvTCpMC4MSMtr/7CUfnYM= array-includes@^3.1.1: version "3.1.1" @@ -3698,6 +3608,16 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +assert@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32" + integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A== + dependencies: + es6-object-assign "^1.1.0" + is-nan "^1.2.1" + object-is "^1.0.1" + util "^0.12.0" + assert@^1.1.1: version "1.5.0" resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" @@ -3743,11 +3663,6 @@ astral-regex@^2.0.0: resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - async@0.9.x: version "0.9.2" resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" @@ -3795,6 +3710,13 @@ autoprefixer@10.2.5: normalize-range "^0.1.2" postcss-value-parser "^4.1.0" +available-typed-arrays@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.2.tgz#6b098ca9d8039079ee3f77f7b783c4480ba513f5" + integrity sha512-XWX3OX8Onv97LMk/ftVyBibpGwY5a8SmuxZPzeOxqmuEqUCOM9ZE+uIaD1VNJ5QnvU2UQusvmKbuM1FR8QWGfQ== + dependencies: + array-filter "^1.0.0" + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -3875,16 +3797,6 @@ babel-plugin-extract-import-names@1.6.22: dependencies: "@babel/helper-plugin-utils" "7.10.4" -babel-plugin-istanbul@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" - integrity sha512-5LphC0USA8t4i1zCtjbbNb6jJj/9+X6P37Qfirc/70EQ34xKlMW+a1RHGwxGI+SwWpNwZ27HqvzAobeqaXwiZw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - find-up "^3.0.0" - istanbul-lib-instrument "^3.3.0" - test-exclude "^5.2.3" - babel-plugin-istanbul@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" @@ -4038,6 +3950,18 @@ before-after-hook@^2.1.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635" integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A== +better-path-resolve@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/better-path-resolve/-/better-path-resolve-1.0.0.tgz#13a35a1104cdd48a7b74bf8758f96a1ee613f99d" + integrity sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g== + dependencies: + is-windows "^1.0.0" + +big-integer@^1.6.16: + version "1.6.48" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.48.tgz#8fd88bd1632cba4a1c8c3e3d7159f08bb95b4b9e" + integrity sha512-j51egjPa7/i+RdiRuJbPdJ2FIUYYPhvYLjzoYbcMMm62ooO6F94fETG4MTs46zPAF9Brs04OajboA/qTGuz78w== + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -4048,13 +3972,6 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== -bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - bl@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489" @@ -4064,33 +3981,33 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" -blitz@0.33.1: - version "0.33.1" - resolved "https://registry.yarnpkg.com/blitz/-/blitz-0.33.1.tgz#4a4cccb9bd1e6633fd6e17b3258656289f651a6e" - integrity sha512-1SfQmtWXRGtu63rqK3Rb3B1V6WdOiBlF2ruZX3zRjiP0FFC8wuIoAX5qiiVEKWO6te3b6XHsxaiwW0Zcn7Q7JA== - dependencies: - "@blitzjs/babel-preset" "0.33.1" - "@blitzjs/cli" "0.33.1" - "@blitzjs/config" "0.33.1" - "@blitzjs/core" "0.33.1" - "@blitzjs/display" "0.33.1" - "@blitzjs/generator" "0.33.1" - "@blitzjs/installer" "0.33.1" - "@blitzjs/server" "0.33.1" +blitz@0.34.0: + version "0.34.0" + resolved "https://registry.yarnpkg.com/blitz/-/blitz-0.34.0.tgz#f5672c4f86fb5cac517687221220ddd0b6938372" + integrity sha512-+rQnOSfCCwuRxRALwi/tXpTUYXZvwW2J0nxhW3y1WvxZspBGSC5DKo+O5FBM/JgsqwrbQaBQTZUzYPx3Llvi4Q== + dependencies: + "@blitzjs/babel-preset" "0.34.0" + "@blitzjs/cli" "0.34.0" + "@blitzjs/config" "0.34.0" + "@blitzjs/core" "0.34.0" + "@blitzjs/display" "0.34.0" + "@blitzjs/generator" "0.34.0" + "@blitzjs/installer" "0.34.0" + "@blitzjs/server" "0.34.0" "@testing-library/jest-dom" "5.11.9" - "@testing-library/react" "^11.2.3" + "@testing-library/react" "11.2.5" "@testing-library/react-hooks" "^4.0.1" - "@types/jest" "^26.0.20" + "@types/jest" "26.0.20" chalk "^4.1.0" envinfo "^7.7.3" - eslint-config-blitz "0.33.1" + eslint-config-blitz "0.34.0" jest "^26.6.3" - jest-environment-jsdom-fourteen "^1.0.1" jest-watch-typeahead "^0.6.1" os-name "^4.0.0" pkg-dir "^5.0.0" react-test-renderer "17.0.1" resolve-from "^5.0.0" + symlink-dir "4.1.0" ts-jest "26.5.0" bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: @@ -4153,6 +4070,19 @@ braces@^3.0.1, braces@~3.0.2: dependencies: fill-range "^7.0.1" +broadcast-channel@^3.4.1: + version "3.5.3" + resolved "https://registry.yarnpkg.com/broadcast-channel/-/broadcast-channel-3.5.3.tgz#c75c39d923ae8af6284a893bfdc8bd3996d2dd2d" + integrity sha512-OLOXfwReZa2AAAh9yOUyiALB3YxBe0QpThwwuyRHLgpl8bSznSDmV6Mz7LeBJg1VZsMcDcNMy7B53w12qHrIhQ== + dependencies: + "@babel/runtime" "^7.7.2" + detect-node "^2.0.4" + js-sha3 "0.8.0" + microseconds "0.2.0" + nano-time "1.0.0" + rimraf "3.0.2" + unload "2.2.0" + brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" @@ -4217,7 +4147,7 @@ browserify-sign@^4.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" -browserify-zlib@^0.2.0: +browserify-zlib@0.2.0, browserify-zlib@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== @@ -4480,7 +4410,7 @@ ccount@^1.0.0, ccount@^1.0.3: resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== -chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.1, chalk@^2.4.2: +chalk@2.4.2, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -4952,7 +4882,7 @@ console-table-printer@^2.7.5: dependencies: simple-wcswidth "^1.0.0" -constants-browserify@^1.0.0: +constants-browserify@1.0.0, constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= @@ -5217,22 +5147,15 @@ csso@^4.0.2: dependencies: css-tree "^1.0.0" -cssom@0.3.x, cssom@^0.3.4, cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - cssom@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== -cssstyle@^1.1.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.4.0.tgz#9d31328229d3c565c61e586b02041a28fccdccf1" - integrity sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA== - dependencies: - cssom "0.3.x" +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== cssstyle@^2.3.0: version "2.3.0" @@ -5278,15 +5201,6 @@ data-uri-to-buffer@3.0.1: resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== -data-urls@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== - dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" - data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -5498,6 +5412,11 @@ detect-newline@^3.0.0: resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== +detect-node@^2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.0.5.tgz#9d270aa7eaa5af0b72c4c9d9b814e7f4ce738b79" + integrity sha512-qi86tE6hRcFHy8jI1m2VG+LaPUR1LhqDa5G8tVjuUXmOrpuAgqsA1pN0+ldgr3aKUH+QLI9hCY/OcRYisERejw== + detect-port@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" @@ -5599,6 +5518,11 @@ dom-serializer@0: domelementtype "^2.0.1" entities "^2.0.0" +domain-browser@4.19.0: + version "4.19.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.19.0.tgz#1093e17c0a17dbd521182fe90d49ac1370054af1" + integrity sha512-fRA+BaAWOR/yr/t7T9E9GJztHPeFjj8U35ajyAjCDtAAnTn1Rc1f6W6VGPJrO1tkQv9zWu+JRof7z6oQtiYVFQ== + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -5614,13 +5538,6 @@ domelementtype@^2.0.1: resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.2.tgz#f3b6e549201e46f588b59463dd77187131fe6971" integrity sha512-wFwTwCVebUrMgGeAwRL/NhZtHAUyT9n9yg4IMDwf10+6iCMxSkVq9MGCVEH+QZWo1nNidy8kNvwmv4zWHDTqvA== -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== - dependencies: - webidl-conversions "^4.0.2" - domexception@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" @@ -5770,6 +5687,13 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== +encoding@0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" @@ -5872,6 +5796,11 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es6-object-assign@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c" + integrity sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw= + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -5882,7 +5811,7 @@ escape-goat@^2.0.0: resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: +escape-string-regexp@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== @@ -5897,17 +5826,10 @@ escape-string-regexp@^2.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== -escodegen@^1.11.0: - version "1.14.3" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" - integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== - dependencies: - esprima "^4.0.1" - estraverse "^4.2.0" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.6.1" +escape-string-regexp@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz#4683126b500b61762f2dbebace1806e8be31b1c8" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== escodegen@^2.0.0: version "2.0.0" @@ -5921,13 +5843,13 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-config-blitz@0.33.1: - version "0.33.1" - resolved "https://registry.yarnpkg.com/eslint-config-blitz/-/eslint-config-blitz-0.33.1.tgz#122bd0606c2f62cbe1d30cf9b926bcbcdd760e57" - integrity sha512-ObSP361SlIa9EEoYZWkj21M6/Qu+dwEXtJrd0BH8OrWDGJ7kgFIwI/zKrwTAirbiOZFQGKRQYedXo91YtNDSlw== +eslint-config-blitz@0.34.0: + version "0.34.0" + resolved "https://registry.yarnpkg.com/eslint-config-blitz/-/eslint-config-blitz-0.34.0.tgz#8aa8c45b0ff25db80a8754cd2f6f8c57f708a452" + integrity sha512-Hz8F2ATZ3wce41iEZSVfk2PjBdFHO7qlnH34gBdIPb4CXPelXKHXIk5kUS6ne55qeWMlEm8xEzRR7zAZnDlW9A== dependencies: - "@typescript-eslint/eslint-plugin" "~4.14.0" - "@typescript-eslint/parser" "~4.14.0" + "@typescript-eslint/eslint-plugin" "4.17.0" + "@typescript-eslint/parser" "4.17.0" babel-eslint "~10.1.0" eslint-config-react-app "~6.0.0" eslint-plugin-cypress "~2.11.2" @@ -6139,7 +6061,7 @@ esrecurse@^4.3.0: dependencies: estraverse "^5.2.0" -estraverse@^4.1.1, estraverse@^4.2.0: +estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -6421,11 +6343,6 @@ file-loader@6.2.0: loader-utils "^2.0.0" schema-utils "^3.0.0" -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - filelist@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.2.tgz#80202f21462d4d1c2e214119b1807c1bc0380e5b" @@ -6450,15 +6367,6 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -find-cache-dir@3.3.1, find-cache-dir@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" - integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - find-cache-dir@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" @@ -6468,6 +6376,15 @@ find-cache-dir@^2.0.0: make-dir "^2.0.0" pkg-dir "^3.0.0" +find-cache-dir@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" + integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + find-up@5.0.0, find-up@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -6544,18 +6461,16 @@ focus-visible@5.2.0: resolved "https://registry.yarnpkg.com/focus-visible/-/focus-visible-5.2.0.tgz#3a9e41fccf587bd25dcc2ef045508284f0a4d6b3" integrity sha512-Rwix9pBtC1Nuy5wysTmKy+UjbDJpIfg8eHjw0rjZ1mX4GNLz1Bmd16uDpI3Gk1i70Fgcs8Csg2lPm8HULFg9DQ== -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + integrity sha1-C+4AUBiusmDQo6865ljdATbsG5k= + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" @@ -6592,10 +6507,10 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -framer-motion@4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-4.1.3.tgz#fdde56885910f516233233073f8f0ed6aab6492e" - integrity sha512-WJ3iZiMgzR3cf/W5/o5OwGyNeXvjuIriItPnDtqbAGgd8rCq5ysAW3RS4cC2i2wVA9EfrlxWmosTt+lKhaVI3Q== +framer-motion@4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-4.1.5.tgz#451ac3a41c682190bf247d5e209e24572e45cfc3" + integrity sha512-ExZ/BGKecRDs91W9ZebbCW5HgO8PaVT5V2ZUs28/jqLyef7VrTho0J5BRH/oAvwc9Qdnl0nRS/YRJWNOCt/PYQ== dependencies: framesync "5.3.0" hey-listen "^1.0.8" @@ -6673,24 +6588,11 @@ fs-mkdirp-stream@^1.0.0: graceful-fs "^4.1.11" through2 "^2.0.3" -fs-readdir-recursive@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" - integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== - fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fsevents@^1.2.7: - version "1.2.13" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" - integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - fsevents@^2.1.2, fsevents@~2.3.1: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" @@ -7313,13 +7215,6 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== -html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== - dependencies: - whatwg-encoding "^1.0.1" - html-encoding-sniffer@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" @@ -7389,7 +7284,7 @@ http2-wrapper@^1.0.0-beta.5.2: quick-lru "^5.1.1" resolve-alpn "^1.0.0" -https-browserify@^1.0.0: +https-browserify@1.0.0, https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= @@ -7429,6 +7324,13 @@ iconv-lite@0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" +iconv-lite@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" + integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + ieee754@^1.1.13, ieee754@^1.1.4: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -7587,13 +7489,6 @@ internal-slot@^1.0.2: has "^1.0.3" side-channel "^1.0.2" -invariant@^2.2.4: - version "2.2.4" - resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" - integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== - dependencies: - loose-envify "^1.0.0" - is-absolute@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" @@ -7634,6 +7529,13 @@ is-alphanumerical@^1.0.0: is-alphabetical "^1.0.0" is-decimal "^1.0.0" +is-arguments@^1.0.4: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9" + integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg== + dependencies: + call-bind "^1.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -7673,16 +7575,16 @@ is-buffer@^2.0.0: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== -is-callable@^1.1.3, is-callable@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" - integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== - is-callable@^1.1.4, is-callable@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9" integrity sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA== +is-callable@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e" + integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ== + is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -7805,6 +7707,11 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== +is-generator-function@^1.0.7: + version "1.0.8" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.8.tgz#dfb5c2b120e02b0a8d9d2c6806cd5621aa922f7b" + integrity sha512-2Omr/twNtufVZFr1GhxjOMFPAj2sjc/dKaIqBhvo4qciXfJmITGH6ZGd8eZYNHza8t1y0e01AuqRhJwfWp26WQ== + is-glob@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -7844,6 +7751,14 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-nan@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d" + integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + is-negated-glob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" @@ -7977,6 +7892,17 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.1" +is-typed-array@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e" + integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.2" + es-abstract "^1.18.0-next.2" + foreach "^2.0.5" + has-symbols "^1.0.1" + is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -8004,7 +7930,7 @@ is-whitespace-character@^1.0.0: resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== -is-windows@^1.0.1, is-windows@^1.0.2: +is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== @@ -8068,29 +7994,11 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-lib-coverage@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" - integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== - istanbul-lib-coverage@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec" integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg== -istanbul-lib-instrument@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" - integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== - dependencies: - "@babel/generator" "^7.4.0" - "@babel/parser" "^7.4.3" - "@babel/template" "^7.4.0" - "@babel/traverse" "^7.4.3" - "@babel/types" "^7.4.0" - istanbul-lib-coverage "^2.0.5" - semver "^6.0.0" - istanbul-lib-instrument@^4.0.0, istanbul-lib-instrument@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" @@ -8217,18 +8125,6 @@ jest-each@^26.6.2: jest-util "^26.6.2" pretty-format "^26.6.2" -jest-environment-jsdom-fourteen@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom-fourteen/-/jest-environment-jsdom-fourteen-1.0.1.tgz#4cd0042f58b4ab666950d96532ecb2fc188f96fb" - integrity sha512-DojMX1sY+at5Ep+O9yME34CdidZnO3/zfPh8UW+918C5fIZET5vCjfkegixmsi7AtdYfkr4bPlIzmWnlvQkP7Q== - dependencies: - "@jest/environment" "^24.3.0" - "@jest/fake-timers" "^24.3.0" - "@jest/types" "^24.3.0" - jest-mock "^24.0.0" - jest-util "^24.0.0" - jsdom "^14.1.0" - jest-environment-jsdom@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz#78d09fe9cf019a357009b9b7e1f101d23bd1da3e" @@ -8259,25 +8155,6 @@ jest-get-type@^26.3.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" integrity sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig== -jest-haste-map@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-24.9.0.tgz#b38a5d64274934e21fa417ae9a9fbeb77ceaac7d" - integrity sha512-kfVFmsuWui2Sj1Rp1AJ4D9HqJwE4uwTlS/vO+eRUaMmd54BFpli2XhMQnPC2k4cHFVbB2Q2C+jtI1AGLgEnCjQ== - dependencies: - "@jest/types" "^24.9.0" - anymatch "^2.0.0" - fb-watchman "^2.0.0" - graceful-fs "^4.1.15" - invariant "^2.2.4" - jest-serializer "^24.9.0" - jest-util "^24.9.0" - jest-worker "^24.9.0" - micromatch "^3.1.10" - sane "^4.0.3" - walker "^1.0.7" - optionalDependencies: - fsevents "^1.2.7" - jest-haste-map@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" @@ -8341,20 +8218,6 @@ jest-matcher-utils@^26.6.2: jest-get-type "^26.3.0" pretty-format "^26.6.2" -jest-message-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-24.9.0.tgz#527f54a1e380f5e202a8d1149b0ec872f43119e3" - integrity sha512-oCj8FiZ3U0hTP4aSui87P4L4jC37BtQwUMqk+zk/b11FR19BJDeZsZAvIHutWnmtw7r85UmR3CEWZ0HWU2mAlw== - dependencies: - "@babel/code-frame" "^7.0.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - "@types/stack-utils" "^1.0.1" - chalk "^2.0.1" - micromatch "^3.1.10" - slash "^2.0.0" - stack-utils "^1.0.1" - jest-message-util@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.6.2.tgz#58173744ad6fc0506b5d21150b9be56ef001ca07" @@ -8370,13 +8233,6 @@ jest-message-util@^26.6.2: slash "^3.0.0" stack-utils "^2.0.2" -jest-mock@^24.0.0, jest-mock@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-24.9.0.tgz#c22835541ee379b908673ad51087a2185c13f1c6" - integrity sha512-3BEYN5WbSq9wd+SyLDES7AHnjH9A/ROBwmz7l2y+ol+NtSFO8DYiEBzoO1CeFc9a8DYy10EO4dDFVv/wN3zl1w== - dependencies: - "@jest/types" "^24.9.0" - jest-mock@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" @@ -8390,11 +8246,6 @@ jest-pnp-resolver@^1.2.2: resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz#b704ac0ae028a89108a4d040b3f919dfddc8e33c" integrity sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w== -jest-regex-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-24.9.0.tgz#c13fb3380bde22bf6575432c493ea8fe37965636" - integrity sha512-05Cmb6CuxaA+Ys6fjr3PhvV3bGQmO+2p2La4hFbU+W5uOc479f7FdLXUWXw4pYMAhhSZIuKHwSXSu6CsSBAXQA== - jest-regex-util@^26.0.0: version "26.0.0" resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" @@ -8482,11 +8333,6 @@ jest-runtime@^26.6.3: strip-bom "^4.0.0" yargs "^15.4.1" -jest-serializer@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.9.0.tgz#e6d7d7ef96d31e8b9079a714754c5d5c58288e73" - integrity sha512-DxYipDr8OvfrKH3Kel6NdED3OXxjvxXZ1uIY2I9OFbGg+vUkkg7AGvi65qbhbWNPvDckXmzMPbK3u3HaDO49bQ== - jest-serializer@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" @@ -8517,24 +8363,6 @@ jest-snapshot@^26.6.2: pretty-format "^26.6.2" semver "^7.3.2" -jest-util@^24.0.0, jest-util@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-24.9.0.tgz#7396814e48536d2e85a37de3e4c431d7cb140162" - integrity sha512-x+cZU8VRmOJxbA1K5oDBdxQmdq0OIdADarLxk0Mq+3XS4jgvhG/oKGWcIDCtPG0HgjxOYvF+ilPJQsAyXfbNOg== - dependencies: - "@jest/console" "^24.9.0" - "@jest/fake-timers" "^24.9.0" - "@jest/source-map" "^24.9.0" - "@jest/test-result" "^24.9.0" - "@jest/types" "^24.9.0" - callsites "^3.0.0" - chalk "^2.0.1" - graceful-fs "^4.1.15" - is-ci "^2.0.0" - mkdirp "^0.5.1" - slash "^2.0.0" - source-map "^0.6.0" - jest-util@^26.1.0, jest-util@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" @@ -8585,13 +8413,14 @@ jest-watcher@^26.3.0, jest-watcher@^26.6.2: jest-util "^26.6.2" string-length "^4.0.1" -jest-worker@24.9.0, jest-worker@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.9.0.tgz#5dbfdb5b2d322e98567898238a9697bcce67b3e5" - integrity sha512-51PE4haMSXcHohnSMdM42anbvZANYTqMrr52tVKPqqsPJMzoP6FYYDVqahX/HrAoKEKz3uUPzSvKs9A3qR4iVw== +jest-worker@27.0.0-next.5: + version "27.0.0-next.5" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.0-next.5.tgz#5985ee29b12a4e191f4aae4bb73b97971d86ec28" + integrity sha512-mk0umAQ5lT+CaOJ+Qp01N6kz48sJG2kr2n1rX0koqKf6FIygQV0qLOdN9SCYID4IVeSigDOcPeGLozdMLYfb5g== dependencies: + "@types/node" "*" merge-stream "^2.0.0" - supports-color "^6.1.0" + supports-color "^8.0.0" jest-worker@^26.6.2: version "26.6.2" @@ -8611,6 +8440,11 @@ jest@^26.6.3: import-local "^3.0.2" jest-cli "^26.6.3" +js-sha3@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -8662,38 +8496,6 @@ jscodeshift@0.11.0: temp "^0.8.1" write-file-atomic "^2.3.0" -jsdom@^14.1.0: - version "14.1.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-14.1.0.tgz#916463b6094956b0a6c1782c94e380cd30e1981b" - integrity sha512-O901mfJSuTdwU2w3Sn+74T+RnDVP+FuV5fH8tcPWyqrseRAb0s5xOtPgCFiPOtLcyK7CLIJwPyD83ZqQWvA5ng== - dependencies: - abab "^2.0.0" - acorn "^6.0.4" - acorn-globals "^4.3.0" - array-equal "^1.0.0" - cssom "^0.3.4" - cssstyle "^1.1.1" - data-urls "^1.1.0" - domexception "^1.0.1" - escodegen "^1.11.0" - html-encoding-sniffer "^1.0.2" - nwsapi "^2.1.3" - parse5 "5.1.0" - pn "^1.1.0" - request "^2.88.0" - request-promise-native "^1.0.5" - saxes "^3.1.9" - symbol-tree "^3.2.2" - tough-cookie "^2.5.0" - w3c-hr-time "^1.0.1" - w3c-xmlserializer "^1.1.2" - webidl-conversions "^4.0.2" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^7.0.0" - ws "^6.1.2" - xml-name-validator "^3.0.0" - jsdom@^16.4.0: version "16.5.1" resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.5.1.tgz#4ced6bbd7b77d67fb980e64d9e3e6fb900f97dd6" @@ -8746,11 +8548,6 @@ json-buffer@3.0.1: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - json-parse-even-better-errors@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" @@ -9050,16 +8847,6 @@ load-json-file@^2.0.0: pify "^2.0.0" strip-bom "^3.0.0" -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - load-plugin@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/load-plugin/-/load-plugin-3.0.0.tgz#8f3ce57cf4e5111639911012487bc1c2ba3d0e6c" @@ -9278,7 +9065,7 @@ longest-streak@^2.0.1: resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-2.0.4.tgz#b8599957da5b5dab64dee3fe316fa774597d90e4" integrity sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg== -loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0: +loose-envify@^1.1.0, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== @@ -9385,6 +9172,14 @@ markdown-table@^2.0.0: dependencies: repeat-string "^1.0.0" +match-sorter@^6.0.2: + version "6.3.0" + resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.3.0.tgz#454a1b31ed218cddbce6231a0ecb5fdc549fed01" + integrity sha512-efYOf/wUpNb8FgNY+cOD2EIJI1S5I7YPKsw0LBp7wqPh5pmMS6i/wr3ZWwfwrAw1NvqTA2KUReVRWDX84lUcOQ== + dependencies: + "@babel/runtime" "^7.12.5" + remove-accents "0.4.2" + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -9551,6 +9346,11 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" +microseconds@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/microseconds/-/microseconds-0.2.0.tgz#233b25f50c62a65d861f978a4a4f8ec18797dc39" + integrity sha512-n7DHHMjR1avBbSpsTBj6fmMGh2AGrifVV4e+WYc3Q9lO+xnSZ3NyhcBND3vzzatt05LFhoKFRxrIyklmLlUtyA== + miller-rabin@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" @@ -9655,7 +9455,7 @@ mkdirp@1.x, mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== -mkdirp@^0.5.1, mkdirp@~0.5.1: +mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== @@ -9714,10 +9514,12 @@ multimatch@^5.0.0: arrify "^2.0.1" minimatch "^3.0.4" -nan@^2.12.1: - version "2.14.2" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" - integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== +nano-time@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/nano-time/-/nano-time-1.0.0.tgz#b0554f69ad89e22d0907f7a12b0993a5d96137ef" + integrity sha1-sFVPaa2J4i0JB/ehKwmTpdlhN+8= + dependencies: + big-integer "^1.6.16" nanoassert@^1.0.0: version "1.1.0" @@ -9788,46 +9590,58 @@ next-themes@0.0.14: resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.0.14.tgz#2b9861990bc453149e23d8e6ef1a25a119e36675" integrity sha512-x09OaM+wg3SIlEjOv8B21aw/E36jxTtfW3Dm/DPwMsSMluGt7twe1LigA6nc+mXP1u0qu9MxBaIrPPH6UTiKnA== -next@10.0.9: - version "10.0.9" - resolved "https://registry.yarnpkg.com/next/-/next-10.0.9.tgz#ad5d8e0368fee8363cdfd64d22dfbf71f683ae66" - integrity sha512-HyoVjYydcM6LaFAUOHSxVQCcKOsIimVO/IKXCuWUu1rr6DDgXbWNg/8ckH084qD46MOYlLzjViiZ3KCmNQL4Cw== +"next@npm:@blitzjs/next@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@blitzjs/next/-/next-0.34.0.tgz#0094c8eedf22a0c0e8c65dafd25cced440a42732" + integrity sha512-rAqGufaov9OooexcNjcWN/zU51zdXEpthTlPATT+gVKYvA+ZJ/+AgT8YGZG4gSLN9VIY1wciiZTSgKhZrWM1wg== dependencies: "@babel/runtime" "7.12.5" "@hapi/accept" "5.0.1" - "@next/env" "10.0.9" - "@next/polyfill-module" "10.0.9" - "@next/react-dev-overlay" "10.0.9" - "@next/react-refresh-utils" "10.0.9" + "@next/env" "10.1.3" + "@next/polyfill-module" "10.1.3" + "@next/react-dev-overlay" "10.1.3" + "@next/react-refresh-utils" "10.1.3" "@opentelemetry/api" "0.14.0" + assert "2.0.0" ast-types "0.13.2" + browserify-zlib "0.2.0" browserslist "4.16.1" buffer "5.6.0" caniuse-lite "^1.0.30001179" chalk "2.4.2" chokidar "3.5.1" + constants-browserify "1.0.0" crypto-browserify "3.12.0" cssnano-simple "1.2.2" + domain-browser "4.19.0" + encoding "0.1.13" etag "1.8.1" - find-cache-dir "3.3.1" get-orientation "1.1.2" - jest-worker "24.9.0" + https-browserify "1.0.0" + jest-worker "27.0.0-next.5" native-url "0.3.4" node-fetch "2.6.1" node-html-parser "1.4.9" node-libs-browser "^2.2.1" + os-browserify "0.3.0" p-limit "3.1.0" path-browserify "1.0.1" pnp-webpack-plugin "1.6.4" postcss "8.1.7" process "0.11.10" prop-types "15.7.2" + querystring-es3 "0.2.1" raw-body "2.4.1" react-is "16.13.1" react-refresh "0.8.3" stream-browserify "3.0.0" + stream-http "3.1.1" + string_decoder "1.3.0" styled-jsx "3.3.2" + timers-browserify "2.0.12" + tty-browserify "0.0.1" use-subscription "1.5.1" + util "0.12.3" vm-browserify "1.1.2" watchpack "2.1.1" @@ -10045,7 +9859,7 @@ null-loader@4.0.1: loader-utils "^2.0.0" schema-utils "^3.0.0" -nwsapi@^2.1.3, nwsapi@^2.2.0: +nwsapi@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.0.tgz#204879a9e3d068ff2a55139c2c772780681a38b7" integrity sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ== @@ -10084,6 +9898,14 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== +object-is@^1.0.1: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + object-keys@^1.0.12, object-keys@^1.0.9, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -10143,15 +9965,6 @@ object.getownpropertydescriptors@^2.1.0: define-properties "^1.1.3" es-abstract "^1.17.0-next.1" -object.getownpropertydescriptors@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7" - integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.18.0-next.2" - object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" @@ -10238,7 +10051,7 @@ ordered-read-streams@^1.0.0: dependencies: readable-stream "^2.0.1" -os-browserify@^0.3.0: +os-browserify@0.3.0, os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= @@ -10467,14 +10280,6 @@ parse-json@^2.2.0: dependencies: error-ex "^1.2.0" -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - parse-json@^5.0.0: version "5.1.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" @@ -10499,11 +10304,6 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= -parse5@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" - integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== - parse5@6.0.1, parse5@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" @@ -10597,13 +10397,6 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -10647,11 +10440,6 @@ pify@^2.0.0, pify@^2.3.0: resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= - pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" @@ -10709,11 +10497,6 @@ pluralize@^8.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== - pnp-webpack-plugin@1.6.4: version "1.6.4" resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" @@ -11045,7 +10828,7 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== -querystring-es3@^0.2.0: +querystring-es3@0.2.1, querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= @@ -11165,12 +10948,14 @@ react-player@2.9.0: prop-types "^15.7.2" react-fast-compare "^3.0.1" -react-query@2.5.12: - version "2.5.12" - resolved "https://registry.yarnpkg.com/react-query/-/react-query-2.5.12.tgz#f48be402886b9d95f892d836c2476ee3fdd3e479" - integrity sha512-ni2Hrz8tU/WCc5EQj+QB0jzSgxKdVL3tznFvTrXDmGjTxFj9hg1vXoxEPAn8d4pXy+lgPAflcjxht3IakUgHzg== +react-query@3.13.9: + version "3.13.9" + resolved "https://registry.yarnpkg.com/react-query/-/react-query-3.13.9.tgz#52f3e29176eb115248b4c6e3b5c0bea7b60322d4" + integrity sha512-gPJ2ekm2NA911C9Fc18h///WcE7b4edf5K1JGtyi8kTSv0q9FyM2V+ttTbBAKafTMbbYh4Xg2wqXlR+/cIUZPw== dependencies: - ts-toolbelt "^6.9.4" + "@babel/runtime" "^7.5.5" + broadcast-channel "^3.4.1" + match-sorter "^6.0.2" react-reconciler@^0.24.0: version "0.24.0" @@ -11244,14 +11029,6 @@ read-pkg-up@^2.0.0: find-up "^2.0.0" read-pkg "^2.0.0" -read-pkg-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" - integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== - dependencies: - find-up "^3.0.0" - read-pkg "^3.0.0" - read-pkg-up@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" @@ -11270,15 +11047,6 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - read-pkg@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" @@ -11345,13 +11113,6 @@ readline@1.3.0: resolved "https://registry.yarnpkg.com/readline/-/readline-1.3.0.tgz#c580d77ef2cfc8752b132498060dc9793a7ac01c" integrity sha1-xYDXfvLPyHUrEySYBg3JeTp6wBw= -realpath-native@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" - integrity sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA== - dependencies: - util.promisify "^1.0.0" - recast@0.17.2: version "0.17.2" resolved "https://registry.yarnpkg.com/recast/-/recast-0.17.2.tgz#f18f18cf20bf3fad4522621a7f9c2ada37276814" @@ -11612,6 +11373,11 @@ remark-stringify@^8.1.0: unherit "^1.0.4" xtend "^4.0.1" +remove-accents@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.4.2.tgz#0a43d3aaae1e80db919e07ae254b285d9e1c7bb5" + integrity sha1-CkPTqq4egNuRngeuJUsoXZ4ce7U= + remove-bom-buffer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" @@ -11634,6 +11400,13 @@ remove-trailing-separator@^1.0.1: resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= +rename-overwrite@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/rename-overwrite/-/rename-overwrite-3.1.2.tgz#a176b9b64081aca8a7396d9f442e69eaa0caa30a" + integrity sha512-hRjXzyL+g9uBmRDpX8m/00zwtso+e3XQsOgsCJGGJOQm+paoNZCKBS8Hm9x4WFfPCv2W0Ql5HOFqHlPiAO/UDw== + dependencies: + rimraf "^3.0.2" + repeat-element@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" @@ -11661,7 +11434,7 @@ request-promise-core@1.1.4: dependencies: lodash "^4.17.19" -request-promise-native@^1.0.5, request-promise-native@^1.0.9: +request-promise-native@^1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== @@ -11670,7 +11443,7 @@ request-promise-native@^1.0.5, request-promise-native@^1.0.9: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.88.0, request@^2.88.2: +request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -11849,7 +11622,7 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^3.0.0, rimraf@^3.0.2: +rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== @@ -11905,7 +11678,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -11930,13 +11703,6 @@ sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -saxes@^3.1.9: - version "3.1.11" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" - integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== - dependencies: - xmlchars "^2.1.1" - saxes@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" @@ -12155,11 +11921,6 @@ sisteransi@^1.0.5: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -12367,13 +12128,6 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== -stack-utils@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.4.tgz#4b600971dcfc6aed0cbdf2a8268177cc916c87c8" - integrity sha512-IPDJfugEGbfizBwBZRZ3xpccMdRyP5lqsBWXGQWimVjua/ccLCeMOAVjlc1R7LxFjo5sEDhyNIXd8mo/AiDS9w== - dependencies: - escape-string-regexp "^2.0.0" - stack-utils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.3.tgz#cd5f030126ff116b78ccb3c027fe302713b61277" @@ -12434,6 +12188,16 @@ stream-combiner@~0.0.4: dependencies: duplexer "~0.1.1" +stream-http@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.1.1.tgz#0370a8017cf8d050b9a8554afe608f043eaff564" + integrity sha512-S7OqaYu0EkFpgeGFb/NPOoPLxFko7TPqtEeFg5DXPB4v/KETHG0Ln6fRFrNezoelpaDKmycEmmZ81cC9DAwgYg== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.4" + readable-stream "^3.6.0" + xtend "^4.0.2" + stream-http@^2.7.2: version "2.8.3" resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" @@ -12558,7 +12322,7 @@ string.prototype.trimstart@^1.0.4: call-bind "^1.0.2" define-properties "^1.1.3" -string_decoder@^1.0.0, string_decoder@^1.1.1: +string_decoder@1.3.0, string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -12752,6 +12516,13 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + supports-hyperlinks@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz#71daedf36cc1060ac5100c351bb3da48c29c0ef7" @@ -12792,11 +12563,20 @@ svgo@^1.2.2: unquote "~1.1.1" util.promisify "~1.0.0" -symbol-tree@^3.2.2, symbol-tree@^3.2.4: +symbol-tree@^3.2.4: version "3.2.4" resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +symlink-dir@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/symlink-dir/-/symlink-dir-4.1.0.tgz#655bc0573f6a359fe4f07265dfb8c2ddb98d4fa7" + integrity sha512-yT256U0E+AcFxbSUc0suJXTdOjVbVk5MmBLzqD+unQRwQbcMhTvTZnG/3UZZknemOK8+nQz2lTBZs0+uYS2apg== + dependencies: + better-path-resolve "^1.0.0" + graceful-fs "^4.1.11" + rename-overwrite "^3.0.0" + table@^6.0.4: version "6.0.7" resolved "https://registry.yarnpkg.com/table/-/table-6.0.7.tgz#e45897ffbcc1bcf9e8a87bf420f2c9e5a7a52a34" @@ -12937,16 +12717,6 @@ ternary-stream@^3.0.0: merge-stream "^2.0.0" through2 "^3.0.1" -test-exclude@^5.2.3: - version "5.2.3" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" - integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== - dependencies: - glob "^7.1.3" - minimatch "^3.0.4" - read-pkg-up "^4.0.0" - require-main-filename "^2.0.0" - test-exclude@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" @@ -13018,7 +12788,7 @@ through@2, through@^2.3.8, through@~2.3, through@~2.3.1: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -timers-browserify@^2.0.4: +timers-browserify@2.0.12, timers-browserify@^2.0.4: version "2.0.12" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== @@ -13127,7 +12897,7 @@ totalist@^1.0.0: resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== -tough-cookie@^2.3.3, tough-cookie@^2.5.0, tough-cookie@~2.5.0: +tough-cookie@^2.3.3, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -13217,11 +12987,6 @@ ts-pnp@^1.1.6: resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== -ts-toolbelt@^6.9.4: - version "6.15.5" - resolved "https://registry.yarnpkg.com/ts-toolbelt/-/ts-toolbelt-6.15.5.tgz#cb3b43ed725cb63644782c64fbcad7d8f28c0a83" - integrity sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A== - tsconfig-paths@3.9.0, tsconfig-paths@^3.9.0: version "3.9.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b" @@ -13271,6 +13036,11 @@ tty-browserify@0.0.0: resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= +tty-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811" + integrity sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw== + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -13604,6 +13374,14 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== +unload@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/unload/-/unload-2.2.0.tgz#ccc88fdcad345faa06a92039ec0f80b488880ef7" + integrity sha512-B60uB5TNBLtN6/LsgAf3udH9saB5p7gqJwcFfbOEZ8BcBHnGwCf6G/TGiEqkRAxX7zAFIUtzdrXQSdL3Q/wqNA== + dependencies: + "@babel/runtime" "^7.6.2" + detect-node "^2.0.4" + unpipe@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -13701,17 +13479,6 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util.promisify@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.1.1.tgz#77832f57ced2c9478174149cae9b96e9918cd54b" - integrity sha512-/s3UsZUrIfa6xDhr7zZhnE9SLQ5RIXyYfiVnMMyMDzOc8WhWN4Nbh36H842OyurKbCDAesZOJaVyvmSl6fhGQw== - dependencies: - call-bind "^1.0.0" - define-properties "^1.1.3" - for-each "^0.3.3" - has-symbols "^1.0.1" - object.getownpropertydescriptors "^2.1.1" - util.promisify@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.1.tgz#6baf7774b80eeb0f7520d8b81d07982a59abbaee" @@ -13729,6 +13496,18 @@ util@0.10.3: dependencies: inherits "2.0.1" +util@0.12.3, util@^0.12.0: + version "0.12.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888" + integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + safe-buffer "^5.1.2" + which-typed-array "^1.1.2" + util@^0.11.0: version "0.11.1" resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" @@ -13899,22 +13678,13 @@ vm-browserify@1.1.2, vm-browserify@^1.0.1: resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== -w3c-hr-time@^1.0.1, w3c-hr-time@^1.0.2: +w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== dependencies: browser-process-hrtime "^1.0.0" -w3c-xmlserializer@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" - integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== - dependencies: - domexception "^1.0.1" - webidl-conversions "^4.0.2" - xml-name-validator "^3.0.0" - w3c-xmlserializer@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" @@ -13979,14 +13749,14 @@ webpack-bundle-analyzer@4.3.0: sirv "^1.0.7" ws "^7.3.1" -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: +whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== dependencies: iconv-lite "0.4.24" -whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: +whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== @@ -14025,6 +13795,19 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= +which-typed-array@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff" + integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA== + dependencies: + available-typed-arrays "^1.0.2" + call-bind "^1.0.0" + es-abstract "^1.18.0-next.1" + foreach "^2.0.5" + function-bind "^1.1.1" + has-symbols "^1.0.1" + is-typed-array "^1.1.3" + which@^1.2.10, which@^1.2.9: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -14090,15 +13873,6 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write-file-atomic@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.1.tgz#d0b05463c188ae804396fd5ab2a370062af87529" - integrity sha512-TGHFeZEZMnv+gBFRfjAcxL5bPHrsGKtnb4qsFAws7/vlh+QfwAaySIw4AXP9ZskTTh5GWu3FLuJhsWVdiJPGvg== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - write-file-atomic@^2.3.0: version "2.4.3" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" @@ -14118,13 +13892,6 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" -ws@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" - integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== - dependencies: - async-limiter "~1.0.0" - ws@^7, ws@^7.2.5: version "7.4.0" resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.0.tgz#a5dd76a24197940d4a8bb9e0e152bb4503764da7" @@ -14150,7 +13917,7 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== -xmlchars@^2.1.1, xmlchars@^2.2.0: +xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== From f6ce373a6d70c043dc0893598a5430c82e76a995 Mon Sep 17 00:00:00 2001 From: Roshan Manuel <31125563+Roesh@users.noreply.github.com> Date: Mon, 19 Apr 2021 18:13:35 -0400 Subject: [PATCH 05/77] Remove Anonymous Functions Exports (#451) * typo fix Small typo fix: you'll need to do the chech => you'll need to do the check * Update session.create > session.$create * Update api routes doc examples - no anon exports * Edit preview mode doc examples - no anon exports * Change export name to handler * Change export name to handler --- app/pages/docs/api-routes.mdx | 15 ++++++++++----- app/pages/docs/preview-mode.mdx | 6 ++++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/app/pages/docs/api-routes.mdx b/app/pages/docs/api-routes.mdx index d141d7c..a31ee4f 100644 --- a/app/pages/docs/api-routes.mdx +++ b/app/pages/docs/api-routes.mdx @@ -19,11 +19,12 @@ For example, the following API route `app/api/hello.js` handles a `json` response: ```ts -export default (req: BlitzApiRequest, res: BlitzApiResponse) => { +const handler = (req: BlitzApiRequest, res: BlitzApiResponse) => { res.statusCode = 200 res.setHeader("Content-Type", "application/json") res.end(JSON.stringify({name: "John Doe"})) } +export default handler ``` For an API route to work, you need to export as default a function (a.k.a @@ -40,13 +41,14 @@ To handle different HTTP methods in an API route, you can use `req.method` in your request handler, like so: ```ts -export default (req: BlitzApiRequest, res: BlitzApiResponse) => { +const handler = (req: BlitzApiRequest, res: BlitzApiResponse) => { if (req.method === "POST") { // Process a POST request } else { // Handle any other HTTP method } } +export default handler ``` To fetch API endpoints, take a look into any of the examples at the start @@ -105,13 +107,14 @@ Dynamic API routes follow the same file naming rules used for `pages`. For example, the API route `app/api/post/[pid].js` has the following code: ```ts -export default (req: BlitzApiRequest, res: BlitzApiResponse) => { +const handler = (req: BlitzApiRequest, res: BlitzApiResponse) => { const { query: {pid}, } = req res.end(`Post: ${pid}`) } +export default handler ``` Now, a request to `/api/post/abc` will respond with the text: `Post: abc`. @@ -163,13 +166,14 @@ parameters will be added to the array, like so: An API route for `app/api/post/[...slug].js` could look like this: ```ts -export default (req: BlitzApiRequest, res: BlitzApiResponse) => { +const handler = (req: BlitzApiRequest, res: BlitzApiResponse) => { const { query: {slug}, } = req res.end(`Post: ${slug.join(", ")}`) } +export default handler ``` Now, a request to `/api/post/a/b/c` will respond with the text: @@ -209,9 +213,10 @@ the developer experience and increase the speed of creating new API endpoints, take a look at the following example: ```ts -export default (req: BlitzApiRequest, res: BlitzApiResponse) => { +const handler = (req: BlitzApiRequest, res: BlitzApiResponse) => { res.status(200).json({name: "Blitz.js"}) } +export default handler ``` The included helpers are: diff --git a/app/pages/docs/preview-mode.mdx b/app/pages/docs/preview-mode.mdx index 9ec3967..d235e6d 100644 --- a/app/pages/docs/preview-mode.mdx +++ b/app/pages/docs/preview-mode.mdx @@ -32,11 +32,12 @@ can be used by `getStaticProps` (more on this later). For now, we’ll use `{}`. ```js -export default (req, res) => { +const handler = (req, res) => { // ... res.setPreviewData({}) // ... } +export default handler ``` `res.setPreviewData` sets some **cookies** on the browser which turns on @@ -51,10 +52,11 @@ accessing it from your browser manually: // A simple example for testing it manually from your browser. // If this is located at app/api/preview.js, then // open /api/preview from your browser. -export default (req, res) => { +const handler = (req, res) => { res.setPreviewData({}) res.end("Preview mode enabled") } +export default handler ``` If you use your browser’s developer tools, you’ll notice that the From 4dbbdab2a89f86c4647ce1254520baadfc9cd42b Mon Sep 17 00:00:00 2001 From: JuanM04 Date: Mon, 19 Apr 2021 19:29:29 -0300 Subject: [PATCH 06/77] Added BlitzApiHandler --- app/pages/docs/api-routes.mdx | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/app/pages/docs/api-routes.mdx b/app/pages/docs/api-routes.mdx index a31ee4f..76a1d75 100644 --- a/app/pages/docs/api-routes.mdx +++ b/app/pages/docs/api-routes.mdx @@ -37,11 +37,23 @@ For an API route to work, you need to export as default a function (a.k.a [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse), plus some helper functions you can see [here](#response-helpers) +If you want to avoid writting the types `BlitzApiRequest` and +`BlitzApiResponse` everywhere, you can use `BlitzApiHandler`: + +```ts +const handler: BlitzApiHandler = (req, res) => { + res.statusCode = 200 + res.setHeader("Content-Type", "application/json") + res.end(JSON.stringify({name: "John Doe"})) +} +export default handler +``` + To handle different HTTP methods in an API route, you can use `req.method` in your request handler, like so: ```ts -const handler = (req: BlitzApiRequest, res: BlitzApiResponse) => { +const handler: BlitzApiHandler = (req, res) => { if (req.method === "POST") { // Process a POST request } else { @@ -107,7 +119,7 @@ Dynamic API routes follow the same file naming rules used for `pages`. For example, the API route `app/api/post/[pid].js` has the following code: ```ts -const handler = (req: BlitzApiRequest, res: BlitzApiResponse) => { +const handler: BlitzApiHandler = (req, res) => { const { query: {pid}, } = req @@ -166,7 +178,7 @@ parameters will be added to the array, like so: An API route for `app/api/post/[...slug].js` could look like this: ```ts -const handler = (req: BlitzApiRequest, res: BlitzApiResponse) => { +const handler: BlitzApiHandler = (req, res) => { const { query: {slug}, } = req @@ -213,7 +225,7 @@ the developer experience and increase the speed of creating new API endpoints, take a look at the following example: ```ts -const handler = (req: BlitzApiRequest, res: BlitzApiResponse) => { +const handler: BlitzApiHandler = (req, res) => { res.status(200).json({name: "Blitz.js"}) } export default handler From 4b0a1d0ee6d6eae06e8572bf0aa078dda0bf9830 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Tue, 20 Apr 2021 10:14:25 -0400 Subject: [PATCH 07/77] Update contributing.mdx --- app/pages/docs/contributing.mdx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/pages/docs/contributing.mdx b/app/pages/docs/contributing.mdx index 8b2645b..be17378 100644 --- a/app/pages/docs/contributing.mdx +++ b/app/pages/docs/contributing.mdx @@ -147,8 +147,16 @@ Most Blitz packages in `packages/` have jest unit tests. #### Integration Tests + Blitz integration tests are inside the root `test/` folder. +Make sure you have `chromedriver` installed for your Chrome version. You can install it with + +- `brew install --cask chromedriver` on Mac OS X +- `chocolatey install chromedriver` on Windows +- Or manually download the version that matches your installed chrome version (if there's no match, download a version under it, but not above) from the [chromedriver repo](https://chromedriver.storage.googleapis.com/index.html) and add the binary to `/node_modules/.bin` + + You can run all integration tests by running `yarn test:integration` from the repo root. Or you can run `yarn testheadles` to run them in headless mode (so it doesn't open a web browser window). From c7c36dd56d4cf80f018ab63977ee1f476be1aeec Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Wed, 21 Apr 2021 11:08:39 -0400 Subject: [PATCH 08/77] add RIT as sponsor --- app/core/components/SponsorPack.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/app/core/components/SponsorPack.js b/app/core/components/SponsorPack.js index c68d74c..9fe62de 100644 --- a/app/core/components/SponsorPack.js +++ b/app/core/components/SponsorPack.js @@ -20,6 +20,14 @@ const sponsors = [ tier: 3, cost: 250, }, + { + name: "RIT", + href: + "https://rit-inc.co.jp/?utm_source=BlitzJS&utm_medium=sponsorship&utm_campaign=BlitzJS_Sponsorship_2021", + imageUrl: "https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/rit_logo.png", + tier: 3, + cost: 250, + }, { name: "Andreas", href: "https://andreas.fyi/", From 287b7ba2943f570971a480d3c59b8de3edc65d90 Mon Sep 17 00:00:00 2001 From: Antony Date: Wed, 21 Apr 2021 17:49:25 +0200 Subject: [PATCH 09/77] Added description to `useInfiniteQuery` and `usePaginatedQuery` (#453) --- app/pages/docs/use-infinite-query.mdx | 6 ++++++ app/pages/docs/use-paginated-query.mdx | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/app/pages/docs/use-infinite-query.mdx b/app/pages/docs/use-infinite-query.mdx index 4dd35b3..6efad17 100644 --- a/app/pages/docs/use-infinite-query.mdx +++ b/app/pages/docs/use-infinite-query.mdx @@ -3,6 +3,12 @@ title: useInfiniteQuery sidebar_label: useInfiniteQuery --- +Use `useInfiniteQuery` instead of `useQuery`, if you want to show large +data gradually more. For instance, you have many numbered pages, and you +want to show the first ten pages initially. After clicking on +`Show more pages`, the user should see three pages more than before. For +this case, you can `useInfiniteQuery` as shown in the following example. + ### Example {#example} ```ts diff --git a/app/pages/docs/use-paginated-query.mdx b/app/pages/docs/use-paginated-query.mdx index 7ea51f8..c721bc8 100644 --- a/app/pages/docs/use-paginated-query.mdx +++ b/app/pages/docs/use-paginated-query.mdx @@ -3,6 +3,13 @@ title: usePaginatedQuery sidebar_label: usePaginatedQuery --- +Use `usePaginatedQuery` instead of `useQuery`, if you want to divide large +data into smaller contiguous intervals of data. For instance, you have +many numbered pages, and you want to show the first three pages initially. +After clicking on `Show next pages`, the user should see the following +three pages only. For this case, you can `usePaginatedQuery` as shown in +the following example. + ### Example {#example} ```ts From 2f576f62e4a42d01af2f4f969ab46c010343b13f Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Wed, 21 Apr 2021 15:44:27 -0400 Subject: [PATCH 10/77] update docs for server.ts --- app/pages/docs/custom-server.mdx | 55 +++++++++++++++++--------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/app/pages/docs/custom-server.mdx b/app/pages/docs/custom-server.mdx index 77a8e1a..aaf3f14 100644 --- a/app/pages/docs/custom-server.mdx +++ b/app/pages/docs/custom-server.mdx @@ -8,7 +8,8 @@ some other direct control over the web server itself. ### How {#how} -1. Add a `server.js` file in your project root. See below for an example. +1. Add a `server.ts` or `server.js` file in your project root. See below + for an example. 2. Now `blitz dev` and `blitz start` will automatically detect and use your custom server. @@ -16,12 +17,14 @@ some other direct control over the web server itself. Here's an example custom server: -```js -// server.js -const {createServer} = require("http") -const {parse} = require("url") -const blitz = require("blitz/custom-server") +```ts +// server.ts +import blitz from "blitz/custom-server" +import {createServer} from "http" +import {parse} from "url" +import {log} from "@blitzjs/display" +const {PORT = "3000"} = process.env const dev = process.env.NODE_ENV !== "production" const app = blitz({dev}) const handle = app.getRequestHandler() @@ -30,34 +33,36 @@ app.prepare().then(() => { createServer((req, res) => { // Be sure to pass `true` as the second argument to `url.parse`. // This tells it to parse the query portion of the URL. - const parsedUrl = parse(req.url, true) - const {pathname, query} = parsedUrl + const parsedUrl = parse(req.url!, true) + const {pathname} = parsedUrl + + if (pathname === "/hello") { + res.writeHead(200).end("world") + return + } - if (pathname === "/a") { + if (pathname === "/hello") { + res.writeHead(200).end("world") + return + } else if (pathname === "/a") { app.render(req, res, "/a", query) } else if (pathname === "/b") { app.render(req, res, "/b", query) } else { handle(req, res, parsedUrl) } - }).listen(3000, (err) => { - if (err) throw err - console.log("> Ready on http://localhost:3000") + + handle(req, res, parsedUrl) + }).listen(PORT, () => { + log.success(`Ready on http://localhost:${PORT}`) }) }) ``` -> `server.js` doesn't go through babel or webpack. Make sure the syntax -> and sources this file requires are compatible with the current node -> version you are running. - --- -The custom server uses the following import to connect the server with the -Blitz application: - -The above `blitz` import is a function that receives an object with the -following options: +The above `blitz/custom-server` import is a function that receives an +object with the following options: - `dev`: `Boolean` - Whether or not to launch Blitz in dev mode. Defaults to `false` @@ -72,10 +77,10 @@ required. ## Disabling file-system routing {#disabling-file-system-routing} -By default, `blitz` will serve each file in the `pages` folder under a -pathname matching the filename. If your project uses a custom server, this -behavior may result in the same content being served from multiple paths, -which can present problems with SEO and UX. +By default, `blitz` will serve each file `pages` folders under a pathname +matching the filename. If your project uses a custom server, this behavior +may result in the same content being served from multiple paths, which can +present problems with SEO and UX. To disable this behavior and prevent routing based on files in `pages`, open `blitz.config.js` and disable the `useFileSystemPublicRoutes` config: From 00be1036eecfa0167a19a0253f361334b5727a27 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Thu, 22 Apr 2021 12:18:57 -0400 Subject: [PATCH 11/77] Update get-started.mdx --- app/pages/docs/get-started.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/get-started.mdx b/app/pages/docs/get-started.mdx index 92684ce..dffe27a 100644 --- a/app/pages/docs/get-started.mdx +++ b/app/pages/docs/get-started.mdx @@ -9,7 +9,7 @@ You need Node.js 12 or newer ### Install Blitz {#install-blitz} -Run `npm install -g blitz` +Run `yarn global add blitz` or `npm install -g blitz --legacy-peer-deps` (legacy-peer-deps is needed because npm totally change behavior of peer deps and some dependencies haven't caught up) ### Create a New App {#create-a-new-app} From 3f003d29d83aefc97d4b866f9acce50681c29eae Mon Sep 17 00:00:00 2001 From: JuanM04 Date: Sun, 25 Apr 2021 10:11:07 -0300 Subject: [PATCH 12/77] Formatted docs --- app/pages/docs/contributing.mdx | 11 ++++--- app/pages/docs/error-pages.mdx | 57 ++++++++++++++++++++++++--------- app/pages/docs/get-started.mdx | 4 ++- app/pages/docs/query-usage.mdx | 8 ++--- app/pages/docs/why-blitz.mdx | 2 +- 5 files changed, 57 insertions(+), 25 deletions(-) diff --git a/app/pages/docs/contributing.mdx b/app/pages/docs/contributing.mdx index be17378..ae928c2 100644 --- a/app/pages/docs/contributing.mdx +++ b/app/pages/docs/contributing.mdx @@ -147,15 +147,18 @@ Most Blitz packages in `packages/` have jest unit tests. #### Integration Tests - Blitz integration tests are inside the root `test/` folder. -Make sure you have `chromedriver` installed for your Chrome version. You can install it with +Make sure you have `chromedriver` installed for your Chrome version. You +can install it with - `brew install --cask chromedriver` on Mac OS X - `chocolatey install chromedriver` on Windows -- Or manually download the version that matches your installed chrome version (if there's no match, download a version under it, but not above) from the [chromedriver repo](https://chromedriver.storage.googleapis.com/index.html) and add the binary to `/node_modules/.bin` - +- Or manually download the version that matches your installed chrome + version (if there's no match, download a version under it, but not + above) from the + [chromedriver repo](https://chromedriver.storage.googleapis.com/index.html) + and add the binary to `/node_modules/.bin` You can run all integration tests by running `yarn test:integration` from the repo root. Or you can run `yarn testheadles` to run them in headless diff --git a/app/pages/docs/error-pages.mdx b/app/pages/docs/error-pages.mdx index 7945fbc..15d3d81 100644 --- a/app/pages/docs/error-pages.mdx +++ b/app/pages/docs/error-pages.mdx @@ -58,27 +58,31 @@ export default Error ## Customize the Error Boundary Fallback Component {#custom-error-boundary-component} -The default `app/pages/_app.tsx` configures an error boundary which catches errors that happen during render, on the client side. This will also catch errors within `useQuery` or `useMutation` because they happen in suspense. +The default `app/pages/_app.tsx` configures an error boundary which +catches errors that happen during render, on the client side. This will +also catch errors within `useQuery` or `useMutation` because they happen +in suspense. In essence, the default configuration is: ```tsx -export default function App({ Component, pageProps }: AppProps) { +export default function App({Component, pageProps}: AppProps) { return ( - + {getLayout()} ) } ``` -The `RootErrorFallback` is rendered when a error happens within render, or a suspended mutation or query. By default: +The `RootErrorFallback` is rendered when a error happens within render, or +a suspended mutation or query. By default: ```tsx -function RootErrorFallback({ error, resetErrorBoundary }: ErrorFallbackProps) { +function RootErrorFallback({ + error, + resetErrorBoundary, +}: ErrorFallbackProps) { if (error instanceof AuthenticationError) { return } else if (error instanceof AuthorizationError) { @@ -90,7 +94,10 @@ function RootErrorFallback({ error, resetErrorBoundary }: ErrorFallbackProps) { ) } else { return ( - + ) } } @@ -98,27 +105,47 @@ function RootErrorFallback({ error, resetErrorBoundary }: ErrorFallbackProps) { ### Authentication Error Component (401) {#custom-authentication-error-component} -If your query, mutation, or render function `throw new AuthenticationError()` when the user is not authenticated, you can detect that within the error fallback: +If your query, mutation, or render function +`throw new AuthenticationError()` when the user is not authenticated, you +can detect that within the error fallback: ```tsx -function RootErrorFallback({ error, resetErrorBoundary }: ErrorFallbackProps) { +function RootErrorFallback({ + error, + resetErrorBoundary, +}: ErrorFallbackProps) { if (error instanceof AuthenticationError) { return } - return + return ( + + ) } ``` ### Authorization Error Component (403) {#custom-authorization-error-component} -Your query, mutation, or render function may call `throw new AuthorizationError()` when a user is authenticated but not authorized to do something. The error fallback may handle that: +Your query, mutation, or render function may call +`throw new AuthorizationError()` when a user is authenticated but not +authorized to do something. The error fallback may handle that: ```tsx -function RootErrorFallback({ error, resetErrorBoundary }: ErrorFallbackProps) { +function RootErrorFallback({ + error, + resetErrorBoundary, +}: ErrorFallbackProps) { if (error instanceof AuthorizationError) { return } - return + return ( + + ) } ``` diff --git a/app/pages/docs/get-started.mdx b/app/pages/docs/get-started.mdx index dffe27a..9fbd16b 100644 --- a/app/pages/docs/get-started.mdx +++ b/app/pages/docs/get-started.mdx @@ -9,7 +9,9 @@ You need Node.js 12 or newer ### Install Blitz {#install-blitz} -Run `yarn global add blitz` or `npm install -g blitz --legacy-peer-deps` (legacy-peer-deps is needed because npm totally change behavior of peer deps and some dependencies haven't caught up) +Run `yarn global add blitz` or `npm install -g blitz --legacy-peer-deps` +(legacy-peer-deps is needed because npm totally change behavior of peer +deps and some dependencies haven't caught up) ### Create a New App {#create-a-new-app} diff --git a/app/pages/docs/query-usage.mdx b/app/pages/docs/query-usage.mdx index a65d404..87463b1 100644 --- a/app/pages/docs/query-usage.mdx +++ b/app/pages/docs/query-usage.mdx @@ -159,10 +159,10 @@ export default ProjectPage To ensure data is not shared between users and requests, a new query client is created for each page request. You can prefetch your data by -invoking the `prefetchQuery` method on the newly-created client, passing in -the query key and resolver along with any relevant input arguments. Once -the data has been fetched, dehydrate the queries to the query client using -the `dehydrate` method and pass the result to the page via the +invoking the `prefetchQuery` method on the newly-created client, passing +in the query key and resolver along with any relevant input arguments. +Once the data has been fetched, dehydrate the queries to the query client +using the `dehydrate` method and pass the result to the page via the `dehydratedState` prop. ## On the Server {#on-the-server} diff --git a/app/pages/docs/why-blitz.mdx b/app/pages/docs/why-blitz.mdx index a64dd39..44fbd04 100644 --- a/app/pages/docs/why-blitz.mdx +++ b/app/pages/docs/why-blitz.mdx @@ -124,7 +124,7 @@ Examples: - `app/admin/pages/` could contain all pages related to the backend admin section -### 9. Route Manifest {#9-relaxed-restrictions} +### 9. Route Manifest {#9-route-manifest} Next.js requires you to manually type out page locations. Blitz comes with a [Route Manifest](./route-manifest), so you can do: From 1bb9378131611b7ef745abe9083d993af7b76b45 Mon Sep 17 00:00:00 2001 From: JuanM04 Date: Sun, 25 Apr 2021 10:14:17 -0300 Subject: [PATCH 13/77] Updated dependencies --- package.json | 14 +-- yarn.lock | 254 +++++++++++++++++++++++++-------------------------- 2 files changed, 134 insertions(+), 134 deletions(-) diff --git a/package.json b/package.json index 3742b12..4412c50 100644 --- a/package.json +++ b/package.json @@ -18,18 +18,18 @@ }, "dependencies": { "@docsearch/react": "1.0.0-alpha.28", - "@octokit/rest": "18.5.2", + "@octokit/rest": "18.5.3", "@reach/rect": "0.15.0", "@sindresorhus/slugify": "2.0.0", "@visx/hierarchy": "1.7.0", "@visx/responsive": "1.7.0", - "blitz": "0.34.0", + "blitz": "0.34.3", "clsx": "1.1.1", "dlv": "1.1.3", "fathom-client": "3.0.0", "focus-visible": "5.2.0", - "framer-motion": "4.1.5", - "gray-matter": "4.0.2", + "framer-motion": "4.1.9", + "gray-matter": "4.0.3", "just-group-by": "1.0.0", "next-themes": "0.0.14", "prismjs": "1.23.0", @@ -54,20 +54,20 @@ "alex": "9.1.0", "autoprefixer": "10.2.5", "babel-plugin-preval": "5.0.0", - "eslint": "7.24.0", + "eslint": "7.25.0", "eslint-plugin-simple-import-sort": "7.0.0", "file-loader": "6.2.0", "glob": "7.1.6", "husky": "6.0.0", "lint-staged": "10.5.4", "minimatch": "3.0.4", - "postcss": "8.2.10", + "postcss": "8.2.12", "postcss-nested": "5.0.5", "prettier": "2.2.1", "pretty-quick": "3.1.0", "remark-admonitions": "1.2.1", "simple-functional-loader": "1.2.1", - "tailwindcss": "2.1.1" + "tailwindcss": "2.1.2" }, "private": true } diff --git a/yarn.lock b/yarn.lock index 744f9aa..87fc9dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1566,21 +1566,21 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@blitzjs/babel-preset@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@blitzjs/babel-preset/-/babel-preset-0.34.0.tgz#728f99aa2f85860f5d06fa2a6ab55727b99ca591" - integrity sha512-oFVh7oXb3qh8IAlNLjSS/NeXSnAZYDrXDjRz5C4t6wTIzGkGhbVFBXKX9Jb6mrGJCbWeNo667rmCRZhQB0NxNg== +"@blitzjs/babel-preset@0.34.3": + version "0.34.3" + resolved "https://registry.yarnpkg.com/@blitzjs/babel-preset/-/babel-preset-0.34.3.tgz#c3756c6bdeca540072ed3472ed1bb148834896af" + integrity sha512-A5kqm69btVWXQaeqA2qySRkSeKUw/SrW+iF5VE6hFDz/euINMKrRQiKxS3on3lotb1LBUP3FTF2iHHN6PSmq0g== dependencies: "@babel/helper-module-imports" "^7.0.0" babel-plugin-superjson-next "0.2.2" -"@blitzjs/cli@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@blitzjs/cli/-/cli-0.34.0.tgz#f81e7d9bf0b8bf1d88d1cdeeb427462399a57c39" - integrity sha512-Qtq5Cyy8QcX0KCzCALaBIloRl00Lp/aaw4hPm5JF+dpzyqhcnmdhq4OonwU6ebx7IYg+Bg2OIPButGBKjHHb9Q== +"@blitzjs/cli@0.34.3": + version "0.34.3" + resolved "https://registry.yarnpkg.com/@blitzjs/cli/-/cli-0.34.3.tgz#4a40bdf0f955a261f85728e03f7f57d719df10ca" + integrity sha512-ZRS7sNPlZ8A1RqtAdgG9uhsstad28XZYCQum76tkPuh++T8qvMKJCyzGdRjX2ScyoD7Ny9HhujokxPdTVbq6Pg== dependencies: - "@blitzjs/display" "0.34.0" - "@blitzjs/repl" "0.34.0" + "@blitzjs/display" "0.34.3" + "@blitzjs/repl" "0.34.3" "@oclif/command" "1.8.0" "@oclif/config" "1.17.0" "@oclif/plugin-autocomplete" "0.3.0" @@ -1609,21 +1609,21 @@ tsconfig-paths "3.9.0" v8-compile-cache "2.2.0" -"@blitzjs/config@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@blitzjs/config/-/config-0.34.0.tgz#72b1f48e3d1b036571635ee84f82f4dbd3afa957" - integrity sha512-7F1zyCeVQA6yr0GVbCK8/NCDCsddmpR8JKWK1SPperbmddVSPUbeHGdYGlF0xzGZdaBEU+uhofmYSRR/KchbQA== +"@blitzjs/config@0.34.3": + version "0.34.3" + resolved "https://registry.yarnpkg.com/@blitzjs/config/-/config-0.34.3.tgz#83604d63e9722a80ba3fa324e99dba359e6b658b" + integrity sha512-3MAmHK6Kh7XJIT6mCETUvRFalqJLkk1wCYBuFXLtzqpwry/bSgPHBzAlpzccgSys5zpjBvbftns2X3i1L9X2gQ== dependencies: fs-extra "^9.1.0" pkg-dir "^5.0.0" -"@blitzjs/core@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@blitzjs/core/-/core-0.34.0.tgz#34f639d87f9db673c793df625d36184df8df4932" - integrity sha512-jt92Ui2vPWl/AGmIbPa91A7ULeLVrAntlDnSiqFkrMgd0LwmUOvAP4BAt4EXujiFei7emht49sAt5j2/Z3SyCA== +"@blitzjs/core@0.34.3": + version "0.34.3" + resolved "https://registry.yarnpkg.com/@blitzjs/core/-/core-0.34.3.tgz#8078ec3f9856450dd303a828782b7742bde93323" + integrity sha512-moheoboOMVxR5YGEpexjt5HxO1NyoY984uvSsqiEmQkoWz6Fk/HvU2tfwlj+ybNOkBr2XNU6pAzxbMVZflHdzw== dependencies: - "@blitzjs/config" "0.34.0" - "@blitzjs/display" "0.34.0" + "@blitzjs/config" "0.34.3" + "@blitzjs/display" "0.34.3" "@types/secure-password" "3.1.0" b64-lite "^1.4.0" bad-behavior "^1.0.1" @@ -1635,7 +1635,7 @@ jsonwebtoken "8.5.1" lodash.frompairs "4.0.1" nanoid "^3.1.20" - next "npm:@blitzjs/next@0.34.0" + next "npm:@blitzjs/next@10.1.3-0.34.3" npm-which "^3.0.1" null-loader "4.0.1" passport "0.4.1" @@ -1643,25 +1643,25 @@ secure-password "4.0.0" superjson "1.7.2" -"@blitzjs/display@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@blitzjs/display/-/display-0.34.0.tgz#f46ed3d3774d0170eb52af71d4c89da09cac9e8f" - integrity sha512-+tHVyEe5umCnwlRoPqzryfZLuDqSORUXNiXP8z3Ufrpjo6hr4Yl0DxGbtcCz4TgBx91OvbVyDI68bkHFePj0Iw== +"@blitzjs/display@0.34.3": + version "0.34.3" + resolved "https://registry.yarnpkg.com/@blitzjs/display/-/display-0.34.3.tgz#9d17d16658c3d5576509356bccc33351e581ec4b" + integrity sha512-PvZphihfJKFmr5aVLQZgq/MEYDJFb2I8NmwNwNE8U+M4asctZACbiXeuRnjqN3JUultO8bk+ZyLos4vUr6nDcw== dependencies: - "@blitzjs/config" "0.34.0" - "@blitzjs/display" "0.34.0" + "@blitzjs/config" "0.34.3" + "@blitzjs/display" "0.34.3" chalk "^4.1.0" console-table-printer "^2.7.5" ora "^5.3.0" readline "1.3.0" tslog "^3.1.1" -"@blitzjs/file-pipeline@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@blitzjs/file-pipeline/-/file-pipeline-0.34.0.tgz#c6c6543e84aae1213529c365c0ac3fcc88e71343" - integrity sha512-nyAT9zTy4xZQlXu4MLC72lbedUVuKQ0pbY/bJeFwcZ8kKHD4tX3YZNGvW5qgBVQPrnk2uUB9uaGnkGpTLfBq7g== +"@blitzjs/file-pipeline@0.34.3": + version "0.34.3" + resolved "https://registry.yarnpkg.com/@blitzjs/file-pipeline/-/file-pipeline-0.34.3.tgz#10c40e8906683fc5e936b27f04b981f7ad4c5cf7" + integrity sha512-AeSAypDniFuXC9xUbz07daFAbQWBIUzlz3M6tCWA2lWFBegPDciC/3xKeP/LCHjKqSVpA5tQcR2qVsoxM0R1Qg== dependencies: - "@blitzjs/display" "0.34.0" + "@blitzjs/display" "0.34.3" chalk "^4.1.0" chokidar "3.5.1" flush-write-stream "2.0.0" @@ -1680,14 +1680,14 @@ vinyl-file "3.0.0" vinyl-fs "3.0.3" -"@blitzjs/generator@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@blitzjs/generator/-/generator-0.34.0.tgz#315c8b79e33df1a2cac66b2942d1343cc042d767" - integrity sha512-Bg1mXOMwqbH8yG4Gi7yT9DEOp34ryPs8WaeIi8tBOWf5ULXfz9Py5DQlsMfF3Lg8+yxzWV+xttQ6axueo2wasg== +"@blitzjs/generator@0.34.3": + version "0.34.3" + resolved "https://registry.yarnpkg.com/@blitzjs/generator/-/generator-0.34.3.tgz#0b75758bc5b8e319853f548a0df161621c418107" + integrity sha512-KlsroS8Tx0Dq1MkcfT3qBux90CgKFp2Gs4AHWy1ZYV/9Fiu3lw/d53sY1msEEB0ggIhXjlb+AFgE5FqtBG5+FA== dependencies: "@babel/core" "7.12.10" "@babel/plugin-transform-typescript" "7.12.1" - "@blitzjs/display" "0.34.0" + "@blitzjs/display" "0.34.3" "@types/jscodeshift" "0.7.2" chalk "^4.1.0" cross-spawn "7.0.3" @@ -1704,16 +1704,16 @@ username "^5.1.0" vinyl "2.2.1" -"@blitzjs/installer@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@blitzjs/installer/-/installer-0.34.0.tgz#7731c5040c196c0a8c0717da11ae2a8c1208b3e0" - integrity sha512-fCuLnCcR1mM+FFoVwpdSU/jNZghS/7x0nmGAa3gx/RGN9Q7/quvqY1M6iR5iXRhxYKQGTXLWOWJDcYH4wmkbKQ== +"@blitzjs/installer@0.34.3": + version "0.34.3" + resolved "https://registry.yarnpkg.com/@blitzjs/installer/-/installer-0.34.3.tgz#51f33c855391c00fb1a5f417fb4818a4e3c00249" + integrity sha512-y7Od0YCj+ltwegNB0gmtjnLJk5e6uiqfHp8ZmpK/mnETIJXfXab/xXSJBhvyKcEvh0oO9GQC7v7ivGGouBL57g== dependencies: "@babel/core" "7.12.10" "@babel/plugin-transform-typescript" "7.12.1" - "@blitzjs/config" "0.34.0" - "@blitzjs/display" "0.34.0" - "@blitzjs/generator" "0.34.0" + "@blitzjs/config" "0.34.3" + "@blitzjs/display" "0.34.3" + "@blitzjs/generator" "0.34.3" "@types/jscodeshift" "0.7.2" cross-spawn "7.0.3" diff "5.0.0" @@ -1728,26 +1728,26 @@ recast "0.20.4" ts-node "^9.1.1" -"@blitzjs/repl@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@blitzjs/repl/-/repl-0.34.0.tgz#a9f8244958d1b4b51d234db7e19c9b214661a186" - integrity sha512-xRIfxAzLP5nP3nRHm1WlEPiCaSvYsncuG6JAS9n2SpctwUZGbCORuSTLaLtUPhbNayOm4Qc3Z2sI22fkQRnxag== +"@blitzjs/repl@0.34.3": + version "0.34.3" + resolved "https://registry.yarnpkg.com/@blitzjs/repl/-/repl-0.34.3.tgz#403469358ec162077ab4dde91cf3be93bde060e2" + integrity sha512-XHj9DYPqc8KY+zEPcoTL9Nc4vups7Vj4Fz5v82o7i6SPXGuzuCsOJu528HwtX8Y5fO5EHJFNAp8bhr8cDML20g== dependencies: - "@blitzjs/config" "0.34.0" + "@blitzjs/config" "0.34.3" chokidar "3.5.1" globby "11.0.2" pkg-dir "^5.0.0" progress "^2.0.3" -"@blitzjs/server@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@blitzjs/server/-/server-0.34.0.tgz#180b7fe7a7e49796165fc5bd3e51304a850f98b8" - integrity sha512-mgPgEwUDzvAL+HuyhGo0ns14dxamJxm84Fc1jswq/cXsL77BD2Ta7VH1GYGXDDp0rJMgDlc1KG3eZN4IGIJjFg== +"@blitzjs/server@0.34.3": + version "0.34.3" + resolved "https://registry.yarnpkg.com/@blitzjs/server/-/server-0.34.3.tgz#9e682b0b1ee6cf144a986bc4e1f268e0d248af56" + integrity sha512-FVmKHH9sawM/xTRtboUKRMehxeChTosD6Eyj/XxrvP+GAirgCKPLefttyjvwzJdw+y7h+RWHH5iZpxdQDXppDg== dependencies: - "@blitzjs/config" "0.34.0" - "@blitzjs/core" "0.34.0" - "@blitzjs/display" "0.34.0" - "@blitzjs/file-pipeline" "0.34.0" + "@blitzjs/config" "0.34.3" + "@blitzjs/core" "0.34.3" + "@blitzjs/display" "0.34.3" + "@blitzjs/file-pipeline" "0.34.3" cross-spawn "7.0.3" detect-port "1.3.0" expand-tilde "2.0.2" @@ -2374,10 +2374,10 @@ resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-2.0.1.tgz#7453d8281ce66b8ed1607f7ac7d751c3baffd2cc" integrity sha512-9AuC04PUnZrjoLiw3uPtwGh9FE4Q3rTqs51oNlQ0rkwgE8ftYsOC+lsrQyvCvWm85smBbSc0FNRKKumvGyb44Q== -"@octokit/openapi-types@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-6.0.0.tgz#7da8d7d5a72d3282c1a3ff9f951c8133a707480d" - integrity sha512-CnDdK7ivHkBtJYzWzZm7gEkanA7gKH6a09Eguz7flHw//GacPJLmkHA3f3N++MJmlxD1Fl+mB7B32EEpSCwztQ== +"@octokit/openapi-types@^6.1.1": + version "6.1.1" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-6.1.1.tgz#27f9386fcbcb9846b27b1bc8a41ba6f313c922a6" + integrity sha512-ICBhnEb+ahi/TTdNuYb/kTyKVBgAM0VD4k6JPzlhJyzt3Z+Tq/bynwCD+gpkJP7AEcNnzC8YO5R39trmzEo2UA== "@octokit/plugin-paginate-rest@^2.6.2": version "2.6.2" @@ -2391,12 +2391,12 @@ resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.2.tgz#394d59ec734cd2f122431fbaf05099861ece3c44" integrity sha512-oTJSNAmBqyDR41uSMunLQKMX0jmEXbwD1fpz8FG27lScV3RhtGfBa1/BBLym+PxcC16IBlF7KH9vP1BUYxA+Eg== -"@octokit/plugin-rest-endpoint-methods@5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.0.0.tgz#cf2cdeb24ea829c31688216a5b165010b61f9a98" - integrity sha512-Jc7CLNUueIshXT+HWt6T+M0sySPjF32mSFQAK7UfAg8qGeRI6OM1GSBxDLwbXjkqy2NVdnqCedJcP1nC785JYg== +"@octokit/plugin-rest-endpoint-methods@5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.0.1.tgz#631b8d4edc6798b03489911252a25f2a4e58c594" + integrity sha512-vvWbPtPqLyIzJ7A4IPdTl+8IeuKAwMJ4LjvmqWOOdfSuqWQYZXq2CEd0hsnkidff2YfKlguzujHs/reBdAx8Sg== dependencies: - "@octokit/types" "^6.13.0" + "@octokit/types" "^6.13.1" deprecation "^2.3.1" "@octokit/request-error@^2.0.0": @@ -2422,15 +2422,15 @@ once "^1.4.0" universal-user-agent "^6.0.0" -"@octokit/rest@18.5.2": - version "18.5.2" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.5.2.tgz#0369e554b7076e3749005147be94c661c7a5a74b" - integrity sha512-Kz03XYfKS0yYdi61BkL9/aJ0pP2A/WK5vF/syhu9/kY30J8He3P68hv9GRpn8bULFx2K0A9MEErn4v3QEdbZcw== +"@octokit/rest@18.5.3": + version "18.5.3" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-18.5.3.tgz#6a2e6006a87ebbc34079c419258dd29ec9ff659d" + integrity sha512-KPAsUCr1DOdLVbZJgGNuE/QVLWEaVBpFQwDAz/2Cnya6uW2wJ/P5RVGk0itx7yyN1aGa8uXm2pri4umEqG1JBA== dependencies: "@octokit/core" "^3.2.3" "@octokit/plugin-paginate-rest" "^2.6.2" "@octokit/plugin-request-log" "^1.0.2" - "@octokit/plugin-rest-endpoint-methods" "5.0.0" + "@octokit/plugin-rest-endpoint-methods" "5.0.1" "@octokit/types@^6.0.0", "@octokit/types@^6.0.1", "@octokit/types@^6.0.3": version "6.1.2" @@ -2440,12 +2440,12 @@ "@octokit/openapi-types" "^2.0.1" "@types/node" ">= 8" -"@octokit/types@^6.13.0": - version "6.13.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.13.0.tgz#779e5b7566c8dde68f2f6273861dd2f0409480d0" - integrity sha512-W2J9qlVIU11jMwKHUp5/rbVUeErqelCsO5vW5PKNb7wAXQVUz87Rc+imjlEvpvbH8yUb+KHmv8NEjVZdsdpyxA== +"@octokit/types@^6.13.1": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-6.13.2.tgz#e3423dc733567ac4836e116b34d154a8e9cbbf3c" + integrity sha512-jN5LImYHvv7W6SZargq1UMJ3EiaqIz5qkpfsv4GAb4b16SGqctxtOU2TQAZxvsKHkOw2A4zxdsi5wR9en1/ezQ== dependencies: - "@octokit/openapi-types" "^6.0.0" + "@octokit/openapi-types" "^6.1.1" "@opentelemetry/api@0.14.0": version "0.14.0" @@ -3981,26 +3981,26 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" -blitz@0.34.0: - version "0.34.0" - resolved "https://registry.yarnpkg.com/blitz/-/blitz-0.34.0.tgz#f5672c4f86fb5cac517687221220ddd0b6938372" - integrity sha512-+rQnOSfCCwuRxRALwi/tXpTUYXZvwW2J0nxhW3y1WvxZspBGSC5DKo+O5FBM/JgsqwrbQaBQTZUzYPx3Llvi4Q== - dependencies: - "@blitzjs/babel-preset" "0.34.0" - "@blitzjs/cli" "0.34.0" - "@blitzjs/config" "0.34.0" - "@blitzjs/core" "0.34.0" - "@blitzjs/display" "0.34.0" - "@blitzjs/generator" "0.34.0" - "@blitzjs/installer" "0.34.0" - "@blitzjs/server" "0.34.0" +blitz@0.34.3: + version "0.34.3" + resolved "https://registry.yarnpkg.com/blitz/-/blitz-0.34.3.tgz#27f84c53c4ec3b01a428b1b87e9823013ad95ae1" + integrity sha512-C0zNSrdAO+9L0yfX3bRU9T8orfhSQCdbjy46XW4GKNKotU7qHu0rpafJZX9hYf/0MEHmKXc+7yxByJpoH2+DiQ== + dependencies: + "@blitzjs/babel-preset" "0.34.3" + "@blitzjs/cli" "0.34.3" + "@blitzjs/config" "0.34.3" + "@blitzjs/core" "0.34.3" + "@blitzjs/display" "0.34.3" + "@blitzjs/generator" "0.34.3" + "@blitzjs/installer" "0.34.3" + "@blitzjs/server" "0.34.3" "@testing-library/jest-dom" "5.11.9" "@testing-library/react" "11.2.5" "@testing-library/react-hooks" "^4.0.1" "@types/jest" "26.0.20" chalk "^4.1.0" envinfo "^7.7.3" - eslint-config-blitz "0.34.0" + eslint-config-blitz "0.34.3" jest "^26.6.3" jest-watch-typeahead "^0.6.1" os-name "^4.0.0" @@ -5843,10 +5843,10 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-config-blitz@0.34.0: - version "0.34.0" - resolved "https://registry.yarnpkg.com/eslint-config-blitz/-/eslint-config-blitz-0.34.0.tgz#8aa8c45b0ff25db80a8754cd2f6f8c57f708a452" - integrity sha512-Hz8F2ATZ3wce41iEZSVfk2PjBdFHO7qlnH34gBdIPb4CXPelXKHXIk5kUS6ne55qeWMlEm8xEzRR7zAZnDlW9A== +eslint-config-blitz@0.34.3: + version "0.34.3" + resolved "https://registry.yarnpkg.com/eslint-config-blitz/-/eslint-config-blitz-0.34.3.tgz#337a41187333944d2e03ed320a985d4dd8194e07" + integrity sha512-sYR8IcJSG4sag3FrlRRNtRPpNDxY5qSq1oiPjsCgN3rdbx7OcvuBMUsqSVXtoNh4PEgrltOXJVBcrwX7cVmwhA== dependencies: "@typescript-eslint/eslint-plugin" "4.17.0" "@typescript-eslint/parser" "4.17.0" @@ -5985,10 +5985,10 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@7.24.0: - version "7.24.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.24.0.tgz#2e44fa62d93892bfdb100521f17345ba54b8513a" - integrity sha512-k9gaHeHiFmGCDQ2rEfvULlSLruz6tgfA8DEn+rY9/oYPFFTlz55mM/Q/Rij1b2Y42jwZiK3lXvNTw6w6TXzcKQ== +eslint@7.25.0: + version "7.25.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.25.0.tgz#1309e4404d94e676e3e831b3a3ad2b050031eb67" + integrity sha512-TVpSovpvCNpLURIScDRB6g5CYu/ZFq9GfX2hLNIV4dSBKxIWojeDODvYl3t0k0VtMxYeR8OXPCFE5+oHMlGfhw== dependencies: "@babel/code-frame" "7.12.11" "@eslint/eslintrc" "^0.4.0" @@ -6507,10 +6507,10 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -framer-motion@4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-4.1.5.tgz#451ac3a41c682190bf247d5e209e24572e45cfc3" - integrity sha512-ExZ/BGKecRDs91W9ZebbCW5HgO8PaVT5V2ZUs28/jqLyef7VrTho0J5BRH/oAvwc9Qdnl0nRS/YRJWNOCt/PYQ== +framer-motion@4.1.9: + version "4.1.9" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-4.1.9.tgz#e4b237cb4cedb26002fb61fdbb64149a7cb3c422" + integrity sha512-s5vvzxlHk8sxvvFOr/jA7pON7elI4bvsqjmgeyvLZj0z58yzC94AGx09uB+wuzuWpKOoFwjgiD+ClcyMQ6WC9A== dependencies: framesync "5.3.0" hey-listen "^1.0.8" @@ -6868,12 +6868,12 @@ graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== -gray-matter@4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.2.tgz#9aa379e3acaf421193fce7d2a28cebd4518ac454" - integrity sha512-7hB/+LxrOjq/dd8APlK0r24uL/67w7SkYnfwhNFwg/VDIGWGmduTDYf3WNstLW2fbbmRwrDGCVSJ2isuf2+4Hw== +gray-matter@4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-4.0.3.tgz#e893c064825de73ea1f5f7d88c7a9f7274288798" + integrity sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q== dependencies: - js-yaml "^3.11.0" + js-yaml "^3.13.1" kind-of "^6.0.2" section-matter "^1.0.0" strip-bom-string "^1.0.0" @@ -8450,14 +8450,6 @@ js-sha3@0.8.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.11.0, js-yaml@^3.6.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - js-yaml@^3.13.1: version "3.14.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" @@ -8466,6 +8458,14 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^3.6.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -9590,10 +9590,10 @@ next-themes@0.0.14: resolved "https://registry.yarnpkg.com/next-themes/-/next-themes-0.0.14.tgz#2b9861990bc453149e23d8e6ef1a25a119e36675" integrity sha512-x09OaM+wg3SIlEjOv8B21aw/E36jxTtfW3Dm/DPwMsSMluGt7twe1LigA6nc+mXP1u0qu9MxBaIrPPH6UTiKnA== -"next@npm:@blitzjs/next@0.34.0": - version "0.34.0" - resolved "https://registry.yarnpkg.com/@blitzjs/next/-/next-0.34.0.tgz#0094c8eedf22a0c0e8c65dafd25cced440a42732" - integrity sha512-rAqGufaov9OooexcNjcWN/zU51zdXEpthTlPATT+gVKYvA+ZJ/+AgT8YGZG4gSLN9VIY1wciiZTSgKhZrWM1wg== +"next@npm:@blitzjs/next@10.1.3-0.34.3": + version "10.1.3-0.34.3" + resolved "https://registry.yarnpkg.com/@blitzjs/next/-/next-10.1.3-0.34.3.tgz#6ae0a769b3740267c99b9ead7caeef02c210b328" + integrity sha512-imoVqfPnxgQ5aJ1v1PIfIlDRK8bKL6OhiHUJ3+WGtTaJDfyvXQEIa1M4MrZsEua92jV5/VUbRICp7erJRwGqrw== dependencies: "@babel/runtime" "7.12.5" "@hapi/accept" "5.0.1" @@ -10574,10 +10574,10 @@ postcss@8.1.7, postcss@^8.1.6: nanoid "^3.1.16" source-map "^0.6.1" -postcss@8.2.10: - version "8.2.10" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.10.tgz#ca7a042aa8aff494b334d0ff3e9e77079f6f702b" - integrity sha512-b/h7CPV7QEdrqIxtAf2j31U5ef05uBDuvoXv6L51Q4rcS1jdlXAVKJv+atCFdUXYl9dyTHGyoMzIepwowRJjFw== +postcss@8.2.12: + version "8.2.12" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.12.tgz#81248a1a87e0f575cc594a99a08207fd1c4addc4" + integrity sha512-BJnGT5+0q2tzvs6oQfnY2NpEJ7rIXNfBnZtQOKCIsweeWXBXeDd5k31UgTdS3d/c02ouspufn37mTaHWkJyzMQ== dependencies: colorette "^1.2.2" nanoid "^3.1.22" @@ -12587,10 +12587,10 @@ table@^6.0.4: slice-ansi "^4.0.0" string-width "^4.2.0" -tailwindcss@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.1.1.tgz#642f6038c9283a8e1454da34585b8b7c1a1e8877" - integrity sha512-zZ6axGqpSZOCBS7wITm/WNHkBzDt5CIZlDlx0eCVldwTxFPELCVGbgh7Xpb3/kZp3cUxOmK7bZUjqhuMrbN6xQ== +tailwindcss@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-2.1.2.tgz#29402bf73a445faedd03df6d3b177e7b52b7c4a1" + integrity sha512-T5t+wwd+/hsOyRw2HJuFuv0LTUm3MUdHm2DJ94GPVgzqwPPFa9XxX0KlwLWupUuiOUj6uiKURCzYPHFcuPch/w== dependencies: "@fullhuman/postcss-purgecss" "^3.1.3" bytes "^3.0.0" From 5ad43493cd4a6f6c5161e0c988f02cf1129664b1 Mon Sep 17 00:00:00 2001 From: mlabate Date: Sun, 25 Apr 2021 20:00:20 +0200 Subject: [PATCH 14/77] Fix typo tutorial.mdx (#458) Typo removed --- app/pages/docs/tutorial.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/tutorial.mdx b/app/pages/docs/tutorial.mdx index 94e3792..d299d78 100644 --- a/app/pages/docs/tutorial.mdx +++ b/app/pages/docs/tutorial.mdx @@ -828,7 +828,7 @@ this! #### Now it’s time to add voting! First we need to open `app/choices/mutations/updateChoice.ts`, update the -zod schema, and add add a vote increment. +zod schema, and add a vote increment. ```diff const UpdateChoice = z From 2c987bbf1570847bc4688923d4f8c26e067eba82 Mon Sep 17 00:00:00 2001 From: JuanM04 Date: Tue, 27 Apr 2021 17:57:35 -0300 Subject: [PATCH 15/77] Admonitions --> Cards (#456) --- README.md | 21 +++++++ app/core/components/docs/Card.js | 44 ++++++++++++++ app/core/components/docs/Card.module.css | 30 ++++++++++ app/core/styles/utilities.css | 55 ------------------ app/pages/docs/api-routes.mdx | 12 ++-- app/pages/docs/cli-db.mdx | 14 ++--- app/pages/docs/cli-start.mdx | 8 +-- app/pages/docs/contributing.mdx | 20 +++---- app/pages/docs/database-overview.mdx | 8 +-- app/pages/docs/deploy-heroku.mdx | 6 +- app/pages/docs/deploy-vercel.mdx | 8 +-- app/pages/docs/get-static-props.mdx | 8 +-- app/pages/docs/image-optimization.mdx | 12 ++-- app/pages/docs/mutation-usage.mdx | 16 ++--- app/pages/docs/query-usage.mdx | 16 ++--- app/pages/docs/resolver-server-utilities.mdx | 12 ++-- app/pages/docs/rpc-specification.mdx | 12 ++-- app/pages/docs/static-html-export.mdx | 8 +-- app/pages/docs/templates.mdx | 8 +-- app/pages/docs/tutorial.mdx | 14 ++--- blitz.config.js | 29 ++-------- package.json | 1 - tailwind.config.js | 6 -- yarn.lock | 61 +------------------- 24 files changed, 193 insertions(+), 236 deletions(-) create mode 100644 app/core/components/docs/Card.js create mode 100644 app/core/components/docs/Card.module.css diff --git a/README.md b/README.md index ee04909..f7d345a 100644 --- a/README.md +++ b/README.md @@ -70,3 +70,24 @@ Example: ``` If you aren't totally sure how the slug should look like, or just want to automate the process, run `yarn english-slugify` + +## Cards + +You can use cards, like the one at the start of [_API Routes_](https://blitzjs.com/docs/api-routes) like this: + +```md + + +Unlike Next.js, your `api/` folder should be a sibling of `pages/` instead +of being nested inside. But `pages/api` is still supported for +compatibility with Next.js. + + +``` + +Properties: + +- `type`: `'caution' | 'info' | 'note'` +- `title`: `string` (optional) + +**Remember to leave an empty line** between the component tag and the content as shown in the example above. diff --git a/app/core/components/docs/Card.js b/app/core/components/docs/Card.js new file mode 100644 index 0000000..c09bc6a --- /dev/null +++ b/app/core/components/docs/Card.js @@ -0,0 +1,44 @@ +import clsx from "clsx" + +import styles from "./Card.module.css" + +/** + * @param {{type: 'caution' | 'info' | 'note', title: string, children: any}} + * @returns + */ +export function Card({type, title, children}) { + const defaultTitle = type[0].toUpperCase() + type.substr(1) + + return ( +
+
+ + + + {title || defaultTitle} +
+
{children}
+
+ ) +} + +const InfoIcon = () => ( + + + + +) diff --git a/app/core/components/docs/Card.module.css b/app/core/components/docs/Card.module.css new file mode 100644 index 0000000..61bd0ff --- /dev/null +++ b/app/core/components/docs/Card.module.css @@ -0,0 +1,30 @@ +.container { + @apply p-5 mb-4 rounded-xl; + + a { + /* Remember to change this if you update the a (anchor, link) styles */ + @apply text-purple-light font-medium no-underline hover:underline; + } +} + +.heading { + @apply mt-0 mb-4 capitalize font-bold flex items-center text-black; +} + +.icon { + @apply inline-block align-middle mr-2; + + svg { + @apply block w-4 h-4 stroke-0; + } +} + +.content { + * { + @apply text-black; + } + + strong { + color: inherit !important; + } +} diff --git a/app/core/styles/utilities.css b/app/core/styles/utilities.css index f7961a9..43541d0 100644 --- a/app/core/styles/utilities.css +++ b/app/core/styles/utilities.css @@ -130,61 +130,6 @@ body.cursor-grabbing * { background-repeat: no-repeat; } -/* Like doing `!important`, but worse */ -.admonition.admonition.admonition { - @apply px-5 pt-5 pb-px rounded-xl text-black; - - a { - /* Remember to change this if you update the a (anchor, link) styles */ - @apply text-purple-light font-medium no-underline hover:underline; - } -} - -.admonition-content > *:first-child { - @apply mt-2; -} - -.admonition.admonition-caution { - @apply bg-supplementary-yellow; -} - -.admonition.admonition-info { - @apply bg-supplementary-blue; -} - -.admonition.admonition-note { - @apply bg-blue-primary; -} - -.admonition .admonition-heading { - @apply capitalize font-bold; -} - -.admonition .admonition-heading > * { - @apply flex items-center; - margin-top: 0; -} - -.admonition .admonition-icon { - @apply mr-2; -} - -.admonition .admonition-icon { - @apply mr-2; -} - -.dark .admonition .admonition-heading h5 { - @apply text-black; -} - -.dark .admonition .admonition-content.admonition-content { - @apply text-black; -} - -.dark .admonition .admonition-content.admonition-content strong { - color: inherit; -} - .topic-select .topic-select__placeholder, .topic-select .topic-select__menu-list, .topic-select .topic-select__single-value { diff --git a/app/pages/docs/api-routes.mdx b/app/pages/docs/api-routes.mdx index 76a1d75..83573a2 100644 --- a/app/pages/docs/api-routes.mdx +++ b/app/pages/docs/api-routes.mdx @@ -3,13 +3,13 @@ title: API Routes sidebar_label: API Routes --- - -:::info -Unlike Next.js, your `api/` folder should be a sibling of `pages/` -instead of being nested inside. But `pages/api` is still supported for + + +Unlike Next.js, your `api/` folder should be a sibling of `pages/` instead +of being nested inside. But `pages/api` is still supported for compatibility with Next.js. -::: - + + Any file inside an `api/` folder are accessible at a URL corresponding to its path inside `api/`. So `app/projects/api/webhook.ts` will be at diff --git a/app/pages/docs/cli-db.mdx b/app/pages/docs/cli-db.mdx index 643c3c6..b2cb5d8 100644 --- a/app/pages/docs/cli-db.mdx +++ b/app/pages/docs/cli-db.mdx @@ -3,13 +3,13 @@ title: blitz db sidebar_label: blitz db --- - -:::caution -This command is now deprecated in favor of using the -`blitz prisma` command. The `blitz db seed` command still works until -Prisma finishes adding their native seeding functionatily. -::: - + + +This command is now deprecated in favor of using the `blitz prisma` +command. The `blitz db seed` command still works until Prisma finishes +adding their native seeding functionatily. + + ### `blitz db seed` {#blitz-db-seed} diff --git a/app/pages/docs/cli-start.mdx b/app/pages/docs/cli-start.mdx index 4a050b6..6010aae 100644 --- a/app/pages/docs/cli-start.mdx +++ b/app/pages/docs/cli-start.mdx @@ -17,11 +17,11 @@ Starts the Blitz production server. #### Examples - -:::note + + Make sure to run `blitz build` before running `blitz start` -::: - + + ```bash blitz start diff --git a/app/pages/docs/contributing.mdx b/app/pages/docs/contributing.mdx index ae928c2..b85185c 100644 --- a/app/pages/docs/contributing.mdx +++ b/app/pages/docs/contributing.mdx @@ -204,16 +204,16 @@ If they do, then locally run the one that fails and fix the issue. ### Testing Development Version of Blitz Inside and App {#testing-development-version-of-blitz} - -:::info -Currently, to test the local dev version of Blitz, you can -**only** test an app inside the `blitz/examples/` folder. In there, the -blitz dependency will automatically use the local dev version. We mainly -use the `auth` and `store` example apps. We use them for development -testing and for blitz integration tests. You must also make sure you are -running `yarn dev` in the `blitz` folder at the same time. -::: - + + +Currently, to test the local dev version of Blitz, you can **only** test +an app inside the `blitz/examples/` folder. In there, the blitz dependency +will automatically use the local dev version. We mainly use the `auth` and +`store` example apps. We use them for development testing and for blitz +integration tests. You must also make sure you are running `yarn dev` in +the `blitz` folder at the same time. + + For using in apps outside the repo, [yalc](https://github.com/whitecolor/yalc) should work, but hasn't been diff --git a/app/pages/docs/database-overview.mdx b/app/pages/docs/database-overview.mdx index 5ef504c..b5f670b 100644 --- a/app/pages/docs/database-overview.mdx +++ b/app/pages/docs/database-overview.mdx @@ -3,13 +3,13 @@ title: Database Overview sidebar_label: Overview --- - -:::info + + If you are totally new to Databases, check out [Prisma's Data Guide](https://www.prisma.io/dataguide/) which covers the very large majority of everything you might want to know. -::: - + + By default, Blitz uses Prisma 2 which is a strongly typed database client. diff --git a/app/pages/docs/deploy-heroku.mdx b/app/pages/docs/deploy-heroku.mdx index db3ac67..8375a24 100644 --- a/app/pages/docs/deploy-heroku.mdx +++ b/app/pages/docs/deploy-heroku.mdx @@ -3,8 +3,7 @@ title: Deploy to a Server on Heroku sidebar_label: To Heroku --- - -:::info + This guide assumes the following: @@ -16,8 +15,7 @@ This guide assumes the following: 4. That deployments will be made with git and the [Heroku CLI](https://devcenter.heroku.com/articles/heroku-cli). -::: - + **In Heroku:** diff --git a/app/pages/docs/deploy-vercel.mdx b/app/pages/docs/deploy-vercel.mdx index 77348ae..0c71e29 100644 --- a/app/pages/docs/deploy-vercel.mdx +++ b/app/pages/docs/deploy-vercel.mdx @@ -3,15 +3,15 @@ title: Deploy Serverless to Vercel sidebar_label: To Vercel --- - -:::caution + + We do not recommend deploying Blitz to Vercel. Vercel is a platform optimized for frontend deployments, not fullstack. While you can deploy to Vercel, most people run into too many issues and give up. Direct SQL database connections are one of the biggest issues. You have to pay for a very expensive database to support any amount of scale. -::: - + + ## Serverless Peculiarities for SQL Databases {#peculiarities} diff --git a/app/pages/docs/get-static-props.mdx b/app/pages/docs/get-static-props.mdx index 9f4f34b..830227b 100644 --- a/app/pages/docs/get-static-props.mdx +++ b/app/pages/docs/get-static-props.mdx @@ -3,8 +3,8 @@ title: getStaticProps API sidebar_label: getStaticProps API --- - -:::info + + `getStaticProps` should only be used for pages that do not require authentication. The statically generated pages will be publicly available via your server and via a CDN if you have one. Therefore they cannot @@ -13,8 +13,8 @@ contain any personal or sensitive data. Also, this is why there is no `req` and `res` objects for `getStaticProps`, because the pages are generated at build time, not at runtime. And at build time, there is no user http request to handle. -::: - + + If you export an `async` function called `getStaticProps` from a page, Blitz will pre-render this page at build time using the props returned by diff --git a/app/pages/docs/image-optimization.mdx b/app/pages/docs/image-optimization.mdx index 288e299..a5ccc58 100644 --- a/app/pages/docs/image-optimization.mdx +++ b/app/pages/docs/image-optimization.mdx @@ -330,15 +330,15 @@ The image position when using `layout="fill"`. #### loading - -:::caution -This property is only meant for advanced usage. Switching an image to -load with `eager` will normally **hurt performance**. + + +This property is only meant for advanced usage. Switching an image to load +with `eager` will normally **hurt performance**. We recommend using the `priority` property instead, which properly loads the image eagerly for nearly all use cases. -::: - + + The loading behavior of the image. Defaults to `lazy`. diff --git a/app/pages/docs/mutation-usage.mdx b/app/pages/docs/mutation-usage.mdx index 855f3ae..f1a21c6 100644 --- a/app/pages/docs/mutation-usage.mdx +++ b/app/pages/docs/mutation-usage.mdx @@ -40,14 +40,14 @@ function (props) { For complete details, see the [`useMutation` documentation](./use-mutation). - -:::info 🤔 -You may be wondering how that can work since it's importing -server code into your component: At build time, the direct function import -is swapped out with a network call. So the query function code is never -included in your client code. -::: - + + +You may be wondering how that can work since it's importing server code +into your component: At build time, the direct function import is swapped +out with a network call. So the query function code is never included in +your client code. + + ## Error Handling {#error-handling} diff --git a/app/pages/docs/query-usage.mdx b/app/pages/docs/query-usage.mdx index 87463b1..6bb024b 100644 --- a/app/pages/docs/query-usage.mdx +++ b/app/pages/docs/query-usage.mdx @@ -31,14 +31,14 @@ function App() { For complete details, see the [`useQuery` documentation](./use-query). - -:::info 🤔 -You may be wondering how that can work since it's importing -server code into your component: At build time, the direct function import -is swapped out with a network call. So the query function code is never -included in your client code. -::: - + + +You may be wondering how that can work since it's importing server code +into your component: At build time, the direct function import is swapped +out with a network call. So the query function code is never included in +your client code. + + ### Defaults to Keep in Mind {#defaults-to-keep-in-mind} diff --git a/app/pages/docs/resolver-server-utilities.mdx b/app/pages/docs/resolver-server-utilities.mdx index 90c17b4..f73835e 100644 --- a/app/pages/docs/resolver-server-utilities.mdx +++ b/app/pages/docs/resolver-server-utilities.mdx @@ -78,15 +78,15 @@ export default resolver.pipe( ) ``` - -:::info -The input type of the entire composed resolver function is -determined by the input type of the **first** argument to pipe. + + +The input type of the entire composed resolver function is determined by +the input type of the **first** argument to pipe. This means you will almost always want `resolver.zod()` to be the first in the pipe. -::: - + + ### API {#api} diff --git a/app/pages/docs/rpc-specification.mdx b/app/pages/docs/rpc-specification.mdx index d453efa..1aced09 100644 --- a/app/pages/docs/rpc-specification.mdx +++ b/app/pages/docs/rpc-specification.mdx @@ -4,18 +4,18 @@ title: RPC Specification sidebar_label: RPC Specification --- - -:::caution -This is documentation for using Blitz queries and mutations in -a non-Blitz app. For example, from a mobile application or some other app. + + +This is documentation for using Blitz queries and mutations in a non-Blitz +app. For example, from a mobile application or some other app. **For using queries and mutations in your app, refer to [Using Queries](./query-usage) and [Using Mutations](./mutation-usage).** **If you want to access your app e.g. as an external API, take a look at [API Routes](./api-routes) instead.** -::: - + + ## URL {#url} diff --git a/app/pages/docs/static-html-export.mdx b/app/pages/docs/static-html-export.mdx index efd2c9d..ce2ca2d 100644 --- a/app/pages/docs/static-html-export.mdx +++ b/app/pages/docs/static-html-export.mdx @@ -20,14 +20,14 @@ route. server-side or incremental data requirements (though statically-rendered pages can still fetch data on the client side normally). - -:::info + + If you're looking to make a hybrid site where only some pages are prerendered to static HTML, Blitz already does that automatically for you! If your page doesn't use `getServerSideProps`, then it will be a static HTML page. -::: - + + `blitz export` also causes features like [Incremental Static Generation and Regeneration](get-static-props#incremental-static-regeneration) diff --git a/app/pages/docs/templates.mdx b/app/pages/docs/templates.mdx index ad7064e..1e46303 100644 --- a/app/pages/docs/templates.mdx +++ b/app/pages/docs/templates.mdx @@ -43,14 +43,14 @@ If you access a variable that _isn't_ a template value it is ignored, allowing functionality like dead code elimination via `process.env.NODE_ENV` into template to work properly. -:::info + The conditions are not dynamically evaluated, they're only checked for truthiness. This means that for dynamic evaluation you'll need to do the check ahead of time and pass it into the template as context, a check like `if (process.env.componentName === 'SomeComp')` will not work properly. -::: + ```typescript // Input @@ -123,13 +123,13 @@ prop on the `if` statement is read out of the template context. If its value is truthy the first child of `` will be rendered, otherwise the contents of the `` element will be rendered. -:::info + Both `` and `` only accept a **single child component.** You will see unexpected behavior and errors if you try to provide a fragment or multiple elements. -::: + ```tsx // input diff --git a/app/pages/docs/tutorial.mdx b/app/pages/docs/tutorial.mdx index d299d78..4da4539 100644 --- a/app/pages/docs/tutorial.mdx +++ b/app/pages/docs/tutorial.mdx @@ -401,13 +401,13 @@ undefined ## Update generated code for our model attributes {#update-generated-code-for-our-model-attributes} - -:::info -Before running the app again, we need to customize some of the -code that has been generated. Ultimately, these fixes will not be needed - -but for now, we need to work around a couple outstanding issues. -::: - + + +Before running the app again, we need to customize some of the code that +has been generated. Ultimately, these fixes will not be needed - but for +now, we need to work around a couple outstanding issues. + + The generated page content does not currently use the actual model attributes you defined during generation. It will soon, but in the diff --git a/blitz.config.js b/blitz.config.js index 105ea25..eb06b31 100644 --- a/blitz.config.js +++ b/blitz.config.js @@ -11,7 +11,6 @@ const minimatch = require("minimatch") const withBundleAnalyzer = require("@next/bundle-analyzer")({ enabled: process.env.ANALYZE === "true", }) -const admonitions = require("remark-admonitions") const fallbackDefaultExports = { // Have to use compiled locations @@ -90,29 +89,7 @@ module.exports = withBundleAnalyzer({ { loader: "@mdx-js/loader", options: { - remarkPlugins: [ - withProse, - withTableOfContents, - withSyntaxHighlighting, - withBlitzLinks, - [ - admonitions, - { - customTypes: { - caution: { - keyword: "caution", - svg: - '', - }, - info: { - keyword: "info", - svg: - '', - }, - }, - }, - ], - ], + remarkPlugins: [withProse, withTableOfContents, withSyntaxHighlighting, withBlitzLinks], }, }, createLoader(function (source) { @@ -141,6 +118,10 @@ module.exports = withBundleAnalyzer({ } } + if (/^<\/Card>$/m.test(source)) { + extra.push(`import { Card } from '@/components/docs/Card'`) + } + return [ ...(typeof fields === "undefined" ? extra : []), typeof fields === "undefined" ? body : "", diff --git a/package.json b/package.json index 4412c50..a26a4dc 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "postcss-nested": "5.0.5", "prettier": "2.2.1", "pretty-quick": "3.1.0", - "remark-admonitions": "1.2.1", "simple-functional-loader": "1.2.1", "tailwindcss": "2.1.2" }, diff --git a/tailwind.config.js b/tailwind.config.js index d0de892..e97669d 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -79,12 +79,6 @@ module.exports = { string: "#A2F679", highlight: "rgba(134, 239, 172, 0.25)", }, - - supplementary: { - yellow: "#FDEA69", - blue: "#69C6FD", - red: "#FF003D", - }, }, fontSize: { xxs: "0.75rem", // 12px diff --git a/yarn.lock b/yarn.lock index 87fc9dd..9146fdd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4405,7 +4405,7 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -ccount@^1.0.0, ccount@^1.0.3: +ccount@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== @@ -7049,17 +7049,6 @@ hast-util-embedded@^1.0.0: dependencies: hast-util-is-element "^1.1.0" -hast-util-from-parse5@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-5.0.3.tgz#3089dc0ee2ccf6ec8bc416919b51a54a589e097c" - integrity sha512-gOc8UB99F6eWVWFtM9jUikjN7QkWxB3nY0df5Z0Zq1/Nkwl5V4hAAsl0tmwlgWl/1shlTF8DnNYLO8X6wRV9pA== - dependencies: - ccount "^1.0.3" - hastscript "^5.0.0" - property-information "^5.0.0" - web-namespaces "^1.1.2" - xtend "^4.0.1" - hast-util-from-parse5@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" @@ -7156,16 +7145,6 @@ hast-util-whitespace@^1.0.0: resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-1.0.4.tgz#e4fe77c4a9ae1cb2e6c25e02df0043d0164f6e41" integrity sha512-I5GTdSfhYfAPNztx2xJRQpG8cuDSNt599/7YUn7Gx/WxNMsG+a835k97TDkFgk123cwjfwINaZknkKkphx/f2A== -hastscript@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.2.tgz#bde2c2e56d04c62dd24e8c5df288d050a355fb8a" - integrity sha512-WlztFuK+Lrvi3EggsqOkQ52rKbxkXL3RwB6t5lwoa8QLMemoWfBuL43eDrwOamJyR7uKQKdmKYaBH1NZBiIRrQ== - dependencies: - comma-separated-tokens "^1.0.0" - hast-util-parse-selector "^2.0.0" - property-information "^5.0.0" - space-separated-tokens "^1.0.0" - hastscript@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" @@ -10309,11 +10288,6 @@ parse5@6.0.1, parse5@^6.0.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== -parse5@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" - integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== - pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" @@ -11239,15 +11213,6 @@ regjsparser@^0.6.4: dependencies: jsesc "~0.5.0" -rehype-parse@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-6.0.2.tgz#aeb3fdd68085f9f796f1d3137ae2b85a98406964" - integrity sha512-0S3CpvpTAgGmnz8kiCyFLGuW5yA4OQhyNTm/nwPopZ7+PI11WnGl1TTWTGv/2hPEe/g2jRLlhVVSsoDH8waRug== - dependencies: - hast-util-from-parse5 "^5.0.0" - parse5 "^5.0.0" - xtend "^4.0.0" - rehype-parse@^7.0.0: version "7.0.1" resolved "https://registry.yarnpkg.com/rehype-parse/-/rehype-parse-7.0.1.tgz#58900f6702b56767814afc2a9efa2d42b1c90c57" @@ -11263,15 +11228,6 @@ rehype-retext@^2.0.1: dependencies: hast-util-to-nlcst "^1.0.0" -remark-admonitions@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/remark-admonitions/-/remark-admonitions-1.2.1.tgz#87caa1a442aa7b4c0cafa04798ed58a342307870" - integrity sha512-Ji6p68VDvD+H1oS95Fdx9Ar5WA2wcDA4kwrrhVU7fGctC6+d3uiMICu7w7/2Xld+lnU7/gi+432+rRbup5S8ow== - dependencies: - rehype-parse "^6.0.2" - unified "^8.4.2" - unist-util-visit "^2.0.1" - remark-footnotes@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f" @@ -13241,17 +13197,6 @@ unified@9.2.0, unified@^9.0.0: trough "^1.0.0" vfile "^4.0.0" -unified@^8.4.2: - version "8.4.2" - resolved "https://registry.yarnpkg.com/unified/-/unified-8.4.2.tgz#13ad58b4a437faa2751a4a4c6a16f680c500fff1" - integrity sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA== - dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" - union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -13350,7 +13295,7 @@ unist-util-visit-parents@^3.0.0: "@types/unist" "^2.0.0" unist-util-is "^4.0.0" -unist-util-visit@2.0.3, unist-util-visit@^2.0.0, unist-util-visit@^2.0.1: +unist-util-visit@2.0.3, unist-util-visit@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== @@ -13714,7 +13659,7 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -web-namespaces@^1.0.0, web-namespaces@^1.1.2: +web-namespaces@^1.0.0: version "1.1.4" resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== From a67a535d5c192c1b0272dccf5991ddf2312236b9 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Tue, 27 Apr 2021 13:58:15 -0700 Subject: [PATCH 16/77] Recommend customTsParser for building a new recipe (#455) --- app/pages/docs/writing-recipes.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/pages/docs/writing-recipes.mdx b/app/pages/docs/writing-recipes.mdx index 301ae6a..2dbb341 100644 --- a/app/pages/docs/writing-recipes.mdx +++ b/app/pages/docs/writing-recipes.mdx @@ -187,11 +187,15 @@ testing, the tests are quick to write: ```typescript import j from "jscodeshift" +import { customTsParser } from "@blitzjs/installer"; + const sampleFile = `export default function Comp() { return
hello!
; })` -expect(addImport(j(sampleFile), newImport).toSource()).toMatchSnapshot() +expect(addImport(j(sampleFile, { + parser: customTsParser +}), newImport).toSource()).toMatchSnapshot() ``` #### Modifying Non-JS files From d21543d3654b286e15f95bf80c58ac03fff73ecf Mon Sep 17 00:00:00 2001 From: Muhammad Ubaid Raza Date: Wed, 28 Apr 2021 01:58:57 +0500 Subject: [PATCH 17/77] add info for proxy-support https://github.com/blitz-js/blitz/pull/2264 (#454) Co-authored-by: Brandon Bayer --- app/pages/docs/blitz-config.mdx | 19 +++++++++++++++++++ app/pages/docs/get-started.mdx | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/pages/docs/blitz-config.mdx b/app/pages/docs/blitz-config.mdx index f389057..bf6d511 100644 --- a/app/pages/docs/blitz-config.mdx +++ b/app/pages/docs/blitz-config.mdx @@ -129,6 +129,8 @@ module.exports = { ## CLI {#cli} +### Clear Console On Blitz Dev {#clear-console-on-blitz-dev} + When you run `blitz dev`, the console gets cleared. You can disable it by setting the `cli.clearConsoleOnBlitzDev` to `false`: @@ -140,6 +142,23 @@ module.exports = { } ``` +### Proxy support {#proxy-support} + +Proxy support is enabled automatically for recipe install if either `http_proxy` or `https_proxy` +environment variable is present. You can also set proxy using: + +```js +module.exports = { + cli: { + httpProxy: "http://127.0.0.1:8080", + httpsProxy: "http://127.0.0.1:8080", + noProxy: "localhost", + }, +} +``` + +Please note that proxy configuration in `blitz.config.js` will override environment proxy configuration. + ## CDN Support with Asset Prefix {#cdn-support-with-asset-prefix} To set up a [CDN](https://en.wikipedia.org/wiki/Content_delivery_network), diff --git a/app/pages/docs/get-started.mdx b/app/pages/docs/get-started.mdx index 92684ce..dffe27a 100644 --- a/app/pages/docs/get-started.mdx +++ b/app/pages/docs/get-started.mdx @@ -9,7 +9,7 @@ You need Node.js 12 or newer ### Install Blitz {#install-blitz} -Run `npm install -g blitz` +Run `yarn global add blitz` or `npm install -g blitz --legacy-peer-deps` (legacy-peer-deps is needed because npm totally change behavior of peer deps and some dependencies haven't caught up) ### Create a New App {#create-a-new-app} From 8fdf72128e8d17b8b0b4620e4140f506d0662cef Mon Sep 17 00:00:00 2001 From: Jeremy Liberman Date: Tue, 27 Apr 2021 15:59:49 -0500 Subject: [PATCH 18/77] Documentation for new schema.prisma transform utilities (#457) Co-authored-by: Brandon Bayer --- app/pages/docs/custom-server.mdx | 55 +++++----- app/pages/docs/writing-recipes.mdx | 163 +++++++++++++++++++++++++++++ 2 files changed, 193 insertions(+), 25 deletions(-) diff --git a/app/pages/docs/custom-server.mdx b/app/pages/docs/custom-server.mdx index 77a8e1a..aaf3f14 100644 --- a/app/pages/docs/custom-server.mdx +++ b/app/pages/docs/custom-server.mdx @@ -8,7 +8,8 @@ some other direct control over the web server itself. ### How {#how} -1. Add a `server.js` file in your project root. See below for an example. +1. Add a `server.ts` or `server.js` file in your project root. See below + for an example. 2. Now `blitz dev` and `blitz start` will automatically detect and use your custom server. @@ -16,12 +17,14 @@ some other direct control over the web server itself. Here's an example custom server: -```js -// server.js -const {createServer} = require("http") -const {parse} = require("url") -const blitz = require("blitz/custom-server") +```ts +// server.ts +import blitz from "blitz/custom-server" +import {createServer} from "http" +import {parse} from "url" +import {log} from "@blitzjs/display" +const {PORT = "3000"} = process.env const dev = process.env.NODE_ENV !== "production" const app = blitz({dev}) const handle = app.getRequestHandler() @@ -30,34 +33,36 @@ app.prepare().then(() => { createServer((req, res) => { // Be sure to pass `true` as the second argument to `url.parse`. // This tells it to parse the query portion of the URL. - const parsedUrl = parse(req.url, true) - const {pathname, query} = parsedUrl + const parsedUrl = parse(req.url!, true) + const {pathname} = parsedUrl + + if (pathname === "/hello") { + res.writeHead(200).end("world") + return + } - if (pathname === "/a") { + if (pathname === "/hello") { + res.writeHead(200).end("world") + return + } else if (pathname === "/a") { app.render(req, res, "/a", query) } else if (pathname === "/b") { app.render(req, res, "/b", query) } else { handle(req, res, parsedUrl) } - }).listen(3000, (err) => { - if (err) throw err - console.log("> Ready on http://localhost:3000") + + handle(req, res, parsedUrl) + }).listen(PORT, () => { + log.success(`Ready on http://localhost:${PORT}`) }) }) ``` -> `server.js` doesn't go through babel or webpack. Make sure the syntax -> and sources this file requires are compatible with the current node -> version you are running. - --- -The custom server uses the following import to connect the server with the -Blitz application: - -The above `blitz` import is a function that receives an object with the -following options: +The above `blitz/custom-server` import is a function that receives an +object with the following options: - `dev`: `Boolean` - Whether or not to launch Blitz in dev mode. Defaults to `false` @@ -72,10 +77,10 @@ required. ## Disabling file-system routing {#disabling-file-system-routing} -By default, `blitz` will serve each file in the `pages` folder under a -pathname matching the filename. If your project uses a custom server, this -behavior may result in the same content being served from multiple paths, -which can present problems with SEO and UX. +By default, `blitz` will serve each file `pages` folders under a pathname +matching the filename. If your project uses a custom server, this behavior +may result in the same content being served from multiple paths, which can +present problems with SEO and UX. To disable this behavior and prevent routing based on files in `pages`, open `blitz.config.js` and disable the `useFileSystemPublicRoutes` config: diff --git a/app/pages/docs/writing-recipes.mdx b/app/pages/docs/writing-recipes.mdx index 2dbb341..d0e654e 100644 --- a/app/pages/docs/writing-recipes.mdx +++ b/app/pages/docs/writing-recipes.mdx @@ -216,6 +216,169 @@ builder This step would append "Paul Plain was here!" to the user's README.md +#### Modifying Prisma schemas + +A lot of recipes may need to add or modify models in the schema.prisma +file in order to apply the recipe's effects. You can attempt to manipulate +the schema using plain string transformations in `transformPlain`, but a +lot of recipes may require the ability to query something about the schema +first. For example, to determine the model on the other end of a +[Relation](https://www.prisma.io/docs/concepts/components/prisma-schema/relations/), +or to detect if a field already exists. + +For your convenience, there are several pre-written utilities for common +schema modifications: + +##### Create an Enum + +```ts +singleFileSearch: paths.prismaSchema(), +transformPlain(source: string) { + // Create the enum Role with two values, USER and ADMIN + return addPrismaEnum(source, { + type: "enum", + name: "Role", + enumerators: [ + {type: "enumerator", name: "USER"}, + {type: "enumerator", name: "ADMIN"}, + ], + }) +} +``` + +##### Add a Field to a Model + +```ts +singleFileSearch: paths.prismaSchema(), +transformPlain(source: string) { + // Add a field "name String @unique" to the "Project" model + return addPrismaField(source, "Project", { + type: "field", + name: "name", + fieldType: "String", + optional: false, + attributes: [{type: "attribute", kind: "field", name: "unique"}], + }) +} +``` + +##### Create a Generator + +```ts +singleFileSearch: paths.prismaSchema(), +transformPlain(source: string) { + // Create a prisma generator for nexus-prisma + return addPrismaGenerator(source, { + type: "generator", + name: "nexusPrisma", + assignments: [ + {type: "assignment", key: "provider", value: '"nexus-prisma"'}, + ], + }) +} +``` + +##### Create a Model + +```ts +singleFileSearch: paths.prismaSchema(), +transformPlain(source: string) { + // Create a prisma model called Project + return addPrismaModel(source, { + type: "model", + name: "Project", + properties: [{type: "field", name: "name", fieldType: "String"}], + }) +} +``` + +##### Add an Attribute such as an Index to a Model + +```ts +singleFileSearch: paths.prismaSchema(), +transformPlain(source: string) { + // Creates an index attribute on the Project model "@@index([name])" + return addPrismaModelAttribute(source, "Project", { + type: "attribute", + kind: "model", + name: "index", + args: [ + {type: "attributeArgument", value: {type: "array", args: ["name"]}}, + ], + }) +} +``` + +##### Set the schema's Datasource + +Since a prisma schema can only have one data source, there is no "add" +utility, this will replace the schema's current data source. + +```ts +singleFileSearch: paths.prismaSchema(), +transformPlain(source: string) { + // Set the datasource to postgresql + return setPrismaDataSource(source, { + type: "datasource", + name: "db", + assignments: [ + {type: "assignment", key: "provider", value: '"postgresql"'}, + { + type: "assignment", + key: "url", + value: {type: "function", name: "env", params: ['"DATABASE_URL"']}, + }, + ], + }) +} +``` + +##### Custom Schema Transformations with produceSchema + +If the provided helpers aren't flexible enough for your recipe, you can +use the `produceSchema` utility function to parse the prisma schema file +and apply custom transformations. It will convert the schema into a JSON +object format that you can modify using JavaScript, then print the schema +(with your changes applied) back out to a string. All of the above helpers +are implemented using `produceSchema`. + +```ts +builder.addTransformFilesStep({ + ..., + singleFileSearch: paths.prismaSchema(), + transformPlain(source: string) { + return produceSchema(source, (schema) => { + // find a model named "User" + const model = schema.list.find(function(item): item is Model { + return item.type === "model" && item.name === "User" + }) as Model + if (!model) return + + // find a field on the "User" model named "email" + const field = model.properties.find(function (property): property is Field { + return property.type === "attribute" && property.name === "email" + }) + if (!field) return + + // add the "@unique" attribute to "email" + field.attributes?.push({ + type: "attribute", + kind: "field", + name: "unique" + }) + }) + } +}) +``` + +It is a best practice for schema transformations to be idempotent, meaning +that the function should not attempt to make a change to the schema if +that change already has been made. For instance, do not add a field to a +model if that field already exists. + +To see how the schema file is parsed, +[click here](https://github.com/MrLeebo/prisma-ast). + ### Publishing {#publishing} That's all you need to build a recipe! At this point, you can commit and From a52e32decbd679d6b1ffdb0ddd14ca8f6c3c21bb Mon Sep 17 00:00:00 2001 From: Antony Date: Tue, 27 Apr 2021 23:00:41 +0200 Subject: [PATCH 19/77] Extend "run postgres via docker" section (#460) --- app/pages/docs/postgres.mdx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/pages/docs/postgres.mdx b/app/pages/docs/postgres.mdx index 5b509b8..3f2e54c 100644 --- a/app/pages/docs/postgres.mdx +++ b/app/pages/docs/postgres.mdx @@ -68,7 +68,8 @@ POSTGRES_PASSWORD=your_password POSTGRES_DB=your_database_name ``` -Given these values your `DATABASE_URL` should look like this +Given these values, update `DATABASE_URL` in `.env.local` to something +similar like `postgresql://your_user:your_password@localhost:5432/your_database_name` 3. Modify your `package.json` to start the database before Blitz @@ -80,5 +81,6 @@ Given these values your `DATABASE_URL` should look like this } ``` -4. Run `blitz prisma migrate dev` to get your new database to the latest - version of your migrations +4. Start your new database and get it to the latest version of your + migrations by running `docker-compose up -d` and + `blitz prisma migrate dev`. From 63d81edb440b8a4fe06b5875d3ca219f6625f27f Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Wed, 28 Apr 2021 17:25:22 -0400 Subject: [PATCH 20/77] add multitenancy doc page --- app/core/navs/documentation.json | 2 +- app/pages/docs/multitenancy.mdx | 360 +++++++++++++++++++++++++++++++ 2 files changed, 361 insertions(+), 1 deletion(-) create mode 100644 app/pages/docs/multitenancy.mdx diff --git a/app/core/navs/documentation.json b/app/core/navs/documentation.json index 2006562..0979214 100644 --- a/app/core/navs/documentation.json +++ b/app/core/navs/documentation.json @@ -126,7 +126,7 @@ "iconPath": "/img/mutations.svg", "iconDarkPath": "/img/mutations-white.svg" }, - "pages": ["background-processing-with-quirrel", "middleware", "custom-server"] + "pages": ["multitenancy", "background-processing-with-quirrel", "middleware", "custom-server"] }, { "title": { diff --git a/app/pages/docs/multitenancy.mdx b/app/pages/docs/multitenancy.mdx new file mode 100644 index 0000000..d716ead --- /dev/null +++ b/app/pages/docs/multitenancy.mdx @@ -0,0 +1,360 @@ +--- +title: Multitenancy +sidebar_label: Multitenancy +--- + +Multitenancy is a software architecture where a single app can server +multiple different users or organizations whose data is kept private from +the other users of the system. One way to do this is have a totally +separate database for each user, but that has a high operations overhead. +The most common way is to store all user data in a single database and use +foreign keys to keep data private. + +This guide shows you a good way to implement a multitenant Blitz app. + +## Data Model {#data-model} + +We recommend implementing the data model +[as described by Andrew Culver of Bullet Train](https://blog.bullettrain.co/teams-should-be-an-mvp-feature/). + +- The `Organization` is the "God" model which owns everything for an + account +- An `Organization` **has many** `User`s **through** `Membership` +- Every other model in the system has an `organizationId` to indicate who + owns it. +- A `User` can have access to multiple `Organization`s +- When assigning an entity to a user, like a task, assign the task to the + user's `Membership` instead of directly to the user. See the Bullet + Train blog post linked above for more explanation on this. + +The prisma schema looks like this: + +```prisma +model Organization { + id Int @id @default(autoincrement()) + name String + role GlobalRole + + membership Membership[] +} + +// The owners of the SaaS (you) can have a SUPERADMIN role to access all data +enum GlobalRole { + SUPERADMIN + CUSTOMER +} + +model Membership { + id Int @id @default(autoincrement()) + role MembershipRole + + organization Organization @relation(fields: [organizationId], references: [id]) + organizationId Int + + user User? @relation(fields: [userId], references: [id]) + userId Int? + + // When the user joins, we will clear out the name and email and set the user. + invitedName String? + invitedEmail String? + + @@unique([organizationId, invitedEmail]) +} + +enum MembershipRole { + OWNER + ADMIN + USER +} + +model User { + id Int @id @default(autoincrement()) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + name String? + email String @unique + + memberships Membership[] +} +``` + +Then you will need to update your `signup` mutation to also create an +organization and membership at the same time as you create the user. Like +this: + +```ts +const user = await db.user.create({ + data: { + // ... + memberships: { + create: { + role: "OWNER", + organization: { + create: { + name: organizationName, + }, + }, + }, + }, + }, +}) +``` + +## User Sessions {#sessions} + +The above data model allows a single user to be in multiple organizations. +So how can we track which organization a user is currently accessing or +modifying? + +The best way is to only let a user access one organization at a time. And +then provide a menu in the UI that let's them switch which organization +they are accessing. + +To do that, first add an `orgId` field to the +[session `PublicData`](./session-management#change-session-public-data-of-current-user). + +Update `types.ts` like this: + +```diff ++import { GlobalRole, MembershipRole, Organization } from "db" + +declare module "blitz" { + export interface Ctx extends DefaultCtx { + session: SessionContext + } + export interface Session { + isAuthorized: SimpleRolesIsAuthorized + PublicData: { + userId: User["id"] ++ roles: Array ++ orgId: Organization["id"] + } + } +} +``` + +and then update all places where you call `ctx.session.$create()`. You +will need to add `orgId` and update `roles`. + +It will look something like this: + +```ts +await session.$create({ + userId: user.id, + roles: [user.role, user.memberships[0].role], + orgId: user.memberships[0].organizationId, +}) +``` + +Then you can use `ctx.session.orgId` in queries and mutations to filter +your queries based on the current organization. + +## Queries {#queries} + +You must filter all your queries by `organizationId` to ensure one user +cannot see another user's private data. + +```ts +import db from "db" + +// If you accept only the `id` as input +const project = await db.project.findFirst({ + where: { + id: input.id, + organizationId: ctx.session.orgId, + }, +}) + +// If you accept `where` as input +const projects = await db.project.findMany({ + where: { + ...input.where, + organizationId: ctx.session.orgId, + }, +}) +``` + +## Mutations {#mutations} + +You must also filter mutations by `organizationId` to ensure another +user's data can't be updated. And when creating new entities, ensure you +set `organizationId` to the current organization (`ctx.session.orgId`). + +Here's an example where a mutation accepts `id` that could be the id of an +entity belonging to a different organization. You could first make a +`db.project.findFirst()` query for that id and then manually verify that +`organizationId` is correct. But the easier way shown here is by adding +`organizationId` to the `db.update` `where` input. This update call will +fail if the organizationId doesn't match. + +```ts +import {resolver} from "blitz" +import db from "db" +import * as z from "zod" + +const UpdateProject = z + .object({ + id: z.number(), + name: z.string(), + }) + .nonstrict() + +export default resolver.pipe( + resolver.zod(UpdateProject), + resolver.authorize(), + async ({id, ...data}, ctx) => { + const project = await db.project.update({ + where: { + id, + // Filter by organizationId + organizationId: ctx.session.orgId, + }, + data, + }) + + return project + }, +) +``` + +## Advanced Authorization {#authorization} + +You can do more advanced things like calling `ctx.session.$authorize()` +inside an if/else + +```ts +import {resolver} from "blitz" +import db, {GlobalRole, MembershipRole} from "db" +import * as z from "zod" + +const UpdateProject = z + .object({ + id: z.number(), + organizationId: z.number(), + name: z.string(), + }) + .nonstrict() + +export default resolver.pipe( + resolver.zod(UpdateProject), + // Ensure all users are logged in + resolver.authorize(), + async ({id, organizationId, ...data}, ctx) => { + // if organizationId doesn't match current organization + if (organizationId !== ctx.session.orgId) { + // Require SUPERADMIN role + ctx.session.$authorize(GlobalRole.SUPERADMIN) + } else if (!ctx.session.accessibleProjects.includes(id)) { + // If user doesn't have specific access to this project, + // require them to be a project manager + ctx.session.$authorize(MembershipRole.PROJECT_MANAGER) + } + + const project = await db.project.update({ + where: { + id, + organizationId, + }, + data, + }) + + return project + }, +) +``` + +#### Utilities + +Here's some advanced utilities that allow you to do authorization in a way +that allows SUPERADMINs to access all organizations but only permits +regular users to access the organization they are currently logged in to. + +```ts +// app/orders/queries/getOrder.ts +import {NotFoundError, resolver} from "blitz" +import db from "db" +import * as z from "zod" +import { + enforceAdminOrProctorIfNotCurrentOrganization, + setDefaultOrganizationId, +} from "app/core/utils" + +const GetOrder = z.object({ + id: z.number(), + organizationId: z.number().optional(), +}) + +export default resolver.pipe( + resolver.zod(GetOrder), + // Ensure user is logged in + resolver.authorize(), //highlight-line + // Set input.organizationId to the current organization if one is not set + // This allows SUPERADMINs to pass in a specific organizationId + setDefaultOrganizationId, //highlight-line + // But now we need to enforce input.organizationId matches + // session.orgId unless user is a SUPERADMIN + enforceSuperAdminIfNotCurrentOrganization, //highlight-line + async ({id, organizationId}) => { + const order = await db.getOrder({ + where: { + id, + // Now we can safely use organizationId to filter queries + organizationId, + }, + }) + if (!order) throw new NotFoundError() + return order + }, +) +``` + +```ts +// app/core/utils.ts +import {Ctx} from "blitz" +import {Prisma, GloblRole} from "db" + +export default function assert( + condition: any, + message: string, +): asserts condition { + if (!condition) throw new Error(message) +} + +export const setDefaultOrganizationId = >( + input: T, + {session}: Ctx, +): T & {organizationId: Prisma.IntNullableFilter | number} => { + assert( + session.orgId, + "Missing session.orgId in setDefaultOrganizationId", + ) + if (input.organizationId) { + // Pass through the input + return input as T & {organizationId: number} + } else if (session.roles?.includes(GloblRole.SUPERADMIN)) { + // Allow viewing any organization + return {...input, organizationId: {not: 0}} + } else { + // Set organizationId to session.orgId + return {...input, organizationId: session.orgId} + } +} + +export const enforceSuperAdminIfNotCurrentOrganization = < + T extends Record +>( + input: T, + ctx: Ctx, +): T => { + assert(ctx.session.orgId, "missing session.orgId") + assert(input.organizationId, "missing input.organizationId") + + if (input.organizationId !== ctx.session.orgId) { + ctx.session.$authorize(GloblRole.SUPERADMIN) + } + return input +} +``` + +If you want to do more advanced authorization, check out +[Blitz Guard](https://github.com/ntgussoni/blitz-guard). From 1b4420a5da4c73158d206be29d849312b076cb49 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Wed, 28 Apr 2021 17:30:26 -0400 Subject: [PATCH 21/77] update query and mutation docs to reflect latest recommendations --- app/pages/docs/mutation-resolvers.mdx | 21 +++++++++++++++------ app/pages/docs/query-resolvers.mdx | 21 ++++++++++++++------- 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/app/pages/docs/mutation-resolvers.mdx b/app/pages/docs/mutation-resolvers.mdx index 24cbd94..827f7c3 100644 --- a/app/pages/docs/mutation-resolvers.mdx +++ b/app/pages/docs/mutation-resolvers.mdx @@ -35,20 +35,29 @@ fetching from third-party APIs. ```ts // app/products/mutations/createProduct.tsx import {Ctx} from "blitz" -import db, {ProjectCreateArgs} from "db" +import db from "db" +import * as z from "zod" -type CreateProjectInput = { - data: ProjectCreateArgs["data"] -} +const CreateProject = z + .object({ + name: z.string(), + }) + .nonstrict() export default async function createProject( - {data}: CreateProjectInput, + input: z.infer, ctx: Ctx, ) { - // Can do any processing, fetching from other APIs, etc + // Validate input - very importnant for security + const data = CreateProject.parse(input) + + // Require user to be logged in + ctx.session.$authorize() const project = await db.project.create({data}) + // Can do any processing, fetching from other APIs, etc + return project } ``` diff --git a/app/pages/docs/query-resolvers.mdx b/app/pages/docs/query-resolvers.mdx index 602f26e..df67a1d 100644 --- a/app/pages/docs/query-resolvers.mdx +++ b/app/pages/docs/query-resolvers.mdx @@ -35,19 +35,26 @@ fetching from third-party APIs. ```ts // app/products/queries/getProduct.tsx import {Ctx} from "blitz" -import db, {FindOneProjectArgs} from "db" +import db from "db" +import * as z from "zod" -type GetProjectInput = { - where: FindOneProjectArgs["where"] -} +const GetProject = z.object({ + id: z.number(), +}) export default async function getProject( - {where}: GetProjectInput, + input: z.infer, ctx: Ctx, ) { - // Can do any processing, fetching from other APIs, etc + // Validate the input + const data = GetProject.parse(input) + + // Require user to be logged in + ctx.session.$authorize() - const project = await db.project.findOne({where}) + const project = await db.project.findOne({where: {id: data.id}}) + + // Can do any processing, fetching from other APIs, etc return project } From 8d31fabeeeb2327bb06d63dc36c42524d982545f Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Thu, 29 Apr 2021 12:44:52 -0400 Subject: [PATCH 22/77] add example of creating entity to multitenancy page --- app/pages/docs/multitenancy.mdx | 35 ++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/app/pages/docs/multitenancy.mdx b/app/pages/docs/multitenancy.mdx index d716ead..79bf262 100644 --- a/app/pages/docs/multitenancy.mdx +++ b/app/pages/docs/multitenancy.mdx @@ -176,9 +176,38 @@ const projects = await db.project.findMany({ ## Mutations {#mutations} -You must also filter mutations by `organizationId` to ensure another -user's data can't be updated. And when creating new entities, ensure you -set `organizationId` to the current organization (`ctx.session.orgId`). +When creating new entities, make sure you attach them to the current +organization. Here's an example of how to do that: + +```ts +import {resolver} from "blitz" +import db from "db" +import * as z from "zod" + +const CreateProject = z + .object({ + name: z.string(), + }) + .nonstrict() + +export default resolver.pipe( + resolver.zod(CreateProject), + resolver.authorize(), + async (input, ctx) => { + const project = await db.project.create({ + data: { + ...input, + organizationId: ctx.session.orgId, + }, + }) + + return project + }, +) +``` + +You must also filter update and delete mutations by `organizationId` to +ensure another user's data can't be changed. Here's an example where a mutation accepts `id` that could be the id of an entity belonging to a different organization. You could first make a From bf793f80813b8e7492014c0d83c3cc396517d560 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Thu, 29 Apr 2021 15:36:31 -0400 Subject: [PATCH 23/77] update docs for blitz.config.ts --- app/pages/docs/blitz-config.mdx | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/app/pages/docs/blitz-config.mdx b/app/pages/docs/blitz-config.mdx index bf6d511..82c65bf 100644 --- a/app/pages/docs/blitz-config.mdx +++ b/app/pages/docs/blitz-config.mdx @@ -3,11 +3,8 @@ title: blitz.config.js sidebar_label: blitz.config.js --- -You can customize advanced behavior of Blitz with `blitz.config.js`. - -`blitz.config.js` is a regular Node.js module, not a JSON file. It gets -used by the Blitz server and build phases, and it's not included in the -browser build. +You can customize advanced behavior of Blitz with `blitz.config.js` or +`blitz.config.ts`. Take a look at the following `blitz.config.js` example: @@ -33,7 +30,7 @@ can see the available phases Phases can be imported from `next/constants`: ```js -const {PHASE_DEVELOPMENT_SERVER} = require("next/constants") +import {PHASE_DEVELOPMENT_SERVER} from "next/constants" module.exports = (phase, {defaultConfig}) => { if (phase === PHASE_DEVELOPMENT_SERVER) { @@ -57,10 +54,6 @@ understand what each config does, instead, search for the features you need to enable or modify in this section and they will show you what to do. -> Avoid using new JavaScript features not available in your target Node.js -> version. `blitz.config.js` will not be parsed by Webpack, Babel or -> TypeScript. - ## Webpack Config {#webpack-config} You can customize the Blitz webpack config. See @@ -93,9 +86,6 @@ module.exports = { } ``` -> Deployments to [Vercel](https://vercel.com) will automatically enable -> this target. You should not opt-into it yourself. - ## Middleware {#middleware} HTTP middleware can be added queries and mutations. @@ -144,8 +134,9 @@ module.exports = { ### Proxy support {#proxy-support} -Proxy support is enabled automatically for recipe install if either `http_proxy` or `https_proxy` -environment variable is present. You can also set proxy using: +Proxy support is enabled automatically for recipe install if either +`http_proxy` or `https_proxy` environment variable is present. You can +also set proxy using: ```js module.exports = { @@ -157,7 +148,8 @@ module.exports = { } ``` -Please note that proxy configuration in `blitz.config.js` will override environment proxy configuration. +Please note that proxy configuration in `blitz.config.js` will override +environment proxy configuration. ## CDN Support with Asset Prefix {#cdn-support-with-asset-prefix} From 5ed8f32bbe86f89bebe7a273296bfe5842f48c67 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Thu, 29 Apr 2021 18:15:08 -0400 Subject: [PATCH 24/77] update docs for nextjs 10.2 --- app/core/layouts/ContentsLayout.js | 2 +- app/core/navs/documentation.json | 4 +- app/pages/docs/app-component.mdx | 15 +- app/pages/docs/blitz-config.mdx | 726 ----------------------------- app/pages/docs/code-splitting.mdx | 8 + app/pages/docs/headers.mdx | 390 ++++++++++++++++ app/pages/docs/i18n-routing.mdx | 9 +- app/pages/docs/link.mdx | 8 +- app/pages/docs/preview-mode.mdx | 16 + app/pages/docs/redirects.mdx | 292 ++++++++++++ app/pages/docs/rewrites.mdx | 400 ++++++++++++++++ 11 files changed, 1137 insertions(+), 733 deletions(-) create mode 100644 app/pages/docs/headers.mdx create mode 100644 app/pages/docs/rewrites.mdx diff --git a/app/core/layouts/ContentsLayout.js b/app/core/layouts/ContentsLayout.js index b9035fa..a2dc3d9 100644 --- a/app/core/layouts/ContentsLayout.js +++ b/app/core/layouts/ContentsLayout.js @@ -176,7 +176,7 @@ export function ContentsLayout({children, meta, tableOfContents: toc}) { The exported `pathname` can also be a filename (for example, -> `/readme.md`), but you may need to set the `Content-Type` header to -> `text/html` when serving its content if it is different than `.html`. - -#### Example - -Original pages: - -- `pages/index.js` -- `pages/about.js` -- `pages/post.js` - -`blitz.config.js`: - -```js -module.exports = { - exportPathMap: async function ( - defaultPathMap, - {dev, dir, outDir, distDir, buildId}, - ) { - return { - "/": {page: "/"}, - "/about": {page: "/about"}, - "/p/hello-nextjs": {page: "/post", query: {title: "hello-nextjs"}}, - "/p/learn-nextjs": {page: "/post", query: {title: "learn-nextjs"}}, - "/p/deploy-nextjs": { - page: "/post", - query: {title: "deploy-nextjs"}, - }, - } - }, -} -``` - ## Trailing Slash {#trailing-slash} By default Blitz will redirect urls with trailing slashes to their diff --git a/app/pages/docs/code-splitting.mdx b/app/pages/docs/code-splitting.mdx index e5dea78..7bc5abf 100644 --- a/app/pages/docs/code-splitting.mdx +++ b/app/pages/docs/code-splitting.mdx @@ -55,6 +55,14 @@ export default Home `../components/hello`. It works like a regular React Component, and you can pass props to it as you normally would. +> **Note**: In `import('path/to/component')`, the path must be explicitly +> written. It can't be a template string nor a variable. Furthermore the +> `import()` has to be inside the `dynamic()` call for Next.js to be able +> to match webpack bundles / module ids to the specific `dynamic()` call +> and preload them before rendering. `dynamic()` can't be used inside of +> React rendering as it needs to be marked in the top level of the module +> for preloading to work, similar to `React.lazy`. + ## With named exports {#with-named-exports} If the dynamic component is not the default export, you can use a named diff --git a/app/pages/docs/headers.mdx b/app/pages/docs/headers.mdx new file mode 100644 index 0000000..c9812ab --- /dev/null +++ b/app/pages/docs/headers.mdx @@ -0,0 +1,390 @@ +--- +title: HTTP Headers +sidebar_label: HTTP Headers +--- + +Headers allow you to set custom HTTP headers for an incoming request path. + +To set custom HTTP headers you can use the `headers` key in +`blitz.config.js`: + +```js +module.exports = { + async headers() { + return [ + { + source: "/about", + headers: [ + { + key: "x-custom-header", + value: "my custom header value", + }, + { + key: "x-another-custom-header", + value: "my other custom header value", + }, + ], + }, + ] + }, +} +``` + +`headers` is an async function that expects an array to be returned +holding objects with `source` and `headers` properties: + +- `source` is the incoming request path pattern. +- `headers` is an array of header objects with the `key` and `value` + properties. +- `basePath`: `false` or `undefined` - if false the basePath won't be + included when matching, can be used for external rewrites only. +- `locale`: `false` or `undefined` - whether the locale should not be + included when matching. +- `has` is an array of [has objects](#header-cookie-and-query-matching) + with the `type`, `key` and `value` properties. + +Headers are checked before the filesystem which includes pages and +`/public` files. + +## Header Overriding Behavior {#overriding} + +If two headers match the same path and set the same header key, the last +header key will override the first. Using the below headers, the path +`/hello` will result in the header `x-hello` being `world` due to the last +header value set being `world`. + +```js +module.exports = { + async headers() { + return [ + { + source: '/:path*', + headers: [ + { + key: 'x-hello', + value: 'there', + }, + ], + }, + { + source: '/hello', + headers: [ + { + key: 'x-hello', + value: 'world', + }, + ], + }, + ], + }, +} +``` + +## Path Matching {#path-matching} + +Path matches are allowed, for example `/blog/:slug` will match +`/blog/hello-world` (no nested paths): + +```js +module.exports = { + async headers() { + return [ + { + source: '/blog/:slug', + headers: [ + { + key: 'x-slug', + value: ':slug', // Matched parameters can be used in the value + }, + { + key: 'x-slug-:slug', // Matched parameters can be used in the key + value: 'my other custom header value', + }, + ], + }, + ], + }, +} +``` + +### Wildcard Path Matching {#wildcard} + +To match a wildcard path you can use `*` after a parameter, for example +`/blog/:slug*` will match `/blog/a/b/c/d/hello-world`: + +```js +module.exports = { + async headers() { + return [ + { + source: '/blog/:slug*', + headers: [ + { + key: 'x-slug', + value: ':slug*', // Matched parameters can be used in the value + }, + { + key: 'x-slug-:slug*', // Matched parameters can be used in the key + value: 'my other custom header value', + }, + ], + }, + ], + }, +} +``` + +### Regex Path Matching {#regex} + +To match a regex path you can wrap the regex in parenthesis after a +parameter, for example `/blog/:slug(\\d{1,})` will match `/blog/123` but +not `/blog/abc`: + +```js +module.exports = { + async headers() { + return [ + { + source: '/blog/:post(\\d{1,})', + headers: [ + { + key: 'x-post', + value: ':post', + }, + ], + }, + ], + }, +} +``` + +The following characters `(`, `)`, `{`, `}`, `:`, `*`, `+`, `?` are used +for regex path matching, so when used in the `source` as non-special +values they must be escaped by adding `\\` before them: + +```js +module.exports = { + async redirects() { + return [ + { + // this will match `/english(default)/something` being requested + source: "/english\\(default\\)/:slug", + destination: "/en-us/:slug", + permanent: false, + }, + ] + }, +} +``` + +## Header, Cookie, and Query Matching {#header-cookie-matching} + +To only apply a header when either header, cookie, or query values also +match the `has` field can be used. Both the `source` and all `has` items +must match for the header to be applied. + +`has` items have the following fields: + +- `type`: `String` - must be either `header`, `cookie`, `host`, or + `query`. +- `key`: `String` - the key from the selected type to match against. +- `value`: `String` or `undefined` - the value to check for, if undefined + any value will match. A regex like string can be used to capture a + specific part of the value, e.g. if the value `first-(?.*)` + is used for `first-second` then `second` will be usable in the + destination with `:paramName`. + +```js +module.exports = { + async headers() { + return [ + // if the header `x-add-header` is present, + // the `x-another-header` header will be applied + { + source: "/:path*", + has: [ + { + type: "header", + key: "x-add-header", + }, + ], + headers: [ + { + key: "x-another-header", + value: "hello", + }, + ], + }, + // if the source, query, and cookie are matched, + // the `x-authorized` header will be applied + { + source: "/specific/:path*", + has: [ + { + type: "query", + key: "page", + // the page value will not be available in the + // header key/values since value is provided and + // doesn't use a named capture group e.g. (?home) + value: "home", + }, + { + type: "cookie", + key: "authorized", + value: "true", + }, + ], + headers: [ + { + key: "x-authorized", + value: ":authorized", + }, + ], + }, + // if the header `x-authorized` is present and + // contains a matching value, the `x-another-header` will be applied + { + source: "/:path*", + has: [ + { + type: "header", + key: "x-authorized", + value: "(?yes|true)", + }, + ], + headers: [ + { + key: "x-another-header", + value: ":authorized", + }, + ], + }, + // if the host is `example.com`, + // this header will be applied + { + source: "/:path*", + has: [ + { + type: "host", + value: "example.com", + }, + ], + headers: [ + { + key: "x-another-header", + value: ":authorized", + }, + ], + }, + ] + }, +} +``` + +### Headers with basePath support {#basepath} + +When leveraging [`basePath` support](./blitz-config#base-path) with +headers each `source` is automatically prefixed with the `basePath` unless +you add `basePath: false` to the header: + +```js +module.exports = { + basePath: "/docs", + + async headers() { + return [ + { + source: "/with-basePath", // becomes /docs/with-basePath + headers: [ + { + key: "x-hello", + value: "world", + }, + ], + }, + { + source: "/without-basePath", // is not modified since basePath: false is set + headers: [ + { + key: "x-hello", + value: "world", + }, + ], + basePath: false, + }, + ] + }, +} +``` + +### Headers with i18n support {#i18n} + +When leveraging [`i18n` support](./i18n-routing) with headers each +`source` is automatically prefixed to handle the configured `locales` +unless you add `locale: false` to the header. If `locale: false` is used +you must prefix the `source` with a locale for it to be matched correctly. + +```js +module.exports = { + i18n: { + locales: ["en", "fr", "de"], + defaultLocale: "en", + }, + + async headers() { + return [ + { + source: "/with-locale", // automatically handles all locales + headers: [ + { + key: "x-hello", + value: "world", + }, + ], + }, + { + // does not handle locales automatically since locale: false is set + source: "/nl/with-locale-manual", + locale: false, + headers: [ + { + key: "x-hello", + value: "world", + }, + ], + }, + { + // this matches '/' since `en` is the defaultLocale + source: "/en", + locale: false, + headers: [ + { + key: "x-hello", + value: "world", + }, + ], + }, + { + // this gets converted to /(en|fr|de)/(.*) so will not match the top-level + // `/` or `/fr` routes like /:path* would + source: "/(.*)", + headers: [ + { + key: "x-hello", + value: "worlld", + }, + ], + }, + ] + }, +} +``` + +### Cache-Control {#cache-control} + +Cache-Control headers set in blitz.config.js will be overwritten in +production to ensure that static assets can be cached effectively. If you +need to revalidate the cache of a page that has been +[statically generated](./pages#automatic-static-optimization), you can do +so by setting `revalidate` in the page's +[`getStaticProps`](./get-static-props) function. diff --git a/app/pages/docs/i18n-routing.mdx b/app/pages/docs/i18n-routing.mdx index 4af6f30..4d3065c 100644 --- a/app/pages/docs/i18n-routing.mdx +++ b/app/pages/docs/i18n-routing.mdx @@ -9,8 +9,13 @@ routing. You can provide a list of locales, the default locale, and domain-specific locales and Blitz will automatically handle the routing. The i18n routing support is currently meant to complement existing i18n -library solutions like `react-intl`, `react-i18next`, `lingui`, `rosetta`, -and others by streamlining the routes and locale parsing. +library solutions like +[`react-intl`](https://formatjs.io/docs/getting-started/installation), +[`react-i18next`](https://react.i18next.com/), +[`lingui`](https://lingui.js.org/), +[`rosetta`](https://github.com/lukeed/rosetta), +[`next-intl`](https://github.com/amannn/next-intl) and others by +streamlining the routes and locale parsing. ## Getting started {#getting-started} diff --git a/app/pages/docs/link.mdx b/app/pages/docs/link.mdx index 5344555..841c136 100644 --- a/app/pages/docs/link.mdx +++ b/app/pages/docs/link.mdx @@ -48,8 +48,12 @@ you can link to it with `Routes.About`. For more information, see the `false` - `prefetch` - Prefetch the page in the background. Defaults to `true`. Any `` that is in the viewport (initially or through scroll) - will be preloaded. Pages using [Static Generation](./get-static-props) - will preload `JSON` files with the data for faster page transitions. + will be preloaded. Prefetch can be disabled by passing + `prefetch={false}`. When `prefetch` is set to `false`, prefetching will + still occur on hover. Pages using + [Static Generation](./get-static-props.mdx) will preload `JSON` files + with the data for faster page transitions. Prefetching is only enabled + in production. - [`replace`](#replace-the-url-instead-of-push) - Replace the current `history` state instead of adding a new url into the stack. Defaults to `false` diff --git a/app/pages/docs/preview-mode.mdx b/app/pages/docs/preview-mode.mdx index d235e6d..e25d2c4 100644 --- a/app/pages/docs/preview-mode.mdx +++ b/app/pages/docs/preview-mode.mdx @@ -244,8 +244,24 @@ there’s a size limitation. Currently, preview data is limited to 2KB. The preview mode works on `getServerSideProps` as well. It will also be available on the `context` object containing `preview` and `previewData`. +### Works with API Routes {#works-with-api-routes} + +API Routes will have access to `preview` and `previewData` under the +request object. For example: + +```js +export default function myApiRoute(req, res) { + const isPreview = req.preview + const previewData = req.previewData + // ... +} +``` + ### Unique per `blitz build` {#unique-per-blitz-build} The bypass cookie value and private key for encrypting the `previewData` changes when a `blitz build` is ran, this ensures that the bypass cookie can’t be guessed. + +> **Note:** To test Preview Mode locally over HTTP your browser will need +> to allow third-party cookies and local storage access. diff --git a/app/pages/docs/redirects.mdx b/app/pages/docs/redirects.mdx index 85f3c13..98a8650 100644 --- a/app/pages/docs/redirects.mdx +++ b/app/pages/docs/redirects.mdx @@ -3,6 +3,12 @@ title: Redirects sidebar_label: Redirects --- +Redirects allow you to redirect an incoming request path to a different +destination path. + +Redirects are only available on the Node.js environment and do not affect +client-side routing. + ## On the Client {#on-the-client} One common use case is conditionally redirecting a user to a different @@ -50,3 +56,289 @@ export const getServerSideProps = async ({req, res}) => { return {props: {}} } ``` + +## Global Redirects {#global} + +To use global redirects, you can use the `redirects` key in +`blitz.config.js`: + +```js +module.exports = { + async redirects() { + return [ + { + source: "/about", + destination: "/", + permanent: true, + }, + ] + }, +} +``` + +`redirects` is an async function that expects an array to be returned +holding objects with `source`, `destination`, and `permanent` properties: + +- `source` is the incoming request path pattern. +- `destination` is the path you want to route to. +- `permanent` if the redirect is permanent or not. +- `basePath`: `false` or `undefined` - if false the basePath won't be + included when matching, can be used for external rewrites only. +- `locale`: `false` or `undefined` - whether the locale should not be + included when matching. +- `has` is an array of [has objects](#header-cookie-and-query-matching) + with the `type`, `key` and `value` properties. + +Redirects are checked before the filesystem which includes pages and +`/public` files. + +### Path Matching {#path-matching} + +Path matches are allowed, for example `/old-blog/:slug` will match +`/old-blog/hello-world` (no nested paths): + +```js +module.exports = { + async redirects() { + return [ + { + source: "/old-blog/:slug", + destination: "/news/:slug", // Matched parameters can be used in the destination + permanent: true, + }, + ] + }, +} +``` + +#### Wildcard Path Matching + +To match a wildcard path you can use `*` after a parameter, for example +`/blog/:slug*` will match `/blog/a/b/c/d/hello-world`: + +```js +module.exports = { + async redirects() { + return [ + { + source: "/blog/:slug*", + destination: "/news/:slug*", // Matched parameters can be used in the destination + permanent: true, + }, + ] + }, +} +``` + +#### Regex Path Matching + +To match a regex path you can wrap the regex in parentheses after a +parameter, for example `/post/:slug(\\d{1,})` will match `/post/123` but +not `/post/abc`: + +```js +module.exports = { + async redirects() { + return [ + { + source: "/post/:slug(\\d{1,})", + destination: "/news/:slug", // Matched parameters can be used in the destination + permanent: false, + }, + ] + }, +} +``` + +The following characters `(`, `)`, `{`, `}`, `:`, `*`, `+`, `?` are used +for regex path matching, so when used in the `source` as non-special +values they must be escaped by adding `\\` before them: + +```js +module.exports = { + async redirects() { + return [ + { + // this will match `/english(default)/something` being requested + source: "/english\\(default\\)/:slug", + destination: "/en-us/:slug", + permanent: false, + }, + ] + }, +} +``` + +### Header, Cookie, and Query Matching {#header-cooking-matching} + +To only match a redirect when header, cookie, or query values also match +the `has` field can be used. Both the `source` and all `has` items must +match for the redirect to be applied. + +`has` items have the following fields: + +- `type`: `String` - must be either `header`, `cookie`, `host`, or + `query`. +- `key`: `String` - the key from the selected type to match against. +- `value`: `String` or `undefined` - the value to check for, if undefined + any value will match. A regex like string can be used to capture a + specific part of the value, e.g. if the value `first-(?.*)` + is used for `first-second` then `second` will be usable in the + destination with `:paramName`. + +```js +module.exports = { + async redirects() { + return [ + // if the header `x-redirect-me` is present, + // this redirect will be applied + { + source: "/:path*", + has: [ + { + type: "header", + key: "x-redirect-me", + }, + ], + permanent: false, + destination: "/another-page", + }, + // if the source, query, and cookie are matched, + // this redirect will be applied + { + source: "/specific/:path*", + has: [ + { + type: "query", + key: "page", + // the page value will not be available in the + // destination since value is provided and doesn't + // use a named capture group e.g. (?home) + value: "home", + }, + { + type: "cookie", + key: "authorized", + value: "true", + }, + ], + permanent: false, + destination: "/:path*/:page", + }, + // if the header `x-authorized` is present and + // contains a matching value, this redirect will be applied + { + source: "/:path*", + has: [ + { + type: "header", + key: "x-authorized", + value: "(?yes|true)", + }, + ], + permanent: false, + destination: "/home?authorized=:authorized", + }, + // if the host is `example.com`, + // this redirect will be applied + { + source: "/:path*", + has: [ + { + type: "host", + value: "example.com", + }, + ], + destination: "/another-page", + }, + ] + }, +} +``` + +#### Redirects with basePath support + +When leveraging [`basePath` support](./blitz-config#base-path) with +redirects each `source` and `destination` is automatically prefixed with +the `basePath` unless you add `basePath: false` to the redirect: + +```js +module.exports = { + basePath: "/docs", + + async redirects() { + return [ + { + source: "/with-basePath", // automatically becomes /docs/with-basePath + destination: "/another", // automatically becomes /docs/another + permanent: false, + }, + { + // does not add /docs since basePath: false is set + source: "/without-basePath", + destination: "/another", + basePath: false, + permanent: false, + }, + ] + }, +} +``` + +#### Redirects with i18n support + +When leveraging [`i18n` support](./i18n-routing) with redirects each +`source` and `destination` is automatically prefixed to handle the +configured `locales` unless you add `locale: false` to the redirect. If +`locale: false` is used you must prefix the `source` and `destination` +with a locale for it to be matched correctly. + +```js +module.exports = { + i18n: { + locales: ["en", "fr", "de"], + defaultLocale: "en", + }, + + async redirects() { + return [ + { + source: "/with-locale", // automatically handles all locales + destination: "/another", // automatically passes the locale on + permanent: false, + }, + { + // does not handle locales automatically since locale: false is set + source: "/nl/with-locale-manual", + destination: "/nl/another", + locale: false, + permanent: false, + }, + { + // this matches '/' since `en` is the defaultLocale + source: "/en", + destination: "/en/another", + locale: false, + permanent: false, + }, + { + // this gets converted to /(en|fr|de)/(.*) so will not match the top-level + // `/` or `/fr` routes like /:path* would + source: "/(.*)", + destination: "/another", + permanent: false, + }, + ] + }, +} +``` + +In some rare cases, you might need to assign a custom status code for +older HTTP Clients to properly redirect. In these cases, you can use the +`statusCode` property instead of the `permanent` property, but not both. +Note: to ensure IE11 compatibility a `Refresh` header is automatically +added for the 308 status code. + +### Other Redirects {#other} + +- Inside [API Routes](./api-routes), you can use `res.redirect()`. diff --git a/app/pages/docs/rewrites.mdx b/app/pages/docs/rewrites.mdx new file mode 100644 index 0000000..07726f9 --- /dev/null +++ b/app/pages/docs/rewrites.mdx @@ -0,0 +1,400 @@ +--- +title: Rewrites +sidebar_label: Rewrites +--- + +Rewrites allow you to map an incoming request path to a different +destination path. + +Rewrites are only available on the Node.js environment and do not affect +client-side routing. + +To use rewrites you can use the `rewrites` key in `blitz.config.js`: + +```js +module.exports = { + async rewrites() { + return [ + { + source: "/about", + destination: "/", + }, + ] + }, +} +``` + +`rewrites` is an async function that expects an array to be returned +holding objects with `source` and `destination` properties: + +- `source`: `String` - is the incoming request path pattern. +- `destination`: `String` is the path you want to route to. +- `basePath`: `false` or `undefined` - if false the basePath won't be + included when matching, can be used for external rewrites only. +- `locale`: `false` or `undefined` - whether the locale should not be + included when matching. +- `has` is an array of [has objects](#header-cookie-and-query-matching) + with the `type`, `key` and `value` properties. + +Rewrites are applied after checking the filesystem (pages and `/public` +files) and before dynamic routes by default. + +```js +module.exports = { + async rewrites() { + return { + beforeFiles: [ + // These rewrites are checked after headers/redirects + // and before pages/public files which allows overriding + // page files + { + source: "/some-page", + destination: "/somewhere-else", + has: [{type: "query", key: "overrideMe"}], + }, + ], + afterFiles: [ + // These rewrites are checked after pages/public files + // are checked but before dynamic routes + { + source: "/non-existent", + destination: "/somewhere-else", + }, + ], + fallback: [ + // These rewrites are checked after both pages/public files + // and dynamic routes are checked + { + source: "/:path*", + destination: "https://my-old-site.com", + }, + ], + } + }, +} +``` + +## Rewrite parameters {#parameters} + +When using parameters in a rewrite the parameters will be passed in the +query by default when none of the parameters are used in the +`destination`. + +```js +module.exports = { + async rewrites() { + return [ + { + source: "/old-about/:path*", + destination: "/about", // The :path parameter isn't used here so will be automatically passed in the query + }, + ] + }, +} +``` + +If a parameter is used in the destination none of the parameters will be +automatically passed in the query. + +```js +module.exports = { + async rewrites() { + return [ + { + source: "/docs/:path*", + destination: "/:path*", // The :path parameter is used here so will not be automatically passed in the query + }, + ] + }, +} +``` + +You can still pass the parameters manually in the query if one is already +used in the destination by specifying the query in the `destination`. + +```js +module.exports = { + async rewrites() { + return [ + { + source: "/:first/:second", + destination: "/:first?second=:second", + // Since the :first parameter is used in the destination the :second parameter + // will not automatically be added in the query although we can manually add it + // as shown above + }, + ] + }, +} +``` + +## Path Matching {#path-matching} + +Path matches are allowed, for example `/blog/:slug` will match +`/blog/hello-world` (no nested paths): + +```js +module.exports = { + async rewrites() { + return [ + { + source: "/blog/:slug", + destination: "/news/:slug", // Matched parameters can be used in the destination + }, + ] + }, +} +``` + +### Wildcard Path Matching {#wildcard} + +To match a wildcard path you can use `*` after a parameter, for example +`/blog/:slug*` will match `/blog/a/b/c/d/hello-world`: + +```js +module.exports = { + async rewrites() { + return [ + { + source: "/blog/:slug*", + destination: "/news/:slug*", // Matched parameters can be used in the destination + }, + ] + }, +} +``` + +### Regex Path Matching {#regex} + +To match a regex path you can wrap the regex in parenthesis after a +parameter, for example `/blog/:slug(\\d{1,})` will match `/blog/123` but +not `/blog/abc`: + +```js +module.exports = { + async rewrites() { + return [ + { + source: "/old-blog/:post(\\d{1,})", + destination: "/blog/:post", // Matched parameters can be used in the destination + }, + ] + }, +} +``` + +The following characters `(`, `)`, `{`, `}`, `:`, `*`, `+`, `?` are used +for regex path matching, so when used in the `source` as non-special +values they must be escaped by adding `\\` before them: + +```js +module.exports = { + async redirects() { + return [ + { + // this will match `/english(default)/something` being requested + source: "/english\\(default\\)/:slug", + destination: "/en-us/:slug", + permanent: false, + }, + ] + }, +} +``` + +## Header, Cookie, and Query Matching {#header-cookie-matching} + +To only match a rewrite when header, cookie, or query values also match +the `has` field can be used. Both the `source` and all `has` items must +match for the rewrite to be applied. + +`has` items have the following fields: + +- `type`: `String` - must be either `header`, `cookie`, `host`, or + `query`. +- `key`: `String` - the key from the selected type to match against. +- `value`: `String` or `undefined` - the value to check for, if undefined + any value will match. A regex like string can be used to capture a + specific part of the value, e.g. if the value `first-(?.*)` + is used for `first-second` then `second` will be usable in the + destination with `:paramName`. + +```js +module.exports = { + async rewrites() { + return [ + // if the header `x-rewrite-me` is present, + // this rewrite will be applied + { + source: "/:path*", + has: [ + { + type: "header", + key: "x-rewrite-me", + }, + ], + destination: "/another-page", + }, + // if the source, query, and cookie are matched, + // this rewrite will be applied + { + source: "/specific/:path*", + has: [ + { + type: "query", + key: "page", + // the page value will not be available in the + // destination since value is provided and doesn't + // use a named capture group e.g. (?home) + value: "home", + }, + { + type: "cookie", + key: "authorized", + value: "true", + }, + ], + destination: "/:path*/home", + }, + // if the header `x-authorized` is present and + // contains a matching value, this rewrite will be applied + { + source: "/:path*", + has: [ + { + type: "header", + key: "x-authorized", + value: "(?yes|true)", + }, + ], + destination: "/home?authorized=:authorized", + }, + // if the host is `example.com`, + // this rewrite will be applied + { + source: "/:path*", + has: [ + { + type: "host", + value: "example.com", + }, + ], + destination: "/another-page", + }, + ] + }, +} +``` + +## Rewriting to an external URL {#external} + +Rewrites allow you to rewrite to an external url. This is especially +useful for incrementally adopting Blitz.js + +```js +module.exports = { + async rewrites() { + return [ + { + source: "/blog/:slug", + destination: "https://example.com/blog/:slug", // Matched parameters can be used in the destination + }, + ] + }, +} +``` + +### Incremental adoption of Blitz.js {#incremental} + +You can also have Blitz.js fall back to proxying to an existing website +after checking all Blitz.js routes. + +This way you don't have to change the rewrites configuration when +migrating more pages to Blitz.js + +```js +module.exports = { + async rewrites() { + return { + fallback: [ + { + source: "/:path*", + destination: `https://custom-routes-proxying-endpoint.vercel.app/:path*`, + }, + ], + } + }, +} +``` + +### Rewrites with basePath support {#basepath} + +When leveraging [`basePath` support](./blitz-config#base-path) with +rewrites each `source` and `destination` is automatically prefixed with +the `basePath` unless you add `basePath: false` to the rewrite: + +```js +module.exports = { + basePath: "/docs", + + async rewrites() { + return [ + { + source: "/with-basePath", // automatically becomes /docs/with-basePath + destination: "/another", // automatically becomes /docs/another + }, + { + // does not add /docs to /without-basePath since basePath: false is set + // Note: this can not be used for internal rewrites e.g. `destination: '/another'` + source: "/without-basePath", + destination: "https://example.com", + basePath: false, + }, + ] + }, +} +``` + +### Rewrites with i18n support {#18n} + +When leveraging [`i18n` support](./i18n-routing) with rewrites each +`source` and `destination` is automatically prefixed to handle the +configured `locales` unless you add `locale: false` to the rewrite. If +`locale: false` is used you must prefix the `source` and `destination` +with a locale for it to be matched correctly. + +```js +module.exports = { + i18n: { + locales: ["en", "fr", "de"], + defaultLocale: "en", + }, + + async rewrites() { + return [ + { + source: "/with-locale", // automatically handles all locales + destination: "/another", // automatically passes the locale on + }, + { + // does not handle locales automatically since locale: false is set + source: "/nl/with-locale-manual", + destination: "/nl/another", + locale: false, + }, + { + // this matches '/' since `en` is the defaultLocale + source: "/en", + destination: "/en/another", + locale: false, + }, + { + // this gets converted to /(en|fr|de)/(.*) so will not match the top-level + // `/` or `/fr` routes like /:path* would + source: "/(.*)", + destination: "/another", + }, + ] + }, +} +``` From 072cb16a202efde536ffa57d56be6350a627f115 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Thu, 29 Apr 2021 18:18:05 -0400 Subject: [PATCH 25/77] another update --- app/pages/docs/blitz-config.mdx | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/pages/docs/blitz-config.mdx b/app/pages/docs/blitz-config.mdx index b1dc657..0c74d16 100644 --- a/app/pages/docs/blitz-config.mdx +++ b/app/pages/docs/blitz-config.mdx @@ -380,19 +380,18 @@ module.exports = { } ``` -### React Mode {#react-mode} +### React Root Mode {#react-mode} By default Blitz uses [React Concurrent Mode](https://reactjs.org/docs/concurrent-mode-intro.html). -You can disable it by changing `experimental.reactMode` to `legacy`. +You can disable it by changing `experimental.reactRoot` to `false`. -- Default: `concurrent` -- Options: `concurrent` | `legacy` +- Default: `true` ```js module.exports = { experimental: { - reactMode: "legacy", + reactRoot: false, }, } ``` From a383c864e95fd17cc97fa81682ec122329928c7e Mon Sep 17 00:00:00 2001 From: JuanM04 Date: Thu, 29 Apr 2021 19:22:53 -0300 Subject: [PATCH 26/77] Changed Prettier config to match new app config --- .prettierrc | 4 +- app/pages/docs/api-routes.mdx | 24 ++++----- app/pages/docs/app-component.mdx | 2 +- app/pages/docs/auth-utils.mdx | 28 +++++----- app/pages/docs/authorization.mdx | 27 +++++----- .../background-processing-with-quirrel.mdx | 30 +++++------ app/pages/docs/blitz-config.mdx | 24 +++++---- app/pages/docs/code-splitting.mdx | 14 ++--- app/pages/docs/css.mdx | 2 +- app/pages/docs/custom-server.mdx | 12 ++--- app/pages/docs/database-seeds.mdx | 2 +- app/pages/docs/document-component.mdx | 2 +- app/pages/docs/error-handling.mdx | 20 ++++--- app/pages/docs/error-pages.mdx | 12 ++--- app/pages/docs/get-server-side-props.mdx | 2 +- app/pages/docs/get-static-paths.mdx | 2 +- app/pages/docs/get-static-props.mdx | 10 ++-- app/pages/docs/head-component.mdx | 4 +- app/pages/docs/i18n-routing.mdx | 16 +++--- app/pages/docs/image-optimization.mdx | 8 +-- app/pages/docs/impersonation.mdx | 20 +++---- app/pages/docs/link.mdx | 14 ++--- app/pages/docs/measuring-performance.mdx | 6 +-- app/pages/docs/middleware.mdx | 18 +++---- app/pages/docs/multitenancy.mdx | 44 +++++++-------- app/pages/docs/mutation-resolvers.mdx | 6 +-- app/pages/docs/mutation-usage.mdx | 28 +++++----- app/pages/docs/passportjs.mdx | 38 ++++++------- app/pages/docs/preview-mode.mdx | 8 +-- app/pages/docs/prisma.mdx | 4 +- app/pages/docs/query-resolvers.mdx | 6 +-- app/pages/docs/query-usage.mdx | 26 ++++----- app/pages/docs/redirects.mdx | 8 +-- app/pages/docs/resolver-client-utilities.mdx | 34 +++++++----- app/pages/docs/resolver-server-utilities.mdx | 33 ++++++------ app/pages/docs/route-params-query.mdx | 14 ++--- app/pages/docs/router.mdx | 42 +++++++-------- app/pages/docs/routing.mdx | 14 ++--- app/pages/docs/session-management.mdx | 54 +++++++++---------- app/pages/docs/shallow-routing.mdx | 8 +-- app/pages/docs/stickers.mdx | 2 +- app/pages/docs/tutorial.mdx | 23 ++++---- app/pages/docs/use-infinite-query.mdx | 28 +++++----- app/pages/docs/use-paginated-query.mdx | 18 +++---- app/pages/docs/use-query.mdx | 6 +-- app/pages/docs/webpack-config.mdx | 2 +- app/pages/docs/writing-recipes.mdx | 28 +++++----- 47 files changed, 408 insertions(+), 369 deletions(-) diff --git a/.prettierrc b/.prettierrc index 77b066d..abe4813 100644 --- a/.prettierrc +++ b/.prettierrc @@ -8,7 +8,9 @@ "files": "*.mdx", "options": { "printWidth": 74, - "proseWrap": "always" + "proseWrap": "always", + "bracketSpacing": true, + "trailingComma": "es5" } } ] diff --git a/app/pages/docs/api-routes.mdx b/app/pages/docs/api-routes.mdx index 83573a2..ff15244 100644 --- a/app/pages/docs/api-routes.mdx +++ b/app/pages/docs/api-routes.mdx @@ -22,7 +22,7 @@ response: const handler = (req: BlitzApiRequest, res: BlitzApiResponse) => { res.statusCode = 200 res.setHeader("Content-Type", "application/json") - res.end(JSON.stringify({name: "John Doe"})) + res.end(JSON.stringify({ name: "John Doe" })) } export default handler ``` @@ -44,7 +44,7 @@ If you want to avoid writting the types `BlitzApiRequest` and const handler: BlitzApiHandler = (req, res) => { res.statusCode = 200 res.setHeader("Content-Type", "application/json") - res.end(JSON.stringify({name: "John Doe"})) + res.end(JSON.stringify({ name: "John Doe" })) } export default handler ``` @@ -81,25 +81,25 @@ You can use the `getSession` function to get the session of the user. Here is an example using session in a API route `app/api/customRoute.tsx`: ```ts -import {getSession, BlitzApiRequest, BlitzApiResponse} from "blitz" +import { getSession, BlitzApiRequest, BlitzApiResponse } from "blitz" export default async function customRoute( req: BlitzApiRequest, - res: BlitzApiResponse, + res: BlitzApiResponse ) { const session = await getSession(req, res) console.log("User ID:", session.userId) res.statusCode = 200 res.setHeader("Content-Type", "application/json") - res.end(JSON.stringify({userId: session.userId})) + res.end(JSON.stringify({ userId: session.userId })) } ``` This is called in the frontend like this: ```ts -import {getAntiCSRFToken} from "blitz" +import { getAntiCSRFToken } from "blitz" const antiCSRFToken = getAntiCSRFToken() const response = await window.fetch("/api/customRoute", { @@ -121,7 +121,7 @@ For example, the API route `app/api/post/[pid].js` has the following code: ```ts const handler: BlitzApiHandler = (req, res) => { const { - query: {pid}, + query: { pid }, } = req res.end(`Post: ${pid}`) @@ -165,14 +165,14 @@ example) to the api handler, and it will always be an array, so, the path `/api/post/a` will have the following `query` object: ```json -{"slug": ["a"]} +{ "slug": ["a"] } ``` And in the case of `/api/post/a/b`, and any other matching path, new parameters will be added to the array, like so: ```json -{"slug": ["a", "b"]} +{ "slug": ["a", "b"] } ``` An API route for `app/api/post/[...slug].js` could look like this: @@ -180,7 +180,7 @@ An API route for `app/api/post/[...slug].js` could look like this: ```ts const handler: BlitzApiHandler = (req, res) => { const { - query: {slug}, + query: { slug }, } = req res.end(`Post: ${slug.join(", ")}`) @@ -226,7 +226,7 @@ endpoints, take a look at the following example: ```ts const handler: BlitzApiHandler = (req, res) => { - res.status(200).json({name: "Blitz.js"}) + res.status(200).json({ name: "Blitz.js" }) } export default handler ``` @@ -355,7 +355,7 @@ async function handler(req: BlitzApiRequest, res: BlitzApiResponse) { await runMiddleware(req, res, cors) // Rest of the API logic - res.json({message: "Hello Everyone!"}) + res.json({ message: "Hello Everyone!" }) } export default handler diff --git a/app/pages/docs/app-component.mdx b/app/pages/docs/app-component.mdx index 4539675..8e9a36e 100644 --- a/app/pages/docs/app-component.mdx +++ b/app/pages/docs/app-component.mdx @@ -16,7 +16,7 @@ The default `_app.tsx` file looks like this: ```tsx // app/pages/_app.tsx -export default function App({Component, pageProps}) { +export default function App({ Component, pageProps }) { return } ``` diff --git a/app/pages/docs/auth-utils.mdx b/app/pages/docs/auth-utils.mdx index 3c3780b..a88abb8 100644 --- a/app/pages/docs/auth-utils.mdx +++ b/app/pages/docs/auth-utils.mdx @@ -10,7 +10,7 @@ sidebar_label: Hooks & Utilities ### Example {#example} ```ts -import {useSession} from "blitz" +import { useSession } from "blitz" const session = useSession() ``` @@ -36,7 +36,7 @@ This will throw `AuthenticationError` if the user is not logged in ### Example {#example-1} ```ts -import {useAuthenticatedSession} from "blitz" +import { useAuthenticatedSession } from "blitz" const session = useAuthenticatedSession() ``` @@ -62,7 +62,7 @@ This will throw `AuthenticationError` if the user is not logged in ### Example {#example-2} ```ts -import {useAuthorize} from "blitz" +import { useAuthorize } from "blitz" useAuthorize() ``` @@ -85,7 +85,7 @@ for logged out users. ### Example {#example-3} ```ts -import {useRedirectAuthenticated} from "blitz" +import { useRedirectAuthenticated } from "blitz" useRedirectAuthenticated("/dashboard") ``` @@ -111,7 +111,7 @@ like password resets. #### Example Usage ```ts -import {generateToken} from "blitz" +import { generateToken } from "blitz" const token = generateToken() ``` @@ -128,7 +128,7 @@ tokens before saving them in the database. #### Example Usage ```ts -import {hash256} from "blitz" +import { hash256 } from "blitz" const hashedToken = hash256(token) ``` @@ -140,7 +140,7 @@ const hashedToken = hash256(token) a nice way to hash passwords and verify password hashes. ```ts -import {SecurePassword} from "blitz" +import { SecurePassword } from "blitz" await SecurePassword.hash(password) await SecurePassword.verify(passwordHash, password) @@ -180,31 +180,31 @@ Size of the `hash` Buffer returned by `hash` and `hashSync` and used by #### Example Usage ```ts -import {SecurePassword, AuthenticationError} from "blitz" +import { SecurePassword, AuthenticationError } from "blitz" import db from "db" export const authenticateUser = async ( email: string, - password: string, + password: string ) => { - const user = await db.user.findFirst({where: {email}}) + const user = await db.user.findFirst({ where: { email } }) if (!user) throw new AuthenticationError() const result = await SecurePassword.verify( user.hashedPassword, - password, + password ) if (result === SecurePassword.VALID_NEEDS_REHASH) { // Upgrade hashed password with a more secure hash const improvedHash = await SecurePassword.hash(password) await db.user.update({ - where: {id: user.id}, - data: {hashedPassword: improvedHash}, + where: { id: user.id }, + data: { hashedPassword: improvedHash }, }) } - const {hashedPassword, ...rest} = user + const { hashedPassword, ...rest } = user return rest } ``` diff --git a/app/pages/docs/authorization.mdx b/app/pages/docs/authorization.mdx index 3e3c562..b9fe196 100644 --- a/app/pages/docs/authorization.mdx +++ b/app/pages/docs/authorization.mdx @@ -78,7 +78,7 @@ which we include in all our code generation templates. Without this, users may be able to access data or perform actions that are forbidden. ```ts -import {resolver} from "blitz" +import { resolver } from "blitz" import db from "db" import * as z from "zod" @@ -97,9 +97,9 @@ export default resolver.pipe( resolver.authorize(), async (input, ctx) => { // TODO: in multi-tenant app, you must add validation to ensure correct tenant - const projects = await db.projects.create({data: input}) + const projects = await db.projects.create({ data: input }) return projects - }, + } ) ``` @@ -221,7 +221,7 @@ on first load. You can fix that by setting [`Page.suppressFirstRenderFlicker = true`](./pages##automatic-static-optimization) ```tsx -import {useSession} from "blitz" +import { useSession } from "blitz" const session = useSession() @@ -238,7 +238,7 @@ New Blitz apps by default have a `useCurrentUser()` hook and a corresponding `getCurrentUser` query. ```tsx -import {useCurrentUser} from "app/hooks/useCurrentUser" +import { useCurrentUser } from "app/hooks/useCurrentUser" const user = useCurrentUser() @@ -265,15 +265,15 @@ Always returns a boolean indicating if user is authorized commonly use to secure your queries and mutations. ```ts -import {Ctx} from "blitz" -import {GetUserInput} from "./somewhere" +import { Ctx } from "blitz" +import { GetUserInput } from "./somewhere" -export default async function getUser({where}: GetUserInput, ctx: Ctx) { +export default async function getUser({ where }: GetUserInput, ctx: Ctx) { // highlight-start ctx.session.$authorize("admin") // highlight-end - return await db.user.findOne({where}) + return await db.user.findOne({ where }) } ``` @@ -286,7 +286,7 @@ set up by default in new apps). ```js // blitz.config.js -const {sessionMiddleware, simpleRolesIsAuthorized} = require("blitz") +const { sessionMiddleware, simpleRolesIsAuthorized } = require("blitz") module.exports = { middleware: [ @@ -302,7 +302,7 @@ module.exports = { And if using Typescript, set the type in `types.ts` like this: ```ts -import {SimpleRolesIsAuthorized} from "blitz" +import { SimpleRolesIsAuthorized } from "blitz" type Role = "ADMIN" | "USER" @@ -354,7 +354,10 @@ type CustomIsAuthorizedArgs = { ctx: any args: [/* args that you want for session.$authorize(...args) */] } -export function customIsAuthorized({ctx, args}: CustomIsAuthorizedArgs) { +export function customIsAuthorized({ + ctx, + args, +}: CustomIsAuthorizedArgs) { // can access ctx.session, ctx.session.userId, etc } ``` diff --git a/app/pages/docs/background-processing-with-quirrel.mdx b/app/pages/docs/background-processing-with-quirrel.mdx index 7b4bd08..4a84534 100644 --- a/app/pages/docs/background-processing-with-quirrel.mdx +++ b/app/pages/docs/background-processing-with-quirrel.mdx @@ -57,7 +57,7 @@ First, you define your ```ts // app/api/booking-reminder import db from "db" -import {Queue} from "quirrel/blitz" +import { Queue } from "quirrel/blitz" import sms from "some-sms-provider" // it's important to export it as default @@ -65,15 +65,15 @@ export default Queue( "api/booking-reminder", // 👈 the route that it's reachable on async (bookingId: number) => { const booking = await db.booking.findUnique({ - where: {id: bookingId}, - include: {user: true, event: true}, + where: { id: bookingId }, + include: { user: true, event: true }, }) await sms.send({ to: booking.user.phoneNumber, content: `Put on your dancing shoes for ${booking.event.title} 🕺`, }) - }, + } ) ``` @@ -137,7 +137,7 @@ the perfect fit. ```ts // app/api/monthly-invoice import db from "db" -import {CronJob} from "quirrel/blitz" +import { CronJob } from "quirrel/blitz" import stripe from "stripe" export default CronJob( @@ -148,9 +148,9 @@ export default CronJob( await Promise.all( customers.map(async (customer) => { await stripe.finalizeInvoice(customer.stripeId) - }), + }) ) - }, + } ) ``` @@ -161,8 +161,8 @@ Again, [`CronJob`](https://docs.quirrel.dev/api/cronjob) is a great fit. ```ts // app/api/remove-old-data import db from "db" -import {CronJob} from "quirrel/blitz" -import {subDays} from "date-fns" +import { CronJob } from "quirrel/blitz" +import { subDays } from "date-fns" export default CronJob( "api/remove-old-data", // 👈 the route that it's reachable on @@ -178,7 +178,7 @@ export default CronJob( }, }, }) - }, + } ) ``` @@ -204,7 +204,7 @@ import csvProcessingQueue from "app/api/process-csv" export default async function uploadCsvForProcessing(data: string) { const record = await db.uploadedCsv.create({ - data: {data}, + data: { data }, }) await csvProcessingQueue.enqueue(record.id) @@ -221,16 +221,16 @@ set it to true). ```ts // app/api/process-csv import db from "db" -import {Queue} from "quirrel/blitz" +import { Queue } from "quirrel/blitz" export default Queue("api/process-csv", async (uploadId: number) => { const upload = await db.uplodadedCsv.findUnique({ - where: {id: uploadId}, + where: { id: uploadId }, }) await doYourProcessing(upload.data) - await db.uplodadedCsv.delete({where: {id: uploadId}}) + await db.uplodadedCsv.delete({ where: { id: uploadId } }) }) ``` @@ -242,7 +242,7 @@ can look it up in your own database: import db from "db" export default async function hasFinishedProcessing(uploadId: number) { - const count = await db.uploadedCsv.count({where: {uploadId}}) + const count = await db.uploadedCsv.count({ where: { uploadId } }) return count === 0 } ``` diff --git a/app/pages/docs/blitz-config.mdx b/app/pages/docs/blitz-config.mdx index f389057..42604a8 100644 --- a/app/pages/docs/blitz-config.mdx +++ b/app/pages/docs/blitz-config.mdx @@ -20,7 +20,7 @@ module.exports = { You can also use a function: ```js -module.exports = (phase, {defaultConfig}) => { +module.exports = (phase, { defaultConfig }) => { return { /* config options here */ } @@ -33,9 +33,9 @@ can see the available phases Phases can be imported from `next/constants`: ```js -const {PHASE_DEVELOPMENT_SERVER} = require("next/constants") +const { PHASE_DEVELOPMENT_SERVER } = require("next/constants") -module.exports = (phase, {defaultConfig}) => { +module.exports = (phase, { defaultConfig }) => { if (phase === PHASE_DEVELOPMENT_SERVER) { return { /* development only config options here */ @@ -1041,16 +1041,22 @@ Original pages: module.exports = { exportPathMap: async function ( defaultPathMap, - {dev, dir, outDir, distDir, buildId}, + { dev, dir, outDir, distDir, buildId } ) { return { - "/": {page: "/"}, - "/about": {page: "/about"}, - "/p/hello-nextjs": {page: "/post", query: {title: "hello-nextjs"}}, - "/p/learn-nextjs": {page: "/post", query: {title: "learn-nextjs"}}, + "/": { page: "/" }, + "/about": { page: "/about" }, + "/p/hello-nextjs": { + page: "/post", + query: { title: "hello-nextjs" }, + }, + "/p/learn-nextjs": { + page: "/post", + query: { title: "learn-nextjs" }, + }, "/p/deploy-nextjs": { page: "/post", - query: {title: "deploy-nextjs"}, + query: { title: "deploy-nextjs" }, }, } }, diff --git a/app/pages/docs/code-splitting.mdx b/app/pages/docs/code-splitting.mdx index e5dea78..7d5f409 100644 --- a/app/pages/docs/code-splitting.mdx +++ b/app/pages/docs/code-splitting.mdx @@ -34,7 +34,7 @@ In the following example, the module `../components/hello` will be dynamically loaded by the page: ```jsx -import {dynamic} from "blitz" +import { dynamic } from "blitz" const DynamicComponent = dynamic(() => import("../components/hello")) @@ -74,10 +74,10 @@ returned by like so: ```jsx -import {dynamic} from "blitz" +import { dynamic } from "blitz" const DynamicComponent = dynamic(() => - import("../components/hello").then((mod) => mod.Hello), + import("../components/hello").then((mod) => mod.Hello) ) function Home() { @@ -99,13 +99,13 @@ An optional `loading` component can be added to render a loading state while the dynamic component is being loaded. For example: ```jsx -import {dynamic} from "blitz" +import { dynamic } from "blitz" const DynamicComponentWithCustomLoading = dynamic( () => import("../components/hello"), { loading: () =>

...

, - }, + } ) function Home() { @@ -129,13 +129,13 @@ when the module includes a library that only works in the browser. Take a look at the following example: ```jsx -import {dynamic} from "blitz" +import { dynamic } from "blitz" const DynamicComponentWithNoSSR = dynamic( () => import("../components/hello3"), { ssr: false, - }, + } ) function Home() { diff --git a/app/pages/docs/css.mdx b/app/pages/docs/css.mdx index a943398..e13fd76 100644 --- a/app/pages/docs/css.mdx +++ b/app/pages/docs/css.mdx @@ -27,7 +27,7 @@ Then, import the `styles.css` file. ```jsx import "../styles.css" -export default function App({Component, pageProps}) { +export default function App({ Component, pageProps }) { return } ``` diff --git a/app/pages/docs/custom-server.mdx b/app/pages/docs/custom-server.mdx index aaf3f14..4528a03 100644 --- a/app/pages/docs/custom-server.mdx +++ b/app/pages/docs/custom-server.mdx @@ -20,13 +20,13 @@ Here's an example custom server: ```ts // server.ts import blitz from "blitz/custom-server" -import {createServer} from "http" -import {parse} from "url" -import {log} from "@blitzjs/display" +import { createServer } from "http" +import { parse } from "url" +import { log } from "@blitzjs/display" -const {PORT = "3000"} = process.env +const { PORT = "3000" } = process.env const dev = process.env.NODE_ENV !== "production" -const app = blitz({dev}) +const app = blitz({ dev }) const handle = app.getRequestHandler() app.prepare().then(() => { @@ -34,7 +34,7 @@ app.prepare().then(() => { // Be sure to pass `true` as the second argument to `url.parse`. // This tells it to parse the query portion of the URL. const parsedUrl = parse(req.url!, true) - const {pathname} = parsedUrl + const { pathname } = parsedUrl if (pathname === "/hello") { res.writeHead(200).end("world") diff --git a/app/pages/docs/database-seeds.mdx b/app/pages/docs/database-seeds.mdx index 1b689ef..6cb9974 100644 --- a/app/pages/docs/database-seeds.mdx +++ b/app/pages/docs/database-seeds.mdx @@ -40,7 +40,7 @@ model Task { import db from "./index" const seed = async () => { - const project = await db.project.create({data: {name: "FooBar"}}) + const project = await db.project.create({ data: { name: "FooBar" } }) for (let i = 0; i < 5; i++) { await db.task.create({ diff --git a/app/pages/docs/document-component.mdx b/app/pages/docs/document-component.mdx index 22fe218..e5068e9 100644 --- a/app/pages/docs/document-component.mdx +++ b/app/pages/docs/document-component.mdx @@ -92,7 +92,7 @@ The `ctx` parameter is an object containing the following keys: It takes as argument an options object for further customization: ```jsx -import {Document} from "blitz" +import { Document } from "blitz" class MyDocument extends Document { static async getInitialProps(ctx) { diff --git a/app/pages/docs/error-handling.mdx b/app/pages/docs/error-handling.mdx index df0f071..c8453ca 100644 --- a/app/pages/docs/error-handling.mdx +++ b/app/pages/docs/error-handling.mdx @@ -30,7 +30,7 @@ curious, you can [see the source code for these](https://github.com/blitz-js/blitz/blob/canary/packages/core/src/errors.ts). ```ts -import {AuthenticationError} from "blitz" +import { AuthenticationError } from "blitz" try { throw new AuthenticationError() @@ -57,14 +57,18 @@ It looks something like this: ```tsx // app/pages/_app.tsx -import {AppProps, ErrorComponent, useQueryErrorResetBoundary} from "blitz" -import {ErrorBoundary} from "react-error-boundary" +import { + AppProps, + ErrorComponent, + useQueryErrorResetBoundary, +} from "blitz" +import { ErrorBoundary } from "react-error-boundary" import LoginForm from "app/auth/components/LoginForm" -export default function App({Component, pageProps}: AppProps) { +export default function App({ Component, pageProps }: AppProps) { // This ensures the Blitz useQuery hooks will automatically refetch // data any time you reset the error boundary - const {reset} = useQueryErrorResetBoundary() + const { reset } = useQueryErrorResetBoundary() return ( @@ -73,7 +77,7 @@ export default function App({Component, pageProps}: AppProps) { ) } -function RootErrorFallback({error, resetErrorBoundary}) { +function RootErrorFallback({ error, resetErrorBoundary }) { if (error.name === "AuthenticationError") { return } else if (error.name === "AuthorizationError") { @@ -127,7 +131,7 @@ import SuperJson from "superjson" export class UsernameTakenError extends Error { name = "UsernameTakenError" - constructor({suggestedUserName}) { + constructor({ suggestedUserName }) { super() this.suggestedUserName = suggestedUserName } @@ -136,7 +140,7 @@ export class UsernameTakenError extends Error { SuperJson.registerClass(UsernameTakenError) SuperJson.allowErrorProps("suggestedUserName") -throw new UsernameTakenError({suggestedUserName: "second_best"}) +throw new UsernameTakenError({ suggestedUserName: "second_best" }) ``` Note that you **must register it with SuperJson** as shown above in order diff --git a/app/pages/docs/error-pages.mdx b/app/pages/docs/error-pages.mdx index 15d3d81..9b9e587 100644 --- a/app/pages/docs/error-pages.mdx +++ b/app/pages/docs/error-pages.mdx @@ -34,7 +34,7 @@ component. If you wish to override it, define the file `app/pages/_error.js` and add the following code: ```jsx -function Error({statusCode}) { +function Error({ statusCode }) { return (

{statusCode @@ -44,9 +44,9 @@ function Error({statusCode}) { ) } -Error.getInitialProps = ({res, err}) => { +Error.getInitialProps = ({ res, err }) => { const statusCode = res ? res.statusCode : err ? err.statusCode : 404 - return {statusCode} + return { statusCode } } export default Error @@ -66,7 +66,7 @@ in suspense. In essence, the default configuration is: ```tsx -export default function App({Component, pageProps}: AppProps) { +export default function App({ Component, pageProps }: AppProps) { return ( {getLayout()} @@ -159,7 +159,7 @@ It accepts two props: - `title` - a string to display as the error message ```jsx -import {ErrorComponent} from "blitz" +import { ErrorComponent } from "blitz" export default function Page() { return @@ -167,7 +167,7 @@ export default function Page() { ``` ```jsx -import {ErrorComponent} from "blitz" +import { ErrorComponent } from "blitz" export default function Page() { return diff --git a/app/pages/docs/get-server-side-props.mdx b/app/pages/docs/get-server-side-props.mdx index 199c139..3fbbc59 100644 --- a/app/pages/docs/get-server-side-props.mdx +++ b/app/pages/docs/get-server-side-props.mdx @@ -134,7 +134,7 @@ fetching data on the client side. For TypeScript, you can use the `GetServerSideProps` type from `blitz`: ```ts -import {GetServerSideProps} from "blitz" +import { GetServerSideProps } from "blitz" export const getServerSideProps: GetServerSideProps = async (context) => { // ... diff --git a/app/pages/docs/get-static-paths.mdx b/app/pages/docs/get-static-paths.mdx index 1297a11..ea77fec 100644 --- a/app/pages/docs/get-static-paths.mdx +++ b/app/pages/docs/get-static-paths.mdx @@ -239,7 +239,7 @@ that use dynamic routes. For TypeScript, you can use the `GetStaticPaths` type from `blitz`: ```ts -import {GetStaticPaths} from "blitz" +import { GetStaticPaths } from "blitz" export const getStaticPaths: GetStaticPaths = async () => { // ... diff --git a/app/pages/docs/get-static-props.mdx b/app/pages/docs/get-static-props.mdx index 830227b..8304fbb 100644 --- a/app/pages/docs/get-static-props.mdx +++ b/app/pages/docs/get-static-props.mdx @@ -170,7 +170,7 @@ You should use `getStaticProps` if: For TypeScript, you can use the `GetStaticProps` type from `blitz`: ```ts -import {GetStaticProps} from "blitz" +import { GetStaticProps } from "blitz" export const getStaticProps: GetStaticProps = async (context) => { // ... @@ -181,7 +181,7 @@ If you want to get inferred typings for your props, you can use `InferGetStaticPropsType`, like this: ```tsx -import {InferGetStaticPropsType} from "blitz" +import { InferGetStaticPropsType } from "blitz" type Post = { author: string @@ -199,7 +199,7 @@ export const getStaticProps = async () => { } } -function Blog({posts}: InferGetStaticPropsType) { +function Blog({ posts }: InferGetStaticPropsType) { // will resolve posts to type Post[] } @@ -222,7 +222,7 @@ Consider our previous [`getStaticProps` example](#simple-example), but now with regeneration enabled: ```jsx -function Blog({posts}) { +function Blog({ posts }) { return (

    {posts.map((post) => ( @@ -297,7 +297,7 @@ import fs from "fs" import path from "path" // posts will be populated at build time by getStaticProps() -function Blog({posts}) { +function Blog({ posts }) { return (
      {posts.map((post) => ( diff --git a/app/pages/docs/head-component.mdx b/app/pages/docs/head-component.mdx index e82b78b..e1da3a6 100644 --- a/app/pages/docs/head-component.mdx +++ b/app/pages/docs/head-component.mdx @@ -7,7 +7,7 @@ We expose a built-in component for appending elements to the `head` of the page: ```jsx -import {Head} from "blitz" +import { Head } from "blitz" function IndexPage() { return ( @@ -32,7 +32,7 @@ which will make sure the tag is only rendered once, as in the following example: ```jsx -import {Head} from "blitz" +import { Head } from "blitz" function IndexPage() { return ( diff --git a/app/pages/docs/i18n-routing.mdx b/app/pages/docs/i18n-routing.mdx index 4af6f30..39aff5f 100644 --- a/app/pages/docs/i18n-routing.mdx +++ b/app/pages/docs/i18n-routing.mdx @@ -194,7 +194,7 @@ locale from the currently active one. If no `locale` prop is provided, the currently active `locale` is used during client-transitions. For example: ```jsx -import {Link} from "blitz" +import { Link } from "blitz" export default function IndexPage(props) { return ( @@ -209,7 +209,7 @@ When using the `Router` methods directly, you can specify the `locale` that should be used via the transition options. For example: ```jsx -import {useRouter} from "blitz" +import { useRouter } from "blitz" export default function IndexPage(props) { const router = useRouter() @@ -217,7 +217,7 @@ export default function IndexPage(props) { return (
      { - router.push("/another", "/another", {locale: "fr"}) + router.push("/another", "/another", { locale: "fr" }) }} > to /fr/another @@ -230,7 +230,7 @@ If you have a `href` that already includes the locale you can opt-out of automatically handling the locale prefixing: ```jsx -import {Link} from "blitz" +import { Link } from "blitz" export default function IndexPage(props) { return ( @@ -279,7 +279,7 @@ being pre-rendered, you can return `notFound: true` from `getStaticProps` and this variant of the page will not be generated. ```js -export async function getStaticProps({locale}) { +export async function getStaticProps({ locale }) { // Call an external API endpoint to get posts. // You can use any data fetching library const res = await fetch(`https://.../posts?locale=${locale}`) @@ -311,11 +311,11 @@ specifying which locale you want to render. For example: ```js // pages/blog/[slug].js -export const getStaticPaths = ({locales}) => { +export const getStaticPaths = ({ locales }) => { return { paths: [ - {params: {slug: "post-1"}, locale: "en-US"}, - {params: {slug: "post-1"}, locale: "fr"}, + { params: { slug: "post-1" }, locale: "en-US" }, + { params: { slug: "post-1" }, locale: "fr" }, ], fallback: true, } diff --git a/app/pages/docs/image-optimization.mdx b/app/pages/docs/image-optimization.mdx index a5ccc58..d725eaf 100644 --- a/app/pages/docs/image-optimization.mdx +++ b/app/pages/docs/image-optimization.mdx @@ -39,7 +39,7 @@ Images are always rendered in such a way as to avoid To add an image to your application, import the `Image` component: ```jsx -import {Image} from "blitz" +import { Image } from "blitz" function Home() { return ( @@ -185,7 +185,7 @@ For an example, consider a project with the following files: We can serve an optimized image like so: ```jsx -import {Image} from "blitz" +import { Image } from "blitz" function Home() { return ( @@ -270,9 +270,9 @@ A custom function used to resolve URLs. Defaults to - `quality` ```js -import {Image} from "blitz" +import { Image } from "blitz" -const myLoader = ({src, width, quality}) => { +const myLoader = ({ src, width, quality }) => { return `https://example.com/${src}?w=${width}&q=${quality || 75}` } diff --git a/app/pages/docs/impersonation.mdx b/app/pages/docs/impersonation.mdx index 4a4ae94..0d2c6e0 100644 --- a/app/pages/docs/impersonation.mdx +++ b/app/pages/docs/impersonation.mdx @@ -15,8 +15,8 @@ First, add a `impersonatingFromUserId` type to your ```ts // types.ts -import {DefaultCtx, SessionContext, DefaultPublicData} from "blitz" -import {User} from "db" +import { DefaultCtx, SessionContext, DefaultPublicData } from "blitz" +import { User } from "db" declare module "blitz" { export interface Ctx extends DefaultCtx { @@ -36,7 +36,7 @@ start the impersonation as well as stopping it. ```ts // app/auth/mutations/impersonateUser.ts -import {resolver} from "blitz" +import { resolver } from "blitz" import db from "db" import * as z from "zod" @@ -47,8 +47,8 @@ export const ImpersonateUserInput = z.object({ export default resolver.pipe( resolver.zod(ImpersonateUserInput), resolver.authorize(), - async ({userId}, ctx) => { - const user = await db.user.findFirst({where: {id: userId}}) + async ({ userId }, ctx) => { + const user = await db.user.findFirst({ where: { id: userId } }) if (!user) throw new Error("Could not find user id " + userId) await ctx.session.$create({ @@ -59,13 +59,13 @@ export default resolver.pipe( }) return user - }, + } ) ``` ```ts // app/auth/mutations/stopImpersonating.ts -import {resolver} from "blitz" +import { resolver } from "blitz" import db from "db" export default resolver.pipe(resolver.authorize(), async (_, ctx) => { @@ -76,7 +76,7 @@ export default resolver.pipe(resolver.authorize(), async (_, ctx) => { } const user = await db.user.findFirst({ - where: {id: userId}, + where: { id: userId }, }) if (!user) throw new Error("Could not find user id " + userId) @@ -94,7 +94,7 @@ export default resolver.pipe(resolver.authorize(), async (_, ctx) => { Add a form similar to this in order to switch users. ```tsx -import {useMutation, queryClient} from "blitz" +import { useMutation, queryClient } from "blitz" import impersonateUser, { ImpersonateUserInput, } from "app/auth/mutations/impersonateUser" @@ -131,7 +131,7 @@ Lastly, add the following component at the top of your Layout(s). ```tsx // app/core/components/ImpersonatingUserNotice.tsx -import {invoke, useSession, queryClient} from "blitz" +import { invoke, useSession, queryClient } from "blitz" import stopImpersonating from "app/auth/mutations/stopImpersonating" export const ImpersonatingUserNotice = () => { diff --git a/app/pages/docs/link.mdx b/app/pages/docs/link.mdx index 5344555..9cbe5e0 100644 --- a/app/pages/docs/link.mdx +++ b/app/pages/docs/link.mdx @@ -69,7 +69,7 @@ A `Link` to a dynamic route works like the other links. A link to the page `pages/post/[pid].js` will look like this: ```jsx - + First Post ``` @@ -97,7 +97,7 @@ the `` tag will not have the `href` attribute, which might hurt your site’s SEO. ```jsx -import {Link} from "blitz" +import { Link } from "blitz" import styled from "styled-components" // This creates a custom component that wraps an tag @@ -105,7 +105,7 @@ const RedLink = styled.a` color: red; ` -function NavLink({href, name}) { +function NavLink({ href, name }) { // Must add passHref to Link return ( @@ -128,11 +128,11 @@ If the child of `Link` is a function component, in addition to using [`React.forwardRef`](https://reactjs.org/docs/react-api.html#reactforwardref): ```jsx -import {Link, Routes} from "blitz" +import { Link, Routes } from "blitz" // `onClick`, `href`, and `ref` need to be passed to the DOM element // for proper handling -const MyButton = React.forwardRef(({onClick, href}, ref) => { +const MyButton = React.forwardRef(({ onClick, href }, ref) => { return ( Click Me @@ -157,12 +157,12 @@ export default Home to create the URL string. Here's how to do it: ```jsx -import {Link} from "blitz" +import { Link } from "blitz" function Home() { return ( diff --git a/app/pages/docs/measuring-performance.mdx b/app/pages/docs/measuring-performance.mdx index dc3ac1b..2c17aeb 100644 --- a/app/pages/docs/measuring-performance.mdx +++ b/app/pages/docs/measuring-performance.mdx @@ -15,7 +15,7 @@ export function reportWebVitals(metric) { console.log(metric) } -function MyApp({Component, pageProps}) { +function MyApp({ Component, pageProps }) { return } @@ -161,7 +161,7 @@ export function reportWebVitals(metric) { if (navigator.sendBeacon) { navigator.sendBeacon(url, body) } else { - fetch(url, {body, method: "POST", keepalive: true}) + fetch(url, { body, method: "POST", keepalive: true }) } } ``` @@ -172,7 +172,7 @@ export function reportWebVitals(metric) { > (to calculate percentiles, etc...). > > ```js -> export function reportWebVitals({id, name, label, value}) { +> export function reportWebVitals({ id, name, label, value }) { > ga("send", "event", { > eventCategory: > label === "web-vital" ? "Web Vitals" : "Blitz custom metric", diff --git a/app/pages/docs/middleware.mdx b/app/pages/docs/middleware.mdx index b76fe68..72a9b1d 100644 --- a/app/pages/docs/middleware.mdx +++ b/app/pages/docs/middleware.mdx @@ -43,7 +43,7 @@ project (this is included in new apps by default). ```ts // types.ts -import {DefaultCtx, SessionContext} from "blitz" +import { DefaultCtx, SessionContext } from "blitz" declare module "blitz" { export interface Ctx extends DefaultCtx { @@ -56,7 +56,7 @@ Whatever types you add to `Ctx` add will be automatically available in your queries and mutations as shown here. ```ts -import {Ctx} from "blitz" +import { Ctx } from "blitz" export default async function getThing(input, ctx: Ctx) { // Properly typed @@ -71,8 +71,8 @@ by exporting a `middleware` array from a query or mutation. ```ts // app/products/queries/getProduct.tsx -import {Middleware} from "blitz" -import db, {FindOneProjectArgs} from "db" +import { Middleware } from "blitz" +import db, { FindOneProjectArgs } from "db" type GetProjectInput = { where: FindOneProjectArgs["where"] @@ -89,11 +89,11 @@ export const middleware: Middleware[] = [ ] export default async function getProject( - {where}: GetProjectInput, - ctx: Record = {}, + { where }: GetProjectInput, + ctx: Record = {} ) { console.log("Referer:", ctx.referer) - return await db.project.findOne({where}) + return await db.project.findOne({ where }) } ``` @@ -106,7 +106,7 @@ middleware by doing `return next()` or `await next()`. See below for the `connectMiddleware()` adapter for existing connect middleware. ```js -import {Middleware} from "blitz" +import { Middleware } from "blitz" const middleware: Middleware = async (req, res, next) => { res.blitzCtx.referer = req.headers.referer @@ -213,7 +213,7 @@ middleware to Blitz middleware. ```ts // blitz.config.js -const {connectMiddleware} = require("blitz") +const { connectMiddleware } = require("blitz") const Cors = require("cors") const cors = Cors({ diff --git a/app/pages/docs/multitenancy.mdx b/app/pages/docs/multitenancy.mdx index 79bf262..8d676ce 100644 --- a/app/pages/docs/multitenancy.mdx +++ b/app/pages/docs/multitenancy.mdx @@ -180,7 +180,7 @@ When creating new entities, make sure you attach them to the current organization. Here's an example of how to do that: ```ts -import {resolver} from "blitz" +import { resolver } from "blitz" import db from "db" import * as z from "zod" @@ -202,7 +202,7 @@ export default resolver.pipe( }) return project - }, + } ) ``` @@ -217,7 +217,7 @@ entity belonging to a different organization. You could first make a fail if the organizationId doesn't match. ```ts -import {resolver} from "blitz" +import { resolver } from "blitz" import db from "db" import * as z from "zod" @@ -231,7 +231,7 @@ const UpdateProject = z export default resolver.pipe( resolver.zod(UpdateProject), resolver.authorize(), - async ({id, ...data}, ctx) => { + async ({ id, ...data }, ctx) => { const project = await db.project.update({ where: { id, @@ -242,7 +242,7 @@ export default resolver.pipe( }) return project - }, + } ) ``` @@ -252,8 +252,8 @@ You can do more advanced things like calling `ctx.session.$authorize()` inside an if/else ```ts -import {resolver} from "blitz" -import db, {GlobalRole, MembershipRole} from "db" +import { resolver } from "blitz" +import db, { GlobalRole, MembershipRole } from "db" import * as z from "zod" const UpdateProject = z @@ -268,7 +268,7 @@ export default resolver.pipe( resolver.zod(UpdateProject), // Ensure all users are logged in resolver.authorize(), - async ({id, organizationId, ...data}, ctx) => { + async ({ id, organizationId, ...data }, ctx) => { // if organizationId doesn't match current organization if (organizationId !== ctx.session.orgId) { // Require SUPERADMIN role @@ -288,7 +288,7 @@ export default resolver.pipe( }) return project - }, + } ) ``` @@ -300,7 +300,7 @@ regular users to access the organization they are currently logged in to. ```ts // app/orders/queries/getOrder.ts -import {NotFoundError, resolver} from "blitz" +import { NotFoundError, resolver } from "blitz" import db from "db" import * as z from "zod" import { @@ -323,7 +323,7 @@ export default resolver.pipe( // But now we need to enforce input.organizationId matches // session.orgId unless user is a SUPERADMIN enforceSuperAdminIfNotCurrentOrganization, //highlight-line - async ({id, organizationId}) => { + async ({ id, organizationId }) => { const order = await db.getOrder({ where: { id, @@ -333,39 +333,39 @@ export default resolver.pipe( }) if (!order) throw new NotFoundError() return order - }, + } ) ``` ```ts // app/core/utils.ts -import {Ctx} from "blitz" -import {Prisma, GloblRole} from "db" +import { Ctx } from "blitz" +import { Prisma, GloblRole } from "db" export default function assert( condition: any, - message: string, + message: string ): asserts condition { if (!condition) throw new Error(message) } export const setDefaultOrganizationId = >( input: T, - {session}: Ctx, -): T & {organizationId: Prisma.IntNullableFilter | number} => { + { session }: Ctx +): T & { organizationId: Prisma.IntNullableFilter | number } => { assert( session.orgId, - "Missing session.orgId in setDefaultOrganizationId", + "Missing session.orgId in setDefaultOrganizationId" ) if (input.organizationId) { // Pass through the input - return input as T & {organizationId: number} + return input as T & { organizationId: number } } else if (session.roles?.includes(GloblRole.SUPERADMIN)) { // Allow viewing any organization - return {...input, organizationId: {not: 0}} + return { ...input, organizationId: { not: 0 } } } else { // Set organizationId to session.orgId - return {...input, organizationId: session.orgId} + return { ...input, organizationId: session.orgId } } } @@ -373,7 +373,7 @@ export const enforceSuperAdminIfNotCurrentOrganization = < T extends Record >( input: T, - ctx: Ctx, + ctx: Ctx ): T => { assert(ctx.session.orgId, "missing session.orgId") assert(input.organizationId, "missing input.organizationId") diff --git a/app/pages/docs/mutation-resolvers.mdx b/app/pages/docs/mutation-resolvers.mdx index 827f7c3..5ab7018 100644 --- a/app/pages/docs/mutation-resolvers.mdx +++ b/app/pages/docs/mutation-resolvers.mdx @@ -34,7 +34,7 @@ fetching from third-party APIs. ```ts // app/products/mutations/createProduct.tsx -import {Ctx} from "blitz" +import { Ctx } from "blitz" import db from "db" import * as z from "zod" @@ -46,7 +46,7 @@ const CreateProject = z export default async function createProject( input: z.infer, - ctx: Ctx, + ctx: Ctx ) { // Validate input - very importnant for security const data = CreateProject.parse(input) @@ -54,7 +54,7 @@ export default async function createProject( // Require user to be logged in ctx.session.$authorize() - const project = await db.project.create({data}) + const project = await db.project.create({ data }) // Can do any processing, fetching from other APIs, etc diff --git a/app/pages/docs/mutation-usage.mdx b/app/pages/docs/mutation-usage.mdx index f1a21c6..7b58e4a 100644 --- a/app/pages/docs/mutation-usage.mdx +++ b/app/pages/docs/mutation-usage.mdx @@ -66,9 +66,9 @@ exactly like you'd expect. So you can wrap the `invoke` in passing an options object `{refetch: false}` as the second argument. ```tsx -export default function (props: {query: {id: number}}) { - const [product, {setQueryData}] = useQuery(getProduct, { - where: {id: props.query.id}, +export default function (props: { query: { id: number } }) { + const [product, { setQueryData }] = useQuery(getProduct, { + where: { id: props.query.id }, }) const [updateProjectMutation] = useMutation(updateProject) @@ -97,8 +97,8 @@ trigger a query reload. ```tsx export default function (props) { - const [product, {refetch}] = useQuery(getProduct, { - where: {id: props.id}, + const [product, { refetch }] = useQuery(getProduct, { + where: { id: props.id }, }) const [updateProjectMutation] = useMutation(updateProject) @@ -131,10 +131,10 @@ function provided by `blitz`. ##### Example ```tsx -import {invalidateQuery} from "blitz" // highlight-line +import { invalidateQuery } from "blitz" // highlight-line import getProducts from "app/products/queries/getProducts" -const Page = function ({products}) { +const Page = function ({ products }) { return (
      diff --git a/app/pages/docs/use-infinite-query.mdx b/app/pages/docs/use-infinite-query.mdx index 6efad17..abb9842 100644 --- a/app/pages/docs/use-infinite-query.mdx +++ b/app/pages/docs/use-infinite-query.mdx @@ -12,16 +12,20 @@ this case, you can `useInfiniteQuery` as shown in the following example. ### Example {#example} ```ts -import {useInfiniteQuery} from "blitz" +import { useInfiniteQuery } from "blitz" import getProjects from "app/projects/queries/getProjects" function Projects(props) { const [ projectPages, - {isFetching, isFetchingNextPage, fetchNextPage, hasNextPage}, - ] = useInfiniteQuery(getProjects, (page = {take: 3, skip: 0}) => page, { - getNextPageParam: (lastPage) => lastPage.nextPage, - }) + { isFetching, isFetchingNextPage, fetchNextPage, hasNextPage }, + ] = useInfiniteQuery( + getProjects, + (page = { take: 3, skip: 0 }) => page, + { + getNextPageParam: (lastPage) => lastPage.nextPage, + } + ) return ( <> {projectPages.map((group, i) => ( @@ -54,8 +58,8 @@ function Projects(props) { And here's the query to work with that: ```ts -import {paginate} from "blitz" -import db, {Prisma, Project} from "db" +import { paginate } from "blitz" +import db, { Prisma, Project } from "db" type GetProjectsInput = { where?: Prisma.ProjectFindManyArgs["where"] @@ -65,8 +69,8 @@ type GetProjectsInput = { } export default async function getProjects( - {where, orderBy, take, skip}: GetProjectsInput, - ctx: Record = {}, + { where, orderBy, take, skip }: GetProjectsInput, + ctx: Record = {} ) { const projects = await db.project.findMany({ where, @@ -78,12 +82,12 @@ export default async function getProjects( console.log("HTTP referer:", ctx.referer) } - const {items: projects, hasMore, nextPage, count} = await paginate({ + const { items: projects, hasMore, nextPage, count } = await paginate({ skip, take, - count: () => db.project.count({where}), + count: () => db.project.count({ where }), query: (paginateArgs) => - db.project.findMany({...paginateArgs, where, orderBy}), + db.project.findMany({ ...paginateArgs, where, orderBy }), }) return { diff --git a/app/pages/docs/use-paginated-query.mdx b/app/pages/docs/use-paginated-query.mdx index c721bc8..5f12515 100644 --- a/app/pages/docs/use-paginated-query.mdx +++ b/app/pages/docs/use-paginated-query.mdx @@ -13,7 +13,7 @@ the following example. ### Example {#example} ```ts -import {Suspense} from "react" +import { Suspense } from "react" import { Link, BlitzPage, @@ -28,20 +28,20 @@ const ITEMS_PER_PAGE = 3 const Projects = () => { const router = useRouter() - const {page = 0} = useRouterQuery() - const [{projects, hasMore}, {isPreviousData}] = usePaginatedQuery( + const { page = 0 } = useRouterQuery() + const [{ projects, hasMore }, { isPreviousData }] = usePaginatedQuery( getProjects, { skip: ITEMS_PER_PAGE * Number(page), take: ITEMS_PER_PAGE, - }, + } ) const goToPreviousPage = () => - router.push({query: {page: Number(page) - 1}}) + router.push({ query: { page: Number(page) - 1 } }) const goToNextPage = () => { if (!isPreviousData && hasMore) { - router.push({query: {page: Number(page) + 1}}) + router.push({ query: { page: Number(page) + 1 } }) } } @@ -49,7 +49,7 @@ const Projects = () => {
      {projects.map((project) => (

      - + {project.name}

      @@ -72,8 +72,8 @@ And here's the query to work with that: ```ts export default async function getProjects( - {where, orderBy, cursor, take, skip}: GetProjectsInput, - ctx: Record = {}, + { where, orderBy, cursor, take, skip }: GetProjectsInput, + ctx: Record = {} ) { const projects = await db.project.findMany({ where, diff --git a/app/pages/docs/use-query.mdx b/app/pages/docs/use-query.mdx index 5f863c8..0e287ae 100644 --- a/app/pages/docs/use-query.mdx +++ b/app/pages/docs/use-query.mdx @@ -11,15 +11,15 @@ used to display errors. If you need, you can read the [React Concurrent Mode Docs](https://reactjs.org/docs/concurrent-mode-intro.html). ```tsx -import {Suspense} from "react" -import {useQuery, useRouter, useParam} from "blitz" +import { Suspense } from "react" +import { useQuery, useRouter, useParam } from "blitz" import getProject from "app/projects/queries/getProject" import ErrorBoundary from "app/components/ErrorBoundary" function Project() { const router = useRouter() const projectId = useParam("projectId", "number") - const [project] = useQuery(getProject, {where: {id: projectId}}) + const [project] = useQuery(getProject, { where: { id: projectId } }) return
      {project.name}
      } diff --git a/app/pages/docs/webpack-config.mdx b/app/pages/docs/webpack-config.mdx index a9fef17..843ebc7 100644 --- a/app/pages/docs/webpack-config.mdx +++ b/app/pages/docs/webpack-config.mdx @@ -10,7 +10,7 @@ extends its config inside `blitz.config.js`, like so: module.exports = { webpack: ( config, - {buildId, dev, isServer, defaultLoaders, webpack}, + { buildId, dev, isServer, defaultLoaders, webpack } ) => { // Note: we provide webpack above so you should not `require` it // Perform customizations to webpack config diff --git a/app/pages/docs/writing-recipes.mdx b/app/pages/docs/writing-recipes.mdx index d0e654e..d14cc04 100644 --- a/app/pages/docs/writing-recipes.mdx +++ b/app/pages/docs/writing-recipes.mdx @@ -44,7 +44,7 @@ set that up. ```typescript // index.ts -import {RecipeBuilder} from "@blitzjs/installer" +import { RecipeBuilder } from "@blitzjs/installer" export default RecipeBuilder().build() ``` @@ -60,7 +60,7 @@ they can look for support if they need it. RecipeBuilder() .setName("My Package") .setDescription( - "A little bit of information about what exactly is being installed.", + "A little bit of information about what exactly is being installed." ) .setOwner("Fake Author ") .setRepoLink("https://github.com/fake-author/my-recipe") @@ -107,8 +107,8 @@ builder.addAddDependenciesStep({ stepName: "Add npm dependencies", explanation: `We'll install the Tailwind library itself, as well as PostCSS for removing unused styles from our production bundles.`, packages: [ - {name: "tailwindcss", version: "1"}, - {name: "postcss-preset-env", version: "latest", isDevDep: true}, + { name: "tailwindcss", version: "1" }, + { name: "postcss-preset-env", version: "latest", isDevDep: true }, ], }) ``` @@ -130,7 +130,7 @@ anywhere in your recipe's file structure, you supply the path as a part of the recipe definition. ```typescript -import {join} from "path" +import { join } from "path" builder.addNewFilesStep({ stepId: "addStyles", @@ -161,7 +161,7 @@ path is a glob pattern, the installer process will prompt the user to select a file matching the pattern. ```typescript -import {addImport, paths} from "@blitzjs/installer" +import { addImport, paths } from "@blitzjs/installer" import j from "jscodeshift" import Collection from "jscodeshift/src/Collection" @@ -173,7 +173,7 @@ builder.addTransformFilesStep({ transform(program: Collection) { const stylesImport = j.importDeclaration( [], - j.literal("app/styles/index.css"), + j.literal("app/styles/index.css") ) return addImport(program, stylesImport)! }, @@ -187,15 +187,19 @@ testing, the tests are quick to write: ```typescript import j from "jscodeshift" -import { customTsParser } from "@blitzjs/installer"; - +import { customTsParser } from "@blitzjs/installer" const sampleFile = `export default function Comp() { return
      hello!
      ; })` -expect(addImport(j(sampleFile, { - parser: customTsParser -}), newImport).toSource()).toMatchSnapshot() +expect( + addImport( + j(sampleFile, { + parser: customTsParser, + }), + newImport + ).toSource() +).toMatchSnapshot() ``` #### Modifying Non-JS files From 0275b46dd56f19c12afb3828e1e7041293198979 Mon Sep 17 00:00:00 2001 From: DawnOfMidnight <78233879+dawnofmidnight@users.noreply.github.com> Date: Fri, 30 Apr 2021 11:17:06 -0400 Subject: [PATCH 27/77] Add `scroll-behavior: smooth;` to main.css (#461) This commit is rather simple. It simply makes the scrolling when you scroll by id much smoother. For example, when you use the Back to top button in the footer, it won't jump up so quickly, it'll instead scroll. This is useful because it will surprise people less and it'll seem cleaner and less choppy too. --- app/core/styles/main.css | 1 + 1 file changed, 1 insertion(+) diff --git a/app/core/styles/main.css b/app/core/styles/main.css index 75cb599..12ffc70 100644 --- a/app/core/styles/main.css +++ b/app/core/styles/main.css @@ -11,6 +11,7 @@ html { font-family: "Libre Franklin", sans-serif; + scroll-behavior: smooth; } .player-wrapper { From 9b573d27271bd03f02ce30056d23d0ac5e16c4c4 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Tue, 4 May 2021 12:27:33 -0400 Subject: [PATCH 28/77] Update use-paginated-query.mdx --- app/pages/docs/use-paginated-query.mdx | 62 +++++++++++++------------- 1 file changed, 30 insertions(+), 32 deletions(-) diff --git a/app/pages/docs/use-paginated-query.mdx b/app/pages/docs/use-paginated-query.mdx index 5f12515..4371291 100644 --- a/app/pages/docs/use-paginated-query.mdx +++ b/app/pages/docs/use-paginated-query.mdx @@ -28,22 +28,18 @@ const ITEMS_PER_PAGE = 3 const Projects = () => { const router = useRouter() - const { page = 0 } = useRouterQuery() - const [{ projects, hasMore }, { isPreviousData }] = usePaginatedQuery( + const page = Number(router.query.page) || 0 + const [{ projects, hasMore }] = usePaginatedQuery( getProjects, { - skip: ITEMS_PER_PAGE * Number(page), + orderBy: {id: "asc"}, + skip: ITEMS_PER_PAGE * page, take: ITEMS_PER_PAGE, } ) - const goToPreviousPage = () => - router.push({ query: { page: Number(page) - 1 } }) - const goToNextPage = () => { - if (!isPreviousData && hasMore) { - router.push({ query: { page: Number(page) + 1 } }) - } - } + const goToPreviousPage = () => router.push({query: {page: page - 1}}) + const goToNextPage = () => router.push({query: {page: page + 1}}) return (
      @@ -57,10 +53,7 @@ const Projects = () => { -
      @@ -71,25 +64,30 @@ const Projects = () => { And here's the query to work with that: ```ts -export default async function getProjects( - { where, orderBy, cursor, take, skip }: GetProjectsInput, - ctx: Record = {} -) { - const projects = await db.project.findMany({ - where, - orderBy, - take, - skip, - }) - - const count = await db.project.count() - const hasMore = skip! + take! < count - - return { - projects, - hasMore, +import { paginate, resolver } from "blitz" +import db, { Prisma } from "db" + +interface GetProjectsInput + extends Pick {} + +export default resolver.pipe( + resolver.authorize(), + async ({ where, orderBy, skip = 0, take = 100 }: GetProjectsInput) => { + const { items: projects, hasMore, nextPage, count } = await paginate({ + skip, + take, + count: () => db.project.count({ where }), + query: (paginateArgs) => db.project.findMany({ ...paginateArgs, where, orderBy }), + }) + + return { + projects, + nextPage, + hasMore, + count, + } } -} +) ``` ## API {#api} From e3632e915a26a2b7f6aa28c719d11c3d94b587d3 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Thu, 6 May 2021 11:02:13 -0400 Subject: [PATCH 29/77] Update use-infinite-query.mdx --- app/pages/docs/use-infinite-query.mdx | 61 ++++++++++----------------- 1 file changed, 23 insertions(+), 38 deletions(-) diff --git a/app/pages/docs/use-infinite-query.mdx b/app/pages/docs/use-infinite-query.mdx index abb9842..065c53b 100644 --- a/app/pages/docs/use-infinite-query.mdx +++ b/app/pages/docs/use-infinite-query.mdx @@ -58,45 +58,30 @@ function Projects(props) { And here's the query to work with that: ```ts -import { paginate } from "blitz" -import db, { Prisma, Project } from "db" - -type GetProjectsInput = { - where?: Prisma.ProjectFindManyArgs["where"] - orderBy?: Prisma.ProjectFindManyArgs["orderBy"] - skip?: number - take?: number -} - -export default async function getProjects( - { where, orderBy, take, skip }: GetProjectsInput, - ctx: Record = {} -) { - const projects = await db.project.findMany({ - where, - orderBy, - take, - skip, - }) - if (ctx.referer) { - console.log("HTTP referer:", ctx.referer) - } - - const { items: projects, hasMore, nextPage, count } = await paginate({ - skip, - take, - count: () => db.project.count({ where }), - query: (paginateArgs) => - db.project.findMany({ ...paginateArgs, where, orderBy }), - }) - - return { - projects, - nextPage, - hasMore, - count, +import { paginate, resolver } from "blitz" +import db, { Prisma } from "db" + +interface GetProjectsInput + extends Pick {} + +export default resolver.pipe( + resolver.authorize(), + async ({ where, orderBy, skip = 0, take = 100 }: GetProjectsInput) => { + const { items: projects, hasMore, nextPage, count } = await paginate({ + skip, + take, + count: () => db.project.count({ where }), + query: (paginateArgs) => db.project.findMany({ ...paginateArgs, where, orderBy }), + }) + + return { + projects, + nextPage, + hasMore, + count, + } } -} +) ``` ## API {#api} From 50481880e9a0ee93ba07d4679310d166bb36cf6e Mon Sep 17 00:00:00 2001 From: Abu Uzayr Date: Thu, 6 May 2021 23:15:56 +0800 Subject: [PATCH 30/77] Create guide to deploy to Railway (#462) Co-authored-by: JuanM04 --- app/core/navs/documentation.json | 2 +- app/pages/docs/deploy-railway.mdx | 121 ++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 app/pages/docs/deploy-railway.mdx diff --git a/app/core/navs/documentation.json b/app/core/navs/documentation.json index 0979214..0fb1cc3 100644 --- a/app/core/navs/documentation.json +++ b/app/core/navs/documentation.json @@ -134,7 +134,7 @@ "iconPath": "/img/deploying-to-production.svg", "iconDarkPath": "/img/deploying-to-production-white.svg" }, - "pages": ["deploy-render", "deploy-heroku", "deploy-vercel"] + "pages": ["deploy-render", "deploy-heroku", "deploy-vercel", "deploy-railway"] }, { "title": { diff --git a/app/pages/docs/deploy-railway.mdx b/app/pages/docs/deploy-railway.mdx new file mode 100644 index 0000000..bb4674a --- /dev/null +++ b/app/pages/docs/deploy-railway.mdx @@ -0,0 +1,121 @@ +--- +title: Deploy to a Server on Railway +sidebar_label: To Railway +--- + +## If you don't have a Railway account {#signup} + +Sign up for an account on [Railway](https://railway.app) - they have a + free tier that is sufficient for small applications. + +![Screen Shot 2021-05-04 at 6 11 09 PM](https://user-images.githubusercontent.com/19371989/117007314-13ee3580-ad1c-11eb-9705-2ca9b5f545bd.png) + +## Set up a new project {#setup} + +1. Create a new project (via your + [Dashboard](https://railway.app/dashboard) or `⌘ + /` shortcut) + +![Screen Shot 2021-05-04 at 5 19 28 PM](https://user-images.githubusercontent.com/19371989/117007376-28323280-ad1c-11eb-90a5-9fa5c165f5df.png) + +2. If a database is required, select **Provision PostgreSQL** (or + MongoDB/MySQL/Redis - whichever flavour your app requires). Once the + database is provisioned, you will see the Project Setup page. + +![Screen Shot 2021-05-04 at 6 01 16 PM](https://user-images.githubusercontent.com/19371989/117007600-6deefb00-ad1c-11eb-876c-22a374c1f535.png) + +If a database is not required, select **Deploy From Repo**. + +There are two ways to set up your project on Railway: + +1. [Via the command line interface (CLI)](#cli) +2. [Via Railway's user interface (GUI)](#gui) + +### Via CLI {#cli} + +1. Install Railway + +```bash +npm i -g @railway/cli +# or +yarn global add @railway/cli +``` + +2. Login to Railway + +``` +railway login +``` + +3. Go to your project folder and link to Railway + +``` +cd /path/to/project +railway link your-project-id +``` + +The project ID is taken from the **Project Setup** page. + +4. Enter your required environment variables + +Blitz requires the `SESSION_SECRET_KEY` variable to be set. Go to your +project on the GUI, select the Variables link and enter +`SESSION_SECRET_KEY` as the name of the variables a random 32-key secret +as its value. Click **Add** to add the variable. + +Enter other environment variables that you require. The `DATABASE_URL` +variable will be automatically set by Railway if you provision a +PostgreSQL database. + +Verify that the variables are set correctly via your linked project: + +``` +railway variables +``` + +5. Deploy your project + +``` +railway up +``` + +Once the build is successful and deployment is completed, you will receive +the URL for your application that is now accessible via the internet. To +get the URL, go to the **Deployments** section in the project's dashboard +and the URL will be listed under a successful deployment. + +![Screen Shot 2021-05-04 at 8 49 57 PM](https://user-images.githubusercontent.com/19371989/117007722-8e1eba00-ad1c-11eb-9a9e-91908e4c281c.png) + +You may also view your app logs by running + +``` +railway logs +``` + +In order to set Railway to build + deploy automatically when you push to a +branch on your GitHub repository, connect your GitHub repository by +following the [GUI](#gui) steps below from Step 2 onward. + +### Via GUI {#gui} + +1. Enter your required environment variables + +Blitz requires the `SESSION_SECRET_KEY` variable to be set. Go to your +project on the GUI, select the **Variables** link and enter +`SESSION_SECRET_KEY` as the name of the variable and a random 32-key secret +as its value. Click **Add** to add the variable. + +Enter other environment variables that you require. The `DATABASE_URL` +variable will be automatically set by Railway if you provision a database. + +2. Go to the **Deployments** section. If your project is on GitHub, you + can click on **Connect GitHub** to deploy and connect directly to your + repositories on GitHub. Otherwise, you will have to use the [CLI](#cli) + to deploy your application. + +3. Select the repository and the branch to deploy from and click + **Connect + Deploy** + +![Screen Shot 2021-05-04 at 8 55 36 PM](https://user-images.githubusercontent.com/19371989/117007814-a5f63e00-ad1c-11eb-84d6-d75019930ea1.png) + +4. Railway will now build and deploy your app on every push to this branch + on your selected repository. From 30f8d9a619bdcbe03897981a018cf2abeb31bbe8 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Thu, 6 May 2021 11:25:21 -0400 Subject: [PATCH 31/77] fix tutorial --- app/pages/docs/tutorial.mdx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/pages/docs/tutorial.mdx b/app/pages/docs/tutorial.mdx index 9917824..c694040 100644 --- a/app/pages/docs/tutorial.mdx +++ b/app/pages/docs/tutorial.mdx @@ -1016,6 +1016,9 @@ export default resolver.pipe( + })), + }, + }, ++ include: { ++ choices: true, ++ }, + }) return question @@ -1029,6 +1032,12 @@ create it". This is perfect for this case because we didn't require the user to add three choices when creating the question. So if later the user adds another choice by editing the question, then it'll be created here. +## Cleanup + +In order for `yarn tsc` or `git push` to succeed, you'll need to delete +`app/choices/mutations/createChoice.ts` (unused) or update the +CreateChoice zod schema to include the required fields. + ## Conclusion {#conclusion} 🥳 Congrats! You created your very own Blitz app! Have fun playing around From 7aca5c613fb5704613528832b0041c55e972743b Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Fri, 7 May 2021 11:36:23 -0400 Subject: [PATCH 32/77] update link --- blitz.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blitz.config.js b/blitz.config.js index eb06b31..c2a9435 100644 --- a/blitz.config.js +++ b/blitz.config.js @@ -27,8 +27,8 @@ module.exports = withBundleAnalyzer({ permanent: false, }, { - source: "/meetup", - destination: "https://us02web.zoom.us/j/85901497017?pwd=MVFMUXJOQndqbDNJaU1BK2N0ZjNpQT09", + source: "/joinmeetup", + destination: "https://us02web.zoom.us/j/85901497017?pwd=eVo4YlhsU2E3UHQvUmgxTmtRUDBIZz09", permanent: false, }, ] From ed76c181601f96e923a3aca5e5baa768fc6b6988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kevin=20=C3=98sterkilde?= Date: Fri, 7 May 2021 20:15:14 +0200 Subject: [PATCH 33/77] Update done method in passportjs.mdx (#464) --- app/pages/docs/passportjs.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/pages/docs/passportjs.mdx b/app/pages/docs/passportjs.mdx index fd58d1a..50db5b5 100644 --- a/app/pages/docs/passportjs.mdx +++ b/app/pages/docs/passportjs.mdx @@ -162,7 +162,7 @@ export default passportAuth({ roles: [user.role], source: "twitter", } - done(null, { publicData }) + done(undefined, { publicData }) } ), }, @@ -200,7 +200,7 @@ app**. from your `verify` callback. ```ts -done(null, result) +done(undefined, result) ``` where `result` is an object of type `VerifyCallbackResult` @@ -245,7 +245,7 @@ should be sent after they are authenticated. They are listed here in order of priority. A URL provided with method #1 will override all other URLs. 1. Add `redirectUrl` to the `verify` callback result - - Example: `done(null, {publicData, redirectUrl: '/'})` + - Example: `done(undefined, {publicData, redirectUrl: '/'})` 2. Add a `redirectUrl` query parameter to the "initiate login" url - Example: `example.com/api/auth/twitter?redirectUrl=/dashboard` - Example: From af4fae47595156d1ad435eeba78c05a754a5a046 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Sat, 8 May 2021 15:15:14 -0400 Subject: [PATCH 34/77] Update use-infinite-query.mdx --- app/pages/docs/use-infinite-query.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/use-infinite-query.mdx b/app/pages/docs/use-infinite-query.mdx index 065c53b..ea26819 100644 --- a/app/pages/docs/use-infinite-query.mdx +++ b/app/pages/docs/use-infinite-query.mdx @@ -28,7 +28,7 @@ function Projects(props) { ) return ( <> - {projectPages.map((group, i) => ( + {projectPages.map((page, i) => ( {page.projects.map((project) => (

      {project.name}

      From bfbb00492a38c56fed7fd256b2f2399d1b3484a3 Mon Sep 17 00:00:00 2001 From: meepdeew <43303008+meepdeew@users.noreply.github.com> Date: Sun, 9 May 2021 05:42:33 -0700 Subject: [PATCH 35/77] Fix typo in tutorial.mdx (#467) --- app/pages/docs/tutorial.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/tutorial.mdx b/app/pages/docs/tutorial.mdx index c694040..a32fc3b 100644 --- a/app/pages/docs/tutorial.mdx +++ b/app/pages/docs/tutorial.mdx @@ -187,7 +187,7 @@ const Home: BlitzPage = () => { ``` Save the file and you should see the page update in your browser. You can -add customize this as much as you want. When you’re ready, move on to the +customize this as much as you want. When you’re ready, move on to the next section. ## Database setup {#database-setup} From 9ea25006e37afb59aecaaf55c59324b8fd22ef59 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Mon, 10 May 2021 15:37:34 -0400 Subject: [PATCH 36/77] fix build --- app/pages/docs/tutorial.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/pages/docs/tutorial.mdx b/app/pages/docs/tutorial.mdx index a32fc3b..384f804 100644 --- a/app/pages/docs/tutorial.mdx +++ b/app/pages/docs/tutorial.mdx @@ -187,8 +187,8 @@ const Home: BlitzPage = () => { ``` Save the file and you should see the page update in your browser. You can -customize this as much as you want. When you’re ready, move on to the -next section. +customize this as much as you want. When you’re ready, move on to the next +section. ## Database setup {#database-setup} @@ -1032,7 +1032,7 @@ create it". This is perfect for this case because we didn't require the user to add three choices when creating the question. So if later the user adds another choice by editing the question, then it'll be created here. -## Cleanup +## Cleanup {#cleanup} In order for `yarn tsc` or `git push` to succeed, you'll need to delete `app/choices/mutations/createChoice.ts` (unused) or update the From 1d9533668ae924b680248631153a07a1fc17dd41 Mon Sep 17 00:00:00 2001 From: Hardik Gaur Date: Tue, 11 May 2021 01:13:12 +0530 Subject: [PATCH 37/77] Toggling text and removing outline (#469) Co-authored-by: Brandon Bayer --- app/core/components/DarkModeToggle.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/core/components/DarkModeToggle.js b/app/core/components/DarkModeToggle.js index 42bdc22..6fe8d5f 100644 --- a/app/core/components/DarkModeToggle.js +++ b/app/core/components/DarkModeToggle.js @@ -18,7 +18,7 @@ const DarkModeToggle = ({className}) => { return ( ) From e334eb81e2e2f2c940514654f2b86c8f56270034 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Mon, 10 May 2021 16:06:39 -0400 Subject: [PATCH 38/77] Update query-usage.mdx --- app/pages/docs/query-usage.mdx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/pages/docs/query-usage.mdx b/app/pages/docs/query-usage.mdx index 6c1561a..0f87385 100644 --- a/app/pages/docs/query-usage.mdx +++ b/app/pages/docs/query-usage.mdx @@ -89,10 +89,7 @@ query when it is ready to turn on: ```tsx const [user] = useQuery(getUser, { where: { id: props.query.id } }) -const [projects] = useQuery( - getProjects, - () => ({ where: { userId: user.id } }, { enabled: user }) -) +const [projects] = useQuery(getProjects, { where: { userId: user.id } }, { enabled: user })) ``` ### Pagination {#pagination} From e6f46efd1502e8c98c137c69cf7fac4653466a5d Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Mon, 10 May 2021 16:24:30 -0400 Subject: [PATCH 39/77] add docs for setting up node.js --- app/pages/docs/get-started.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/pages/docs/get-started.mdx b/app/pages/docs/get-started.mdx index 9fbd16b..7f920d8 100644 --- a/app/pages/docs/get-started.mdx +++ b/app/pages/docs/get-started.mdx @@ -5,7 +5,11 @@ sidebar_label: Get Started ### Set Up Your Computer {#set-up-your-computer} -You need Node.js 12 or newer +You need Node.js 12 or newer. You can verify this by running `node -v` in +your terminal. If you don't have Node or need a newer version, we +recommend using a node version manager like +[fnm](https://github.com/Schniz/fnm). That will allow you to easily change +node versions and even have different versions for each project. ### Install Blitz {#install-blitz} From 7209765e8264098bfb25c8d11f2a36a29ad243bd Mon Sep 17 00:00:00 2001 From: Jeremy Liberman Date: Mon, 10 May 2021 15:38:29 -0500 Subject: [PATCH 40/77] Documentation about prefetching and dehydratedState (#465) --- app/pages/docs/get-server-side-props.mdx | 21 +++++-- app/pages/docs/get-static-props.mdx | 21 +++++-- app/pages/docs/pages.mdx | 77 ++++++++++++++++++++++-- 3 files changed, 104 insertions(+), 15 deletions(-) diff --git a/app/pages/docs/get-server-side-props.mdx b/app/pages/docs/get-server-side-props.mdx index 199c139..4e7b609 100644 --- a/app/pages/docs/get-server-side-props.mdx +++ b/app/pages/docs/get-server-side-props.mdx @@ -3,9 +3,9 @@ title: getServerSideProps API sidebar_label: getServerSideProps API --- -If you export an `async` function called `getServerSideProps` from a page, -Blitz will pre-render this page on each request using the data returned by -`getServerSideProps`. +If you export an `async` function called `getServerSideProps` from a +[page](./pages), Blitz will pre-render this page on each request using the +data returned by `getServerSideProps`. ```js export async function getServerSideProps(context) { @@ -189,9 +189,20 @@ what Blitz eliminates from the client-side bundle. #### Only allowed in a page -`getServerSideProps` can only be exported from a **page**. You can’t -export it from non-page files. +`getServerSideProps` can only be exported from a [page](./pages). You +can’t export it from non-page files. Also, you must use `export async function getServerSideProps() {}` — it will **not** work if you add `getServerSideProps` as a property of the page component. + +#### First Render UX + +Even though a page with `getServerSideProps` will be pre-rendered on the +server, it may fallback to the page's loading state if your page contains +queries that request data missing from the initial page props. This can +create a flickering effect where the contents of the page rapidly changes +when the query data gets loaded into the app. + +[Click here](./pages#first-render-ux) to discover ways you can improve the +first render User Experience (UX) of your pages. diff --git a/app/pages/docs/get-static-props.mdx b/app/pages/docs/get-static-props.mdx index 830227b..bcb70d9 100644 --- a/app/pages/docs/get-static-props.mdx +++ b/app/pages/docs/get-static-props.mdx @@ -16,9 +16,9 @@ runtime. And at build time, there is no user http request to handle. -If you export an `async` function called `getStaticProps` from a page, -Blitz will pre-render this page at build time using the props returned by -`getStaticProps`. +If you export an `async` function called `getStaticProps` from a +[page](./pages), Blitz will pre-render this page at build time using the +props returned by `getStaticProps`. ```jsx export async function getStaticProps(context) { @@ -376,8 +376,8 @@ the exported JSON is used. #### Only allowed in a page -`getStaticProps` can only be exported from a **page**. You can’t export it -from non-page files. +`getStaticProps` can only be exported from a [page](./pages). You can’t +export it from non-page files. One of the reasons for this restriction is that React needs to have all the required data before the page is rendered. @@ -391,6 +391,17 @@ component. In development (`blitz dev`), `getStaticProps` will be called on every request. +#### First Render UX + +Even though a page with `getStaticProps` will be pre-rendered on the +server, it may fallback to the page's loading state if your page contains +queries that request data missing from the initial page props. This can +create a flickering effect where the contents of the page rapidly changes +when the query data gets loaded into the app. + +[Click here](./pages#first-render-ux) to discover ways you can improve the +first render User Experience (UX) of your pages. + #### Preview Mode In some cases, you might want to temporarily bypass Static Generation and diff --git a/app/pages/docs/pages.mdx b/app/pages/docs/pages.mdx index e894cc6..364cd09 100644 --- a/app/pages/docs/pages.mdx +++ b/app/pages/docs/pages.mdx @@ -39,15 +39,26 @@ file called `app/pages/posts/[id].js`, then it will be accessible at By default, Blitz pre-renders the static HTML for every page unless you explicitly opt-in to server-side rendering. -For pages with dynamic data, the page's loading state will be -pre-rendered. - -#### First Render UX +For pages with dynamic data, the page's loading fallback state will be +rendered unless you [prefetch](./query-usage#prefetching) the data to +populate the cache. In some cases, the static optimization can cause an undesirable UX where the first render shows one thing but the second render shows another. For example this happens when using `useSession()`. +Next, we'll introduce some ways to improve the way Blitz pre-renders your +pages. + +### First Render UX {#first-render-ux} + +To provide a better User Experience (UX), Blitz tries to automatically +pre-render the HTML for your pages, but if your page contains dynamic data +fetched with [useQuery](./use-query) hooks, Blitz will fallback to the +page's loading state and you will not see much benefit from the automatic +pre-rendering, because the application will need to immediately make +another request to fetch the data it needs to satisfy the query. + In this case you can set `Page.suppressFirstRenderFlicker = true`, and Blitz will hide the first render's content. This will result in a tiny delay of first paint but will greatly improve the perceived UX. @@ -64,6 +75,62 @@ Page.suppressFirstRenderFlicker = true export default Page ``` +You can also consider prefetching all of the necessary queries that your +page needs to complete its first render. You can use either the +`getStaticProps` or `getServerSideProps` page functions, depending on what +you need. + +If you create an instance of QueryClient and populate it with query data, +then you can pass it as `dehydratedState` to your page props. Blitz will +automatically use the state to build the query cache later when the page +tries to render. + +```tsx +import { + useQuery, + getQueryKey, + invokeWithMiddleware, + dehydrate, + QueryClient, + BlitzPage, + GetServerSidePropsContext +} from 'blitz' +const Page: BlitzPage = () => { + // highlight-start + const [organization] = useQuery(getCurrentOrganization, null) + // highlight-end + + return
      You have selected: {organization.name}
      +} + +export async function getServerSideProps(ctx: GetServerSidePropsContext) { + const queryClient = new QueryClient() + + // highlight-start + const queryKey = getQueryKey(getCurrentOrganization, null) + await queryClient.prefetchQuery(queryKey, () => + invokeWithMiddleware(getCurrentOrganization, null, ctx), + ) + // highlight-end + + return { + props: { + dehydratedState: dehydrate(queryClient), + }, + } +} +``` + +In this way, the pre-rendered version of your page HTML will not have to +make a request as soon as it loads to fetch any data and will avoid any +screen flickering. This is very useful for Search Engine Optimization and +the Link Previews used by Social Media sites like Facebook and Twitter. + +You can also use prefetching to pre-populate queries that a user might +need shortly after the page loads--such a common searches or filter +criteria--by setting a [staleTime](./use-query#options) on the query being +prefetched. + ### Static Page Generation for Unauthenticated Pages {#static-page-generation-for-unauthenticated-pages} For pages accessible by anyone without authentication, we recommend using @@ -91,5 +158,5 @@ To use Server-side Rendering for a page, you need to `export` an `async` function called `getServerSideProps`. This function will be called by the server on every request. -See the [`getServerSideProps` documentation](./get-server-side-props) for +See the `getServerSideProps` [documentation](./get-server-side-props) for more details. From 1c11b918dbfcd9f1a9ddd11f77ce5ba20a98360f Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Mon, 10 May 2021 18:50:08 -0400 Subject: [PATCH 41/77] improve custom server doc --- app/pages/docs/custom-server.mdx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/pages/docs/custom-server.mdx b/app/pages/docs/custom-server.mdx index 4528a03..d47d1ed 100644 --- a/app/pages/docs/custom-server.mdx +++ b/app/pages/docs/custom-server.mdx @@ -8,8 +8,9 @@ some other direct control over the web server itself. ### How {#how} -1. Add a `server.ts` or `server.js` file in your project root. See below - for an example. +1. Add a `server.ts` or `server.js` file in your project root. Or you can + use `server/index.js` or `server/index.ts`. See below for an example + server. 2. Now `blitz dev` and `blitz start` will automatically detect and use your custom server. From d348d41d56848f3e7d1326b781584e1e55a6838f Mon Sep 17 00:00:00 2001 From: craigglennie Date: Tue, 11 May 2021 22:28:12 +1200 Subject: [PATCH 42/77] Fixes import path for useCurrentUser in authorization.mdx (#471) --- app/pages/docs/authorization.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/authorization.mdx b/app/pages/docs/authorization.mdx index b9fe196..f12393a 100644 --- a/app/pages/docs/authorization.mdx +++ b/app/pages/docs/authorization.mdx @@ -238,7 +238,7 @@ New Blitz apps by default have a `useCurrentUser()` hook and a corresponding `getCurrentUser` query. ```tsx -import { useCurrentUser } from "app/hooks/useCurrentUser" +import { useCurrentUser } from "app/core/hooks/useCurrentUser" const user = useCurrentUser() From fdaa2cfeb6dccc748c149d29164cc969200c1781 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Wed, 12 May 2021 11:52:56 -0400 Subject: [PATCH 43/77] Update session-management.mdx --- app/pages/docs/session-management.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/session-management.mdx b/app/pages/docs/session-management.mdx index b194792..2a9eeb1 100644 --- a/app/pages/docs/session-management.mdx +++ b/app/pages/docs/session-management.mdx @@ -336,7 +336,7 @@ defined above in `SessionConfig`. The functions can do anything, but they must conform to the defined input and outputs types. For reference, here's -[the default config that works with Prisma](https://github.com/blitz-js/blitz/blob/canary/packages/server/src/supertokens.ts#L62-L85). +[the default config that works with Prisma](https://github.com/blitz-js/blitz/blob/canary/packages/core/src/server/auth/sessions.ts#L65-L88). ## Manual API Requests {#manual-api-requests} From bd8bfc9d9db48e244b7e0be009cf58f991cc78ee Mon Sep 17 00:00:00 2001 From: Roshan Manuel <31125563+Roesh@users.noreply.github.com> Date: Wed, 12 May 2021 16:57:42 -0400 Subject: [PATCH 44/77] Images optimization (#474) * typo fix Small typo fix: you'll need to do the chech => you'll need to do the check * Update session.create > session.$create * Update api routes doc examples - no anon exports * Edit preview mode doc examples - no anon exports * Change export name to handler * Change export name to handler * lazy load random contributor images * lazy load appropriate player, url * switch to Image tag * fix image sizing * change user track image to github url * make layout intrinsic Co-authored-by: Roshan Manuel --- app/core/components/SponsorPack.js | 2 +- app/core/components/home/VideoPlayer.js | 3 ++- app/pages/index.js | 5 ++++- blitz.config.js | 13 +++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/app/core/components/SponsorPack.js b/app/core/components/SponsorPack.js index 9fe62de..3832735 100644 --- a/app/core/components/SponsorPack.js +++ b/app/core/components/SponsorPack.js @@ -61,7 +61,7 @@ const sponsors = [ { name: "userTrack", href: "https://www.usertrack.net/?ref=blitzjs_web", - imageUrl: "https://i.imgur.com/UDBeazC.png", + imageUrl: "https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/usertrack.png", tier: 4, cost: 100, }, diff --git a/app/core/components/home/VideoPlayer.js b/app/core/components/home/VideoPlayer.js index 9606cb2..a5e31d2 100644 --- a/app/core/components/home/VideoPlayer.js +++ b/app/core/components/home/VideoPlayer.js @@ -1,4 +1,4 @@ -import ReactPlayer from "react-player" +import ReactPlayer from "react-player/lazy" const VideoPlayer = ({url, className = ""}) => { return ( @@ -9,6 +9,7 @@ const VideoPlayer = ({url, className = ""}) => { width="100%" height="100%" controls={true} + light={true} />
      ) diff --git a/app/pages/index.js b/app/pages/index.js index 55c255b..240c1b5 100644 --- a/app/pages/index.js +++ b/app/pages/index.js @@ -224,7 +224,10 @@ const Home = ({randomContributors}) => { target="_blank" rel="noopener noreferrer" > - {contributor.name} Date: Sat, 15 May 2021 14:33:13 +0200 Subject: [PATCH 45/77] redirectAuthenticatedTo with Routes Manifest in authorization.mdx (#475) --- app/pages/docs/authorization.mdx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/pages/docs/authorization.mdx b/app/pages/docs/authorization.mdx index f12393a..0b92563 100644 --- a/app/pages/docs/authorization.mdx +++ b/app/pages/docs/authorization.mdx @@ -132,12 +132,17 @@ pages, set `Page.redirectAuthenticatedTo = '/'` to automatically redirect logged in users to another page. ```tsx +import { Routes } from "blitz" + const Page: BlitzPage = () => { return
      {/* ... */}
      } // highlight-start +// using full path Page.redirectAuthenticatedTo = "/" +// using route manifest +Page.redirectAuthenticatedTo = Routes.Home() // highlight-end export default Page From 70a4ef1de11636f6d26d6c46ccbd29b5c68fecd5 Mon Sep 17 00:00:00 2001 From: swiftgaruda <16741392+swiftgaruda@users.noreply.github.com> Date: Mon, 17 May 2021 00:43:48 +0200 Subject: [PATCH 46/77] Typo in tradeoffs.mdx (#477) --- app/pages/docs/tradeoffs.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/tradeoffs.mdx b/app/pages/docs/tradeoffs.mdx index bb71939..4f00ad5 100644 --- a/app/pages/docs/tradeoffs.mdx +++ b/app/pages/docs/tradeoffs.mdx @@ -69,7 +69,7 @@ clients. This can be an excellent choice and some folks are doing this. ## Advanced Backend Architecture {#advanced-backend-architecture} Currently Blitz is fairly minimal on backend architecture, especially -compared so something like Nest.js or AdonisJs. However, that doesn't mean +compared to something like Nest.js or AdonisJs. However, that doesn't mean you can't use those patterns in Blitz, it means you have to set it up yourself. In fact you can use Nest.js in your Blitz app if you need. From bc32f825fadc6a402d8556b98d6ffaccf8e99d4a Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Mon, 17 May 2021 14:02:13 -0400 Subject: [PATCH 47/77] Update query-usage.mdx --- app/pages/docs/query-usage.mdx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/pages/docs/query-usage.mdx b/app/pages/docs/query-usage.mdx index 0f87385..74e4efc 100644 --- a/app/pages/docs/query-usage.mdx +++ b/app/pages/docs/query-usage.mdx @@ -102,17 +102,16 @@ Use the [`useInfiniteQuery`](./use-infinite-query) hook ### Prefetching {#prefetching} -- All queries are automatically cached, so manually calling a query - function will cache its data - -Both of the following will cache the `getProject` query. +All queries are automatically cached, so both of the following will cache the `getProject` query. ```ts -const project = await getProject({ where: { id: props.id } }) +import {invoke} from 'blitz' + +const project = await invoke(getProject, { where: { id: props.id } }) ``` ```tsx - getProject({ where: { id: projectId } })}> + invoke(getProject, { where: { id: props.id } })}> View Project ``` From 5375fa0750b544423133aba9be4da879badce091 Mon Sep 17 00:00:00 2001 From: Pankaj Patil Date: Tue, 18 May 2021 02:48:28 +0530 Subject: [PATCH 48/77] Documentation Improvement: Page.authenticate implies Page.suppressFirstRenderFlicker (#476) --- app/pages/docs/pages.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/pages/docs/pages.mdx b/app/pages/docs/pages.mdx index e894cc6..710afdf 100644 --- a/app/pages/docs/pages.mdx +++ b/app/pages/docs/pages.mdx @@ -63,6 +63,10 @@ Page.suppressFirstRenderFlicker = true export default Page ``` +In case you have set `Page.authenticate = true` or `Page.redirectAuthenticatedTo = true`, +Blitz will hide the first render's content. For these cases, you can simply ignore setting +`Page.suppressFirstRenderFlicker = true`. + ### Static Page Generation for Unauthenticated Pages {#static-page-generation-for-unauthenticated-pages} From 7e1e2a7ab25c511bf875da3d0accf38524509f8d Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Mon, 17 May 2021 18:39:58 -0400 Subject: [PATCH 49/77] add cookie prefix to docs --- app/pages/docs/session-management.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/pages/docs/session-management.mdx b/app/pages/docs/session-management.mdx index b194792..a507645 100644 --- a/app/pages/docs/session-management.mdx +++ b/app/pages/docs/session-management.mdx @@ -284,6 +284,7 @@ module.exports = { middleware: [ sessionMiddleware({ // highlight-start + cookiePrefix: "my-app", sessionExpiryMinutes: 1234, isAuthorized: simpleRolesIsAuthorized, // highlight-end @@ -296,6 +297,7 @@ Available options: ```ts type SessionConfig = { + cookiePrefix?: string /* default: 'blitz' */ sessionExpiryMinutes?: number /* Default: 30 days */ sameSite?: "strict" | "lax" | "none" /* Default: 'lax' */ domain?: string /* Default: undefined. Can set as `.yourDomain.com` to work across subdomains */ From e49b76e11c08bb2a456932834a39db750401c7c3 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 19 May 2021 16:43:50 +0200 Subject: [PATCH 50/77] Document authenticate.redirectTo: RouteManifest (#479) --- app/pages/docs/authorization.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/pages/docs/authorization.mdx b/app/pages/docs/authorization.mdx index 0b92563..efe711c 100644 --- a/app/pages/docs/authorization.mdx +++ b/app/pages/docs/authorization.mdx @@ -120,6 +120,7 @@ const Page: BlitzPage = () => { // highlight-start Page.authenticate = true // or Page.authenticate = {redirectTo: '/login'} +// or Page.authenticate = {redirectTo: Routes.Login()} // highlight-end export default Page From 28e83ccf43b4f6edba48e1b458a9bdbdc97e60dc Mon Sep 17 00:00:00 2001 From: Roshan Manuel <31125563+Roesh@users.noreply.github.com> Date: Wed, 19 May 2021 10:45:11 -0400 Subject: [PATCH 51/77] Add doc page for eslint config and fix typo (#478) Co-authored-by: Roshan Manuel --- app/core/navs/documentation.json | 1 + app/pages/docs/contributing.mdx | 2 +- app/pages/docs/eslint-config.mdx | 43 ++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 app/pages/docs/eslint-config.mdx diff --git a/app/core/navs/documentation.json b/app/core/navs/documentation.json index c53c108..ae42b95 100644 --- a/app/core/navs/documentation.json +++ b/app/core/navs/documentation.json @@ -156,6 +156,7 @@ "blitz-config", "webpack-config", "postcss-config", + "eslint-config", "rpc-specification", "measuring-performance" ] diff --git a/app/pages/docs/contributing.mdx b/app/pages/docs/contributing.mdx index b85185c..56184d6 100644 --- a/app/pages/docs/contributing.mdx +++ b/app/pages/docs/contributing.mdx @@ -202,7 +202,7 @@ The typical workflow will be only run next.js integation tests related to your change. Then push to CI and see if any other intergration tests fail. If they do, then locally run the one that fails and fix the issue. -### Testing Development Version of Blitz Inside and App {#testing-development-version-of-blitz} +### Testing Development Version of Blitz Inside an App {#testing-development-version-of-blitz} diff --git a/app/pages/docs/eslint-config.mdx b/app/pages/docs/eslint-config.mdx new file mode 100644 index 0000000..53ac31c --- /dev/null +++ b/app/pages/docs/eslint-config.mdx @@ -0,0 +1,43 @@ +--- +title: Custom ESLint Config +sidebar_label: ESLint Config +--- + +Blitz extends the +[create-react-app](https://create-react-app.dev/docs/setting-up-your-editor/#experimental-extending-the-eslint-config) +eslint config. + +Our configuration contains a few modifications, and the full preset can be +found on github +[here](https://github.com/blitz-js/blitz/blob/canary/packages/eslint-config/index.js), + +This configuration is found in .eslintrc.js, and by default is + +```js +module.exports = { + extends: ["blitz"], +} +``` + +## Extending or replacing the default Blitz ESLint config {#extending} + +You can extend the base Blitz ESLint config, or replace it completely if you need. + +There are a few things to remember: + +1. We highly recommend extending the base config, as removing it could introduce hard-to-find issues. +2. It's important to note that any rules that are set to "error" will stop the project from building. + +In the below example: + + - the base config has been extended by a shared ESLint config, + - a new rule has been set that applies to all JavaScript and TypeScript files + +```js +module.exports = { + extends: ["blitz", "shared-config"], + rules: { + "additional-rule": "warn" + }, +} +``` \ No newline at end of file From e501d278247f6338ecca64c8499fee55047a863a Mon Sep 17 00:00:00 2001 From: Francesco Sardo Date: Wed, 19 May 2021 15:45:31 +0100 Subject: [PATCH 52/77] Missing import (#480) If you try to copy-paste the examples there's a missing import --- app/pages/docs/impersonation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/impersonation.mdx b/app/pages/docs/impersonation.mdx index 0d2c6e0..b491d63 100644 --- a/app/pages/docs/impersonation.mdx +++ b/app/pages/docs/impersonation.mdx @@ -98,7 +98,7 @@ import { useMutation, queryClient } from "blitz" import impersonateUser, { ImpersonateUserInput, } from "app/auth/mutations/impersonateUser" -import Form from "app/core/components/Form" +import { Form, FORM_ERROR } from "app/core/components/Form" import LabeledTextField from "app/core/components/LabeledTextField" export const ImpersonateUserForm = () => { From 5129c9696bb23a1c93ef1bb6350185431383bc3c Mon Sep 17 00:00:00 2001 From: Francesco Sardo Date: Wed, 19 May 2021 15:46:08 +0100 Subject: [PATCH 53/77] Avoid hardcoding "admin" role during impersonation (#481) When you impersonate another use it would be a good idea to assumer their role too. Most endpoints will be protected with some for of authorizer e.g. `resolver.authorize("seller")` or `resolver.authorize("buyer")`. If you try and invoke these endpoints as an admin, they all need to be changed to `resolver.authorize(["seller", "admin"])` or `resolver.authorize(["buyer", "admin"])` etc. If you assume the role of the user you're impersonating, you don't need to change anything. In terms of security: - `startImpersonating` should only be available to admins, so it should be secured with `resolver.authorize("admin")`. - we can allow `stopImpersonating` to be called without a role restriction as it is: the code already checks if `impersonatingFromUserId` is present in the session. If present, the user simply regains whatever role they had before ("admin", "support", etc), otherwise the endpoint is no-op. --- app/pages/docs/impersonation.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/impersonation.mdx b/app/pages/docs/impersonation.mdx index b491d63..3f6ed84 100644 --- a/app/pages/docs/impersonation.mdx +++ b/app/pages/docs/impersonation.mdx @@ -53,7 +53,7 @@ export default resolver.pipe( await ctx.session.$create({ userId: user.id, - role: "admin", + role: user.role, orgId: user.organizationId, impersonatingFromUserId: ctx.session.userId, }) From 03e52b734258df3db9d94f5d6564f87f2caedeb0 Mon Sep 17 00:00:00 2001 From: Antony Kamp Date: Fri, 21 May 2021 20:58:31 +0200 Subject: [PATCH 54/77] `resolver.authorize` description at resolver-server-utilities.mdx (#484) --- app/pages/docs/resolver-server-utilities.mdx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/pages/docs/resolver-server-utilities.mdx b/app/pages/docs/resolver-server-utilities.mdx index 727d71e..4766de1 100644 --- a/app/pages/docs/resolver-server-utilities.mdx +++ b/app/pages/docs/resolver-server-utilities.mdx @@ -180,6 +180,12 @@ A function to give `resolver.pipe` of type ## `resolver.authorize` {#resolver-authorize} +Using `resolver.authorize` in `resolver.pipe` is a simple way to check +whether the user has the authorization to call the query or mutation or +not. For this, blitz uses +[`session.$authorize`](./authorization#isauthorized-adapters) from the +context object. + ### Example {#example-2} From 9fe39d8ebeff642759bb10ad1b0cd2f1114ec7aa Mon Sep 17 00:00:00 2001 From: Nikolay Date: Sat, 22 May 2021 01:37:46 +0300 Subject: [PATCH 55/77] Fix theme toggle (#485) --- app/pages/_app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/_app.js b/app/pages/_app.js index 2863164..28fcaae 100644 --- a/app/pages/_app.js +++ b/app/pages/_app.js @@ -71,7 +71,7 @@ export default function App({Component, pageProps, router}) { - + From b2aab2e88bac03d30f9b0d556a20717146bd994d Mon Sep 17 00:00:00 2001 From: Roshan Manuel <31125563+Roesh@users.noreply.github.com> Date: Tue, 25 May 2021 11:31:01 -0400 Subject: [PATCH 56/77] Add doc page for prettier config (#482) Co-authored-by: Roshan Manuel --- app/core/navs/documentation.json | 1 + app/pages/docs/prettier-config.mdx | 44 ++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 app/pages/docs/prettier-config.mdx diff --git a/app/core/navs/documentation.json b/app/core/navs/documentation.json index ae42b95..658c1f3 100644 --- a/app/core/navs/documentation.json +++ b/app/core/navs/documentation.json @@ -157,6 +157,7 @@ "webpack-config", "postcss-config", "eslint-config", + "prettier-config", "rpc-specification", "measuring-performance" ] diff --git a/app/pages/docs/prettier-config.mdx b/app/pages/docs/prettier-config.mdx new file mode 100644 index 0000000..1321161 --- /dev/null +++ b/app/pages/docs/prettier-config.mdx @@ -0,0 +1,44 @@ +--- +title: Custom Prettier Config +sidebar_label: Prettier Config +--- + +[Prettier](https://prettier.io/) is an opinionated code formatter. It +enforces a consistent code style across your entire codebase. + +It re-prints the parsed AST (abstract syntax tree) with its own rules that +take the maximum line length into account, wrapping code when necessary, +etc. + +## Configuration File {#config} + +Prettier uses [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) +for configuration file support. This means you can configure Prettier via +(in order of precedence): + +- A "prettier" key in your package.json file. +- A .prettierrc file written in JSON or YAML. +- A .prettierrc.json, .prettierrc.yml, .prettierrc.yaml, or + .prettierrc.json5 file. +- A .prettierrc.js, .prettierrc.cjs, prettier.config.js, or + prettier.config.cjs file that exports an object using module.exports. +- A .prettierrc.toml file. + +The configuration file will be resolved starting from the location of the +file being formatted, and searching up the file tree until a config file +is (or isn’t) found. + +Prettier intentionally doesn’t support any kind of global configuration. +This is to make sure that when a project is copied to another computer, +Prettier’s behavior stays the same. Otherwise, Prettier wouldn’t be able +to guarantee that everybody in a team gets the same consistent results. + +The full set of configuration options, including overrides and sharing +options can be found in the +[prettier docs](https://prettier.io/docs/en/configuration.html) + +## Default Blitz config {#blitz-config} + +By default, new Blitz apps configure prettier using the "prettier" key in +the +[package.json file](https://github.com/blitz-js/blitz/blob/canary/packages/generator/templates/app/package.json) From 789b52b6aeb7549d7b1c4485f616694eb2358d1b Mon Sep 17 00:00:00 2001 From: Roshan Manuel <31125563+Roesh@users.noreply.github.com> Date: Tue, 25 May 2021 11:32:00 -0400 Subject: [PATCH 57/77] Husky doc (#487) Co-authored-by: Roshan Manuel Co-authored-by: JuanM04 Co-authored-by: Brandon Bayer --- app/core/navs/documentation.json | 1 + app/pages/docs/husky-config.mdx | 43 ++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 app/pages/docs/husky-config.mdx diff --git a/app/core/navs/documentation.json b/app/core/navs/documentation.json index 658c1f3..3d00593 100644 --- a/app/core/navs/documentation.json +++ b/app/core/navs/documentation.json @@ -157,6 +157,7 @@ "webpack-config", "postcss-config", "eslint-config", + "husky-config", "prettier-config", "rpc-specification", "measuring-performance" diff --git a/app/pages/docs/husky-config.mdx b/app/pages/docs/husky-config.mdx new file mode 100644 index 0000000..669ed98 --- /dev/null +++ b/app/pages/docs/husky-config.mdx @@ -0,0 +1,43 @@ +--- +title: Custom Husky Config +sidebar_label: Husky Config +--- + +[Husky](https://typicode.github.io/husky/#/) is a tool that helps improve +your commits. + +You can use it to lint your commit messages, run tests, lint code, and +more when you commit or push using +[Git hooks](https://git-scm.com/docs/githooks). + +For example, a `pre-commit` hook is triggered right before a commit is +created. + +## Default Blitz config {#blitz-config} + +By default, new Blitz apps install a pre-commit and pre-push hook inside +`.husky/` in the project root. You can view these hooks +[here](https://github.com/blitz-js/blitz/tree/canary/packages/generator/templates/app/.husky). + +Husky is installed after you use NPM or Yarn to install your dependencies +following this instruction in the `package.json` file: + +```json +{ + "scripts": { + "prepare": "husky install" + } +} +``` + +Note that if you use Yarn 2, Husky needs to be installed differently. Yarn +2 doesn't support the `prepare` lifecycle script. See +[Yarn 2 install](https://typicode.github.io/husky/#/?id=yarn-2). + +## Troubleshooting Husky {#troubleshooting} + +If you are having problems commiting or pushing, check out the Husky +[troubleshooting guide](https://typicode.github.io/husky/#/?id=troubleshoot). + +To optionally bypass checks, you can run +`git commit -m "message" --no-verify` or `git push --no-verify`. From a92d807fee281df7014023acfb9d3d446cc501f2 Mon Sep 17 00:00:00 2001 From: Andreas Thomas Date: Wed, 26 May 2021 12:50:22 +0200 Subject: [PATCH 58/77] Fix typo at testing.mdx (#489) --- app/pages/docs/testing.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/pages/docs/testing.mdx b/app/pages/docs/testing.mdx index d64d03b..478031a 100644 --- a/app/pages/docs/testing.mdx +++ b/app/pages/docs/testing.mdx @@ -55,8 +55,8 @@ All other files will run in the Jest client environment (with jsdom). ## @testing-library {#testing-library} -[@testing-library](https://testing-library.com/docs/) is family of -packages helps you test UI components in a user-centric way. It's a better +[@testing-library](https://testing-library.com/docs/) is a family of +packages that help you test UI components in a user-centric way. It's a better alternative to Enzyme, if you've used that in the past. The following packages are installed for you. Refer to their documentation From 208eb3097566aa851ab700f90d357e111a350a23 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Fri, 28 May 2021 15:49:37 -0400 Subject: [PATCH 59/77] update docs for nextjs 10.2.3 --- app/core/navs/documentation.json | 1 + app/pages/docs/api-routes.mdx | 4 +- app/pages/docs/font-optimization.mdx | 97 ++++++++++++++++++++++++++++ app/pages/docs/router.mdx | 3 +- 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 app/pages/docs/font-optimization.mdx diff --git a/app/core/navs/documentation.json b/app/core/navs/documentation.json index c53c108..8017be6 100644 --- a/app/core/navs/documentation.json +++ b/app/core/navs/documentation.json @@ -34,6 +34,7 @@ "app-component", "css", "image-optimization", + "font-optimization", "static-files", "environment-variables", "error-handling", diff --git a/app/pages/docs/api-routes.mdx b/app/pages/docs/api-routes.mdx index ff15244..48e8760 100644 --- a/app/pages/docs/api-routes.mdx +++ b/app/pages/docs/api-routes.mdx @@ -236,8 +236,8 @@ The included helpers are: - `res.status(code)` - A function to set the status code. `code` must be a valid [HTTP status code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) -- `res.json(json)` - Sends a JSON response. `json` must be a valid JSON - object +- `res.json(body)` - Sends a JSON response. `body` must be a valid + [serialiazable object](https://developer.mozilla.org/en-US/docs/Glossary/Serialization) - `res.send(body)` - Sends the HTTP response. `body` can be a `string`, an `object` or a `Buffer` diff --git a/app/pages/docs/font-optimization.mdx b/app/pages/docs/font-optimization.mdx new file mode 100644 index 0000000..8838da3 --- /dev/null +++ b/app/pages/docs/font-optimization.mdx @@ -0,0 +1,97 @@ +--- +title: Font Optimization +sidebar_label: Font Optimization +--- + +By default, Blitz.js will automatically inline font CSS at build time, +eliminating an extra round trip to fetch font declarations. This results +in improvements to [First Contentful Paint (FCP)](https://web.dev/fcp/) +and +[Largest Contentful Paint (LCP)](https://vercel.com/blog/core-web-vitals#largest-contentful-paint). + +For example: + +```js +// Before + + +// After + +``` + +## Usage + +To add a web font to your Blitz.js application, use ``. You can add +a font to a specific page like this: + +```js +// pages/index.js + +import { Head } from "blitz" + +export default function IndexPage() { + return ( +
      + + + +

      Hello world!

      +
      + ) +} +``` + +or to your entire application with a +[Custom `Document`](./document-component). + +```js +// pages/_document.js + +import { Document, Html, DocumentHead, Main, BlitzScript } from "blitz" + +class MyDocument extends Document { + render() { + return ( + + + + + +
      + + + + ) + } +} + +export default MyDocument +``` + +Automatic Webfont Optimization currently supports Google Fonts and Typekit +with support for other font providers coming soon. We're also planning to +add control +over [loading strategies](https://github.com/vercel/next.js/issues/21555) and `font-display` values. + +## Disabling Optimization + +If you do not want Blitz.js to optimize your fonts, you can opt-out. + +```js +// blitz.config.js + +module.exports = { + optimizeFonts: false, +} +``` diff --git a/app/pages/docs/router.mdx b/app/pages/docs/router.mdx index ab49349..5e148a0 100644 --- a/app/pages/docs/router.mdx +++ b/app/pages/docs/router.mdx @@ -51,7 +51,7 @@ Here's the definition of the `router` object returned by `useRouter` and `withRouter`: - `pathname`: `String` - Current route. That is the path of the page in - `/pages` + `/pages`, the configured `basePath` or `locale` is not included. - `query`: `Object` - All the query string parameters from the current url. Parameter type is always `string`. - `params`: `Object` - All the dynamic route parameters for the current @@ -92,6 +92,7 @@ Router.push(url, as, options) - [`shallow`](./shallow-routing): Update the path of the current page without rerunning [`getStaticProps`](./get-static-props) or [`getServerSideProps`](./get-server-side-props). Defaults to `false` +- `locale` - Optional string, indicates locale of the new page > You don't need to use `Router` for external URLs, > [window.location](https://developer.mozilla.org/en-US/docs/Web/API/Window/location) From b61ce8d9d1c53985238cc34bf603763f6117d326 Mon Sep 17 00:00:00 2001 From: Antony Kamp Date: Sat, 29 May 2021 17:08:19 +0200 Subject: [PATCH 60/77] Expanded getQueryKey and invalidateQuery at resolver-client-utilities.mdx (#492) * add some comments to getQueryKey and invalidateQuery * add link to react query docs --- app/pages/docs/resolver-client-utilities.mdx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/pages/docs/resolver-client-utilities.mdx b/app/pages/docs/resolver-client-utilities.mdx index d2a3ba8..dc92879 100644 --- a/app/pages/docs/resolver-client-utilities.mdx +++ b/app/pages/docs/resolver-client-utilities.mdx @@ -55,7 +55,9 @@ const results = await invoke(resolver, resolverInputArguments) ## `invalidateQuery` {#invalidate-query} -This allows you to invalidate a specific query. +This allows you to invalidate a specific query. Use `invalidateQuery` if +you know for sure that a query's data is stale and you don't want to wait +for the automatic refetch. ### Example {#example-1} @@ -105,7 +107,10 @@ are done being refetched. ## `getQueryKey` {#get-query-key} -This allows you to get the query key for a query +This allows you to get the query key for a query. The `queryClient` +manages query based on query keys. For a more detailed explanation, see +the [`React Query`](https://react-query.tanstack.com/guides/query-keys) +documentation. ### Example {#example-2} From 60107a2448e427500dec9fc060cac25644a48310 Mon Sep 17 00:00:00 2001 From: Antony Kamp Date: Sat, 29 May 2021 23:56:51 +0200 Subject: [PATCH 61/77] Add bilaterial reference between dynamic routing and useParam/useRouterQuery (#491) * Add usecase "dynamic routing" * Add reference to useParams, useParam and useRouterQuery * typo, move link at useParams and useParam --- app/pages/docs/route-params-query.mdx | 18 ++++++++++-------- app/pages/docs/routing.mdx | 7 +++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/app/pages/docs/route-params-query.mdx b/app/pages/docs/route-params-query.mdx index f22d80d..cdf617f 100644 --- a/app/pages/docs/route-params-query.mdx +++ b/app/pages/docs/route-params-query.mdx @@ -5,10 +5,10 @@ sidebar_label: URL Params & Query ## `useParams` {#use-params} -This hook returns all the parameters for the current route as an object. -The default parameter type is `undefined | string | string[]`, but you can -optionally provide a type argument to narrow the parameters and types that -are returned. +This hook returns all the [parameters](./routing#dynamic-route-segments) +for the current route as an object. The default parameter type is +`undefined | string | string[]`, but you can optionally provide a type +argument to narrow the parameters and types that are returned. ```tsx import { useParams } from "blitz" @@ -54,9 +54,10 @@ const params = useParams("array") ## `useParam` {#use-param} -This hook return a single parameters for the current route. The default -return type is `undefined | string | string[]`, but you can optionally -provide a type argument to cast the return type. +This hook returns a single [parameter](./routing#dynamic-route-segments) +for the current route. The default return type is +`undefined | string | string[]`, but you can optionally provide a type +argument to cast the return type. ```tsx import { useParam } from "blitz" @@ -99,7 +100,8 @@ const slug = useParam("slug", "string") ## `useRouterQuery` {#use-router-query} This hook returns all the query parameters from the URL as an object. -Parameter type is always `string`. +Using query parameters, you can pass key-value pairs via the URL with the +pattern`?key1=value1&key2=value2`. Parameter type is always `string`. ```tsx // URL: /products?sort=asc&limit=10 diff --git a/app/pages/docs/routing.mdx b/app/pages/docs/routing.mdx index 9e3144a..8949803 100644 --- a/app/pages/docs/routing.mdx +++ b/app/pages/docs/routing.mdx @@ -59,7 +59,9 @@ export default Post Any route like `/post/1`, `/post/abc`, etc. will be matched by `app/pages/post/[pid].js`. The matched path parameter will be sent as a query parameter to the page, and it will be merged with the other query -parameters. +parameters. Use [`useParams`](./route-params-query#use-params) or +[`useParam`](./route-params-query#use-param) to extract the parameter +values afterwards. For example, the route `/post/abc` will have the following `query` object: @@ -68,7 +70,8 @@ For example, the route `/post/abc` will have the following `query` object: ``` Similarly, the route `/post/abc?foo=bar` will have the following `query` -object: +object, which you can extract with +[`useRouterQuery`](./route-params-query#use-router-query): ```json { "foo": "bar", "pid": "abc" } From e8ff6aa7d9a569e566130424327ddff861f3e2c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Or=C5=82owski?= <16357457+ormarek@users.noreply.github.com> Date: Sun, 30 May 2021 02:17:21 +0200 Subject: [PATCH 62/77] Test database notes (#493) * add test database to postgres docker docs * clarified that test db must be different than main --- app/pages/docs/database-overview.mdx | 1 + app/pages/docs/postgres.mdx | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/app/pages/docs/database-overview.mdx b/app/pages/docs/database-overview.mdx index b5f670b..1c10279 100644 --- a/app/pages/docs/database-overview.mdx +++ b/app/pages/docs/database-overview.mdx @@ -66,6 +66,7 @@ datasource db { commented-out PostgreSQL `DATABASE_URL` there already. Depending on your setup, you may need to modify the URL. 3. Update `.env.test.local` as well to use PostgreSQL in your test runs. + (It has to point to different database than your `.env.local`) 4. Delete the `db/migrations` folder 5. Run `blitz prisma migrate dev`. This command will create the database (if it does not already exist) and tables based on your schema. diff --git a/app/pages/docs/postgres.mdx b/app/pages/docs/postgres.mdx index 3f2e54c..c1373f1 100644 --- a/app/pages/docs/postgres.mdx +++ b/app/pages/docs/postgres.mdx @@ -55,6 +55,12 @@ services: ports: - "5432:5432" + db-test: + image: postgres:latest + env_file: ./.env.test.local + ports: + - 5433:5432 + volumes: data: ``` @@ -71,6 +77,10 @@ POSTGRES_DB=your_database_name Given these values, update `DATABASE_URL` in `.env.local` to something similar like `postgresql://your_user:your_password@localhost:5432/your_database_name` +and in `.env.test.local` to +`postgresql://your_user:your_password@localhost:5433/your_database_name` + +Please note that test database is using port `5433` instead of `5432` 3. Modify your `package.json` to start the database before Blitz From 4033fadfdab02f9cfe5b18f3c2a88bec09478a79 Mon Sep 17 00:00:00 2001 From: Mark Hughes Date: Sat, 5 Jun 2021 05:49:05 +1000 Subject: [PATCH 63/77] feat: add documentation for customServer.hotReload (#495) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Roshan Manuel Co-authored-by: JuanM04 Co-authored-by: Brandon Bayer Co-authored-by: Roshan Manuel <31125563+Roesh@users.noreply.github.com> Co-authored-by: Francesco Sardo Co-authored-by: Antony Kamp Co-authored-by: Nikolay Co-authored-by: Andreas Thomas Co-authored-by: Marek Orłowski <16357457+ormarek@users.noreply.github.com> --- app/core/navs/documentation.json | 3 ++ app/pages/_app.js | 2 +- app/pages/docs/blitz-config.mdx | 6 +++ app/pages/docs/contributing.mdx | 2 +- app/pages/docs/custom-server.mdx | 14 +++++++ app/pages/docs/database-overview.mdx | 1 + app/pages/docs/eslint-config.mdx | 43 +++++++++++++++++++ app/pages/docs/husky-config.mdx | 43 +++++++++++++++++++ app/pages/docs/impersonation.mdx | 4 +- app/pages/docs/postgres.mdx | 10 +++++ app/pages/docs/prettier-config.mdx | 44 ++++++++++++++++++++ app/pages/docs/resolver-client-utilities.mdx | 9 +++- app/pages/docs/resolver-server-utilities.mdx | 6 +++ app/pages/docs/route-params-query.mdx | 18 ++++---- app/pages/docs/routing.mdx | 7 +++- app/pages/docs/testing.mdx | 4 +- 16 files changed, 198 insertions(+), 18 deletions(-) create mode 100644 app/pages/docs/eslint-config.mdx create mode 100644 app/pages/docs/husky-config.mdx create mode 100644 app/pages/docs/prettier-config.mdx diff --git a/app/core/navs/documentation.json b/app/core/navs/documentation.json index 8017be6..a52afb8 100644 --- a/app/core/navs/documentation.json +++ b/app/core/navs/documentation.json @@ -157,6 +157,9 @@ "blitz-config", "webpack-config", "postcss-config", + "eslint-config", + "husky-config", + "prettier-config", "rpc-specification", "measuring-performance" ] diff --git a/app/pages/_app.js b/app/pages/_app.js index 2863164..28fcaae 100644 --- a/app/pages/_app.js +++ b/app/pages/_app.js @@ -71,7 +71,7 @@ export default function App({Component, pageProps, router}) { - + diff --git a/app/pages/docs/blitz-config.mdx b/app/pages/docs/blitz-config.mdx index 2d162fb..8f9f5a8 100644 --- a/app/pages/docs/blitz-config.mdx +++ b/app/pages/docs/blitz-config.mdx @@ -360,6 +360,12 @@ module.exports = { With this option set, urls like `/about` will redirect to `/about/`. +## Custom Server {#custom-server} + +You can setup and configure some items in the blitz config regarding +custom servers. [See the custom server documentation](./custom-server) for +full details. + ## Experimental {#experimental} These features aren't ready for production and could change at any time. diff --git a/app/pages/docs/contributing.mdx b/app/pages/docs/contributing.mdx index b85185c..56184d6 100644 --- a/app/pages/docs/contributing.mdx +++ b/app/pages/docs/contributing.mdx @@ -202,7 +202,7 @@ The typical workflow will be only run next.js integation tests related to your change. Then push to CI and see if any other intergration tests fail. If they do, then locally run the one that fails and fix the issue. -### Testing Development Version of Blitz Inside and App {#testing-development-version-of-blitz} +### Testing Development Version of Blitz Inside an App {#testing-development-version-of-blitz} diff --git a/app/pages/docs/custom-server.mdx b/app/pages/docs/custom-server.mdx index d47d1ed..b62781f 100644 --- a/app/pages/docs/custom-server.mdx +++ b/app/pages/docs/custom-server.mdx @@ -100,3 +100,17 @@ module.exports = { > You may also wish to configure the client-side router to disallow > client-side redirects to filename routes; for that refer to > [`router.beforePopState`](./router#router-object). + +## Disabling hot reloading in development {#disabling-hot-reloading} + +The default value for `customServer.hotReload` is `true`. Should you need +to disable hot reloading for your custom server, you can change the value +of it to `false`. + +```js +module.exports = { + customServer: { + hotReload: false, + }, +} +``` diff --git a/app/pages/docs/database-overview.mdx b/app/pages/docs/database-overview.mdx index b5f670b..1c10279 100644 --- a/app/pages/docs/database-overview.mdx +++ b/app/pages/docs/database-overview.mdx @@ -66,6 +66,7 @@ datasource db { commented-out PostgreSQL `DATABASE_URL` there already. Depending on your setup, you may need to modify the URL. 3. Update `.env.test.local` as well to use PostgreSQL in your test runs. + (It has to point to different database than your `.env.local`) 4. Delete the `db/migrations` folder 5. Run `blitz prisma migrate dev`. This command will create the database (if it does not already exist) and tables based on your schema. diff --git a/app/pages/docs/eslint-config.mdx b/app/pages/docs/eslint-config.mdx new file mode 100644 index 0000000..53ac31c --- /dev/null +++ b/app/pages/docs/eslint-config.mdx @@ -0,0 +1,43 @@ +--- +title: Custom ESLint Config +sidebar_label: ESLint Config +--- + +Blitz extends the +[create-react-app](https://create-react-app.dev/docs/setting-up-your-editor/#experimental-extending-the-eslint-config) +eslint config. + +Our configuration contains a few modifications, and the full preset can be +found on github +[here](https://github.com/blitz-js/blitz/blob/canary/packages/eslint-config/index.js), + +This configuration is found in .eslintrc.js, and by default is + +```js +module.exports = { + extends: ["blitz"], +} +``` + +## Extending or replacing the default Blitz ESLint config {#extending} + +You can extend the base Blitz ESLint config, or replace it completely if you need. + +There are a few things to remember: + +1. We highly recommend extending the base config, as removing it could introduce hard-to-find issues. +2. It's important to note that any rules that are set to "error" will stop the project from building. + +In the below example: + + - the base config has been extended by a shared ESLint config, + - a new rule has been set that applies to all JavaScript and TypeScript files + +```js +module.exports = { + extends: ["blitz", "shared-config"], + rules: { + "additional-rule": "warn" + }, +} +``` \ No newline at end of file diff --git a/app/pages/docs/husky-config.mdx b/app/pages/docs/husky-config.mdx new file mode 100644 index 0000000..669ed98 --- /dev/null +++ b/app/pages/docs/husky-config.mdx @@ -0,0 +1,43 @@ +--- +title: Custom Husky Config +sidebar_label: Husky Config +--- + +[Husky](https://typicode.github.io/husky/#/) is a tool that helps improve +your commits. + +You can use it to lint your commit messages, run tests, lint code, and +more when you commit or push using +[Git hooks](https://git-scm.com/docs/githooks). + +For example, a `pre-commit` hook is triggered right before a commit is +created. + +## Default Blitz config {#blitz-config} + +By default, new Blitz apps install a pre-commit and pre-push hook inside +`.husky/` in the project root. You can view these hooks +[here](https://github.com/blitz-js/blitz/tree/canary/packages/generator/templates/app/.husky). + +Husky is installed after you use NPM or Yarn to install your dependencies +following this instruction in the `package.json` file: + +```json +{ + "scripts": { + "prepare": "husky install" + } +} +``` + +Note that if you use Yarn 2, Husky needs to be installed differently. Yarn +2 doesn't support the `prepare` lifecycle script. See +[Yarn 2 install](https://typicode.github.io/husky/#/?id=yarn-2). + +## Troubleshooting Husky {#troubleshooting} + +If you are having problems commiting or pushing, check out the Husky +[troubleshooting guide](https://typicode.github.io/husky/#/?id=troubleshoot). + +To optionally bypass checks, you can run +`git commit -m "message" --no-verify` or `git push --no-verify`. diff --git a/app/pages/docs/impersonation.mdx b/app/pages/docs/impersonation.mdx index 0d2c6e0..3f6ed84 100644 --- a/app/pages/docs/impersonation.mdx +++ b/app/pages/docs/impersonation.mdx @@ -53,7 +53,7 @@ export default resolver.pipe( await ctx.session.$create({ userId: user.id, - role: "admin", + role: user.role, orgId: user.organizationId, impersonatingFromUserId: ctx.session.userId, }) @@ -98,7 +98,7 @@ import { useMutation, queryClient } from "blitz" import impersonateUser, { ImpersonateUserInput, } from "app/auth/mutations/impersonateUser" -import Form from "app/core/components/Form" +import { Form, FORM_ERROR } from "app/core/components/Form" import LabeledTextField from "app/core/components/LabeledTextField" export const ImpersonateUserForm = () => { diff --git a/app/pages/docs/postgres.mdx b/app/pages/docs/postgres.mdx index 3f2e54c..c1373f1 100644 --- a/app/pages/docs/postgres.mdx +++ b/app/pages/docs/postgres.mdx @@ -55,6 +55,12 @@ services: ports: - "5432:5432" + db-test: + image: postgres:latest + env_file: ./.env.test.local + ports: + - 5433:5432 + volumes: data: ``` @@ -71,6 +77,10 @@ POSTGRES_DB=your_database_name Given these values, update `DATABASE_URL` in `.env.local` to something similar like `postgresql://your_user:your_password@localhost:5432/your_database_name` +and in `.env.test.local` to +`postgresql://your_user:your_password@localhost:5433/your_database_name` + +Please note that test database is using port `5433` instead of `5432` 3. Modify your `package.json` to start the database before Blitz diff --git a/app/pages/docs/prettier-config.mdx b/app/pages/docs/prettier-config.mdx new file mode 100644 index 0000000..1321161 --- /dev/null +++ b/app/pages/docs/prettier-config.mdx @@ -0,0 +1,44 @@ +--- +title: Custom Prettier Config +sidebar_label: Prettier Config +--- + +[Prettier](https://prettier.io/) is an opinionated code formatter. It +enforces a consistent code style across your entire codebase. + +It re-prints the parsed AST (abstract syntax tree) with its own rules that +take the maximum line length into account, wrapping code when necessary, +etc. + +## Configuration File {#config} + +Prettier uses [cosmiconfig](https://github.com/davidtheclark/cosmiconfig) +for configuration file support. This means you can configure Prettier via +(in order of precedence): + +- A "prettier" key in your package.json file. +- A .prettierrc file written in JSON or YAML. +- A .prettierrc.json, .prettierrc.yml, .prettierrc.yaml, or + .prettierrc.json5 file. +- A .prettierrc.js, .prettierrc.cjs, prettier.config.js, or + prettier.config.cjs file that exports an object using module.exports. +- A .prettierrc.toml file. + +The configuration file will be resolved starting from the location of the +file being formatted, and searching up the file tree until a config file +is (or isn’t) found. + +Prettier intentionally doesn’t support any kind of global configuration. +This is to make sure that when a project is copied to another computer, +Prettier’s behavior stays the same. Otherwise, Prettier wouldn’t be able +to guarantee that everybody in a team gets the same consistent results. + +The full set of configuration options, including overrides and sharing +options can be found in the +[prettier docs](https://prettier.io/docs/en/configuration.html) + +## Default Blitz config {#blitz-config} + +By default, new Blitz apps configure prettier using the "prettier" key in +the +[package.json file](https://github.com/blitz-js/blitz/blob/canary/packages/generator/templates/app/package.json) diff --git a/app/pages/docs/resolver-client-utilities.mdx b/app/pages/docs/resolver-client-utilities.mdx index d2a3ba8..dc92879 100644 --- a/app/pages/docs/resolver-client-utilities.mdx +++ b/app/pages/docs/resolver-client-utilities.mdx @@ -55,7 +55,9 @@ const results = await invoke(resolver, resolverInputArguments) ## `invalidateQuery` {#invalidate-query} -This allows you to invalidate a specific query. +This allows you to invalidate a specific query. Use `invalidateQuery` if +you know for sure that a query's data is stale and you don't want to wait +for the automatic refetch. ### Example {#example-1} @@ -105,7 +107,10 @@ are done being refetched. ## `getQueryKey` {#get-query-key} -This allows you to get the query key for a query +This allows you to get the query key for a query. The `queryClient` +manages query based on query keys. For a more detailed explanation, see +the [`React Query`](https://react-query.tanstack.com/guides/query-keys) +documentation. ### Example {#example-2} diff --git a/app/pages/docs/resolver-server-utilities.mdx b/app/pages/docs/resolver-server-utilities.mdx index 727d71e..4766de1 100644 --- a/app/pages/docs/resolver-server-utilities.mdx +++ b/app/pages/docs/resolver-server-utilities.mdx @@ -180,6 +180,12 @@ A function to give `resolver.pipe` of type ## `resolver.authorize` {#resolver-authorize} +Using `resolver.authorize` in `resolver.pipe` is a simple way to check +whether the user has the authorization to call the query or mutation or +not. For this, blitz uses +[`session.$authorize`](./authorization#isauthorized-adapters) from the +context object. + ### Example {#example-2} diff --git a/app/pages/docs/route-params-query.mdx b/app/pages/docs/route-params-query.mdx index f22d80d..cdf617f 100644 --- a/app/pages/docs/route-params-query.mdx +++ b/app/pages/docs/route-params-query.mdx @@ -5,10 +5,10 @@ sidebar_label: URL Params & Query ## `useParams` {#use-params} -This hook returns all the parameters for the current route as an object. -The default parameter type is `undefined | string | string[]`, but you can -optionally provide a type argument to narrow the parameters and types that -are returned. +This hook returns all the [parameters](./routing#dynamic-route-segments) +for the current route as an object. The default parameter type is +`undefined | string | string[]`, but you can optionally provide a type +argument to narrow the parameters and types that are returned. ```tsx import { useParams } from "blitz" @@ -54,9 +54,10 @@ const params = useParams("array") ## `useParam` {#use-param} -This hook return a single parameters for the current route. The default -return type is `undefined | string | string[]`, but you can optionally -provide a type argument to cast the return type. +This hook returns a single [parameter](./routing#dynamic-route-segments) +for the current route. The default return type is +`undefined | string | string[]`, but you can optionally provide a type +argument to cast the return type. ```tsx import { useParam } from "blitz" @@ -99,7 +100,8 @@ const slug = useParam("slug", "string") ## `useRouterQuery` {#use-router-query} This hook returns all the query parameters from the URL as an object. -Parameter type is always `string`. +Using query parameters, you can pass key-value pairs via the URL with the +pattern`?key1=value1&key2=value2`. Parameter type is always `string`. ```tsx // URL: /products?sort=asc&limit=10 diff --git a/app/pages/docs/routing.mdx b/app/pages/docs/routing.mdx index 9e3144a..8949803 100644 --- a/app/pages/docs/routing.mdx +++ b/app/pages/docs/routing.mdx @@ -59,7 +59,9 @@ export default Post Any route like `/post/1`, `/post/abc`, etc. will be matched by `app/pages/post/[pid].js`. The matched path parameter will be sent as a query parameter to the page, and it will be merged with the other query -parameters. +parameters. Use [`useParams`](./route-params-query#use-params) or +[`useParam`](./route-params-query#use-param) to extract the parameter +values afterwards. For example, the route `/post/abc` will have the following `query` object: @@ -68,7 +70,8 @@ For example, the route `/post/abc` will have the following `query` object: ``` Similarly, the route `/post/abc?foo=bar` will have the following `query` -object: +object, which you can extract with +[`useRouterQuery`](./route-params-query#use-router-query): ```json { "foo": "bar", "pid": "abc" } diff --git a/app/pages/docs/testing.mdx b/app/pages/docs/testing.mdx index d64d03b..478031a 100644 --- a/app/pages/docs/testing.mdx +++ b/app/pages/docs/testing.mdx @@ -55,8 +55,8 @@ All other files will run in the Jest client environment (with jsdom). ## @testing-library {#testing-library} -[@testing-library](https://testing-library.com/docs/) is family of -packages helps you test UI components in a user-centric way. It's a better +[@testing-library](https://testing-library.com/docs/) is a family of +packages that help you test UI components in a user-centric way. It's a better alternative to Enzyme, if you've used that in the past. The following packages are installed for you. Refer to their documentation From ffdcac322084cdcc5293d088ef606419cc5cad8a Mon Sep 17 00:00:00 2001 From: garnerp Date: Tue, 8 Jun 2021 11:57:46 -0400 Subject: [PATCH 64/77] Typo in API routes documentation (#496) --- app/pages/docs/api-routes.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/api-routes.mdx b/app/pages/docs/api-routes.mdx index ff15244..4dd2c55 100644 --- a/app/pages/docs/api-routes.mdx +++ b/app/pages/docs/api-routes.mdx @@ -37,7 +37,7 @@ For an API route to work, you need to export as default a function (a.k.a [http.ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse), plus some helper functions you can see [here](#response-helpers) -If you want to avoid writting the types `BlitzApiRequest` and +If you want to avoid writing the types `BlitzApiRequest` and `BlitzApiResponse` everywhere, you can use `BlitzApiHandler`: ```ts From af24062a70bd29877bbcfc07d20e113baaf7c43a Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Tue, 8 Jun 2021 14:34:34 -0400 Subject: [PATCH 65/77] fix build --- app/pages/docs/font-optimization.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/pages/docs/font-optimization.mdx b/app/pages/docs/font-optimization.mdx index 8838da3..74e060b 100644 --- a/app/pages/docs/font-optimization.mdx +++ b/app/pages/docs/font-optimization.mdx @@ -24,7 +24,7 @@ For example: ``` -## Usage +## Usage {#usage} To add a web font to your Blitz.js application, use ``. You can add a font to a specific page like this: @@ -84,7 +84,7 @@ with support for other font providers coming soon. We're also planning to add control over [loading strategies](https://github.com/vercel/next.js/issues/21555) and `font-display` values. -## Disabling Optimization +## Disabling Optimization {#disabling-optimization} If you do not want Blitz.js to optimize your fonts, you can opt-out. From 608682c8231b1c45e9dfeb373aba69616e2b0d95 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Wed, 9 Jun 2021 10:57:18 -0400 Subject: [PATCH 66/77] update 1.0 expectation date --- app/core/components/Header.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/core/components/Header.js b/app/core/components/Header.js index b56a41c..f88fa5a 100644 --- a/app/core/components/Header.js +++ b/app/core/components/Header.js @@ -80,7 +80,7 @@ const Header = ({ onNavToggle(newValue) } - const bannerMsg = "Blitz is in beta! 🎉 1.0 expected in May or June" + const bannerMsg = "Blitz is in beta! 🎉 1.0 expected in Q3 this year" const menuLinks = [ { From 863b5bed7a3490bf3c62136b4e0c80f65eeefe68 Mon Sep 17 00:00:00 2001 From: Sean Winner Date: Fri, 11 Jun 2021 12:49:28 -0600 Subject: [PATCH 67/77] adds documentation for utility functions (#498) Co-authored-by: Brandon Bayer --- app/core/components/Header.js | 2 +- app/core/navs/documentation.json | 3 ++- app/pages/docs/utilities.mdx | 45 ++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 app/pages/docs/utilities.mdx diff --git a/app/core/components/Header.js b/app/core/components/Header.js index b56a41c..f88fa5a 100644 --- a/app/core/components/Header.js +++ b/app/core/components/Header.js @@ -80,7 +80,7 @@ const Header = ({ onNavToggle(newValue) } - const bannerMsg = "Blitz is in beta! 🎉 1.0 expected in May or June" + const bannerMsg = "Blitz is in beta! 🎉 1.0 expected in Q3 this year" const menuLinks = [ { diff --git a/app/core/navs/documentation.json b/app/core/navs/documentation.json index a52afb8..cbb6034 100644 --- a/app/core/navs/documentation.json +++ b/app/core/navs/documentation.json @@ -38,7 +38,8 @@ "static-files", "environment-variables", "error-handling", - "testing" + "testing", + "utilities" ] }, { diff --git a/app/pages/docs/utilities.mdx b/app/pages/docs/utilities.mdx new file mode 100644 index 0000000..0633e60 --- /dev/null +++ b/app/pages/docs/utilities.mdx @@ -0,0 +1,45 @@ +--- +title: Utilities +sidebar_label: Utilities +--- + +Blitz provides some handy utility functions + +## `validateZodSchema` {#validate-zod-schema} + +This utility function will validate input using a +[`zod`](https://github.com/colinhacks/zod) schema, and format any errors +to be usable with your form library. + +This is currently compatible with both React Final Form and Formik and any +others with the same API. + +### Example {#validate-zod-schema-example} + +```ts + +```js +const validationFunction = validateZodSchema(MyZodSchema) +``` + +#### Arguments + +- `ZodSchema:` a [zod](https://github.com/colinhacks/zod) schema + - **Required** + +#### Returns + +A validation function to pass to a Form component's `validate` prop. It +accepts some values and returns an object containing any errors. + +``` +(values: any) => Object +``` From d92525302371e6894593ce4ca273d0fbc73da8b6 Mon Sep 17 00:00:00 2001 From: Lukas Neumann Date: Fri, 11 Jun 2021 21:00:16 +0200 Subject: [PATCH 68/77] docs: document new setPublicDataForUser API (#500) Co-authored-by: Brandon Bayer Co-authored-by: Lukas Neumann --- app/pages/docs/auth-utils.mdx | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/app/pages/docs/auth-utils.mdx b/app/pages/docs/auth-utils.mdx index a88abb8..9ca2bc3 100644 --- a/app/pages/docs/auth-utils.mdx +++ b/app/pages/docs/auth-utils.mdx @@ -208,3 +208,28 @@ export const authenticateUser = async ( return rest } ``` + +## `setPublicDataForUser()` {#set-public-data-for-user} + +#### `setPublicDataForUser(userId: PublicData['userId'], publicData: Record) => void` + +This can be used to update the `publicData` of a user's sessions. It can +be useful when changing a user's role, since the new permissions can be +enforced as soon as the user is doing the next request. + +#### Example Usage + +```ts +import { setPublicDataForUser } from "blitz" +import db from "db" + +export const updateUserRole = async ( + userId: PublicData["userId"], + role: string +) => { + // update the user's role + await db.user.update({ where: { id: userId }, data: { role } }) + // update role in all active sessions + await setPublicDataForUser(userId, { role }) +} +``` From 5a124731b43c27a9ab61976e8a468bd09f7e66eb Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Fri, 11 Jun 2021 17:02:17 -0400 Subject: [PATCH 69/77] adds documentation for utility functions (#498) (#502) --- app/core/navs/documentation.json | 1 + app/pages/docs/error-boundary.mdx | 355 ++++++++++++++++++++++++++++++ app/pages/docs/error-handling.mdx | 11 +- 3 files changed, 362 insertions(+), 5 deletions(-) create mode 100644 app/pages/docs/error-boundary.mdx diff --git a/app/core/navs/documentation.json b/app/core/navs/documentation.json index cbb6034..d7dbedf 100644 --- a/app/core/navs/documentation.json +++ b/app/core/navs/documentation.json @@ -38,6 +38,7 @@ "static-files", "environment-variables", "error-handling", + "error-boundary", "testing", "utilities" ] diff --git a/app/pages/docs/error-boundary.mdx b/app/pages/docs/error-boundary.mdx new file mode 100644 index 0000000..c4cb5b3 --- /dev/null +++ b/app/pages/docs/error-boundary.mdx @@ -0,0 +1,355 @@ +--- +title: Component +sidebar_label: +--- + +## Usage {#usage} + +The simplest way to use `` is to wrap it around any +component that may throw an error. This will handle errors thrown by that +component and its descendants too. + +```jsx +import { ErrorBoundary } from "blitz" + +function ErrorFallback({ error, resetErrorBoundary }) { + return ( +
      +

      Something went wrong:

      +
      {error.message}
      + +
      + ) +} + +const ui = ( + { + // reset the state of your app so the error doesn't happen again + }} + > + + +) +``` + +You can react to errors (e.g. for logging) by providing an `onError` +callback: + +```jsx +import {ErrorBoundary} from 'blitz' + +const myErrorHandler = (error: Error, info: {componentStack: string}) => { + // Do something with the error + // E.g. log to an error logging client here +} + +const ui = ( + + + , +) +``` + +You can also use it as a +[higher-order component](https://reactjs.org/docs/higher-order-components.html): + +```jsx +import { withErrorBoundary } from "blitz" + +const ComponentWithErrorBoundary = withErrorBoundary( + ComponentThatMayError, + { + FallbackComponent: ErrorBoundaryFallbackComponent, + onError(error, info) { + // Do something with the error + // E.g. log to an error logging client here + }, + } +) + +const ui = +``` + +### Error Recovery {#error-recovery} + +In the event of an error if you want to recover from that error and allow +the user to "try again" or continue with their work, you'll need a way to +reset the ErrorBoundary's internal state. You can do this various ways, +but here's the most idiomatic approach: + +```jsx +function ErrorFallback({ error, resetErrorBoundary }) { + return ( +
      +

      Something went wrong:

      +
      {error.message}
      + +
      + ) +} + +function Bomb() { + throw new Error("💥 CABOOM 💥") +} + +function App() { + const [explode, setExplode] = React.useState(false) + return ( +
      + + setExplode(false)} + resetKeys={[explode]} + > + {explode ? : null} + +
      + ) +} +``` + +So, with this setup, you've got a button which when clicked will trigger +an error. Clicking the button again will trigger a re-render which +recovers from the error (we no longer render the ``). We also pass +the `resetKeys` prop which is an array of elements for the `ErrorBoundary` +to check each render (if there's currently an error state). If any of +those elements change between renders, then the `ErrorBoundary` will reset +the state which will re-render the children. + +We have the `onReset` prop so that if the user clicks the "Try again" +button we have an opportunity to re-initialize our state into a good place +before attempting to re-render the children. + +This combination allows us both the opportunity to give the user something +specific to do to recover from the error, and recover from the error by +interacting with other areas of the app that might fix things for us. It's +hard to describe here, but hopefully it makes sense when you apply it to +your specific scenario. + +## API {#api} + +### `ErrorBoundary` props {#error-boundary-props} + +#### `children` + +This is what you want rendered when everything's working fine. If there's +an error that React can handle within the children of the `ErrorBoundary`, +the `ErrorBoundary` will catch that and allow you to handle it gracefully. + +#### `FallbackComponent` + +This is a component you want rendered in the event of an error. As props +it will be passed the `error` and `resetErrorBoundary` (which will reset +the error boundary's state when called, useful for a "try again" button +when used in combination with the `onReset` prop). + +This is required if no `fallback` or `fallbackRender` prop is provided. + +#### `fallbackRender` + +This is a render-prop based API that allows you to inline your error +fallback UI into the component that's using the `ErrorBoundary`. This is +useful if you need access to something that's in the scope of the +component you're using. + +It will be called with an object that has `error` and +`resetErrorBoundary`: + +```jsx +const ui = ( + ( +
      +
      Oh no
      +
      {error.message}
      + +
      + )} + > + +
      +) +``` + +I know what you're thinking: I thought we ditched render props when hooks +came around. Unfortunately, the current React Error Boundary API only +supports class components at the moment, so render props are the best +solution we have to this problem. + +This is required if no `FallbackComponent` or `fallback` prop is provided. + +#### `fallback` + +In the spirit of consistency with the `React.Suspense` component, we also +support a simple `fallback` prop which you can use for a generic fallback. +This will not be passed any props so you can't show the user anything +actually useful though, so it's not really recommended. + +```jsx +const ui = ( + Oh no
      }> + + +) +``` + +#### `onError` + +This will be called when there's been an error that the `ErrorBoundary` +has handled. It will be called with two arguments: `error`, `info`. + +#### `onReset` + +This will be called immediately before the `ErrorBoundary` resets it's +internal state (which will result in rendering the `children` again). You +should use this to ensure that re-rendering the children will not result +in a repeat of the same error happening again. + +`onReset` will be called with whatever `resetErrorBoundary` is called +with. + +**Important**: `onReset` will _not_ be called when reset happens from a +change in `resetKeys`. Use `onResetKeysChange` for that. + +#### `resetKeys` + +Sometimes an error happens as a result of local state to the component +that's rendering the error. If this is the case, then you can pass +`resetKeys` which is an array of values. If the `ErrorBoundary` is in an +error state, then it will check these values each render and if they +change from one render to the next, then it will reset automatically +(triggering a re-render of the `children`). + +We automatically reset any time the route changes. We effectively use +`resetKeys={[router.asPath]}` internally. + +See the recovery examples above. + +#### `onResetKeysChange` + +This is called when the `resetKeys` are changed (triggering a reset of the +`ErrorBoundary`). It's called with the `prevResetKeys` and the +`resetKeys`. + +### `useErrorHandler(error?: unknown)` {#use-error-handler} + +React's error boundaries feature is limited in that the boundaries can +only handle errors thrown during React's lifecycles. To quote +[the React docs on Error Boundaries](https://reactjs.org/docs/error-boundaries.html): + +> Error boundaries do not catch errors for: +> +> - Event handlers +> ([learn more](https://reactjs.org/docs/error-boundaries.html#how-about-event-handlers)) +> - Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks) +> - Server side rendering +> - Errors thrown in the error boundary itself (rather than its children) + +This means you have to handle those errors yourself, but you probably +would like to reuse the error boundaries you worked hard on creating for +those kinds of errors as well. This is what `useErrorHandler` is for. + +There are two ways to use `useErrorHandler`: + +1. `const handleError = useErrorHandler()`: call `handleError(theError)` +2. `useErrorHandler(error)`: useful if you are managing the error state + yourself or get it from another hook. + +Here's an example: + +```javascript +function Greeting() { + const [greeting, setGreeting] = React.useState(null) + const handleError = useErrorHandler() + + function handleSubmit(event) { + event.preventDefault() + const name = event.target.elements.name.value + fetchGreeting(name).then( + (newGreeting) => setGreeting(newGreeting), + handleError + ) + } + + return greeting ? ( +
      {greeting}
      + ) : ( +
      + + + +
      + ) +} +``` + +> Note, in case it's not clear what's happening here, you could also write +> `handleSubmit` like this: + +```javascript +function handleSubmit(event) { + event.preventDefault() + const name = event.target.elements.name.value + fetchGreeting(name).then( + (newGreeting) => setGreeting(newGreeting), + (error) => handleError(error) + ) +} +``` + +Alternatively, let's say you're using a hook that gives you the error: + +```javascript +function Greeting() { + const [name, setName] = React.useState("") + const { greeting, error } = useGreeting(name) + useErrorHandler(error) + + function handleSubmit(event) { + event.preventDefault() + const name = event.target.elements.name.value + setName(name) + } + + return greeting ? ( +
      {greeting}
      + ) : ( +
      + + + +
      + ) +} +``` + +In this case, if the `error` is ever set to a truthy value, then it will +be propagated to the nearest error boundary. + +In either case, you could handle those errors like this: + +```javascript +const ui = ( + + + +) +``` + +And now that'll handle your runtime errors as well as the async errors in +the `fetchGreeting` or `useGreeting` code. diff --git a/app/pages/docs/error-handling.mdx b/app/pages/docs/error-handling.mdx index c8453ca..f8aadc6 100644 --- a/app/pages/docs/error-handling.mdx +++ b/app/pages/docs/error-handling.mdx @@ -48,10 +48,11 @@ on the server or on the client. ## Catching and Handling Errors on the Client {#catching-and-handling-errors-on-the-client} -By default, new Blitz applications come with -[`react-error-boundary`](https://github.com/bvaughn/react-error-boundary) -installed with a top-level `ErrorBoundary` and `FallbackComponent` in -`app/pages/_app.tsx`. +You handle errors on the client by using +[``](./error-boundary). + +By default, new Blitz applications include a top-level `ErrorBoundary` and +`FallbackComponent` in `app/pages/_app.tsx`. It looks something like this: @@ -59,10 +60,10 @@ It looks something like this: // app/pages/_app.tsx import { AppProps, + ErrorBoundary, ErrorComponent, useQueryErrorResetBoundary, } from "blitz" -import { ErrorBoundary } from "react-error-boundary" import LoginForm from "app/auth/components/LoginForm" export default function App({ Component, pageProps }: AppProps) { From 06a50cf4e8c9c663ff8729fd457490b1e5c8519d Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Sat, 12 Jun 2021 17:06:17 -0400 Subject: [PATCH 70/77] add docs for RedirectError --- app/pages/docs/error-handling.mdx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/pages/docs/error-handling.mdx b/app/pages/docs/error-handling.mdx index f8aadc6..c2ce7c4 100644 --- a/app/pages/docs/error-handling.mdx +++ b/app/pages/docs/error-handling.mdx @@ -24,6 +24,13 @@ application. - `name`: "NotFoundError" - `statusCode`: 404 - Default `message`: "This could not be found" +- `RedirectError` + - `name`: "RedirectError" + - You can throw this error from a render function if you want to + redirect the user while also preventing the user from seeing on the + current render path. Our `ErrorBoundary` component will automatically + handle this redirect for you. + - Example: `throw new RedirectError('/login')` To use, import from `blitz` and use like any JavaScript Error. If you're curious, you can From e307ef0818e2e23a65e75f733e7828071d817d6a Mon Sep 17 00:00:00 2001 From: Dustin Bachrach Date: Tue, 15 Jun 2021 04:04:02 -0700 Subject: [PATCH 71/77] Clarify distinction between useSession & useCurrentUser (#501) --- app/pages/docs/authorization.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/pages/docs/authorization.mdx b/app/pages/docs/authorization.mdx index efe711c..6908e7e 100644 --- a/app/pages/docs/authorization.mdx +++ b/app/pages/docs/authorization.mdx @@ -221,7 +221,7 @@ This is available on the client without making a network call to the backend, so it's available faster than the `useCurrentUser()` approach described below. -However, due to the nature of static pre-rendering, the `session` will not +Note: due to the nature of static pre-rendering, the `session` will not exist on the very first render on the client. This causes a quick "flash" on first load. You can fix that by setting [`Page.suppressFirstRenderFlicker = true`](./pages##automatic-static-optimization) @@ -240,8 +240,8 @@ if (session.role === "admin") { #### `useCurrentUser()` -New Blitz apps by default have a `useCurrentUser()` hook and a -corresponding `getCurrentUser` query. +The second way is to use the `useCurrentUser()` hook. New Blitz apps by default have a `useCurrentUser()` hook and a +corresponding `getCurrentUser` query. Unlike the `useSession()` approach above, `useCurrentUser()` will require a network call and thus be slower. However, if you need access to user data that would be insecure to store in the session's `publicData`, you would need to use `useCurrentUser()` instead of `useSession()`. ```tsx import { useCurrentUser } from "app/core/hooks/useCurrentUser" From 74fa62b5cdf8b371a18aca4bf026eb42f1df3a4f Mon Sep 17 00:00:00 2001 From: Daniel Almaguer Date: Tue, 15 Jun 2021 20:41:35 -0500 Subject: [PATCH 72/77] Update mutation-resolvers.mdx (#503) --- app/pages/docs/mutation-resolvers.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/pages/docs/mutation-resolvers.mdx b/app/pages/docs/mutation-resolvers.mdx index 5ab7018..3cdeb9d 100644 --- a/app/pages/docs/mutation-resolvers.mdx +++ b/app/pages/docs/mutation-resolvers.mdx @@ -48,7 +48,7 @@ export default async function createProject( input: z.infer, ctx: Ctx ) { - // Validate input - very importnant for security + // Validate input - very important for security const data = CreateProject.parse(input) // Require user to be logged in From ded29a7feb34161e5b057872a3f00d8d825900de Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Wed, 16 Jun 2021 11:47:56 -0400 Subject: [PATCH 73/77] add docs for nextjs 11 (#504) --- .alexrc.js | 3 +- app/core/navs/documentation.json | 3 +- app/pages/docs/blitz-config.mdx | 39 ++++++-- app/pages/docs/css.mdx | 2 +- app/pages/docs/eslint-config.mdx | 63 +++++++++--- app/pages/docs/get-started.mdx | 4 +- ...e-optimization.mdx => image-component.mdx} | 45 ++++++--- app/pages/docs/resolver-server-utilities.mdx | 2 +- app/pages/docs/rewrites.mdx | 4 +- app/pages/docs/script-component.mdx | 97 +++++++++++++++++++ app/pages/docs/static-files.mdx | 4 +- 11 files changed, 226 insertions(+), 40 deletions(-) rename app/pages/docs/{image-optimization.mdx => image-component.mdx} (87%) create mode 100644 app/pages/docs/script-component.mdx diff --git a/.alexrc.js b/.alexrc.js index bd676be..7c1ecff 100644 --- a/.alexrc.js +++ b/.alexrc.js @@ -9,5 +9,6 @@ exports.allow = [ "her-him", "herself-himself", "obvious", - "easy", + "host", + "host-hostess", ] diff --git a/app/core/navs/documentation.json b/app/core/navs/documentation.json index d7dbedf..bf25111 100644 --- a/app/core/navs/documentation.json +++ b/app/core/navs/documentation.json @@ -32,8 +32,9 @@ "pages": [ "file-structure", "app-component", + "image-component", + "script-component", "css", - "image-optimization", "font-optimization", "static-files", "environment-variables", diff --git a/app/pages/docs/blitz-config.mdx b/app/pages/docs/blitz-config.mdx index 8f9f5a8..2aab68b 100644 --- a/app/pages/docs/blitz-config.mdx +++ b/app/pages/docs/blitz-config.mdx @@ -166,12 +166,39 @@ module.exports = { } ``` -Blitz will automatically use your prefix in the scripts it loads, but this -has no effect whatsoever on the [public](./static-files) folder; if you -want to serve those assets over a CDN, you'll have to introduce the prefix -yourself. One way of introducing a prefix that works inside your -components and varies by environment is documented -[in this example](https://github.com/vercel/next.js/tree/canary/examples/with-universal-configuration-build-time). +Blitz.js will automatically use your asset prefix for the JavaScript and +CSS files it loads from the `/_next/` path (`.next/static/` folder). For +example, with the above configuration, the following request for a JS +chunk: + +``` +/_next/static/chunks/4b9b41aaa062cbbfeff4add70f256968c51ece5d.4d708494b3aed70c04f0.js +``` + +Would instead become: + +``` +https://cdn.mydomain.com/_next/static/chunks/4b9b41aaa062cbbfeff4add70f256968c51ece5d.4d708494b3aed70c04f0.js +``` + +The exact configuration for uploading your files to a given CDN will +depend on your CDN of choice. The only folder you need to host on your CDN +is the contents of `.next/static/`, which should be uploaded as +`_next/static/` as the above URL request indicates. **Do not upload the +rest of your `.next/` folder**, as you should not expose your server code +and other configuration to the public. + +While `assetPrefix` covers requests to `_next/static`, it does not +influence the following paths: + +- Files in the [public](./static-files) folder; if you want to serve those + assets over a CDN, you'll have to introduce the prefix yourself +- `/_next/data/` requests for `getServerSideProps` pages. These requests + will always be made against the main domain since they're not static. +- `/_next/data/` requests for `getStaticProps` pages. These requests will + always be made against the main domain to support + [Incremental Static Generation](./get-static-props), even if you're not + using it (for consistency). ## Custom Page Extensions {#custom-page-extensions} diff --git a/app/pages/docs/css.mdx b/app/pages/docs/css.mdx index e13fd76..b39fb5c 100644 --- a/app/pages/docs/css.mdx +++ b/app/pages/docs/css.mdx @@ -1,6 +1,6 @@ --- title: Built-In CSS Support -sidebar_label: Built-In CSS Support +sidebar_label: CSS --- Blitz allows you to import CSS files directly into any JavaScript file. diff --git a/app/pages/docs/eslint-config.mdx b/app/pages/docs/eslint-config.mdx index 53ac31c..1aa7486 100644 --- a/app/pages/docs/eslint-config.mdx +++ b/app/pages/docs/eslint-config.mdx @@ -4,12 +4,7 @@ sidebar_label: ESLint Config --- Blitz extends the -[create-react-app](https://create-react-app.dev/docs/setting-up-your-editor/#experimental-extending-the-eslint-config) -eslint config. - -Our configuration contains a few modifications, and the full preset can be -found on github -[here](https://github.com/blitz-js/blitz/blob/canary/packages/eslint-config/index.js), +[default Next.js eslint config](https://nextjs.org/docs/basic-features/eslint#eslint-plugin) This configuration is found in .eslintrc.js, and by default is @@ -21,23 +16,65 @@ module.exports = { ## Extending or replacing the default Blitz ESLint config {#extending} -You can extend the base Blitz ESLint config, or replace it completely if you need. +You can extend the base Blitz ESLint config, or replace it completely if +you need. There are a few things to remember: -1. We highly recommend extending the base config, as removing it could introduce hard-to-find issues. -2. It's important to note that any rules that are set to "error" will stop the project from building. +1. We highly recommend extending the base config, as removing it could + introduce hard-to-find issues. +2. It's important to note that any rules that are set to "error" will stop + the project from building. In the below example: - - the base config has been extended by a shared ESLint config, - - a new rule has been set that applies to all JavaScript and TypeScript files +- the base config has been extended by a shared ESLint config, +- a new rule has been set that applies to all JavaScript and TypeScript + files ```js module.exports = { extends: ["blitz", "shared-config"], rules: { - "additional-rule": "warn" + "additional-rule": "warn", }, } -``` \ No newline at end of file +``` + +## Linting During Builds {#during-builds} + +When ESLint is detected in your project, Blitz.js fails your **production +build** (`blitz build`) when errors are present. + +If you'd like Blitz.js to produce production code even when your +application has ESLint errors, you can disable the built-in linting step +completely. + +> Be sure you have configured ESLint to run in a separate part of your +> workflow (for example, in CI or a pre-commit hook). Open +> `blitz.config.js` and enable the `ignoreDuringBuilds` option in the +> `eslint` config: + +```js +// blitz.config.js +module.exports = { + eslint: { + ignoreDuringBuilds: true, + }, +} +``` + +## Core Web Vitals {#core-web-vitals} + +A stricter `next/core-web-vitals` rule set can also be added in +`.eslintrc`: + +``` +{ + "extends": ["blitz", "next/core-web-vitals"] +} +``` + +`next/core-web-vitals` updates some rules from the base config to error on +a number of rules that are warnings by default if they affect +[Core Web Vitals](https://web.dev/vitals/). diff --git a/app/pages/docs/get-started.mdx b/app/pages/docs/get-started.mdx index 7f920d8..f44855e 100644 --- a/app/pages/docs/get-started.mdx +++ b/app/pages/docs/get-started.mdx @@ -8,8 +8,8 @@ sidebar_label: Get Started You need Node.js 12 or newer. You can verify this by running `node -v` in your terminal. If you don't have Node or need a newer version, we recommend using a node version manager like -[fnm](https://github.com/Schniz/fnm). That will allow you to easily change -node versions and even have different versions for each project. +[fnm](https://github.com/Schniz/fnm). That will allow you to change node +versions and even have different versions for each project. ### Install Blitz {#install-blitz} diff --git a/app/pages/docs/image-optimization.mdx b/app/pages/docs/image-component.mdx similarity index 87% rename from app/pages/docs/image-optimization.mdx rename to app/pages/docs/image-component.mdx index d725eaf..fad3f71 100644 --- a/app/pages/docs/image-optimization.mdx +++ b/app/pages/docs/image-component.mdx @@ -1,6 +1,6 @@ --- title: Image Component and Image Optimization -sidebar_label: Image Optimization +sidebar_label: --- Blitz has a built-in Image Component and Automatic Image Optimization. @@ -40,17 +40,13 @@ To add an image to your application, import the `Image` component: ```jsx import { Image } from "blitz" +import profilePic from "../me.png" function Home() { return ( <>

      My Homepage

      - Picture of the author + Picture of the author

      Welcome to my homepage!

      ) @@ -211,7 +207,11 @@ The `Image` component requires the following properties. #### src -The path or URL to the source image. This is required. +Required and must be one of the following: + +1. A statically imported image file, as in the example code above, or +2. A path string. This can be either an absolute external URL, or an + internal path depending on the [loader](#loader). When using an external URL, you must add it to [`domains`](#domains) in `blitz.config.js`. @@ -220,13 +220,15 @@ When using an external URL, you must add it to [`domains`](#domains) in The width of the image, in pixels. Must be an integer without a unit. -Required unless `layout="fill"`. +Required, except for statically imported images, or those with +[`layout="fill"`](#layout). #### height The height of the image, in pixels. Must be an integer without a unit. -Required unless `layout="fill"`. +Required, except for statically imported images, or those with +[`layout="fill"`](#layout). ### Optional Props {#optional-props} @@ -280,7 +282,7 @@ const MyImage = (props) => { return ( Picture of the author Component +sidebar_label: + +// Lazy load FB scripts + + +// Use the onLoad callback to execute code on script load + + +// Loading strategy works for inline scripts too + + +// or + + +// All script attributes are forwarded to the final element + +``` + +## Which third-party scripts to wrap with Script Loader {#recommendations} + +We recommend the following Script Loader strategies for these categories +of third-party scripts + +| Loading strategy | third-party categories | +| ----------------- | ------------------------------------------------------------------------------------------ | +| beforeInteractive | polyfill.io, Bot detection, security & authentication, User consent management (GDPR) | +| afterInteractive | Tag-managers, Analytics | +| lazyOnload | customer relationship management eg. Google feedback, chat support widget, social networks | diff --git a/app/pages/docs/static-files.mdx b/app/pages/docs/static-files.mdx index 62a445b..7281698 100644 --- a/app/pages/docs/static-files.mdx +++ b/app/pages/docs/static-files.mdx @@ -1,6 +1,6 @@ --- -title: Static Files & Images -sidebar_label: Static Files & Images +title: Static Files +sidebar_label: Static Files --- Blitz can serve static files, like images, under a folder called `public` From e93f7843bdeef6ca80783ce777585157c710c7a6 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Wed, 16 Jun 2021 18:08:54 -0400 Subject: [PATCH 74/77] add docs for formatZodError --- app/pages/docs/utilities.mdx | 51 +++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/app/pages/docs/utilities.mdx b/app/pages/docs/utilities.mdx index 0633e60..7054697 100644 --- a/app/pages/docs/utilities.mdx +++ b/app/pages/docs/utilities.mdx @@ -17,10 +17,12 @@ others with the same API. ### Example {#validate-zod-schema-example} ```ts - Object ``` + +## `formatZodError` {#format-zod-error} + +This utility function will take a ZodError and format it nicely to be +usable with your form library. + +This is currently compatible with both React Final Form and Formik and any +others with the same API. + +### Example {#format-zod-error-example} + +```ts +import {formatZodError} from 'blitz' + + { + try { + schema.parse(values) + } catch (error) { + return formatZodError(error) + } + }} + ... +``` + +### API {#format-zod-error-api} + + +```js +const formattedErrorsObject = formatZodError(myZodError) +``` + +#### Arguments + +- `ZodError:` a [zod](https://github.com/colinhacks/zod) error + - **Required** + +#### Returns + +An object with errors that makes the same shape as the original schema From c487b07bd77b2d6581fc1163df570163dd7b1751 Mon Sep 17 00:00:00 2001 From: Brandon Bayer Date: Thu, 17 Jun 2021 10:02:37 -0400 Subject: [PATCH 75/77] Upgrade blitz and to react 18 (#505) --- app/pages/index.js | 21 +- app/pages/languages.js | 2 +- blitz.config.js | 6 +- package.json | 6 +- yarn.lock | 1205 ++++++++++++++++++++++------------------ 5 files changed, 678 insertions(+), 562 deletions(-) diff --git a/app/pages/index.js b/app/pages/index.js index 240c1b5..7c5f7bd 100644 --- a/app/pages/index.js +++ b/app/pages/index.js @@ -54,9 +54,9 @@ const Home = ({randomContributors}) => { The Fullstack React Framework

      - Blitz is a batteries-included framework that's inspired by Ruby on Rails, is - built on Next.js, and features a "Zero-API" data layer abstraction that - eliminates the need for REST/GraphQL. + Blitz is a batteries-included framework that's inspired by Ruby on Rails, + is built on Next.js, and features a "Zero-API" data layer abstraction + that eliminates the need for REST/GraphQL.

      @@ -161,7 +161,7 @@ const Home = ({randomContributors}) => { free to do so.

      - And nearly everything is pluggable. For example, we don't mandate which + And nearly everything is pluggable. For example, we don't mandate which styling or form libraries you use.

      @@ -181,8 +181,8 @@ const Home = ({randomContributors}) => {

      - Once we reach version 1.0, we'll switch to a stable, predictable release - cycle with multiple channels like stable, LTS, and beta. + Once we reach version 1.0, we'll switch to a stable, predictable + release cycle with multiple channels like stable, LTS, and beta.

      We are taking a lot inspiration from Ember in this regard.

      @@ -203,7 +203,12 @@ const Home = ({randomContributors}) => { href="https://codesandbox.io/s/flamboyant-meninsky-j63yq?file=/app/projects/mutations/createProject.ts" className="h-sandbox xl:h-xl-sandbox block relative" > - + Codesandbox placeholder
      Click to Open in New Tab
      @@ -271,7 +276,7 @@ const Home = ({randomContributors}) => { similar than we are different. We love to work together.

      - We invite you to help make Blitz the best framework we've ever had! + We invite you to help make Blitz the best framework we've ever had!

      diff --git a/app/pages/languages.js b/app/pages/languages.js index 5170e1c..7479114 100644 --- a/app/pages/languages.js +++ b/app/pages/languages.js @@ -56,7 +56,7 @@ const LanguagesPage = ({languages}) => { ))}
      - Don't see your language?{" "} + Don't see your language?{" "} Date: Fri, 18 Jun 2021 18:22:27 +0200 Subject: [PATCH 76/77] Add instruction for render.yaml (#507) --- app/pages/docs/deploy-render.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/app/pages/docs/deploy-render.mdx b/app/pages/docs/deploy-render.mdx index ca439f4..c263a2e 100644 --- a/app/pages/docs/deploy-render.mdx +++ b/app/pages/docs/deploy-render.mdx @@ -45,6 +45,7 @@ services: plan: starter buildCommand: yarn --frozen-lockfile --prod=false && + blitz prisma generate && blitz build && blitz prisma migrate deploy startCommand: blitz start From 9a282371a929bae5732160068e4ff99fb796722c Mon Sep 17 00:00:00 2001 From: Nicolas Torres Date: Sat, 19 Jun 2021 20:01:44 +0200 Subject: [PATCH 77/77] Adds builder.printMessage documentation (#508) Co-authored-by: Nicolas --- app/pages/docs/writing-recipes.mdx | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/app/pages/docs/writing-recipes.mdx b/app/pages/docs/writing-recipes.mdx index d14cc04..703da3b 100644 --- a/app/pages/docs/writing-recipes.mdx +++ b/app/pages/docs/writing-recipes.mdx @@ -220,6 +220,36 @@ builder This step would append "Paul Plain was here!" to the user's README.md +#### Creating a custom message + +Sometimes you need to print a simple message, or give some instructions, +you can achieve that with `printMessage` + +```ts +builder.printMessage({ + successIcon: "ℹ️", + stepId: "oops", + stepName: "Contributors needed!", + message: "If you like this recipe, consider helping out!", +}) +``` + +This step would print "If you like this recipe, consider helping out!" to +terminal and wait for the user to go to the next step. + +#### Custom step icons + +If you want to customize your recipe even further, you can pass an +optional `successIcon` param to your steps. + +```ts +builder + .addTransformFilesStep({ + successIcon: "🔧", + ... + }) +``` + #### Modifying Prisma schemas A lot of recipes may need to add or modify models in the schema.prisma