2024-06-24 22:16:55 +00: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 21:35:46 +00:00
import { z } from "zod" ;
2025-01-07 15:52:47 +00:00
import { redirect } from "next/dist/server/api-utils" ;
2024-06-24 22:16:55 +00:00
export async function GET ( req : Request ) {
try {
const user = await fetchUserWithImpersonation ( req )
if ( ! user ) {
2024-08-25 21:35:46 +00:00
return NextResponse . json ( { message : 'Unauthorized.' , error : null , value : null } , { status : 401 } ) ;
2024-06-24 22:16:55 +00:00
}
const actions = await db . action . findMany ( {
where : {
userId : user.id
}
} )
2024-08-14 20:33:40 +00:00
return NextResponse . json ( actions . map ( ( { userId , . . . attrs } ) = > attrs ) ) ;
2024-08-25 21:35:46 +00:00
} catch ( error : any ) {
return NextResponse . json ( { message : null , error : error , value : null } , { status : 500 } ) ;
2024-06-24 22:16:55 +00:00
}
}
2024-08-25 21:35:46 +00: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." )
2025-01-07 15:52:47 +00:00
async function common ( req : Request , action : ( id : string , name : string , type : ActionType , values : any ) = > void ) {
2024-06-24 22:16:55 +00:00
try {
const user = await fetchUserWithImpersonation ( req )
if ( ! user ) {
2024-08-25 21:35:46 +00:00
return NextResponse . json ( { message : 'Unauthorized.' , error : null , value : null } , { status : 401 } ) ;
2024-06-24 22:16:55 +00:00
}
2025-01-07 15:52:47 +00:00
const { name , type , data } : { name : string , type : ActionType , data : any } = await req . json ( ) ;
2024-08-25 21:35:46 +00: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 } ) ;
2025-01-07 15:52:47 +00:00
if ( type == ActionType . OBS_TRANSFORM && ( ! data . scene_name || ! data . scene_item_name || ! data . rotation && ! data . position_x && ! data . position_y ) )
2024-08-25 21:35:46 +00: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 } ) ;
2025-01-07 15:52:47 +00:00
if ( ( type == ActionType . WRITE_TO_FILE || type == ActionType . APPEND_TO_FILE ) && ( ! data . file_path || ! data . file_content ) )
2024-08-25 21:35:46 +00:00
return NextResponse . json ( { message : '"scene_name", "scene_item_name", "file_path" & "file_content" are required.' , error : null , value : null } , { status : 400 } ) ;
2025-01-07 15:52:47 +00:00
if ( type == ActionType . AUDIO_FILE && ! data . file_path )
2024-08-25 21:35:46 +00:00
return NextResponse . json ( { message : '"scene_name", "scene_item_name" & "file_path" are required.' , error : null , value : null } , { status : 400 } ) ;
2025-01-07 15:52:47 +00: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 ) && ( ! data . oauth_name || ! data . oauth_type ) )
2024-08-25 21:35:46 +00:00
return NextResponse . json ( { message : '"oauth_name" & "oauth_type" are required.' , error : null , value : null } , { status : 400 } ) ;
2025-01-07 15:52:47 +00:00
if ( [ ActionType . VEADOTUBE_POP_STATE , ActionType . VEADOTUBE_PUSH_STATE , ActionType . VEADOTUBE_SET_STATE ] . some ( t = > t == type ) && ! data . state )
return NextResponse . json ( { message : '"state" is required.' , error : null , value : null } , { status : 400 } ) ;
2024-06-24 22:16:55 +00:00
2025-01-07 15:52:47 +00:00
let d : any = { }
2024-06-24 22:16:55 +00:00
if ( type == ActionType . WRITE_TO_FILE || type == ActionType . APPEND_TO_FILE ) {
2025-01-07 15:52:47 +00:00
d = { file_path : data.file_path , file_content : data.file_content }
2024-06-24 22:16:55 +00:00
} else if ( type == ActionType . OBS_TRANSFORM ) {
2025-01-07 15:52:47 +00:00
d = { scene_name : data.scene_name , scene_item_name : data.scene_item_name }
if ( ! ! data . rotation )
d = { rotation : data.rotation , . . . data }
if ( ! ! data . position_x )
d = { position_x : data.position_x , . . . data }
if ( ! ! data . position_y )
d = { position_y : data.position_y , . . . data }
2024-06-24 22:16:55 +00:00
} else if ( type == ActionType . AUDIO_FILE ) {
2025-01-07 15:52:47 +00:00
d = { file_path : data.file_path }
2024-08-14 20:33:40 +00:00
} else if ( type == ActionType . SPECIFIC_TTS_VOICE ) {
2025-01-07 15:52:47 +00:00
d = { tts_voice : data.tts_voice }
2024-08-14 20:33:40 +00:00
} else if ( type == ActionType . TOGGLE_OBS_VISIBILITY ) {
2025-01-07 15:52:47 +00:00
d = { scene_name : data.scene_name , scene_item_name : data.scene_item_name }
2024-08-14 20:33:40 +00:00
} else if ( type == ActionType . SPECIFIC_OBS_VISIBILITY ) {
2025-01-07 15:52:47 +00:00
d = { scene_name : data.scene_name , scene_item_name : data.scene_item_name , obs_visible : data.obs_visible }
2024-08-14 20:33:40 +00:00
} else if ( type == ActionType . SPECIFIC_OBS_INDEX ) {
2025-01-07 15:52:47 +00:00
d = { scene_name : data.scene_name , scene_item_name : data.scene_item_name , obs_index : data.obs_index }
2024-08-14 20:33:40 +00:00
} else if ( type == ActionType . SLEEP ) {
2025-01-07 15:52:47 +00:00
d = { sleep : data.sleep }
2024-08-14 20:33:40 +00:00
} 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 ) ) {
2025-01-07 15:52:47 +00:00
d = {
oauth_name : data.oauth_name ,
oauth_type : data.oauth_type
2024-08-14 20:33:40 +00:00
}
2025-01-07 15:52:47 +00:00
} else if ( [ ActionType . VEADOTUBE_POP_STATE , ActionType . VEADOTUBE_PUSH_STATE , ActionType . VEADOTUBE_SET_STATE ] . some ( t = > t == type ) ) {
d = { state : data.state }
2024-06-24 22:16:55 +00:00
}
2025-01-07 15:52:47 +00:00
const dd = action ( user . id , name , type , d )
return NextResponse . json ( { message : null , error : null , value : dd } , { status : 200 } ) ;
2024-08-14 20:33:40 +00:00
} catch ( error : any ) {
2024-08-25 21:35:46 +00:00
return NextResponse . json ( { message : null , error : error , value : null } , { status : 500 } ) ;
2024-08-14 20:33:40 +00:00
}
}
export async function POST ( req : Request ) {
return common ( req , async ( id , name , type , data ) = > {
2025-01-07 15:52:47 +00:00
return await db . action . create ( {
2024-06-24 22:16:55 +00:00
data : {
2024-08-14 20:33:40 +00:00
userId : id ,
2024-06-24 22:16:55 +00:00
name ,
type ,
data : data as Prisma . JsonObject
}
} ) ;
2024-08-14 20:33:40 +00:00
} )
2024-06-24 22:16:55 +00:00
}
export async function PUT ( req : Request ) {
2024-08-14 20:33:40 +00:00
return common ( req , async ( id , name , type , data ) = > {
2025-01-07 15:52:47 +00:00
return await db . action . update ( {
2024-06-24 22:16:55 +00:00
where : {
userId_name : {
2024-08-14 20:33:40 +00:00
userId : id ,
2024-06-24 22:16:55 +00:00
name
}
} ,
data : {
type ,
data : data as Prisma . JsonObject
}
2024-08-14 20:33:40 +00:00
} )
} )
2024-06-24 22:16:55 +00:00
}
export async function DELETE ( req : Request ) {
try {
const user = await fetchUserWithImpersonation ( req )
if ( ! user ) {
2024-08-25 21:35:46 +00:00
return NextResponse . json ( { message : 'Unauthorized.' , error : null , value : null } , { status : 401 } ) ;
2024-06-24 22:16:55 +00: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 21:35:46 +00:00
} catch ( error : any ) {
return NextResponse . json ( { message : null , error : error , value : null } , { status : 500 } ) ;
2024-06-24 22:16:55 +00:00
}
}