Login works

This commit is contained in:
Ebenezer
2026-03-27 15:44:21 +08:00
parent d5c75c9f5c
commit e7816f78f3
1185 changed files with 198529 additions and 34 deletions

208
backend/node_modules/@epic-web/invariant/README.md generated vendored Normal file
View File

@@ -0,0 +1,208 @@
<div>
<h1 align="center"><a href="https://npm.im/@epic-web/invariant">💥 @epic-web/invariant</a></h1>
<strong>
Throw errors when thing's aren't right.
</strong>
<p>
Type safe utilities for throwing errors (and responses) in exceptional
situations in a declarative way.
</p>
</div>
```
npm install @epic-web/invariant
```
<div align="center">
<a
alt="Epic Web logo"
href="https://www.epicweb.dev"
>
<img
width="300px"
src="https://github-production-user-asset-6210df.s3.amazonaws.com/1500684/257881576-fd66040b-679f-4f25-b0d0-ab886a14909a.png"
/>
</a>
</div>
<hr />
<!-- prettier-ignore-start -->
[![Build Status][build-badge]][build]
[![MIT License][license-badge]][license]
[![Code of Conduct][coc-badge]][coc]
<!-- prettier-ignore-end -->
## The Problem
Your application has boundaries. Network requests/responses, file system reads,
etc. When you're working with these boundaries, you need to be able to handle
errors that may occur, even in TypeScript.
TypeScript will typically make these boundaries much more obvious because it
doesn't like not knowing what the type of something is. For example:
```ts
const formData = new FormData(formElement)
const name = await formData.get('name')
// name is `File | string | null`
```
Often it's a good idea to use a proper parsing library for situations like this,
but for simple cases that can often feel like overkill. But you don't want to
just ignore TypeScript because:
> TypeScript is that brutally honest friend you put up with because they save
> you from making terrible mistakes.
> [@kentcdodds](https://twitter.com/kentcdodds/status/1715562350835855396)
So you check it:
```ts
const formData = new FormData(formElement)
const name = await formData.get('name')
// name is `File | string | null`
if (typeof name !== 'string') {
throw new Error('Name must be a string')
}
// now name is `string` (and TypeScript knows it too)
```
You're fine throwing a descriptive error here because it's just _very_ unlikely
this will ever happen and even if it does you wouldn't really know what to do
about it anyway.
It's not a big deal, but there's a tiny bit of boilerplate that would be nice to
avoid. Especially when you find yourself doing this all over the codebase. This
is the problem `@epic-web/invariant` solves.
## The Solution
Here's the diff from what we had above:
```diff
const formData = new FormData(formElement)
const name = await formData.get('name')
// name is `File | string | null`
- if (typeof name !== 'string') {
- throw new Error('Name must be a string')
- }
+ invariant(typeof name === 'string', 'Name must be a string')
// now name is `string` (and TypeScript knows it too)
```
It's pretty simple. But honestly, it's nicer to read, it throws a special
`InvariantError` object to distinguish it from other types of errors, and we
have another useful utility for throwing `Response` objects instead of `Error`
objects which is handy
[in Remix](https://remix.run/docs/en/main/route/loader#throwing-responses-in-loaders).
## Usage
### `invariant`
The `invariant` function is used to assert that a condition is true. If the
condition is false, it throws an error with the provided message.
**Basic Usage**
```ts
import { invariant } from '@epic-web/invariant'
const creature = { name: 'Dragon', type: 'Fire' }
invariant(creature.name === 'Dragon', 'Creature must be a Dragon')
```
**Throwing a Response on False Condition**
```ts
import { invariant } from '@epic-web/invariant'
const creature = { name: 'Unicorn', type: 'Magic' }
invariant(creature.type === 'Fire', 'Creature must be of type Fire')
// Throws: InvariantError: Creature must be of type Fire
```
**Using Callback for Error Message**
```ts
import { invariantResponse } from '@epic-web/invariant'
const creature = { name: 'Elf', type: 'Forest' }
invariant(creature.type === 'Water', () => 'Creature must be of type Water')
// Throws: InvariantError: Creature must be of type Water
```
### `invariantResponse`
The `invariantResponse` function works similarly to `invariant`, but instead of
throwing an `InvariantError`, it throws a Response object.
**Basic Usage**
```ts
import { invariantResponse } from '@epic-web/invariant'
const creature = { name: 'Phoenix', type: 'Fire' }
invariantResponse(creature.type === 'Fire', 'Creature must be of type Fire')
```
**Throwing a Response on False Condition**
```ts
import { invariantResponse } from '@epic-web/invariant'
const creature = { name: 'Griffin', type: 'Air' }
invariantResponse(creature.type === 'Water', 'Creature must be of type Water')
// Throws: Response { status: 400, body: 'Creature must be of type Water' }
```
The response status default if 400 (Bad Request), but you'll find how to change
that below.
**Using Callback for Response Message**
```ts
import { invariantResponse } from '@epic-web/invariant'
const creature = { name: 'Mermaid', type: 'Water' }
invariantResponse(
creature.type === 'Land',
() => `Expected a Land creature, but got a ${creature.type} creature`,
)
```
**Throwing a Response with Additional Options**
```ts
import { invariantResponse } from '@epic-web/invariant'
const creature = { name: 'Cerberus', type: 'Underworld' }
invariantResponse(
creature.type === 'Sky',
JSON.stringify({ error: 'Creature must be of type Sky' }),
{ status: 500, headers: { 'Content-Type': 'text/json' } },
)
```
## Differences from [invariant](https://www.npmjs.com/package/invariant)
There are three main differences. With `@epic-web/invariant`:
1. Error messages are the same in dev and prod
2. It's typesafe
3. We support the common case (for Remix anyway) of throwing Responses as well
with `invariantResponse`.
## License
MIT
<!-- prettier-ignore-start -->
[build-badge]: https://img.shields.io/github/actions/workflow/status/epicweb-dev/invariant/release.yml?branch=main&logo=github&style=flat-square
[build]: https://github.com/epicweb-dev/invariant/actions?query=workflow%3Arelease
[license-badge]: https://img.shields.io/badge/license-MIT%20License-blue.svg?style=flat-square
[license]: https://github.com/epicweb-dev/invariant/blob/main/LICENSE
[coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square
[coc]: https://kentcdodds.com/conduct
<!-- prettier-ignore-end -->

View File

@@ -0,0 +1,36 @@
export declare class InvariantError extends Error {
constructor(message: string);
}
/**
* Provide a condition and if that condition is falsey, this throws an error
* with the given message.
*
* inspired by invariant from 'tiny-invariant' except will still include the
* message in production.
*
* @example
* invariant(typeof value === 'string', `value must be a string`)
*
* @param condition The condition to check
* @param message The message to throw (or a callback to generate the message)
* @param responseInit Additional response init options if a response is thrown
*
* @throws {InvariantError} if condition is falsey
*/
export declare function invariant(condition: any, message: string | (() => string)): asserts condition;
/**
* Provide a condition and if that condition is falsey, this throws a 400
* Response with the given message.
*
* inspired by invariant from 'tiny-invariant'
*
* @example
* invariantResponse(typeof value === 'string', `value must be a string`)
*
* @param condition The condition to check
* @param message The message to throw (or a callback to generate the message)
* @param responseInit Additional response init options if a response is thrown
*
* @throws {Response} if condition is falsey
*/
export declare function invariantResponse(condition: any, message: string | (() => string), responseInit?: ResponseInit): asserts condition;

50
backend/node_modules/@epic-web/invariant/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,50 @@
export class InvariantError extends Error {
constructor(message) {
super(message);
Object.setPrototypeOf(this, InvariantError.prototype);
}
}
/**
* Provide a condition and if that condition is falsey, this throws an error
* with the given message.
*
* inspired by invariant from 'tiny-invariant' except will still include the
* message in production.
*
* @example
* invariant(typeof value === 'string', `value must be a string`)
*
* @param condition The condition to check
* @param message The message to throw (or a callback to generate the message)
* @param responseInit Additional response init options if a response is thrown
*
* @throws {InvariantError} if condition is falsey
*/
export function invariant(condition, message) {
if (!condition) {
throw new InvariantError(typeof message === 'function' ? message() : message);
}
}
/**
* Provide a condition and if that condition is falsey, this throws a 400
* Response with the given message.
*
* inspired by invariant from 'tiny-invariant'
*
* @example
* invariantResponse(typeof value === 'string', `value must be a string`)
*
* @param condition The condition to check
* @param message The message to throw (or a callback to generate the message)
* @param responseInit Additional response init options if a response is thrown
*
* @throws {Response} if condition is falsey
*/
export function invariantResponse(condition, message, responseInit) {
if (!condition) {
throw new Response(typeof message === 'function' ? message() : message, {
status: 400,
...responseInit,
});
}
}

59
backend/node_modules/@epic-web/invariant/package.json generated vendored Normal file
View File

@@ -0,0 +1,59 @@
{
"name": "@epic-web/invariant",
"version": "1.0.0",
"description": "Type safe utilities for throwing errors (and responses) if things aren't quite right. Inspired by npm.im/invariant",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "https://github.com/epicweb-dev/invariant"
},
"bugs": {
"url": "https://github.com/epicweb-dev/invariant/issues"
},
"homepage": "https://github.com/epicweb-dev/invariant#readme",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
},
"files": [
"dist"
],
"scripts": {
"build": "tsc",
"format": "prettier --write .",
"test": "tsx --test --test-reporter spec --experimental-test-coverage test/*.test.ts",
"test:watch": "tsx --test --test-reporter spec --watch test/*.test.ts"
},
"devDependencies": {
"@types/node": "^20.10.4",
"prettier": "^3.1.1",
"tsx": "^4.6.2",
"typescript": "^5.3.3"
},
"prettier": {
"semi": false,
"useTabs": true,
"singleQuote": true,
"proseWrap": "always",
"overrides": [
{
"files": [
"**/*.json"
],
"options": {
"useTabs": false
}
}
]
},
"keywords": [],
"author": "Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com/)",
"license": "MIT"
}