Skip to content

Commit

Permalink
remove custom invariant utility in favor of @epic-stack/invariant
Browse files Browse the repository at this point in the history
  • Loading branch information
kentcdodds committed Dec 14, 2023
1 parent e6f9241 commit 5164851
Show file tree
Hide file tree
Showing 26 changed files with 41 additions and 92 deletions.
2 changes: 1 addition & 1 deletion app/routes/_auth+/auth.$provider.callback.test.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { invariant } from '@epic-web/invariant'
import { faker } from '@faker-js/faker'
import { http } from 'msw'
import { afterEach, expect, test } from 'vitest'
Expand All @@ -6,7 +7,6 @@ import { getSessionExpirationDate, sessionKey } from '#app/utils/auth.server.ts'
import { connectionSessionStorage } from '#app/utils/connections.server.ts'
import { GITHUB_PROVIDER_NAME } from '#app/utils/connections.tsx'
import { prisma } from '#app/utils/db.server.ts'
import { invariant } from '#app/utils/misc.tsx'
import { authSessionStorage } from '#app/utils/session.server.ts'
import { generateTOTP } from '#app/utils/totp.server.ts'
import { createUser } from '#tests/db-utils.ts'
Expand Down
7 changes: 2 additions & 5 deletions app/routes/_auth+/login.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { conform, useForm } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
import { invariant } from '@epic-web/invariant'
import {
json,
redirect,
Expand Down Expand Up @@ -29,11 +30,7 @@ import {
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { checkHoneypot } from '#app/utils/honeypot.server.ts'
import {
combineResponseInits,
invariant,
useIsPending,
} from '#app/utils/misc.tsx'
import { combineResponseInits, useIsPending } from '#app/utils/misc.tsx'
import { authSessionStorage } from '#app/utils/session.server.ts'
import { redirectWithToast } from '#app/utils/toast.server.ts'
import { PasswordSchema, UsernameSchema } from '#app/utils/user-validation.ts'
Expand Down
3 changes: 2 additions & 1 deletion app/routes/_auth+/onboarding.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { conform, useForm } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
import { invariant } from '@epic-web/invariant'
import {
json,
redirect,
Expand All @@ -23,7 +24,7 @@ import { requireAnonymous, sessionKey, signup } from '#app/utils/auth.server.ts'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { checkHoneypot } from '#app/utils/honeypot.server.ts'
import { invariant, useIsPending } from '#app/utils/misc.tsx'
import { useIsPending } from '#app/utils/misc.tsx'
import { authSessionStorage } from '#app/utils/session.server.ts'
import { redirectWithToast } from '#app/utils/toast.server.ts'
import {
Expand Down
3 changes: 2 additions & 1 deletion app/routes/_auth+/onboarding_.$provider.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { conform, useForm } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
import { invariant } from '@epic-web/invariant'
import {
json,
redirect,
Expand All @@ -26,7 +27,7 @@ import {
} from '#app/utils/auth.server.ts'
import { ProviderNameSchema } from '#app/utils/connections.tsx'
import { prisma } from '#app/utils/db.server.ts'
import { invariant, useIsPending } from '#app/utils/misc.tsx'
import { useIsPending } from '#app/utils/misc.tsx'
import { authSessionStorage } from '#app/utils/session.server.ts'
import { redirectWithToast } from '#app/utils/toast.server.ts'
import { NameSchema, UsernameSchema } from '#app/utils/user-validation.ts'
Expand Down
3 changes: 2 additions & 1 deletion app/routes/_auth+/reset-password.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import { ErrorList, Field } from '#app/components/forms.tsx'
import { StatusButton } from '#app/components/ui/status-button.tsx'
import { requireAnonymous, resetUserPassword } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { invariant, useIsPending } from '#app/utils/misc.tsx'
import { invariant } from '@epic-web/invariant'

Check warning on line 15 in app/routes/_auth+/reset-password.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

`@epic-web/invariant` import should occur before import of `@remix-run/node`
import { useIsPending } from '#app/utils/misc.tsx'
import { PasswordAndConfirmPasswordSchema } from '#app/utils/user-validation.ts'
import { verifySessionStorage } from '#app/utils/verification.server.ts'
import { type VerifyFunctionArgs } from './verify.tsx'
Expand Down
7 changes: 2 additions & 5 deletions app/routes/admin+/cache.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { invariantResponse } from '@epic-web/invariant'
import { type SEOHandle } from '@nasa-gcn/remix-seo'
import { json, redirect, type DataFunctionArgs } from '@remix-run/node'
import {
Expand All @@ -22,11 +23,7 @@ import {
getAllInstances,
getInstanceInfo,
} from '#app/utils/litefs.server.ts'
import {
invariantResponse,
useDebounce,
useDoubleCheck,
} from '#app/utils/misc.tsx'
import { useDebounce, useDoubleCheck } from '#app/utils/misc.tsx'
import { requireUserWithRole } from '#app/utils/permissions.ts'

export const handle: SEOHandle = {
Expand Down
2 changes: 1 addition & 1 deletion app/routes/admin+/cache_.lru.$cacheKey.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { invariantResponse } from '@epic-web/invariant'
import { json, type DataFunctionArgs } from '@remix-run/node'
import { getAllInstances, getInstanceInfo } from 'litefs-js'
import { ensureInstance } from 'litefs-js/remix.js'
import { lruCache } from '#app/utils/cache.server.ts'
import { invariantResponse } from '#app/utils/misc.tsx'
import { requireUserWithRole } from '#app/utils/permissions.ts'

export async function loader({ request, params }: DataFunctionArgs) {
Expand Down
2 changes: 1 addition & 1 deletion app/routes/admin+/cache_.sqlite.$cacheKey.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { invariantResponse } from '@epic-web/invariant'
import { json, type DataFunctionArgs } from '@remix-run/node'
import { getAllInstances, getInstanceInfo } from 'litefs-js'
import { ensureInstance } from 'litefs-js/remix.js'
import { cache } from '#app/utils/cache.server.ts'
import { invariantResponse } from '#app/utils/misc.tsx'
import { requireUserWithRole } from '#app/utils/permissions.ts'

export async function loader({ request, params }: DataFunctionArgs) {
Expand Down
2 changes: 1 addition & 1 deletion app/routes/resources+/note-images.$imageId.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type DataFunctionArgs } from '@remix-run/node'
import { prisma } from '#app/utils/db.server.ts'
import { invariantResponse } from '#app/utils/misc.tsx'
import { invariantResponse } from '@epic-web/invariant'

Check warning on line 3 in app/routes/resources+/note-images.$imageId.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

`@epic-web/invariant` import should occur before import of `@remix-run/node`

export async function loader({ params }: DataFunctionArgs) {
invariantResponse(params.imageId, 'Image ID is required', { status: 400 })
Expand Down
2 changes: 1 addition & 1 deletion app/routes/resources+/user-images.$imageId.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type DataFunctionArgs } from '@remix-run/node'
import { prisma } from '#app/utils/db.server.ts'
import { invariantResponse } from '#app/utils/misc.tsx'
import { invariantResponse } from '@epic-web/invariant'

Check warning on line 3 in app/routes/resources+/user-images.$imageId.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

`@epic-web/invariant` import should occur before import of `@remix-run/node`

export async function loader({ params }: DataFunctionArgs) {
invariantResponse(params.imageId, 'Image ID is required', { status: 400 })
Expand Down
3 changes: 2 additions & 1 deletion app/routes/settings+/profile.change-email.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import { requireUserId } from '#app/utils/auth.server.ts'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { sendEmail } from '#app/utils/email.server.ts'
import { invariant, useIsPending } from '#app/utils/misc.tsx'
import { invariant } from '@epic-web/invariant'

Check warning on line 21 in app/routes/settings+/profile.change-email.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

`@epic-web/invariant` import should occur before import of `@nasa-gcn/remix-seo`
import { useIsPending } from '#app/utils/misc.tsx'
import { redirectWithToast } from '#app/utils/toast.server.ts'
import { EmailSchema } from '#app/utils/user-validation.ts'
import { verifySessionStorage } from '#app/utils/verification.server.ts'
Expand Down
2 changes: 1 addition & 1 deletion app/routes/settings+/profile.connections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
providerNames,
} from '#app/utils/connections.tsx'
import { prisma } from '#app/utils/db.server.ts'
import { invariantResponse } from '#app/utils/misc.tsx'
import { invariantResponse } from '@epic-web/invariant'

Check warning on line 28 in app/routes/settings+/profile.connections.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

`@epic-web/invariant` import should occur before import of `@nasa-gcn/remix-seo`
import { makeTimings } from '#app/utils/timing.server.ts'
import { createToastHeaders } from '#app/utils/toast.server.ts'
import { type BreadcrumbHandle } from './profile.tsx'
Expand Down
7 changes: 2 additions & 5 deletions app/routes/settings+/profile.index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { conform, useForm } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
import { invariantResponse } from '@epic-web/invariant'
import { type SEOHandle } from '@nasa-gcn/remix-seo'
import { json, type DataFunctionArgs } from '@remix-run/node'
import { Link, useFetcher, useLoaderData } from '@remix-run/react'
Expand All @@ -12,11 +13,7 @@ import { StatusButton } from '#app/components/ui/status-button.tsx'
import { requireUserId, sessionKey } from '#app/utils/auth.server.ts'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import {
getUserImgSrc,
invariantResponse,
useDoubleCheck,
} from '#app/utils/misc.tsx'
import { getUserImgSrc, useDoubleCheck } from '#app/utils/misc.tsx'
import { authSessionStorage } from '#app/utils/session.server.ts'
import { redirectWithToast } from '#app/utils/toast.server.ts'
import { NameSchema, UsernameSchema } from '#app/utils/user-validation.ts'
Expand Down
2 changes: 1 addition & 1 deletion app/routes/settings+/profile.photo.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { conform, useForm } from '@conform-to/react'
import { getFieldsetConstraint, parse } from '@conform-to/zod'
import { invariantResponse } from '@epic-web/invariant'
import { type SEOHandle } from '@nasa-gcn/remix-seo'
import {
json,
Expand All @@ -26,7 +27,6 @@ import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import {
getUserImgSrc,
invariantResponse,
useDoubleCheck,
useIsPending,
} from '#app/utils/misc.tsx'
Expand Down
3 changes: 2 additions & 1 deletion app/routes/settings+/profile.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { invariantResponse } from '@epic-web/invariant'
import { type SEOHandle } from '@nasa-gcn/remix-seo'
import { json, type DataFunctionArgs } from '@remix-run/node'
import { Link, Outlet, useMatches } from '@remix-run/react'
Expand All @@ -6,7 +7,7 @@ import { Spacer } from '#app/components/spacer.tsx'
import { Icon } from '#app/components/ui/icon.tsx'
import { requireUserId } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { cn, invariantResponse } from '#app/utils/misc.tsx'
import { cn } from '#app/utils/misc.tsx'
import { useUser } from '#app/utils/user.ts'

export const BreadcrumbHandle = z.object({ breadcrumb: z.any() })
Expand Down
3 changes: 2 additions & 1 deletion app/routes/users+/$username.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { invariantResponse } from '@epic-web/invariant'
import { json, type DataFunctionArgs } from '@remix-run/node'
import { Form, Link, useLoaderData, type MetaFunction } from '@remix-run/react'
import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'
import { Spacer } from '#app/components/spacer.tsx'
import { Button } from '#app/components/ui/button.tsx'
import { Icon } from '#app/components/ui/icon.tsx'
import { prisma } from '#app/utils/db.server.ts'
import { getUserImgSrc, invariantResponse } from '#app/utils/misc.tsx'
import { getUserImgSrc } from '#app/utils/misc.tsx'
import { useOptionalUser } from '#app/utils/user.ts'

export async function loader({ params }: DataFunctionArgs) {
Expand Down
7 changes: 2 additions & 5 deletions app/routes/users+/$username_+/notes.$noteId.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useForm } from '@conform-to/react'
import { parse } from '@conform-to/zod'
import { invariantResponse } from '@epic-web/invariant'
import { json, type DataFunctionArgs } from '@remix-run/node'
import {
Form,
Expand All @@ -20,11 +21,7 @@ import { StatusButton } from '#app/components/ui/status-button.tsx'
import { requireUserId } from '#app/utils/auth.server.ts'
import { validateCSRF } from '#app/utils/csrf.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import {
getNoteImgSrc,
invariantResponse,
useIsPending,
} from '#app/utils/misc.tsx'
import { getNoteImgSrc, useIsPending } from '#app/utils/misc.tsx'
import {
requireUserWithPermission,
userHasPermission,
Expand Down
2 changes: 1 addition & 1 deletion app/routes/users+/$username_+/notes.$noteId_.edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useLoaderData } from '@remix-run/react'
import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'
import { requireUserId } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { invariantResponse } from '#app/utils/misc.tsx'
import { invariantResponse } from '@epic-web/invariant'

Check warning on line 6 in app/routes/users+/$username_+/notes.$noteId_.edit.tsx

View workflow job for this annotation

GitHub Actions / ⬣ ESLint

`@epic-web/invariant` import should occur before import of `@remix-run/node`
import { NoteEditor, action } from './__note-editor.tsx'

export { action }
Expand Down
3 changes: 2 additions & 1 deletion app/routes/users+/$username_+/notes.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { invariantResponse } from '@epic-web/invariant'
import { json, type DataFunctionArgs } from '@remix-run/node'
import { Link, NavLink, Outlet, useLoaderData } from '@remix-run/react'
import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'
import { Icon } from '#app/components/ui/icon.tsx'
import { prisma } from '#app/utils/db.server.ts'
import { cn, getUserImgSrc, invariantResponse } from '#app/utils/misc.tsx'
import { cn, getUserImgSrc } from '#app/utils/misc.tsx'
import { useOptionalUser } from '#app/utils/user.ts'

export async function loader({ params }: DataFunctionArgs) {
Expand Down
53 changes: 0 additions & 53 deletions app/utils/misc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -139,59 +139,6 @@ export function combineResponseInits(
return combined
}

/**
* 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 {Error} if condition is falsey
*/
export function invariant(
condition: any,
message: string | (() => string),
): asserts condition {
if (!condition) {
throw new Error(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: any,
message: string | (() => string),
responseInit?: ResponseInit,
): asserts condition {
if (!condition) {
throw new Response(typeof message === 'function' ? message() : message, {
status: 400,
...responseInit,
})
}
}

/**
* Returns true if the current navigation is submitting the current route's
* form. Defaults to the current route's form action and method POST.
Expand Down
2 changes: 1 addition & 1 deletion app/utils/request-info.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { invariant } from '@epic-web/invariant'
import { useRouteLoaderData } from '@remix-run/react'
import { type loader as rootLoader } from '#app/root.tsx'
import { invariant } from './misc.tsx'

/**
* @returns the request info from the root loader
Expand Down
6 changes: 6 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@conform-to/zod": "^0.9.1",
"@epic-web/cachified": "^4.0.0",
"@epic-web/client-hints": "^1.2.2",
"@epic-web/invariant": "^1.0.0",
"@epic-web/remember": "^1.0.2",
"@epic-web/totp": "^1.1.1",
"@nasa-gcn/remix-seo": "^2.0.0",
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/onboarding.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { invariant } from '@epic-web/invariant'
import { faker } from '@faker-js/faker'
import { prisma } from '#app/utils/db.server.ts'
import { invariant } from '#app/utils/misc.tsx'
import { readEmail } from '#tests/mocks/utils.ts'
import { createUser, expect, test as base } from '#tests/playwright-utils.ts'

Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/search.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { invariant } from '#app/utils/misc.tsx'
import { invariant } from '@epic-web/invariant'
import { expect, test } from '#tests/playwright-utils.ts'

test('Search from home page', async ({ page, insertNewUser }) => {
Expand Down
2 changes: 1 addition & 1 deletion tests/e2e/settings-profile.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { invariant } from '@epic-web/invariant'
import { faker } from '@faker-js/faker'
import { verifyUserPassword } from '#app/utils/auth.server.ts'
import { prisma } from '#app/utils/db.server.ts'
import { invariant } from '#app/utils/misc.tsx'
import { readEmail } from '#tests/mocks/utils.ts'
import { expect, test, createUser, waitFor } from '#tests/playwright-utils.ts'

Expand Down

0 comments on commit 5164851

Please sign in to comment.