@@ -13,7 +13,7 @@ import { giteaSchema } from "@sourcebot/schemas/v3/gitea.schema";
13
13
import { gerritSchema } from "@sourcebot/schemas/v3/gerrit.schema" ;
14
14
import { GithubConnectionConfig , GitlabConnectionConfig , GiteaConnectionConfig , GerritConnectionConfig , ConnectionConfig } from "@sourcebot/schemas/v3/connection.type" ;
15
15
import { encrypt } from "@sourcebot/crypto"
16
- import { getConnection , getLinkedRepos } from "./data/connection" ;
16
+ import { getConnection } from "./data/connection" ;
17
17
import { ConnectionSyncStatus , Prisma , OrgRole , RepoIndexingStatus , StripeSubscriptionStatus } from "@sourcebot/db" ;
18
18
import { headers } from "next/headers"
19
19
import { getStripe } from "@/lib/stripe"
@@ -278,7 +278,7 @@ export const getConnections = async (domain: string, filter: { status?: Connecti
278
278
connectionType : connection . connectionType ,
279
279
updatedAt : connection . updatedAt ,
280
280
syncedAt : connection . syncedAt ?? undefined ,
281
- linkedRepos : connection . repos . map ( ( { repo } ) => ( {
281
+ linkedRepos : connection . repos . map ( ( { repo } ) => ( {
282
282
id : repo . id ,
283
283
name : repo . name ,
284
284
repoIndexingStatus : repo . repoIndexingStatus ,
@@ -317,23 +317,6 @@ export const getConnectionInfo = async (connectionId: number, domain: string) =>
317
317
} )
318
318
)
319
319
320
- export const getConnectionFailedRepos = async ( connectionId : number , domain : string ) : Promise < { repoId : number , repoName : string } [ ] | ServiceError > =>
321
- withAuth ( ( session ) =>
322
- withOrgMembership ( session , domain , async ( { orgId } ) => {
323
- const connection = await getConnection ( connectionId , orgId ) ;
324
- if ( ! connection ) {
325
- return notFound ( ) ;
326
- }
327
-
328
- const linkedRepos = await getLinkedRepos ( connectionId , orgId ) ;
329
-
330
- return linkedRepos . filter ( ( repo ) => repo . repo . repoIndexingStatus === RepoIndexingStatus . FAILED ) . map ( ( repo ) => ( {
331
- repoId : repo . repo . id ,
332
- repoName : repo . repo . name ,
333
- } ) ) ;
334
- } )
335
- ) ;
336
-
337
320
export const getRepos = async ( domain : string , filter : { status ?: RepoIndexingStatus [ ] , connectionId ?: number } = { } ) =>
338
321
withAuth ( ( session ) =>
339
322
withOrgMembership ( session , domain , async ( { orgId } ) => {
@@ -367,7 +350,6 @@ export const getRepos = async (domain: string, filter: { status?: RepoIndexingSt
367
350
} )
368
351
) ;
369
352
370
-
371
353
export const createConnection = async ( name : string , type : string , connectionConfig : string , domain : string ) : Promise < { id : number } | ServiceError > =>
372
354
withAuth ( ( session ) =>
373
355
withOrgMembership ( session , domain , async ( { orgId } ) => {
@@ -493,36 +475,6 @@ export const flagReposForIndex = async (repoIds: number[], domain: string) =>
493
475
} )
494
476
) ;
495
477
496
- export const flagRepoForIndex = async ( repoId : number , domain : string ) : Promise < { success : boolean } | ServiceError > =>
497
- withAuth ( ( session ) =>
498
- withOrgMembership ( session , domain , async ( ) => {
499
- const repo = await prisma . repo . findUnique ( {
500
- where : {
501
- id : repoId ,
502
- } ,
503
- } ) ;
504
-
505
- if ( ! repo ) {
506
- return notFound ( ) ;
507
- }
508
-
509
- await prisma . repo . update ( {
510
- where : {
511
- id : repoId ,
512
- } ,
513
- data : {
514
- repoIndexingStatus : RepoIndexingStatus . NEW ,
515
- }
516
- } ) ;
517
-
518
- return {
519
- success : true ,
520
- }
521
- } )
522
- ) ;
523
-
524
-
525
-
526
478
export const deleteConnection = async ( connectionId : number , domain : string ) : Promise < { success : boolean } | ServiceError > =>
527
479
withAuth ( ( session ) =>
528
480
withOrgMembership ( session , domain , async ( { orgId } ) => {
@@ -689,7 +641,6 @@ export const cancelInvite = async (inviteId: string, domain: string): Promise<{
689
641
} , /* minRequiredRole = */ OrgRole . OWNER )
690
642
) ;
691
643
692
-
693
644
export const redeemInvite = async ( inviteId : string ) : Promise < { success : boolean } | ServiceError > =>
694
645
withAuth ( async ( session ) => {
695
646
const invite = await prisma . invite . findUnique ( {
@@ -863,97 +814,6 @@ export const transferOwnership = async (newOwnerId: string, domain: string): Pro
863
814
} , /* minRequiredRole = */ OrgRole . OWNER )
864
815
) ;
865
816
866
- const parseConnectionConfig = ( connectionType : string , config : string ) => {
867
- let parsedConfig : ConnectionConfig ;
868
- try {
869
- parsedConfig = JSON . parse ( config ) ;
870
- } catch ( _e ) {
871
- return {
872
- statusCode : StatusCodes . BAD_REQUEST ,
873
- errorCode : ErrorCode . INVALID_REQUEST_BODY ,
874
- message : "config must be a valid JSON object."
875
- } satisfies ServiceError ;
876
- }
877
-
878
- const schema = ( ( ) => {
879
- switch ( connectionType ) {
880
- case "github" :
881
- return githubSchema ;
882
- case "gitlab" :
883
- return gitlabSchema ;
884
- case 'gitea' :
885
- return giteaSchema ;
886
- case 'gerrit' :
887
- return gerritSchema ;
888
- }
889
- } ) ( ) ;
890
-
891
- if ( ! schema ) {
892
- return {
893
- statusCode : StatusCodes . BAD_REQUEST ,
894
- errorCode : ErrorCode . INVALID_REQUEST_BODY ,
895
- message : "invalid connection type" ,
896
- } satisfies ServiceError ;
897
- }
898
-
899
- const { numRepos, hasToken } = ( ( ) => {
900
- switch ( connectionType ) {
901
- case "github" : {
902
- const githubConfig = parsedConfig as GithubConnectionConfig ;
903
- return {
904
- numRepos : githubConfig . repos ?. length ,
905
- hasToken : ! ! githubConfig . token ,
906
- }
907
- }
908
- case "gitlab" : {
909
- const gitlabConfig = parsedConfig as GitlabConnectionConfig ;
910
- return {
911
- numRepos : gitlabConfig . projects ?. length ,
912
- hasToken : ! ! gitlabConfig . token ,
913
- }
914
- }
915
- case "gitea" : {
916
- const giteaConfig = parsedConfig as GiteaConnectionConfig ;
917
- return {
918
- numRepos : giteaConfig . repos ?. length ,
919
- hasToken : ! ! giteaConfig . token ,
920
- }
921
- }
922
- case "gerrit" : {
923
- const gerritConfig = parsedConfig as GerritConnectionConfig ;
924
- return {
925
- numRepos : gerritConfig . projects ?. length ,
926
- hasToken : true , // gerrit doesn't use a token atm
927
- }
928
- }
929
- default :
930
- return {
931
- numRepos : undefined ,
932
- hasToken : true
933
- }
934
- }
935
- } ) ( ) ;
936
-
937
- if ( ! hasToken && numRepos && numRepos > CONFIG_MAX_REPOS_NO_TOKEN ) {
938
- return {
939
- statusCode : StatusCodes . BAD_REQUEST ,
940
- errorCode : ErrorCode . INVALID_REQUEST_BODY ,
941
- message : `You must provide a token to sync more than ${ CONFIG_MAX_REPOS_NO_TOKEN } repositories.` ,
942
- } satisfies ServiceError ;
943
- }
944
-
945
- const isValidConfig = ajv . validate ( schema , parsedConfig ) ;
946
- if ( ! isValidConfig ) {
947
- return {
948
- statusCode : StatusCodes . BAD_REQUEST ,
949
- errorCode : ErrorCode . INVALID_REQUEST_BODY ,
950
- message : `config schema validation failed with errors: ${ ajv . errorsText ( ajv . errors ) } ` ,
951
- } satisfies ServiceError ;
952
- }
953
-
954
- return parsedConfig ;
955
- }
956
-
957
817
export const createOnboardingStripeCheckoutSession = async ( domain : string ) =>
958
818
withAuth ( async ( session ) =>
959
819
withOrgMembership ( session , domain , async ( { orgId } ) => {
@@ -1106,8 +966,6 @@ export const createStripeCheckoutSession = async (domain: string) =>
1106
966
} )
1107
967
)
1108
968
1109
-
1110
-
1111
969
export const getCustomerPortalSessionLink = async ( domain : string ) : Promise < string | ServiceError > =>
1112
970
withAuth ( ( session ) =>
1113
971
withOrgMembership ( session , domain , async ( { orgId } ) => {
@@ -1139,32 +997,6 @@ export const fetchSubscription = (domain: string): Promise<Stripe.Subscription |
1139
997
} )
1140
998
) ;
1141
999
1142
- const _fetchSubscriptionForOrg = async ( orgId : number , prisma : Prisma . TransactionClient ) : Promise < Stripe . Subscription | null | ServiceError > => {
1143
- const org = await prisma . org . findUnique ( {
1144
- where : {
1145
- id : orgId ,
1146
- } ,
1147
- } ) ;
1148
-
1149
- if ( ! org ) {
1150
- return notFound ( ) ;
1151
- }
1152
-
1153
- if ( ! org . stripeCustomerId ) {
1154
- return null ;
1155
- }
1156
-
1157
- const stripe = getStripe ( ) ;
1158
- const subscriptions = await stripe . subscriptions . list ( {
1159
- customer : org . stripeCustomerId
1160
- } ) ;
1161
-
1162
- if ( subscriptions . data . length === 0 ) {
1163
- return orgInvalidSubscription ( ) ;
1164
- }
1165
- return subscriptions . data [ 0 ] ;
1166
- }
1167
-
1168
1000
export const getSubscriptionBillingEmail = async ( domain : string ) : Promise < string | ServiceError > =>
1169
1001
withAuth ( async ( session ) =>
1170
1002
withOrgMembership ( session , domain , async ( { orgId } ) => {
@@ -1211,16 +1043,6 @@ export const changeSubscriptionBillingEmail = async (domain: string, newEmail: s
1211
1043
} , /* minRequiredRole = */ OrgRole . OWNER )
1212
1044
) ;
1213
1045
1214
- export const checkIfUserHasOrg = async ( userId : string ) : Promise < boolean | ServiceError > => {
1215
- const orgs = await prisma . userToOrg . findMany ( {
1216
- where : {
1217
- userId,
1218
- } ,
1219
- } ) ;
1220
-
1221
- return orgs . length > 0 ;
1222
- }
1223
-
1224
1046
export const checkIfOrgDomainExists = async ( domain : string ) : Promise < boolean | ServiceError > =>
1225
1047
withAuth ( async ( ) => {
1226
1048
const org = await prisma . org . findFirst ( {
@@ -1392,7 +1214,6 @@ export const getOrgMembers = async (domain: string) =>
1392
1214
} )
1393
1215
) ;
1394
1216
1395
-
1396
1217
export const getOrgInvites = async ( domain : string ) =>
1397
1218
withAuth ( async ( session ) =>
1398
1219
withOrgMembership ( session , domain , async ( { orgId } ) => {
@@ -1409,3 +1230,123 @@ export const getOrgInvites = async (domain: string) =>
1409
1230
} ) ) ;
1410
1231
} )
1411
1232
) ;
1233
+
1234
+
1235
+ ////// Helpers ///////
1236
+
1237
+ const _fetchSubscriptionForOrg = async ( orgId : number , prisma : Prisma . TransactionClient ) : Promise < Stripe . Subscription | null | ServiceError > => {
1238
+ const org = await prisma . org . findUnique ( {
1239
+ where : {
1240
+ id : orgId ,
1241
+ } ,
1242
+ } ) ;
1243
+
1244
+ if ( ! org ) {
1245
+ return notFound ( ) ;
1246
+ }
1247
+
1248
+ if ( ! org . stripeCustomerId ) {
1249
+ return null ;
1250
+ }
1251
+
1252
+ const stripe = getStripe ( ) ;
1253
+ const subscriptions = await stripe . subscriptions . list ( {
1254
+ customer : org . stripeCustomerId
1255
+ } ) ;
1256
+
1257
+ if ( subscriptions . data . length === 0 ) {
1258
+ return orgInvalidSubscription ( ) ;
1259
+ }
1260
+ return subscriptions . data [ 0 ] ;
1261
+ }
1262
+
1263
+ const parseConnectionConfig = ( connectionType : string , config : string ) => {
1264
+ let parsedConfig : ConnectionConfig ;
1265
+ try {
1266
+ parsedConfig = JSON . parse ( config ) ;
1267
+ } catch ( _e ) {
1268
+ return {
1269
+ statusCode : StatusCodes . BAD_REQUEST ,
1270
+ errorCode : ErrorCode . INVALID_REQUEST_BODY ,
1271
+ message : "config must be a valid JSON object."
1272
+ } satisfies ServiceError ;
1273
+ }
1274
+
1275
+ const schema = ( ( ) => {
1276
+ switch ( connectionType ) {
1277
+ case "github" :
1278
+ return githubSchema ;
1279
+ case "gitlab" :
1280
+ return gitlabSchema ;
1281
+ case 'gitea' :
1282
+ return giteaSchema ;
1283
+ case 'gerrit' :
1284
+ return gerritSchema ;
1285
+ }
1286
+ } ) ( ) ;
1287
+
1288
+ if ( ! schema ) {
1289
+ return {
1290
+ statusCode : StatusCodes . BAD_REQUEST ,
1291
+ errorCode : ErrorCode . INVALID_REQUEST_BODY ,
1292
+ message : "invalid connection type" ,
1293
+ } satisfies ServiceError ;
1294
+ }
1295
+
1296
+ const { numRepos, hasToken } = ( ( ) => {
1297
+ switch ( connectionType ) {
1298
+ case "github" : {
1299
+ const githubConfig = parsedConfig as GithubConnectionConfig ;
1300
+ return {
1301
+ numRepos : githubConfig . repos ?. length ,
1302
+ hasToken : ! ! githubConfig . token ,
1303
+ }
1304
+ }
1305
+ case "gitlab" : {
1306
+ const gitlabConfig = parsedConfig as GitlabConnectionConfig ;
1307
+ return {
1308
+ numRepos : gitlabConfig . projects ?. length ,
1309
+ hasToken : ! ! gitlabConfig . token ,
1310
+ }
1311
+ }
1312
+ case "gitea" : {
1313
+ const giteaConfig = parsedConfig as GiteaConnectionConfig ;
1314
+ return {
1315
+ numRepos : giteaConfig . repos ?. length ,
1316
+ hasToken : ! ! giteaConfig . token ,
1317
+ }
1318
+ }
1319
+ case "gerrit" : {
1320
+ const gerritConfig = parsedConfig as GerritConnectionConfig ;
1321
+ return {
1322
+ numRepos : gerritConfig . projects ?. length ,
1323
+ hasToken : true , // gerrit doesn't use a token atm
1324
+ }
1325
+ }
1326
+ default :
1327
+ return {
1328
+ numRepos : undefined ,
1329
+ hasToken : true
1330
+ }
1331
+ }
1332
+ } ) ( ) ;
1333
+
1334
+ if ( ! hasToken && numRepos && numRepos > CONFIG_MAX_REPOS_NO_TOKEN ) {
1335
+ return {
1336
+ statusCode : StatusCodes . BAD_REQUEST ,
1337
+ errorCode : ErrorCode . INVALID_REQUEST_BODY ,
1338
+ message : `You must provide a token to sync more than ${ CONFIG_MAX_REPOS_NO_TOKEN } repositories.` ,
1339
+ } satisfies ServiceError ;
1340
+ }
1341
+
1342
+ const isValidConfig = ajv . validate ( schema , parsedConfig ) ;
1343
+ if ( ! isValidConfig ) {
1344
+ return {
1345
+ statusCode : StatusCodes . BAD_REQUEST ,
1346
+ errorCode : ErrorCode . INVALID_REQUEST_BODY ,
1347
+ message : `config schema validation failed with errors: ${ ajv . errorsText ( ajv . errors ) } ` ,
1348
+ } satisfies ServiceError ;
1349
+ }
1350
+
1351
+ return parsedConfig ;
1352
+ }
0 commit comments