1
mirror of https://github.com/jakejarvis/jarv.is.git synced 2026-06-05 19:15:30 -04:00

refactor: remove @t3-oss/env-nextjs, use process.env directly

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-19 14:12:42 -05:00
parent c30197ccc5
commit 6f86fd1ca9
28 changed files with 91 additions and 287 deletions
+1 -2
View File
@@ -1,8 +1,7 @@
import { createAuthClient } from "better-auth/react";
import { env } from "@/lib/env";
export const authClient = createAuthClient({
baseURL: env.NEXT_PUBLIC_BASE_URL,
baseURL: process.env.NEXT_PUBLIC_BASE_URL,
});
export const { signIn, signUp, useSession } = authClient;
+5 -4
View File
@@ -3,10 +3,9 @@ import { drizzleAdapter } from "better-auth/adapters/drizzle";
import { nextCookies } from "better-auth/next-js";
import { db } from "@/lib/db";
import * as schema from "@/lib/db/schema";
import { env } from "@/lib/env";
export const auth = betterAuth({
baseURL: env.NEXT_PUBLIC_BASE_URL,
baseURL: process.env.NEXT_PUBLIC_BASE_URL,
database: drizzleAdapter(db, {
provider: "pg",
schema,
@@ -14,8 +13,10 @@ export const auth = betterAuth({
plugins: [nextCookies()],
socialProviders: {
github: {
clientId: env.AUTH_GITHUB_CLIENT_ID,
clientSecret: env.AUTH_GITHUB_CLIENT_SECRET,
// biome-ignore lint/style/noNonNullAssertion: expected to be set in env
clientId: process.env.AUTH_GITHUB_CLIENT_ID!,
// biome-ignore lint/style/noNonNullAssertion: expected to be set in env
clientSecret: process.env.AUTH_GITHUB_CLIENT_SECRET!,
mapProfileToUser: (profile) => ({
name: profile.login,
email: profile.email,
+8 -8
View File
@@ -2,7 +2,7 @@ import { Feed, type Item as FeedItem } from "feed";
import ogImage from "@/app/opengraph-image.jpg";
import authorConfig from "@/lib/config/author";
import siteConfig from "@/lib/config/site";
import { env } from "@/lib/env";
import { getContent, getFrontMatter } from "@/lib/posts";
/**
@@ -11,20 +11,20 @@ import { getContent, getFrontMatter } from "@/lib/posts";
*/
export const buildFeed = async (): Promise<Feed> => {
const feed = new Feed({
id: `${env.NEXT_PUBLIC_BASE_URL}`,
link: `${env.NEXT_PUBLIC_BASE_URL}`,
id: `${process.env.NEXT_PUBLIC_BASE_URL}`,
link: `${process.env.NEXT_PUBLIC_BASE_URL}`,
title: siteConfig.name,
description: siteConfig.description,
copyright: `https://spdx.org/licenses/${siteConfig.license}.html`,
updated: new Date(),
image: `${env.NEXT_PUBLIC_BASE_URL}${ogImage.src}`,
image: `${process.env.NEXT_PUBLIC_BASE_URL}${ogImage.src}`,
feedLinks: {
rss: `${env.NEXT_PUBLIC_BASE_URL}/feed.xml`,
atom: `${env.NEXT_PUBLIC_BASE_URL}/feed.atom`,
rss: `${process.env.NEXT_PUBLIC_BASE_URL}/feed.xml`,
atom: `${process.env.NEXT_PUBLIC_BASE_URL}/feed.atom`,
},
author: {
name: authorConfig.name,
link: env.NEXT_PUBLIC_BASE_URL,
link: process.env.NEXT_PUBLIC_BASE_URL,
email: authorConfig.email,
},
});
@@ -40,7 +40,7 @@ export const buildFeed = async (): Promise<Feed> => {
author: [
{
name: authorConfig.name,
link: `${env.NEXT_PUBLIC_BASE_URL}`,
link: `${process.env.NEXT_PUBLIC_BASE_URL}`,
},
],
date: new Date(post.date),
+1 -2
View File
@@ -2,11 +2,10 @@ import { attachDatabasePool } from "@vercel/functions";
import { drizzle } from "drizzle-orm/node-postgres";
import { Pool } from "pg";
import * as schema from "@/lib/db/schema";
import { env } from "@/lib/env";
// Create explicit pool instance for better connection management
const pool = new Pool({
connectionString: env.DATABASE_URL,
connectionString: process.env.DATABASE_URL,
});
// Attach to Vercel's pool management to ensure idle connections are properly
-142
View File
@@ -1,142 +0,0 @@
import { createEnv } from "@t3-oss/env-nextjs";
import { z } from "zod";
export const env = createEnv({
server: {
/**
* Required. A random value used for authentication encryption.
*
* @see https://www.better-auth.com/docs/installation#set-environment-variables
*/
AUTH_SECRET: z.string().min(1),
/**
* Required. The client ID from the GitHub Developer Portal for this site's OAuth App.
*
* @see https://www.better-auth.com/docs/authentication/github
*/
AUTH_GITHUB_CLIENT_ID: z.string().min(1),
/**
* Required. A client secret from the GitHub Developer Portal for this site's OAuth App.
*
* @see https://www.better-auth.com/docs/authentication/github
*/
AUTH_GITHUB_CLIENT_SECRET: z.string().min(1),
/**
* Required. Database connection string for a Postgres database.
*/
DATABASE_URL: z.string().startsWith("postgresql://"),
/**
* Required. GitHub API token used for [/projects](../app/projects/page.tsx) grid. Only needs the `public_repo`
* scope since we don't need/want to change anything, obviously.
*
* @see https://github.com/settings/tokens/new?scopes=public_repo
*/
GITHUB_TOKEN: z.string().startsWith("ghp_").optional(),
/**
* Required. Uses Resend API to send contact form submissions via a [server action](../app/contact/action.ts). May
* be set automatically by Vercel's Resend integration.
*
* @see https://resend.com/api-keys
* @see https://vercel.com/integrations/resend
*/
RESEND_API_KEY: z.string().startsWith("re_"),
/**
* Optional, but will throw a warning if unset. Use an approved domain (or subdomain) on the Resend account to send
* submissions from. Sender's real email is passed via a Reply-To header, so setting this makes zero difference to
* the user, only for deliverability success. Defaults to `onboarding@resend.dev`.
*
* @see https://resend.com/domains
*/
RESEND_FROM_EMAIL: z.string().email().default("onboarding@resend.dev"),
/** Required. The destination email for contact form submissions. */
RESEND_TO_EMAIL: z.string().email(),
},
client: {
/**
* Optional. We try to make an educated guess for the most appropriate URL based on the current deployment's
* environment and platform (if Vercel or Netlify), but you can override it by simply setting this manually. Must be
* a fully-qualified URL if set beginning with `http(s)://`, and should not end with a trailing slash.
*
* @see https://nextjs.org/docs/app/api-reference/functions/generate-metadata#default-value
*/
NEXT_PUBLIC_BASE_URL: z
.string()
.url()
.default(
((): string =>
(process.env.VERCEL || process.env.NEXT_PUBLIC_VERCEL
? process.env.NEXT_PUBLIC_VERCEL_ENV === "production"
? `https://${process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL}`
: process.env.NEXT_PUBLIC_VERCEL_ENV === "preview"
? `https://${process.env.NEXT_PUBLIC_VERCEL_BRANCH_URL}`
: process.env.NEXT_PUBLIC_VERCEL_URL
? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}`
: undefined
: undefined) ||
(process.env.NETLIFY
? process.env.CONTEXT === "production"
? `${process.env.URL}`
: process.env.DEPLOY_PRIME_URL
? `${process.env.DEPLOY_PRIME_URL}`
: process.env.DEPLOY_URL
? `${process.env.DEPLOY_URL}`
: undefined
: undefined) ||
`http://localhost:${process.env.PORT || 3000}`)(),
),
/**
* Optional. Set this to override the best guess as to the environment the site is running in.
*/
NEXT_PUBLIC_ENV: z
.enum(["production", "development"])
.default(
((): "production" | "development" =>
(process.env.VERCEL && process.env.VERCEL_ENV === "production") ||
(process.env.NETLIFY && process.env.CONTEXT === "production")
? "production"
: "development")(),
),
/** Required. GitHub repository for the site in the format of `{username}/{repo}`. */
NEXT_PUBLIC_GITHUB_REPO: z.string().refine((val) => val.includes("/"), {
message: "Must be in the format {username}/{repo}",
}),
/** Required. GitHub username of the author, used to generate [/projects](../app/projects/page.tsx). */
NEXT_PUBLIC_GITHUB_USERNAME: z.string().min(1),
/**
* Optional. Sets an `Onion-Location` header in responses to advertise a URL for the same page but hosted on a
* hidden service on the Tor network. Browsers like Brave and Tor Browser will automatically pick this up and offer
* to redirect users to it.
*
* @see https://community.torproject.org/onion-services/advanced/onion-location/
*/
NEXT_PUBLIC_ONION_DOMAIN: z.string().endsWith(".onion").optional(),
/**
* Optional. Locale code to define the site's language in ISO-639 format. Defaults to `en-US`.
*
* @see https://www.loc.gov/standards/iso639-2/php/code_list.php
*/
NEXT_PUBLIC_SITE_LOCALE: z.string().default("en-US"),
},
experimental__runtimeEnv: {
NEXT_PUBLIC_BASE_URL: process.env.NEXT_PUBLIC_BASE_URL,
NEXT_PUBLIC_ENV: process.env.NEXT_PUBLIC_ENV,
NEXT_PUBLIC_GITHUB_REPO: process.env.NEXT_PUBLIC_GITHUB_REPO,
NEXT_PUBLIC_GITHUB_USERNAME: process.env.NEXT_PUBLIC_GITHUB_USERNAME,
NEXT_PUBLIC_ONION_DOMAIN: process.env.NEXT_PUBLIC_ONION_DOMAIN,
NEXT_PUBLIC_SITE_LOCALE: process.env.NEXT_PUBLIC_SITE_LOCALE,
},
emptyStringAsUndefined: true,
skipValidation: !!process.env.SKIP_ENV_VALIDATION,
});
+3 -3
View File
@@ -1,10 +1,10 @@
import type { Metadata } from "next";
import authorConfig from "@/lib/config/author";
import siteConfig from "@/lib/config/site";
import { env } from "@/lib/env";
export const defaultMetadata: Metadata = {
metadataBase: new URL(env.NEXT_PUBLIC_BASE_URL),
// biome-ignore lint/style/noNonNullAssertion: expected to be set in env
metadataBase: new URL(process.env.NEXT_PUBLIC_BASE_URL!),
title: {
template: `%s ${siteConfig.name}`,
default: `${siteConfig.name} ${siteConfig.tagline}`,
@@ -17,7 +17,7 @@ export const defaultMetadata: Metadata = {
default: `${siteConfig.name} ${siteConfig.tagline}`,
},
url: "/",
locale: env.NEXT_PUBLIC_SITE_LOCALE.replace("-", "_"),
locale: process.env.NEXT_PUBLIC_SITE_LOCALE?.replace("-", "_"),
type: "website",
},
twitter: {
+2 -2
View File
@@ -3,7 +3,7 @@ import path from "node:path";
import glob from "fast-glob";
import { decode } from "html-entities";
import { unified } from "unified";
import { env } from "@/lib/env";
import { rehypeSanitize, rehypeStringify } from "@/lib/rehype";
import {
remarkFrontmatter,
@@ -89,7 +89,7 @@ export const getFrontMatter: {
slug,
// validate/normalize the date string provided from front matter
date: new Date(frontmatter.date).toISOString(),
permalink: `${env.NEXT_PUBLIC_BASE_URL}/${POSTS_DIR}/${slug}`,
permalink: `${process.env.NEXT_PUBLIC_BASE_URL}/${POSTS_DIR}/${slug}`,
} as FrontMatter;
} catch (error) {
console.error(
+6 -5
View File
@@ -3,7 +3,7 @@
import { checkBotId } from "botid/server";
import { Resend } from "resend";
import siteConfig from "@/lib/config/site";
import { env } from "@/lib/env";
import { ContactSchema } from "@/lib/schemas/contact";
export type ContactResult = {
@@ -39,18 +39,19 @@ export const sendContactForm = async (
}
try {
if (env.RESEND_FROM_EMAIL === "onboarding@resend.dev") {
if (process.env.RESEND_FROM_EMAIL === "onboarding@resend.dev") {
// https://resend.com/docs/api-reference/emails/send-email
console.warn(
"[server/contact] 'RESEND_FROM_EMAIL' is not set, falling back to onboarding@resend.dev.",
);
}
const resend = new Resend(env.RESEND_API_KEY);
const resend = new Resend(process.env.RESEND_API_KEY);
await resend.emails.send({
from: `${parsed.data.name} <${env.RESEND_FROM_EMAIL || "onboarding@resend.dev"}>`,
from: `${parsed.data.name} <${process.env.RESEND_FROM_EMAIL || "onboarding@resend.dev"}>`,
replyTo: `${parsed.data.name} <${parsed.data.email}>`,
to: [env.RESEND_TO_EMAIL],
// biome-ignore lint/style/noNonNullAssertion: expected to be set in env
to: [process.env.RESEND_TO_EMAIL!],
subject: `[${siteConfig.name}] Contact Form Submission`,
text: parsed.data.message,
});