Somewhat automate types and stuff.

This commit is contained in:
Gabriel Brown 2025-05-14 12:59:00 -05:00
parent 68ba7cc41f
commit 0cf1049ec6
23 changed files with 595 additions and 64 deletions

View File

@ -19,3 +19,9 @@ NODE_ENV=
# Client Variables
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
# Script Variables # Default Values
SUPABASE_DB_PASSWORD=
#SUPABASE_DB_PORT= # 5432
#SUPABASE_DB_USER= # postgres
#SUPABASE_DB_NAME= # postgres

View File

@ -1,29 +1,19 @@
# Create T3 App
# T3 Template with Self Hosted Supabase
This is a [T3 Stack](https://create.t3.gg/) project bootstrapped with `create-t3-app`.
This is my template for self hosting both Next.js & Supabase in order to create a perfect app!!
## What's next? How do I make an app with this?
## What to do
We try to keep this project as simple as possible, so you can start with just the scaffolding we set up for you, and add additional things later when they become necessary.
- [Self Host Supabase](https://supabase.com/docs/guides/self-hosting/docker)
- You will need to make sure you have some way to connect to the postgres database from the host. I had to remove the database port from the supabase-pooler and add it to the supabase-db in order to directly connect to it. This will be important for generating our types.
- Clone this repo.
- Go to src/server/db/schema.sql & run this SQL in the SQL editor on the Web UI of your Supabase instance.
- Generate your types
- This part is potentially super weird if you are self hosting. If you are connecting directly to your database that you plan to use for production, you will need to clone your repo on the host running supabase so that you can then use the supabase cli tool. Once you have done that, you will need to install the supabase-cli tool with sudo. I just run something like `sudo npx supabase --help` and then accept the prompt to install the program. Once you have done this, you can then run the following command, replacing the password and the port to match your supabase database:
If you are not familiar with the different technologies used in this project, please refer to the respective docs. If you still are in the wind, please join our [Discord](https://t3.gg/discord) and ask for help.
- [Next.js](https://nextjs.org)
- [NextAuth.js](https://next-auth.js.org)
- [Prisma](https://prisma.io)
- [Drizzle](https://orm.drizzle.team)
- [Tailwind CSS](https://tailwindcss.com)
- [tRPC](https://trpc.io)
## Learn More
To learn more about the [T3 Stack](https://create.t3.gg/), take a look at the following resources:
- [Documentation](https://create.t3.gg/)
- [Learn the T3 Stack](https://create.t3.gg/en/faq#what-learning-resources-are-currently-available) — Check out these awesome tutorials
You can check out the [create-t3-app GitHub repository](https://github.com/t3-oss/create-t3-app) — your feedback and contributions are welcome!
## How do I deploy this?
Follow our deployment guides for [Vercel](https://create.t3.gg/en/deployment/vercel), [Netlify](https://create.t3.gg/en/deployment/netlify) and [Docker](https://create.t3.gg/en/deployment/docker) for more information.
```bash
sudo npx supabase gen types typescript \
--db-url "postgres://postgres:password@localhost:5432/postgres" \
--schema public \
> ./src/lib/types
```

View File

@ -52,5 +52,5 @@
"ct3aMetadata": {
"initVersion": "7.39.3"
},
"packageManager": "pnpm@10.10.0"
"packageManager": "pnpm@10.11.0+sha512.6540583f41cc5f628eb3d9773ecee802f4f9ef9923cc45b69890fb47991d4b092964694ec3a4f738a420c918a333062c8b925d312f42e4f0c263eb603551f977"
}

133
scripts/generate_types.sh Executable file
View File

@ -0,0 +1,133 @@
#!/bin/bash
# Define colors for better output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
BOLD='\033[1m'
NC='\033[0m' # No Color
# Get the project root directory (one level up from scripts/)
PROJECT_ROOT="$(dirname "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)")"
# Clear the screen for better visibility
clear
echo -e "${BOLD}${BLUE}===== Supabase TypeScript Type Generator =====${NC}"
echo
echo -e "${YELLOW}⚠️ IMPORTANT: This script must be run on the server hosting the Supabase Docker container.${NC}"
echo -e "It will not work if you're running it from a different machine, even if connected via VPN."
echo
echo -e "Project root: ${BLUE}${PROJECT_ROOT}${NC}"
echo
# Ask for confirmation
read -p "Are you running this script on the Supabase host server? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${RED}Aborted. Please run this script on the server hosting Supabase.${NC}"
exit 1
fi
# Check for sudo access
if ! sudo -v; then
echo -e "${RED}Error: This script requires sudo privileges.${NC}"
exit 1
fi
# Check if .env file exists in project root
ENV_FILE="${PROJECT_ROOT}/.env"
if [ ! -f "$ENV_FILE" ]; then
echo -e "${RED}Error: .env file not found at ${ENV_FILE}${NC}"
echo -e "Please create a .env file with the following variables:"
echo -e "SUPABASE_DB_HOST, SUPABASE_DB_PORT, SUPABASE_DB_USER, SUPABASE_DB_PASSWORD, SUPABASE_DB_NAME"
exit 1
fi
echo -e "${GREEN}Found .env file at $ENV_FILE${NC}"
# Source the .env file to get environment variables
export $(grep -v '^#' $ENV_FILE | xargs)
# Check if required variables are set
if [ -z "$SUPABASE_DB_HOST" ] || [ -z "$SUPABASE_DB_PORT" ] || [ -z "$SUPABASE_DB_USER" ] || [ -z "$SUPABASE_DB_PASSWORD" ] || [ -z "$SUPABASE_DB_NAME" ]; then
# Try to use default variables if Supabase-specific ones aren't set
if [ -z "$SUPABASE_DB_HOST" ]; then SUPABASE_DB_HOST=${DB_HOST:-localhost}; fi
if [ -z "$SUPABASE_DB_PORT" ]; then SUPABASE_DB_PORT=${DB_PORT:-5432}; fi
if [ -z "$SUPABASE_DB_USER" ]; then SUPABASE_DB_USER=${DB_USER:-postgres}; fi
if [ -z "$SUPABASE_DB_PASSWORD" ]; then SUPABASE_DB_PASSWORD=${DB_PASSWORD}; fi
if [ -z "$SUPABASE_DB_NAME" ]; then SUPABASE_DB_NAME=${DB_NAME:-postgres}; fi
# Check again after trying defaults
if [ -z "$SUPABASE_DB_HOST" ] || [ -z "$SUPABASE_DB_PORT" ] || [ -z "$SUPABASE_DB_USER" ] || [ -z "$SUPABASE_DB_PASSWORD" ] || [ -z "$SUPABASE_DB_NAME" ]; then
echo -e "${RED}Error: Missing required environment variables${NC}"
echo -e "Please ensure your .env file contains:"
echo -e "SUPABASE_DB_HOST, SUPABASE_DB_PORT, SUPABASE_DB_USER, SUPABASE_DB_PASSWORD, SUPABASE_DB_NAME"
echo -e "Or the equivalent DB_* variables"
exit 1
fi
fi
# Check if supabase CLI is installed for the sudo user
echo -e "${YELLOW}Checking if Supabase CLI is installed...${NC}"
if ! sudo npx supabase --version &>/dev/null; then
echo -e "${YELLOW}Supabase CLI not found. Installing...${NC}"
sudo npm install -g supabase
if [ $? -ne 0 ]; then
echo -e "${RED}Failed to install Supabase CLI. Please install it manually:${NC}"
echo -e "sudo npm install -g supabase"
exit 1
fi
echo -e "${GREEN}Supabase CLI installed successfully.${NC}"
else
echo -e "${GREEN}Supabase CLI is already installed.${NC}"
fi
echo -e "${YELLOW}Generating Supabase TypeScript types...${NC}"
# Construct the database URL from environment variables
DB_URL="postgres://$SUPABASE_DB_USER:$SUPABASE_DB_PASSWORD@$SUPABASE_DB_HOST:$SUPABASE_DB_PORT/$SUPABASE_DB_NAME"
# Determine the output directory (relative to project root)
OUTPUT_DIR="${PROJECT_ROOT}/utils/supabase"
if [ ! -d "$OUTPUT_DIR" ]; then
echo -e "${YELLOW}Output directory $OUTPUT_DIR not found. Creating...${NC}"
mkdir -p "$OUTPUT_DIR"
fi
# Create a temporary file for the output
TEMP_FILE=$(mktemp)
# Run the Supabase CLI command with sudo
echo -e "${YELLOW}Running Supabase CLI to generate types...${NC}"
sudo -E npx supabase gen types typescript \
--db-url "$DB_URL" \
--schema public > "$TEMP_FILE" 2>&1
# Check if the command was successful
if [ $? -eq 0 ] && [ -s "$TEMP_FILE" ] && ! grep -q "Error" "$TEMP_FILE"; then
# Move the temp file to the final destination
mv "$TEMP_FILE" "$OUTPUT_DIR/types.ts"
echo -e "${GREEN}✓ TypeScript types successfully generated at $OUTPUT_DIR/types.ts${NC}"
# Show the first few lines to confirm it looks right
echo -e "${YELLOW}Preview of generated types:${NC}"
head -n 10 "$OUTPUT_DIR/types.ts"
echo -e "${YELLOW}...${NC}"
else
echo -e "${RED}✗ Failed to generate TypeScript types${NC}"
echo -e "${RED}Error output:${NC}"
cat "$TEMP_FILE"
rm "$TEMP_FILE"
exit 1
fi
# Clear sensitive environment variables
unset SUPABASE_DB_PASSWORD
unset DB_URL
echo -e "${GREEN}${BOLD}Type generation complete!${NC}"
echo -e "You can now use these types in your Next.js application."
echo -e "Import them with: ${BLUE}import { Database } from '@/utils/supabase/types'${NC}"

View File

@ -2,14 +2,14 @@
import 'server-only';
import { encodedRedirect } from '@/utils/utils';
import { createClient } from '@/utils/supabase/server';
import { createServerClient } from '@/utils/supabase';
import { headers } from 'next/headers';
import { redirect } from 'next/navigation';
export const signUp = async (formData: FormData) => {
const email = formData.get('email') as string;
const password = formData.get('password') as string;
const supabase = await createClient();
const supabase = await createServerClient();
const origin = (await headers()).get('origin');
if (!email || !password) {
@ -47,7 +47,7 @@ export const signUp = async (formData: FormData) => {
export const signIn = async (formData: FormData) => {
const email = formData.get('email') as string;
const password = formData.get('password') as string;
const supabase = await createClient();
const supabase = await createServerClient();
const { error } = await supabase.auth.signInWithPassword({
email,
@ -63,7 +63,7 @@ export const signIn = async (formData: FormData) => {
export const forgotPassword = async (formData: FormData) => {
const email = formData.get('email') as string;
const supabase = await createClient();
const supabase = await createServerClient();
const origin = (await headers()).get('origin');
const callbackUrl = formData.get('callbackUrl') as string;
@ -96,7 +96,7 @@ export const forgotPassword = async (formData: FormData) => {
};
export const resetPassword = async (formData: FormData) => {
const supabase = await createClient();
const supabase = await createServerClient();
const password = formData.get('password') as string;
const confirmPassword = formData.get('confirmPassword') as string;
@ -132,7 +132,7 @@ export const resetPassword = async (formData: FormData) => {
};
export const signOut = async () => {
const supabase = await createClient();
const supabase = await createServerClient();
await supabase.auth.signOut();
return redirect('/sign-in');
};

View File

@ -1,4 +1,4 @@
'use server';
import 'server-only';
import { createClient } from '@/utils/supabase/server';
import { createServerClient } from '@/utils/supabase';

View File

@ -1,4 +1,4 @@
import { createClient } from '@/utils/supabase/server';
import { createServerClient } from '@/utils/supabase';
import { NextResponse } from 'next/server';
export async function GET(request: Request) {
@ -11,7 +11,7 @@ export async function GET(request: Request) {
const redirectTo = requestUrl.searchParams.get('redirect_to')?.toString();
if (code) {
const supabase = await createClient();
const supabase = await createServerClient();
await supabase.auth.exchangeCodeForSession(code);
}

View File

@ -1,12 +1,12 @@
'use server';
import { FetchDataSteps } from '@/components/tutorial';
import { createClient } from '@/utils/supabase/server';
import { createServerClient } from '@/utils/supabase';
import { InfoIcon } from 'lucide-react';
import { redirect } from 'next/navigation';
const ProtectedPage = async () => {
const supabase = await createClient();
const supabase = await createServerClient();
const {
data: { user },
} = await supabase.auth.getUser();

View File

@ -1,10 +1,10 @@
'use server';
import { createClient } from '@/utils/supabase/server';
import { createServerClient } from '@/utils/supabase';
import Image from 'next/image';
export default async function Page() {
const supabase = await createClient();
const supabase = await createServerClient();
// Get authenticated user
const {

View File

@ -3,7 +3,7 @@ import * as React from 'react';
import { ThemeProvider as NextThemesProvider } from 'next-themes';
import { Moon, Sun } from 'lucide-react';
import { useTheme } from 'next-themes';
import { Button } from '@/components/ui/button';
import { Button } from '@/components/ui';
export const ThemeProvider = ({
children,

View File

@ -2,11 +2,11 @@
import Link from 'next/link';
import { Button } from '@/components/ui';
import { createClient } from '@/utils/supabase/server';
import { createServerClient } from '@/utils/supabase';
import { signOut } from '@/actions/auth';
const NavigationAuth = async () => {
const supabase = await createClient();
const supabase = await createServerClient();
const {
data: { user },
} = await supabase.auth.getUser();

View File

@ -43,7 +43,7 @@ export default function Page() {
}
`.trim();
const FetchDataSteps = () => {
export const FetchDataSteps = () => {
return (
<ol className='flex flex-col gap-6'>
<TutorialStep title='Create some tables and insert some data'>
@ -93,4 +93,3 @@ const FetchDataSteps = () => {
</ol>
);
};
export default FetchDataSteps;

View File

@ -1,5 +1,3 @@
import { CodeBlock } from '@/components/tutorial/code-block';
import FetchDataSteps from '@/components/tutorial/fetch-data-steps';
import { TutorialStep } from '@/components/tutorial/tutorial-step';
export { CodeBlock, FetchDataSteps, TutorialStep };
export { CodeBlock } from '@/components/tutorial/code-block';
export { FetchDataSteps } from '@/components/tutorial/fetch-data-steps';
export { TutorialStep } from '@/components/tutorial/tutorial-step';

View File

@ -1,7 +1,5 @@
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
export { Badge, Button, Checkbox, Input, Label };
export { Badge } from '@/components/ui/badge';
export { Button } from '@/components/ui/button';
export { Checkbox } from '@/components/ui/checkbox';
export { Input } from '@/components/ui/input';
export { Label } from '@/components/ui/label';

View File

View File

@ -2,7 +2,7 @@
create table profiles (
id uuid references auth.users on delete cascade not null primary key,
updated_at timestamp with time zone,
email text,
email text unique,
full_name text,
avatar_url text,
provider text,
@ -35,7 +35,7 @@ begin
new.id,
new.email,
new.raw_user_meta_data->>'full_name',
new.raw_user_meta_data->>'avatar_url'
new.raw_user_meta_data->>'avatar_url',
new.raw_user_meta_data->>'provider',
now()
);
@ -58,7 +58,6 @@ create policy "Avatar images are publicly accessible." on storage.objects
create policy "Anyone can upload an avatar." on storage.objects
for insert with check (bucket_id = 'avatars');
-- -- Create a table for public statuses
-- CREATE TABLE statuses (
-- id uuid DEFAULT gen_random_uuid() PRIMARY KEY,
@ -66,8 +65,7 @@ create policy "Anyone can upload an avatar." on storage.objects
-- updated_by_id uuid REFERENCES auth.users ON DELETE SET NULL DEFAULT auth.uid(),
-- created_at timestamp with time zone DEFAULT now() NOT NULL,
-- status text NOT NULL,
-- CONSTRAINT status_length CHECK (char_length(status) >= 3 AND char_length(status) <= 80),
-- CONSTRAINT statuses_user_id_fkey FOREIGN KEY (user_id) REFERENCES profiles(id) ON DELETE CASCADE
-- CONSTRAINT status_length CHECK (char_length(status) >= 3 AND char_length(status) <= 80)
-- );
-- -- Set up Row Level Security (RLS)

View File

@ -1,7 +1,8 @@
import { createBrowserClient } from '@supabase/ssr';
import type { Database } from '@/utils/supabase/types';
export const createClient = () =>
createBrowserClient(
createBrowserClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
);

View File

@ -0,0 +1,5 @@
export { createClient } from './client';
export { createClient as createServerClient } from './server';
export { updateSession } from './middleware';
export type * from './utils';
export type { Database } from './types';

View File

@ -1,5 +1,6 @@
import { createServerClient } from '@supabase/ssr';
import { type NextRequest, NextResponse } from 'next/server';
import type { Database } from '@/utils/supabase/types';
export const updateSession = async (request: NextRequest) => {
// This `try/catch` block is only here for the interactive tutorial.
@ -12,7 +13,7 @@ export const updateSession = async (request: NextRequest) => {
},
});
const supabase = createServerClient(
const supabase = createServerClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{

View File

@ -1,10 +1,11 @@
import { createServerClient } from '@supabase/ssr';
import type { Database } from '@/utils/supabase/types';
import { cookies } from 'next/headers';
export const createClient = async () => {
const cookieStore = await cookies();
return createServerClient(
return createServerClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{

188
src/utils/supabase/types.ts Normal file
View File

@ -0,0 +1,188 @@
export type Json =
| string
| number
| boolean
| null
| { [key: string]: Json | undefined }
| Json[];
export type Database = {
public: {
Tables: {
profiles: {
Row: {
avatar_url: string | null;
email: string | null;
full_name: string | null;
id: string;
provider: string | null;
updated_at: string | null;
};
Insert: {
avatar_url?: string | null;
email?: string | null;
full_name?: string | null;
id: string;
provider?: string | null;
updated_at?: string | null;
};
Update: {
avatar_url?: string | null;
email?: string | null;
full_name?: string | null;
id?: string;
provider?: string | null;
updated_at?: string | null;
};
Relationships: [];
};
statuses: {
Row: {
created_at: string;
id: string;
status: string;
updated_by_id: string | null;
user_id: string;
};
Insert: {
created_at?: string;
id?: string;
status: string;
updated_by_id?: string | null;
user_id: string;
};
Update: {
created_at?: string;
id?: string;
status?: string;
updated_by_id?: string | null;
user_id?: string;
};
Relationships: [];
};
};
Views: {
[_ in never]: never;
};
Functions: {
[_ in never]: never;
};
Enums: {
[_ in never]: never;
};
CompositeTypes: {
[_ in never]: never;
};
};
};
type DefaultSchema = Database[Extract<keyof Database, 'public'>];
export type Tables<
DefaultSchemaTableNameOrOptions extends
| keyof (DefaultSchema['Tables'] & DefaultSchema['Views'])
| { schema: keyof Database },
TableName extends DefaultSchemaTableNameOrOptions extends {
schema: keyof Database;
}
? keyof (Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'] &
Database[DefaultSchemaTableNameOrOptions['schema']]['Views'])
: never = never,
> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database }
? (Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'] &
Database[DefaultSchemaTableNameOrOptions['schema']]['Views'])[TableName] extends {
Row: infer R;
}
? R
: never
: DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema['Tables'] &
DefaultSchema['Views'])
? (DefaultSchema['Tables'] &
DefaultSchema['Views'])[DefaultSchemaTableNameOrOptions] extends {
Row: infer R;
}
? R
: never
: never;
export type TablesInsert<
DefaultSchemaTableNameOrOptions extends
| keyof DefaultSchema['Tables']
| { schema: keyof Database },
TableName extends DefaultSchemaTableNameOrOptions extends {
schema: keyof Database;
}
? keyof Database[DefaultSchemaTableNameOrOptions['schema']]['Tables']
: never = never,
> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database }
? Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'][TableName] extends {
Insert: infer I;
}
? I
: never
: DefaultSchemaTableNameOrOptions extends keyof DefaultSchema['Tables']
? DefaultSchema['Tables'][DefaultSchemaTableNameOrOptions] extends {
Insert: infer I;
}
? I
: never
: never;
export type TablesUpdate<
DefaultSchemaTableNameOrOptions extends
| keyof DefaultSchema['Tables']
| { schema: keyof Database },
TableName extends DefaultSchemaTableNameOrOptions extends {
schema: keyof Database;
}
? keyof Database[DefaultSchemaTableNameOrOptions['schema']]['Tables']
: never = never,
> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database }
? Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'][TableName] extends {
Update: infer U;
}
? U
: never
: DefaultSchemaTableNameOrOptions extends keyof DefaultSchema['Tables']
? DefaultSchema['Tables'][DefaultSchemaTableNameOrOptions] extends {
Update: infer U;
}
? U
: never
: never;
export type Enums<
DefaultSchemaEnumNameOrOptions extends
| keyof DefaultSchema['Enums']
| { schema: keyof Database },
EnumName extends DefaultSchemaEnumNameOrOptions extends {
schema: keyof Database;
}
? keyof Database[DefaultSchemaEnumNameOrOptions['schema']]['Enums']
: never = never,
> = DefaultSchemaEnumNameOrOptions extends { schema: keyof Database }
? Database[DefaultSchemaEnumNameOrOptions['schema']]['Enums'][EnumName]
: DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema['Enums']
? DefaultSchema['Enums'][DefaultSchemaEnumNameOrOptions]
: never;
export type CompositeTypes<
PublicCompositeTypeNameOrOptions extends
| keyof DefaultSchema['CompositeTypes']
| { schema: keyof Database },
CompositeTypeName extends PublicCompositeTypeNameOrOptions extends {
schema: keyof Database;
}
? keyof Database[PublicCompositeTypeNameOrOptions['schema']]['CompositeTypes']
: never = never,
> = PublicCompositeTypeNameOrOptions extends { schema: keyof Database }
? Database[PublicCompositeTypeNameOrOptions['schema']]['CompositeTypes'][CompositeTypeName]
: PublicCompositeTypeNameOrOptions extends keyof DefaultSchema['CompositeTypes']
? DefaultSchema['CompositeTypes'][PublicCompositeTypeNameOrOptions]
: never;
export const Constants = {
public: {
Enums: {},
},
} as const;

View File

@ -0,0 +1,25 @@
import type { Database } from '@/utils/supabase/types';
// Table row types
export type Profile = Database['public']['Tables']['profiles']['Row'];
export type Status = Database['public']['Tables']['statuses']['Row'];
// Insert types
export type ProfileInsert = Database['public']['Tables']['profiles']['Insert'];
export type StatusInsert = Database['public']['Tables']['statuses']['Insert'];
// Update types
export type ProfileUpdate = Database['public']['Tables']['profiles']['Update'];
export type StatusUpdate = Database['public']['Tables']['statuses']['Update'];
// Generic helper to get any table's row type
export type TableRow<T extends keyof Database['public']['Tables']> =
Database['public']['Tables'][T]['Row'];
// Generic helper to get any table's insert type
export type TableInsert<T extends keyof Database['public']['Tables']> =
Database['public']['Tables'][T]['Insert'];
// Generic helper to get any table's update type
export type TableUpdate<T extends keyof Database['public']['Tables']> =
Database['public']['Tables'][T]['Update'];

188
utils/supabase/types.ts Normal file
View File

@ -0,0 +1,188 @@
export type Json =
| string
| number
| boolean
| null
| { [key: string]: Json | undefined }
| Json[];
export type Database = {
public: {
Tables: {
profiles: {
Row: {
avatar_url: string | null;
email: string | null;
full_name: string | null;
id: string;
provider: string | null;
updated_at: string | null;
};
Insert: {
avatar_url?: string | null;
email?: string | null;
full_name?: string | null;
id: string;
provider?: string | null;
updated_at?: string | null;
};
Update: {
avatar_url?: string | null;
email?: string | null;
full_name?: string | null;
id?: string;
provider?: string | null;
updated_at?: string | null;
};
Relationships: [];
};
statuses: {
Row: {
created_at: string;
id: string;
status: string;
updated_by_id: string | null;
user_id: string;
};
Insert: {
created_at?: string;
id?: string;
status: string;
updated_by_id?: string | null;
user_id: string;
};
Update: {
created_at?: string;
id?: string;
status?: string;
updated_by_id?: string | null;
user_id?: string;
};
Relationships: [];
};
};
Views: {
[_ in never]: never;
};
Functions: {
[_ in never]: never;
};
Enums: {
[_ in never]: never;
};
CompositeTypes: {
[_ in never]: never;
};
};
};
type DefaultSchema = Database[Extract<keyof Database, 'public'>];
export type Tables<
DefaultSchemaTableNameOrOptions extends
| keyof (DefaultSchema['Tables'] & DefaultSchema['Views'])
| { schema: keyof Database },
TableName extends DefaultSchemaTableNameOrOptions extends {
schema: keyof Database;
}
? keyof (Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'] &
Database[DefaultSchemaTableNameOrOptions['schema']]['Views'])
: never = never,
> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database }
? (Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'] &
Database[DefaultSchemaTableNameOrOptions['schema']]['Views'])[TableName] extends {
Row: infer R;
}
? R
: never
: DefaultSchemaTableNameOrOptions extends keyof (DefaultSchema['Tables'] &
DefaultSchema['Views'])
? (DefaultSchema['Tables'] &
DefaultSchema['Views'])[DefaultSchemaTableNameOrOptions] extends {
Row: infer R;
}
? R
: never
: never;
export type TablesInsert<
DefaultSchemaTableNameOrOptions extends
| keyof DefaultSchema['Tables']
| { schema: keyof Database },
TableName extends DefaultSchemaTableNameOrOptions extends {
schema: keyof Database;
}
? keyof Database[DefaultSchemaTableNameOrOptions['schema']]['Tables']
: never = never,
> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database }
? Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'][TableName] extends {
Insert: infer I;
}
? I
: never
: DefaultSchemaTableNameOrOptions extends keyof DefaultSchema['Tables']
? DefaultSchema['Tables'][DefaultSchemaTableNameOrOptions] extends {
Insert: infer I;
}
? I
: never
: never;
export type TablesUpdate<
DefaultSchemaTableNameOrOptions extends
| keyof DefaultSchema['Tables']
| { schema: keyof Database },
TableName extends DefaultSchemaTableNameOrOptions extends {
schema: keyof Database;
}
? keyof Database[DefaultSchemaTableNameOrOptions['schema']]['Tables']
: never = never,
> = DefaultSchemaTableNameOrOptions extends { schema: keyof Database }
? Database[DefaultSchemaTableNameOrOptions['schema']]['Tables'][TableName] extends {
Update: infer U;
}
? U
: never
: DefaultSchemaTableNameOrOptions extends keyof DefaultSchema['Tables']
? DefaultSchema['Tables'][DefaultSchemaTableNameOrOptions] extends {
Update: infer U;
}
? U
: never
: never;
export type Enums<
DefaultSchemaEnumNameOrOptions extends
| keyof DefaultSchema['Enums']
| { schema: keyof Database },
EnumName extends DefaultSchemaEnumNameOrOptions extends {
schema: keyof Database;
}
? keyof Database[DefaultSchemaEnumNameOrOptions['schema']]['Enums']
: never = never,
> = DefaultSchemaEnumNameOrOptions extends { schema: keyof Database }
? Database[DefaultSchemaEnumNameOrOptions['schema']]['Enums'][EnumName]
: DefaultSchemaEnumNameOrOptions extends keyof DefaultSchema['Enums']
? DefaultSchema['Enums'][DefaultSchemaEnumNameOrOptions]
: never;
export type CompositeTypes<
PublicCompositeTypeNameOrOptions extends
| keyof DefaultSchema['CompositeTypes']
| { schema: keyof Database },
CompositeTypeName extends PublicCompositeTypeNameOrOptions extends {
schema: keyof Database;
}
? keyof Database[PublicCompositeTypeNameOrOptions['schema']]['CompositeTypes']
: never = never,
> = PublicCompositeTypeNameOrOptions extends { schema: keyof Database }
? Database[PublicCompositeTypeNameOrOptions['schema']]['CompositeTypes'][CompositeTypeName]
: PublicCompositeTypeNameOrOptions extends keyof DefaultSchema['CompositeTypes']
? DefaultSchema['CompositeTypes'][PublicCompositeTypeNameOrOptions]
: never;
export const Constants = {
public: {
Enums: {},
},
} as const;