1
0
mirror of synced 2026-02-06 18:00:14 -05:00

Compare commits

..

6 Commits

Author SHA1 Message Date
Brandon Bayer
0816950fb6 work with no JS 2021-02-09 19:29:27 -05:00
Brandon Bayer
57c70795e8 more cleanup 2021-02-09 19:04:47 -05:00
Brandon Bayer
12785484c0 cleanup 2021-02-09 19:02:47 -05:00
Brandon Bayer
2b65ce2206 refactor 2021-02-09 19:01:57 -05:00
Brandon Bayer
ad58be3f52 Merge branch 'canary' into use-authorize 2021-02-09 18:53:55 -05:00
Brandon Bayer
f9dca5c60a wip 2021-02-08 19:49:56 -05:00
4280 changed files with 18725 additions and 480812 deletions

View File

@@ -20,9 +20,7 @@
"code",
"content",
"ideas",
"review",
"test",
"doc"
"review"
]
},
{
@@ -181,8 +179,7 @@
"contributions": [
"code",
"maintenance",
"test",
"doc"
"test"
]
},
{
@@ -357,8 +354,7 @@
"contributions": [
"test",
"code",
"review",
"doc"
"review"
]
},
{
@@ -369,8 +365,7 @@
"contributions": [
"code",
"test",
"maintenance",
"doc"
"maintenance"
]
},
{
@@ -532,8 +527,7 @@
"avatar_url": "https://avatars1.githubusercontent.com/u/19371989?v=4",
"profile": "https://builtforfifty.com",
"contributions": [
"code",
"doc"
"code"
]
},
{
@@ -1251,8 +1245,7 @@
"avatar_url": "https://avatars0.githubusercontent.com/u/8682104?v=4",
"profile": "https://github.com/konradkalemba",
"contributions": [
"code",
"doc"
"code"
]
},
{
@@ -1594,8 +1587,7 @@
"avatar_url": "https://avatars3.githubusercontent.com/u/43112535?v=4",
"profile": "http://Dal.Design",
"contributions": [
"code",
"doc"
"code"
]
},
{
@@ -1613,8 +1605,7 @@
"avatar_url": "https://avatars3.githubusercontent.com/u/4396533?v=4",
"profile": "https://github.com/sakulstra",
"contributions": [
"code",
"test"
"code"
]
},
{
@@ -1668,9 +1659,7 @@
"avatar_url": "https://avatars0.githubusercontent.com/u/61833561?v=4",
"profile": "https://tundera.dev",
"contributions": [
"code",
"test",
"doc"
"code"
]
},
{
@@ -1918,8 +1907,7 @@
"avatar_url": "https://avatars.githubusercontent.com/u/1926271?v=4",
"profile": "https://github.com/akbo",
"contributions": [
"code",
"doc"
"code"
]
},
{
@@ -1987,891 +1975,8 @@
"contributions": [
"code"
]
},
{
"login": "LBrian",
"name": "Brian Liu",
"avatar_url": "https://avatars.githubusercontent.com/u/3888780?v=4",
"profile": "https://brianypliu.com",
"contributions": [
"code"
]
},
{
"login": "beerose",
"name": "Aleksandra Sikora",
"avatar_url": "https://avatars.githubusercontent.com/u/9019397?v=4",
"profile": "http://aleksandra.codes",
"contributions": [
"code"
]
},
{
"login": "JuanM04",
"name": "JuanM04",
"avatar_url": "https://avatars.githubusercontent.com/u/16712703?v=4",
"profile": "https://juanm04.com",
"contributions": [
"code",
"doc",
"test"
]
},
{
"login": "arenddeboer",
"name": "Arend de Boer",
"avatar_url": "https://avatars.githubusercontent.com/u/7022204?v=4",
"profile": "https://github.com/arenddeboer",
"contributions": [
"doc"
]
},
{
"login": "fmilani",
"name": "Felipe Milani",
"avatar_url": "https://avatars.githubusercontent.com/u/1580375?v=4",
"profile": "https://github.com/fmilani",
"contributions": [
"doc"
]
},
{
"login": "jxe",
"name": "Joe Edelman",
"avatar_url": "https://avatars.githubusercontent.com/u/13018?v=4",
"profile": "http://nxhx.org",
"contributions": [
"code"
]
},
{
"login": "garytube",
"name": "Gary",
"avatar_url": "https://avatars.githubusercontent.com/u/3823504?v=4",
"profile": "https://github.com/garytube",
"contributions": [
"doc"
]
},
{
"login": "oliverloops",
"name": "Oliver Lopez ",
"avatar_url": "https://avatars.githubusercontent.com/u/33361399?v=4",
"profile": "http://oliverloops.com",
"contributions": [
"doc"
]
},
{
"login": "DecadentIpsum",
"name": "Andreas Zaralis",
"avatar_url": "https://avatars.githubusercontent.com/u/32861532?v=4",
"profile": "https://decadentIpsum.me",
"contributions": [
"doc"
]
},
{
"login": "davetorbeck",
"name": "David Torbeck",
"avatar_url": "https://avatars.githubusercontent.com/u/5829885?v=4",
"profile": "https://github.com/davetorbeck",
"contributions": [
"doc"
]
},
{
"login": "gusgard",
"name": "Gustavo Gard",
"avatar_url": "https://avatars.githubusercontent.com/u/2577356?v=4",
"profile": "https://github.com/gusgard",
"contributions": [
"doc"
]
},
{
"login": "Immortalin",
"name": "Immortalin",
"avatar_url": "https://avatars.githubusercontent.com/u/7126128?v=4",
"profile": "https://narrationbox.com",
"contributions": [
"code"
]
},
{
"login": "cristianbgp",
"name": "Cristian Granda",
"avatar_url": "https://avatars.githubusercontent.com/u/8507974?v=4",
"profile": "https://cristianbgp.com",
"contributions": [
"code"
]
},
{
"login": "deniseyu",
"name": "Denise Yu",
"avatar_url": "https://avatars.githubusercontent.com/u/8420094?v=4",
"profile": "https://deniseyu.io",
"contributions": [
"code"
]
},
{
"login": "andreadellacorte",
"name": "Andrea Della Corte",
"avatar_url": "https://avatars.githubusercontent.com/u/295683?v=4",
"profile": "http://dellacorte.me",
"contributions": [
"doc"
]
},
{
"login": "aditsachde",
"name": "Adit Sachde",
"avatar_url": "https://avatars.githubusercontent.com/u/23707194?v=4",
"profile": "http://aditsachde.com",
"contributions": [
"doc"
]
},
{
"login": "hirenchauhan2",
"name": "Hiren Chauhan",
"avatar_url": "https://avatars.githubusercontent.com/u/8999668?v=4",
"profile": "https://github.com/hirenchauhan2",
"contributions": [
"code"
]
},
{
"login": "remjx",
"name": "Mark Jackson",
"avatar_url": "https://avatars.githubusercontent.com/u/35121685?v=4",
"profile": "http://remjx.com/",
"contributions": [
"doc",
"code"
]
},
{
"login": "lewisblackburn",
"name": "Lewis Blackburn",
"avatar_url": "https://avatars.githubusercontent.com/u/51877955?v=4",
"profile": "https://lewisb.cloud/",
"contributions": [
"doc"
]
},
{
"login": "FDiskas",
"name": "Vytenis",
"avatar_url": "https://avatars.githubusercontent.com/u/468006?v=4",
"profile": "https://github.com/FDiskas",
"contributions": [
"code"
]
},
{
"login": "matthieu994",
"name": "Matthieu",
"avatar_url": "https://avatars.githubusercontent.com/u/12969089?v=4",
"profile": "https://portfolio.matthieupetit.com",
"contributions": [
"code",
"test"
]
},
{
"login": "mitchazj",
"name": "Mitchell Johnson",
"avatar_url": "https://avatars.githubusercontent.com/u/15032956?v=4",
"profile": "https://github.com/mitchazj",
"contributions": [
"code"
]
},
{
"login": "Roesh",
"name": "Roshan Manuel",
"avatar_url": "https://avatars.githubusercontent.com/u/31125563?v=4",
"profile": "https://roshan.page/",
"contributions": [
"code",
"doc",
"test"
]
},
{
"login": "kevinlangleyjr",
"name": "Kevin Langley Jr.",
"avatar_url": "https://avatars.githubusercontent.com/u/877634?v=4",
"profile": "https://kevinlangleyjr.com",
"contributions": [
"code",
"doc"
]
},
{
"login": "heavygabriel",
"name": "Gabriel Picard",
"avatar_url": "https://avatars.githubusercontent.com/u/51029779?v=4",
"profile": "https://projet-test-99df0.firebaseapp.com/",
"contributions": [
"doc"
]
},
{
"login": "chenkie",
"name": "Ryan Chenkie",
"avatar_url": "https://avatars.githubusercontent.com/u/1847678?v=4",
"profile": "http://ryanchenkie.com/",
"contributions": [
"doc"
]
},
{
"login": "sbappan",
"name": "Santhosh B. Appan",
"avatar_url": "https://avatars.githubusercontent.com/u/12586088?v=4",
"profile": "https://github.com/sbappan",
"contributions": [
"doc"
]
},
{
"login": "james2406",
"name": "James Moran",
"avatar_url": "https://avatars.githubusercontent.com/u/10858584?v=4",
"profile": "http://stackoverflow.com/users/5207233/james-moran",
"contributions": [
"code",
"doc"
]
},
{
"login": "bugzpodder",
"name": "Jack Zhao",
"avatar_url": "https://avatars.githubusercontent.com/u/14841421?v=4",
"profile": "http://fb.me/yz",
"contributions": [
"code"
]
},
{
"login": "the-red",
"name": "Hisaki Akaza",
"avatar_url": "https://avatars.githubusercontent.com/u/4494300?v=4",
"profile": "https://github.com/the-red",
"contributions": [
"doc"
]
},
{
"login": "Flavyoo",
"name": "Flavio",
"avatar_url": "https://avatars.githubusercontent.com/u/14948074?v=4",
"profile": "http://flavioander.com/",
"contributions": [
"code"
]
},
{
"login": "pbteja1998",
"name": "Bhanu Teja Pachipulusu",
"avatar_url": "https://avatars.githubusercontent.com/u/17903466?v=4",
"profile": "https://bhanuteja.dev/",
"contributions": [
"code"
]
},
{
"login": "pavestru",
"name": "Pavel Struhar",
"avatar_url": "https://avatars.githubusercontent.com/u/10186479?v=4",
"profile": "https://twitter.com/pavestru",
"contributions": [
"code"
]
},
{
"login": "reo777",
"name": "Reo Ishiyama",
"avatar_url": "https://avatars.githubusercontent.com/u/42126368?v=4",
"profile": "https://in-thepink.com/",
"contributions": [
"code"
]
},
{
"login": "tmcw",
"name": "Tom MacWright",
"avatar_url": "https://avatars.githubusercontent.com/u/32314?v=4",
"profile": "https://macwright.com/",
"contributions": [
"doc"
]
},
{
"login": "franky47",
"name": "François Best",
"avatar_url": "https://avatars.githubusercontent.com/u/1174092?v=4",
"profile": "https://francoisbest.com",
"contributions": [
"code"
]
},
{
"login": "FarazPatankar",
"name": "Faraz Patankar",
"avatar_url": "https://avatars.githubusercontent.com/u/10681116?v=4",
"profile": "https://github.com/FarazPatankar",
"contributions": [
"doc"
]
},
{
"login": "ericvicenti",
"name": "Eric Vicenti",
"avatar_url": "https://avatars.githubusercontent.com/u/1483597?v=4",
"profile": "https://github.com/ericvicenti",
"contributions": [
"doc",
"code"
]
},
{
"login": "amdolan",
"name": "Alex Dolan",
"avatar_url": "https://avatars.githubusercontent.com/u/2552275?v=4",
"profile": "https://github.com/amdolan",
"contributions": [
"doc",
"code",
"test"
]
},
{
"login": "Maastrich",
"name": "Mathis Pinsault",
"avatar_url": "https://avatars.githubusercontent.com/u/58431775?v=4",
"profile": "https://github.com/Maastrich",
"contributions": [
"doc"
]
},
{
"login": "gstranger",
"name": "gstranger",
"avatar_url": "https://avatars.githubusercontent.com/u/36181416?v=4",
"profile": "https://github.com/gstranger",
"contributions": [
"code",
"doc"
]
},
{
"login": "markhughes",
"name": "Mark Hughes",
"avatar_url": "https://avatars.githubusercontent.com/u/1357323?v=4",
"profile": "http://twitter.com/_markeh",
"contributions": [
"code",
"doc"
]
},
{
"login": "andrearizzello",
"name": "Andrea Rizzello",
"avatar_url": "https://avatars.githubusercontent.com/u/10348930?v=4",
"profile": "www.andrearizzello.work",
"contributions": [
"doc"
]
},
{
"login": "jahredhope",
"name": "Jahred Hope",
"avatar_url": "https://avatars.githubusercontent.com/u/13903378?v=4",
"profile": "jahred.com.au",
"contributions": [
"doc"
]
},
{
"login": "simonelnahas",
"name": "Simon El Nahas",
"avatar_url": "https://avatars.githubusercontent.com/u/29279201?v=4",
"profile": "simonelnahas.github.io/",
"contributions": [
"doc"
]
},
{
"login": "Cristy94",
"name": "Buleandra Cristian",
"avatar_url": "https://avatars.githubusercontent.com/u/1384885?v=4",
"profile": "www.usertrack.net",
"contributions": [
"doc",
"code"
]
},
{
"login": "peterpalau",
"name": "Pedro Enrique Palau Isaac",
"avatar_url": "https://avatars.githubusercontent.com/u/12257885?v=4",
"profile": "http://palauisaac.me/",
"contributions": [
"code"
]
},
{
"login": "sean-brydon",
"name": "sean-brydon",
"avatar_url": "https://avatars.githubusercontent.com/u/55134778?v=4",
"profile": "www.seanbrydon.me",
"contributions": [
"doc"
]
},
{
"login": "Dieman89",
"name": "Alessandro",
"avatar_url": "https://avatars.githubusercontent.com/u/28837891?v=4",
"profile": "buonerba.dev",
"contributions": [
"doc"
]
},
{
"login": "laubonghaudoi",
"name": "laubonghaudoi",
"avatar_url": "https://avatars.githubusercontent.com/u/11172180?v=4",
"profile": "www.jyutping.org",
"contributions": [
"doc"
]
},
{
"login": "TommasoBruno99",
"name": "Tommaso Bruno",
"avatar_url": "https://avatars.githubusercontent.com/u/61512591?v=4",
"profile": "https://github.com/TommasoBruno99",
"contributions": [
"doc"
]
},
{
"login": "antonykamp",
"name": "Antony",
"avatar_url": "https://avatars.githubusercontent.com/u/45163503?v=4",
"profile": "antonykamp.de",
"contributions": [
"doc"
]
},
{
"login": "frontsideair",
"name": "Fatih Altinok",
"avatar_url": "https://avatars.githubusercontent.com/u/868283?v=4",
"profile": "https://blog.6nok.org",
"contributions": [
"doc"
]
},
{
"login": "Mokshit06",
"name": "Mokshit Jain",
"avatar_url": "https://avatars.githubusercontent.com/u/50412128?v=4",
"profile": "https://mokshitjain.co/",
"contributions": [
"code"
]
},
{
"login": "mubaidr",
"name": "Muhammad Ubaid Raza",
"avatar_url": "https://avatars.githubusercontent.com/u/2222702?v=4",
"profile": "https://mubaidr.github.io",
"contributions": [
"code",
"doc"
]
},
{
"login": "silicontwin",
"name": "Nick Warren",
"avatar_url": "https://avatars.githubusercontent.com/u/121665?v=4",
"profile": "https://github.com/silicontwin",
"contributions": [
"code"
]
},
{
"login": "mlabate",
"name": "mlabate",
"avatar_url": "https://avatars.githubusercontent.com/u/17139676?v=4",
"profile": "https://github.com/mlabate",
"contributions": [
"doc"
]
},
{
"login": "lumaxis",
"name": "Lukas Spieß",
"avatar_url": "https://avatars.githubusercontent.com/u/406937?v=4",
"profile": "https://github.com/lumaxis",
"contributions": [
"doc"
]
},
{
"login": "dawnofmidnight",
"name": "DawnOfMidnight",
"avatar_url": "https://avatars.githubusercontent.com/u/78233879?v=4",
"profile": "https://dawnofmidnight.vercel.app",
"contributions": [
"doc"
]
},
{
"login": "kirakik",
"name": "Kenza Iraki",
"avatar_url": "https://avatars.githubusercontent.com/u/17203119?v=4",
"profile": "https://www.linkedin.com/in/kenzairaki/",
"contributions": [
"test",
"code"
]
},
{
"login": "agustif",
"name": "Agusti Fernandez",
"avatar_url": "https://avatars.githubusercontent.com/u/6601142?v=4",
"profile": "https://github.com/agustif",
"contributions": [
"code"
]
},
{
"login": "Anjianto",
"name": "Anjianto",
"avatar_url": "https://avatars.githubusercontent.com/u/61521141?v=4",
"profile": "https://github.com/Anjianto",
"contributions": [
"code"
]
},
{
"login": "adblanc",
"name": "Blanc Adrien",
"avatar_url": "https://avatars.githubusercontent.com/u/41756894?v=4",
"profile": "https://adrienblanc.com",
"contributions": [
"code"
]
},
{
"login": "meepdeew",
"name": "meepdeew",
"avatar_url": "https://avatars.githubusercontent.com/u/43303008?v=4",
"profile": "https://github.com/meepdeew",
"contributions": [
"doc"
]
},
{
"login": "Hardik3296",
"name": "Hardik Gaur",
"avatar_url": "https://avatars.githubusercontent.com/u/20360325?v=4",
"profile": "https://github.com/Hardik3296",
"contributions": [
"doc"
]
},
{
"login": "acornellier",
"name": "acornellier",
"avatar_url": "https://avatars.githubusercontent.com/u/8725423?v=4",
"profile": "https://github.com/acornellier",
"contributions": [
"code"
]
},
{
"login": "craigglennie",
"name": "craigglennie",
"avatar_url": "https://avatars.githubusercontent.com/u/149281?v=4",
"profile": "https://github.com/craigglennie",
"contributions": [
"doc"
]
},
{
"login": "fernvilla",
"name": "Fernando Villasenor",
"avatar_url": "https://avatars.githubusercontent.com/u/5857808?v=4",
"profile": "http://www.fernvillasenor.com",
"contributions": [
"code"
]
},
{
"login": "swiftgaruda",
"name": "swiftgaruda",
"avatar_url": "https://avatars.githubusercontent.com/u/16741392?v=4",
"profile": "https://github.com/swiftgaruda",
"contributions": [
"doc"
]
},
{
"login": "Patil2099",
"name": "Pankaj Patil",
"avatar_url": "https://avatars.githubusercontent.com/u/35653876?v=4",
"profile": "https://pplife.home.blog",
"contributions": [
"doc"
]
},
{
"login": "mabadir",
"name": "Mina Abadir",
"avatar_url": "https://avatars.githubusercontent.com/u/3389914?v=4",
"profile": "minaabadir.ca",
"contributions": [
"code",
"doc",
"test"
]
},
{
"login": "frankiesardo",
"name": "Francesco Sardo",
"avatar_url": "https://avatars.githubusercontent.com/u/1476561?v=4",
"profile": "https://github.com/frankiesardo",
"contributions": [
"doc",
"code"
]
},
{
"login": "enemycnt",
"name": "Nikolay",
"avatar_url": "https://avatars.githubusercontent.com/u/320313?v=4",
"profile": "https://github.com/enemycnt",
"contributions": [
"doc"
]
},
{
"login": "Dipeshwagle",
"name": "Dipesh Wagle",
"avatar_url": "https://avatars.githubusercontent.com/u/4191022?v=4",
"profile": "https://dipeshwagle.com",
"contributions": [
"code"
]
},
{
"login": "benbender",
"name": "Benjamin Bender",
"avatar_url": "https://avatars.githubusercontent.com/u/462455?v=4",
"profile": "https://codepoet.de",
"contributions": [
"code"
]
},
{
"login": "nimashoghi",
"name": "Nima Shoghi",
"avatar_url": "https://avatars.githubusercontent.com/u/3728170?v=4",
"profile": "https://nima.sh",
"contributions": [
"code"
]
},
{
"login": "chronark",
"name": "Andreas Thomas",
"avatar_url": "https://avatars.githubusercontent.com/u/18246773?v=4",
"profile": "https://github.com/chronark",
"contributions": [
"doc"
]
},
{
"login": "guoqqqi",
"name": "guoqqqi",
"avatar_url": "https://avatars.githubusercontent.com/u/72343596?v=4",
"profile": "https://github.com/guoqqqi",
"contributions": [
"doc"
]
},
{
"login": "timbooker",
"name": "Tim",
"avatar_url": "https://avatars.githubusercontent.com/u/612681?v=4",
"profile": "https://github.com/timbooker",
"contributions": [
"code",
"test"
]
},
{
"login": "ormarek",
"name": "Marek Orłowski",
"avatar_url": "https://avatars.githubusercontent.com/u/16357457?v=4",
"profile": "http://orlowski.me/",
"contributions": [
"doc"
]
},
{
"login": "AntoineGuestin",
"name": "Antoine G",
"avatar_url": "https://avatars.githubusercontent.com/u/70888750?v=4",
"profile": "https://github.com/AntoineGuestin",
"contributions": [
"code"
]
},
{
"login": "swinner2",
"name": "Sean Winner",
"avatar_url": "https://avatars.githubusercontent.com/u/6707308?v=4",
"profile": "https://github.com/swinner2",
"contributions": [
"code",
"test",
"doc"
]
},
{
"login": "max-programming",
"name": "Max Programming",
"avatar_url": "https://avatars.githubusercontent.com/u/51731966?v=4",
"profile": "https://usman-s.me",
"contributions": [
"code"
]
},
{
"login": "sebastianhoitz",
"name": "Sebastian Hoitz",
"avatar_url": "https://avatars.githubusercontent.com/u/353768?v=4",
"profile": "https://makemake.sh",
"contributions": [
"test",
"code"
]
},
{
"login": "garnerp",
"name": "garnerp",
"avatar_url": "https://avatars.githubusercontent.com/u/737307?v=4",
"profile": "https://github.com/garnerp",
"contributions": [
"doc"
]
},
{
"login": "kivi",
"name": "kivi",
"avatar_url": "https://avatars.githubusercontent.com/u/366163?v=4",
"profile": "https://github.com/kivi",
"contributions": [
"code"
]
},
{
"login": "dangreaves",
"name": "Dan Greaves",
"avatar_url": "https://avatars.githubusercontent.com/u/1036142?v=4",
"profile": "http://dangreaves.com",
"contributions": [
"code"
]
},
{
"login": "lksnmnn",
"name": "Lukas Neumann",
"avatar_url": "https://avatars.githubusercontent.com/u/4983285?v=4",
"profile": "lksnmnn.com",
"contributions": [
"doc",
"code",
"test"
]
},
{
"login": "dbachrach",
"name": "Dustin Bachrach",
"avatar_url": "https://avatars.githubusercontent.com/u/45016?v=4",
"profile": "dbachrach.com",
"contributions": [
"code",
"doc"
]
},
{
"login": "ashikka",
"name": "Ashikka Gupta",
"avatar_url": "https://avatars.githubusercontent.com/u/58368421?v=4",
"profile": "https://github.com/ashikka",
"contributions": [
"code",
"test"
]
},
{
"login": "deini",
"name": "Daniel Almaguer",
"avatar_url": "https://avatars.githubusercontent.com/u/2752665?v=4",
"profile": "https://github.com/deini",
"contributions": [
"doc"
]
},
{
"login": "igeligel",
"name": "Kevin Peters",
"avatar_url": "https://avatars.githubusercontent.com/u/12736734?v=4",
"profile": "https://www.kevinpeters.net/about/",
"contributions": [
"doc"
]
},
{
"login": "prisis",
"name": "Daniel Bannert",
"avatar_url": "https://avatars.githubusercontent.com/u/2716058?v=4",
"profile": "http://anolilab.de",
"contributions": [
"code"
]
},
{
"login": "benjakugler96",
"name": "Benja Kugler",
"avatar_url": "https://avatars.githubusercontent.com/u/53273645?v=4",
"profile": "https://benjakugler96.github.io/",
"contributions": [
"code"
]
},
{
"login": "esemeniuc",
"name": "Eric Semeniuc",
"avatar_url": "https://avatars.githubusercontent.com/u/3838856?v=4",
"profile": "https://semeniuc.ml/",
"contributions": [
"test",
"code"
]
}
],
"contributorsPerLine": 7,
"skipCi": true
}
}

