mirror of
https://github.com/ershisan99/www.git
synced 2025-12-17 05:19:23 +00:00
add branches to releases
This commit is contained in:
@@ -17,7 +17,10 @@ export default async function ReleasesPage() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
await api.releases.getReleases.prefetch()
|
await Promise.all([
|
||||||
|
api.releases.getReleases.prefetch(),
|
||||||
|
api.branches.getBranches.prefetch(),
|
||||||
|
])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Suspense>
|
<Suspense>
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import {
|
|||||||
AlertDialogTitle,
|
AlertDialogTitle,
|
||||||
} from '@/components/ui/alert-dialog'
|
} from '@/components/ui/alert-dialog'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
|
||||||
import {
|
import {
|
||||||
Dialog,
|
Dialog,
|
||||||
DialogContent,
|
DialogContent,
|
||||||
@@ -80,8 +79,42 @@ export function ReleasesClient() {
|
|||||||
|
|
||||||
const [smodsVersions, setSmodsVersions] = useState<string[]>(['latest'])
|
const [smodsVersions, setSmodsVersions] = useState<string[]>(['latest'])
|
||||||
const [lovelyVersions, setLovelyVersions] = useState<string[]>(['latest'])
|
const [lovelyVersions, setLovelyVersions] = useState<string[]>(['latest'])
|
||||||
|
const [newBranch, setNewBranch] = useState<string>('')
|
||||||
|
|
||||||
|
// Fetch branches from the database
|
||||||
|
const [branches] = api.branches.getBranches.useSuspenseQuery()
|
||||||
|
console.log(branches)
|
||||||
|
// Add branch mutation
|
||||||
|
const addBranch = api.branches.addBranch.useMutation({
|
||||||
|
onSuccess: () => {
|
||||||
|
utils.branches.getBranches.invalidate()
|
||||||
|
toast.success('Branch added successfully')
|
||||||
|
setNewBranch('')
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(`Error adding branch: ${error.message}`)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Delete branch mutation
|
||||||
|
const deleteBranch = api.branches.deleteBranch.useMutation({
|
||||||
|
onSuccess: () => {
|
||||||
|
utils.branches.getBranches.invalidate()
|
||||||
|
toast.success('Branch deleted successfully')
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
toast.error(`Error deleting branch: ${error.message}`)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleAddBranch = () => {
|
||||||
|
if (newBranch && !branches.some((branch) => branch.name === newBranch)) {
|
||||||
|
addBranch.mutate({ name: newBranch })
|
||||||
|
}
|
||||||
|
}
|
||||||
const [editDialogOpen, setEditDialogOpen] = useState(false)
|
const [editDialogOpen, setEditDialogOpen] = useState(false)
|
||||||
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false)
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false)
|
||||||
|
const [branchManagementOpen, setBranchManagementOpen] = useState(false)
|
||||||
const [selectedRelease, setSelectedRelease] = useState<
|
const [selectedRelease, setSelectedRelease] = useState<
|
||||||
(typeof releases)[0] | null
|
(typeof releases)[0] | null
|
||||||
>(null)
|
>(null)
|
||||||
@@ -126,6 +159,7 @@ export function ReleasesClient() {
|
|||||||
url: '',
|
url: '',
|
||||||
smods_version: 'latest',
|
smods_version: 'latest',
|
||||||
lovely_version: 'latest',
|
lovely_version: 'latest',
|
||||||
|
branchId: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -138,6 +172,7 @@ export function ReleasesClient() {
|
|||||||
url: '',
|
url: '',
|
||||||
smods_version: 'latest',
|
smods_version: 'latest',
|
||||||
lovely_version: 'latest',
|
lovely_version: 'latest',
|
||||||
|
branchId: 1,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -151,6 +186,7 @@ export function ReleasesClient() {
|
|||||||
url: release.url,
|
url: release.url,
|
||||||
smods_version: release.smods_version || 'latest',
|
smods_version: release.smods_version || 'latest',
|
||||||
lovely_version: release.lovely_version || 'latest',
|
lovely_version: release.lovely_version || 'latest',
|
||||||
|
branchId: release.branchId,
|
||||||
})
|
})
|
||||||
setEditDialogOpen(true)
|
setEditDialogOpen(true)
|
||||||
}
|
}
|
||||||
@@ -170,6 +206,7 @@ export function ReleasesClient() {
|
|||||||
<TableHead>Version</TableHead>
|
<TableHead>Version</TableHead>
|
||||||
<TableHead>Description</TableHead>
|
<TableHead>Description</TableHead>
|
||||||
<TableHead>URL</TableHead>
|
<TableHead>URL</TableHead>
|
||||||
|
<TableHead>Branch</TableHead>
|
||||||
<TableHead>Steamodded Version</TableHead>
|
<TableHead>Steamodded Version</TableHead>
|
||||||
<TableHead>Lovely Injector Version</TableHead>
|
<TableHead>Lovely Injector Version</TableHead>
|
||||||
<TableHead className='text-right'>Actions</TableHead>
|
<TableHead className='text-right'>Actions</TableHead>
|
||||||
@@ -196,6 +233,7 @@ export function ReleasesClient() {
|
|||||||
<div className='truncate'>{release.url}</div>
|
<div className='truncate'>{release.url}</div>
|
||||||
</a>
|
</a>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell>{release.branchName || 'main'}</TableCell>
|
||||||
<TableCell>{release.smods_version || 'latest'}</TableCell>
|
<TableCell>{release.smods_version || 'latest'}</TableCell>
|
||||||
<TableCell>{release.lovely_version || 'latest'}</TableCell>
|
<TableCell>{release.lovely_version || 'latest'}</TableCell>
|
||||||
<TableCell className='space-x-2 text-right'>
|
<TableCell className='space-x-2 text-right'>
|
||||||
@@ -247,7 +285,7 @@ export function ReleasesClient() {
|
|||||||
<Label htmlFor='url'>URL</Label>
|
<Label htmlFor='url'>URL</Label>
|
||||||
<Input id='url' {...form.register('url')} />
|
<Input id='url' {...form.register('url')} />
|
||||||
</div>
|
</div>
|
||||||
<div className='grid grid-cols-2 gap-4'>
|
<div className='grid grid-cols-3 gap-4'>
|
||||||
<div className='grid grid-cols-1 gap-2'>
|
<div className='grid grid-cols-1 gap-2'>
|
||||||
<Label htmlFor='smods_version'>Steamodded Version</Label>
|
<Label htmlFor='smods_version'>Steamodded Version</Label>
|
||||||
<Select
|
<Select
|
||||||
@@ -288,6 +326,44 @@ export function ReleasesClient() {
|
|||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='grid grid-cols-1 gap-2'>
|
||||||
|
<Label htmlFor='branch'>Branch</Label>
|
||||||
|
<div className='flex gap-2'>
|
||||||
|
<Select
|
||||||
|
defaultValue={'1'}
|
||||||
|
onValueChange={(value) =>
|
||||||
|
form.setValue('branchId', Number(value))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<SelectTrigger id='branch'>
|
||||||
|
<SelectValue placeholder='Select branch' />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{branches.map((branch) => (
|
||||||
|
<SelectItem
|
||||||
|
key={branch.id}
|
||||||
|
value={branch.id.toString()}
|
||||||
|
>
|
||||||
|
{branch.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='grid grid-cols-1 gap-2'>
|
||||||
|
<div className='flex justify-between items-center'>
|
||||||
|
<Label htmlFor='branch-management'>Branch Management</Label>
|
||||||
|
<Button
|
||||||
|
type='button'
|
||||||
|
variant='outline'
|
||||||
|
size='sm'
|
||||||
|
onClick={() => setBranchManagementOpen(true)}
|
||||||
|
>
|
||||||
|
Manage Branches
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button type='submit' className='w-full'>
|
<Button type='submit' className='w-full'>
|
||||||
Add new release
|
Add new release
|
||||||
@@ -330,7 +406,7 @@ export function ReleasesClient() {
|
|||||||
<Label htmlFor='edit-url'>URL</Label>
|
<Label htmlFor='edit-url'>URL</Label>
|
||||||
<Input id='edit-url' {...editForm.register('url')} />
|
<Input id='edit-url' {...editForm.register('url')} />
|
||||||
</div>
|
</div>
|
||||||
<div className='grid grid-cols-2 gap-4'>
|
<div className='grid grid-cols-3 gap-4'>
|
||||||
<div className='grid grid-cols-1 gap-2'>
|
<div className='grid grid-cols-1 gap-2'>
|
||||||
<Label htmlFor='edit-smods_version'>Steamodded Version</Label>
|
<Label htmlFor='edit-smods_version'>Steamodded Version</Label>
|
||||||
<Select
|
<Select
|
||||||
@@ -373,6 +449,29 @@ export function ReleasesClient() {
|
|||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
<div className='grid grid-cols-1 gap-2'>
|
||||||
|
<Label htmlFor='edit-branch'>Branch</Label>
|
||||||
|
<Select
|
||||||
|
value={editForm.watch('branchId').toString()}
|
||||||
|
onValueChange={(value) =>
|
||||||
|
editForm.setValue('branchId', Number(value))
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<SelectTrigger id='edit-branch'>
|
||||||
|
<SelectValue placeholder='Select branch' />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
{branches.map((branch) => (
|
||||||
|
<SelectItem
|
||||||
|
key={branch.id}
|
||||||
|
value={branch.id.toString()}
|
||||||
|
>
|
||||||
|
{branch.name}
|
||||||
|
</SelectItem>
|
||||||
|
))}
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<DialogFooter>
|
<DialogFooter>
|
||||||
@@ -414,6 +513,80 @@ export function ReleasesClient() {
|
|||||||
</AlertDialogFooter>
|
</AlertDialogFooter>
|
||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
|
|
||||||
|
{/* Branch Management Modal */}
|
||||||
|
<Dialog open={branchManagementOpen} onOpenChange={setBranchManagementOpen}>
|
||||||
|
<DialogContent className='sm:max-w-[500px]'>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Manage Branches</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
Add new branches or remove existing ones.
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<div className='grid gap-4 py-4'>
|
||||||
|
<div className='grid grid-cols-1 gap-2'>
|
||||||
|
<Label htmlFor='modal-new-branch'>Add New Branch</Label>
|
||||||
|
<div className='flex gap-2'>
|
||||||
|
<Input
|
||||||
|
id='modal-new-branch'
|
||||||
|
value={newBranch}
|
||||||
|
onChange={(e) => setNewBranch(e.target.value)}
|
||||||
|
placeholder='Enter new branch name'
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
type='button'
|
||||||
|
onClick={handleAddBranch}
|
||||||
|
disabled={
|
||||||
|
!newBranch ||
|
||||||
|
branches.some((branch) => branch.name === newBranch)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Add
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className='grid grid-cols-1 gap-2'>
|
||||||
|
<Label>Existing Branches</Label>
|
||||||
|
<div className='max-h-60 overflow-y-auto rounded-md border p-2'>
|
||||||
|
{branches.length === 0 ? (
|
||||||
|
<p className='text-muted-foreground text-sm'>
|
||||||
|
No branches found
|
||||||
|
</p>
|
||||||
|
) : (
|
||||||
|
<ul className='space-y-1'>
|
||||||
|
{branches.map((branch) => (
|
||||||
|
<li
|
||||||
|
key={branch.id}
|
||||||
|
className='flex items-center justify-between rounded-md px-2 py-1 hover:bg-muted'
|
||||||
|
>
|
||||||
|
<span>{branch.name}</span>
|
||||||
|
{branch.name !== 'main' && (
|
||||||
|
<Button
|
||||||
|
variant='ghost'
|
||||||
|
size='sm'
|
||||||
|
className='h-7 w-7 p-0 text-destructive hover:bg-destructive/10 hover:text-destructive'
|
||||||
|
onClick={() =>
|
||||||
|
deleteBranch.mutate({ id: branch.id })
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Trash2 className='h-4 w-4' />
|
||||||
|
<span className='sr-only'>Delete branch</span>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<DialogFooter>
|
||||||
|
<Button type='button' onClick={() => setBranchManagementOpen(false)}>
|
||||||
|
Close
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,24 @@
|
|||||||
import { db } from '@/server/db'
|
import { db } from '@/server/db'
|
||||||
import { releases } from '@/server/db/schema'
|
import { branches, releases } from '@/server/db/schema'
|
||||||
|
import { eq } from 'drizzle-orm'
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const res = await db.select().from(releases)
|
const res = await db
|
||||||
|
.select({
|
||||||
|
id: releases.id,
|
||||||
|
name: releases.name,
|
||||||
|
description: releases.description,
|
||||||
|
version: releases.version,
|
||||||
|
url: releases.url,
|
||||||
|
smods_version: releases.smods_version,
|
||||||
|
lovely_version: releases.lovely_version,
|
||||||
|
branchId: releases.branchId,
|
||||||
|
branchName: branches.name,
|
||||||
|
createdAt: releases.createdAt,
|
||||||
|
updatedAt: releases.updatedAt,
|
||||||
|
})
|
||||||
|
.from(releases)
|
||||||
|
.leftJoin(branches, eq(releases.branchId, branches.id))
|
||||||
|
|
||||||
return Response.json(res)
|
return Response.json(res)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { branchesRouter } from '@/server/api/routers/branches'
|
||||||
import { discord_router } from '@/server/api/routers/discord'
|
import { discord_router } from '@/server/api/routers/discord'
|
||||||
import { history_router } from '@/server/api/routers/history'
|
import { history_router } from '@/server/api/routers/history'
|
||||||
import { leaderboard_router } from '@/server/api/routers/leaderboard'
|
import { leaderboard_router } from '@/server/api/routers/leaderboard'
|
||||||
@@ -11,6 +12,7 @@ import { createCallerFactory, createTRPCRouter } from '@/server/api/trpc'
|
|||||||
* All routers added in /api/routers should be manually added here.
|
* All routers added in /api/routers should be manually added here.
|
||||||
*/
|
*/
|
||||||
export const appRouter = createTRPCRouter({
|
export const appRouter = createTRPCRouter({
|
||||||
|
branches: branchesRouter,
|
||||||
history: history_router,
|
history: history_router,
|
||||||
discord: discord_router,
|
discord: discord_router,
|
||||||
leaderboard: leaderboard_router,
|
leaderboard: leaderboard_router,
|
||||||
|
|||||||
53
src/server/api/routers/branches.ts
Normal file
53
src/server/api/routers/branches.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import {
|
||||||
|
adminProcedure,
|
||||||
|
createTRPCRouter,
|
||||||
|
publicProcedure,
|
||||||
|
} from '@/server/api/trpc'
|
||||||
|
import { db } from '@/server/db'
|
||||||
|
import { branches } from '@/server/db/schema'
|
||||||
|
import { z } from 'zod'
|
||||||
|
import { eq } from 'drizzle-orm'
|
||||||
|
|
||||||
|
export const branchesRouter = createTRPCRouter({
|
||||||
|
getBranches: publicProcedure.query(async () => {
|
||||||
|
const res = await db.select().from(branches)
|
||||||
|
return res
|
||||||
|
}),
|
||||||
|
addBranch: adminProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
name: z.string(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
try {
|
||||||
|
const res = await db
|
||||||
|
.insert(branches)
|
||||||
|
.values({
|
||||||
|
name: input.name,
|
||||||
|
})
|
||||||
|
.returning()
|
||||||
|
|
||||||
|
return res[0]
|
||||||
|
} catch (error) {
|
||||||
|
// Handle unique constraint violation
|
||||||
|
if (error instanceof Error && error.message.includes('unique constraint')) {
|
||||||
|
throw new Error('Branch with this name already exists')
|
||||||
|
}
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
deleteBranch: adminProcedure
|
||||||
|
.input(
|
||||||
|
z.object({
|
||||||
|
id: z.number(),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.mutation(async ({ input }) => {
|
||||||
|
await db
|
||||||
|
.delete(branches)
|
||||||
|
.where(eq(branches.id, input.id))
|
||||||
|
|
||||||
|
return { success: true }
|
||||||
|
}),
|
||||||
|
})
|
||||||
@@ -4,13 +4,28 @@ import {
|
|||||||
publicProcedure,
|
publicProcedure,
|
||||||
} from '@/server/api/trpc'
|
} from '@/server/api/trpc'
|
||||||
import { db } from '@/server/db'
|
import { db } from '@/server/db'
|
||||||
import { releases } from '@/server/db/schema'
|
import { branches, releases } from '@/server/db/schema'
|
||||||
import { z } from 'zod'
|
|
||||||
import { eq } from 'drizzle-orm'
|
import { eq } from 'drizzle-orm'
|
||||||
|
import { z } from 'zod'
|
||||||
|
|
||||||
export const releasesRouter = createTRPCRouter({
|
export const releasesRouter = createTRPCRouter({
|
||||||
getReleases: publicProcedure.query(async () => {
|
getReleases: publicProcedure.query(async () => {
|
||||||
const res = await db.select().from(releases)
|
const res = await db
|
||||||
|
.select({
|
||||||
|
id: releases.id,
|
||||||
|
name: releases.name,
|
||||||
|
description: releases.description,
|
||||||
|
version: releases.version,
|
||||||
|
url: releases.url,
|
||||||
|
smods_version: releases.smods_version,
|
||||||
|
lovely_version: releases.lovely_version,
|
||||||
|
branchId: releases.branchId,
|
||||||
|
branchName: branches.name,
|
||||||
|
createdAt: releases.createdAt,
|
||||||
|
updatedAt: releases.updatedAt,
|
||||||
|
})
|
||||||
|
.from(releases)
|
||||||
|
.leftJoin(branches, eq(releases.branchId, branches.id))
|
||||||
return res
|
return res
|
||||||
}),
|
}),
|
||||||
addRelease: adminProcedure
|
addRelease: adminProcedure
|
||||||
@@ -22,6 +37,7 @@ export const releasesRouter = createTRPCRouter({
|
|||||||
description: z.string(),
|
description: z.string(),
|
||||||
smods_version: z.string().default('latest'),
|
smods_version: z.string().default('latest'),
|
||||||
lovely_version: z.string().default('latest'),
|
lovely_version: z.string().default('latest'),
|
||||||
|
branchId: z.number().default(1),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
@@ -34,6 +50,7 @@ export const releasesRouter = createTRPCRouter({
|
|||||||
description: input.description,
|
description: input.description,
|
||||||
smods_version: input.smods_version,
|
smods_version: input.smods_version,
|
||||||
lovely_version: input.lovely_version,
|
lovely_version: input.lovely_version,
|
||||||
|
branchId: input.branchId,
|
||||||
})
|
})
|
||||||
.returning()
|
.returning()
|
||||||
|
|
||||||
@@ -49,6 +66,7 @@ export const releasesRouter = createTRPCRouter({
|
|||||||
description: z.string(),
|
description: z.string(),
|
||||||
smods_version: z.string().default('latest'),
|
smods_version: z.string().default('latest'),
|
||||||
lovely_version: z.string().default('latest'),
|
lovely_version: z.string().default('latest'),
|
||||||
|
branchId: z.number().default(1),
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
@@ -61,6 +79,7 @@ export const releasesRouter = createTRPCRouter({
|
|||||||
description: input.description,
|
description: input.description,
|
||||||
smods_version: input.smods_version,
|
smods_version: input.smods_version,
|
||||||
lovely_version: input.lovely_version,
|
lovely_version: input.lovely_version,
|
||||||
|
branchId: input.branchId,
|
||||||
})
|
})
|
||||||
.where(eq(releases.id, input.id))
|
.where(eq(releases.id, input.id))
|
||||||
.returning()
|
.returning()
|
||||||
@@ -74,9 +93,7 @@ export const releasesRouter = createTRPCRouter({
|
|||||||
})
|
})
|
||||||
)
|
)
|
||||||
.mutation(async ({ input }) => {
|
.mutation(async ({ input }) => {
|
||||||
await db
|
await db.delete(releases).where(eq(releases.id, input.id))
|
||||||
.delete(releases)
|
|
||||||
.where(eq(releases.id, input.id))
|
|
||||||
|
|
||||||
return { success: true }
|
return { success: true }
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -125,6 +125,13 @@ export const verificationTokens = pgTable(
|
|||||||
(t) => [primaryKey({ columns: [t.identifier, t.token] })]
|
(t) => [primaryKey({ columns: [t.identifier, t.token] })]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export const branches = pgTable('mod_branches', {
|
||||||
|
id: integer('id').primaryKey().generatedByDefaultAsIdentity(),
|
||||||
|
name: text('name').notNull().unique(),
|
||||||
|
description: text('description'),
|
||||||
|
createdAt: timestamp('created_at').notNull().defaultNow(),
|
||||||
|
})
|
||||||
|
|
||||||
export const releases = pgTable('mod_release', {
|
export const releases = pgTable('mod_release', {
|
||||||
id: integer('id').primaryKey().generatedByDefaultAsIdentity(),
|
id: integer('id').primaryKey().generatedByDefaultAsIdentity(),
|
||||||
name: text('name').notNull(),
|
name: text('name').notNull(),
|
||||||
@@ -133,9 +140,24 @@ export const releases = pgTable('mod_release', {
|
|||||||
url: text('url').notNull(),
|
url: text('url').notNull(),
|
||||||
smods_version: text('smods_version').default('latest'),
|
smods_version: text('smods_version').default('latest'),
|
||||||
lovely_version: text('lovely_version').default('latest'),
|
lovely_version: text('lovely_version').default('latest'),
|
||||||
|
branchId: integer('branch_id')
|
||||||
|
.references(() => branches.id)
|
||||||
|
.notNull()
|
||||||
|
.default(1),
|
||||||
createdAt: timestamp('created_at').notNull().defaultNow(),
|
createdAt: timestamp('created_at').notNull().defaultNow(),
|
||||||
updatedAt: timestamp('updated_at')
|
updatedAt: timestamp('updated_at')
|
||||||
.notNull()
|
.notNull()
|
||||||
.defaultNow()
|
.defaultNow()
|
||||||
.$onUpdate(() => new Date()),
|
.$onUpdate(() => new Date()),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export const branchesRelations = relations(branches, ({ many }) => ({
|
||||||
|
releases: many(releases),
|
||||||
|
}))
|
||||||
|
|
||||||
|
export const releasesRelations = relations(releases, ({ one }) => ({
|
||||||
|
branch: one(branches, {
|
||||||
|
fields: [releases.branchId],
|
||||||
|
references: [branches.id],
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
|||||||
Reference in New Issue
Block a user