Skip to content

Commit 85f3f34

Browse files
cleanup
1 parent 303b5e4 commit 85f3f34

File tree

11 files changed

+323
-308
lines changed

11 files changed

+323
-308
lines changed

packages/web/src/actions.ts

Lines changed: 122 additions & 181 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { giteaSchema } from "@sourcebot/schemas/v3/gitea.schema";
1313
import { gerritSchema } from "@sourcebot/schemas/v3/gerrit.schema";
1414
import { GithubConnectionConfig, GitlabConnectionConfig, GiteaConnectionConfig, GerritConnectionConfig, ConnectionConfig } from "@sourcebot/schemas/v3/connection.type";
1515
import { encrypt } from "@sourcebot/crypto"
16-
import { getConnection, getLinkedRepos } from "./data/connection";
16+
import { getConnection } from "./data/connection";
1717
import { ConnectionSyncStatus, Prisma, OrgRole, RepoIndexingStatus, StripeSubscriptionStatus } from "@sourcebot/db";
1818
import { headers } from "next/headers"
1919
import { getStripe } from "@/lib/stripe"
@@ -278,7 +278,7 @@ export const getConnections = async (domain: string, filter: { status?: Connecti
278278
connectionType: connection.connectionType,
279279
updatedAt: connection.updatedAt,
280280
syncedAt: connection.syncedAt ?? undefined,
281-
linkedRepos: connection.repos.map(( { repo }) => ({
281+
linkedRepos: connection.repos.map(({ repo }) => ({
282282
id: repo.id,
283283
name: repo.name,
284284
repoIndexingStatus: repo.repoIndexingStatus,
@@ -317,23 +317,6 @@ export const getConnectionInfo = async (connectionId: number, domain: string) =>
317317
})
318318
)
319319

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-
337320
export const getRepos = async (domain: string, filter: { status?: RepoIndexingStatus[], connectionId?: number } = {}) =>
338321
withAuth((session) =>
339322
withOrgMembership(session, domain, async ({ orgId }) => {
@@ -367,7 +350,6 @@ export const getRepos = async (domain: string, filter: { status?: RepoIndexingSt
367350
})
368351
);
369352

370-
371353
export const createConnection = async (name: string, type: string, connectionConfig: string, domain: string): Promise<{ id: number } | ServiceError> =>
372354
withAuth((session) =>
373355
withOrgMembership(session, domain, async ({ orgId }) => {
@@ -493,36 +475,6 @@ export const flagReposForIndex = async (repoIds: number[], domain: string) =>
493475
})
494476
);
495477

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-
526478
export const deleteConnection = async (connectionId: number, domain: string): Promise<{ success: boolean } | ServiceError> =>
527479
withAuth((session) =>
528480
withOrgMembership(session, domain, async ({ orgId }) => {
@@ -689,7 +641,6 @@ export const cancelInvite = async (inviteId: string, domain: string): Promise<{
689641
}, /* minRequiredRole = */ OrgRole.OWNER)
690642
);
691643

692-
693644
export const redeemInvite = async (inviteId: string): Promise<{ success: boolean } | ServiceError> =>
694645
withAuth(async (session) => {
695646
const invite = await prisma.invite.findUnique({
@@ -863,97 +814,6 @@ export const transferOwnership = async (newOwnerId: string, domain: string): Pro
863814
}, /* minRequiredRole = */ OrgRole.OWNER)
864815
);
865816

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-
957817
export const createOnboardingStripeCheckoutSession = async (domain: string) =>
958818
withAuth(async (session) =>
959819
withOrgMembership(session, domain, async ({ orgId }) => {
@@ -1106,8 +966,6 @@ export const createStripeCheckoutSession = async (domain: string) =>
1106966
})
1107967
)
1108968

1109-
1110-
1111969
export const getCustomerPortalSessionLink = async (domain: string): Promise<string | ServiceError> =>
1112970
withAuth((session) =>
1113971
withOrgMembership(session, domain, async ({ orgId }) => {
@@ -1139,32 +997,6 @@ export const fetchSubscription = (domain: string): Promise<Stripe.Subscription |
1139997
})
1140998
);
1141999

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-
11681000
export const getSubscriptionBillingEmail = async (domain: string): Promise<string | ServiceError> =>
11691001
withAuth(async (session) =>
11701002
withOrgMembership(session, domain, async ({ orgId }) => {
@@ -1211,16 +1043,6 @@ export const changeSubscriptionBillingEmail = async (domain: string, newEmail: s
12111043
}, /* minRequiredRole = */ OrgRole.OWNER)
12121044
);
12131045

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-
12241046
export const checkIfOrgDomainExists = async (domain: string): Promise<boolean | ServiceError> =>
12251047
withAuth(async () => {
12261048
const org = await prisma.org.findFirst({
@@ -1392,7 +1214,6 @@ export const getOrgMembers = async (domain: string) =>
13921214
})
13931215
);
13941216

1395-
13961217
export const getOrgInvites = async (domain: string) =>
13971218
withAuth(async (session) =>
13981219
withOrgMembership(session, domain, async ({ orgId }) => {
@@ -1409,3 +1230,123 @@ export const getOrgInvites = async (domain: string) =>
14091230
}));
14101231
})
14111232
);
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

Comments
 (0)