2024-06-24 18:16:55 -04:00
import { db } from "@/lib/db"
import { NextResponse } from "next/server" ;
import fetchUserWithImpersonation from "@/lib/fetch-user-impersonation" ;
import { ActionType , Prisma } from "@prisma/client" ;
2024-08-25 17:35:46 -04:00
import { z } from "zod" ;
2024-06-24 18:16:55 -04:00
export async function GET ( req : Request ) {
try {
const user = await fetchUserWithImpersonation ( req )
if ( ! user ) {
2024-08-25 17:35:46 -04:00
return NextResponse . json ( { message : 'Unauthorized.' , error : null , value : null } , { status : 401 } ) ;
2024-06-24 18:16:55 -04:00
}
const actions = await db . action . findMany ( {
where : {
userId : user.id
}
} )
2024-08-14 16:33:40 -04:00
return NextResponse . json ( actions . map ( ( { userId , . . . attrs } ) = > attrs ) ) ;
2024-08-25 17:35:46 -04:00
} catch ( error : any ) {
return NextResponse . json ( { message : null , error : error , value : null } , { status : 500 } ) ;
2024-06-24 18:16:55 -04:00
}
}
2024-08-25 17:35:46 -04:00
const nameSchema = z . string ( {
required_error : "Name is required." ,
invalid_type_error : "Name must be a string"
} ) . regex ( /^[\w\-\s]{1,32}$/ , "Name must contain only letters, numbers, spaces, dashes, and underscores." )
2024-08-14 16:33:40 -04:00
async function common ( req : Request , action : ( id : string , name : string , type : ActionType , data : any ) = > void ) {
2024-06-24 18:16:55 -04:00
try {
const user = await fetchUserWithImpersonation ( req )
if ( ! user ) {
2024-08-25 17:35:46 -04:00
return NextResponse . json ( { message : 'Unauthorized.' , error : null , value : null } , { status : 401 } ) ;
2024-06-24 18:16:55 -04:00
}
2024-08-14 16:33:40 -04:00
const { name , type , scene_name , scene_item_name , rotation , position_x , position_y , file_path , file_content , tts_voice , obs_visible , obs_index , sleep , oauth_name , oauth_type } :
{
name : string , type : ActionType , scene_name : string , scene_item_name : string , rotation : string , position_x : string , position_y : string , file_path : string , file_content : string , tts_voice : string , obs_visible : boolean , obs_index : number , sleep : number ,
oauth_name : string , oauth_type : string
} = await req . json ( ) ;
2024-08-25 17:35:46 -04:00
if ( ! name )
return NextResponse . json ( { message : 'name is required.' , error : null , value : null } , { status : 400 } ) ;
const nameValidation = nameSchema . safeParse ( name )
if ( ! nameValidation . success )
return NextResponse . json ( { message : 'name must follow some requirements.' , error : nameValidation.error , value : null } , { status : 400 } ) ;
if ( ! type )
return NextResponse . json ( { message : 'type is required' , error : null , value : null } , { status : 400 } ) ;
2024-06-24 18:16:55 -04:00
if ( type == ActionType . OBS_TRANSFORM && ( ! scene_name || ! scene_item_name || ! rotation && ! position_x && ! position_y ) )
2024-08-25 17:35:46 -04:00
return NextResponse . json ( { message : '"scene_name", "scene_item_name" and one of "rotation", "position_x", "position_y" are required.' , error : null , value : null } , { status : 400 } ) ;
2024-06-24 18:16:55 -04:00
if ( ( type == ActionType . WRITE_TO_FILE || type == ActionType . APPEND_TO_FILE ) && ( ! file_path || ! file_content ) )
2024-08-25 17:35:46 -04:00
return NextResponse . json ( { message : '"scene_name", "scene_item_name", "file_path" & "file_content" are required.' , error : null , value : null } , { status : 400 } ) ;
2024-06-24 18:16:55 -04:00
if ( type == ActionType . AUDIO_FILE && ! file_path )
2024-08-25 17:35:46 -04:00
return NextResponse . json ( { message : '"scene_name", "scene_item_name" & "file_path" are required.' , error : null , value : null } , { status : 400 } ) ;
2024-08-14 16:33:40 -04:00
if ( [ ActionType . OAUTH , ActionType . NIGHTBOT_PLAY , ActionType . NIGHTBOT_PAUSE , ActionType . NIGHTBOT_SKIP , ActionType . NIGHTBOT_CLEAR_PLAYLIST , ActionType . NIGHTBOT_CLEAR_QUEUE , ActionType . TWITCH_OAUTH ] . some ( t = > t == type ) && ( ! oauth_name || ! oauth_type ) )
2024-08-25 17:35:46 -04:00
return NextResponse . json ( { message : '"oauth_name" & "oauth_type" are required.' , error : null , value : null } , { status : 400 } ) ;
2024-06-24 18:16:55 -04:00
2024-08-14 16:33:40 -04:00
let data : any = { }
2024-06-24 18:16:55 -04:00
if ( type == ActionType . WRITE_TO_FILE || type == ActionType . APPEND_TO_FILE ) {
2024-08-14 16:33:40 -04:00
data = { file_path , file_content }
2024-06-24 18:16:55 -04:00
} else if ( type == ActionType . OBS_TRANSFORM ) {
2024-08-14 16:33:40 -04:00
data = { scene_name , scene_item_name }
2024-06-24 18:16:55 -04:00
if ( ! ! rotation )
data = { rotation , . . . data }
if ( ! ! position_x )
data = { position_x , . . . data }
if ( ! ! position_y )
data = { position_y , . . . data }
} else if ( type == ActionType . AUDIO_FILE ) {
2024-08-14 16:33:40 -04:00
data = { file_path }
} else if ( type == ActionType . SPECIFIC_TTS_VOICE ) {
data = { tts_voice }
} else if ( type == ActionType . TOGGLE_OBS_VISIBILITY ) {
data = { scene_name , scene_item_name }
} else if ( type == ActionType . SPECIFIC_OBS_VISIBILITY ) {
data = { scene_name , scene_item_name , obs_visible }
} else if ( type == ActionType . SPECIFIC_OBS_INDEX ) {
data = { scene_name , scene_item_name , obs_index }
} else if ( type == ActionType . SLEEP ) {
data = { sleep }
} else if ( [ ActionType . OAUTH , ActionType . NIGHTBOT_PLAY , ActionType . NIGHTBOT_PAUSE , ActionType . NIGHTBOT_SKIP , ActionType . NIGHTBOT_CLEAR_PLAYLIST , ActionType . NIGHTBOT_CLEAR_QUEUE , ActionType . TWITCH_OAUTH ] . some ( t = > t == type ) ) {
data = {
oauth_name ,
oauth_type
}
2024-06-24 18:16:55 -04:00
}
2024-08-14 16:33:40 -04:00
action ( user . id , name , type , data )
2024-08-25 17:35:46 -04:00
return NextResponse . json ( { message : null , error : null , value : null } , { status : 200 } ) ;
2024-08-14 16:33:40 -04:00
} catch ( error : any ) {
2024-08-25 17:35:46 -04:00
return NextResponse . json ( { message : null , error : error , value : null } , { status : 500 } ) ;
2024-08-14 16:33:40 -04:00
}
}
export async function POST ( req : Request ) {
return common ( req , async ( id , name , type , data ) = > {
2024-06-24 18:16:55 -04:00
await db . action . create ( {
data : {
2024-08-14 16:33:40 -04:00
userId : id ,
2024-06-24 18:16:55 -04:00
name ,
type ,
data : data as Prisma . JsonObject
}
} ) ;
2024-08-14 16:33:40 -04:00
} )
2024-06-24 18:16:55 -04:00
}
export async function PUT ( req : Request ) {
2024-08-14 16:33:40 -04:00
return common ( req , async ( id , name , type , data ) = > {
2024-06-24 18:16:55 -04:00
await db . action . update ( {
where : {
userId_name : {
2024-08-14 16:33:40 -04:00
userId : id ,
2024-06-24 18:16:55 -04:00
name
}
} ,
data : {
2024-08-14 16:33:40 -04:00
name ,
2024-06-24 18:16:55 -04:00
type ,
data : data as Prisma . JsonObject
}
2024-08-14 16:33:40 -04:00
} )
} )
2024-06-24 18:16:55 -04:00
}
export async function DELETE ( req : Request ) {
try {
const user = await fetchUserWithImpersonation ( req )
if ( ! user ) {
2024-08-25 17:35:46 -04:00
return NextResponse . json ( { message : 'Unauthorized.' , error : null , value : null } , { status : 401 } ) ;
2024-06-24 18:16:55 -04:00
}
const { searchParams } = new URL ( req . url )
const name = searchParams . get ( 'action_name' ) as string
const redemptions = await db . action . delete ( {
where : {
userId_name : {
userId : user.id ,
name
}
}
} )
return NextResponse . json ( redemptions ) ;
2024-08-25 17:35:46 -04:00
} catch ( error : any ) {
return NextResponse . json ( { message : null , error : error , value : null } , { status : 500 } ) ;
2024-06-24 18:16:55 -04:00
}
}