View File

@@ -1,53 +0,0 @@
node_modules
reports
*.log
.nyc_output
**/coverage
tsconfig.tsbuildinfo
**/.blitz/**
**/.next/**
**/dist/**
**/.vercel/**
**/.test*
/examples/auth2
prettier.config.*
jest.config.*
jest.setup.*
babel.config.*
eslint.config.*
/__mocks__
/__fixturse
/assets
/patches
/rfc-docs
/scripts
/types
/recipes/*/templates
/packages/generator/templates
/packages/cli/lib
/packages/babel-preset/src/fix-node-file-trace/tests/**
/test/integration/**/out/**
/nextjs/packages/create-next-app
// COPIED FROM nextjs/.eslintignore
/nextjs/**/.next/**
/nextjs/**/_next/**
/nextjs/**/dist/**
/nextjs/examples/**
/nextjs/packages/next/bundles/webpack/packages/*.runtime.js
/nextjs/packages/next/compiled/**/*
/nextjs/packages/react-refresh-utils/**/*.js
/nextjs/packages/react-dev-overlay/lib/**
/nextjs/**/__tmp__/**
/nextjs/.github/actions/next-stats-action/.work
/nextjs/packages/next-codemod/transforms/__testfixtures__/**/*
/nextjs/packages/next-codemod/transforms/__tests__/**/*
/nextjs/packages/next-codemod/**/*.js
/nextjs/packages/next-codemod/**/*.d.ts
/nextjs/packages/next-env/**/*.d.ts
/nextjs/test/integration/async-modules/**
/nextjs/test/integration/eslint/**
/nextjs/test-timings.json

View File

@@ -1,19 +1,14 @@
module.exports = {
parser: "babel-eslint",
env: {
browser: true,
commonjs: true,
es6: true,
node: true,
},
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: 6,
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
project: `./tsconfig.json`,
},
plugins: ["import", "unicorn", "simple-import-sort"],
plugins: ["@typescript-eslint", "import", "unicorn", "simple-import-sort"],
extends: ["react-app"],
rules: {
"react/react-in-jsx-scope": "off", // React is always in scope with Blitz
@@ -28,6 +23,13 @@ module.exports = {
case: "kebabCase",
},
],
"@typescript-eslint/no-floating-promises": "error",
// note you must disable the base rule as it can report incorrect errors
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": ["error"],
// note you must disable the base rule as it can report incorrect errors
"no-redeclare": "off",
"@typescript-eslint/no-redeclare": ["error"],
"simple-import-sort/imports": [
"warn",
{
@@ -49,63 +51,20 @@ module.exports = {
},
],
},
ignorePatterns: [
"packages/cli/",
"packages/generator/templates",
".eslintrc.js",
"recipes/*/templates",
],
overrides: [
{
files: ["**/*.ts", "**/*.tsx"],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: 6,
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
project: `./tsconfig.eslint.json`,
},
plugins: ["@typescript-eslint"],
rules: {
"@typescript-eslint/no-floating-promises": "error",
// note you must disable the base rule as it can report incorrect errors
"no-use-before-define": "off",
// "@typescript-eslint/no-use-before-define": ["error"],
// note you must disable the base rule as it can report incorrect errors
"no-redeclare": "off",
"@typescript-eslint/no-redeclare": ["error"],
},
},
{
files: ["examples/**", "recipes/**"],
files: ["examples/**", "packages/gui/**", "recipes/**"],
rules: {
"import/no-default-export": "off",
"unicorn/filename-case": "off",
"@typescript-eslint/no-floating-promises": "off",
},
},
{
files: ["examples/**"],
plugins: ["cypress"],
parserOptions: {
project: null,
},
env: {
"cypress/globals": true,
},
rules: {
"simple-import-sort/imports": "off",
},
},
{
files: ["packages/cli/src/commands/**/*"],
rules: {
"require-await": "off",
},
},
{
files: ["test/**", "**/__fixtures__/**"],
rules: {
"import/no-default-export": "off",
"require-await": "off",
"unicorn/filename-case": "off",
},
},
],
}

6
.github/CODEOWNERS vendored
View File

@@ -2,7 +2,7 @@
* @flybayer
# packages/cli/**/* @aem, @flybayer
# packages/generator/**/* @aem @flybayer
packages/cli/**/* @aem, @flybayer
packages/generator/**/* @aem @flybayer
packages/generator/templates**/* @flybayer
# packages/installer/**/* @aem @flybayer
packages/installer/**/* @aem @flybayer

23
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,23 @@
---
name: Bug report
about: Something is not working right. Or error messages are unclear.
title: ''
labels: ''
assignees: ''
---
### What is the problem?
### Steps to Reproduce
1.
### Versions
```
output of `blitz --version --verbose`
```
### Other
Please include applicable logs and screenshots that show your problem.

View File

