Skip to content

Commit 249cef8

Browse files
committed
feat: upgrade to Remix v2
1 parent 87ccf36 commit 249cef8

30 files changed

+98
-172
lines changed

Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Base node image.
2-
FROM node:16-bullseye-slim as base
2+
FROM node:18-bullseye-slim as base
33

44
# Set global environment variables.
55
ENV PORT="8080"

app/entry.server.tsx

+12-7
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
1-
import type { EntryContext } from '@remix-run/node'
1+
/**
2+
* By default, Remix will handle generating the HTTP Response for you.
3+
* You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨
4+
* For more information, see https://remix.run/docs/en/main/file-conventions/entry.server
5+
*/
26

3-
import { PassThrough } from 'stream'
4-
import { Response } from '@remix-run/node'
7+
import { PassThrough } from 'node:stream'
8+
import type { EntryContext } from '@remix-run/node'
9+
import { createReadableStreamFromReadable } from "@remix-run/node";
510
import { RemixServer } from '@remix-run/react'
611
import { renderToPipeableStream } from 'react-dom/server'
712
import { getSharedEnvs } from './utils/envs'
@@ -35,7 +40,7 @@ function handleBotRequest(
3540
return new Promise((resolve, reject) => {
3641
let didError = false
3742

38-
const { pipe, abort } = renderToPipeableStream(
43+
const { abort, pipe } = renderToPipeableStream(
3944
<RemixServer context={remixContext} url={request.url} />,
4045
{
4146
onAllReady() {
@@ -44,7 +49,7 @@ function handleBotRequest(
4449
responseHeaders.set('Content-Type', 'text/html')
4550

4651
resolve(
47-
new Response(body, {
52+
new Response(createReadableStreamFromReadable(body), {
4853
headers: responseHeaders,
4954
status: didError ? 500 : responseStatusCode,
5055
}),
@@ -76,7 +81,7 @@ function handleBrowserRequest(
7681
return new Promise((resolve, reject) => {
7782
let didError = false
7883

79-
const { pipe, abort } = renderToPipeableStream(
84+
const { abort, pipe } = renderToPipeableStream(
8085
<RemixServer context={remixContext} url={request.url} />,
8186
{
8287
onShellReady() {
@@ -85,7 +90,7 @@ function handleBrowserRequest(
8590
responseHeaders.set('Content-Type', 'text/html')
8691

8792
resolve(
88-
new Response(body, {
93+
new Response(createReadableStreamFromReadable(body), {
8994
headers: responseHeaders,
9095
status: didError ? 500 : responseStatusCode,
9196
}),

app/root.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { LinksFunction, DataFunctionArgs } from '@remix-run/node'
1+
import type { LinksFunction } from '@remix-run/node'
22
import {
33
Links,
44
LiveReload,
@@ -16,7 +16,7 @@ export const links: LinksFunction = () => {
1616
return [{ rel: 'stylesheet', href: TailwindCSS }]
1717
}
1818

19-
export function loader({ request }: DataFunctionArgs) {
19+
export function loader() {
2020
return { ENV: getSharedEnvs() }
2121
}
2222

app/routes/_layout+/_index.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import type { V2_MetaFunction } from "@remix-run/node";
1+
import type { MetaFunction } from "@remix-run/node";
22
import { Link } from '@remix-run/react'
33

4-
export const meta: V2_MetaFunction = () => [
4+
export const meta: MetaFunction = () => [
55
{ title: 'Stripe Stack - Remix' },
66
{ description: `A Stripe focused Remix Stack that integrates User Subscriptions, Authentication and Testing. Driven by Prisma ORM. Deploys to Fly.io` },
77
{ keywords: 'remix, stripe, remix-stack, typescript, sqlite, postgresql, prisma, tailwindcss, fly.io' },

app/routes/_layout+/_layout.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
1+
import type { LoaderFunctionArgs } from '@remix-run/node'
22
import type { User } from '@prisma/client'
33

44
import { redirect, json } from '@remix-run/node'
@@ -12,7 +12,7 @@ type LoaderData = {
1212
user: User | null
1313
}
1414

15-
export async function loader({ request }: DataFunctionArgs) {
15+
export async function loader({ request }: LoaderFunctionArgs) {
1616
const session = await authenticator.isAuthenticated(request)
1717

1818
// Force redirect to /account on authenticated user.

app/routes/_layout+/account.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
1+
import type { LoaderFunctionArgs } from '@remix-run/node'
22
import type { User, Subscription } from '@prisma/client'
33

44
import { json, redirect } from '@remix-run/node'
@@ -17,7 +17,7 @@ type LoaderData = {
1717
subscription: Omit<Subscription, 'createdAt' | 'updatedAt'>
1818
}
1919

20-
export async function loader({ request }: DataFunctionArgs) {
20+
export async function loader({ request }: LoaderFunctionArgs) {
2121
const session = await authenticator.isAuthenticated(request, {
2222
failureRedirect: '/login',
2323
})

app/routes/_layout+/checkout.tsx

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
2-
3-
import { useState } from 'react'
4-
import { Link, useLoaderData, useSubmit } from '@remix-run/react'
1+
import type { LoaderFunctionArgs } from '@remix-run/node'
52
import { redirect, json } from '@remix-run/node'
6-
import { authenticator } from '~/services/auth/config.server'
3+
import { Link, useLoaderData, useSubmit } from '@remix-run/react'
4+
import { useState } from 'react'
75

8-
import { PlanId } from '~/services/stripe/plans'
96
import { getSubscriptionByUserId } from '~/models/subscription/get-subscription'
7+
import { authenticator } from '~/services/auth/config.server'
8+
import { PlanId } from '~/services/stripe/plans'
109
import { useInterval } from '~/utils/hooks'
1110

12-
export async function loader({ request }: DataFunctionArgs) {
11+
export async function loader({ request }: LoaderFunctionArgs) {
1312
const session = await authenticator.isAuthenticated(request, {
1413
failureRedirect: '/login',
1514
})

app/routes/_layout+/login.email.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
2-
1+
import type { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node'
32
import { json } from '@remix-run/node'
43
import { Form, useLoaderData } from '@remix-run/react'
54

65
import { authenticator } from '~/services/auth/config.server'
76
import { getSession, commitSession } from '~/services/auth/session.server'
87

9-
export async function loader({ request }: DataFunctionArgs) {
8+
export async function loader({ request }: LoaderFunctionArgs) {
109
const userSession = await authenticator.isAuthenticated(request, {
1110
successRedirect: '/account',
1211
})
@@ -28,7 +27,7 @@ export async function loader({ request }: DataFunctionArgs) {
2827
)
2928
}
3029

31-
export async function action({ request }: DataFunctionArgs) {
30+
export async function action({ request }: ActionFunctionArgs) {
3231
await authenticator.authenticate('OTP', request, {
3332
successRedirect: '/login/email',
3433
failureRedirect: '/login/email',

app/routes/_layout+/login.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
2-
1+
import type { LoaderFunctionArgs } from '@remix-run/node'
32
import { json } from '@remix-run/node'
43
import { Outlet, useLocation } from '@remix-run/react'
54
import { authenticator } from '~/services/auth/config.server'
65

7-
export async function loader({ request }: DataFunctionArgs) {
6+
export async function loader({ request }: LoaderFunctionArgs) {
87
await authenticator.isAuthenticated(request, {
98
successRedirect: '/account',
109
})

app/routes/_layout+/plans.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
2-
3-
import { useState } from 'react'
1+
import type { LoaderFunctionArgs } from '@remix-run/node'
42
import { json } from '@remix-run/node'
53
import { Link, useLoaderData } from '@remix-run/react'
4+
import { useState } from 'react'
65

76
import { authenticator } from '~/services/auth/config.server'
87
import { getSubscriptionByUserId } from '~/models/subscription/get-subscription'
@@ -11,7 +10,7 @@ import { getDefaultCurrency } from '~/utils/locales'
1110
import { PlanId, Interval, Currency, PRICING_PLANS } from '~/services/stripe/plans'
1211
import { CheckoutButton } from '~/components/stripe/checkout-button'
1312

14-
export async function loader({ request }: DataFunctionArgs) {
13+
export async function loader({ request }: LoaderFunctionArgs) {
1514
const session = await authenticator.isAuthenticated(request)
1615
const subscription = session?.id ? await getSubscriptionByUserId(session.id) : null
1716

app/routes/_layout+/register.name.tsx

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
2-
1+
import type { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node'
32
import { json, redirect } from '@remix-run/node'
43
import { useFetcher } from '@remix-run/react'
54

65
import { authenticator } from '~/services/auth/config.server'
76
import { getUserById } from '~/models/user/get-user'
87
import { updateUserById } from '~/models/user/update-user'
98

10-
export async function loader({ request }: DataFunctionArgs) {
9+
export async function loader({ request }: LoaderFunctionArgs) {
1110
const session = await authenticator.isAuthenticated(request, {
1211
failureRedirect: '/login',
1312
})
@@ -19,7 +18,7 @@ export async function loader({ request }: DataFunctionArgs) {
1918
return json({})
2019
}
2120

22-
export async function action({ request }: DataFunctionArgs) {
21+
export async function action({ request }: ActionFunctionArgs) {
2322
const session = await authenticator.isAuthenticated(request, {
2423
failureRedirect: '/login',
2524
})

app/routes/_layout+/register.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
2-
1+
import type { LoaderFunctionArgs } from '@remix-run/node'
32
import { json } from '@remix-run/node'
43
import { Outlet } from '@remix-run/react'
54
import { authenticator } from '~/services/auth/config.server'
65

7-
export async function loader({ request }: DataFunctionArgs) {
6+
export async function loader({ request }: LoaderFunctionArgs) {
87
await authenticator.isAuthenticated(request, {
98
failureRedirect: '/login',
109
})

app/routes/api+/healthcheck.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
1+
import type { LoaderFunctionArgs } from '@remix-run/node'
22
import { db } from '~/utils/db.server'
33

44
/**
55
* Learn more about Fly.io Health Check:
66
* https://fly.io/docs/reference/configuration/#services-http_checks
77
*/
8-
export async function loader({ request }: DataFunctionArgs) {
8+
export async function loader({ request }: LoaderFunctionArgs) {
99
const host = request.headers.get('X-Forwarded-Host') ?? request.headers.get('host')
1010

1111
try {

app/routes/api+/webhook.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@
22
// More info: https://bit.ly/3KlNXLs
33
/// <reference types="stripe-event-types" />
44

5-
import type { DataFunctionArgs } from '@remix-run/node'
5+
import type { ActionFunctionArgs } from '@remix-run/node'
6+
import { json } from '@remix-run/node'
67
import type { Stripe } from 'stripe'
78

8-
import { json } from '@remix-run/node'
99
import { stripe } from '~/services/stripe/config.server'
1010
import { PlanId } from '~/services/stripe/plans'
1111
import { retrieveStripeSubscription } from '~/services/stripe/api/retrieve-subscription'
12-
1312
import { getUserByCustomerId } from '~/models/user/get-user'
1413
import { getSubscriptionById } from '~/models/subscription/get-subscription'
1514
import { updateSubscriptionByUserId } from '~/models/subscription/update-subscription'
@@ -43,7 +42,7 @@ async function getStripeEvent(request: Request) {
4342
}
4443
}
4544

46-
export async function action({ request }: DataFunctionArgs) {
45+
export async function action({ request }: ActionFunctionArgs) {
4746
const event = await getStripeEvent(request)
4847

4948
try {

app/routes/auth+/$provider.callback.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
1+
import type { LoaderFunctionArgs } from '@remix-run/node'
22
import { authenticator } from '~/services/auth/config.server'
33

4-
export async function loader({ request, params }: DataFunctionArgs) {
4+
export async function loader({ params, request }: LoaderFunctionArgs) {
55
if (typeof params.provider !== 'string') throw new Error('Invalid provider.')
66

77
return await authenticator.authenticate(params.provider, request, {

app/routes/auth+/$provider.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
1+
import type { ActionFunctionArgs } from '@remix-run/node'
22
import { authenticator } from '~/services/auth/config.server'
33

4-
export async function action({ request, params }: DataFunctionArgs) {
4+
export async function action({ params, request }: ActionFunctionArgs) {
55
if (typeof params.provider !== 'string') throw new Error('Invalid provider.')
66

77
return await authenticator.authenticate(params.provider, request, {

app/routes/auth+/logout.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
1+
import type { ActionFunctionArgs } from '@remix-run/node'
22
import { authenticator } from '~/services/auth/config.server'
33

4-
export async function action({ request }: DataFunctionArgs) {
4+
export async function action({ request }: ActionFunctionArgs) {
55
return await authenticator.logout(request, { redirectTo: '/' })
66
}
77

app/routes/auth+/magic.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
1+
import type { LoaderFunctionArgs } from '@remix-run/node'
22
import { authenticator } from '~/services/auth/config.server'
33

4-
export async function loader({ request }: DataFunctionArgs) {
4+
export async function loader({ request }: LoaderFunctionArgs) {
55
await authenticator.authenticate('OTP', request, {
66
successRedirect: '/account',
77
failureRedirect: '/login',

app/routes/resources+/stripe.create-checkout.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
1+
import type { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node'
22

33
import { redirect } from '@remix-run/node'
44
import { authenticator } from '~/services/auth/config.server'
@@ -8,12 +8,12 @@ import { getPlanById } from '~/models/plan/get-plan'
88
import { getDefaultCurrency } from '~/utils/locales'
99
import { createStripeCheckoutSession } from '~/services/stripe/api/create-checkout'
1010

11-
export async function loader({ request }: DataFunctionArgs) {
11+
export async function loader({ request }: LoaderFunctionArgs) {
1212
await authenticator.isAuthenticated(request, { failureRedirect: '/login' })
1313
return redirect('/account')
1414
}
1515

16-
export async function action({ request }: DataFunctionArgs) {
16+
export async function action({ request }: ActionFunctionArgs) {
1717
const session = await authenticator.isAuthenticated(request, {
1818
failureRedirect: '/',
1919
})

app/routes/resources+/stripe.create-customer-portal.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
2-
1+
import type { ActionFunctionArgs, LoaderFunctionArgs } from '@remix-run/node'
32
import { redirect, json } from '@remix-run/node'
43
import { authenticator } from '~/services/auth/config.server'
54
import { getUserById } from '~/models/user/get-user'
65
import { createStripeCustomerPortalSession } from '~/services/stripe/api/create-customer-portal'
76

8-
export async function loader({ request }: DataFunctionArgs) {
7+
export async function loader({ request }: LoaderFunctionArgs) {
98
await authenticator.isAuthenticated(request, {
109
failureRedirect: '/',
1110
})
1211
return redirect('/account')
1312
}
1413

15-
export async function action({ request }: DataFunctionArgs) {
14+
export async function action({ request }: ActionFunctionArgs) {
1615
const session = await authenticator.isAuthenticated(request, {
1716
failureRedirect: '/',
1817
})

app/routes/resources+/stripe.create-customer.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
1+
import type { LoaderFunctionArgs } from '@remix-run/node'
22

33
import { redirect } from '@remix-run/node'
44
import { authenticator } from '~/services/auth/config.server'
@@ -7,7 +7,7 @@ import { getUserById } from '~/models/user/get-user'
77
import { updateUserById } from '~/models/user/update-user'
88
import { createStripeCustomer } from '~/services/stripe/api/create-customer'
99

10-
export async function loader({ request }: DataFunctionArgs) {
10+
export async function loader({ request }: LoaderFunctionArgs) {
1111
const session = await authenticator.isAuthenticated(request, {
1212
failureRedirect: '/login',
1313
})

app/routes/resources+/stripe.create-subscription.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import type { DataFunctionArgs } from '@remix-run/node'
2-
1+
import type { LoaderFunctionArgs } from '@remix-run/node'
32
import { redirect } from '@remix-run/node'
43
import { authenticator } from '~/services/auth/config.server'
54

@@ -12,7 +11,7 @@ import { PlanId } from '~/services/stripe/plans'
1211
import { createStripeSubscription } from '~/services/stripe/api/create-subscription'
1312
import { getDefaultCurrency } from '~/utils/locales'
1413

15-
export async function loader({ request }: DataFunctionArgs) {
14+
export async function loader({ request }: LoaderFunctionArgs) {
1615
const session = await authenticator.isAuthenticated(request, {
1716
failureRedirect: '/login',
1817
})

0 commit comments

Comments
 (0)