Fix a bunch of errors we had

This commit is contained in:
2026-03-28 12:15:22 -05:00
parent b9c845cac1
commit 4c97c7fa17
43 changed files with 6003 additions and 8839 deletions

View File

@@ -0,0 +1 @@
[{"/home/gib/Documents/Code/convex-monorepo/apps/expo/index.ts":"1","/home/gib/Documents/Code/convex-monorepo/apps/expo/nativewind-env.d.ts":"2","/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/_layout.tsx":"3","/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/index.tsx":"4","/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/post/[id].tsx":"5","/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/base-url.ts":"6","/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/convex.ts":"7","/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/session-store.ts":"8"},{"size":28,"mtime":1768155639000,"results":"9","hashOfConfig":"10"},{"size":246,"mtime":1766222924000,"results":"11","hashOfConfig":"10"},{"size":836,"mtime":1774546669443,"results":"12","hashOfConfig":"10"},{"size":1935,"mtime":1774546669443,"results":"13","hashOfConfig":"10"},{"size":678,"mtime":1774546669443,"results":"14","hashOfConfig":"10"},{"size":880,"mtime":1768155639000,"results":"15","hashOfConfig":"10"},{"size":909,"mtime":1774546669443,"results":"16","hashOfConfig":"10"},{"size":272,"mtime":1768155639000,"results":"17","hashOfConfig":"10"},{"filePath":"18","messages":"19","suppressedMessages":"20","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"x7pzu2",{"filePath":"21","messages":"22","suppressedMessages":"23","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"24","messages":"25","suppressedMessages":"26","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"27","messages":"28","suppressedMessages":"29","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"30","messages":"31","suppressedMessages":"32","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"33","messages":"34","suppressedMessages":"35","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"36","messages":"37","suppressedMessages":"38","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"39","messages":"40","suppressedMessages":"41","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"/home/gib/Documents/Code/convex-monorepo/apps/expo/index.ts",[],[],"/home/gib/Documents/Code/convex-monorepo/apps/expo/nativewind-env.d.ts",[],[],"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/_layout.tsx",[],[],"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/index.tsx",[],[],"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/post/[id].tsx",[],[],"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/base-url.ts",[],[],"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/convex.ts",[],[],"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/session-store.ts",[],[]]

View File

@@ -1 +1 @@
[["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21"],{"key":"22","value":"23"},{"key":"24","value":"25"},{"key":"26","value":"27"},{"key":"28","value":"29"},{"key":"30","value":"31"},{"key":"32","value":"33"},{"key":"34","value":"35"},{"key":"36","value":"37"},{"key":"38","value":"39"},{"key":"40","value":"41"},{"key":"42","value":"43"},{"key":"44","value":"45"},{"key":"46","value":"47"},{"key":"48","value":"49"},{"key":"50","value":"51"},{"key":"52","value":"53"},{"key":"54","value":"55"},{"key":"56","value":"57"},{"key":"58","value":"59"},{"key":"60","value":"61"},{"key":"62","value":"63"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/index.tsx",{"size":1935,"mtime":1774546669443,"hash":"64","data":"65"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/index.ts",{"size":28,"mtime":1768155639000,"hash":"66","data":"67"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/assets/icon-dark.png",{"size":19633,"mtime":1766222924000,"hash":"68"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/postcss.config.js",{"size":65,"mtime":1774546669443,"hash":"69","data":"70"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/post/[id].tsx",{"size":678,"mtime":1774546669443,"hash":"71","data":"72"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/convex.ts",{"size":909,"mtime":1774546669443,"data":"73"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/eas.json",{"size":566,"mtime":1774546669443,"hash":"74","data":"75"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/_layout.tsx",{"size":836,"mtime":1774546669443,"hash":"76","data":"77"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/styles.css",{"size":89,"mtime":1774546669443,"hash":"78","data":"79"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/.cache/.prettiercache",{"size":4646,"mtime":1774546669443},"/home/gib/Documents/Code/convex-monorepo/apps/expo/assets/icon-light.png",{"size":19133,"mtime":1766222924000,"hash":"80"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/package.json",{"size":2228,"mtime":1774588990619,"hash":"81","data":"82"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/turbo.json",{"size":171,"mtime":1774031879321,"hash":"83","data":"84"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/eslint.config.mts",{"size":274,"mtime":1774546669443,"hash":"85","data":"86"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/tsconfig.json",{"size":387,"mtime":1766228480000,"hash":"87","data":"88"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/metro.config.js",{"size":511,"mtime":1768155639000,"hash":"89","data":"90"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/nativewind-env.d.ts",{"size":246,"mtime":1766222924000,"hash":"91","data":"92"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/base-url.ts",{"size":880,"mtime":1768155639000,"hash":"93","data":"94"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/.expo-shared/assets.json",{"size":155,"mtime":1766222924000,"hash":"95","data":"96"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/session-store.ts",{"size":272,"mtime":1768155639000,"hash":"97","data":"98"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/app.config.ts",{"size":1333,"mtime":1768155639000,"hash":"99","data":"100"},"73c235a66242df70b69394cce29d1ed3",{"hashOfOptions":"101"},"11cdbef6afa001cd39bc187041ca6865",{"hashOfOptions":"102"},"1e8ac0d261e95efb19d290ffcf70ce36","b7edffce093c4c84092cc93f3dc208ef",{"hashOfOptions":"103"},"ead19d73283f9d8e08b55c896c9fd570",{"hashOfOptions":"104"},{"hashOfOptions":"105"},"a3c1487f8318513ae7c156acc857fde2",{"hashOfOptions":"106"},"8e407b4b1b0c0bd9c862a00243344be3",{"hashOfOptions":"107"},"52a1d72379b952dd802f47e1865bd0da",{"hashOfOptions":"108"},"863da15dbd856008b7c24077ca746d91","d8763702c14cdc382dcfb84f6f9a068f",{"hashOfOptions":"109"},"c7d4dcf839dfeaa02e0407adfd5e47a6",{"hashOfOptions":"110"},"1c1710ce3de3ce02e8054cc3787c8579",{"hashOfOptions":"111"},"6937fb7370f1e17491df649888d6ecc9",{"hashOfOptions":"112"},"dbe97bcde588a81538bbcd6a9befdddd",{"hashOfOptions":"113"},"d4d589c153ac8b5e7bf0fb130a5b5a7d",{"hashOfOptions":"114"},"dd2007a211e323deabb3f7fa7d16313f",{"hashOfOptions":"115"},"0f7f54c7161b8403d3bc42d91f59cd91",{"hashOfOptions":"116"},"1bc3e15a40c117eecc51294886ea9b38",{"hashOfOptions":"117"},"4f49c6df7733f874fbe72b4e20b3092b",{"hashOfOptions":"118"},"3000879843","3103968608","384110377","141502567","1235541372","1050155876","2025343866","4147067111","4228440757","3451484829","4039211292","3318113268","2585374463","45764855","1418614640","2754339483","1950506033","3468872477"]
[["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22"],{"key":"23","value":"24"},{"key":"25","value":"26"},{"key":"27","value":"28"},{"key":"29","value":"30"},{"key":"31","value":"32"},{"key":"33","value":"34"},{"key":"35","value":"36"},{"key":"37","value":"38"},{"key":"39","value":"40"},{"key":"41","value":"42"},{"key":"43","value":"44"},{"key":"45","value":"46"},{"key":"47","value":"48"},{"key":"49","value":"50"},{"key":"51","value":"52"},{"key":"53","value":"54"},{"key":"55","value":"56"},{"key":"57","value":"58"},{"key":"59","value":"60"},{"key":"61","value":"62"},{"key":"63","value":"64"},{"key":"65","value":"66"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/index.tsx",{"size":1935,"mtime":1774546669443,"hash":"67","data":"68"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/index.ts",{"size":28,"mtime":1768155639000,"hash":"69","data":"70"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/assets/icon-dark.png",{"size":19633,"mtime":1766222924000,"hash":"71"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/postcss.config.js",{"size":65,"mtime":1774546669443,"hash":"72","data":"73"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/post/[id].tsx",{"size":678,"mtime":1774546669443,"hash":"74","data":"75"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/convex.ts",{"size":909,"mtime":1774546669443,"data":"76"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/eas.json",{"size":566,"mtime":1774546669443,"hash":"77","data":"78"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/app/_layout.tsx",{"size":836,"mtime":1774546669443,"hash":"79","data":"80"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/styles.css",{"size":89,"mtime":1774546669443,"hash":"81","data":"82"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/.cache/.prettiercache",{"size":4646,"mtime":1774715745793},"/home/gib/Documents/Code/convex-monorepo/apps/expo/.cache/.eslintcache",{"size":3079,"mtime":1774717490445},"/home/gib/Documents/Code/convex-monorepo/apps/expo/assets/icon-light.png",{"size":19133,"mtime":1766222924000,"hash":"83"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/package.json",{"size":2228,"mtime":1774588990619,"hash":"84","data":"85"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/turbo.json",{"size":171,"mtime":1774031879321,"hash":"86","data":"87"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/eslint.config.mts",{"size":274,"mtime":1774546669443,"hash":"88","data":"89"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/tsconfig.json",{"size":387,"mtime":1766228480000,"hash":"90","data":"91"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/metro.config.js",{"size":511,"mtime":1768155639000,"hash":"92","data":"93"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/nativewind-env.d.ts",{"size":246,"mtime":1766222924000,"hash":"94","data":"95"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/base-url.ts",{"size":880,"mtime":1768155639000,"hash":"96","data":"97"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/.expo-shared/assets.json",{"size":155,"mtime":1766222924000,"hash":"98","data":"99"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/src/utils/session-store.ts",{"size":272,"mtime":1768155639000,"hash":"100","data":"101"},"/home/gib/Documents/Code/convex-monorepo/apps/expo/app.config.ts",{"size":1333,"mtime":1768155639000,"hash":"102","data":"103"},"73c235a66242df70b69394cce29d1ed3",{"hashOfOptions":"104"},"11cdbef6afa001cd39bc187041ca6865",{"hashOfOptions":"105"},"1e8ac0d261e95efb19d290ffcf70ce36","b7edffce093c4c84092cc93f3dc208ef",{"hashOfOptions":"106"},"ead19d73283f9d8e08b55c896c9fd570",{"hashOfOptions":"107"},{"hashOfOptions":"108"},"a3c1487f8318513ae7c156acc857fde2",{"hashOfOptions":"109"},"8e407b4b1b0c0bd9c862a00243344be3",{"hashOfOptions":"110"},"52a1d72379b952dd802f47e1865bd0da",{"hashOfOptions":"111"},"863da15dbd856008b7c24077ca746d91","d8763702c14cdc382dcfb84f6f9a068f",{"hashOfOptions":"112"},"c7d4dcf839dfeaa02e0407adfd5e47a6",{"hashOfOptions":"113"},"1c1710ce3de3ce02e8054cc3787c8579",{"hashOfOptions":"114"},"6937fb7370f1e17491df649888d6ecc9",{"hashOfOptions":"115"},"dbe97bcde588a81538bbcd6a9befdddd",{"hashOfOptions":"116"},"d4d589c153ac8b5e7bf0fb130a5b5a7d",{"hashOfOptions":"117"},"dd2007a211e323deabb3f7fa7d16313f",{"hashOfOptions":"118"},"0f7f54c7161b8403d3bc42d91f59cd91",{"hashOfOptions":"119"},"1bc3e15a40c117eecc51294886ea9b38",{"hashOfOptions":"120"},"4f49c6df7733f874fbe72b4e20b3092b",{"hashOfOptions":"121"},"3000879843","3103968608","384110377","141502567","1235541372","1050155876","2025343866","4147067111","4228440757","3451484829","4039211292","3318113268","2585374463","45764855","1418614640","2754339483","1950506033","3468872477"]

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -159,7 +159,7 @@ const SignIn = () => {
};
const handleVerifyEmail = async (
values: z.infer<typeof verifyEmailFormSchema>,
_values: z.infer<typeof verifyEmailFormSchema>,
) => {
const formData = new FormData();
formData.append('code', code);
@@ -194,7 +194,7 @@ const SignIn = () => {
<FormField
control={verifyEmailForm.control}
name='code'
render={({ field }) => (
render={({ field: _field }) => (
<FormItem>
<FormLabel className='text-xl'>Code</FormLabel>
<FormControl>

View File

@@ -1,4 +1,6 @@
import type { LandingPageContent } from '@/components/landing/content';
import { LandingPageBuilder } from '@/components/landing';
import { defaultLandingPageContent } from '@/components/landing/content';
import { RefreshRouteOnSave } from '@/components/payload/refresh-route-on-save';
import { getLandingPageContent } from '@/lib/payload/get-landing-page-content';
@@ -14,7 +16,13 @@ const Home = async ({ searchParams }: HomeProps) => {
const isPreview = Array.isArray(previewParam)
? previewParam.includes('true')
: previewParam === 'true';
const content = await getLandingPageContent(isPreview);
let content: LandingPageContent;
try {
content = await getLandingPageContent(isPreview);
} catch {
content = defaultLandingPageContent;
}
return (
<main className='flex min-h-screen flex-col'>

View File

@@ -10,9 +10,7 @@ type Args = {
params: Promise<{
segments: string[];
}>;
searchParams: Promise<{
[key: string]: string | string[];
}>;
searchParams: Promise<Record<string, string | string[]>>;
};
export const generateMetadata = ({

View File

@@ -10,9 +10,7 @@ type Args = {
params: Promise<{
segments: string[];
}>;
searchParams: Promise<{
[key: string]: string | string[];
}>;
searchParams: Promise<Record<string, string | string[]>>;
};
export const generateMetadata = ({

View File

@@ -16,7 +16,7 @@ type Args = {
children: React.ReactNode;
};
const serverFunction: ServerFunctionClient = async function (args) {
const serverFunction: ServerFunctionClient = async (args) => {
'use server';
return handleServerFunctions({
...args,

View File

@@ -7,14 +7,15 @@ import { getPayloadClient } from './get-payload';
export const getLandingPageContent = async (
isPreview = false,
): Promise<LandingPageContent> => {
noStore();
if (isPreview) {
noStore();
}
const payload = await getPayloadClient();
const landingPage = await (
payload as {
findGlobal: (args: { slug: string; draft?: boolean }) => Promise<unknown>;
}
).findGlobal({ slug: 'landing-page', draft: isPreview });
const landingPage = await payload.findGlobal({
slug: 'landing-page',
draft: isPreview,
});
return mergeLandingPageContent(landingPage as Partial<LandingPageContent>);
return mergeLandingPageContent(landingPage);
};

View File

@@ -1,4 +1,3 @@
/* tslint:disable */
/* eslint-disable */
/**
* This file was automatically generated by Payload.

View File

@@ -8,6 +8,7 @@ import { Users } from './payload/collections/users';
import { LandingPage } from './payload/globals/landing-page';
export default buildConfig({
serverURL: env.NEXT_PUBLIC_SITE_URL,
editor: lexicalEditor(),
collections: [Users],
globals: [LandingPage],

View File

@@ -11,7 +11,11 @@ export const LandingPage: GlobalConfig = {
},
admin: {
livePreview: {
url: '/?preview=true',
url: ({
payload,
}: {
payload: { config: { serverURL?: string | null } };
}) => `${payload.config.serverURL ?? ''}/?preview=true`,
breakpoints: [
{
label: 'Mobile',

View File

@@ -6,7 +6,7 @@
"name": "convex-monorepo",
"devDependencies": {
"@gib/prettier-config": "workspace:",
"@turbo/gen": "^2.8.20",
"@turbo/gen": "^2.8.21",
"dotenv-cli": "11.0.0",
"prettier": "catalog:",
"turbo": "^2.8.21",
@@ -120,6 +120,7 @@
"@gib/eslint-config": "workspace:*",
"@gib/prettier-config": "workspace:*",
"@gib/tsconfig": "workspace:*",
"@types/node": "catalog:",
"eslint": "catalog:",
"prettier": "catalog:",
"react-email": "5.2.10",
@@ -1398,7 +1399,7 @@
"@turbo/darwin-arm64": ["@turbo/darwin-arm64@2.8.21", "", { "os": "darwin", "cpu": "arm64" }, "sha512-o9HEflxUEyr987x0cTUzZBhDOyL6u95JmdmlkH2VyxAw7zq2sdtM5e72y9ufv2N5SIoOBw1fVn9UES5VY5H6vQ=="],
"@turbo/gen": ["@turbo/gen@2.8.20", "", { "dependencies": { "@inquirer/prompts": "^7.10.1", "esbuild": "^0.25.0" }, "bin": { "gen": "dist/cli.js" } }, "sha512-SazKn5Pc9mitpc3uc6Pmf+QhkNtvF5t6Ro0V1cuc0QFhblbfw4KwWqFnnfTEmGzgDtb2CZJB3BK8LFMBX52eLg=="],
"@turbo/gen": ["@turbo/gen@2.8.21", "", { "dependencies": { "@inquirer/prompts": "^7.10.1", "esbuild": "^0.25.0" }, "bin": { "gen": "dist/cli.js" } }, "sha512-6MIArRRT2Re6Y3xF+Cn/aJY9zZZpsZro3LeDWpIOyTNscAIz0pRNfIHNlvwlwSHEkL9haVxQenuJxogFR3IVEQ=="],
"@turbo/linux-64": ["@turbo/linux-64@2.8.21", "", { "os": "linux", "cpu": "x64" }, "sha512-uTxlCcXWy5h1fSSymP8XSJ+AudzEHMDV3IDfKX7+DGB8kgJ+SLoTUAH7z4OFA7I/l2sznz0upPdbNNZs91YMag=="],

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -15,7 +15,6 @@ import type * as custom_auth_providers_password from "../custom/auth/providers/p
import type * as custom_auth_providers_usesend from "../custom/auth/providers/usesend.js";
import type * as files from "../files.js";
import type * as http from "../http.js";
import type * as utils from "../utils.js";
import type {
ApiFromModules,
@@ -31,7 +30,6 @@ declare const fullApi: ApiFromModules<{
"custom/auth/providers/usesend": typeof custom_auth_providers_usesend;
files: typeof files;
http: typeof http;
utils: typeof utils;
}>;
/**

View File

@@ -11,12 +11,11 @@
import type {
DataModelFromSchemaDefinition,
DocumentByName,
SystemTableNames,
TableNamesInDataModel,
} from 'convex/server';
import type { GenericId } from 'convex/values';
import schema from '../schema.js';
SystemTableNames,
} from "convex/server";
import type { GenericId } from "convex/values";
import schema from "../schema.js";
/**
* The names of all of your Convex tables.

View File

@@ -8,7 +8,7 @@ import {
import { ConvexError, v } from 'convex/values';
import type { Doc, Id } from './_generated/dataModel';
import type { MutationCtx, QueryCtx } from './_generated/server';
import type { QueryCtx } from './_generated/server';
import { api } from './_generated/api';
import { action, mutation, query } from './_generated/server';
import { Password, validatePassword } from './custom/auth';
@@ -96,11 +96,10 @@ export const updateUserPassword = action({
if (!userId) throw new ConvexError('Not authenticated.');
const user = await ctx.runQuery(api.auth.getUser, { userId });
if (!user?.email) throw new ConvexError('User not found.');
const verified = await retrieveAccount(ctx, {
await retrieveAccount(ctx, {
provider: 'password',
account: { id: user.email, secret: currentPassword },
});
if (!verified) throw new ConvexError('Current password is incorrect.');
if (!validatePassword(newPassword))
throw new ConvexError('Invalid password.');

View File

@@ -11,7 +11,7 @@ export default function UseSendProvider(config: EmailUserConfig): EmailConfig {
from: process.env.USESEND_FROM_EMAIL ?? 'noreply@example.com',
maxAge: 24 * 60 * 60, // 24 hours
async generateVerificationToken() {
generateVerificationToken() {
const random: RandomReader = {
read(bytes) {
crypto.getRandomValues(bytes);
@@ -26,17 +26,20 @@ export default function UseSendProvider(config: EmailUserConfig): EmailConfig {
const siteUrl = process.env.USESEND_FROM_EMAIL ?? '';
const appName = siteUrl.split('@')[1]?.split('.')[0] ?? 'App';
const useSend = new UseSend(
process.env.USESEND_API_KEY!,
process.env.USESEND_URL!,
);
const apiKey = process.env.USESEND_API_KEY;
const useSendUrl = process.env.USESEND_URL;
if (!apiKey || !useSendUrl) {
throw new Error('USESEND_API_KEY and USESEND_URL must be set.');
}
const useSend = new UseSend(apiKey, useSendUrl);
// For password reset, we want to send the code, not the magic link
const isPasswordReset =
url.includes('reset') || provider.id?.includes('reset');
url.includes('reset') || provider.id.includes('reset');
const result = await useSend.emails.send({
from: provider.from!,
from: provider.from ?? 'noreply@example.com',
to: [to],
subject: isPasswordReset
? `Reset your password - ${appName}`

11
packages/backend/convex/globals.d.ts vendored Normal file
View File

@@ -0,0 +1,11 @@
// Declare process.env for Convex backend environment variables.
// Convex supports process.env to read variables set in the Convex Dashboard.
declare const process: {
readonly env: {
readonly USESEND_API_KEY?: string;
readonly USESEND_URL?: string;
readonly USESEND_FROM_EMAIL?: string;
readonly CONVEX_CLOUD_URL?: string;
readonly [key: string]: string | undefined;
};
};

View File

@@ -1,16 +0,0 @@
export function missingEnvVariableUrl(envVarName: string, whereToGet: string) {
const deployment = deploymentName();
if (!deployment) return `Missing ${envVarName} in environment variables.`;
return (
`\n Missing ${envVarName} in environment variables.\n\n` +
` Get it from ${whereToGet} .\n Paste it on the Convex dashboard:\n` +
` https://dashboard.convex.dev/d/${deployment}/settings?var=${envVarName}`
);
}
export function deploymentName() {
const url = process.env.CONVEX_CLOUD_URL;
if (!url) return undefined;
const regex = new RegExp('https://(.+).convex.cloud');
return regex.exec(url)?.[1];
}

View File

@@ -0,0 +1,10 @@
import { defineConfig } from 'eslint/config';
import { baseConfig } from '@gib/eslint-config/base';
export default defineConfig(
{
ignores: ['convex/_generated/**', 'types/**', 'scripts/**', 'dist/**'],
},
baseConfig,
);

View File

@@ -36,6 +36,7 @@
"@gib/eslint-config": "workspace:*",
"@gib/prettier-config": "workspace:*",
"@gib/tsconfig": "workspace:*",
"@types/node": "catalog:",
"eslint": "catalog:",
"prettier": "catalog:",
"react-email": "5.2.10",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@ const BasedProgress = ({
value = 0,
...props
}: BasedProgressProps) => {
const [progress, setProgress] = React.useState<number>(value ?? 0);
const [progress, setProgress] = React.useState<number>(value);
React.useEffect(() => {
const id = window.setInterval(() => {
@@ -45,7 +45,7 @@ const BasedProgress = ({
<ProgressPrimitive.Indicator
data-slot='progress-indicator'
className='bg-primary h-full w-full flex-1 transition-all'
style={{ transform: `translateX(-${100 - (progress ?? 0)}%)` }}
style={{ transform: `translateX(-${100 - progress}%)` }}
/>
</ProgressPrimitive.Root>
);

View File

@@ -98,7 +98,7 @@ const Carousel = ({
api.on('select', onSelect);
return () => {
api?.off('select', onSelect);
api.off('select', onSelect);
};
}, [api, onSelect]);
@@ -108,8 +108,7 @@ const Carousel = ({
carouselRef,
api: api,
opts,
orientation:
orientation || (opts?.axis === 'y' ? 'vertical' : 'horizontal'),
orientation: orientation,
scrollPrev,
scrollNext,
canScrollPrev,

View File

@@ -48,7 +48,7 @@ const ChartContainer = ({
>['children'];
}) => {
const uniqueId = React.useId();
const chartId = `chart-${id || uniqueId.replace(/:/g, '')}`;
const chartId = `chart-${id ?? uniqueId.replace(/:/g, '')}`;
return (
<ChartContext.Provider value={{ config }}>
@@ -72,7 +72,7 @@ const ChartContainer = ({
const ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {
const colorConfig = Object.entries(config).filter(
([, config]) => config.theme || config.color,
([, config]) => config.theme ?? config.color,
);
if (!colorConfig.length) {
@@ -89,7 +89,7 @@ ${prefix} [data-chart=${id}] {
${colorConfig
.map(([key, itemConfig]) => {
const color =
itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ||
itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ??
itemConfig.color;
return color ? ` --color-${key}: ${color};` : null;
})
@@ -135,11 +135,11 @@ const ChartTooltipContent = ({
}
const [item] = payload;
const key = `${labelKey || item?.dataKey || item?.name || 'value'}`;
const key = `${labelKey ?? item?.dataKey ?? item?.name ?? 'value'}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
const value =
!labelKey && typeof label === 'string'
? config[label]?.label || label
? config[label]?.label ?? label
: itemConfig?.label;
if (labelFormatter) {
@@ -183,9 +183,9 @@ const ChartTooltipContent = ({
{payload
.filter((item) => item.type !== 'none')
.map((item, index) => {
const key = `${nameKey || item.name || item.dataKey || 'value'}`;
const key = `${nameKey ?? item.name ?? item.dataKey ?? 'value'}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
const indicatorColor = color || item.payload.fill || item.color;
const indicatorColor = color ?? item.payload.fill ?? item.color;
return (
<div
@@ -232,7 +232,7 @@ const ChartTooltipContent = ({
<div className='grid gap-1.5'>
{nestLabel ? tooltipLabel : null}
<span className='text-muted-foreground'>
{itemConfig?.label || item.name}
{itemConfig?.label ?? item.name}
</span>
</div>
{item.value && (
@@ -281,7 +281,7 @@ const ChartLegendContent = ({
{payload
.filter((item) => item.type !== 'none')
.map((item) => {
const key = `${nameKey || item.dataKey || 'value'}`;
const key = `${nameKey ?? item.dataKey ?? 'value'}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
return (

View File

@@ -46,10 +46,6 @@ const useFormField = () => {
const formState = useFormState({ name: fieldContext.name });
const fieldState = getFieldState(fieldContext.name, formState);
if (!fieldContext) {
throw new Error('useFormField should be used within <FormField>');
}
const { id } = itemContext;
return {
@@ -138,7 +134,7 @@ const FormDescription = ({
const FormMessage = ({ className, ...props }: React.ComponentProps<'p'>) => {
const { error, formMessageId } = useFormField();
const body = error ? String(error?.message ?? '') : props.children;
const body = error ? String(error.message ?? '') : props.children;
if (!body) {
return null;

View File

@@ -1,5 +1,4 @@
import * as React from 'react';
import { MousePointerClick, X } from 'lucide-react';
type EventType =
| 'mousedown'

View File

@@ -153,7 +153,7 @@ export const ImageCrop = ({
useEffect(() => {
const reader = new FileReader();
reader.addEventListener('load', () =>
setImgSrc(reader.result?.toString() || ''),
setImgSrc(typeof reader.result === 'string' ? reader.result : ''),
);
reader.readAsDataURL(file);
}, [file]);
@@ -173,12 +173,13 @@ export const ImageCrop = ({
onChange?.(pixelCrop, percentCrop);
};
const handleComplete = async (
const handleComplete = (
pixelCrop: PixelCrop,
percentCrop: PercentCrop,
) => {
): Promise<void> => {
setCompletedCrop(pixelCrop);
onComplete?.(pixelCrop, percentCrop);
return Promise.resolve();
};
const applyCrop = async () => {

View File

@@ -47,7 +47,7 @@ const InputOTPSlot = ({
index: number;
}) => {
const inputOTPContext = React.useContext(OTPInputContext);
const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {};
const { char, hasFakeCaret, isActive } = inputOTPContext.slots[index] ?? {};
return (
<div

View File

@@ -21,7 +21,7 @@ const Progress = ({
<ProgressPrimitive.Indicator
data-slot='progress-indicator'
className='bg-primary size-full flex-1 transition-all'
style={{ transform: `translateX(-${100 - (value || 0)}%)` }}
style={{ transform: `translateX(-${100 - (value ?? 0)}%)` }}
/>
</ProgressPrimitive.Root>
);

View File

@@ -602,9 +602,9 @@ const SidebarMenuSkeleton = ({
showIcon?: boolean;
}) => {
// Random width between 50 to 90%.
const width = React.useMemo(() => {
return `${Math.floor(Math.random() * 40) + 50}%`;
}, []);
const [width] = React.useState(
() => `${Math.floor(Math.random() * 40) + 50}%`,
);
return (
<div

View File

@@ -58,13 +58,13 @@ const ToggleGroupItem = ({
return (
<ToggleGroupPrimitive.Item
data-slot='toggle-group-item'
data-variant={context.variant || variant}
data-size={context.size || size}
data-variant={context.variant ?? variant}
data-size={context.size ?? size}
data-spacing={context.spacing}
className={cn(
toggleVariants({
variant: context.variant || variant,
size: context.size || size,
variant: context.variant ?? variant,
size: context.size ?? size,
}),
'w-auto min-w-0 shrink-0 px-3 focus:z-10 focus-visible:z-10',
'data-[spacing=0]:rounded-none data-[spacing=0]:shadow-none data-[spacing=0]:first:rounded-l-md data-[spacing=0]:last:rounded-r-md data-[spacing=0]:data-[variant=outline]:border-l-0 data-[spacing=0]:data-[variant=outline]:first:border-l',

View File

@@ -1 +1 @@
[["1","2","3","4","5","6"],{"key":"7","value":"8"},{"key":"9","value":"10"},{"key":"11","value":"12"},{"key":"13","value":"14"},{"key":"15","value":"16"},{"key":"17","value":"18"},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/base.ts",{"size":2963,"mtime":1774546669459,"hash":"19","data":"20"},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/nextjs.ts",{"size":440,"mtime":1768155639000,"hash":"21","data":"22"},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/.cache/.prettiercache",{"size":1278,"mtime":1774546669459},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/package.json",{"size":1034,"mtime":1774588268325,"hash":"23","data":"24"},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/react.ts",{"size":592,"mtime":1768155639000,"hash":"25","data":"26"},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/tsconfig.json",{"size":94,"mtime":1766222924000,"hash":"27","data":"28"},"6a779439826cf31b5561a21273d134a9",{"hashOfOptions":"29"},"25c52c46972131dcc296288599ff108d",{"hashOfOptions":"30"},"a5326aca75246da261fd2e354257b45a",{"hashOfOptions":"31"},"2292935ede6baf909f6a0c61486e15da",{"hashOfOptions":"32"},"b3c77d33a30318d89c9c2cafcbe00bbe",{"hashOfOptions":"33"},"1686097143","2347540204","302976953","3406150487","1582266352"]
[["1","2","3","4","5","6"],{"key":"7","value":"8"},{"key":"9","value":"10"},{"key":"11","value":"12"},{"key":"13","value":"14"},{"key":"15","value":"16"},{"key":"17","value":"18"},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/base.ts",{"size":2963,"mtime":1774546669459,"hash":"19","data":"20"},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/nextjs.ts",{"size":440,"mtime":1768155639000,"hash":"21","data":"22"},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/.cache/.prettiercache",{"size":1278,"mtime":1774715745635},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/package.json",{"size":1034,"mtime":1774588268325,"hash":"23","data":"24"},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/react.ts",{"size":592,"mtime":1768155639000,"hash":"25","data":"26"},"/home/gib/Documents/Code/convex-monorepo/tools/eslint/tsconfig.json",{"size":94,"mtime":1766222924000,"hash":"27","data":"28"},"6a779439826cf31b5561a21273d134a9",{"hashOfOptions":"29"},"25c52c46972131dcc296288599ff108d",{"hashOfOptions":"30"},"a5326aca75246da261fd2e354257b45a",{"hashOfOptions":"31"},"2292935ede6baf909f6a0c61486e15da",{"hashOfOptions":"32"},"b3c77d33a30318d89c9c2cafcbe00bbe",{"hashOfOptions":"33"},"1686097143","2347540204","302976953","3406150487","1582266352"]

View File

@@ -1 +1 @@
[["1","2","3","4"],{"key":"5","value":"6"},{"key":"7","value":"8"},{"key":"9","value":"10"},{"key":"11","value":"12"},"/home/gib/Documents/Code/convex-monorepo/tools/prettier/.cache/.prettiercache",{"size":832,"mtime":1774546669459},"/home/gib/Documents/Code/convex-monorepo/tools/prettier/index.js",{"size":1194,"mtime":1768372320442,"hash":"13","data":"14"},"/home/gib/Documents/Code/convex-monorepo/tools/prettier/package.json",{"size":607,"mtime":1774032385569,"hash":"15","data":"16"},"/home/gib/Documents/Code/convex-monorepo/tools/prettier/tsconfig.json",{"size":94,"mtime":1766222924000,"hash":"17","data":"18"},"ecbaa91166a940dfcec8117059f52402",{"hashOfOptions":"19"},"11b634ce56ac720ac9a2860d77fbd2cc",{"hashOfOptions":"20"},"b3c77d33a30318d89c9c2cafcbe00bbe",{"hashOfOptions":"21"},"1828250668","802511607","4250532914"]
[["1","2","3","4"],{"key":"5","value":"6"},{"key":"7","value":"8"},{"key":"9","value":"10"},{"key":"11","value":"12"},"/home/gib/Documents/Code/convex-monorepo/tools/prettier/.cache/.prettiercache",{"size":832,"mtime":1774715745646},"/home/gib/Documents/Code/convex-monorepo/tools/prettier/index.js",{"size":1194,"mtime":1768372320442,"hash":"13","data":"14"},"/home/gib/Documents/Code/convex-monorepo/tools/prettier/package.json",{"size":607,"mtime":1774032385569,"hash":"15","data":"16"},"/home/gib/Documents/Code/convex-monorepo/tools/prettier/tsconfig.json",{"size":94,"mtime":1766222924000,"hash":"17","data":"18"},"ecbaa91166a940dfcec8117059f52402",{"hashOfOptions":"19"},"11b634ce56ac720ac9a2860d77fbd2cc",{"hashOfOptions":"20"},"b3c77d33a30318d89c9c2cafcbe00bbe",{"hashOfOptions":"21"},"1828250668","802511607","4250532914"]

View File

@@ -1 +1 @@
[{"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/postcss-config.js":"1"},{"size":70,"mtime":1768155639000,"results":"2","hashOfConfig":"3"},{"filePath":"4","messages":"5","suppressedMessages":"6","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"z9il2c","/home/gib/Documents/Code/convex-monorepo/tools/tailwind/postcss-config.js",[],[]]
[{"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/postcss-config.js":"1"},{"size":70,"mtime":1768155639000,"results":"2","hashOfConfig":"3"},{"filePath":"4","messages":"5","suppressedMessages":"6","errorCount":0,"fatalErrorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"zvlfqu","/home/gib/Documents/Code/convex-monorepo/tools/tailwind/postcss-config.js",[],[]]

View File

@@ -1 +1 @@
[["1","2","3","4","5","6","7"],{"key":"8","value":"9"},{"key":"10","value":"11"},{"key":"12","value":"13"},{"key":"14","value":"15"},{"key":"16","value":"17"},{"key":"18","value":"19"},{"key":"20","value":"21"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/.cache/.eslintcache",{"size":396,"mtime":1774546669459},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/.cache/.prettiercache",{"size":1450,"mtime":1774546669459},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/package.json",{"size":851,"mtime":1774032407411,"hash":"22","data":"23"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/tsconfig.json",{"size":94,"mtime":1766222924000,"hash":"24","data":"25"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/eslint.config.ts",{"size":143,"mtime":1768155639000,"hash":"26","data":"27"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/theme.css",{"size":7273,"mtime":1768320378000,"hash":"28","data":"29"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/postcss-config.js",{"size":70,"mtime":1768155639000,"hash":"30","data":"31"},"0d22e47f57739db9de04c6f8420d6fb5",{"hashOfOptions":"32"},"b3c77d33a30318d89c9c2cafcbe00bbe",{"hashOfOptions":"33"},"b8fec960cb32340eea62ca1485093e68",{"hashOfOptions":"34"},"e40c2569ef375a9c828c80c0f9ce1bf2",{"hashOfOptions":"35"},"9a944fbda06979be39571bd9bd00b0d9",{"hashOfOptions":"36"},"286235122","2846522359","1288936688","2683656544","1694755693"]
[["1","2","3","4","5","6","7"],{"key":"8","value":"9"},{"key":"10","value":"11"},{"key":"12","value":"13"},{"key":"14","value":"15"},{"key":"16","value":"17"},{"key":"18","value":"19"},{"key":"20","value":"21"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/.cache/.eslintcache",{"size":396,"mtime":1774717490012},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/.cache/.prettiercache",{"size":1450,"mtime":1774715745705},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/package.json",{"size":851,"mtime":1774032407411,"hash":"22","data":"23"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/tsconfig.json",{"size":94,"mtime":1766222924000,"hash":"24","data":"25"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/eslint.config.ts",{"size":143,"mtime":1768155639000,"hash":"26","data":"27"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/theme.css",{"size":7273,"mtime":1768320378000,"hash":"28","data":"29"},"/home/gib/Documents/Code/convex-monorepo/tools/tailwind/postcss-config.js",{"size":70,"mtime":1768155639000,"hash":"30","data":"31"},"0d22e47f57739db9de04c6f8420d6fb5",{"hashOfOptions":"32"},"b3c77d33a30318d89c9c2cafcbe00bbe",{"hashOfOptions":"33"},"b8fec960cb32340eea62ca1485093e68",{"hashOfOptions":"34"},"e40c2569ef375a9c828c80c0f9ce1bf2",{"hashOfOptions":"35"},"9a944fbda06979be39571bd9bd00b0d9",{"hashOfOptions":"36"},"286235122","2846522359","1288936688","2683656544","1694755693"]

View File

@@ -16,6 +16,7 @@
"CONVEX_SELF_HOSTED_URL",
"CONVEX_SELF_HOSTED_ADMIN_KEY",
"CONVEX_SITE_URL",
"CONVEX_CLOUD_URL",
"USESEND_API_KEY",
"USESEND_URL",
"USESEND_FROM_EMAIL",