@@ -1,48 +0,0 @@
name: Bug Report
description: Something is not working right. Or error messages are unclear.
labels: "kind/bug, status/triage"
body:
- type: markdown
attributes:
value: Thanks for taking the time to file a bug report! Please fill out this form as completely as possible.
- type: textarea
attributes:
label: What is the problem?
validations:
required: true
- type: textarea
attributes:
label: "Paste all your error logs here:"
value: |
```
PASTE_HERE (leave the ``` marks)
```
validations:
required: true
- type: textarea
attributes:
label: "Paste all relevant code snippets here:"
value: |
```
PASTE_HERE (leave the ``` marks)
```
validations:
required: true
- type: textarea
attributes:
label: What are detailed steps to reproduce this?
value: "1."
validations:
required: true
- type: textarea
attributes:
label: "Run `blitz -v` and paste the output here:"
value: |
```
PASTE_HERE (leave the ``` marks)
```
validations:
required: true
- type: textarea
attributes:
label: "Please include below any other applicable logs and screenshots that show your problem:"

View File

@@ -2,7 +2,7 @@
name: Feature/change request
about: Something new or better!
title: ""
labels: "status/triage"
labels: ""
assignees: ""
---

View File

@@ -1,19 +1,10 @@
<!--
Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible please:
- Link issue via "Closes #[issue_number]
- Choose & follow the right checklist for the change that you're making:
-->
Closes: ?
Closes: ??
### What are the changes and their implications?
## Bug Checklist
### Checklist
- [ ] Integration test added (see [test docs](https://blitzjs.com/docs/contributing#running-tests) if needed)
- [ ] Changes covered by tests (tests added if needed)
- [ ] PR submitted to [blitzjs.com](https://github.com/blitz-js/blitzjs.com) for any user facing changes
## Feature Checklist
- [ ] Integration test added (see [test docs](https://blitzjs.com/docs/contributing#running-tests) if needed)
- [ ] Documentation added/updated (submit PR to [blitzjs.com repo](https://github.com/blitz-js/blitzjs.com))
<!-- IMPORTANT: Make sure to check the "Allow edits from maintainers" box below this window -->

View File

@@ -1,13 +1,9 @@
name: Size Check
name: CI
on:
pull_request:
branches: [master, canary]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
name: Compressed Size
@@ -15,8 +11,16 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: Use Node and Yarn
uses: actions/setup-node@v2
with:
node-version: "14"
- name: Install dependencies
run: |
yarn && yarn build
env:
CI: true
- name: Count size
uses: preactjs/compressed-size-action@v2
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
exclude: "{./nextjs/**}"

View File

@@ -1,14 +1,14 @@
# https://github.com/vercel/next.js/commits/canary/.github/workflows/build_test_deploy.yml
name: CI
on:
push:
branches:
- master
- canary
pull_request:
types: [opened, synchronize]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
branches:
- master
- canary
jobs:
lint:
@@ -30,42 +30,32 @@ jobs:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
/home/runner/.cache/Cypress
C:\Users\runneradmin\AppData\Local\Cypress\Cache
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v4-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
${{ runner.os }}-${{ runner.node_version}}-yarn-v4-
- name: Install dependencies
run: yarn install --frozen-lockfile --silent
env:
CI: true
- name: manypkg lint
run: yarn manypkg check
env:
CI: true
- name: Build next.js
run: yarn build:nextjs
env:
CI: true
- name: yarn lint
run: yarn lint
env:
CI: true
build:
name: Build
runs-on: ubuntu-latest
env:
NEXT_TELEMETRY_DISABLED: 1
outputs:
docsChange: ${{ steps.docs-change.outputs.DOCS_CHANGE }}
build_and_test_pkgs:
name: Packages Tests
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node_version: [12, 14]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 25
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: "14"
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
node-version: ${{ matrix.node_version }}
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
@@ -75,65 +65,40 @@ jobs:
with:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
/home/runner/.cache/Cypress
C:\Users\runneradmin\AppData\Local\Cypress\Cache
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v4-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
- run: yarn install --frozen-lockfile --check-files
- name: Build Packages
run: yarn build
- run: node run-tests.js --timings --write-timings -g 1/1
working-directory: nextjs
- name: Check docs only change
working-directory: nextjs
run: echo ::set-output name=DOCS_CHANGE::$(node skip-docs-change.js echo 'not-docs-only-change')
id: docs-change
- run: echo ${{steps.docs-change.outputs.DOCS_CHANGE}}
- uses: actions/cache@v2
id: cache-build
with:
path: ./*
key: ${{ github.sha }}
testBlitzPackages:
name: Blitz - Test Packages
needs: build
runs-on: ubuntu-latest
env:
NEXT_TELEMETRY_DISABLED: 1
steps:
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
with:
path: ./*
key: ${{ github.sha }}
${{ runner.os }}-${{ runner.node_version}}-yarn-v4-
- name: Install dependencies
run: yarn install --frozen-lockfile --silent
env:
CI: true
- name: Setup kernel to increase watchers
if: matrix.os == 'ubuntu-latest'
run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
- name: Build packages
run: yarn build
env:
CI: true
- name: Test Blitz Packages
run: yarn testonly:packages
env:
CI: true
testBlitzExamples:
build_and_test_examples:
timeout-minutes: 30
name: Blitz - Test Example Apps
name: Example Apps Tests
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node_version: [12, 14]
runs-on: ${{ matrix.os }}
env:
NEXT_TELEMETRY_DISABLED: 1
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 25
- name: Use Node.js
uses: actions/setup-node@v2
with:
node-version: "14"
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
node-version: ${{ matrix.node_version }}
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
@@ -143,237 +108,23 @@ jobs:
with:
path: |
${{ steps.yarn-cache-dir-path.outputs.dir }}
**/node_modules
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v13-${{ hashFiles('yarn.lock') }}
/home/runner/.cache/Cypress
C:\Users\runneradmin\AppData\Local\Cypress\Cache
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v4-${{ hashFiles('yarn.lock') }}
restore-keys: |
${{ runner.os }}-${{ runner.node_version}}-yarn-v13-
- run: yarn install --frozen-lockfile --check-files
# - run: yarn cpy node_modules/.blitz packages/core/node_modules/.blitz
# if: matrix.os == 'windows-latest'
- name: Build Packages
run: yarn build
# Needed to get cypress binary
- run: yarn cypress install
- name: Install sass
run: yarn install -W sass
${{ runner.os }}-${{ runner.node_version}}-yarn-v4-
- name: Install dependencies
run: yarn install --frozen-lockfile --silent
env:
CI: true
- name: Setup kernel to increase watchers
if: matrix.os == 'ubuntu-latest'
run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
- name: Build packages
run: yarn build
env:
CI: true
- name: Test examples
run: yarn testonly:examples
env:
CI: true
checkPrecompiled:
name: Check Pre-compiled
defaults:
run:
working-directory: nextjs
runs-on: ubuntu-latest
needs: build
env:
NEXT_TELEMETRY_DISABLED: 1
steps:
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
with:
path: ./*
key: ${{ github.sha }}
- run: ./check-pre-compiled.sh
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testUnit:
name: Nextjs - Test Unit
defaults:
run:
working-directory: nextjs
runs-on: ubuntu-latest
needs: build
env:
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_JOB: 1
HEADLESS: true
steps:
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
with:
path: ./*
key: ${{ github.sha }}
- run: node run-tests.js --timings --type unit -g 1/1
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testIntegrationBlitz:
name: Blitz - Test Integration
runs-on: ubuntu-latest
needs: build
env:
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_JOB: 1
HEADLESS: true
strategy:
fail-fast: false
steps:
- run: echo ${{needs.build.outputs.docsChange}}
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
with:
path: ./*
key: ${{ github.sha }}
# TODO: remove after we fix watchpack watching too much
- run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
- run: xvfb-run node nextjs/run-tests.js -c 3
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testIntegration:
name: Nextjs - Test Integration
defaults:
run:
working-directory: nextjs
runs-on: ubuntu-latest
needs: build
env:
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_JOB: 1
HEADLESS: true
strategy:
fail-fast: false
matrix:
group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
steps:
- run: echo ${{needs.build.outputs.docsChange}}
working-directory: ./
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
with:
path: ./*
key: ${{ github.sha }}
# TODO: remove after we fix watchpack watching too much
- run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
- run: xvfb-run node run-tests.js --timings -g ${{ matrix.group }}/20 -c 3
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testElectron:
name: Nextjs - Test Electron
defaults:
run:
working-directory: nextjs
runs-on: ubuntu-latest
needs: build
env:
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_JOB: 1
HEADLESS: true
TEST_ELECTRON: 1
steps:
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
with:
path: ./*
key: ${{ github.sha }}
# TODO: remove after we fix watchpack watching too much
- run: echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
- run: cd test/integration/with-electron/app && yarn
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
- run: xvfb-run node run-tests.js test/integration/with-electron/test/index.test.js
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testsPass:
name: thank you, next
runs-on: ubuntu-latest
needs:
[
checkPrecompiled,
testIntegration,
testIntegrationBlitz,
testUnit,
testBlitzPackages,
testBlitzExamples,
]
steps:
- run: exit 0
testFirefox:
name: Nextjs - Test Firefox (production)
defaults:
run:
working-directory: nextjs
runs-on: ubuntu-latest
needs: build
env:
HEADLESS: true
BROWSER_NAME: "firefox"
NEXT_TELEMETRY_DISABLED: 1
steps:
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
with:
path: ./*
key: ${{ github.sha }}
- run: node run-tests.js -c 1 test/integration/production/test/index.test.js
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testSafari:
name: Nextjs - Test Safari (production)
defaults:
run:
working-directory: nextjs
runs-on: ubuntu-latest
needs: build
env:
BROWSERSTACK: true
BROWSER_NAME: "safari"
NEXT_TELEMETRY_DISABLED: 1
SKIP_LOCAL_SELENIUM_SERVER: true
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
steps:
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
with:
path: ./*
key: ${{ github.sha }}
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js -c 1 test/integration/production/test/index.test.js'
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
testSafariOld:
name: Nextjs - Test Safari 10.1 (nav)
defaults:
run:
working-directory: nextjs
runs-on: ubuntu-latest
needs: [build, testSafari]
env:
BROWSERSTACK: true
LEGACY_SAFARI: true
BROWSERNAME: "safari"
NEXT_TELEMETRY_DISABLED: 1
SKIP_LOCAL_SELENIUM_SERVER: true
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
steps:
- uses: actions/cache@v2
if: ${{needs.build.outputs.docsChange != 'docs only change'}}
id: restore-build
with:
path: ./*
key: ${{ github.sha }}
- run: '[[ -z "$BROWSERSTACK_ACCESS_KEY" ]] && echo "Skipping for PR" || node run-tests.js test/integration/production-nav/test/index.test.js'
if: ${{needs.build.outputs.docsChange != 'docs only change'}}

8
.gitignore vendored
View File

@@ -2,6 +2,7 @@
.DS_Store
.idea
.jest-*
lib
node_modules
reports
*.log
@@ -24,10 +25,3 @@ dist
.tsbuildinfo
.nvmrc
**/.test*
examples/auth2
.idea
.ultra.cache.json
db.sqlite-journal
test/integration/**/db.json
test/**/*/out
.blitz**

1
.husky/.gitignore vendored
View File

@@ -1 +0,0 @@
_

View File

@@ -1,5 +0,0 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
yarn lint-staged
yarn pretty-quick --staged

View File

@@ -4,7 +4,7 @@
.log
.DS_Store
.jest-*
packages/cli/lib
lib
node_modules
reports
*.log
@@ -19,7 +19,3 @@ bin
!packages/blitz/src/bin
packages/generator/templates/**
.github/ISSUE_TEMPLATE/bug_report.md
nextjs/packages/next/compiled/**
// Because file from nextjs upstream isn't formatted properly
nextjs/packages/next/build/webpack-config.ts

View File

@@ -1,35 +1,3 @@
# Contributing
[Read the Contributing Guide at Blitzjs.com](https://blitzjs.com/docs/contributing)
## Notes For Core Team
### Syncing Next.js Fork
1. Run `yarn push-nextjs`
- If it fails with an error of `git-subrepo: Can't commit: 'subrepo/nextjs' doesn't contain upstream HEAD:`, then run `yarn push-nextjs --force` (see https://github.com/ingydotnet/git-subrepo/issues/530)
2. Create new git branch for the upgrade
3. In the forked repo (https://github.com/blitz-js/next.js), run:
1. `git pull`
2. `git fetch --all`
3. `git merge v10.2.0` (change the version to be the version you are updating to)
4. Run `rm -rf examples && git add examples`
5. To resolve conflict with their version for a path, like docs, run this:
- `git checkout --theirs docs && git add docs`
6. Resolve all merge conflicts and complete merge
7. Run `yarn` and make sure all builds complete
8. Run `yarn lint` and fix any issues
9. `git push`
4. Run `yarn pull next-nextjs`
5. Run `yarn`
6. Run `yarn manypkg check` and optionally `yarn manypkg fix` to fix any issues
7. Under `nextjs/`, run `./check-pre-compiled.sh` and commit the changes
8. Run `yarn build:nextjs`
9. Run `yarn lint` - fix any issues
10. Run `yarn build` - fix any issues
11. Run `yarn test:nextjs-size` and update tests if there are any failures
12. Open PR and fix any failing tests
13. Update any references to nextjs in new code including imports like `next/image`, etc.
14. Any doc updates needed?
15. Merge PR
16. `yarn push-nextjs`

View File

@@ -1,3 +0,0 @@
# Contributor over time
[![Contributor over time](https://contributor-graph-api.apiseven.com/contributors-svg?chart=contributorOverTime&repo=blitz-js/blitz)](https://www.apiseven.com/en/contributor-graph?chart=contributorOverTime&repo=blitz-js/blitz)

11
GOVERNANCE.md Normal file
View File

@@ -0,0 +1,11 @@
# Blitz.js Governance
_From Brandon Bayer (@flybayer), the creator:_
Currently at this very early stage it's basically a [BDFL situation](https://opensource.guide/leadership-and-governance/#what-are-some-of-the-common-governance-structures-for-open-source-projects), with me having the final say in decisions.
However we will move away from BDFL to something that looks more like Ember.js. It's extremely important to me (Brandon) that Blitz.js is a long-term, sustainable, and community-run project.
I would love some mentorship from people with experience in large open-source projects on making this transition.
Also, it's possible I will create one or more business around Blitz, perhaps similar to how Taylor Otwell has around Laravel, but Blitz itself will always remain a separate community-run project.

View File

@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2021 Brandon Bayer
Copyright (c) 2020 Brandon Bayer
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

1
MAINTAINERS.md Normal file
View File

@@ -0,0 +1 @@
This document has moved here: https://blitzjs.com/docs/maintainers

3
MANIFESTO.md Normal file
View File

@@ -0,0 +1,3 @@
# Manifesto
[The Manifesto has been moved to Blitzjs.com](https://blitzjs.com/docs/manifesto)

257
README.md
View File

@@ -6,7 +6,7 @@
<img alt="" src="https://img.shields.io/badge/Join%20our%20community-6700EB.svg?style=for-the-badge&labelColor=000000&logoWidth=20&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAQ9SURBVHgB7d3dVdtAEIbhcSpICUoH0IEogQqSVBBSAU4FSSpIOoAORAfQgSghHXzZ1U/YcMD4R9rZmf2ec3y448LyiNf27iLiGIAmPLrweC9Un3DhrzG6EarLNP09nlwJ1SOZ/lQr5N80/S/p2QMVCBf5N17XCfm1Y/rBHqjAG9PPHvBsz+mf9WAP+HLA9M/YA14cOP2payH7jpj+VCtk1wnTP+vj7xCy6cTpn7EHLMLp059iD1iD8eveJbVCNsSLheX1YA/YgOWnf8YeKB3Wmf7Ud6Fy4f/FHmtpxbl3YlC4MJ/Cj0bWdwPnPbARg+L0S54XQHS32WwuxClzd4CM0z9rPfeAuTtA5ulPXYQ7wZ04Y+oOoDD9KZc9YOoOoDj9s4dwFzgXR6w1wIPoOvPWA9buAHEJ173o3gWiy3AnuBUHLEbgmYwvAk1/wuM8vAgexThzbwPDkx7/DHwVXfFOxP2GmsKd4Ab6zPeAyU8CI7AHFmH2BRCBPXAyk18GzUrqAXCTiR4ssyj0VFw/oCU8+e+RZ33AWz6KMaYbIIWxB+JSLs1bsbkeMN0AqakHvoku9oA2sAfqBvbAQdw0QArsgb25aYBUQT3QgT2gB+yBuqGcHij2UCqXDZACe2Anlw2QYg/QAOyBuoE98CL3DZDCuK4/rh/Q7oGL6U+TOvcNkJoijN8X1C48+T+g75eQDrAH/qmqAVJgDwyqaoAUe4AGYA/UDZX3QLUNkEIZPRCd5+6BahsgVUgPROwBTSijB7jpVAvGHriHvmw9wAZ4BpX1ABvgmakHtPcbRuwBTWAPULgAV9D/jKDY9YRvwvgEaurD44uQHvAol7qBW7WKluVtIHiUS7GyvA0s6CiXDnxrpQfsgbqBS7GKk/2jYHCrVlGyfxTMrVo0ALdq1Q3sgSKofh0M9oA61a+D2QM0AHugbmAPqClmSRjK2apVVQ8UsySsoK1aHdgDesCtWnUDeyCrIpeFg1u3sylyWTi3btMA7IG6gT2wuuK3hoE9sKrit4YVslWLPaAN7IG6ocKt2zmY2h4O9sDiTG0PZw/QANy6XTewBxZj9ogYVHy025LMHhEz9cBn0We6B0yfERReBLfhx0/R1YQHPx/QBPbA0VwcEwf2wNFcHBPHHjiem3MC2QPHcXdSaJjA+KfgTPQ8hhfjBzHC40mhlzJ+Xq9lK4a4PCs43AVaGTed5mZq+iOXZwWHi3AnOj2wFWNcnxYe7gTxLtBKHuamP/J+Wnh8a5irB7ZC5Yk9gPX1QuXC+usHWqGyhYvUYR0a7zboUOFCNVhnk0krZAOW7wFOvzXhom2xnEbIHizTA1wEYhWW6YFGyC6c1gOcfg9wfA80Qj7g8B7g9HuCww+haIR8wf49wOn3Cvv9k8tGyC/s7gFOv3fY3QONkH+v9MBWqB7PeqDn9FcIT//kcitUn6kHOu/T/xfWzlQy3dEHhwAAAABJRU5ErkJggg==">
</a>
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<a aria-label="All Contributors" href="#contributors-"><img alt="" src="https://img.shields.io/badge/all_contributors-304-17BB8A.svg?style=for-the-badge&labelColor=000000"></a>
<a aria-label="All Contributors" href="#contributors-"><img alt="" src="https://img.shields.io/badge/all_contributors-209-17BB8A.svg?style=for-the-badge&labelColor=000000"></a>
<!-- ALL-CONTRIBUTORS-BADGE:END -->
<a aria-label="License" href="https://github.com/blitz-js/blitz/blob/canary/LICENSE">
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
@@ -22,15 +22,15 @@
<h1 align="center">The Fullstack React Framework</h1>
<h5 align="center">"Zero-API" Data Layer — Built on Next.js — Inspired by Ruby on Rails</h3>
<h3 align="center">Makes you far more productive than you ever dreamed was possible 😉</h3>
<h3 align="center"><a href="https://blitzjs.com" target="_blank">Read the Documentation</a></h3>
<br>
“Zero-API” data layer **lets you import server code directly into your React components** instead of having to manually add API endpoints and do client-side fetching and caching.
New Blitz apps come with **all the boring stuff already set up for you!** Like ESLint, Prettier, Jest, user sign up, log in, and password reset.
Provides **helpful defaults and conventions** for things like routing, file structure, and authentication while also being extremely flexible.
Includes everything you need for production apps. **Everything end-to-end from the database to the frontend.**
Blitz brings back the **simplicity and conventions** of server-rendered frameworks like Ruby on Rails while preserving everything we love about React and client-side rendering!
<br>
@@ -49,7 +49,7 @@ _You can alternatively use [`npx`](https://www.npmjs.com/package/npx)_
1. `blitz new myAppName`
2. `cd myAppName`
3. `blitz dev`
4. View your brand new app at http://localhost:3000
4. View your baby app at http://localhost:3000
<br><br>
@@ -57,10 +57,32 @@ _You can alternatively use [`npx`](https://www.npmjs.com/package/npx)_
<img alt="Bytes Newsletter" src="https://files-8wtskjofb.vercel.app/smarter-16x1.jpg">
</a>
<br><br>
![Architecture diagram](https://blitzjs.now.sh/img/architecture-diagram.png)
<br><br>
**Features:**<br>
⚡️ Built on Next.js<br>
⚡️ Don't have to build an API for client-side rendering<br>
⚡️ Client-side rendering, Server-side rendering, and fully static pages all in the same app<br>
⚡️ Full TypeScript support with static, end-to-end typing (no code generation step needed like with GraphQL)<br>
⚡️ React Concurrent Mode enabled<br>
⚡️ Database/ORM agnostic, but Prisma 2 is default<br>
⚡️ CLI with code scaffolding, Rails-style console REPL, etc<br>
⚡️ GraphQL Ready<br>
⚡️ Deploy serverless or serverful<br>
⚡️ Highly secure authentication <br>
⚡️ Authorization you can use on both server and client<br>
⚡️ Recipes for easily adding libraries like Tailwind, CSS-in-JS, etc.<br>
**Other key features coming:**<br>
⚡️ Model validation you can use on both server and client<br>
⚡️ React native support<br>
⚡️ GUI so you don't have to use the CLI<br>
<br>
### The Foundational Principles
@@ -105,57 +127,36 @@ Your financial contributions help ensure Blitz continues to be developed and mai
### 🌱 Seedling Sponsors
<table>
<tr>
<td><a aria-label="React Bricks" href="https://reactbricks.com/?utm_source=blitzjs&utm_medium=sponsorship&utm_campaign=blitzjs_sponsorship">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/reactbricks_icon.svg" width="40px"/>
</a></td>
<td><a aria-label="Andreas Asprou" href="https://andreas.fyi">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/andreas.jpg" width="40px"/>
</a></td>
<td><a aria-label="Robert Malko" href="https://github.com/malkomalko">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/rob_blitz.jpg" width="40px"/>
</a></td>
<td><a aria-label="Digas" href="https://digsas.com">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/digsas.svg" width="40px"/>
</a></td>
<td><a aria-label="userTrack" href="https://www.usertrack.net/?ref=blitzjs">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/usertrack.png" width="40px"/>
</a></td>
</tr>
</table>
<a aria-label="React Bricks" href="https://reactbricks.com/?utm_source=blitzjs&utm_medium=sponsorship&utm_campaign=blitzjs_sponsorship">
<img alt="" src="https://reactbricks.com/reactbricks_icon.svg" width="30px"/>
</a>
<a aria-label="Andreas Asprou" href="https://andreas.fyi">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/andreas.jpg" width="30px"/>
</a>
### 🥉 Bronze Sponsors
<table>
<tr>
<td><a aria-label="Render.com" href="https://render.com?utm_source=BlitzJS&utm_medium=sponsorship&utm_campaign=BlitzJS_Sponsorship_2020">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/render-logo-color2.png" width="200px">
</a></td>
<td><a aria-label="RIT" href="https://rit-inc.co.jp/?utm_source=BlitzJS&utm_medium=sponsorship&utm_campaign=BlitzJS_Sponsorship_2021">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/rit_logo.png" width="200px">
</a></td>
</tr>
</table>
<a aria-label="Render.com" href="https://render.com?utm_source=BlitzJS&utm_medium=sponsorship&utm_campaign=BlitzJS_Sponsorship_2020">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/render-logo-color2.png" width="110px">
</a>
### 🥈 Silver Sponsors
<a aria-label="Fauna" href="https://dashboard.fauna.com/accounts/register?utm_source=BlitzJS&utm_medium=sponsorship&utm_campaign=BlitzJS_Sponsorship_2020">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/Fauna_Logo_Blue.png" width="300px">
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/Fauna_Logo_Blue.png" width="200px">
</a>
### 🏆 Gold Sponsors
<a aria-label="Your Company" href="#">
<img alt="" src="https://dummyimage.com/1000x330/efe8ff/000000.png&text=Your+Logo+Here" width="400px">
<img alt="" src="https://dummyimage.com/1000x330/efe8ff/000000.png&text=Your+Logo+Here" width="300px">
</a>
### 💎 Diamond Sponsors
<a aria-label="Your Company" href="#">
<img alt="" src="https://dummyimage.com/1000x330/efe8ff/000000.png&text=Your+Logo+Here" width="500px">
<img alt="" src="https://dummyimage.com/1000x330/efe8ff/000000.png&text=Your+Logo+Here" width="400px">
</a>
<br>
@@ -176,15 +177,15 @@ Your financial contributions help ensure Blitz continues to be developed and mai
## Maintainers (Level 2) ✨
_Code ownership, pull request approvals and merging, etc_ (see [Maintainers L2](https://blitzjs.com/docs/maintainers#level-2-maintainers))
_Code ownership, pull request approvals and merging, etc_ (see [MAINTAINERS.md](./MAINTAINERS.md))
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="https://github.com/aem"><img src="https://avatars0.githubusercontent.com/u/1909883?v=4" width="100px;" alt=""/><br /><sub><b>Adam Markon</b></sub></a><br />CLI</td>
<td align="center"><a href="http://robdrosenberg.com"><img src="https://avatars0.githubusercontent.com/u/20813991?v=4" width="100px;" alt=""/><br /><sub><b>Robert Rosenberg</b></sub></a><br />Website/Docs</td>
<td align="center"><a href="http://simonknott.de"><img src="https://avatars1.githubusercontent.com/u/14912729?v=4" width="100px;" alt=""/><br /><sub><b>Simon Knott</b></sub></a><br />SuperJSON</td>
<td align="center"><a href="https://juanm04.com"><img src="https://avatars0.githubusercontent.com/u/16712703?v=4" width="100px;" alt=""/><br /><sub><b>Juan Martín Seery</b></sub></a><br />Website/Docs</td>
</tr>
</table>
<!-- markdownlint-enable -->
@@ -194,41 +195,26 @@ _Code ownership, pull request approvals and merging, etc_ (see [Maintainers L2](
## Maintainers (Level 1) ✨
_Issue triage, pull request triage, community encouragement and moderation, etc_ (see [Maintainers L1](https://blitzjs.com/docs/maintainers#level-1-maintainers))
_Issue triage, pull request triage, community encouragement and moderation, etc_ (see [MAINTAINERS.md](./MAINTAINERS.md))
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="https://corey-brown.com"><img src="https://avatars1.githubusercontent.com/u/12791148?v=4" width="100px;" alt=""/><br /><sub><b>Corey Brown</b></sub></a></td>
<td align="center"><a href="http://jeremyliberman.com/"><img src="https://avatars3.githubusercontent.com/u/2754163?v=4" width="100px;" alt=""/><br /><sub><b>Jeremy Liberman</b></td>
<td align="center"><a href="http://jagascript.com"><img src="https://avatars0.githubusercontent.com/u/4562878?v=4" width="100px;" alt=""/><br /><sub><b>Jaga Santagostino</b></sub></a></td>
<td align="center"><a href="https://twitter.com/nitaking_"><img src="https://avatars2.githubusercontent.com/u/10850034?v=4" width="100px;" alt=""/><br /><sub><b>Satoshi Nitawaki</b></sub></a></td>
<td align="center"><a href="https://twitter.com/sandulat"><img src="https://avatars2.githubusercontent.com/u/7345874?v=4" width="100px;" alt=""/><br /><sub><b>Alexandru Stratulat</b></sub></a></td>
<td align="center"><a href="https://github.com/engelkes-finstreet"><img src="https://avatars0.githubusercontent.com/u/36962022?s=460&u=34cfc4a3d6da0a87026f6068c371779c68daa3a2&v=4" width="100px;" alt=""/><br /><sub><b>Patrick Engelkes</b></sub></a></td>
<td align="center"><a href="https://twitter.com/myrondavis"><img src="https://avatars2.githubusercontent.com/u/1430136?v=4" width="100px;" alt=""/><br /><sub><b>Myron Davis</b></sub></a></td>
<td align="center"><a href="https://twitter.com/NaReto1125_"><img src="https://avatars.githubusercontent.com/reo777" width="100px;" alt=""/><br /><sub><b>Reo Ishiyama</b></sub></a></td>
<td align="center"><a href="https://github.com/malkomalko"><img src="https://avatars.githubusercontent.com/malkomalko" width="100px;" alt=""/><br /><sub><b>Robert Malko</b></sub></a></td>
</tr>
<tr>
<td align="center">
<a href="https://kevinlangleyjr.com">
<img
src="https://avatars.githubusercontent.com/u/877634?v=4"
width="100px;"
alt=""
/><br />
<sub>
<b>Kevin Langley Jr.</b>
</sub>
</a>
</td>
<td align="center">
<a href="https://mina.ca">
<img src="https://avatars.githubusercontent.com/mabadir" width="100px;" alt="Mina Abadir avatar" /><br />
<sub>
<b>Mina Abadir</b>
</sub>
</a>
</td>
<td align="center"><a href="https://twitter.com/jdavenport97"><img src="https://avatars2.githubusercontent.com/u/1329874?v=4" width="100px;" alt=""/><br /><sub><b>Jamie Davenport</b></sub></a></td>
<td align="center"><a href="https://twitter.com/myrondavis"><img src="https://avatars2.githubusercontent.com/u/1430136?v=4" width="100px;" alt=""/><br /><sub><b>Myron Davis</b></sub></a></td>
<td align="center"><a href="https://flavioander.com/"><img src="https://avatars2.githubusercontent.com/u/14948074?s=460&u=31d7ea58b5c5cd9f724d684ed578f68896c4af71&v=4" width="100px;" alt=""/><br /><sub><b>Flavio Andrade</b></sub></a></td>
<td align="center"><a href="https://twitter.com/NaReto1125_"><img src="https://avatars.githubusercontent.com/reo777" width="100px;" alt=""/><br /><sub><b>Reo Ishiyama</b></sub></a></td>
<td align="center"><a href="https://github.com/malkomalko"><img src="https://avatars.githubusercontent.com/malkomalko" width="100px;" alt=""/><br /><sub><b>Robert Malko</b></sub></a></td>
</tr>
</table>
<!-- markdownlint-enable -->
@@ -246,7 +232,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<!-- markdownlint-disable -->
<table>
<tr>
<td align="center"><a href="https://twitter.com/flybayer"><img src="https://avatars3.githubusercontent.com/u/8813276?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brandon Bayer</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=flybayer" title="Code">💻</a> <a href="#content-flybayer" title="Content">🖋</a> <a href="#ideas-flybayer" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/blitz-js/blitz/pulls?q=is%3Apr+reviewed-by%3Aflybayer" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/blitz-js/blitz/commits?author=flybayer" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=flybayer" title="Documentation">📖</a></td>
<td align="center"><a href="https://twitter.com/flybayer"><img src="https://avatars3.githubusercontent.com/u/8813276?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brandon Bayer</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=flybayer" title="Code">💻</a> <a href="#content-flybayer" title="Content">🖋</a> <a href="#ideas-flybayer" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/blitz-js/blitz/pulls?q=is%3Apr+reviewed-by%3Aflybayer" title="Reviewed Pull Requests">👀</a></td>
<td align="center"><a href="https://medium.com/@ryardley"><img src="https://avatars0.githubusercontent.com/u/1256409?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rudi Yardley</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ryardley" title="Code">💻</a> <a href="#ideas-ryardley" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/blitz-js/blitz/pulls?q=is%3Apr+reviewed-by%3Aryardley" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/blitz-js/blitz/commits?author=ryardley" title="Tests">⚠️</a></td>
<td align="center"><a href="https://merelinguist.me"><img src="https://avatars3.githubusercontent.com/u/24858006?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dylan Brookes</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=merelinguist" title="Code">💻</a> <a href="#ideas-merelinguist" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/blitz-js/blitz/pulls?q=is%3Apr+reviewed-by%3Amerelinguist" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/blitz-js/blitz/commits?author=merelinguist" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=merelinguist" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/aem"><img src="https://avatars0.githubusercontent.com/u/1909883?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Adam Markon</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=aem" title="Code">💻</a> <a href="#ideas-aem" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/blitz-js/blitz/pulls?q=is%3Apr+reviewed-by%3Aaem" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/blitz-js/blitz/commits?author=aem" title="Tests">⚠️</a> <a href="#maintenance-aem" title="Maintenance">🚧</a></td>
@@ -265,7 +251,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
</tr>
<tr>
<td align="center"><a href="http://gielcobben.com"><img src="https://avatars0.githubusercontent.com/u/2663212?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Giel</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=gielcobben" title="Code">💻</a></td>
<td align="center"><a href="http://jeremyliberman.com/"><img src="https://avatars3.githubusercontent.com/u/2754163?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jeremy Liberman</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=MrLeebo" title="Code">💻</a> <a href="#maintenance-MrLeebo" title="Maintenance">🚧</a> <a href="https://github.com/blitz-js/blitz/commits?author=MrLeebo" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=MrLeebo" title="Documentation">📖</a></td>
<td align="center"><a href="http://jeremyliberman.com/"><img src="https://avatars3.githubusercontent.com/u/2754163?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jeremy Liberman</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=MrLeebo" title="Code">💻</a> <a href="#maintenance-MrLeebo" title="Maintenance">🚧</a> <a href="https://github.com/blitz-js/blitz/commits?author=MrLeebo" title="Tests">⚠️</a></td>
<td align="center"><a href="https://jimthedev.com"><img src="https://avatars0.githubusercontent.com/u/108938?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jim Cummins</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jimthedev" title="Code">💻</a></td>
<td align="center"><a href="http://kristinamatuska.com/"><img src="https://media-exp1.licdn.com/dms/image/C5603AQHVPAjV21gw9g/profile-displayphoto-shrink_200_200/0?e=1591228800&v=beta&t=0MlbmiYhNvGv1xjLD_fOhOFjVDZ7ltNwfGNeJ4DHedQ?s=100" width="100px;" alt=""/><br /><sub><b>Kristina Matuška</b></sub></a><br /><a href="#design" title="Design">🎨</a></td>
<td align="center"><a href="https://github.com/jasonblalock"><img src="https://avatars0.githubusercontent.com/u/5899929?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jason Blalock</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jasonblalock" title="Code">💻</a></td>
@@ -288,10 +274,10 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="https://mikeattara.com"><img src="https://avatars1.githubusercontent.com/u/31483629?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mike Perry Y Attara</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mikeattara" title="Documentation">📖</a></td>
<td align="center"><a href="https://devanthe.dev"><img src="https://avatars0.githubusercontent.com/u/354652?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Devan</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=DevanB" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/jclancy93"><img src="https://avatars2.githubusercontent.com/u/7850202?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jack Clancy</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jclancy93" title="Code">💻</a> <a href="#maintenance-jclancy93" title="Maintenance">🚧</a></td>
<td align="center"><a href="https://github.com/ntgussoni"><img src="https://avatars0.githubusercontent.com/u/10161067?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nicolas Torres</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ntgussoni" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=ntgussoni" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/pulls?q=is%3Apr+reviewed-by%3Antgussoni" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/blitz-js/blitz/commits?author=ntgussoni" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/ntgussoni"><img src="https://avatars0.githubusercontent.com/u/10161067?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nicolas Torres</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ntgussoni" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=ntgussoni" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/pulls?q=is%3Apr+reviewed-by%3Antgussoni" title="Reviewed Pull Requests">👀</a></td>
</tr>
<tr>
<td align="center"><a href="http://simonknott.de"><img src="https://avatars1.githubusercontent.com/u/14912729?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Simon Knott</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Skn0tt" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=Skn0tt" title="Tests">⚠️</a> <a href="#maintenance-Skn0tt" title="Maintenance">🚧</a> <a href="https://github.com/blitz-js/blitz/commits?author=Skn0tt" title="Documentation">📖</a></td>
<td align="center"><a href="http://simonknott.de"><img src="https://avatars1.githubusercontent.com/u/14912729?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Simon Knott</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Skn0tt" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=Skn0tt" title="Tests">⚠️</a> <a href="#maintenance-Skn0tt" title="Maintenance">🚧</a></td>
<td align="center"><a href="http://jagascript.com"><img src="https://avatars0.githubusercontent.com/u/4562878?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jaga Santagostino</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=kandros" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=kandros" title="Documentation">📖</a> <a href="#maintenance-kandros" title="Maintenance">🚧</a></td>
<td align="center"><a href="http://www.joaoportela.com"><img src="https://avatars0.githubusercontent.com/u/1010018?v=4?s=100" width="100px;" alt=""/><br /><sub><b>João Portela</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jportela" title="Code">💻</a></td>
<td align="center"><a href="http://dajin.dev"><img src="https://avatars0.githubusercontent.com/u/7122182?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Da-Jin Chu</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dajinchu" title="Code">💻</a></td>
@@ -312,7 +298,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="https://www.dwightwatson.com"><img src="https://avatars3.githubusercontent.com/u/1100408?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dwight Watson</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dwightwatson" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=dwightwatson" title="Documentation">📖</a></td>
<td align="center"><a href="http://is2ei.com/"><img src="https://avatars3.githubusercontent.com/u/3948353?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Horie Issei</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=is2ei" title="Code">💻</a></td>
<td align="center"><a href="https://twitter.com/lednhatkhanh"><img src="https://avatars2.githubusercontent.com/u/9303093?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nhat Khanh</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=lednhatkhanh" title="Code">💻</a></td>
<td align="center"><a href="https://builtforfifty.com"><img src="https://avatars1.githubusercontent.com/u/19371989?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Abu Uzayr</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=abuuzayr" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=abuuzayr" title="Documentation">📖</a></td>
<td align="center"><a href="https://builtforfifty.com"><img src="https://avatars1.githubusercontent.com/u/19371989?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Abu Uzayr</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=abuuzayr" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/nabi009"><img src="https://avatars0.githubusercontent.com/u/3170831?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nabiullah elham</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=nabi009" title="Code">💻</a></td>
<td align="center"><a href="https://lachlanjc.com"><img src="https://avatars1.githubusercontent.com/u/5074763?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lachlan Campbell</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=lachlanjc" title="Code">💻</a></td>
<td align="center"><a href="http://enzoferey.com"><img src="https://avatars1.githubusercontent.com/u/10673347?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Enzo Ferey</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=enzoferey" title="Code">💻</a></td>
@@ -411,7 +397,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="https://github.com/phillippschmedt"><img src="https://avatars0.githubusercontent.com/u/16028406?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Phillipp Schmedt</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=phillippschmedt" title="Code">💻</a></td>
<td align="center"><a href="https://haspar.us"><img src="https://avatars0.githubusercontent.com/u/15332326?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Piotr Monwid-Olechnowicz</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=hasparus" title="Code">💻</a></td>
<td align="center"><a href="https://mizchi.dev"><img src="https://avatars2.githubusercontent.com/u/73962?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kotaro Chikuba</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mizchi" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=mizchi" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/konradkalemba"><img src="https://avatars0.githubusercontent.com/u/8682104?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Konrad Kalemba</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=konradkalemba" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=konradkalemba" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/konradkalemba"><img src="https://avatars0.githubusercontent.com/u/8682104?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Konrad Kalemba</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=konradkalemba" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/Alucard17"><img src="https://avatars1.githubusercontent.com/u/26205172?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alucard17</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Alucard17" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/Dohxis"><img src="https://avatars2.githubusercontent.com/u/8768909?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Domantas Mauruča</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Dohxis" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=Dohxis" title="Code">💻</a></td>
<td align="center"><a href="https://sandulat.com/"><img src="https://avatars0.githubusercontent.com/u/7345874?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Stratulat Alexandru</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=sandulat" title="Code">💻</a> <a href="#maintenance-sandulat" title="Maintenance">🚧</a></td>
@@ -458,17 +444,17 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="http://kattcorp.com"><img src="https://avatars1.githubusercontent.com/u/459267?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alex Johansson</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=KATT" title="Code">💻</a></td>
<td align="center"><a href="http://davidmazza.com"><img src="https://avatars0.githubusercontent.com/u/120893?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Mazza</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dmzza" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/rayandrews"><img src="https://avatars1.githubusercontent.com/u/4437323?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ray Andrew</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=rayandrews" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=rayandrews" title="Documentation">📖</a></td>
<td align="center"><a href="http://Dal.Design"><img src="https://avatars3.githubusercontent.com/u/43112535?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Abdullah Mzaien</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Mzaien" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=Mzaien" title="Documentation">📖</a></td>
<td align="center"><a href="http://Dal.Design"><img src="https://avatars3.githubusercontent.com/u/43112535?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Abdullah Mzaien</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Mzaien" title="Code">💻</a></td>
<td align="center"><a href="http://kwao.io"><img src="https://avatars2.githubusercontent.com/u/8839514?v=4?s=100" width="100px;" alt=""/><br /><sub><b>William Kwao</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=williamkwao" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/sakulstra"><img src="https://avatars3.githubusercontent.com/u/4396533?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lukas Strassel</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=sakulstra" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=sakulstra" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/sakulstra"><img src="https://avatars3.githubusercontent.com/u/4396533?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lukas Strassel</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=sakulstra" title="Code">💻</a></td>
<td align="center"><a href="https://thibpat.com"><img src="https://avatars3.githubusercontent.com/u/494686?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Thibaut Patel</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=tpatel" title="Code">💻</a></td>
<td align="center"><a href="http://jonstuebe.com"><img src="https://avatars0.githubusercontent.com/u/156722?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jon Stuebe</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jonstuebe" title="Code">💻</a></td>
<td align="center"><a href="https://ugogo.dev"><img src="https://avatars2.githubusercontent.com/u/5040476?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ugo Onali</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ugogo" title="Documentation">📖</a></td>
<td align="center"><a href="https://saintmalik.me"><img src="https://avatars1.githubusercontent.com/u/37118134?v=4?s=100" width="100px;" alt=""/><br /><sub><b>SaintMalik</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=saintmalik" title="Documentation">📖</a></td>
<td align="center"><a href="https://khaledgarbaya.net"><img src="https://avatars1.githubusercontent.com/u/1156093?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Khaled Garbaya</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Khaledgarbaya" title="Code">💻</a></td>
<td align="center"><a href="https://tundera.dev"><img src="https://avatars0.githubusercontent.com/u/61833561?v=4?s=100" width="100px;" alt=""/><br /><sub><b>tundera</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=tundera" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=tundera" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=tundera" title="Documentation">📖</a></td>
<td align="center"><a href="https://tundera.dev"><img src="https://avatars0.githubusercontent.com/u/61833561?v=4?s=100" width="100px;" alt=""/><br /><sub><b>tundera</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=tundera" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/markylaing"><img src="https://avatars2.githubusercontent.com/u/41469221?v=4?s=100" width="100px;" alt=""/><br /><sub><b>markylaing</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=markylaing" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=markylaing" title="Documentation">📖</a></td>
@@ -503,7 +489,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="https://github.com/rince"><img src="https://avatars.githubusercontent.com/u/933895?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kazuma Suzuki</b></sub></a><br /><a href="#design-rince" title="Design">🎨</a> <a href="https://github.com/blitz-js/blitz/commits?author=rince" title="Code">💻</a></td>
<td align="center"><a href="http://queq1890.info"><img src="https://avatars.githubusercontent.com/u/32263803?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yuji Matsumoto</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=queq1890" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/Gim3l"><img src="https://avatars.githubusercontent.com/u/46765702?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gimel Dick</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Gim3l" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/akbo"><img src="https://avatars.githubusercontent.com/u/1926271?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andreas Bollig</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=akbo" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=akbo" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/akbo"><img src="https://avatars.githubusercontent.com/u/1926271?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andreas Bollig</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=akbo" title="Code">💻</a></td>
<td align="center"><a href="https://ajm.codes"><img src="https://avatars.githubusercontent.com/u/66390428?v=4?s=100" width="100px;" alt=""/><br /><sub><b>AJ Markow</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ajmarkow" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=ajmarkow" title="Code">💻</a></td>
</tr>
<tr>
@@ -513,129 +499,6 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="https://alistair.cloud"><img src="https://avatars.githubusercontent.com/u/25351731?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alistair Smith</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=alii" title="Code">💻</a></td>
<td align="center"><a href="https://rodrigoehlers.com"><img src="https://avatars.githubusercontent.com/u/19683042?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Rodrigo Ehlers</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=rodrigoehlers" title="Code">💻</a></td>
<td align="center"><a href="https://www.builtopen.com/"><img src="https://avatars.githubusercontent.com/u/1734057?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Michael Ford</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mtford90" title="Code">💻</a></td>
<td align="center"><a href="https://brianypliu.com"><img src="https://avatars.githubusercontent.com/u/3888780?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Brian Liu</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=LBrian" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="http://aleksandra.codes"><img src="https://avatars.githubusercontent.com/u/9019397?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aleksandra Sikora</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=beerose" title="Code">💻</a></td>
<td align="center"><a href="https://juanm04.com"><img src="https://avatars.githubusercontent.com/u/16712703?v=4?s=100" width="100px;" alt=""/><br /><sub><b>JuanM04</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=JuanM04" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=JuanM04" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=JuanM04" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/arenddeboer"><img src="https://avatars.githubusercontent.com/u/7022204?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Arend de Boer</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=arenddeboer" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/fmilani"><img src="https://avatars.githubusercontent.com/u/1580375?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Felipe Milani</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=fmilani" title="Documentation">📖</a></td>
<td align="center"><a href="http://nxhx.org"><img src="https://avatars.githubusercontent.com/u/13018?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Joe Edelman</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jxe" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/garytube"><img src="https://avatars.githubusercontent.com/u/3823504?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gary</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=garytube" title="Documentation">📖</a></td>
<td align="center"><a href="http://oliverloops.com"><img src="https://avatars.githubusercontent.com/u/33361399?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Oliver Lopez </b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=oliverloops" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://decadentIpsum.me"><img src="https://avatars.githubusercontent.com/u/32861532?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andreas Zaralis</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=DecadentIpsum" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/davetorbeck"><img src="https://avatars.githubusercontent.com/u/5829885?v=4?s=100" width="100px;" alt=""/><br /><sub><b>David Torbeck</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=davetorbeck" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/gusgard"><img src="https://avatars.githubusercontent.com/u/2577356?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gustavo Gard</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=gusgard" title="Documentation">📖</a></td>
<td align="center"><a href="https://narrationbox.com"><img src="https://avatars.githubusercontent.com/u/7126128?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Immortalin</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Immortalin" title="Code">💻</a></td>
<td align="center"><a href="https://cristianbgp.com"><img src="https://avatars.githubusercontent.com/u/8507974?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cristian Granda</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=cristianbgp" title="Code">💻</a></td>
<td align="center"><a href="https://deniseyu.io"><img src="https://avatars.githubusercontent.com/u/8420094?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Denise Yu</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=deniseyu" title="Code">💻</a></td>
<td align="center"><a href="http://dellacorte.me"><img src="https://avatars.githubusercontent.com/u/295683?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrea Della Corte</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=andreadellacorte" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="http://aditsachde.com"><img src="https://avatars.githubusercontent.com/u/23707194?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Adit Sachde</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=aditsachde" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/hirenchauhan2"><img src="https://avatars.githubusercontent.com/u/8999668?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hiren Chauhan</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=hirenchauhan2" title="Code">💻</a></td>
<td align="center"><a href="http://remjx.com/"><img src="https://avatars.githubusercontent.com/u/35121685?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mark Jackson</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=remjx" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=remjx" title="Code">💻</a></td>
<td align="center"><a href="https://lewisb.cloud/"><img src="https://avatars.githubusercontent.com/u/51877955?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lewis Blackburn</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=lewisblackburn" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/FDiskas"><img src="https://avatars.githubusercontent.com/u/468006?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Vytenis</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=FDiskas" title="Code">💻</a></td>
<td align="center"><a href="https://portfolio.matthieupetit.com"><img src="https://avatars.githubusercontent.com/u/12969089?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Matthieu</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=matthieu994" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=matthieu994" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/mitchazj"><img src="https://avatars.githubusercontent.com/u/15032956?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mitchell Johnson</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mitchazj" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://roshan.page/"><img src="https://avatars.githubusercontent.com/u/31125563?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Roshan Manuel</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Roesh" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=Roesh" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=Roesh" title="Tests">⚠️</a></td>
<td align="center"><a href="https://kevinlangleyjr.com"><img src="https://avatars.githubusercontent.com/u/877634?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kevin Langley Jr.</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=kevinlangleyjr" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=kevinlangleyjr" title="Documentation">📖</a></td>
<td align="center"><a href="https://projet-test-99df0.firebaseapp.com/"><img src="https://avatars.githubusercontent.com/u/51029779?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gabriel Picard</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=heavygabriel" title="Documentation">📖</a></td>
<td align="center"><a href="http://ryanchenkie.com/"><img src="https://avatars.githubusercontent.com/u/1847678?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ryan Chenkie</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=chenkie" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/sbappan"><img src="https://avatars.githubusercontent.com/u/12586088?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Santhosh B. Appan</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=sbappan" title="Documentation">📖</a></td>
<td align="center"><a href="http://stackoverflow.com/users/5207233/james-moran"><img src="https://avatars.githubusercontent.com/u/10858584?v=4?s=100" width="100px;" alt=""/><br /><sub><b>James Moran</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=james2406" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=james2406" title="Documentation">📖</a></td>
<td align="center"><a href="http://fb.me/yz"><img src="https://avatars.githubusercontent.com/u/14841421?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jack Zhao</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=bugzpodder" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/the-red"><img src="https://avatars.githubusercontent.com/u/4494300?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hisaki Akaza</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=the-red" title="Documentation">📖</a></td>
<td align="center"><a href="http://flavioander.com/"><img src="https://avatars.githubusercontent.com/u/14948074?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Flavio</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Flavyoo" title="Code">💻</a></td>
<td align="center"><a href="https://bhanuteja.dev/"><img src="https://avatars.githubusercontent.com/u/17903466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Bhanu Teja Pachipulusu</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=pbteja1998" title="Code">💻</a></td>
<td align="center"><a href="https://twitter.com/pavestru"><img src="https://avatars.githubusercontent.com/u/10186479?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pavel Struhar</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=pavestru" title="Code">💻</a></td>
<td align="center"><a href="https://in-thepink.com/"><img src="https://avatars.githubusercontent.com/u/42126368?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Reo Ishiyama</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=reo777" title="Code">💻</a></td>
<td align="center"><a href="https://macwright.com/"><img src="https://avatars.githubusercontent.com/u/32314?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tom MacWright</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=tmcw" title="Documentation">📖</a></td>
<td align="center"><a href="https://francoisbest.com"><img src="https://avatars.githubusercontent.com/u/1174092?v=4?s=100" width="100px;" alt=""/><br /><sub><b>François Best</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=franky47" title="Code">💻</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/FarazPatankar"><img src="https://avatars.githubusercontent.com/u/10681116?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Faraz Patankar</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=FarazPatankar" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/ericvicenti"><img src="https://avatars.githubusercontent.com/u/1483597?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eric Vicenti</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ericvicenti" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=ericvicenti" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/amdolan"><img src="https://avatars.githubusercontent.com/u/2552275?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alex Dolan</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=amdolan" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=amdolan" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=amdolan" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/Maastrich"><img src="https://avatars.githubusercontent.com/u/58431775?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mathis Pinsault</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Maastrich" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/gstranger"><img src="https://avatars.githubusercontent.com/u/36181416?v=4?s=100" width="100px;" alt=""/><br /><sub><b>gstranger</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=gstranger" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=gstranger" title="Documentation">📖</a></td>
<td align="center"><a href="http://twitter.com/_markeh"><img src="https://avatars.githubusercontent.com/u/1357323?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mark Hughes</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=markhughes" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=markhughes" title="Documentation">📖</a></td>
<td align="center"><a href="www.andrearizzello.work"><img src="https://avatars.githubusercontent.com/u/10348930?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrea Rizzello</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=andrearizzello" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="jahred.com.au"><img src="https://avatars.githubusercontent.com/u/13903378?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jahred Hope</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jahredhope" title="Documentation">📖</a></td>
<td align="center"><a href="simonelnahas.github.io/"><img src="https://avatars.githubusercontent.com/u/29279201?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Simon El Nahas</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=simonelnahas" title="Documentation">📖</a></td>
<td align="center"><a href="www.usertrack.net"><img src="https://avatars.githubusercontent.com/u/1384885?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Buleandra Cristian</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Cristy94" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=Cristy94" title="Code">💻</a></td>
<td align="center"><a href="http://palauisaac.me/"><img src="https://avatars.githubusercontent.com/u/12257885?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pedro Enrique Palau Isaac</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=peterpalau" title="Code">💻</a></td>
<td align="center"><a href="www.seanbrydon.me"><img src="https://avatars.githubusercontent.com/u/55134778?v=4?s=100" width="100px;" alt=""/><br /><sub><b>sean-brydon</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=sean-brydon" title="Documentation">📖</a></td>
<td align="center"><a href="buonerba.dev"><img src="https://avatars.githubusercontent.com/u/28837891?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Alessandro</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Dieman89" title="Documentation">📖</a></td>
<td align="center"><a href="www.jyutping.org"><img src="https://avatars.githubusercontent.com/u/11172180?v=4?s=100" width="100px;" alt=""/><br /><sub><b>laubonghaudoi</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=laubonghaudoi" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/TommasoBruno99"><img src="https://avatars.githubusercontent.com/u/61512591?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tommaso Bruno</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=TommasoBruno99" title="Documentation">📖</a></td>
<td align="center"><a href="antonykamp.de"><img src="https://avatars.githubusercontent.com/u/45163503?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Antony</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=antonykamp" title="Documentation">📖</a></td>
<td align="center"><a href="https://blog.6nok.org"><img src="https://avatars.githubusercontent.com/u/868283?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fatih Altinok</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=frontsideair" title="Documentation">📖</a></td>
<td align="center"><a href="https://mokshitjain.co/"><img src="https://avatars.githubusercontent.com/u/50412128?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mokshit Jain</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Mokshit06" title="Code">💻</a></td>
<td align="center"><a href="https://mubaidr.github.io"><img src="https://avatars.githubusercontent.com/u/2222702?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Muhammad Ubaid Raza</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mubaidr" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=mubaidr" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/silicontwin"><img src="https://avatars.githubusercontent.com/u/121665?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nick Warren</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=silicontwin" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/mlabate"><img src="https://avatars.githubusercontent.com/u/17139676?v=4?s=100" width="100px;" alt=""/><br /><sub><b>mlabate</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mlabate" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/lumaxis"><img src="https://avatars.githubusercontent.com/u/406937?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lukas Spieß</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=lumaxis" title="Documentation">📖</a></td>
<td align="center"><a href="https://dawnofmidnight.vercel.app"><img src="https://avatars.githubusercontent.com/u/78233879?v=4?s=100" width="100px;" alt=""/><br /><sub><b>DawnOfMidnight</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dawnofmidnight" title="Documentation">📖</a></td>
<td align="center"><a href="https://www.linkedin.com/in/kenzairaki/"><img src="https://avatars.githubusercontent.com/u/17203119?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kenza Iraki</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=kirakik" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=kirakik" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/agustif"><img src="https://avatars.githubusercontent.com/u/6601142?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Agusti Fernandez</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=agustif" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/Anjianto"><img src="https://avatars.githubusercontent.com/u/61521141?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Anjianto</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Anjianto" title="Code">💻</a></td>
<td align="center"><a href="https://adrienblanc.com"><img src="https://avatars.githubusercontent.com/u/41756894?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Blanc Adrien</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=adblanc" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/meepdeew"><img src="https://avatars.githubusercontent.com/u/43303008?v=4?s=100" width="100px;" alt=""/><br /><sub><b>meepdeew</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=meepdeew" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/Hardik3296"><img src="https://avatars.githubusercontent.com/u/20360325?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Hardik Gaur</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Hardik3296" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/acornellier"><img src="https://avatars.githubusercontent.com/u/8725423?v=4?s=100" width="100px;" alt=""/><br /><sub><b>acornellier</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=acornellier" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/craigglennie"><img src="https://avatars.githubusercontent.com/u/149281?v=4?s=100" width="100px;" alt=""/><br /><sub><b>craigglennie</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=craigglennie" title="Documentation">📖</a></td>
<td align="center"><a href="http://www.fernvillasenor.com"><img src="https://avatars.githubusercontent.com/u/5857808?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Fernando Villasenor</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=fernvilla" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/swiftgaruda"><img src="https://avatars.githubusercontent.com/u/16741392?v=4?s=100" width="100px;" alt=""/><br /><sub><b>swiftgaruda</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=swiftgaruda" title="Documentation">📖</a></td>
<td align="center"><a href="https://pplife.home.blog"><img src="https://avatars.githubusercontent.com/u/35653876?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pankaj Patil</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Patil2099" title="Documentation">📖</a></td>
<td align="center"><a href="minaabadir.ca"><img src="https://avatars.githubusercontent.com/u/3389914?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Mina Abadir</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mabadir" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=mabadir" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=mabadir" title="Tests">⚠️</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/frankiesardo"><img src="https://avatars.githubusercontent.com/u/1476561?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Francesco Sardo</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=frankiesardo" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=frankiesardo" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/enemycnt"><img src="https://avatars.githubusercontent.com/u/320313?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nikolay</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=enemycnt" title="Documentation">📖</a></td>
<td align="center"><a href="https://dipeshwagle.com"><img src="https://avatars.githubusercontent.com/u/4191022?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dipesh Wagle</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Dipeshwagle" title="Code">💻</a></td>
<td align="center"><a href="https://codepoet.de"><img src="https://avatars.githubusercontent.com/u/462455?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Benjamin Bender</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=benbender" title="Code">💻</a></td>
<td align="center"><a href="https://nima.sh"><img src="https://avatars.githubusercontent.com/u/3728170?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nima Shoghi</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=nimashoghi" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/chronark"><img src="https://avatars.githubusercontent.com/u/18246773?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andreas Thomas</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=chronark" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/guoqqqi"><img src="https://avatars.githubusercontent.com/u/72343596?v=4?s=100" width="100px;" alt=""/><br /><sub><b>guoqqqi</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=guoqqqi" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/timbooker"><img src="https://avatars.githubusercontent.com/u/612681?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tim</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=timbooker" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=timbooker" title="Tests">⚠️</a></td>
<td align="center"><a href="http://orlowski.me/"><img src="https://avatars.githubusercontent.com/u/16357457?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Marek Orłowski</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ormarek" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/AntoineGuestin"><img src="https://avatars.githubusercontent.com/u/70888750?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Antoine G</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=AntoineGuestin" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/swinner2"><img src="https://avatars.githubusercontent.com/u/6707308?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sean Winner</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=swinner2" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=swinner2" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=swinner2" title="Documentation">📖</a></td>
<td align="center"><a href="https://usman-s.me"><img src="https://avatars.githubusercontent.com/u/51731966?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Max Programming</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=max-programming" title="Code">💻</a></td>
<td align="center"><a href="https://makemake.sh"><img src="https://avatars.githubusercontent.com/u/353768?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sebastian Hoitz</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=sebastianhoitz" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=sebastianhoitz" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/garnerp"><img src="https://avatars.githubusercontent.com/u/737307?v=4?s=100" width="100px;" alt=""/><br /><sub><b>garnerp</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=garnerp" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/kivi"><img src="https://avatars.githubusercontent.com/u/366163?v=4?s=100" width="100px;" alt=""/><br /><sub><b>kivi</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=kivi" title="Code">💻</a></td>
<td align="center"><a href="http://dangreaves.com"><img src="https://avatars.githubusercontent.com/u/1036142?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dan Greaves</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dangreaves" title="Code">💻</a></td>
<td align="center"><a href="lksnmnn.com"><img src="https://avatars.githubusercontent.com/u/4983285?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Lukas Neumann</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=lksnmnn" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=lksnmnn" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=lksnmnn" title="Tests">⚠️</a></td>
<td align="center"><a href="dbachrach.com"><img src="https://avatars.githubusercontent.com/u/45016?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dustin Bachrach</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dbachrach" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=dbachrach" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/ashikka"><img src="https://avatars.githubusercontent.com/u/58368421?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ashikka Gupta</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ashikka" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=ashikka" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/deini"><img src="https://avatars.githubusercontent.com/u/2752665?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Almaguer</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=deini" title="Documentation">📖</a></td>
<td align="center"><a href="https://www.kevinpeters.net/about/"><img src="https://avatars.githubusercontent.com/u/12736734?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kevin Peters</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=igeligel" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="http://anolilab.de"><img src="https://avatars.githubusercontent.com/u/2716058?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Bannert</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=prisis" title="Code">💻</a></td>
<td align="center"><a href="https://benjakugler96.github.io/"><img src="https://avatars.githubusercontent.com/u/53273645?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Benja Kugler</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=benjakugler96" title="Code">💻</a></td>
<td align="center"><a href="https://semeniuc.ml/"><img src="https://avatars.githubusercontent.com/u/3838856?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Eric Semeniuc</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=esemeniuc" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=esemeniuc" title="Code">💻</a></td>
</tr>
</table>

View File

@@ -1,10 +0,0 @@
# Security Policy
## Supported Versions
TODO
## Reporting a Vulnerability
Email Brandon Bayer at b@bayer.ws to report a vulnerablity, and he will follow up with you asap.

View File

@@ -1,24 +0,0 @@
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path d="M79.4831 1.95572C70.2813 -0.81923 55.2811 -0.617415 46.1549 2.4098L18.6125 11.5167C9.48627 14.5313 9.38542 19.7784 18.3856 23.1588L49.9743 35.028C58.9744 38.4084 73.6217 38.194 82.5084 34.5487L110.883 22.9192C119.782 19.2739 119.53 14.0267 110.316 11.2518L79.4831 1.95572Z" fill="url(#paint0_linear)"/>
<path d="M84.235 38.6101C75.3357 42.2554 68.0625 53.1029 68.0625 62.727V113.635C68.0625 123.259 74.9071 127.245 83.2644 122.489L109.282 107.706C117.639 102.951 124.912 91.208 125.442 81.6092L127.837 37.8281C128.366 28.2167 121.509 23.3479 112.609 26.9932L84.235 38.6101Z" fill="url(#paint1_linear)"/>
<path d="M0.0071345 37.8409C-0.257575 28.2295 6.877 23.1211 15.8771 26.5015L47.4658 38.3707C56.466 41.7511 63.8274 52.3842 63.8274 62.0082V112.916C63.8274 122.54 56.882 126.715 48.386 122.212L17.0998 105.6C8.60392 101.085 1.44415 89.5306 1.16683 79.9192L0.0071345 37.8409Z" fill="url(#paint2_linear)"/>
</g>
<defs>
<linearGradient id="paint0_linear" x1="63.9326" y1="0" x2="63.9326" y2="124.497" gradientUnits="userSpaceOnUse">
<stop stop-color="#036EB8"/>
<stop offset="1" stop-color="#469196"/>
</linearGradient>
<linearGradient id="paint1_linear" x1="63.9326" y1="0" x2="63.9326" y2="124.497" gradientUnits="userSpaceOnUse">
<stop stop-color="#036EB8"/>
<stop offset="1" stop-color="#469196"/>
</linearGradient>
<linearGradient id="paint2_linear" x1="63.9326" y1="0" x2="63.9326" y2="124.497" gradientUnits="userSpaceOnUse">
<stop stop-color="#036EB8"/>
<stop offset="1" stop-color="#469196"/>
</linearGradient>
<clipPath id="clip0">
<rect width="128" height="128" fill="white"/>
</clipPath>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 980 979.97"><path d="M139.38,0c-185.82-3.54-185.82,277,0,273.46H251.44C437.25,277,437.25-3.5,251.44,0ZM729.25,353.24c-184.92-2.62-184.92,276.1,0,273.48H841.31c184.92,2.62,184.92-276.1,0-273.48ZM138.69,706.46c-184.92-2.61-184.92,276.1,0,273.49H250.75c184.91,2.61,184.91-276.1,0-273.49Z" fill="#b43278"/><path d="M583.47,0c-185.82-3.54-185.82,277,0,273.46H840.61c185.81,3.54,185.81-277,0-273.46ZM138.7,353.24c-184.92-2.62-184.92,276.1,0,273.48H395.85c184.92,2.62,184.92-276.1,0-273.48ZM584.13,706.46c-184.91-2.61-184.91,276.1,0,273.49H841.3c184.92,2.61,184.92-276.1,0-273.49Z" fill="#f65a8e"/></svg>

Before

Width:  |  Height:  |  Size: 650 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

View File

@@ -1,64 +0,0 @@
module.exports = {
presets: [
"@babel/preset-typescript",
"@babel/preset-react",
[
"@babel/preset-env",
{
modules: false,
loose: true,
exclude: [
"@babel/plugin-transform-async-to-generator",
"@babel/plugin-transform-regenerator",
],
},
],
],
plugins: [
"babel-plugin-annotate-pure-calls",
"babel-plugin-dev-expression",
["@babel/plugin-proposal-class-properties", {loose: true}],
"babel-plugin-macros",
[
"transform-inline-environment-variables",
{
include: ["BLITZ_PROD_BUILD"],
},
],
],
overrides: [
{
test: "./test/**/*",
presets: [
[
"@babel/preset-env",
{
modules: false,
exclude: [
"@babel/plugin-transform-async-to-generator",
"@babel/plugin-transform-regenerator",
],
},
],
"blitz/babel",
],
plugins: [],
},
{
test: "./nextjs/test/**/*",
presets: [
[
"@babel/preset-env",
{
modules: false,
exclude: [
"@babel/plugin-transform-async-to-generator",
"@babel/plugin-transform-regenerator",
],
},
],
"blitz/babel",
],
},
],
}

View File

@@ -14,7 +14,7 @@ model Project {
2. DB migrate
```
blitz prisma migrate dev
blitz prisma migrate dev --preview-feature
```
3. Start the dev server

View File

@@ -22,14 +22,14 @@ assert(process.env.AUTH0_DOMAIN, "You must provide the AUTH0_DOMAIN env variable
assert(process.env.AUTH0_CLIENT_ID, "You must provide the AUTH0_CLIENT_ID env variable")
assert(process.env.AUTH0_CLIENT_SECRET, "You must provide the AUTH0_CLIENT_SECRET env variable")
export default passportAuth((ctx) => ({
export default passportAuth({
successRedirectUrl: "/",
strategies: [
{
strategy: new TwitterStrategy(
{
consumerKey: process.env.TWITTER_CONSUMER_KEY as string,
consumerSecret: process.env.TWITTER_CONSUMER_SECRET as string,
consumerKey: process.env.TWITTER_CONSUMER_KEY,
consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
callbackURL:
process.env.NODE_ENV === "production"
? "https://auth-example-flybayer.blitzjs.vercel.app/api/auth/twitter/callback"
@@ -44,8 +44,6 @@ export default passportAuth((ctx) => ({
return done(new Error("Twitter OAuth response doesn't have email."))
}
console.log(ctx.session.userId)
const user = await db.user.upsert({
where: {email},
create: {
@@ -55,7 +53,7 @@ export default passportAuth((ctx) => ({
update: {email},
})
const publicData = {userId: user.id, role: user.role, source: "twitter"}
const publicData = {userId: user.id, roles: [user.role], source: "twitter"}
done(null, {publicData})
},
),
@@ -63,8 +61,8 @@ export default passportAuth((ctx) => ({
{
strategy: new GitHubStrategy(
{
clientID: process.env.GITHUB_CLIENT_ID as string,
clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
clientID: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
callbackURL:
process.env.NODE_ENV === "production"
? "https://auth-example-flybayer.blitzjs.vercel.app/api/auth/github/callback"
@@ -94,7 +92,7 @@ export default passportAuth((ctx) => ({
const publicData = {
userId: user.id,
role: user.role as Role,
roles: [user.role as Role],
source: "github",
githubUsername: profile.username,
}
@@ -106,9 +104,9 @@ export default passportAuth((ctx) => ({
authenticateOptions: {scope: "openid email profile"},
strategy: new Auth0Strategy(
{
domain: process.env.AUTH0_DOMAIN as string,
clientID: process.env.AUTH0_CLIENT_ID as string,
clientSecret: process.env.AUTH0_CLIENT_SECRET as string,
domain: process.env.AUTH0_DOMAIN,
clientID: process.env.AUTH0_CLIENT_ID,
clientSecret: process.env.AUTH0_CLIENT_SECRET,
callbackURL:
process.env.NODE_ENV === "production"
? "https://auth-example-flybayer.blitzjs.vercel.app/api/auth/auth0/callback"
@@ -133,7 +131,7 @@ export default passportAuth((ctx) => ({
const publicData = {
userId: user.id,
role: user.role,
roles: [user.role],
source: "auth0",
githubUsername: profile.username,
}
@@ -142,4 +140,4 @@ export default passportAuth((ctx) => ({
),
},
],
}))
})

View File

@@ -4,8 +4,6 @@ import {Form, FORM_ERROR} from "app/core/components/Form"
import login from "app/auth/mutations/login"
import {Login} from "app/auth/validations"
import {Routes} from ".blitz"
type LoginFormProps = {
onSuccess?: () => void
}
@@ -40,14 +38,14 @@ export const LoginForm = (props: LoginFormProps) => {
<LabeledTextField name="email" label="Email" placeholder="Email" />
<LabeledTextField name="password" label="Password" placeholder="Password" type="password" />
<div>
<Link href={Routes.ForgotPasswordPage()}>
<Link href="/forgot-password">
<a>Forgot your password?</a>
</Link>
</div>
</Form>
<div style={{marginTop: "1rem"}}>
Or <Link href={Routes.SignupPage()}>Sign Up</Link>
Or <Link href="/signup">Sign Up</Link>
</div>
</div>
)

View File

@@ -8,8 +8,8 @@ beforeEach(async () => {
})
const generatedToken = "plain-token"
jest.mock("@blitzjs/core/server", () => ({
...jest.requireActual<object>("@blitzjs/core/server")!,
jest.mock("blitz", () => ({
...jest.requireActual("blitz")!,
generateToken: () => generatedToken,
}))
jest.mock("preview-email", () => jest.fn())

View File

@@ -23,15 +23,7 @@ export default resolver.pipe(resolver.zod(Login), async ({email, password}, ctx)
// This throws an error if credentials are invalid
const user = await authenticateUser(email, password)
await ctx.session.$create({userId: user.id, role: user.role as Role})
await ctx.session.$create({userId: user.id, roles: [user.role as Role]})
return user
})
export const config = {
api: {
bodyParser: {
sizeLimit: "2mb",
},
},
}

View File

@@ -10,6 +10,6 @@ export default resolver.pipe(resolver.zod(Signup), async ({email, password}, ctx
select: {id: true, name: true, email: true, role: true},
})
await ctx.session.$create({userId: user.id, role: user.role as Role})
await ctx.session.$create({userId: user.id, roles: [user.role as Role]})
return user
})

View File

@@ -1,25 +1,19 @@
import React from "react"
import {useRouter, BlitzPage} from "blitz"
import {useRouter, BlitzPage, useRedirectAuthenticatedUser} from "blitz"
import Layout from "app/core/layouts/Layout"
import {LoginForm} from "app/auth/components/LoginForm"
import {Routes} from ".blitz"
const LoginPage: BlitzPage = () => {
useRedirectAuthenticatedUser("/projects")
const router = useRouter()
return (
<div>
<LoginForm
onSuccess={() => {
const next = router.query.next ? decodeURIComponent(router.query.next as string) : "/"
router.push(next)
}}
/>
<LoginForm onSuccess={() => router.push("/")} />
</div>
)
}
LoginPage.redirectAuthenticatedTo = Routes.Home().pathname
LoginPage.getLayout = (page) => <Layout title="Log In">{page}</Layout>
export default LoginPage

View File

@@ -5,8 +5,6 @@ import {Form, FORM_ERROR} from "app/core/components/Form"
import {ResetPassword} from "app/auth/validations"
import resetPassword from "app/auth/mutations/resetPassword"
import {Routes} from ".blitz"
const ResetPasswordPage: BlitzPage = () => {
const query = useRouterQuery()
const [resetPasswordMutation, {isSuccess}] = useMutation(resetPassword)
@@ -19,7 +17,7 @@ const ResetPasswordPage: BlitzPage = () => {
<div>
<h2>Password Reset Successfully</h2>
<p>
Go to the <Link href={Routes.Home()}>homepage</Link>
Go to the <Link href="/">homepage</Link>
</p>
</div>
) : (

View File

@@ -1,5 +1,7 @@
import {useRouter, BlitzPage} from "blitz"
import {Head, useRouter, BlitzPage, useMutation} from "blitz"
import Layout from "app/core/layouts/Layout"
import {Form, FORM_ERROR} from "app/core/components/Form"
import {LabeledTextField} from "app/core/components/LabeledTextField"
import {SignupForm} from "app/auth/components/SignupForm"
const SignupPage: BlitzPage = () => {

View File

@@ -1,4 +1,4 @@
import {z} from "zod"
import * as z from "zod"
const password = z.string().min(10).max(100)

View File

@@ -1,7 +1,6 @@
import React, {ReactNode, PropsWithoutRef} from "react"
import {Form as FinalForm, FormProps as FinalFormProps} from "react-final-form"
import {z} from "zod"
import {validateZodSchema} from "blitz"
import * as z from "zod"
export {FORM_ERROR} from "final-form"
export interface FormProps<S extends z.ZodType<any, any>>
@@ -26,7 +25,14 @@ export function Form<S extends z.ZodType<any, any>>({
return (
<FinalForm
initialValues={initialValues}
validate={validateZodSchema(schema)}
validate={(values) => {
if (!schema) return
try {
schema.parse(values)
} catch (error) {
return error.formErrors.fieldErrors
}
}}
onSubmit={onSubmit}
render={({handleSubmit, submitting, submitError}) => (
<form onSubmit={handleSubmit} className="form" {...props}>

View File

@@ -2,7 +2,7 @@ import {useSession, useRouter, useMutation, Head} from "blitz"
import logout from "app/auth/mutations/logout"
export default function Layout({title, children}: {title?: string; children: React.ReactNode}) {
const session = useSession({suspense: false})
const session = useSession()
const router = useRouter()
const [logoutMutation] = useMutation(logout)
return (

View File

@@ -0,0 +1,13 @@
import {resolver} from "blitz"
import db from "db"
import * as z from "zod"
const __Name__ = z
.object({
id: z.number(),
})
.nonstrict()
export default resolver.pipe(resolver.zod(__Name__), resolver.authorize(), async (input) => {
// Do your stuff :)
})

View File

@@ -1,26 +1,31 @@
import {
AppProps,
ErrorBoundary,
ErrorComponent,
useRouter,
AuthenticationError,
AuthorizationError,
ErrorFallbackProps,
useQueryErrorResetBoundary,
} from "blitz"
import {ErrorBoundary} from "react-error-boundary"
import {queryCache} from "react-query"
import LoginForm from "app/auth/components/LoginForm"
import {ReactQueryDevtools} from "react-query/devtools"
export default function App({Component, pageProps}: AppProps) {
const getLayout = Component.getLayout || ((page) => page)
const {reset} = useQueryErrorResetBoundary()
const router = useRouter()
return (
<>
<ErrorBoundary FallbackComponent={RootErrorFallback} onReset={reset}>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
<ReactQueryDevtools />
</>
<ErrorBoundary
FallbackComponent={RootErrorFallback}
resetKeys={[router.asPath]}
onReset={() => {
// This ensures the Blitz useQuery hooks will automatically refetch
// data any time you reset the error boundary
queryCache.resetErrorBoundaries()
}}
>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
)
}
@@ -36,10 +41,7 @@ function RootErrorFallback({error, resetErrorBoundary}: ErrorFallbackProps) {
)
} else {
return (
<ErrorComponent
statusCode={(error as any)?.statusCode || 400}
title={error.message || error.name}
/>
<ErrorComponent statusCode={error.statusCode || 400} title={error.message || error.name} />
)
}
}

View File

@@ -1,17 +1,10 @@
import {render} from "test/utils"
import Home from "./index"
jest.mock("@blitzjs/core", () => ({
...jest.requireActual<object>("@blitzjs/core")!,
useQuery: () => [
{
id: 1,
name: "User",
email: "user@email.com",
role: "user",
},
],
}))
import Home from "./index"
import {useCurrentUser} from "app/core/hooks/useCurrentUser"
jest.mock("app/core/hooks/useCurrentUser")
const mockUseCurrentUser = useCurrentUser as jest.MockedFunction<typeof useCurrentUser>
test("renders blitz documentation link", () => {
// This is an example of how to ensure a specific item is in the document
@@ -19,9 +12,15 @@ test("renders blitz documentation link", () => {
// when you remove the the default content from the page
// This is an example on how to mock api hooks when testing
mockUseCurrentUser.mockReturnValue({
id: 1,
name: "User",
email: "user@email.com",
role: "user",
})
const {getByText} = render(<Home />)
const element = getByText(/powered by blitz/i)
// @ts-ignore
expect(element).toBeInTheDocument()
})
})

View File

@@ -1,41 +1,39 @@
import {Suspense} from "react"
import {
Head,
Link,
useSession,
useRouterQuery,
useMutation,
invoke,
useQuery,
BlitzPage,
} from "blitz"
import {Head, Link, useSession, useRouterQuery, useMutation, invoke} from "blitz"
import getUser from "app/users/queries/getUser"
import trackView from "app/users/mutations/trackView"
import Layout from "app/core/layouts/Layout"
import {Routes} from ".blitz"
import {useCurrentUser} from "app/core/hooks/useCurrentUser"
// import getUsers from "app/users/queries/getUsers"
const CurrentUserInfo = () => {
const session = useSession()
const [currentUser] = useQuery(getUser, {where: {id: session.userId!}})
const currentUser = useCurrentUser()
return <pre>{JSON.stringify(currentUser, null, 2)}</pre>
}
// const Users = () => {
// const [users] = useQuery(getUsers, {})
//
// return <pre style={{maxWidth: "30rem"}}>{JSON.stringify(users, null, 2)}</pre>
// }
const UserStuff = () => {
const session = useSession()
const query = useRouterQuery()
const [trackViewMutation] = useMutation(trackView)
if (session.isLoading) return <div>Loading...</div>
return (
<div>
{!session.userId && (
<>
<div style={{marginTop: "1rem"}}>
<Link href={Routes.SignupPage()}>Sign Up</Link>
<Link href="/signup">Sign Up</Link>
</div>
<div>
<Link href={Routes.LoginPage()}>Login</Link>
<Link href="/login">Login</Link>
</div>
<a href="/api/auth/twitter" style={{display: "block"}}>
Login with Twitter
@@ -50,6 +48,11 @@ const UserStuff = () => {
<Suspense fallback="Loading...">
<CurrentUserInfo />
</Suspense>
{/*
<Suspense fallback="Loading...">
<Users />
</Suspense>
*/}
<button
onClick={async () => {
try {
@@ -78,7 +81,7 @@ const UserStuff = () => {
)
}
const Home: BlitzPage = () => (
const Home = () => (
<Layout>
<div className="container">
<Head>
@@ -91,9 +94,7 @@ const Home: BlitzPage = () => (
<img src="/logo.png" alt="blitz.js" />
</div>
<Suspense fallback={"Loading..."}>
<UserStuff />
</Suspense>
<UserStuff />
</main>
<footer>
@@ -237,6 +238,4 @@ const Home: BlitzPage = () => (
</Layout>
)
Home.suppressFirstRenderFlicker = true
export default Home

View File

@@ -4,16 +4,12 @@ import Layout from "app/core/layouts/Layout"
import getProject from "app/projects/queries/getProject"
import deleteProject from "app/projects/mutations/deleteProject"
import {Routes} from ".blitz"
export const Project = () => {
const router = useRouter()
const projectId = useParam("projectId", "number")
const [deleteProjectMutation, {isSuccess}] = useMutation(deleteProject)
const [project] = useQuery(getProject, {id: projectId}, {enabled: !isSuccess})
if (!project) return null
return (
<>
<Head>
@@ -24,7 +20,7 @@ export const Project = () => {
<h1>Project {project.id}</h1>
<pre>{JSON.stringify(project, null, 2)}</pre>
<Link href={Routes.EditProjectPage({projectId: project.id})}>
<Link href={`/projects/${project.id}/edit`}>
<a>Edit</a>
</Link>
@@ -49,7 +45,7 @@ const ShowProjectPage: BlitzPage = () => {
return (
<div>
<p>
<Link href={Routes.ProjectsPage()}>
<Link href="/projects">
<a>Projects</a>
</Link>
</p>
@@ -61,7 +57,6 @@ const ShowProjectPage: BlitzPage = () => {
)
}
ShowProjectPage.authenticate = true
ShowProjectPage.getLayout = (page) => <Layout>{page}</Layout>
export default ShowProjectPage

View File

@@ -5,19 +5,10 @@ import getProject from "app/projects/queries/getProject"
import updateProject from "app/projects/mutations/updateProject"
import {ProjectForm, FORM_ERROR} from "app/projects/components/ProjectForm"
import {Routes} from ".blitz"
export const EditProject = () => {
const router = useRouter()
const projectId = useParam("projectId", "number")
const [project, {setQueryData}] = useQuery(
getProject,
{id: projectId},
{
// This ensures the query never refreshes and overwrites the form data while the user is editing.
staleTime: Infinity,
},
)
const [project, {setQueryData}] = useQuery(getProject, {id: projectId})
const [updateProjectMutation] = useMutation(updateProject)
return (
@@ -66,7 +57,7 @@ const EditProjectPage: BlitzPage = () => {
</Suspense>
<p>
<Link href={Routes.ProjectsPage()}>
<Link href="/projects">
<a>Projects</a>
</Link>
</p>
@@ -74,7 +65,6 @@ const EditProjectPage: BlitzPage = () => {
)
}
EditProjectPage.authenticate = true
EditProjectPage.getLayout = (page) => <Layout>{page}</Layout>
export default EditProjectPage

View File

@@ -1,10 +1,8 @@
import {Suspense} from "react"
import {Head, Link, usePaginatedQuery, useRouter, BlitzPage} from "blitz"
import {Head, Link, usePaginatedQuery, useRouter, BlitzPage, useAuthorize} from "blitz"
import Layout from "app/core/layouts/Layout"
import getProjects from "app/projects/queries/getProjects"
import {Routes} from ".blitz"
const ITEMS_PER_PAGE = 100
export const ProjectsList = () => {
@@ -24,7 +22,7 @@ export const ProjectsList = () => {
<ul>
{projects.map((project) => (
<li key={project.id}>
<Link href={Routes.ShowProjectPage({projectId: project.id})}>
<Link href={`/projects/${project.id}`}>
<a>{project.name}</a>
</Link>
</li>
@@ -42,6 +40,8 @@ export const ProjectsList = () => {
}
const ProjectsPage: BlitzPage = () => {
useAuthorize()
return (
<>
<Head>
@@ -50,7 +50,7 @@ const ProjectsPage: BlitzPage = () => {
<div>
<p>
<Link href={Routes.NewProjectPage()}>
<Link href="/projects/new">
<a>Create Project</a>
</Link>
</p>
@@ -63,7 +63,6 @@ const ProjectsPage: BlitzPage = () => {
)
}
ProjectsPage.authenticate = {redirectTo: "/login"}
ProjectsPage.getLayout = (page) => <Layout>{page}</Layout>
export default ProjectsPage

View File

@@ -3,8 +3,6 @@ import Layout from "app/core/layouts/Layout"
import createProject from "app/projects/mutations/createProject"
import {ProjectForm, FORM_ERROR} from "app/projects/components/ProjectForm"
import {Routes} from ".blitz"
const NewProjectPage: BlitzPage = () => {
const router = useRouter()
const [createProjectMutation] = useMutation(createProject)
@@ -23,7 +21,7 @@ const NewProjectPage: BlitzPage = () => {
onSubmit={async (values) => {
try {
const project = await createProjectMutation(values)
router.push(Routes.ShowProjectPage({projectId: project.id}))
router.push(`/projects/${project.id}`)
} catch (error) {
console.error(error)
return {
@@ -34,7 +32,7 @@ const NewProjectPage: BlitzPage = () => {
/>
<p>
<Link href={Routes.ProjectsPage()}>
<Link href="/projects">
<a>Projects</a>
</Link>
</p>
@@ -42,7 +40,6 @@ const NewProjectPage: BlitzPage = () => {
)
}
NewProjectPage.authenticate = true
NewProjectPage.getLayout = (page) => <Layout title={"Create New Project"}>{page}</Layout>
export default NewProjectPage

View File

@@ -1,20 +1,36 @@
import {FC} from "react"
import {getSessionContext} from "@blitzjs/server"
import {
getSession,
invokeWithMiddleware,
useRouter,
GetServerSideProps,
PromiseReturnType,
ErrorComponent as ErrorPage,
useMutation,
AuthenticationError,
AuthorizationError,
GetServerSideProps,
InferGetServerSidePropsType,
BlitzPage,
} from "blitz"
import getUser from "app/users/queries/getUser"
import logout from "app/auth/mutations/logout"
import path from "path"
export const getServerSideProps: GetServerSideProps = async ({req, res}) => {
const session = await getSession(req, res)
type PageProps = {
user?: PromiseReturnType<typeof getUser>
error?: {
statusCode: number
message: string
}
}
export const getServerSideProps: GetServerSideProps<PageProps> = async ({req, res}) => {
// Ensure these files are not eliminated by trace-based tree-shaking (like Vercel)
// https://github.com/blitz-js/blitz/issues/794
path.resolve("next.config.js")
path.resolve("blitz.config.js")
path.resolve(".next/blitz/db.js")
// End anti-tree-shaking
const session = await getSessionContext(req, res)
console.log("Session id:", session.userId)
try {
const user = await invokeWithMiddleware(
@@ -46,7 +62,7 @@ export const getServerSideProps: GetServerSideProps = async ({req, res}) => {
}
}
const Test: BlitzPage<InferGetServerSidePropsType<typeof getServerSideProps>> = ({user, error}) => {
const Test: FC<PageProps> = ({user, error}: PageProps) => {
const router = useRouter()
const [logoutMutation] = useMutation(logout)

View File

@@ -1,13 +0,0 @@
import {useRouter} from "next/router"
import React from "react"
export default function Test() {
const {replace} = useRouter()
const handleChange = (event: any) => {
// replace({ query }, undefined, { shallow: true })
replace(`/test?p=${event.target.value}`)
}
return <input onChange={handleChange} />
}

View File

@@ -1,9 +1,9 @@
import {Form, FormProps} from "app/core/components/Form"
import {LabeledTextField} from "app/core/components/LabeledTextField"
import {ZodType} from "zod"
import * as z from "zod"
export {FORM_ERROR} from "app/core/components/Form"
export function ProjectForm<S extends ZodType<any, any>>(props: FormProps<S>) {
export function ProjectForm<S extends z.ZodType<any, any>>(props: FormProps<S>) {
return (
<Form<S> {...props}>
<LabeledTextField name="name" label="Name" placeholder="Name" />

View File

@@ -1,10 +1,12 @@
import {resolver} from "blitz"
import db from "db"
import {z} from "zod"
import * as z from "zod"
const CreateProject = z.object({
name: z.string(),
})
const CreateProject = z
.object({
name: z.string(),
})
.nonstrict()
export default resolver.pipe(resolver.zod(CreateProject), resolver.authorize(), async (input) => {
// TODO: in multi-tenant app, you must add validation to ensure correct tenant

View File

@@ -1,10 +1,12 @@
import {resolver} from "blitz"
import db from "db"
import {z} from "zod"
import * as z from "zod"
const DeleteProject = z.object({
id: z.number(),
})
const DeleteProject = z
.object({
id: z.number(),
})
.nonstrict()
export default resolver.pipe(resolver.zod(DeleteProject), resolver.authorize(), async ({id}) => {
// TODO: in multi-tenant app, you must add validation to ensure correct tenant

View File

@@ -1,11 +1,13 @@
import {resolver} from "blitz"
import db from "db"
import {z} from "zod"
import * as z from "zod"
const UpdateProject = z.object({
id: z.number(),
name: z.string(),
})
const UpdateProject = z
.object({
id: z.number(),
name: z.string(),
})
.nonstrict()
export default resolver.pipe(
resolver.zod(UpdateProject),

View File

@@ -1,6 +1,6 @@
import {resolver, NotFoundError} from "blitz"
import db from "db"
import {z} from "zod"
import * as z from "zod"
const GetProject = z.object({
// This accepts type of undefined, but is required at runtime

View File

@@ -6,7 +6,7 @@ type GetUserInput = {
}
export default async function getUser({where}: GetUserInput, ctx: Ctx) {
if (!ctx.session.userId) return null
ctx.session.$authorize()
const user = await db.user.findFirst({where})

View File

@@ -1,5 +1,4 @@
import {sessionMiddleware, simpleRolesIsAuthorized} from "blitz"
import db from "db"
const {sessionMiddleware, simpleRolesIsAuthorized} = require("@blitzjs/server")
const withBundleAnalyzer = require("@next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
})
@@ -7,22 +6,15 @@ const withBundleAnalyzer = require("@next/bundle-analyzer")({
module.exports = withBundleAnalyzer({
middleware: [
sessionMiddleware({
cookiePrefix: "blitz-auth-example",
isAuthorized: simpleRolesIsAuthorized,
// sessionExpiryMinutes: 4,
getSession: (handle) => db.session.findFirst({where: {handle}}),
}),
],
cli: {
clearConsoleOnBlitzDev: false,
},
log: {
// level: "trace",
},
experimental: {
initServer() {
console.log("Hello world from initServer")
},
isomorphicResolverImports: false,
},
/*
webpack: (config, {buildId, dev, isServer, defaultLoaders, webpack}) => {

View File

@@ -1,9 +1,6 @@
{
"baseUrl": "http://localhost:3099",
"defaultCommandTimeout": 10000,
"retries": {
"runMode": 1
},
"video": false,
"chromeWebSecurity": false
}

View File

@@ -19,7 +19,6 @@ describe("index page", () => {
const user = createRandomUser()
cy.signup(user)
cy.wait(1000)
cy.location("pathname").should("equal", "/")
cy.contains("button", "Logout")
@@ -29,10 +28,9 @@ describe("index page", () => {
const user = createRandomUser()
cy.signup(user)
cy.wait(1000)
cy.wait(500)
cy.contains("button", "Logout").click()
cy.wait(1000)
cy.contains("a", /login/i).click()
cy.contains("Email").find("input").type(user.email)
@@ -40,7 +38,7 @@ describe("index page", () => {
cy.contains("button", /login/i).click()
cy.location("pathname").should("equal", "/")
cy.wait(1000)
cy.wait(500)
cy.contains("button", "Logout")
})
@@ -48,12 +46,10 @@ describe("index page", () => {
const user = createRandomUser()
cy.signup(user)
cy.wait(1000)
cy.contains("button", "Logout").click()
cy.location("pathname").should("equal", "/")
cy.wait(1000)
cy.contains("a", /login/i)
})
@@ -63,13 +59,10 @@ describe("index page", () => {
const user = createRandomUser()
cy.contains("button", "Track view").click()
cy.wait(500)
cy.contains("button", "Track view").click()
cy.wait(1000)
cy.contains('"views": 2')
cy.signup(user)
cy.wait(1000)
cy.contains('"views": 2')
})

View File

@@ -1,6 +1,6 @@
{
"name": "@examples/auth",
"version": "0.34.0-canary.0",
"version": "0.30.0-canary.6",
"scripts": {
"dev": "blitz dev",
"build": "blitz build",
@@ -9,10 +9,10 @@
"lint": "eslint --ignore-path .gitignore --ext .js,.ts,.tsx .",
"analyze": "cross-env ANALYZE=true blitz build",
"cy:open": "cypress open",
"cy:run": "cypress run --browser chrome",
"test": "prisma generate && blitz codegen && yarn test:jest && yarn test:e2e",
"cy:run": "cypress run || cypress run",
"test": "prisma generate && yarn test:jest && yarn test:e2e",
"test:jest": "jest",
"test:server": "cross-env NODE_ENV=test blitz prisma migrate deploy && blitz build && cross-env NODE_ENV=test blitz start -p 3099",
"test:server": "blitz prisma migrate deploy --preview-feature && blitz build && blitz start -p 3099",
"test:e2e": "cross-env NODE_ENV=test start-server-and-test test:server http://localhost:3099 cy:run"
},
"browserslist": [
@@ -27,37 +27,51 @@
"bracketSpacing": false,
"trailingComma": "all"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged && pretty-quick --staged",
"pre-push": "blitz test"
}
},
"lint-staged": {
"*.{js,ts,tsx}": [
"eslint --fix"
]
},
"dependencies": {
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"@prisma/client": "2.16.0",
"blitz": "0.30.0-canary.6",
"final-form": "4.20.1",
"passport-auth0": "1.4.0",
"passport-github2": "0.1.12",
"passport-twitter": "1.0.4",
"prisma": "2.24.1",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701",
"react-final-form": "6.5.2"
"prisma": "2.16.0",
"react": "0.0.0-experimental-3310209d0",
"react-dom": "0.0.0-experimental-3310209d0",
"react-error-boundary": "3.1.0",
"react-final-form": "6.5.2",
"zod": "1.11.11"
},
"devDependencies": {
"@cypress/skip-test": "2.6.0",
"@next/bundle-analyzer": "^10.0.6",
"@testing-library/react": "11.2.5",
"@testing-library/react-hooks": "^4.0.1",
"@testing-library/react": "11.2.3",
"@testing-library/react-hooks": "4.0.1",
"@types/passport-auth0": "1.0.4",
"@types/passport-github2": "1.2.4",
"@types/passport-twitter": "1.0.36",
"@types/preview-email": "2.0.0",
"@types/react": "17.0.13",
"@types/react": "17.0.0",
"cross-env": "7.0.3",
"cypress": "6.2.1",
"eslint": "7.21.0",
"husky": "5.1.2",
"lint-staged": "10.5.4",
"eslint": "7.18.0",
"husky": "4.3.8",
"lint-staged": "10.5.3",
"prettier": "2.2.1",
"pretty-quick": "3.1.0",
"preview-email": "3.0.3",
"start-server-and-test": "1.11.7"
"start-server-and-test": "1.11.7",
"typescript": "4.1.3"
},
"private": true
}

View File

@@ -1,4 +1,5 @@
import {RouterContext, BlitzRouter, BlitzProvider} from "blitz"
import React from "react"
import {RouterContext, BlitzRouter} from "blitz"
import {render as defaultRender} from "@testing-library/react"
import {renderHook as defaultRenderHook} from "@testing-library/react-hooks"
@@ -24,18 +25,11 @@ export * from "@testing-library/react"
// router: { pathname: '/my-custom-pathname' },
// });
// --------------------------------------------------
export function render(
ui: RenderUI,
{wrapper, router, dehydratedState, ...options}: RenderOptions = {},
) {
export function render(ui: RenderUI, {wrapper, router, ...options}: RenderOptions = {}) {
if (!wrapper) {
// Add a default context wrapper if one isn't supplied from the test
wrapper = ({children}) => (
<BlitzProvider dehydratedState={dehydratedState}>
<RouterContext.Provider value={{...mockRouter, ...router}}>
{children}
</RouterContext.Provider>
</BlitzProvider>
<RouterContext.Provider value={{...mockRouter, ...router}}>{children}</RouterContext.Provider>
)
}
return defaultRender(ui, {wrapper, ...options})
@@ -54,16 +48,12 @@ export function render(
// --------------------------------------------------
export function renderHook(
hook: RenderHook,
{wrapper, router, dehydratedState, ...options}: RenderHookOptions = {},
{wrapper, router, ...options}: RenderHookOptions = {},
) {
if (!wrapper) {
// Add a default context wrapper if one isn't supplied from the test
wrapper = ({children}) => (
<BlitzProvider dehydratedState={dehydratedState}>
<RouterContext.Provider value={{...mockRouter, ...router}}>
{children}
</RouterContext.Provider>
</BlitzProvider>
<RouterContext.Provider value={{...mockRouter, ...router}}>{children}</RouterContext.Provider>
)
}
return defaultRenderHook(hook, {wrapper, ...options})
@@ -77,8 +67,6 @@ export const mockRouter: BlitzRouter = {
params: {},
query: {},
isReady: true,
isLocaleDomain: false,
isPreview: false,
push: jest.fn(),
replace: jest.fn(),
reload: jest.fn(),
@@ -95,14 +83,8 @@ export const mockRouter: BlitzRouter = {
type DefaultParams = Parameters<typeof defaultRender>
type RenderUI = DefaultParams[0]
type RenderOptions = DefaultParams[1] & {
router?: Partial<BlitzRouter>
dehydratedState?: unknown
}
type RenderOptions = DefaultParams[1] & {router?: Partial<BlitzRouter>}
type DefaultHookParams = Parameters<typeof defaultRenderHook>
type RenderHook = DefaultHookParams[0]
type RenderHookOptions = DefaultHookParams[1] & {
router?: Partial<BlitzRouter>
dehydratedState?: unknown
}
type RenderHookOptions = DefaultHookParams[1] & {router?: Partial<BlitzRouter>}

View File

@@ -14,9 +14,8 @@
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"downlevelIteration": true,
"jsx": "preserve"
},
"exclude": ["node_modules", "cypress"],
"include": ["**/*.ts", "**/*.tsx"]
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

View File

@@ -1 +0,0 @@
../../types

View File

@@ -1,4 +1,5 @@
import {DefaultCtx, SessionContext, SimpleRolesIsAuthorized} from "blitz"
import {DefaultCtx, SessionContext} from "blitz"
import {SimpleRolesIsAuthorized} from "@blitzjs/server"
import {User} from "db"
export type Role = "ADMIN" | "USER"
@@ -11,16 +12,8 @@ declare module "blitz" {
isAuthorized: SimpleRolesIsAuthorized<Role>
PublicData: {
userId: User["id"]
role: Role
roles: Role[]
views?: number
}
}
}
// This should not be needed. Usually it isn't but for some reason in this example it is
declare module "react" {
interface StyleHTMLAttributes<T> extends React.HTMLAttributes<T> {
jsx?: boolean
global?: boolean
}
}

View File

@@ -8,7 +8,7 @@
```
2. Migrate
```sh
blitz prisma migrate dev
blitz prisma migrate dev --preview-feature
```
3. Start the dev server

