Use superforms and zod

This commit is contained in:
Santiago Lo Coco 2024-05-09 11:47:46 +02:00
parent b47096f048
commit 7d0bf9b3ef
5 changed files with 533 additions and 31 deletions

487
package-lock.json generated
View File

@ -7,6 +7,7 @@
"": { "": {
"name": "breakoften", "name": "breakoften",
"version": "0.0.1", "version": "0.0.1",
"hasInstallScript": true,
"dependencies": { "dependencies": {
"@prisma/client": "^5.13.0", "@prisma/client": "^5.13.0",
"bcrypt": "^5.1.1" "bcrypt": "^5.1.1"
@ -23,11 +24,13 @@
"prisma": "^5.13.0", "prisma": "^5.13.0",
"svelte": "5.0.0-next.54", "svelte": "5.0.0-next.54",
"svelte-check": "^3.6.0", "svelte-check": "^3.6.0",
"sveltekit-superforms": "^2.13.1",
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"tslib": "^2.4.1", "tslib": "^2.4.1",
"tw-colors": "^3.3.1", "tw-colors": "^3.3.1",
"typescript": "^5.0.0", "typescript": "^5.0.0",
"vite": "^5.1.4" "vite": "^5.1.4",
"zod": "^3.23.8"
} }
}, },
"node_modules/@alloc/quick-lru": { "node_modules/@alloc/quick-lru": {
@ -55,6 +58,19 @@
"node": ">=6.0.0" "node": ">=6.0.0"
} }
}, },
"node_modules/@babel/runtime": {
"version": "7.24.5",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz",
"integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==",
"dev": true,
"optional": true,
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@esbuild/aix-ppc64": { "node_modules/@esbuild/aix-ppc64": {
"version": "0.20.2", "version": "0.20.2",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
@ -423,6 +439,46 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/@exodus/schemasafe": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@exodus/schemasafe/-/schemasafe-1.3.0.tgz",
"integrity": "sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==",
"dev": true,
"optional": true
},
"node_modules/@gcornut/valibot-json-schema": {
"version": "0.0.27",
"resolved": "https://registry.npmjs.org/@gcornut/valibot-json-schema/-/valibot-json-schema-0.0.27.tgz",
"integrity": "sha512-xcMaUStVgQzPrK3d7PuLFbQ+3qSp6LzaLExAm52E3FKmUfjQa7Sw5cDK6Hfu/8WT0yfGsuSCuJ5uT1sosjR9Qg==",
"dev": true,
"optional": true,
"bin": {
"valibot-json-schema": "bin/index.js"
},
"peerDependencies": {
"@types/json-schema": ">= 7.0.14",
"esbuild": ">= 0.18.20",
"esbuild-runner": ">= 2.2.2",
"valibot": ">= 0.21.0"
}
},
"node_modules/@hapi/hoek": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz",
"integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==",
"dev": true,
"optional": true
},
"node_modules/@hapi/topo": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz",
"integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==",
"dev": true,
"optional": true,
"dependencies": {
"@hapi/hoek": "^9.0.0"
}
},
"node_modules/@isaacs/cliui": { "node_modules/@isaacs/cliui": {
"version": "8.0.2", "version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
@ -572,6 +628,16 @@
"integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==", "integrity": "sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==",
"dev": true "dev": true
}, },
"node_modules/@poppinss/macroable": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@poppinss/macroable/-/macroable-1.0.2.tgz",
"integrity": "sha512-xhhEcEvhQC8mP5oOr5hbE4CmUgmw/IPV1jhpGg2xSkzoFrt9i8YVqBQt9744EFesi5F7pBheWozg63RUBM/5JA==",
"dev": true,
"optional": true,
"engines": {
"node": ">=18.16.0"
}
},
"node_modules/@prisma/client": { "node_modules/@prisma/client": {
"version": "5.13.0", "version": "5.13.0",
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.13.0.tgz", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-5.13.0.tgz",
@ -842,6 +908,44 @@
"win32" "win32"
] ]
}, },
"node_modules/@sideway/address": {
"version": "4.1.5",
"resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz",
"integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==",
"dev": true,
"optional": true,
"dependencies": {
"@hapi/hoek": "^9.0.0"
}
},
"node_modules/@sideway/formula": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
"integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
"dev": true,
"optional": true
},
"node_modules/@sideway/pinpoint": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz",
"integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==",
"dev": true,
"optional": true
},
"node_modules/@sinclair/typebox": {
"version": "0.32.29",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.32.29.tgz",
"integrity": "sha512-GWKskKPGQV0vVYizqCu0E1YLwGthvlkDqpRxB3iBuqxJ8dN/9n1cnDRSQHF59GMoxDJwzSgmxpU617SidtUnMw==",
"dev": true,
"optional": true
},
"node_modules/@sodaru/yup-to-json-schema": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@sodaru/yup-to-json-schema/-/yup-to-json-schema-2.0.1.tgz",
"integrity": "sha512-lWb0Wiz8KZ9ip/dY1eUqt7fhTPmL24p6Hmv5Fd9pzlzAdw/YNcWZr+tiCT4oZ4Zyxzi9+1X4zv82o7jYvcFxYA==",
"dev": true,
"optional": true
},
"node_modules/@sveltejs/adapter-auto": { "node_modules/@sveltejs/adapter-auto": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.0.tgz", "resolved": "https://registry.npmjs.org/@sveltejs/adapter-auto/-/adapter-auto-3.2.0.tgz",
@ -949,12 +1053,57 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true "dev": true
}, },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true,
"optional": true,
"peer": true
},
"node_modules/@types/pug": { "node_modules/@types/pug": {
"version": "2.0.10", "version": "2.0.10",
"resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz", "resolved": "https://registry.npmjs.org/@types/pug/-/pug-2.0.10.tgz",
"integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==", "integrity": "sha512-Sk/uYFOBAB7mb74XcpizmH0KOR2Pv3D2Hmrh1Dmy5BmK3MpdSa5kqZcg6EKBdklU0bFXX9gCfzvpnyUehrPIuA==",
"dev": true "dev": true
}, },
"node_modules/@types/validator": {
"version": "13.11.9",
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.9.tgz",
"integrity": "sha512-FCTsikRozryfayPuiI46QzH3fnrOoctTjvOYZkho9BTFLCOZ2rgZJHMOVgCOfttjPJcgOx52EpkY0CMfy87MIw==",
"dev": true,
"optional": true
},
"node_modules/@vinejs/compiler": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/@vinejs/compiler/-/compiler-2.5.0.tgz",
"integrity": "sha512-hg4ekaB5Y2zh+IWzBiC/WCDWrIfpVnKu/ubUvelKlidc/VbulsexoFRw5kJGHZenPVI5YzNnDeTdYSALkTV7jQ==",
"dev": true,
"optional": true,
"engines": {
"node": ">=18.0.0"
}
},
"node_modules/@vinejs/vine": {
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/@vinejs/vine/-/vine-1.8.0.tgz",
"integrity": "sha512-Qq3XxbA26jzqS9ICifkqzT399lMQZ2fWtqeV3luI2as+UIK7qDifJFU2Q4W3q3IB5VXoWxgwAZSZEO0em9I/qQ==",
"dev": true,
"optional": true,
"dependencies": {
"@poppinss/macroable": "^1.0.1",
"@types/validator": "^13.11.9",
"@vinejs/compiler": "^2.4.1",
"camelcase": "^8.0.0",
"dayjs": "^1.11.10",
"dlv": "^1.1.3",
"normalize-url": "^8.0.1",
"validator": "^13.11.0"
},
"engines": {
"node": ">=18.16.0"
}
},
"node_modules/abbrev": { "node_modules/abbrev": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@ -1067,6 +1216,13 @@
"dequal": "^2.0.3" "dequal": "^2.0.3"
} }
}, },
"node_modules/arktype": {
"version": "1.0.29-alpha",
"resolved": "https://registry.npmjs.org/arktype/-/arktype-1.0.29-alpha.tgz",
"integrity": "sha512-glMLgVhIQRSkR3tymiS+POAcWVJH09sfrgic0jHnyFL8BlhHAJZX2BzdImU9zYr1y9NBqy+U93ZNrRTHXsKRDw==",
"dev": true,
"optional": true
},
"node_modules/autoprefixer": { "node_modules/autoprefixer": {
"version": "10.4.19", "version": "10.4.19",
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz",
@ -1205,6 +1361,14 @@
"node": "*" "node": "*"
} }
}, },
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true,
"optional": true,
"peer": true
},
"node_modules/callsites": { "node_modules/callsites": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
@ -1214,6 +1378,19 @@
"node": ">=6" "node": ">=6"
} }
}, },
"node_modules/camelcase": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
"integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==",
"dev": true,
"optional": true,
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/camelcase-css": { "node_modules/camelcase-css": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz",
@ -1378,6 +1555,13 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/dayjs": {
"version": "1.11.11",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz",
"integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==",
"dev": true,
"optional": true
},
"node_modules/debug": { "node_modules/debug": {
"version": "4.3.4", "version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@ -1514,6 +1698,32 @@
"@esbuild/win32-x64": "0.20.2" "@esbuild/win32-x64": "0.20.2"
} }
}, },
"node_modules/esbuild-runner": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/esbuild-runner/-/esbuild-runner-2.2.2.tgz",
"integrity": "sha512-fRFVXcmYVmSmtYm2mL8RlUASt2TDkGh3uRcvHFOKNr/T58VrfVeKD9uT9nlgxk96u0LS0ehS/GY7Da/bXWKkhw==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"source-map-support": "0.5.21",
"tslib": "2.4.0"
},
"bin": {
"esr": "bin/esr.js"
},
"peerDependencies": {
"esbuild": "*"
}
},
"node_modules/esbuild-runner/node_modules/tslib": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz",
"integrity": "sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==",
"dev": true,
"optional": true,
"peer": true
},
"node_modules/escalade": { "node_modules/escalade": {
"version": "3.1.2", "version": "3.1.2",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
@ -1968,6 +2178,40 @@
"jiti": "bin/jiti.js" "jiti": "bin/jiti.js"
} }
}, },
"node_modules/joi": {
"version": "17.13.1",
"resolved": "https://registry.npmjs.org/joi/-/joi-17.13.1.tgz",
"integrity": "sha512-vaBlIKCyo4FCUtCm7Eu4QZd/q02bWcxfUO6YSXAZOWF6gzcLBeba8kwotUdYJjDLW8Cz8RywsSOqiNJZW0mNvg==",
"dev": true,
"optional": true,
"dependencies": {
"@hapi/hoek": "^9.3.0",
"@hapi/topo": "^5.1.0",
"@sideway/address": "^4.1.5",
"@sideway/formula": "^3.0.1",
"@sideway/pinpoint": "^2.0.0"
}
},
"node_modules/json-schema-to-ts": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.0.tgz",
"integrity": "sha512-UeVN/ery4/JeXI8h4rM8yZPxsH+KqPi/84qFxHfTGHZnWnK9D0UU9ZGYO+6XAaJLqCWMiks+ARuFOKAiSxJCHA==",
"dev": true,
"optional": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"ts-algebra": "^2.0.0"
},
"engines": {
"node": ">=16"
}
},
"node_modules/just-clone": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/just-clone/-/just-clone-6.2.0.tgz",
"integrity": "sha512-1IynUYEc/HAwxhi3WDpIpxJbZpMCvvrrmZVqvj9EhpvbH8lls7HhdhiByjL7DkAaWlLIzpC0Xc/VPvy/UxLNjA==",
"dev": true
},
"node_modules/kleur": { "node_modules/kleur": {
"version": "4.1.5", "version": "4.1.5",
"resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
@ -2044,6 +2288,12 @@
"semver": "bin/semver.js" "semver": "bin/semver.js"
} }
}, },
"node_modules/memoize-weak": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/memoize-weak/-/memoize-weak-1.0.2.tgz",
"integrity": "sha512-gj39xkrjEw7nCn4nJ1M5ms6+MyMlyiGmttzsqAUsAKn6bYKwuTHh/AO3cKPF8IBrTIYTxb0wWXFs3E//Y8VoWQ==",
"dev": true
},
"node_modules/merge2": { "node_modules/merge2": {
"version": "1.4.1", "version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@ -2253,6 +2503,19 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/normalize-url": {
"version": "8.0.1",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.1.tgz",
"integrity": "sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==",
"dev": true,
"optional": true,
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/npmlog": { "node_modules/npmlog": {
"version": "5.0.1", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz",
@ -2566,6 +2829,13 @@
"node": ">=16.13" "node": ">=16.13"
} }
}, },
"node_modules/property-expr": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.6.tgz",
"integrity": "sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==",
"dev": true,
"optional": true
},
"node_modules/queue-microtask": { "node_modules/queue-microtask": {
"version": "1.2.3", "version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@ -2620,6 +2890,13 @@
"node": ">=8.10.0" "node": ">=8.10.0"
} }
}, },
"node_modules/regenerator-runtime": {
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
"dev": true,
"optional": true
},
"node_modules/resolve": { "node_modules/resolve": {
"version": "1.22.8", "version": "1.22.8",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
@ -2876,6 +3153,17 @@
"sorcery": "bin/sorcery" "sorcery": "bin/sorcery"
} }
}, },
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"optional": true,
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": { "node_modules/source-map-js": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
@ -2885,6 +3173,18 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"optional": true,
"peer": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/string_decoder": { "node_modules/string_decoder": {
"version": "1.3.0", "version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
@ -3069,6 +3369,16 @@
"url": "https://github.com/sponsors/isaacs" "url": "https://github.com/sponsors/isaacs"
} }
}, },
"node_modules/superstruct": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/superstruct/-/superstruct-1.0.4.tgz",
"integrity": "sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==",
"dev": true,
"optional": true,
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/supports-preserve-symlinks-flag": { "node_modules/supports-preserve-symlinks-flag": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
@ -3189,6 +3499,89 @@
} }
} }
}, },
"node_modules/sveltekit-superforms": {
"version": "2.13.1",
"resolved": "https://registry.npmjs.org/sveltekit-superforms/-/sveltekit-superforms-2.13.1.tgz",
"integrity": "sha512-kmwC3sNFAiHADLq7E46QBgDk4OEXLrhCQumwRbPcRAOQf/XvBzGBNmQGnIP62Rpiq+qLKbwo40c1gA4QA31bKg==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ciscoheat"
},
{
"type": "ko-fi",
"url": "https://ko-fi.com/ciscoheat"
},
{
"type": "paypal",
"url": "https://www.paypal.com/donate/?hosted_button_id=NY7F5ALHHSVQS"
}
],
"dependencies": {
"devalue": "^5.0.0",
"just-clone": "^6.2.0",
"memoize-weak": "^1.0.2",
"ts-deepmerge": "^7.0.0"
},
"optionalDependencies": {
"@exodus/schemasafe": "^1.3.0",
"@gcornut/valibot-json-schema": "^0.0.27",
"@sinclair/typebox": "^0.32.27",
"@sodaru/yup-to-json-schema": "^2.0.1",
"@vinejs/vine": "^1.8.0",
"arktype": "1.0.29-alpha",
"joi": "^17.13.1",
"json-schema-to-ts": "^3.0.1",
"superstruct": "^1.0.4",
"valibot": "^0.30.0",
"yup": "^1.4.0",
"zod": "^3.23.5",
"zod-to-json-schema": "^3.23.0"
},
"peerDependencies": {
"@exodus/schemasafe": "^1.3.0",
"@sinclair/typebox": ">=0.32.27 <1",
"@sveltejs/kit": "1.x || 2.x",
"@vinejs/vine": "^1.7.1",
"arktype": "1.0.29-alpha",
"joi": "^17.13.1",
"superstruct": "^1.0.3",
"svelte": "3.x || 4.x || >=5.0.0-next.51",
"valibot": ">=0.28.1 <1",
"yup": "^1.3.3",
"zod": "^3.23.5"
},
"peerDependenciesMeta": {
"@exodus/schemasafe": {
"optional": true
},
"@sinclair/typebox": {
"optional": true
},
"@vinejs/vine": {
"optional": true
},
"arktype": {
"optional": true
},
"joi": {
"optional": true
},
"superstruct": {
"optional": true
},
"valibot": {
"optional": true
},
"yup": {
"optional": true
},
"zod": {
"optional": true
}
}
},
"node_modules/tailwindcss": { "node_modules/tailwindcss": {
"version": "3.4.3", "version": "3.4.3",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.3.tgz",
@ -3294,6 +3687,13 @@
"node": ">=0.8" "node": ">=0.8"
} }
}, },
"node_modules/tiny-case": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/tiny-case/-/tiny-case-1.0.3.tgz",
"integrity": "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q==",
"dev": true,
"optional": true
},
"node_modules/tiny-glob": { "node_modules/tiny-glob": {
"version": "0.2.9", "version": "0.2.9",
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz", "resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz",
@ -3316,6 +3716,13 @@
"node": ">=8.0" "node": ">=8.0"
} }
}, },
"node_modules/toposort": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz",
"integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==",
"dev": true,
"optional": true
},
"node_modules/totalist": { "node_modules/totalist": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
@ -3330,6 +3737,22 @@
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
}, },
"node_modules/ts-algebra": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz",
"integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==",
"dev": true,
"optional": true
},
"node_modules/ts-deepmerge": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/ts-deepmerge/-/ts-deepmerge-7.0.0.tgz",
"integrity": "sha512-WZ/iAJrKDhdINv1WG6KZIGHrZDar6VfhftG1QJFpVbOYZMYJLJOvZOo1amictRXVdBXZIgBHKswMTXzElngprA==",
"dev": true,
"engines": {
"node": ">=14.13.1"
}
},
"node_modules/ts-interface-checker": { "node_modules/ts-interface-checker": {
"version": "0.1.13", "version": "0.1.13",
"resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz", "resolved": "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz",
@ -3356,6 +3779,19 @@
"tailwindcss": ">=3.0.0" "tailwindcss": ">=3.0.0"
} }
}, },
"node_modules/type-fest": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
"integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
"dev": true,
"optional": true,
"engines": {
"node": ">=12.20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typescript": { "node_modules/typescript": {
"version": "5.4.5", "version": "5.4.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
@ -3404,6 +3840,23 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
}, },
"node_modules/valibot": {
"version": "0.30.0",
"resolved": "https://registry.npmjs.org/valibot/-/valibot-0.30.0.tgz",
"integrity": "sha512-5POBdbSkM+3nvJ6ZlyQHsggisfRtyT4tVTo1EIIShs6qCdXJnyWU5TJ68vr8iTg5zpOLjXLRiBqNx+9zwZz/rA==",
"dev": true,
"optional": true
},
"node_modules/validator": {
"version": "13.12.0",
"resolved": "https://registry.npmjs.org/validator/-/validator-13.12.0.tgz",
"integrity": "sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==",
"dev": true,
"optional": true,
"engines": {
"node": ">= 0.10"
}
},
"node_modules/vite": { "node_modules/vite": {
"version": "5.2.10", "version": "5.2.10",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz",
@ -3660,11 +4113,43 @@
"node": ">= 14" "node": ">= 14"
} }
}, },
"node_modules/yup": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/yup/-/yup-1.4.0.tgz",
"integrity": "sha512-wPbgkJRCqIf+OHyiTBQoJiP5PFuAXaWiJK6AmYkzQAh5/c2K9hzSApBZG5wV9KoKSePF7sAxmNSvh/13YHkFDg==",
"dev": true,
"optional": true,
"dependencies": {
"property-expr": "^2.0.5",
"tiny-case": "^1.0.3",
"toposort": "^2.0.2",
"type-fest": "^2.19.0"
}
},
"node_modules/zimmerframe": { "node_modules/zimmerframe": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz", "resolved": "https://registry.npmjs.org/zimmerframe/-/zimmerframe-1.1.2.tgz",
"integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==", "integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==",
"dev": true "dev": true
},
"node_modules/zod": {
"version": "3.23.8",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"node_modules/zod-to-json-schema": {
"version": "3.23.0",
"resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.23.0.tgz",
"integrity": "sha512-az0uJ243PxsRIa2x1WmNE/pnuA05gUq/JB8Lwe1EDCCL/Fz9MgjYQ0fPlyc2Tcv6aF2ZA7WM5TWaRZVEFaAIag==",
"dev": true,
"optional": true,
"peerDependencies": {
"zod": "^3.23.3"
}
} }
} }
} }

