mirror of
https://github.com/better-auth/better-auth.git
synced 2026-10-19 11:24:57 -05:00
Merge branch 'main' into 2026-10-17/fix/oidc-token-validation
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@better-auth/core": patch
|
||||
---
|
||||
|
||||
Reduce installation size by removing the semantic conventions production dependency while preserving all instrumentation attribute keys.
|
||||
@@ -20,7 +20,7 @@ env:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-24.04' || 'ubuntu-24.04' }}
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-26.04' || 'ubuntu-24.04' }}
|
||||
permissions:
|
||||
contents: read
|
||||
concurrency:
|
||||
@@ -91,7 +91,7 @@ jobs:
|
||||
run: pnpm lint:types
|
||||
|
||||
typecheck:
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-24.04' || 'ubuntu-24.04' }}
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-26.04' || 'ubuntu-24.04' }}
|
||||
permissions:
|
||||
contents: read
|
||||
concurrency:
|
||||
@@ -126,7 +126,7 @@ jobs:
|
||||
run: pnpm typecheck:dist
|
||||
|
||||
test:
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-24.04' || 'ubuntu-24.04' }}
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-26.04' || 'ubuntu-24.04' }}
|
||||
permissions:
|
||||
contents: read
|
||||
timeout-minutes: 30
|
||||
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && contains(fromJSON('["MEMBER", "OWNER", "COLLABORATOR"]'), github.event.review.author_association)) ||
|
||||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) && contains(fromJSON('["MEMBER", "OWNER", "COLLABORATOR"]'), github.event.issue.author_association))
|
||||
)
|
||||
runs-on: ${{ github.repository == 'better-auth/better-auth' && 'starsling-ubuntu-24.04' || 'ubuntu-24.04' }}
|
||||
runs-on: ${{ github.repository == 'better-auth/better-auth' && 'starsling-ubuntu-26.04' || 'ubuntu-24.04' }}
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
smoke:
|
||||
name: Smoke test (${{ matrix.node-version }})
|
||||
timeout-minutes: 30
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-24.04' || 'ubuntu-24.04' }}
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-26.04' || 'ubuntu-24.04' }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -81,11 +81,14 @@ jobs:
|
||||
integration:
|
||||
name: Integration test
|
||||
timeout-minutes: 60
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-24.04' || 'ubuntu-24.04' }}
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-26.04' || 'ubuntu-24.04' }}
|
||||
permissions:
|
||||
contents: read
|
||||
env:
|
||||
COMPOSE_SERVICES: postgres
|
||||
# Playwright 1.58 has no Ubuntu 26.04 browser build (support starts in 1.61), so use the
|
||||
# Ubuntu 24.04 build. Remove this once Playwright is 1.61 or later.
|
||||
PLAYWRIGHT_HOST_PLATFORM_OVERRIDE: ubuntu24.04-x64
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
|
||||
with:
|
||||
@@ -153,7 +156,7 @@ jobs:
|
||||
run: docker compose down --volumes --remove-orphans
|
||||
adapter-integration:
|
||||
name: ${{ matrix.packages }} Integration Test
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-24.04' || 'ubuntu-24.04' }}
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-26.04' || 'ubuntu-24.04' }}
|
||||
timeout-minutes: 30
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
@@ -14,7 +14,7 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-24.04' || 'ubuntu-24.04' }}
|
||||
runs-on: ${{ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == 'better-auth/better-auth' || github.event_name != 'pull_request' && github.repository == 'better-auth/better-auth') && 'starsling-ubuntu-26.04' || 'ubuntu-24.04' }}
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
|
||||
@@ -1,171 +0,0 @@
|
||||
import { ImageResponse } from "@vercel/og";
|
||||
import * as z from "zod";
|
||||
export const runtime = "edge";
|
||||
|
||||
const ogSchema = z.object({
|
||||
heading: z.string(),
|
||||
description: z.string().optional(),
|
||||
date: z.string().optional(),
|
||||
});
|
||||
|
||||
export async function GET(req: Request) {
|
||||
try {
|
||||
const geist = await fetch(
|
||||
new URL("../../../assets/Geist.ttf", import.meta.url),
|
||||
).then((res) => res.arrayBuffer());
|
||||
|
||||
const url = new URL(req.url);
|
||||
const urlParamsValues = Object.fromEntries(url.searchParams);
|
||||
const validParams = ogSchema.parse(urlParamsValues);
|
||||
|
||||
const { heading, description, date } = validParams;
|
||||
const trueHeading =
|
||||
heading.length > 140 ? `${heading.substring(0, 140)}...` : heading;
|
||||
|
||||
return new ImageResponse(
|
||||
<div
|
||||
tw="flex w-full h-full relative flex-col"
|
||||
style={{
|
||||
background:
|
||||
"radial-gradient(circle 230px at 0% 0%, #000000, #000000)",
|
||||
fontFamily: "Geist",
|
||||
color: "white",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
tw="flex w-full h-full relative"
|
||||
style={{
|
||||
borderRadius: "10px",
|
||||
border: "1px solid rgba(32, 34, 34, 0.5)",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
tw="absolute"
|
||||
style={{
|
||||
width: "350px",
|
||||
height: "120px",
|
||||
borderRadius: "100px",
|
||||
background: "#c7c7c7",
|
||||
opacity: 0.21,
|
||||
filter: "blur(35px)",
|
||||
transform: "rotate(50deg)",
|
||||
top: "18%",
|
||||
left: "0%",
|
||||
}}
|
||||
/>
|
||||
|
||||
<div
|
||||
tw="flex flex-col w-full relative h-full p-8"
|
||||
style={{
|
||||
gap: "14px",
|
||||
position: "relative",
|
||||
zIndex: 999,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
tw="absolute bg-repeat w-full h-full"
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
zIndex: 999,
|
||||
|
||||
background:
|
||||
"url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHhtbG5zOnN2Z2pzPSJodHRwOi8vc3ZnanMuZGV2L3N2Z2pzIiB2aWV3Qm94PSIwIDAgODAwIDgwMCIgd2lkdGg9IjgwMCIgaGVpZ2h0PSI4MDAiPjxnIHN0cm9rZS13aWR0aD0iMy41IiBzdHJva2U9ImhzbGEoMCwgMCUsIDEwMCUsIDEuMDApIiBmaWxsPSJub25lIiBvcGFjaXR5PSIwLjUiPjxyZWN0IHdpZHRoPSI0MDAiIGhlaWdodD0iNDAwIiB4PSIwIiB5PSIwIiBvcGFjaXR5PSIwLjE1Ij48L3JlY3Q+PGNpcmNsZSByPSIxMC44NTUyNjMxNTc4OTQ3MzYiIGN4PSIwIiBjeT0iMCIgZmlsbD0iaHNsYSgwLCAwJSwgMTAwJSwgMS4wMCkiIHN0cm9rZT0ibm9uZSI+PC9jaXJjbGU+PHJlY3Qgd2lkdGg9IjQwMCIgaGVpZ2h0PSI0MDAiIHg9IjQwMCIgeT0iMCIgb3BhY2l0eT0iMC4xNSI+PC9yZWN0PjxjaXJjbGUgcj0iMTAuODU1MjYzMTU3ODk0NzM2IiBjeD0iNDAwIiBjeT0iMCIgZmlsbD0iaHNsYSgwLCAwJSwgMTAwJSwgMS4wMCkiIHN0cm9rZT0ibm9uZSI+PC9jaXJjbGU+PHJlY3Qgd2lkdGg9IjQwMCIgaGVpZ2h0PSI0MDAiIHg9IjgwMCIgeT0iMCIgb3BhY2l0eT0iMC4xNSI+PC9yZWN0PjxjaXJjbGUgcj0iMTAuODU1MjYzMTU3ODk0NzM2IiBjeD0iODAwIiBjeT0iMCIgZmlsbD0iaHNsYSgwLCAwJSwgMTAwJSwgMS4wMCkiIHN0cm9rZT0ibm9uZSI+PC9jaXJjbGU+PHJlY3Qgd2lkdGg9IjQwMCIgaGVpZ2h0PSI0MDAiIHg9IjAiIHk9IjQwMCIgb3BhY2l0eT0iMC4xNSI+PC9yZWN0PjxjaXJjbGUgcj0iMTAuODU1MjYzMTU3ODk0NzM2IiBjeD0iMCIgY3k9IjQwMCIgZmlsbD0iaHNsYSgwLCAwJSwgMTAwJSwgMS4wMCkiIHN0cm9rZT0ibm9uZSI+PC9jaXJjbGU+PHJlY3Qgd2lkdGg9IjQwMCIgaGVpZ2h0PSI0MDAiIHg9IjQwMCIgeT0iNDAwIiBvcGFjaXR5PSIwLjE1Ij48L3JlY3Q+PGNpcmNsZSByPSIxMC44NTUyNjMxNTc4OTQ3MzYiIGN4PSI0MDAiIGN5PSI0MDAiIGZpbGw9ImhzbGEoMCwgMCUsIDEwMCUsIDEuMDApIiBzdHJva2U9Im5vbmUiPjwvY2lyY2xlPjxyZWN0IHdpZHRoPSI0MDAiIGhlaWdodD0iNDAwIiB4PSI4MDAiIHk9IjQwMCIgb3BhY2l0eT0iMC4xNSI+PC9yZWN0PjxjaXJjbGUgcj0iMTAuODU1MjYzMTU3ODk0NzM2IiBjeD0iODAwIiBjeT0iNDAwIiBmaWxsPSJoc2xhKDAsIDAlLCAxMDAlLCAxLjAwKSIgc3Ryb2tlPSJub25lIj48L2NpcmNsZT48cmVjdCB3aWR0aD0iNDAwIiBoZWlnaHQ9IjQwMCIgeD0iMCIgeT0iODAwIiBvcGFjaXR5PSIwLjE1Ij48L3JlY3Q+PGNpcmNsZSByPSIxMC44NTUyNjMxNTc4OTQ3MzYiIGN4PSIwIiBjeT0iODAwIiBmaWxsPSJoc2xhKDAsIDAlLCAxMDAlLCAxLjAwKSIgc3Ryb2tlPSJub25lIj48L2NpcmNsZT48cmVjdCB3aWR0aD0iNDAwIiBoZWlnaHQ9IjQwMCIgeD0iNDAwIiB5PSI4MDAiIG9wYWNpdHk9IjAuMTUiPjwvcmVjdD48Y2lyY2xlIHI9IjEwLjg1NTI2MzE1Nzg5NDczNiIgY3g9IjQwMCIgY3k9IjgwMCIgZmlsbD0iaHNsYSgwLCAwJSwgMTAwJSwgMS4wMCkiIHN0cm9rZT0ibm9uZSI+PC9jaXJjbGU+PHJlY3Qgd2lkdGg9IjQwMCIgaGVpZ2h0PSI0MDAiIHg9IjgwMCIgeT0iODAwIiBvcGFjaXR5PSIwLjE1Ij48L3JlY3Q+PGNpcmNsZSByPSIxMC44NTUyNjM1NTc4OTQ3MzYiIGN4PSI4MDAiIGN5PSI4MDAiIGZpbGw9ImhzbGEoMCwgMCUsIDEwMCUsIDEuMDApIiBzdHJva2U9Im5vbmUiPjwvY2lyY2xlPjwvZz48L3N2Zz4=')",
|
||||
backgroundSize: "25px 25px",
|
||||
display: "flex",
|
||||
alignItems: "flex-start",
|
||||
justifyContent: "flex-start",
|
||||
position: "relative",
|
||||
flexDirection: "column",
|
||||
textAlign: "left",
|
||||
paddingLeft: "170px",
|
||||
gap: "14px",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
tw="flex text-6xl absolute top-10 isolate font-bold"
|
||||
style={{
|
||||
paddingLeft: "170px",
|
||||
paddingTop: "200px",
|
||||
background: "linear-gradient(45deg, #000000 4%, #fff, #000)",
|
||||
backgroundClip: "text",
|
||||
color: "transparent",
|
||||
}}
|
||||
>
|
||||
{trueHeading}
|
||||
</div>
|
||||
|
||||
<div
|
||||
tw="flex absolute bottom-44 z-[999] text-2xl"
|
||||
style={{
|
||||
paddingLeft: "170px",
|
||||
background:
|
||||
"linear-gradient(10deg, #d4d4d8, 04%, #fff, #d4d4d8)",
|
||||
backgroundClip: "text",
|
||||
opacity: 0.7,
|
||||
color: "transparent",
|
||||
}}
|
||||
>
|
||||
{description}
|
||||
</div>
|
||||
|
||||
<div
|
||||
tw="flex text-2xl absolute bottom-28 z-[999]"
|
||||
style={{
|
||||
paddingLeft: "170px",
|
||||
background:
|
||||
"linear-gradient(10deg, #d4d4d8, 04%, #fff, #d4d4d8)",
|
||||
backgroundClip: "text",
|
||||
opacity: 0.8,
|
||||
color: "transparent",
|
||||
}}
|
||||
>
|
||||
{date}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Lines */}
|
||||
<div
|
||||
tw="absolute top-10% w-full h-px"
|
||||
style={{
|
||||
background: "linear-gradient(90deg, #888888 30%, #1d1f1f 70%)",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
tw="absolute bottom-10% w-full h-px"
|
||||
style={{
|
||||
background: "#2c2c2c",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
tw="absolute left-10% h-full w-px"
|
||||
style={{
|
||||
background: "linear-gradient(180deg, #747474 30%, #222424 70%)",
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
tw="absolute right-10% h-full w-px"
|
||||
style={{
|
||||
background: "#2c2c2c",
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>,
|
||||
{
|
||||
width: 1200,
|
||||
height: 630,
|
||||
fonts: [
|
||||
{
|
||||
name: "Geist",
|
||||
data: geist,
|
||||
weight: 400,
|
||||
style: "normal",
|
||||
},
|
||||
],
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
console.log({ err });
|
||||
return new Response("Failed to generate the OG image", { status: 500 });
|
||||
}
|
||||
}
|
||||
+151
-171
@@ -1,183 +1,172 @@
|
||||
import { ImageResponse } from "@vercel/og";
|
||||
import * as z from "zod";
|
||||
|
||||
export const runtime = "edge";
|
||||
|
||||
const ogSchema = z.object({
|
||||
heading: z.string().default("Better Auth Documentation"),
|
||||
mode: z.string().default("dark"),
|
||||
type: z.string().default("documentation"),
|
||||
heading: z.string().trim().min(1).max(200).default("Better Auth"),
|
||||
section: z.string().trim().max(40).optional(),
|
||||
version: z.string().trim().max(20).optional(),
|
||||
});
|
||||
|
||||
const colors = {
|
||||
background: "radial-gradient(120% 120% at 80% 0%, #111111 0%, #000000 55%)",
|
||||
titleGradient:
|
||||
"linear-gradient(100deg, #fafafa 0%, #d4d4d4 55%, #8a8a8a 100%)",
|
||||
logo: "#fafafa",
|
||||
divider: "rgba(255, 255, 255, 0.24)",
|
||||
eyebrow: "#8f8f8f",
|
||||
outline: "rgba(255, 255, 255, 0.09)",
|
||||
speck: "rgba(255, 255, 255, 0.35)",
|
||||
};
|
||||
|
||||
const specks: Array<{ top: string; left: string; size: number }> = [
|
||||
{ top: "6%", left: "43%", size: 3 },
|
||||
{ top: "13%", left: "61%", size: 2 },
|
||||
{ top: "4%", left: "76%", size: 2 },
|
||||
{ top: "27%", left: "52%", size: 2 },
|
||||
{ top: "9%", left: "30%", size: 2 },
|
||||
{ top: "31%", left: "88%", size: 3 },
|
||||
];
|
||||
|
||||
const ZERO_WIDTH_SPACE = "\u200b";
|
||||
|
||||
/**
|
||||
* Error codes like `account_already_linked_to_different_user` have no spaces,
|
||||
* so give them a break opportunity after each `_` instead of overflowing.
|
||||
*/
|
||||
function allowBreakAfterUnderscore(text: string) {
|
||||
return text.replaceAll("_", `_${ZERO_WIDTH_SPACE}`);
|
||||
}
|
||||
|
||||
function titleFontSize(title: string) {
|
||||
if (title.length <= 30) return 80;
|
||||
if (title.length <= 60) return 68;
|
||||
if (title.length <= 100) return 56;
|
||||
return 48;
|
||||
}
|
||||
|
||||
export async function GET(req: Request) {
|
||||
try {
|
||||
const geist = await fetch(
|
||||
new URL("../../../assets/Geist.ttf", import.meta.url),
|
||||
).then((res) => res.arrayBuffer());
|
||||
const geistMono = await fetch(
|
||||
new URL("../../../assets/GeistMono.ttf", import.meta.url),
|
||||
).then((res) => res.arrayBuffer());
|
||||
const url = new URL(req.url);
|
||||
const urlParamsValues = Object.fromEntries(url.searchParams);
|
||||
const validParams = ogSchema.parse(urlParamsValues);
|
||||
const { heading, type } = validParams;
|
||||
const trueHeading =
|
||||
heading.length > 140 ? `${heading.substring(0, 140)}...` : heading;
|
||||
const { heading, section, version } = ogSchema.parse(
|
||||
Object.fromEntries(url.searchParams),
|
||||
);
|
||||
|
||||
const paint = "#fff";
|
||||
const [geist, markSvg] = await Promise.all([
|
||||
fetch(new URL("../../../assets/Geist.ttf", import.meta.url)).then((res) =>
|
||||
res.arrayBuffer(),
|
||||
),
|
||||
fetch(
|
||||
new URL(
|
||||
"../../../public/branding/svg/better-auth-mark-light.svg",
|
||||
import.meta.url,
|
||||
),
|
||||
).then((res) => res.text()),
|
||||
]);
|
||||
const markUri = `data:image/svg+xml;base64,${btoa(markSvg)}`;
|
||||
|
||||
const trimmedHeading = allowBreakAfterUnderscore(
|
||||
heading.length > 140 ? `${heading.substring(0, 137)}...` : heading,
|
||||
);
|
||||
|
||||
const fontSize = trueHeading.length > 100 ? "30px" : "60px";
|
||||
return new ImageResponse(
|
||||
<div
|
||||
tw="flex w-full relative flex-col p-12"
|
||||
style={{
|
||||
color: paint,
|
||||
backgroundColor: "transparent",
|
||||
border: "1px solid rgba(255, 255, 255, 0.1)",
|
||||
boxShadow: "0 -20px 80px -20px rgba(28, 12, 12, 0.1) inset",
|
||||
background: "#0a0505",
|
||||
}}
|
||||
tw="flex w-full h-full relative"
|
||||
style={{ background: colors.background, fontFamily: "Geist" }}
|
||||
>
|
||||
{specks.map((speck, i) => (
|
||||
<div
|
||||
key={i}
|
||||
tw="absolute"
|
||||
style={{
|
||||
top: speck.top,
|
||||
left: speck.left,
|
||||
width: `${speck.size}px`,
|
||||
height: `${speck.size}px`,
|
||||
borderRadius: "9999px",
|
||||
background: colors.speck,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
|
||||
{/* Rotated rounded-rect outline, bleeding off the top-right corner */}
|
||||
<div
|
||||
tw={`relative flex flex-col w-full h-full border-2 border-[${paint}]/20 p-10}`}
|
||||
tw="absolute"
|
||||
style={{
|
||||
width: "560px",
|
||||
height: "640px",
|
||||
top: "-180px",
|
||||
right: "-200px",
|
||||
border: `1.5px solid ${colors.outline}`,
|
||||
borderRadius: "56px",
|
||||
transform: "rotate(14deg)",
|
||||
}}
|
||||
/>
|
||||
|
||||
<div
|
||||
tw="flex flex-col justify-between w-full h-full"
|
||||
style={{ padding: "84px 240px 84px 96px" }}
|
||||
>
|
||||
<svg
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "-9px",
|
||||
right: "-9px",
|
||||
}}
|
||||
width="17"
|
||||
height="17"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M7 1a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v2a1 1 0 0 1-1 1H1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V8a1 1 0 0 1 1-1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H8a1 1 0 0 1-1-1V1z"
|
||||
fill="#d0cfd1d3"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<svg
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "-9px",
|
||||
left: "-9px",
|
||||
}}
|
||||
width="17"
|
||||
height="17"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M7 1a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v2a1 1 0 0 1-1 1H1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V8a1 1 0 0 1 1-1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H8a1 1 0 0 1-1-1V1z"
|
||||
fill="#cacaca"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: "-9px",
|
||||
left: "-9px",
|
||||
}}
|
||||
width="17"
|
||||
height="17"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M7 1a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v2a1 1 0 0 1-1 1H1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V8a1 1 0 0 1 1-1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H8a1 1 0 0 1-1-1V1z"
|
||||
fill="#cacaca"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: "-9px",
|
||||
right: "-9px",
|
||||
}}
|
||||
width="17"
|
||||
height="17"
|
||||
fill="none"
|
||||
>
|
||||
<path
|
||||
d="M7 1a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v2a1 1 0 0 1-1 1H1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h2a1 1 0 0 1 1 1v2a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1V8a1 1 0 0 1 1-1h2a1 1 0 0 0 1-1V5a1 1 0 0 0-1-1H8a1 1 0 0 1-1-1V1z"
|
||||
fill="#cacaca"
|
||||
/>
|
||||
</svg>
|
||||
<div tw="flex flex-col flex-1 py-10">
|
||||
<svg
|
||||
width="130"
|
||||
height="95"
|
||||
viewBox="0 0 60 45"
|
||||
fill="none"
|
||||
className="mb-10"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
stroke={paint}
|
||||
clipRule="evenodd"
|
||||
d="M0 0H15V15H30V30H15V45H0V30V15V0ZM45 30V15H30V0H45H60V15V30V45H45H30V30H45Z"
|
||||
fill="white"
|
||||
/>
|
||||
</svg>
|
||||
<div tw="flex items-center">
|
||||
<img src={markUri} width={56} height={42} alt="Better Auth" />
|
||||
<div
|
||||
style={{ fontFamily: "GeistMono", fontWeight: "normal" }}
|
||||
tw="relative flex mt-10 text-xl uppercase font-bold gap-2 items-center"
|
||||
>
|
||||
{type === "documentation" ? (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1.2em"
|
||||
height="1.2em"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M4.172 3.172C3 4.343 3 6.229 3 10v4c0 3.771 0 5.657 1.172 6.828S7.229 22 11 22h2c3.771 0 5.657 0 6.828-1.172S21 17.771 21 14v-4c0-3.771 0-5.657-1.172-6.828S16.771 2 13 2h-2C7.229 2 5.343 2 4.172 3.172M8 9.25a.75.75 0 0 0 0 1.5h8a.75.75 0 0 0 0-1.5zm0 4a.75.75 0 0 0 0 1.5h5a.75.75 0 0 0 0-1.5z"
|
||||
clipRule="evenodd"
|
||||
></path>
|
||||
</svg>
|
||||
) : null}
|
||||
{type}
|
||||
</div>
|
||||
<div
|
||||
tw="flex max-w-[70%] mt-5 tracking-tighter leading-[1.1] text-[30px] font-bold"
|
||||
tw="flex"
|
||||
style={{
|
||||
fontWeight: "bold",
|
||||
marginLeft: "-3px",
|
||||
fontSize,
|
||||
|
||||
fontFamily: "GeistMono",
|
||||
width: "1.5px",
|
||||
height: "40px",
|
||||
margin: "0 24px",
|
||||
background: colors.divider,
|
||||
}}
|
||||
>
|
||||
{trueHeading}
|
||||
/>
|
||||
<div tw="flex items-baseline">
|
||||
<div tw="flex" style={{ fontSize: "38px", color: colors.logo }}>
|
||||
Docs
|
||||
</div>
|
||||
{version ? (
|
||||
// Nudged up so the smaller baseline-aligned text does not sag next to the mark
|
||||
<div
|
||||
tw="flex"
|
||||
style={{
|
||||
marginLeft: "14px",
|
||||
fontSize: "26px",
|
||||
color: colors.eyebrow,
|
||||
position: "relative",
|
||||
top: "-2px",
|
||||
}}
|
||||
>
|
||||
{version}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
<div tw="flex items-center w-full justify-between">
|
||||
<div
|
||||
tw="flex text-xl"
|
||||
style={{ fontFamily: "GeistSans", fontWeight: "semibold" }}
|
||||
>
|
||||
Better Auth.
|
||||
</div>
|
||||
<div tw="flex gap-2 items-center text-xl">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1.2em"
|
||||
height="1.2em"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M12 2A10 10 0 0 0 2 12c0 4.42 2.87 8.17 6.84 9.5c.5.08.66-.23.66-.5v-1.69c-2.77.6-3.36-1.34-3.36-1.34c-.46-1.16-1.11-1.47-1.11-1.47c-.91-.62.07-.6.07-.6c1 .07 1.53 1.03 1.53 1.03c.87 1.52 2.34 1.07 2.91.83c.09-.65.35-1.09.63-1.34c-2.22-.25-4.55-1.11-4.55-4.92c0-1.11.38-2 1.03-2.71c-.1-.25-.45-1.29.1-2.64c0 0 .84-.27 2.75 1.02c.79-.22 1.65-.33 2.5-.33s1.71.11 2.5.33c1.91-1.29 2.75-1.02 2.75-1.02c.55 1.35.2 2.39.1 2.64c.65.71 1.03 1.6 1.03 2.71c0 3.82-2.34 4.66-4.57 4.91c.36.31.69.92.69 1.85V21c0 .27.16.59.67.5C19.14 20.16 22 16.42 22 12A10 10 0 0 0 12 2"
|
||||
></path>
|
||||
</svg>
|
||||
<span
|
||||
|
||||
<div tw="flex flex-col">
|
||||
{section ? (
|
||||
<div
|
||||
tw="flex"
|
||||
style={{
|
||||
fontFamily: "GeistSans",
|
||||
fontSize: "28px",
|
||||
color: colors.eyebrow,
|
||||
marginBottom: "28px",
|
||||
}}
|
||||
tw="flex ml-2"
|
||||
>
|
||||
github.com/better-auth/better-auth
|
||||
</span>
|
||||
{section}
|
||||
</div>
|
||||
) : null}
|
||||
<div
|
||||
tw="flex"
|
||||
style={{
|
||||
fontSize: `${titleFontSize(heading)}px`,
|
||||
fontWeight: 500,
|
||||
letterSpacing: "-0.02em",
|
||||
lineHeight: 1.12,
|
||||
backgroundImage: colors.titleGradient,
|
||||
backgroundClip: "text",
|
||||
color: "transparent",
|
||||
}}
|
||||
>
|
||||
{trimmedHeading}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -185,24 +174,15 @@ export async function GET(req: Request) {
|
||||
{
|
||||
width: 1200,
|
||||
height: 630,
|
||||
fonts: [
|
||||
{
|
||||
name: "Geist",
|
||||
data: geist,
|
||||
weight: 400,
|
||||
style: "normal",
|
||||
},
|
||||
{
|
||||
name: "GeistMono",
|
||||
data: geistMono,
|
||||
weight: 700,
|
||||
style: "normal",
|
||||
},
|
||||
],
|
||||
fonts: [{ name: "Geist", data: geist, weight: 400, style: "normal" }],
|
||||
headers: {
|
||||
"Cache-Control":
|
||||
"public, max-age=86400, s-maxage=31536000, immutable",
|
||||
},
|
||||
},
|
||||
);
|
||||
} catch (err) {
|
||||
console.log({ err });
|
||||
return new Response("Failed to generate the og image", { status: 500 });
|
||||
return new Response("Failed to generate the OG image", { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ export const metadata: Metadata = createMetadata({
|
||||
url: "/blog",
|
||||
title: "Blog - Better Auth",
|
||||
description,
|
||||
images: ["/api/og-release?heading=Better%20Auth%20Blog"],
|
||||
images: ["/api/og-blog?title=Better%20Auth%20Blog"],
|
||||
},
|
||||
twitter: {
|
||||
images: ["/api/og-release?heading=Better%20Auth%20Blog"],
|
||||
images: ["/api/og-blog?title=Better%20Auth%20Blog"],
|
||||
title: "Blog - Better Auth",
|
||||
description,
|
||||
},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { getBreadcrumbItems } from "fumadocs-core/breadcrumb";
|
||||
import { Accordion, Accordions } from "fumadocs-ui/components/accordion";
|
||||
import { File, Files, Folder } from "fumadocs-ui/components/files";
|
||||
import { Step, Steps } from "fumadocs-ui/components/steps";
|
||||
@@ -227,10 +228,13 @@ export async function generateMetadata({
|
||||
? `${version.label} - ${page.data.title}`
|
||||
: page.data.title;
|
||||
|
||||
const [section] = getBreadcrumbItems(page.url, src.getPageTree());
|
||||
const ogSearchParams = new URLSearchParams();
|
||||
ogSearchParams.set("heading", title);
|
||||
ogSearchParams.set("type", "documentation");
|
||||
ogSearchParams.set("mode", "dark");
|
||||
ogSearchParams.set("heading", page.data.title);
|
||||
if (typeof section?.name === "string") {
|
||||
ogSearchParams.set("section", section.name);
|
||||
}
|
||||
if (version.id !== "latest") ogSearchParams.set("version", version.label);
|
||||
|
||||
const ogUrl = `/api/og?${ogSearchParams.toString()}`;
|
||||
|
||||
|
||||
@@ -44,8 +44,8 @@ If you're using another runtime, keep your existing entry point and add the same
|
||||
|
||||
<Callout type="info">
|
||||
The resulting Hono route must match your Better Auth `basePath`, which
|
||||
defaults to `/api/auth`. If your app already uses `new
|
||||
Hono().basePath("/api")`, mount Better Auth at `/auth/*`:
|
||||
defaults to `/api/auth`. If your app already uses
|
||||
`new Hono().basePath("/api")`, mount Better Auth at `/auth/*`:
|
||||
|
||||
```ts
|
||||
const app = new Hono().basePath("/api");
|
||||
|
||||
@@ -434,7 +434,7 @@ export const communityPlugins: CommunityPlugin[] = [
|
||||
name: "good-webhooks",
|
||||
url: "https://github.com/pplytas/good-webhooks",
|
||||
description:
|
||||
"Authenticated webhook endpoint management with typed client APIs, scoped permissions, signing-secret rotation, and optional self-hosted delivery. Currently in beta with a frozen public API.",
|
||||
"Authenticated webhook endpoint management with typed client APIs, scoped permissions, signing-secret rotation, and optional self-hosted delivery.",
|
||||
author: {
|
||||
name: "Panagiotis Plytas",
|
||||
github: "pplytas",
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ export function getRSS() {
|
||||
id: `${baseUrl}blog`,
|
||||
link: `${baseUrl}blog`,
|
||||
language: "en",
|
||||
image: `${baseUrl}release-og/blogs.png`,
|
||||
image: `${baseUrl}og.png`,
|
||||
favicon: `${baseUrl}favicon/favicon-32x32.png`,
|
||||
copyright: `All rights reserved ${new Date().getFullYear()}, Better Auth Inc.`,
|
||||
});
|
||||
|
||||
@@ -43,9 +43,9 @@ async function getAvailablePort(): Promise<number> {
|
||||
async function stopProcess(
|
||||
child: ChildProcessWithoutNullStreams | undefined,
|
||||
): Promise<void> {
|
||||
if (!child?.pid || child.exitCode !== null) return;
|
||||
if (!child) return;
|
||||
const { terminate } = await import("@better-auth-test/test-utils/playwright");
|
||||
await terminate(child.pid);
|
||||
await terminate(child);
|
||||
}
|
||||
|
||||
async function startNextDemoRuntime(): Promise<NextDemoRuntime> {
|
||||
@@ -108,7 +108,7 @@ async function startNextDemoRuntime(): Promise<NextDemoRuntime> {
|
||||
["dev", "--hostname", "127.0.0.1", "--port", String(port)],
|
||||
{
|
||||
cwd: demoDirectory,
|
||||
detached: true,
|
||||
detached: process.platform !== "win32",
|
||||
env: environment,
|
||||
stdio: "pipe",
|
||||
},
|
||||
|
||||
@@ -25,6 +25,7 @@ export function setup() {
|
||||
ref,
|
||||
start: async () => {
|
||||
clientChild = spawn("pnpm", ["run", "dev"], {
|
||||
detached: process.platform !== "win32",
|
||||
cwd: root,
|
||||
stdio: "pipe",
|
||||
env: {
|
||||
@@ -58,7 +59,7 @@ export function setup() {
|
||||
]);
|
||||
},
|
||||
clean: async () => {
|
||||
await terminate(clientChild.pid!);
|
||||
await terminate(clientChild);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ let baseURL: string;
|
||||
|
||||
test.beforeAll(async () => {
|
||||
server = spawn("pnpm", ["run", "dev"], {
|
||||
detached: process.platform !== "win32",
|
||||
cwd: root,
|
||||
stdio: "pipe",
|
||||
env: { ...process.env, NO_COLOR: "1" },
|
||||
@@ -28,7 +29,7 @@ test.beforeAll(async () => {
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
if (server?.pid) await terminate(server.pid);
|
||||
if (server) await terminate(server);
|
||||
});
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,8 +4,5 @@
|
||||
"exports": {
|
||||
"./playwright": "./src/playwright.ts"
|
||||
},
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"terminate": "^2.8.0"
|
||||
}
|
||||
"private": true
|
||||
}
|
||||
|
||||
@@ -1,8 +1,46 @@
|
||||
import { createRequire } from "node:module";
|
||||
import type { ChildProcess } from "node:child_process";
|
||||
import { execFile } from "node:child_process";
|
||||
import { once } from "node:events";
|
||||
import { promisify } from "node:util";
|
||||
|
||||
export const terminate = createRequire(import.meta.url)(
|
||||
// use terminate instead of cp.kill,
|
||||
// because cp.kill will not kill the child process of the child process
|
||||
// to avoid the zombie process
|
||||
"terminate/promise",
|
||||
) as (pid: number) => Promise<void>;
|
||||
// Spawn with detached: true on Unix so the child owns its process group.
|
||||
export async function terminate(child: ChildProcess): Promise<void> {
|
||||
const pid = child.pid;
|
||||
if (pid === undefined) return;
|
||||
|
||||
const exited = child.exitCode !== null || child.signalCode !== null;
|
||||
if (process.platform === "win32" && exited) {
|
||||
return;
|
||||
}
|
||||
|
||||
const closed = exited
|
||||
? Promise.resolve()
|
||||
: once(child, "close", { signal: AbortSignal.timeout(5000) });
|
||||
const killing = Promise.resolve().then(async () => {
|
||||
if (process.platform === "win32") {
|
||||
try {
|
||||
await promisify(execFile)(
|
||||
"taskkill",
|
||||
["/pid", String(pid), "/T", "/F"],
|
||||
{
|
||||
timeout: 5000,
|
||||
windowsHide: true,
|
||||
},
|
||||
);
|
||||
} catch (error) {
|
||||
if (child.exitCode === null && child.signalCode === null) throw error;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
process.kill(-pid, "SIGKILL");
|
||||
} catch (error) {
|
||||
if (
|
||||
!(error instanceof Error && "code" in error && error.code === "ESRCH")
|
||||
) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
await Promise.all([closed, killing]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
@@ -62,6 +62,7 @@ export function setup(overrides?: Partial<BetterAuthOptions>) {
|
||||
start: async () => {
|
||||
server = await createAuthServer(undefined, overrides);
|
||||
clientChild = spawn("pnpm", ["run", "start:client"], {
|
||||
detached: process.platform !== "win32",
|
||||
cwd: root,
|
||||
stdio: "pipe",
|
||||
});
|
||||
@@ -101,8 +102,11 @@ export function setup(overrides?: Partial<BetterAuthOptions>) {
|
||||
]);
|
||||
},
|
||||
clean: async () => {
|
||||
await terminate(clientChild.pid!);
|
||||
server.close();
|
||||
try {
|
||||
await terminate(clientChild);
|
||||
} finally {
|
||||
server.close();
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,20 +29,26 @@ describe("(cloudflare) simple server", () => {
|
||||
*/
|
||||
it("builds and runs the Worker", async (t) => {
|
||||
const cp = spawn("pnpm", ["run", "e2e:smoke"], {
|
||||
detached: process.platform !== "win32",
|
||||
cwd: join(fixturesDir, "cloudflare"),
|
||||
stdio: "pipe",
|
||||
});
|
||||
|
||||
const stopProcessTree = async () => {
|
||||
if (
|
||||
cp.pid === undefined ||
|
||||
cp.exitCode !== null ||
|
||||
cp.signalCode !== null
|
||||
) {
|
||||
return;
|
||||
}
|
||||
await terminate(cp.pid);
|
||||
const stopProcessTree = () => terminate(cp);
|
||||
const stopOnSignal = (signal: NodeJS.Signals) => {
|
||||
const exitWithSignal = () => {
|
||||
process.off("SIGINT", stopOnSignal);
|
||||
process.off("SIGTERM", stopOnSignal);
|
||||
process.kill(process.pid, signal);
|
||||
};
|
||||
void stopProcessTree().then(exitWithSignal, exitWithSignal);
|
||||
};
|
||||
process.on("SIGINT", stopOnSignal);
|
||||
process.on("SIGTERM", stopOnSignal);
|
||||
cp.once("close", () => {
|
||||
process.off("SIGINT", stopOnSignal);
|
||||
process.off("SIGTERM", stopOnSignal);
|
||||
});
|
||||
t.after(stopProcessTree);
|
||||
|
||||
const unexpectedWarnings = new Set(["node:sqlite", "node:async_hooks"]);
|
||||
|
||||
@@ -164,7 +164,6 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentelemetry/semantic-conventions": "^1.41.1",
|
||||
"@standard-schema/spec": "^1.1.0",
|
||||
"zod": "catalog:"
|
||||
},
|
||||
@@ -175,6 +174,7 @@
|
||||
"@opentelemetry/api": "^1.9.1",
|
||||
"@opentelemetry/sdk-trace-base": "^2.10.0",
|
||||
"@opentelemetry/sdk-trace-node": "^2.10.0",
|
||||
"@opentelemetry/semantic-conventions": "^1.41.1",
|
||||
"better-call": "catalog:",
|
||||
"jose": "^6.2.3",
|
||||
"kysely": "catalog:",
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { readdirSync, readFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import * as semanticConventions from "@opentelemetry/semantic-conventions";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import * as attributes from "./attributes";
|
||||
|
||||
const SEMANTIC_CONVENTIONS = "@opentelemetry/semantic-conventions";
|
||||
|
||||
/**
|
||||
* @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/db/
|
||||
* @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/http/
|
||||
*/
|
||||
describe("instrumentation attributes", () => {
|
||||
it.for([
|
||||
"ATTR_DB_COLLECTION_NAME",
|
||||
"ATTR_DB_OPERATION_NAME",
|
||||
"ATTR_HTTP_RESPONSE_STATUS_CODE",
|
||||
"ATTR_HTTP_ROUTE",
|
||||
] as const)("%s matches the OpenTelemetry semantic convention", (name) => {
|
||||
expect(attributes[name]).toBe(semanticConventions[name]);
|
||||
});
|
||||
|
||||
it("keeps the semantic conventions package out of production source", () => {
|
||||
const srcDir = fileURLToPath(new URL("..", import.meta.url));
|
||||
const importers = readdirSync(srcDir, { recursive: true, encoding: "utf8" })
|
||||
.filter((file) => file.endsWith(".ts") && !file.endsWith(".test.ts"))
|
||||
.filter((file) =>
|
||||
readFileSync(join(srcDir, file), "utf8").includes(
|
||||
`"${SEMANTIC_CONVENTIONS}"`,
|
||||
),
|
||||
);
|
||||
|
||||
expect(importers).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -1,16 +1,18 @@
|
||||
import {
|
||||
ATTR_DB_COLLECTION_NAME,
|
||||
ATTR_DB_OPERATION_NAME,
|
||||
ATTR_HTTP_RESPONSE_STATUS_CODE,
|
||||
ATTR_HTTP_ROUTE,
|
||||
} from "@opentelemetry/semantic-conventions";
|
||||
// Keep these stable OpenTelemetry keys local to avoid installing the full
|
||||
// semantic conventions registry just for four string constants.
|
||||
|
||||
export {
|
||||
ATTR_DB_COLLECTION_NAME,
|
||||
ATTR_DB_OPERATION_NAME,
|
||||
ATTR_HTTP_RESPONSE_STATUS_CODE,
|
||||
ATTR_HTTP_ROUTE,
|
||||
};
|
||||
/** Database collection accessed by the operation. */
|
||||
export const ATTR_DB_COLLECTION_NAME = "db.collection.name" as const;
|
||||
|
||||
/** Database operation performed by the span. */
|
||||
export const ATTR_DB_OPERATION_NAME = "db.operation.name" as const;
|
||||
|
||||
/** HTTP response status code. */
|
||||
export const ATTR_HTTP_RESPONSE_STATUS_CODE =
|
||||
"http.response.status_code" as const;
|
||||
|
||||
/** Matched HTTP route template. */
|
||||
export const ATTR_HTTP_ROUTE = "http.route" as const;
|
||||
|
||||
/** Operation identifier (e.g. getSession, signUpWithEmailAndPassword). Uses endpoint operationId when set, otherwise the endpoint key. */
|
||||
export const ATTR_OPERATION_ID = "better_auth.operation_id" as const;
|
||||
|
||||
@@ -308,8 +308,9 @@ export const expoClient = (opts: ExpoClientOptions) => {
|
||||
const rawScheme =
|
||||
opts?.scheme || Constants.expoConfig?.scheme || Constants.platform?.scheme;
|
||||
const scheme = Array.isArray(rawScheme) ? rawScheme[0] : rawScheme;
|
||||
const nativeScheme = isWeb ? undefined : scheme;
|
||||
|
||||
if (!scheme && !isWeb) {
|
||||
if (!nativeScheme && !isWeb) {
|
||||
throw new Error(
|
||||
"Scheme not found in app.json. Please provide a scheme in the options.",
|
||||
);
|
||||
@@ -443,7 +444,7 @@ export const expoClient = (opts: ExpoClientOptions) => {
|
||||
},
|
||||
},
|
||||
async init(url, options) {
|
||||
if (isWeb) {
|
||||
if (!nativeScheme) {
|
||||
return {
|
||||
url,
|
||||
options: options as ClientFetchOption,
|
||||
@@ -469,7 +470,9 @@ export const expoClient = (opts: ExpoClientOptions) => {
|
||||
options.headers = {
|
||||
...options.headers,
|
||||
...(cookie ? { cookie } : {}),
|
||||
...(isLinkSocial ? { "expo-origin": getOrigin(scheme!) } : {}),
|
||||
...(isLinkSocial
|
||||
? { "expo-origin": getOrigin(nativeScheme) }
|
||||
: {}),
|
||||
"x-skip-oauth-proxy": "true",
|
||||
};
|
||||
} else {
|
||||
@@ -478,7 +481,7 @@ export const expoClient = (opts: ExpoClientOptions) => {
|
||||
options.headers = {
|
||||
...options.headers,
|
||||
...(cookie ? { cookie } : {}),
|
||||
"expo-origin": getOrigin(scheme!),
|
||||
"expo-origin": getOrigin(nativeScheme),
|
||||
"x-skip-oauth-proxy": "true",
|
||||
};
|
||||
if (options.body?.callbackURL) {
|
||||
|
||||
Generated
+4
-74
@@ -811,11 +811,7 @@ importers:
|
||||
specifier: 8.2.0
|
||||
version: 8.2.0(@types/node@25.9.4)(esbuild@0.28.1)(jiti@2.7.0)(terser@5.46.1)(tsx@4.21.0)(yaml@2.9.0)
|
||||
|
||||
e2e/integration/test-utils:
|
||||
devDependencies:
|
||||
terminate:
|
||||
specifier: ^2.8.0
|
||||
version: 2.8.0
|
||||
e2e/integration/test-utils: {}
|
||||
|
||||
e2e/integration/vanilla-node:
|
||||
dependencies:
|
||||
@@ -1335,9 +1331,6 @@ importers:
|
||||
|
||||
packages/core:
|
||||
dependencies:
|
||||
'@opentelemetry/semantic-conventions':
|
||||
specifier: ^1.41.1
|
||||
version: 1.41.1
|
||||
'@standard-schema/spec':
|
||||
specifier: ^1.1.0
|
||||
version: 1.1.0
|
||||
@@ -1363,6 +1356,9 @@ importers:
|
||||
'@opentelemetry/sdk-trace-node':
|
||||
specifier: ^2.10.0
|
||||
version: 2.10.0(@opentelemetry/api@1.9.1)
|
||||
'@opentelemetry/semantic-conventions':
|
||||
specifier: ^1.41.1
|
||||
version: 1.41.1
|
||||
better-call:
|
||||
specifier: 'catalog:'
|
||||
version: 1.4.2(zod@4.5.4)
|
||||
@@ -9902,9 +9898,6 @@ packages:
|
||||
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
event-stream@3.3.4:
|
||||
resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==}
|
||||
|
||||
event-target-shim@5.0.1:
|
||||
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -10288,9 +10281,6 @@ packages:
|
||||
resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
from@0.1.7:
|
||||
resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==}
|
||||
|
||||
fromentries@1.3.2:
|
||||
resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==}
|
||||
|
||||
@@ -11699,9 +11689,6 @@ packages:
|
||||
makeerror@1.0.12:
|
||||
resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==}
|
||||
|
||||
map-stream@0.1.0:
|
||||
resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==}
|
||||
|
||||
mariadb@3.4.5:
|
||||
resolution: {integrity: sha512-gThTYkhIS5rRqkVr+Y0cIdzr+GRqJ9sA2Q34e0yzmyhMCwyApf3OKAC1jnF23aSlIOqJuyaUFUcj7O1qZslmmQ==}
|
||||
engines: {node: '>= 14'}
|
||||
@@ -12807,9 +12794,6 @@ packages:
|
||||
pathe@2.0.3:
|
||||
resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==}
|
||||
|
||||
pause-stream@0.0.11:
|
||||
resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==}
|
||||
|
||||
perfect-debounce@1.0.0:
|
||||
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
|
||||
|
||||
@@ -13299,11 +13283,6 @@ packages:
|
||||
resolution: {integrity: sha512-lxMEoIL/BQlk2KunFzxwUPwMvjFH7x7cmvzSLsSHpyMXl9FFfLUlfKrYwFc4wx/ZaIxxuXC4n8rjQ1CX/tkXVQ==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
ps-tree@1.2.0:
|
||||
resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==}
|
||||
engines: {node: '>= 0.10'}
|
||||
hasBin: true
|
||||
|
||||
publint@0.3.21:
|
||||
resolution: {integrity: sha512-OqejcnMV6E9zel2oCrUOJEiiFkGiAAni0A6ibfQNh1k9Gu5z4F+Yso8lllam7AzmV6Do0vp7u3UpZNRBwuXaHQ==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -14210,9 +14189,6 @@ packages:
|
||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||
engines: {node: '>= 10.x'}
|
||||
|
||||
split@0.3.3:
|
||||
resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==}
|
||||
|
||||
sprintf-js@1.0.3:
|
||||
resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
|
||||
|
||||
@@ -14277,9 +14253,6 @@ packages:
|
||||
resolution: {integrity: sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg==}
|
||||
engines: {node: '>= 0.10.0'}
|
||||
|
||||
stream-combiner@0.0.4:
|
||||
resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==}
|
||||
|
||||
streamx@2.23.0:
|
||||
resolution: {integrity: sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==}
|
||||
|
||||
@@ -14540,10 +14513,6 @@ packages:
|
||||
resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
terminate@2.8.0:
|
||||
resolution: {integrity: sha512-bcbjJEg0wY5nuJXvGxxHfmoEPkyHLCctUKO6suwtxy7jVSgGcgPeGwpbLDLELFhIaxCGRr3dPvyNg1yuz2V0eg==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
terracotta@1.1.0:
|
||||
resolution: {integrity: sha512-kfQciWUBUBgYkXu7gh3CK3FAJng/iqZslAaY08C+k1Hdx17aVEpcFFb/WPaysxAfcupNH3y53s/pc53xxZauww==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -14585,9 +14554,6 @@ packages:
|
||||
resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
through@2.3.8:
|
||||
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
|
||||
|
||||
tiny-inflate@1.0.3:
|
||||
resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==}
|
||||
|
||||
@@ -25980,16 +25946,6 @@ snapshots:
|
||||
|
||||
etag@1.8.1: {}
|
||||
|
||||
event-stream@3.3.4:
|
||||
dependencies:
|
||||
duplexer: 0.1.2
|
||||
from: 0.1.7
|
||||
map-stream: 0.1.0
|
||||
pause-stream: 0.0.11
|
||||
split: 0.3.3
|
||||
stream-combiner: 0.0.4
|
||||
through: 2.3.8
|
||||
|
||||
event-target-shim@5.0.1: {}
|
||||
|
||||
eventemitter3@4.0.7: {}
|
||||
@@ -26511,8 +26467,6 @@ snapshots:
|
||||
|
||||
fresh@2.0.0: {}
|
||||
|
||||
from@0.1.7: {}
|
||||
|
||||
fromentries@1.3.2: {}
|
||||
|
||||
fs-constants@1.0.0: {}
|
||||
@@ -27911,8 +27865,6 @@ snapshots:
|
||||
dependencies:
|
||||
tmpl: 1.0.5
|
||||
|
||||
map-stream@0.1.0: {}
|
||||
|
||||
mariadb@3.4.5:
|
||||
dependencies:
|
||||
'@types/geojson': 7946.0.16
|
||||
@@ -30235,10 +30187,6 @@ snapshots:
|
||||
|
||||
pathe@2.0.3: {}
|
||||
|
||||
pause-stream@0.0.11:
|
||||
dependencies:
|
||||
through: 2.3.8
|
||||
|
||||
perfect-debounce@1.0.0: {}
|
||||
|
||||
perfect-debounce@2.1.0: {}
|
||||
@@ -30702,10 +30650,6 @@ snapshots:
|
||||
|
||||
ps-list@9.0.0: {}
|
||||
|
||||
ps-tree@1.2.0:
|
||||
dependencies:
|
||||
event-stream: 3.3.4
|
||||
|
||||
publint@0.3.21:
|
||||
dependencies:
|
||||
'@publint/pack': 0.1.4
|
||||
@@ -32160,10 +32104,6 @@ snapshots:
|
||||
|
||||
split2@4.2.0: {}
|
||||
|
||||
split@0.3.3:
|
||||
dependencies:
|
||||
through: 2.3.8
|
||||
|
||||
sprintf-js@1.0.3: {}
|
||||
|
||||
sprintf-js@1.1.3: {}
|
||||
@@ -32205,10 +32145,6 @@ snapshots:
|
||||
|
||||
stream-buffers@2.2.0: {}
|
||||
|
||||
stream-combiner@0.0.4:
|
||||
dependencies:
|
||||
duplexer: 0.1.2
|
||||
|
||||
streamx@2.23.0:
|
||||
dependencies:
|
||||
events-universal: 1.0.1
|
||||
@@ -32526,10 +32462,6 @@ snapshots:
|
||||
ansi-escapes: 4.3.2
|
||||
supports-hyperlinks: 2.3.0
|
||||
|
||||
terminate@2.8.0:
|
||||
dependencies:
|
||||
ps-tree: 1.2.0
|
||||
|
||||
terracotta@1.1.0(solid-js@1.9.11):
|
||||
dependencies:
|
||||
solid-js: 1.9.11
|
||||
@@ -32572,8 +32504,6 @@ snapshots:
|
||||
|
||||
throttleit@2.1.0: {}
|
||||
|
||||
through@2.3.8: {}
|
||||
|
||||
tiny-inflate@1.0.3: {}
|
||||
|
||||
tiny-invariant@1.3.3: {}
|
||||
|
||||
@@ -84,6 +84,9 @@
|
||||
{
|
||||
"path": "./e2e/adapter/tsconfig.json"
|
||||
},
|
||||
{
|
||||
"path": "./e2e/integration/test-utils/tsconfig.json"
|
||||
},
|
||||
{
|
||||
"path": "./test/tsconfig.json"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user