View File

@@ -9,7 +9,7 @@ export default async function login(input: LoginInputType, {session}: Ctx) {
// This throws an error if credentials are invalid
const user = await authenticateUser(email, password)
await session.$create({userId: user.id})
await session.$create({userId: user.id, roles: [user.role]})
return user
}

View File

@@ -13,7 +13,7 @@ export default async function signup(input: SignupInputType, {session}: Ctx) {
select: {id: true, name: true, email: true, role: true},
})
await session.$create({userId: user.id})
await session.$create({userId: user.id, roles: [user.role]})
return user
}

View File

@@ -1,4 +1,4 @@
import {z} from "zod"
import * as z from "zod"
export const SignupInput = z.object({
email: z.string().email(),

View File

@@ -1,7 +1,6 @@
import React, {ReactNode, PropsWithoutRef} from "react"
import {Form as FinalForm, FormProps as FinalFormProps} from "react-final-form"
import {z} from "zod"
import {validateZodSchema} from "blitz"
import * as z from "zod"
export {FORM_ERROR} from "final-form"
type FormProps<S extends z.ZodType<any, any>> = {
@@ -25,7 +24,14 @@ export function Form<S extends z.ZodType<any, any>>({
return (
<FinalForm
initialValues={initialValues}
validate={validateZodSchema(schema)}
validate={(values) => {
if (!schema) return
try {
schema.parse(values)
} catch (error) {
return error.formErrors.fieldErrors
}
}}
onSubmit={onSubmit}
render={({handleSubmit, submitting, submitError}) => (
<form onSubmit={handleSubmit} className="form" {...props}>

View File

@@ -1,26 +1,28 @@
import {
AppProps,
ErrorBoundary,
ErrorFallbackProps,
ErrorComponent,
AuthenticationError,
AuthorizationError,
useQueryErrorResetBoundary,
} from "blitz"
import {AppProps, ErrorComponent, useRouter, AuthenticationError, AuthorizationError} from "blitz"
import {ErrorBoundary, FallbackProps} from "react-error-boundary"
import {queryCache} from "react-query"
import LoginForm from "app/auth/components/LoginForm"
export default function App({Component, pageProps}: AppProps) {
const getLayout = Component.getLayout || ((page) => page)
const {reset} = useQueryErrorResetBoundary()
const router = useRouter()
return (
<ErrorBoundary FallbackComponent={RootErrorFallback} onReset={reset}>
<ErrorBoundary
FallbackComponent={RootErrorFallback}
resetKeys={[router.asPath]}
onReset={() => {
// This ensures the Blitz useQuery hooks will automatically refetch
// data any time you reset the error boundary
queryCache.resetErrorBoundaries()
}}
>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
)
}
function RootErrorFallback({error, resetErrorBoundary}: ErrorFallbackProps) {
function RootErrorFallback({error, resetErrorBoundary}: FallbackProps) {
if (error instanceof AuthenticationError) {
return <LoginForm onSuccess={resetErrorBoundary} />
} else if (error instanceof AuthorizationError) {

View File

@@ -0,0 +1,26 @@
import React from "react"
import {render} from "test/utils"
import Home from "./index"
import {useCurrentUser} from "app/hooks/useCurrentUser"
jest.mock("app/hooks/useCurrentUser")
const mockUseCurrentUser = useCurrentUser as jest.MockedFunction<typeof useCurrentUser>
test.skip("renders blitz documentation link", () => {
// This is an example of how to ensure a specific item is in the document
// But it's disabled by default (by test.skip) so the test doesn't fail
// when you remove the the default content from the page
// This is an example on how to mock api hooks when testing
mockUseCurrentUser.mockReturnValue({
id: 1,
name: "User",
email: "user@email.com",
role: "user",
})
const {getByText} = render(<Home />)
const linkElement = getByText(/Documentation/i)
expect(linkElement).toBeInTheDocument()
})

View File

@@ -74,7 +74,7 @@ const Home: BlitzPage = () => {
<code>blitz generate all project name:string</code>
</pre>
<pre>
<code>blitz prisma migrate dev</code>
<code>blitz prisma migrate dev --preview-feature</code>
</pre>
<div>
<p>

View File

@@ -1,9 +1,8 @@
const {sessionMiddleware, simpleRolesIsAuthorized} = require("blitz")
const {sessionMiddleware, simpleRolesIsAuthorized} = require("@blitzjs/server")
module.exports = {
middleware: [
sessionMiddleware({
cookiePrefix: "blitz-custom-server-example",
isAuthorized: simpleRolesIsAuthorized,
}),
],

View File

@@ -30,13 +30,11 @@ describe("index page", () => {
cy.signup(user)
cy.contains("button", "Logout").click()
cy.wait(500)
cy.contains("a", /login/i).click()
cy.contains("Email").find("input").type(user.email)
cy.contains("Password").find("input").type(user.password)
cy.contains("button", /login/i).click()
cy.wait(500)
cy.location("pathname").should("equal", "/")
cy.contains("button", "Logout")

View File

@@ -1,8 +1,8 @@
{
"name": "@examples/custom-server",
"version": "0.34.0-canary.0",
"version": "0.30.0-canary.6",
"scripts": {
"dev": "blitz dev",
"dev": "nodemon --watch server.js --exec 'blitz dev'",
"build": "blitz build",
"start": "blitz start",
"studio": "blitz prisma studio",
@@ -10,11 +10,10 @@
"test-watch": "jest --watch",
"cy-open": "cypress open",
"cy-run": "cypress run",
"test:migrate": "prisma generate && blitz prisma migrate deploy",
"test:jest": "jest --passWithNoTests",
"test:migrate": "prisma generate && blitz prisma migrate deploy --preview-feature",
"test:jest": "jest",
"test-server": "blitz build && blitz start",
"test-run-e2e": "cross-env NODE_ENV=test PORT=3099 start-server-and-test test-server http://localhost:3099 cy-run",
"test:e2e": "yarn test-run-e2e || yarn test-run-e2e",
"test:e2e": "cross-env NODE_ENV=test PORT=3099 start-server-and-test test-server http://localhost:3099 cy-run",
"test": "run-s test:*"
},
"browserslist": [
@@ -29,31 +28,62 @@
"bracketSpacing": false,
"trailingComma": "all"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged && pretty-quick --staged",
"pre-push": "tsc && npm run lint && npm run test"
}
},
"lint-staged": {
"*.{js,ts,tsx}": [
"eslint --fix"
]
},
"dependencies": {
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"@prisma/client": "2.16.0",
"blitz": "0.30.0-canary.6",
"final-form": "4.20.1",
"prisma": "2.24.1",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701",
"prisma": "2.16.0",
"react": "0.0.0-experimental-3310209d0",
"react-dom": "0.0.0-experimental-3310209d0",
"react-error-boundary": "2.3.2",
"react-final-form": "6.5.2",
"secure-password": "4.0.0"
"secure-password": "4.0.0",
"typescript": "4.1.3",
"zod": "1.11.11"
},
"devDependencies": {
"@cypress/skip-test": "2.6.0",
"@testing-library/react": "11.2.5",
"@testing-library/react-hooks": "^4.0.1",
"@types/react": "17.0.13",
"@testing-library/jest-dom": "5.11.9",
"@testing-library/react": "11.2.3",
"@testing-library/react-hooks": "4.0.1",
"@types/jest": "26.0.20",
"@types/react": "16.14.1",
"@types/secure-password": "3.1.0",
"@typescript-eslint/eslint-plugin": "4.12.0",
"@typescript-eslint/parser": "4.12.0",
"babel-eslint": "10.1.0",
"cypress": "6.2.1",
"eslint": "7.21.0",
"husky": "5.1.2",
"lint-staged": "10.5.4",
"eslint": "7.18.0",
"eslint-config-react-app": "5.2.1",
"eslint-plugin-cypress": "2.11.1",
"eslint-plugin-flowtype": "5.2.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-react": "7.21.5",
"eslint-plugin-react-hooks": "4.2.0",
"husky": "4.3.8",
"jest": "26.6.3",
"jest-environment-jsdom-fourteen": "1.0.1",
"jest-watch-typeahead": "0.6.1",
"lint-staged": "10.5.1",
"nodemon": "2.0.7",
"npm-run-all": "4.1.5",
"prettier": "2.2.1",
"prettier": "2.2.0",
"pretty-quick": "3.1.0",
"start-server-and-test": "1.11.7"
"react-test-renderer": "16.14.0",
"start-server-and-test": "1.11.2",
"ts-jest": "26.5.0"
},
"private": true
}

View File

@@ -1,7 +1,7 @@
import blitz from "blitz/custom-server"
import {createServer} from "http"
import {parse} from "url"
import {log} from "@blitzjs/display"
const {createServer} = require("http")
const {parse} = require("url")
const blitz = require("@blitzjs/server")
const {log} = require("@blitzjs/display")
const {PORT = "3000"} = process.env
const dev = process.env.NODE_ENV !== "production"
@@ -10,7 +10,7 @@ const handle = app.getRequestHandler()
app.prepare().then(() => {
createServer((req, res) => {
const parsedUrl = parse(req.url!, true)
const parsedUrl = parse(req.url, true)
const {pathname} = parsedUrl
if (pathname === "/hello") {

View File

@@ -1,5 +1,5 @@
import React from "react"
import {RouterContext, BlitzRouter, BlitzProvider} from "blitz"
import {RouterContext, BlitzRouter} from "blitz"
import {render as defaultRender} from "@testing-library/react"
import {renderHook as defaultRenderHook} from "@testing-library/react-hooks"
@@ -25,18 +25,11 @@ export * from "@testing-library/react"
// router: { pathname: '/my-custom-pathname' },
// });
// --------------------------------------------------
export function render(
ui: RenderUI,
{wrapper, router, dehydratedState, ...options}: RenderOptions = {},
) {
export function render(ui: RenderUI, {wrapper, router, ...options}: RenderOptions = {}) {
if (!wrapper) {
// Add a default context wrapper if one isn't supplied from the test
wrapper = ({children}) => (
<BlitzProvider dehydratedState={dehydratedState}>
<RouterContext.Provider value={{...mockRouter, ...router}}>
{children}
</RouterContext.Provider>
</BlitzProvider>
<RouterContext.Provider value={{...mockRouter, ...router}}>{children}</RouterContext.Provider>
)
}
return defaultRender(ui, {wrapper, ...options})
@@ -55,16 +48,12 @@ export function render(
// --------------------------------------------------
export function renderHook(
hook: RenderHook,
{wrapper, router, dehydratedState, ...options}: RenderHookOptions = {},
{wrapper, router, ...options}: RenderHookOptions = {},
) {
if (!wrapper) {
// Add a default context wrapper if one isn't supplied from the test
wrapper = ({children}) => (
<BlitzProvider dehydratedState={dehydratedState}>
<RouterContext.Provider value={{...mockRouter, ...router}}>
{children}
</RouterContext.Provider>
</BlitzProvider>
<RouterContext.Provider value={{...mockRouter, ...router}}>{children}</RouterContext.Provider>
)
}
return defaultRenderHook(hook, {wrapper, ...options})
@@ -78,8 +67,6 @@ export const mockRouter: BlitzRouter = {
params: {},
query: {},
isReady: true,
isLocaleDomain: false,
isPreview: false,
push: jest.fn(),
replace: jest.fn(),
reload: jest.fn(),
@@ -96,14 +83,8 @@ export const mockRouter: BlitzRouter = {
type DefaultParams = Parameters<typeof defaultRender>
type RenderUI = DefaultParams[0]
type RenderOptions = DefaultParams[1] & {
router?: Partial<BlitzRouter>
dehydratedState?: unknown
}
type RenderOptions = DefaultParams[1] & {router?: Partial<BlitzRouter>}
type DefaultHookParams = Parameters<typeof defaultRenderHook>
type RenderHook = DefaultHookParams[0]
type RenderHookOptions = DefaultHookParams[1] & {
router?: Partial<BlitzRouter>
dehydratedState?: unknown
}
type RenderHookOptions = DefaultHookParams[1] & {router?: Partial<BlitzRouter>}

View File

@@ -1 +0,0 @@
../../types

View File

@@ -1,4 +1,5 @@
import {DefaultCtx, SessionContext, SimpleRolesIsAuthorized} from "blitz"
import {DefaultCtx, SessionContext} from "blitz"
import {simpleRolesIsAuthorized} from "@blitzjs/server"
import React from "react"
declare module "blitz" {
@@ -6,9 +7,10 @@ declare module "blitz" {
session: SessionContext
}
export interface Session {
isAuthorized: SimpleRolesIsAuthorized
isAuthorized: typeof simpleRolesIsAuthorized
PublicData: {
userId: number
roles: string[]
}
}
}

View File

@@ -1,2 +1 @@
save-exact=true
legacy-peer-deps=true

View File

@@ -9,7 +9,7 @@ export default async function login(input: LoginInputType, { session }: Ctx) {
// This throws an error if credentials are invalid
const user = await authenticateUser(email, password)
await session.$create({ userId: user.id })
await session.$create({ userId: user.id, roles: [user.role] })
return user
}

View File

@@ -23,7 +23,7 @@ export default async function signup(input: SignupInputType, { session }: Ctx) {
)
console.log("Create user result:", user)
await session.$create({ userId: user.id })
await session.$create({ userId: user.id, roles: [user.role] })
return user
}

View File

@@ -1,4 +1,4 @@
import { z } from "zod"
import * as z from "zod"
export const SignupInput = z.object({
email: z.string().email(),

View File

@@ -1,7 +1,6 @@
import { ReactNode, PropsWithoutRef } from "react"
import { Form as FinalForm, FormProps as FinalFormProps } from "react-final-form"
import { z } from "zod"
import { validateZodSchema } from "blitz"
import * as z from "zod"
export { FORM_ERROR } from "final-form"
type FormProps<S extends z.ZodType<any, any>> = {
@@ -25,7 +24,14 @@ export function Form<S extends z.ZodType<any, any>>({
return (
<FinalForm
initialValues={initialValues}
validate={validateZodSchema(schema)}
validate={(values) => {
if (!schema) return
try {
schema.parse(values)
} catch (error) {
return error.formErrors.fieldErrors
}
}}
onSubmit={onSubmit}
render={({ handleSubmit, submitting, submitError }) => (
<form onSubmit={handleSubmit} className="form" {...props}>

View File

@@ -1,24 +1,28 @@
import {
AppProps,
ErrorBoundary,
ErrorFallbackProps,
ErrorComponent,
useQueryErrorResetBoundary,
} from "blitz"
import { AppProps, ErrorComponent, useRouter } from "blitz"
import { ErrorBoundary, FallbackProps } from "react-error-boundary"
import { queryCache } from "react-query"
import LoginForm from "app/auth/components/LoginForm"
export default function App({ Component, pageProps }: AppProps) {
const getLayout = Component.getLayout || ((page) => page)
const { reset } = useQueryErrorResetBoundary()
const router = useRouter()
return (
<ErrorBoundary FallbackComponent={RootErrorFallback} onReset={reset}>
<ErrorBoundary
FallbackComponent={RootErrorFallback}
resetKeys={[router.asPath]}
onReset={() => {
// This ensures the Blitz useQuery hooks will automatically refetch
// data any time you reset the error boundary
queryCache.resetErrorBoundaries()
}}
>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
)
}
function RootErrorFallback({ error, resetErrorBoundary }: ErrorFallbackProps) {
function RootErrorFallback({ error, resetErrorBoundary }: FallbackProps) {
if (error?.name === "AuthenticationError") {
return <LoginForm onSuccess={resetErrorBoundary} />
} else if (error?.name === "AuthorizationError") {

View File

@@ -1,4 +1,4 @@
const { sessionMiddleware, simpleRolesIsAuthorized } = require("blitz")
const { sessionMiddleware, simpleRolesIsAuthorized } = require("@blitzjs/server")
const { GraphQLClient, gql } = require("graphql-request")
const graphQLClient = new GraphQLClient("https://graphql.fauna.com/graphql", {
@@ -20,7 +20,6 @@ const normalizeSession = (faunaSession) => {
module.exports = {
middleware: [
sessionMiddleware({
cookiePrefix: "blitz-fauna-example",
isAuthorized: simpleRolesIsAuthorized,
getSession: async (handle) => {
const { findSessionByHandle: session } = await graphQLClient.request(

View File

@@ -1,6 +1,6 @@
{
"name": "@examples/fauna",
"version": "0.34.0-canary.0",
"version": "0.30.0-canary.6",
"scripts": {
"dev": "blitz dev",
"build": "blitz build",
@@ -28,29 +28,44 @@
]
},
"dependencies": {
"blitz": "0.38.3-canary.1",
"blitz": "0.30.0-canary.6",
"final-form": "4.20.1",
"graphql": "15.5.0",
"graphql-request": "3.4.0",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701",
"react-final-form": "6.5.2"
"react": "0.0.0-experimental-3310209d0",
"react-dom": "0.0.0-experimental-3310209d0",
"react-error-boundary": "3.1.0",
"react-final-form": "6.5.2",
"secure-password": "4.0.0",
"zod": "1.11.11"
},
"devDependencies": {
"@testing-library/react": "11.2.5",
"@testing-library/react-hooks": "^4.0.1",
"@types/react": "17.0.13",
"@testing-library/jest-dom": "5.11.9",
"@testing-library/react": "11.2.3",
"@testing-library/react-hooks": "4.0.1",
"@types/jest": "26.0.20",
"@types/react": "17.0.0",
"@types/secure-password": "3.1.0",
"babel-eslint": "~10.1.0",
"eslint": "7.21.0",
"eslint-config-react-app": "~6.0.0",
"eslint-plugin-flowtype": "~5.2.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.23.1",
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "5.1.2",
"start-server-and-test": "1.11.7"
"@typescript-eslint/eslint-plugin": "4.12.0",
"@typescript-eslint/parser": "4.12.0",
"babel-eslint": "10.1.0",
"eslint": "7.18.0",
"eslint-config-react-app": "6.0.0",
"eslint-plugin-flowtype": "5.2.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-react": "7.22.0",
"eslint-plugin-react-hooks": "4.2.0",
"husky": "4.3.8",
"jest": "26.6.3",
"jest-environment-jsdom-fourteen": "1.0.1",
"jest-watch-typeahead": "0.6.1",
"lint-staged": "10.5.3",
"prettier": "2.2.1",
"pretty-quick": "3.1.0",
"start-server-and-test": "1.11.7",
"ts-jest": "26.5.0",
"typescript": "4.1.3"
},
"private": true
}

View File

@@ -1,4 +1,4 @@
import { RouterContext, BlitzRouter, BlitzProvider } from "blitz"
import { RouterContext, BlitzRouter } from "blitz"
import { render as defaultRender } from "@testing-library/react"
import { renderHook as defaultRenderHook } from "@testing-library/react-hooks"
@@ -15,17 +15,11 @@ export * from "@testing-library/react"
type DefaultParams = Parameters<typeof defaultRender>
type RenderUI = DefaultParams[0]
type RenderOptions = DefaultParams[1] & {
router?: Partial<BlitzRouter>
dehydratedState?: unknown
}
type RenderOptions = DefaultParams[1] & { router?: Partial<BlitzRouter> }
type DefaultHookParams = Parameters<typeof defaultRenderHook>
type RenderHook = DefaultHookParams[0]
type RenderHookOptions = DefaultHookParams[1] & {
router?: Partial<BlitzRouter>
dehydratedState?: unknown
}
type RenderHookOptions = DefaultHookParams[1] & { router?: Partial<BlitzRouter> }
// --------------------------------------------------
// render()
@@ -38,18 +32,13 @@ type RenderHookOptions = DefaultHookParams[1] & {
// router: { pathname: '/my-custom-pathname' },
// });
// --------------------------------------------------
export function render(
ui: RenderUI,
{ wrapper, router, dehydratedState, ...options }: RenderOptions = {}
) {
export function render(ui: RenderUI, { wrapper, router, ...options }: RenderOptions = {}) {
if (!wrapper) {
// Add a default context wrapper if one isn't supplied from the test
wrapper = ({ children }) => (
<BlitzProvider dehydratedState={dehydratedState}>
<RouterContext.Provider value={{ ...mockRouter, ...router }}>
{children}
</RouterContext.Provider>
</BlitzProvider>
<RouterContext.Provider value={{ ...mockRouter, ...router }}>
{children}
</RouterContext.Provider>
)
}
return defaultRender(ui, { wrapper, ...options })
@@ -68,16 +57,14 @@ export function render(
// --------------------------------------------------
export function renderHook(
hook: RenderHook,
{ wrapper, router, dehydratedState, ...options }: RenderHookOptions = {}
{ wrapper, router, ...options }: RenderHookOptions = {}
) {
if (!wrapper) {
// Add a default context wrapper if one isn't supplied from the test
wrapper = ({ children }) => (
<BlitzProvider dehydratedState={dehydratedState}>
<RouterContext.Provider value={{ ...mockRouter, ...router }}>
{children}
</RouterContext.Provider>
</BlitzProvider>
<RouterContext.Provider value={{ ...mockRouter, ...router }}>
{children}
</RouterContext.Provider>
)
}
return defaultRenderHook(hook, { wrapper, ...options })
@@ -91,8 +78,6 @@ export const mockRouter: BlitzRouter = {
params: {},
query: {},
isReady: true,
isLocaleDomain: false,
isPreview: false,
push: jest.fn(),
replace: jest.fn(),
reload: jest.fn(),

View File

@@ -1 +0,0 @@
../../types

View File

@@ -1,13 +1,15 @@
import { DefaultCtx, SessionContext, SimpleRolesIsAuthorized } from "blitz"
import { DefaultCtx, SessionContext } from "blitz"
import { simpleRolesIsAuthorized } from "@blitzjs/server"
declare module "blitz" {
export interface Ctx extends DefaultCtx {
session: SessionContext
}
export interface Session {
isAuthorized: SimpleRolesIsAuthorized
isAuthorized: typeof simpleRolesIsAuthorized
PublicData: {
userId: string
roles: string[]
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@examples/no-prisma",
"version": "0.34.0-canary.0",
"name": "no-prisma",
"version": "0.30.0-canary.6",
"scripts": {
"dev": "blitz dev",
"build": "blitz build",
@@ -17,7 +17,8 @@
},
"husky": {
"hooks": {
"pre-commit": "lint-staged && pretty-quick --staged"
"pre-commit": "lint-staged && pretty-quick --staged",
"pre-push": "blitz test"
}
},
"lint-staged": {
@@ -26,26 +27,29 @@
]
},
"dependencies": {
"blitz": "0.38.3-canary.1",
"blitz": "0.30.0-canary.6",
"knex": "0.21.16",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701",
"sqlite3": "5.0.2"
"react": "0.0.0-experimental-3310209d0",
"react-dom": "0.0.0-experimental-3310209d0",
"sqlite3": "5.0.0"
},
"devDependencies": {
"@types/react": "17.0.13",
"babel-eslint": "~10.1.0",
"eslint": "7.21.0",
"eslint-config-react-app": "~6.0.0",
"eslint-plugin-flowtype": "~5.2.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.23.1",
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "5.1.2",
"lint-staged": "10.5.4",
"@types/react": "17.0.0",
"@typescript-eslint/eslint-plugin": "4.12.0",
"@typescript-eslint/parser": "4.12.0",
"babel-eslint": "10.1.0",
"eslint": "7.18.0",
"eslint-config-react-app": "6.0.0",
"eslint-plugin-flowtype": "5.2.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-react": "7.22.0",
"eslint-plugin-react-hooks": "4.2.0",
"husky": "4.3.8",
"lint-staged": "10.5.3",
"prettier": "2.2.1",
"pretty-quick": "3.1.0"
"pretty-quick": "3.1.0",
"typescript": "4.1.3"
},
"private": true
}

View File

@@ -1 +0,0 @@
../../types

View File

@@ -14,7 +14,7 @@ model Project {
2. DB migrate
```
blitz prisma migrate dev
blitz prisma migrate dev --preview-feature
```
3. Start the dev server

View File

@@ -3,7 +3,7 @@ const modelSnippet = `model Project {
id Int @default(autoincrement()) @id
name String
}`
const migrateSnippet = `$ blitz prisma migrate dev
const migrateSnippet = `$ blitz prisma migrate dev --preview-feature
$ blitz generate all project`
const Home = () => (

View File

@@ -1,9 +1,9 @@
{
"name": "@examples/plain-js",
"version": "0.34.0-canary.0",
"version": "0.30.0-canary.6",
"scripts": {
"dev": "blitz dev",
"build": "blitz prisma migrate deploy && blitz build",
"build": "blitz prisma migrate deploy --preview-feature && blitz build",
"start": "blitz start",
"lint": "eslint --ignore-path .gitignore --ext .js,.ts,.tsx .",
"test": "echo \"DISABLED\""
@@ -11,9 +11,6 @@
"browserslist": [
"defaults"
],
"prisma": {
"schema": "db/schema.prisma"
},
"prettier": {
"semi": false,
"printWidth": 100,
@@ -22,7 +19,8 @@
},
"husky": {
"hooks": {
"pre-commit": "lint-staged && pretty-quick --staged"
"pre-commit": "lint-staged && pretty-quick --staged",
"pre-push": "blitz test"
}
},
"lint-staged": {
@@ -32,25 +30,28 @@
]
},
"dependencies": {
"@prisma/client": "2.24.1",
"blitz": "0.38.3-canary.1",
"prisma": "2.24.1",
"react": "18.0.0-alpha-ed6c091fe-20210701",
"react-dom": "18.0.0-alpha-ed6c091fe-20210701"
"@prisma/client": "2.16.0",
"blitz": "0.30.0-canary.6",
"prisma": "2.16.0",
"react": "0.0.0-experimental-3310209d0",
"react-dom": "0.0.0-experimental-3310209d0"
},
"devDependencies": {
"babel-eslint": "~10.1.0",
"eslint": "7.21.0",
"eslint-config-react-app": "~6.0.0",
"eslint-plugin-flowtype": "~5.2.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.23.1",
"eslint-plugin-react-hooks": "^4.2.0",
"husky": "5.1.2",
"lint-staged": "10.5.4",
"@typescript-eslint/eslint-plugin": "4.12.0",
"@typescript-eslint/parser": "4.12.0",
"babel-eslint": "10.1.0",
"eslint": "7.18.0",
"eslint-config-react-app": "6.0.0",
"eslint-plugin-flowtype": "5.2.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-jsx-a11y": "6.4.1",
"eslint-plugin-react": "7.22.0",
"eslint-plugin-react-hooks": "4.2.0",
"husky": "4.3.8",
"lint-staged": "10.5.3",
"prettier": "2.2.1",
"pretty-quick": "3.1.0"
"pretty-quick": "3.1.0",
"typescript": "4.1.3"
},
"private": true
}

10059
examples/plain-js/yarn.lock Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +0,0 @@
# This env file should be checked into source control
# This is the place for default values for all environments
# Values in `.env.local` and `.env.production` will override these values

View File

@@ -1,52 +0,0 @@
# dependencies
node_modules
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.pnp.*
.npm
web_modules/
# blitz
/.blitz/
/.next/
*.sqlite
.now
.blitz-console-history
blitz-log.log
# misc
.DS_Store
# local env files
.env.local
.env.*.local
.envrc
# Logs
logs
*.log
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Testing
.coverage
*.lcov
.nyc_output
lib-cov
# Caches
*.tsbuildinfo
.eslintcache
.node_repl_history
.yarn-integrity
# Serverless directories
.serverless/
# Stores VSCode versions used for testing VSCode extensions
.vscode-test

View File

@@ -1,7 +0,0 @@
.gitkeep
.env*
*.ico
*.lock
db/migrations
.next
.blitz

View File

@@ -1,3 +0,0 @@
# Static
This is an example to demonstrate usage of `blitz export`.

Some files were not shown because too many files have changed in this diff Show More