View File

@ -25,11 +25,13 @@
"prisma": "^5.13.0", "prisma": "^5.13.0",
"svelte": "5.0.0-next.54", "svelte": "5.0.0-next.54",
"svelte-check": "^3.6.0", "svelte-check": "^3.6.0",
"sveltekit-superforms": "^2.13.1",
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"tslib": "^2.4.1", "tslib": "^2.4.1",
"tw-colors": "^3.3.1", "tw-colors": "^3.3.1",
"typescript": "^5.0.0", "typescript": "^5.0.0",
"vite": "^5.1.4" "vite": "^5.1.4",
"zod": "^3.23.8"
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {

View File

@ -20,7 +20,7 @@
{/if} {/if}
{#if form?.credentials} {#if form?.credentials}
<p class="error">You have entered the wrong credentials.</p> <p class="error">Username or password is incorrect.</p>
{/if} {/if}
<button type="submit">Log in</button> <button type="submit">Log in</button>
@ -49,7 +49,7 @@
} }
.error { .error {
@apply text-red-500 mt-4; @apply text-red-500 mb-4;
} }
button { button {

View File

@ -7,29 +7,45 @@ export const load = async ({ locals }) => {
if (locals.user) { if (locals.user) {
throw redirect(302, "/") throw redirect(302, "/")
} }
return {
signUpForm: await superValidate(zod(signUpSchema)),
}
} }
export const actions = { import { setError, superValidate } from "sveltekit-superforms"
register: async ({ request }) => { import { zod } from "sveltekit-superforms/adapters"
const data = await request.formData() import * as z from "zod"
const username = data.get("username") import type { Actions } from "./$types"
const password = data.get("password")
if ( const signUpSchema = z.object({
typeof username !== "string" || username: z.string().min(6).max(128).regex(
typeof password !== "string" || /^[a-zA-Z0-9_-]+$/,
!username || "Username may only contain letters, numbers, hyphens, and underscores"
!password ),
) { password: z.string().min(8).max(128).regex(
return fail(400, { invalid: true }) /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*()_+}{"':;?/><.,\|]).{8,}$/,
"Password requires at least one lowercase letter, one uppercase letter, one digit, and one special character"
),
})
export let actions: Actions = {
register: async ({ request }) => {
const form = await superValidate(request, zod(signUpSchema))
if (!form.valid) {
return fail(400, { form })
} }
const username = form.data.username
const password = form.data.password
const user = await db.user.findUnique({ const user = await db.user.findUnique({
where: { username }, where: { username },
}) })
if (user) { if (user) {
return fail(400, { user: true }) setError(form, "username", "Username already exists")
return fail(400, { form })
} }
await db.user.create({ await db.user.create({

View File

@ -1,22 +1,21 @@
<script lang="ts"> <script lang="ts">
import { enhance } from "$app/forms" import { superForm } from "sveltekit-superforms"
export let form let { data } = $props()
let { form, errors, enhance } = superForm(data.signUpForm)
</script> </script>
<form action="?/register" method="POST" use:enhance> <form action="?/register" method="POST" use:enhance>
<div>
<label for="username">Username</label> <label for="username">Username</label>
<input id="username" name="username" type="text" required /> <input name="username" type="text" bind:value={$form.username} />
</div> {#if $errors.username}
<p class="error">{$errors.username}</p>
{/if}
<div>
<label for="password">Password</label> <label for="password">Password</label>
<input id="password" name="password" type="password" required /> <input name="password" type="password" bind:value={$form.password} />
</div> {#if $errors.password}
<p class="error">{$errors.password}</p>
{#if form?.user}
<p class="error">Username is taken.</p>
{/if} {/if}
<button type="submit">Register</button> <button type="submit">Register</button>
@ -45,7 +44,7 @@
} }
.error { .error {
@apply text-red-500 mt-4; @apply text-red-500 mb-4;
} }
button { button {