@@ -8,7 +8,11 @@ import { StatusCodes } from "http-status-codes";
88import { ErrorCode } from "@/lib/errorCodes" ;
99import { isServiceError } from "@/lib/utils" ;
1010import { githubSchema } from "@sourcebot/schemas/v3/github.schema" ;
11+ import { gitlabSchema } from "@sourcebot/schemas/v3/gitlab.schema" ;
12+ import { ConnectionConfig } from "@sourcebot/schemas/v3/connection.type" ;
1113import { encrypt } from "@sourcebot/crypto"
14+ import { getConnection } from "./data/connection" ;
15+ import { Prisma } from "@sourcebot/db" ;
1216
1317const ajv = new Ajv ( {
1418 validateFormats : false ,
@@ -141,25 +145,152 @@ export const switchActiveOrg = async (orgId: number): Promise<{ id: number } | S
141145 }
142146}
143147
144- export const createConnection = async ( config : string ) : Promise < { id : number } | ServiceError > => {
148+ export const createConnection = async ( name : string , type : string , connectionConfig : string ) : Promise < { id : number } | ServiceError > => {
145149 const orgId = await getCurrentUserOrg ( ) ;
146150 if ( isServiceError ( orgId ) ) {
147151 return orgId ;
148152 }
149153
150- let parsedConfig ;
154+ const parsedConfig = parseConnectionConfig ( type , connectionConfig ) ;
155+ if ( isServiceError ( parsedConfig ) ) {
156+ return parsedConfig ;
157+ }
158+
159+ const connection = await prisma . connection . create ( {
160+ data : {
161+ orgId,
162+ name,
163+ config : parsedConfig as unknown as Prisma . InputJsonValue ,
164+ connectionType : type ,
165+ }
166+ } ) ;
167+
168+ return {
169+ id : connection . id ,
170+ }
171+ }
172+
173+ export const updateConnectionDisplayName = async ( connectionId : number , name : string ) : Promise < { success : boolean } | ServiceError > => {
174+ const orgId = await getCurrentUserOrg ( ) ;
175+ if ( isServiceError ( orgId ) ) {
176+ return orgId ;
177+ }
178+
179+ const connection = await getConnection ( connectionId , orgId ) ;
180+ if ( ! connection ) {
181+ return notFound ( ) ;
182+ }
183+
184+ await prisma . connection . update ( {
185+ where : {
186+ id : connectionId ,
187+ orgId,
188+ } ,
189+ data : {
190+ name,
191+ }
192+ } ) ;
193+
194+ return {
195+ success : true ,
196+ }
197+ }
198+
199+ export const updateConnectionConfigAndScheduleSync = async ( connectionId : number , config : string ) : Promise < { success : boolean } | ServiceError > => {
200+ const orgId = await getCurrentUserOrg ( ) ;
201+ if ( isServiceError ( orgId ) ) {
202+ return orgId ;
203+ }
204+
205+ const connection = await getConnection ( connectionId , orgId ) ;
206+ if ( ! connection ) {
207+ return notFound ( ) ;
208+ }
209+
210+ const parsedConfig = parseConnectionConfig ( connection . connectionType , config ) ;
211+ if ( isServiceError ( parsedConfig ) ) {
212+ return parsedConfig ;
213+ }
214+
215+ if ( connection . syncStatus === "SYNC_NEEDED" ||
216+ connection . syncStatus === "IN_SYNC_QUEUE" ||
217+ connection . syncStatus === "SYNCING" ) {
218+ return {
219+ statusCode : StatusCodes . BAD_REQUEST ,
220+ errorCode : ErrorCode . CONNECTION_SYNC_ALREADY_SCHEDULED ,
221+ message : "Connection is already syncing. Please wait for the sync to complete before updating the connection." ,
222+ } satisfies ServiceError ;
223+ }
224+
225+ await prisma . connection . update ( {
226+ where : {
227+ id : connectionId ,
228+ orgId,
229+ } ,
230+ data : {
231+ config : parsedConfig as unknown as Prisma . InputJsonValue ,
232+ syncStatus : "SYNC_NEEDED" ,
233+ }
234+ } ) ;
235+
236+ return {
237+ success : true ,
238+ }
239+ }
240+
241+ export const deleteConnection = async ( connectionId : number ) : Promise < { success : boolean } | ServiceError > => {
242+ const orgId = await getCurrentUserOrg ( ) ;
243+ if ( isServiceError ( orgId ) ) {
244+ return orgId ;
245+ }
246+
247+ const connection = await getConnection ( connectionId , orgId ) ;
248+ if ( ! connection ) {
249+ return notFound ( ) ;
250+ }
251+
252+ await prisma . connection . delete ( {
253+ where : {
254+ id : connectionId ,
255+ orgId,
256+ }
257+ } ) ;
258+
259+ return {
260+ success : true ,
261+ }
262+ }
263+
264+ const parseConnectionConfig = ( connectionType : string , config : string ) => {
265+ let parsedConfig : ConnectionConfig ;
151266 try {
152267 parsedConfig = JSON . parse ( config ) ;
153- } catch {
268+ } catch ( _e ) {
154269 return {
155270 statusCode : StatusCodes . BAD_REQUEST ,
156271 errorCode : ErrorCode . INVALID_REQUEST_BODY ,
157272 message : "config must be a valid JSON object."
158273 } satisfies ServiceError ;
159274 }
160275
161- // @todo : we will need to validate the config against different schemas based on the type of connection.
162- const isValidConfig = ajv . validate ( githubSchema , parsedConfig ) ;
276+ const schema = ( ( ) => {
277+ switch ( connectionType ) {
278+ case "github" :
279+ return githubSchema ;
280+ case "gitlab" :
281+ return gitlabSchema ;
282+ }
283+ } ) ( ) ;
284+
285+ if ( ! schema ) {
286+ return {
287+ statusCode : StatusCodes . BAD_REQUEST ,
288+ errorCode : ErrorCode . INVALID_REQUEST_BODY ,
289+ message : "invalid connection type" ,
290+ } satisfies ServiceError ;
291+ }
292+
293+ const isValidConfig = ajv . validate ( schema , parsedConfig ) ;
163294 if ( ! isValidConfig ) {
164295 return {
165296 statusCode : StatusCodes . BAD_REQUEST ,
@@ -168,14 +299,5 @@ export const createConnection = async (config: string): Promise<{ id: number } |
168299 } satisfies ServiceError ;
169300 }
170301
171- const connection = await prisma . connection . create ( {
172- data : {
173- orgId : orgId ,
174- config : parsedConfig ,
175- }
176- } ) ;
177-
178- return {
179- id : connection . id ,
180- }
302+ return parsedConfig ;
181303}
0 commit comments