11import { type PrismaClient } from "@trigger.dev/database" ;
22import { prisma } from "~/db.server" ;
3- import { DeleteProjectService } from "~/services/deleteProject.server" ;
4- import { BranchTrackingConfigSchema , type BranchTrackingConfig } from "~/v3/github" ;
5- import { checkGitHubBranchExists } from "~/services/gitHub.server" ;
6- import { tryCatch } from "@trigger.dev/core/utils" ;
3+ import { BranchTrackingConfigSchema } from "~/v3/github" ;
74import { env } from "~/env.server" ;
85import { findProjectBySlug } from "~/models/project.server" ;
6+ import { err , fromPromise , ok , okAsync } from "neverthrow" ;
97
108export class ProjectSettingsPresenter {
119 #prismaClient: PrismaClient ;
@@ -14,101 +12,133 @@ export class ProjectSettingsPresenter {
1412 this . #prismaClient = prismaClient ;
1513 }
1614
17- async getProjectSettings ( organizationSlug : string , projectSlug : string , userId : string ) {
15+ getProjectSettings ( organizationSlug : string , projectSlug : string , userId : string ) {
1816 const githubAppEnabled = env . GITHUB_APP_ENABLED === "1" ;
1917
2018 if ( ! githubAppEnabled ) {
21- return {
19+ return okAsync ( {
2220 gitHubApp : {
2321 enabled : false ,
2422 connectedRepository : undefined ,
2523 installations : undefined ,
2624 } ,
27- } ;
25+ } ) ;
2826 }
2927
30- const project = await findProjectBySlug ( organizationSlug , projectSlug , userId ) ;
31- if ( ! project ) {
32- throw new Error ( "Project not found" ) ;
33- }
34- const connectedGithubRepository = await prisma . connectedGithubRepository . findFirst ( {
35- where : {
36- projectId : project . id ,
37- } ,
38- select : {
39- branchTracking : true ,
40- previewDeploymentsEnabled : true ,
41- createdAt : true ,
42- repository : {
28+ const getProject = ( ) =>
29+ fromPromise ( findProjectBySlug ( organizationSlug , projectSlug , userId ) , ( error ) => ( {
30+ type : "other" as const ,
31+ cause : error ,
32+ } ) ) . andThen ( ( project ) => {
33+ if ( ! project ) {
34+ return err ( { type : "project_not_found" as const } ) ;
35+ }
36+ return ok ( project ) ;
37+ } ) ;
38+
39+ const findConnectedGithubRepository = ( projectId : string ) =>
40+ fromPromise (
41+ this . #prismaClient. connectedGithubRepository . findFirst ( {
42+ where : {
43+ projectId,
44+ } ,
4345 select : {
44- id : true ,
45- name : true ,
46- fullName : true ,
47- htmlUrl : true ,
48- private : true ,
46+ branchTracking : true ,
47+ previewDeploymentsEnabled : true ,
48+ createdAt : true ,
49+ repository : {
50+ select : {
51+ id : true ,
52+ name : true ,
53+ fullName : true ,
54+ htmlUrl : true ,
55+ private : true ,
56+ } ,
57+ } ,
4958 } ,
50- } ,
51- } ,
52- } ) ;
59+ } ) ,
60+ ( error ) => ( {
61+ type : "other" as const ,
62+ cause : error ,
63+ } )
64+ ) . map ( ( connectedGithubRepository ) => {
65+ if ( ! connectedGithubRepository ) {
66+ return undefined ;
67+ }
5368
54- if ( connectedGithubRepository ) {
55- const branchTrackingOrFailure = BranchTrackingConfigSchema . safeParse (
56- connectedGithubRepository . branchTracking
57- ) ;
69+ const branchTrackingOrFailure = BranchTrackingConfigSchema . safeParse (
70+ connectedGithubRepository . branchTracking
71+ ) ;
72+ return {
73+ ...connectedGithubRepository ,
74+ branchTracking : branchTrackingOrFailure . success
75+ ? branchTrackingOrFailure . data
76+ : undefined ,
77+ } ;
78+ } ) ;
5879
59- return {
60- gitHubApp : {
61- enabled : true ,
62- connectedRepository : {
63- ...connectedGithubRepository ,
64- branchTracking : branchTrackingOrFailure . success
65- ? branchTrackingOrFailure . data
66- : undefined ,
80+ const listGithubAppInstallations = ( organizationId : string ) =>
81+ fromPromise (
82+ this . #prismaClient. githubAppInstallation . findMany ( {
83+ where : {
84+ organizationId,
85+ deletedAt : null ,
86+ suspendedAt : null ,
6787 } ,
68- // skip loading installations if there is a connected repository
69- // a project can have only a single connected repository
70- installations : undefined ,
71- } ,
72- } ;
73- }
74-
75- const githubAppInstallations = await prisma . githubAppInstallation . findMany ( {
76- where : {
77- organizationId : project . organizationId ,
78- deletedAt : null ,
79- suspendedAt : null ,
80- } ,
81- select : {
82- id : true ,
83- accountHandle : true ,
84- targetType : true ,
85- appInstallationId : true ,
86- repositories : {
8788 select : {
8889 id : true ,
89- name : true ,
90- fullName : true ,
91- htmlUrl : true ,
92- private : true ,
90+ accountHandle : true ,
91+ targetType : true ,
92+ appInstallationId : true ,
93+ repositories : {
94+ select : {
95+ id : true ,
96+ name : true ,
97+ fullName : true ,
98+ htmlUrl : true ,
99+ private : true ,
100+ } ,
101+ // Most installations will only have a couple of repos so loading them here should be fine.
102+ // However, there might be outlier organizations so it's best to expose the installation repos
103+ // via a resource endpoint and filter on user input.
104+ take : 200 ,
105+ } ,
93106 } ,
94- // Most installations will only have a couple of repos so loading them here should be fine.
95- // However, there might be outlier organizations so it's best to expose the installation repos
96- // via a resource endpoint and filter on user input.
97- take : 200 ,
98- } ,
99- } ,
100- take : 20 ,
101- orderBy : {
102- createdAt : "desc" ,
103- } ,
104- } ) ;
107+ take : 20 ,
108+ orderBy : {
109+ createdAt : "desc" ,
110+ } ,
111+ } ) ,
112+ ( error ) => ( {
113+ type : "other" as const ,
114+ cause : error ,
115+ } )
116+ ) ;
117+
118+ return getProject ( ) . andThen ( ( project ) =>
119+ findConnectedGithubRepository ( project . id ) . andThen ( ( connectedGithubRepository ) => {
120+ if ( connectedGithubRepository ) {
121+ return okAsync ( {
122+ gitHubApp : {
123+ enabled : true ,
124+ connectedRepository : connectedGithubRepository ,
125+ // skip loading installations if there is a connected repository
126+ // a project can have only a single connected repository
127+ installations : undefined ,
128+ } ,
129+ } ) ;
130+ }
105131
106- return {
107- gitHubApp : {
108- enabled : true ,
109- connectedRepository : undefined ,
110- installations : githubAppInstallations ,
111- } ,
112- } ;
132+ return listGithubAppInstallations ( project . organizationId ) . map ( ( githubAppInstallations ) => {
133+ return {
134+ gitHubApp : {
135+ enabled : true ,
136+ connectedRepository : undefined ,
137+ installations : githubAppInstallations ,
138+ } ,
139+ } ;
140+ } ) ;
141+ } )
142+ ) ;
113143 }
114144}
0 commit comments