From e19677484184d8cf397d6b5edd0739ac60c5ddf2 Mon Sep 17 00:00:00 2001 From: Armando Belardo <11140328+armandobelardo@users.noreply.github.com> Date: Tue, 17 Sep 2024 13:41:49 -0400 Subject: [PATCH] feat(fern-bot): begin tracking pull requests as well (#1452) --- fern/apis/fdr/definition/git.yml | 246 ++++++++ .../fdr-sdk/src/client/generated/Client.ts | 7 + .../api/resources/git/client/Client.ts | 525 ++++++++++++++++++ .../resources/git/client/deletePullRequest.ts | 38 ++ .../resources/git/client/deleteRepository.ts | 38 ++ .../resources/git/client/getPullRequest.ts | 38 ++ .../api/resources/git/client/getRepository.ts | 38 ++ .../api/resources/git/client/index.ts | 9 + .../resources/git/client/listPullRequests.ts | 38 ++ .../resources/git/client/listRepositories.ts | 38 ++ .../requests/ListPullRequestsRequest.ts | 38 ++ .../requests/ListRepositoriesRequest.ts | 38 ++ .../resources/git/client/requests/index.ts | 2 + .../resources/git/client/upsertPullRequest.ts | 38 ++ .../resources/git/client/upsertRepository.ts | 38 ++ .../generated/api/resources/git/index.ts | 2 + .../api/resources/git/types/BaseRepository.ts | 18 + .../api/resources/git/types/CheckRun.ts | 17 + .../git/types/FernConfigRepository.ts | 7 + .../api/resources/git/types/FernRepository.ts | 17 + .../resources/git/types/GithubRepositoryId.ts | 7 + .../api/resources/git/types/GithubTeam.ts | 8 + .../api/resources/git/types/GithubUser.ts | 9 + .../git/types/ListPullRequestsResponse.ts | 9 + .../git/types/ListRepositoriesResponse.ts | 9 + .../api/resources/git/types/PullRequest.ts | 21 + .../git/types/PullRequestNotFound.ts | 9 + .../git/types/PullRequestReviewer.ts | 17 + .../resources/git/types/PullRequestState.ts | 11 + .../api/resources/git/types/RepositoryId.ts | 13 + .../resources/git/types/RepositoryNotFound.ts | 8 + .../api/resources/git/types/SdkRepository.ts | 9 + .../api/resources/git/types/index.ts | 16 + .../client/generated/api/resources/index.ts | 3 + .../migration.sql | 52 ++ servers/fdr/prisma/schema.prisma | 61 +- .../fdr/src/__test__/local/db/gitDao.test.ts | 110 ++++ .../fdr/src/__test__/local/setupMockFdr.ts | 2 + .../git/errors/PullRequestNotFoundError.d.ts | 11 + .../git/errors/PullRequestNotFoundError.js | 25 + .../git/errors/RepositoryNotFoundError.d.ts | 11 + .../git/errors/RepositoryNotFoundError.js | 25 + .../api/resources/git/errors/index.d.ts | 2 + .../api/resources/git/errors/index.js | 2 + .../generated/api/resources/git/index.d.ts | 3 + .../api/generated/api/resources/git/index.js | 3 + .../api/resources/git/service/GitService.d.ts | 83 +++ .../api/resources/git/service/GitService.js | 224 ++++++++ .../api/resources/git/service/index.d.ts | 1 + .../api/resources/git/service/index.js | 1 + .../resources/git/types/BaseRepository.d.ts | 16 + .../api/resources/git/types/BaseRepository.js | 4 + .../api/resources/git/types/CheckRun.d.ts | 16 + .../api/resources/git/types/CheckRun.js | 4 + .../git/types/FernConfigRepository.d.ts | 6 + .../git/types/FernConfigRepository.js | 4 + .../resources/git/types/FernRepository.d.ts | 13 + .../api/resources/git/types/FernRepository.js | 4 + .../git/types/GithubRepositoryId.d.ts | 6 + .../resources/git/types/GithubRepositoryId.js | 4 + .../api/resources/git/types/GithubTeam.d.ts | 7 + .../api/resources/git/types/GithubTeam.js | 4 + .../api/resources/git/types/GithubUser.d.ts | 8 + .../api/resources/git/types/GithubUser.js | 4 + .../git/types/ListPullRequestsResponse.d.ts | 7 + .../git/types/ListPullRequestsResponse.js | 4 + .../git/types/ListRepositoriesResponse.d.ts | 7 + .../git/types/ListRepositoriesResponse.js | 4 + .../api/resources/git/types/PullRequest.d.ts | 19 + .../api/resources/git/types/PullRequest.js | 4 + .../git/types/PullRequestNotFound.d.ts | 7 + .../git/types/PullRequestNotFound.js | 4 + .../git/types/PullRequestReviewer.d.ts | 13 + .../git/types/PullRequestReviewer.js | 4 + .../resources/git/types/PullRequestState.d.ts | 9 + .../resources/git/types/PullRequestState.js | 8 + .../api/resources/git/types/RepositoryId.d.ts | 10 + .../api/resources/git/types/RepositoryId.js | 4 + .../git/types/RepositoryNotFound.d.ts | 7 + .../resources/git/types/RepositoryNotFound.js | 4 + .../resources/git/types/SdkRepository.d.ts | 7 + .../api/resources/git/types/SdkRepository.js | 4 + .../api/resources/git/types/index.d.ts | 16 + .../api/resources/git/types/index.js | 16 + .../api/generated/api/resources/index.d.ts | 3 + .../src/api/generated/api/resources/index.js | 3 + servers/fdr/src/api/generated/register.d.ts | 2 + servers/fdr/src/api/generated/register.js | 1 + .../src/controllers/git/getGitController.ts | 97 ++++ servers/fdr/src/db/FdrDao.ts | 7 + servers/fdr/src/db/git/GitDao.ts | 335 +++++++++++ servers/fdr/src/server.ts | 2 + 92 files changed, 2702 insertions(+), 1 deletion(-) create mode 100644 fern/apis/fdr/definition/git.yml create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/Client.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/deletePullRequest.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/deleteRepository.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/getPullRequest.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/getRepository.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/index.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/listPullRequests.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/listRepositories.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/ListPullRequestsRequest.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/ListRepositoriesRequest.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/index.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/upsertPullRequest.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/client/upsertRepository.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/index.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/BaseRepository.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/CheckRun.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/FernConfigRepository.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/FernRepository.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubRepositoryId.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubTeam.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubUser.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/ListPullRequestsResponse.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/ListRepositoriesResponse.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequest.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestNotFound.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestReviewer.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestState.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/RepositoryId.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/RepositoryNotFound.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/SdkRepository.ts create mode 100644 packages/fdr-sdk/src/client/generated/api/resources/git/types/index.ts create mode 100644 servers/fdr/prisma/migrations/20240916140019_add_git_repo_and_pr/migration.sql create mode 100644 servers/fdr/src/__test__/local/db/gitDao.test.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/errors/PullRequestNotFoundError.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/errors/PullRequestNotFoundError.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/errors/RepositoryNotFoundError.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/errors/RepositoryNotFoundError.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/errors/index.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/errors/index.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/index.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/index.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/service/GitService.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/service/GitService.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/service/index.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/service/index.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/BaseRepository.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/BaseRepository.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/CheckRun.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/CheckRun.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/FernConfigRepository.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/FernConfigRepository.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/FernRepository.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/FernRepository.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/GithubRepositoryId.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/GithubRepositoryId.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/GithubTeam.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/GithubTeam.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/GithubUser.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/GithubUser.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/ListPullRequestsResponse.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/ListPullRequestsResponse.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/ListRepositoriesResponse.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/ListRepositoriesResponse.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/PullRequest.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/PullRequest.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/PullRequestNotFound.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/PullRequestNotFound.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/PullRequestReviewer.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/PullRequestReviewer.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/PullRequestState.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/PullRequestState.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/RepositoryId.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/RepositoryId.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/RepositoryNotFound.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/RepositoryNotFound.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/SdkRepository.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/SdkRepository.js create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/index.d.ts create mode 100644 servers/fdr/src/api/generated/api/resources/git/types/index.js create mode 100644 servers/fdr/src/controllers/git/getGitController.ts create mode 100644 servers/fdr/src/db/git/GitDao.ts diff --git a/fern/apis/fdr/definition/git.yml b/fern/apis/fdr/definition/git.yml new file mode 100644 index 0000000000..a5497dbaf9 --- /dev/null +++ b/fern/apis/fdr/definition/git.yml @@ -0,0 +1,246 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/fern-api/fern/main/fern.schema.json + +docs: Produces an internal schema to easily track and view pull requests across Fern-managed repositories. This API is named `git` to allow for flexibility in adding other git providers down the line (e.g. gitlab). + +imports: + commons: ./commons.yml + +types: + # Soon to add to our data model: + # - Orgs (internal) + # - Products (internal) + # - Features (internal) + # - Checks (internal, within their own table) + + CheckRun: + properties: + checkId: string + + repositoryOwner: string + repositoryName: string + ref: string + + name: string + status: string + conclusion: string + checkRunUrl: string + createdAt: datetime + completedAt: optional + + rawCheckRun: unknown + + GithubRepositoryId: + properties: + id: string + + RepositoryId: + union: + github: GithubRepositoryId + + BaseRepository: + properties: + id: RepositoryId + name: string + owner: + type: string + docs: The organization name within Github, e.g. fern-api. + fullName: + type: string + docs: The full name of the repository, e.g. fern-api/fern. It includes the owner, as well as the name of the repository. + url: string + repositoryOwnerOrganizationId: + type: commons.OrgId + docs: The Fern organization ID of the repository owner. + defaultBranchChecks: list + + # TODO: We may want to add the concept consumer repos, e.g. customers of customers, people actually using the SDKs. + SdkRepository: + extends: BaseRepository + properties: + sdkLanguage: string + + FernConfigRepository: + extends: BaseRepository + + FernRepository: + union: + sdk: SdkRepository + config: FernConfigRepository + + GithubUser: + properties: + name: string + email: string + username: string + + GithubTeam: + properties: + name: string + teamId: string + + PullRequestReviewer: + union: + user: GithubUser + team: GithubTeam + + PullRequestState: + enum: + - open + - closed + # Technically Github's API only returns open or closed, and merged_at indicates the merge, but we'll add it here for querying convenience. + - merged + + PullRequest: + properties: + pullRequestNumber: integer + repositoryName: string + repositoryOwner: string + author: GithubUser + reviewers: list + title: string + url: string + checks: list + state: PullRequestState + createdAt: datetime + updatedAt: optional + mergedAt: optional + closedAt: optional + + ListRepositoriesResponse: + properties: + repositories: list + + ListPullRequestsResponse: + properties: + pullRequests: list + + RepositoryNotFound: + properties: + repositoryName: string + repositoryOwner: string + + PullRequestNotFound: + extends: RepositoryNotFound + properties: + pullRequestNumber: integer + +service: + audiences: + - generators + base-path: /generators/github + auth: true + endpoints: + getRepository: + docs: Get a repository by its name (mirroring the Github API, this is the main get request). + method: GET + path: /repository/{repositoryOwner}/{repositoryName} + path-parameters: + repositoryOwner: string + repositoryName: string + response: FernRepository + + listRepositories: + docs: Get all repositories. + method: GET + path: "/repository" + pagination: + offset: $request.page + results: $response.repositories + request: + name: ListRepositoriesRequest + query-parameters: + page: + type: optional + docs: The page number to retrieve. Defaults to 0. + pageSize: + type: optional + docs: The number of items to retrieve per page. Defaults to 20. + organizationId: + type: optional + docs: The Fern organization ID to filter repositories by. + repositoryName: + type: optional + docs: | + The name of the repository to filter pull requests by (ex: full-platform). + repositoryOwner: + type: optional + docs: | + The organization name of the repository owner to filter pull requests by (ex: fern-api). + response: ListRepositoriesResponse + + upsertRepository: + docs: Update or create the specified repository. + method: PUT + path: /repository + request: FernRepository + + deleteRepository: + docs: Delete specified repository. + method: DELETE + path: /repository/{repositoryOwner}/{repositoryName} + path-parameters: + repositoryOwner: string + repositoryName: string + + getPullRequest: + docs: Get a pull request by its ID. + method: GET + path: /pull-request/{repositoryOwner}/{repositoryName}/{pullRequestNumber} + path-parameters: + repositoryOwner: string + repositoryName: string + pullRequestNumber: integer + response: PullRequest + + listPullRequests: + docs: Get all pull requests. + method: GET + path: "/pull-request" + pagination: + offset: $request.page + results: $response.pullRequests + request: + name: ListPullRequestsRequest + query-parameters: + page: + type: optional + docs: The page number to retrieve. Defaults to 0. + pageSize: + type: optional + docs: The number of items to retrieve per page. Defaults to 20. + repositoryName: + type: optional + docs: | + The name of the repository to filter pull requests by (ex: full-platform). + repositoryOwner: + type: optional + docs: | + The organization name of the repository owner to filter pull requests by (ex: fern-api). + organizationId: + type: optional + docs: The Fern organization ID to filter repositories by. + response: ListPullRequestsResponse + + upsertPullRequest: + docs: Update or create the specified pull request. + method: PUT + path: /pull-request + request: PullRequest + + deletePullRequest: + docs: Delete specified pull request. + method: DELETE + path: /pull-request/{repositoryOwner}/{repositoryName}/{pullRequestNumber} + path-parameters: + repositoryOwner: string + repositoryName: string + pullRequestNumber: integer + +errors: + PullRequestNotFoundError: + status-code: 404 + type: PullRequestNotFound + + RepositoryNotFoundError: + status-code: 404 + type: RepositoryNotFound diff --git a/packages/fdr-sdk/src/client/generated/Client.ts b/packages/fdr-sdk/src/client/generated/Client.ts index 39d6fa3281..96770d7be3 100644 --- a/packages/fdr-sdk/src/client/generated/Client.ts +++ b/packages/fdr-sdk/src/client/generated/Client.ts @@ -9,6 +9,7 @@ import { Docs } from "./api/resources/docs/client/Client"; import { Generators } from "./api/resources/generators/client/Client"; import { Diff } from "./api/resources/diff/client/Client"; import { DocsCache } from "./api/resources/docsCache/client/Client"; +import { Git } from "./api/resources/git/client/Client"; import { Sdks } from "./api/resources/sdks/client/Client"; import { SnippetsFactory } from "./api/resources/snippetsFactory/client/Client"; import { Snippets } from "./api/resources/snippets/client/Client"; @@ -61,6 +62,12 @@ export class FernRegistryClient { return (this._docsCache ??= new DocsCache(this._options)); } + protected _git: Git | undefined; + + public get git(): Git { + return (this._git ??= new Git(this._options)); + } + protected _sdks: Sdks | undefined; public get sdks(): Sdks { diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/Client.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/Client.ts new file mode 100644 index 0000000000..b142f87907 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/Client.ts @@ -0,0 +1,525 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments"; +import * as core from "../../../../core"; +import * as FernRegistry from "../../../index"; +import urlJoin from "url-join"; + +export declare namespace Git { + interface Options { + environment?: core.Supplier; + token?: core.Supplier; + } + + interface RequestOptions { + timeoutInSeconds?: number; + maxRetries?: number; + abortSignal?: AbortSignal; + } +} + +/** + * Produces an internal schema to easily track and view pull requests across Fern-managed repositories. This API is named `git` to allow for flexibility in adding other git providers down the line (e.g. gitlab). + */ +export class Git { + constructor(protected readonly _options: Git.Options = {}) {} + + /** + * Get a repository by its name (mirroring the Github API, this is the main get request). + * + * @param {string} repositoryOwner + * @param {string} repositoryName + * @param {Git.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await fernRegistry.git.getRepository("string", "string") + */ + public async getRepository( + repositoryOwner: string, + repositoryName: string, + requestOptions?: Git.RequestOptions + ): Promise> { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.FernRegistryEnvironment.Prod, + `/generators/github/repository/${encodeURIComponent(repositoryOwner)}/${encodeURIComponent( + repositoryName + )}` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : undefined, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + ok: true, + body: _response.body as FernRegistry.FernRepository, + }; + } + + return { + ok: false, + error: FernRegistry.git.getRepository.Error._unknown(_response.error), + }; + } + + /** + * Get all repositories. + * + * @param {FernRegistry.ListRepositoriesRequest} request + * @param {Git.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await fernRegistry.git.listRepositories({ + * page: 1, + * pageSize: 1, + * organizationId: "string", + * repositoryName: "string", + * repositoryOwner: "string" + * }) + */ + public async listRepositories( + request: FernRegistry.ListRepositoriesRequest = {}, + requestOptions?: Git.RequestOptions + ): Promise> { + const { page, pageSize, organizationId, repositoryName, repositoryOwner } = request; + const _queryParams: Record = {}; + if (page != null) { + _queryParams["page"] = page.toString(); + } + + if (pageSize != null) { + _queryParams["pageSize"] = pageSize.toString(); + } + + if (organizationId != null) { + _queryParams["organizationId"] = organizationId; + } + + if (repositoryName != null) { + _queryParams["repositoryName"] = repositoryName; + } + + if (repositoryOwner != null) { + _queryParams["repositoryOwner"] = repositoryOwner; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.FernRegistryEnvironment.Prod, + "/generators/github/repository" + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : undefined, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + ok: true, + body: _response.body as FernRegistry.ListRepositoriesResponse, + }; + } + + return { + ok: false, + error: FernRegistry.git.listRepositories.Error._unknown(_response.error), + }; + } + + /** + * Update or create the specified repository. + * + * @param {FernRegistry.FernRepository} request + * @param {Git.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await fernRegistry.git.upsertRepository({ + * type: "sdk", + * sdkLanguage: "string", + * id: { + * type: "github", + * id: "string" + * }, + * name: "string", + * owner: "string", + * fullName: "string", + * url: "string", + * repositoryOwnerOrganizationId: "string", + * defaultBranchChecks: [{ + * checkId: "string", + * repositoryOwner: "string", + * repositoryName: "string", + * ref: "string", + * name: "string", + * status: "string", + * conclusion: "string", + * checkRunUrl: "string", + * createdAt: new Date("2024-01-15T09:30:00.000Z"), + * completedAt: new Date("2024-01-15T09:30:00.000Z"), + * rawCheckRun: { + * "key": "value" + * } + * }] + * }) + */ + public async upsertRepository( + request: FernRegistry.FernRepository, + requestOptions?: Git.RequestOptions + ): Promise> { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.FernRegistryEnvironment.Prod, + "/generators/github/repository" + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : undefined, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + ok: true, + body: undefined, + }; + } + + return { + ok: false, + error: FernRegistry.git.upsertRepository.Error._unknown(_response.error), + }; + } + + /** + * Delete specified repository. + * + * @param {string} repositoryOwner + * @param {string} repositoryName + * @param {Git.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await fernRegistry.git.deleteRepository("string", "string") + */ + public async deleteRepository( + repositoryOwner: string, + repositoryName: string, + requestOptions?: Git.RequestOptions + ): Promise> { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.FernRegistryEnvironment.Prod, + `/generators/github/repository/${encodeURIComponent(repositoryOwner)}/${encodeURIComponent( + repositoryName + )}` + ), + method: "DELETE", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : undefined, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + ok: true, + body: undefined, + }; + } + + return { + ok: false, + error: FernRegistry.git.deleteRepository.Error._unknown(_response.error), + }; + } + + /** + * Get a pull request by its ID. + * + * @param {string} repositoryOwner + * @param {string} repositoryName + * @param {number} pullRequestNumber + * @param {Git.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await fernRegistry.git.getPullRequest("string", "string", 1) + */ + public async getPullRequest( + repositoryOwner: string, + repositoryName: string, + pullRequestNumber: number, + requestOptions?: Git.RequestOptions + ): Promise> { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.FernRegistryEnvironment.Prod, + `/generators/github/pull-request/${encodeURIComponent(repositoryOwner)}/${encodeURIComponent( + repositoryName + )}/${encodeURIComponent(pullRequestNumber)}` + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : undefined, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + ok: true, + body: _response.body as FernRegistry.PullRequest, + }; + } + + return { + ok: false, + error: FernRegistry.git.getPullRequest.Error._unknown(_response.error), + }; + } + + /** + * Get all pull requests. + * + * @param {FernRegistry.ListPullRequestsRequest} request + * @param {Git.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await fernRegistry.git.listPullRequests({ + * page: 1, + * pageSize: 1, + * repositoryName: "string", + * repositoryOwner: "string", + * organizationId: "string" + * }) + */ + public async listPullRequests( + request: FernRegistry.ListPullRequestsRequest = {}, + requestOptions?: Git.RequestOptions + ): Promise> { + const { page, pageSize, repositoryName, repositoryOwner, organizationId } = request; + const _queryParams: Record = {}; + if (page != null) { + _queryParams["page"] = page.toString(); + } + + if (pageSize != null) { + _queryParams["pageSize"] = pageSize.toString(); + } + + if (repositoryName != null) { + _queryParams["repositoryName"] = repositoryName; + } + + if (repositoryOwner != null) { + _queryParams["repositoryOwner"] = repositoryOwner; + } + + if (organizationId != null) { + _queryParams["organizationId"] = organizationId; + } + + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.FernRegistryEnvironment.Prod, + "/generators/github/pull-request" + ), + method: "GET", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + }, + contentType: "application/json", + queryParameters: _queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : undefined, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + ok: true, + body: _response.body as FernRegistry.ListPullRequestsResponse, + }; + } + + return { + ok: false, + error: FernRegistry.git.listPullRequests.Error._unknown(_response.error), + }; + } + + /** + * Update or create the specified pull request. + * + * @param {FernRegistry.PullRequest} request + * @param {Git.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await fernRegistry.git.upsertPullRequest({ + * pullRequestNumber: 1, + * repositoryName: "string", + * repositoryOwner: "string", + * author: { + * name: "string", + * email: "string", + * username: "string" + * }, + * reviewers: [{ + * type: "user", + * name: "string", + * email: "string", + * username: "string" + * }], + * title: "string", + * url: "string", + * checks: [{ + * checkId: "string", + * repositoryOwner: "string", + * repositoryName: "string", + * ref: "string", + * name: "string", + * status: "string", + * conclusion: "string", + * checkRunUrl: "string", + * createdAt: new Date("2024-01-15T09:30:00.000Z"), + * completedAt: new Date("2024-01-15T09:30:00.000Z"), + * rawCheckRun: { + * "key": "value" + * } + * }], + * state: FernRegistry.PullRequestState.Open, + * createdAt: new Date("2024-01-15T09:30:00.000Z"), + * updatedAt: new Date("2024-01-15T09:30:00.000Z"), + * mergedAt: new Date("2024-01-15T09:30:00.000Z"), + * closedAt: new Date("2024-01-15T09:30:00.000Z") + * }) + */ + public async upsertPullRequest( + request: FernRegistry.PullRequest, + requestOptions?: Git.RequestOptions + ): Promise> { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.FernRegistryEnvironment.Prod, + "/generators/github/pull-request" + ), + method: "PUT", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + }, + contentType: "application/json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : undefined, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + ok: true, + body: undefined, + }; + } + + return { + ok: false, + error: FernRegistry.git.upsertPullRequest.Error._unknown(_response.error), + }; + } + + /** + * Delete specified pull request. + * + * @param {string} repositoryOwner + * @param {string} repositoryName + * @param {number} pullRequestNumber + * @param {Git.RequestOptions} requestOptions - Request-specific configuration. + * + * @example + * await fernRegistry.git.deletePullRequest("string", "string", 1) + */ + public async deletePullRequest( + repositoryOwner: string, + repositoryName: string, + pullRequestNumber: number, + requestOptions?: Git.RequestOptions + ): Promise> { + const _response = await core.fetcher({ + url: urlJoin( + (await core.Supplier.get(this._options.environment)) ?? environments.FernRegistryEnvironment.Prod, + `/generators/github/pull-request/${encodeURIComponent(repositoryOwner)}/${encodeURIComponent( + repositoryName + )}/${encodeURIComponent(pullRequestNumber)}` + ), + method: "DELETE", + headers: { + Authorization: await this._getAuthorizationHeader(), + "X-Fern-Language": "JavaScript", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + }, + contentType: "application/json", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : undefined, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + ok: true, + body: undefined, + }; + } + + return { + ok: false, + error: FernRegistry.git.deletePullRequest.Error._unknown(_response.error), + }; + } + + protected async _getAuthorizationHeader(): Promise { + const bearer = await core.Supplier.get(this._options.token); + if (bearer != null) { + return `Bearer ${bearer}`; + } + + return undefined; + } +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/deletePullRequest.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/deletePullRequest.ts new file mode 100644 index 0000000000..644da4ffca --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/deletePullRequest.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; +import * as core from "../../../../core"; + +export type Error = FernRegistry.git.deletePullRequest.Error._Unknown; + +export declare namespace Error { + interface _Unknown { + error: void; + content: core.Fetcher.Error; + } + + interface _Visitor<_Result> { + _other: (value: core.Fetcher.Error) => _Result; + } +} + +export const Error = { + _unknown: (fetcherError: core.Fetcher.Error): FernRegistry.git.deletePullRequest.Error._Unknown => { + return { + error: undefined, + content: fetcherError, + }; + }, + + _visit: <_Result>( + value: FernRegistry.git.deletePullRequest.Error, + visitor: FernRegistry.git.deletePullRequest.Error._Visitor<_Result> + ): _Result => { + switch (value.error) { + default: + return visitor._other(value as any); + } + }, +} as const; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/deleteRepository.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/deleteRepository.ts new file mode 100644 index 0000000000..27d54e919c --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/deleteRepository.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; +import * as core from "../../../../core"; + +export type Error = FernRegistry.git.deleteRepository.Error._Unknown; + +export declare namespace Error { + interface _Unknown { + error: void; + content: core.Fetcher.Error; + } + + interface _Visitor<_Result> { + _other: (value: core.Fetcher.Error) => _Result; + } +} + +export const Error = { + _unknown: (fetcherError: core.Fetcher.Error): FernRegistry.git.deleteRepository.Error._Unknown => { + return { + error: undefined, + content: fetcherError, + }; + }, + + _visit: <_Result>( + value: FernRegistry.git.deleteRepository.Error, + visitor: FernRegistry.git.deleteRepository.Error._Visitor<_Result> + ): _Result => { + switch (value.error) { + default: + return visitor._other(value as any); + } + }, +} as const; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/getPullRequest.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/getPullRequest.ts new file mode 100644 index 0000000000..d584481f49 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/getPullRequest.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; +import * as core from "../../../../core"; + +export type Error = FernRegistry.git.getPullRequest.Error._Unknown; + +export declare namespace Error { + interface _Unknown { + error: void; + content: core.Fetcher.Error; + } + + interface _Visitor<_Result> { + _other: (value: core.Fetcher.Error) => _Result; + } +} + +export const Error = { + _unknown: (fetcherError: core.Fetcher.Error): FernRegistry.git.getPullRequest.Error._Unknown => { + return { + error: undefined, + content: fetcherError, + }; + }, + + _visit: <_Result>( + value: FernRegistry.git.getPullRequest.Error, + visitor: FernRegistry.git.getPullRequest.Error._Visitor<_Result> + ): _Result => { + switch (value.error) { + default: + return visitor._other(value as any); + } + }, +} as const; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/getRepository.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/getRepository.ts new file mode 100644 index 0000000000..22cfbe0f63 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/getRepository.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; +import * as core from "../../../../core"; + +export type Error = FernRegistry.git.getRepository.Error._Unknown; + +export declare namespace Error { + interface _Unknown { + error: void; + content: core.Fetcher.Error; + } + + interface _Visitor<_Result> { + _other: (value: core.Fetcher.Error) => _Result; + } +} + +export const Error = { + _unknown: (fetcherError: core.Fetcher.Error): FernRegistry.git.getRepository.Error._Unknown => { + return { + error: undefined, + content: fetcherError, + }; + }, + + _visit: <_Result>( + value: FernRegistry.git.getRepository.Error, + visitor: FernRegistry.git.getRepository.Error._Visitor<_Result> + ): _Result => { + switch (value.error) { + default: + return visitor._other(value as any); + } + }, +} as const; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/index.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/index.ts new file mode 100644 index 0000000000..a8ffeba628 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/index.ts @@ -0,0 +1,9 @@ +export * from "./requests"; +export * as getRepository from "./getRepository"; +export * as listRepositories from "./listRepositories"; +export * as upsertRepository from "./upsertRepository"; +export * as deleteRepository from "./deleteRepository"; +export * as getPullRequest from "./getPullRequest"; +export * as listPullRequests from "./listPullRequests"; +export * as upsertPullRequest from "./upsertPullRequest"; +export * as deletePullRequest from "./deletePullRequest"; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/listPullRequests.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/listPullRequests.ts new file mode 100644 index 0000000000..2351636548 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/listPullRequests.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; +import * as core from "../../../../core"; + +export type Error = FernRegistry.git.listPullRequests.Error._Unknown; + +export declare namespace Error { + interface _Unknown { + error: void; + content: core.Fetcher.Error; + } + + interface _Visitor<_Result> { + _other: (value: core.Fetcher.Error) => _Result; + } +} + +export const Error = { + _unknown: (fetcherError: core.Fetcher.Error): FernRegistry.git.listPullRequests.Error._Unknown => { + return { + error: undefined, + content: fetcherError, + }; + }, + + _visit: <_Result>( + value: FernRegistry.git.listPullRequests.Error, + visitor: FernRegistry.git.listPullRequests.Error._Visitor<_Result> + ): _Result => { + switch (value.error) { + default: + return visitor._other(value as any); + } + }, +} as const; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/listRepositories.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/listRepositories.ts new file mode 100644 index 0000000000..c22a18a552 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/listRepositories.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; +import * as core from "../../../../core"; + +export type Error = FernRegistry.git.listRepositories.Error._Unknown; + +export declare namespace Error { + interface _Unknown { + error: void; + content: core.Fetcher.Error; + } + + interface _Visitor<_Result> { + _other: (value: core.Fetcher.Error) => _Result; + } +} + +export const Error = { + _unknown: (fetcherError: core.Fetcher.Error): FernRegistry.git.listRepositories.Error._Unknown => { + return { + error: undefined, + content: fetcherError, + }; + }, + + _visit: <_Result>( + value: FernRegistry.git.listRepositories.Error, + visitor: FernRegistry.git.listRepositories.Error._Visitor<_Result> + ): _Result => { + switch (value.error) { + default: + return visitor._other(value as any); + } + }, +} as const; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/ListPullRequestsRequest.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/ListPullRequestsRequest.ts new file mode 100644 index 0000000000..f715536dc7 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/ListPullRequestsRequest.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../../index"; + +/** + * @example + * { + * page: 1, + * pageSize: 1, + * repositoryName: "string", + * repositoryOwner: "string", + * organizationId: "string" + * } + */ +export interface ListPullRequestsRequest { + /** + * The page number to retrieve. Defaults to 0. + */ + page?: number; + /** + * The number of items to retrieve per page. Defaults to 20. + */ + pageSize?: number; + /** + * The name of the repository to filter pull requests by (ex: full-platform). + */ + repositoryName?: string; + /** + * The organization name of the repository owner to filter pull requests by (ex: fern-api). + */ + repositoryOwner?: string; + /** + * The Fern organization ID to filter repositories by. + */ + organizationId?: FernRegistry.OrgId; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/ListRepositoriesRequest.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/ListRepositoriesRequest.ts new file mode 100644 index 0000000000..862e9d0312 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/ListRepositoriesRequest.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../../index"; + +/** + * @example + * { + * page: 1, + * pageSize: 1, + * organizationId: "string", + * repositoryName: "string", + * repositoryOwner: "string" + * } + */ +export interface ListRepositoriesRequest { + /** + * The page number to retrieve. Defaults to 0. + */ + page?: number; + /** + * The number of items to retrieve per page. Defaults to 20. + */ + pageSize?: number; + /** + * The Fern organization ID to filter repositories by. + */ + organizationId?: FernRegistry.OrgId; + /** + * The name of the repository to filter pull requests by (ex: full-platform). + */ + repositoryName?: string; + /** + * The organization name of the repository owner to filter pull requests by (ex: fern-api). + */ + repositoryOwner?: string; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/index.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/index.ts new file mode 100644 index 0000000000..c5a272592c --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/requests/index.ts @@ -0,0 +1,2 @@ +export { type ListRepositoriesRequest } from "./ListRepositoriesRequest"; +export { type ListPullRequestsRequest } from "./ListPullRequestsRequest"; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/upsertPullRequest.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/upsertPullRequest.ts new file mode 100644 index 0000000000..58740a1cbb --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/upsertPullRequest.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; +import * as core from "../../../../core"; + +export type Error = FernRegistry.git.upsertPullRequest.Error._Unknown; + +export declare namespace Error { + interface _Unknown { + error: void; + content: core.Fetcher.Error; + } + + interface _Visitor<_Result> { + _other: (value: core.Fetcher.Error) => _Result; + } +} + +export const Error = { + _unknown: (fetcherError: core.Fetcher.Error): FernRegistry.git.upsertPullRequest.Error._Unknown => { + return { + error: undefined, + content: fetcherError, + }; + }, + + _visit: <_Result>( + value: FernRegistry.git.upsertPullRequest.Error, + visitor: FernRegistry.git.upsertPullRequest.Error._Visitor<_Result> + ): _Result => { + switch (value.error) { + default: + return visitor._other(value as any); + } + }, +} as const; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/client/upsertRepository.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/client/upsertRepository.ts new file mode 100644 index 0000000000..544b7bd6c1 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/client/upsertRepository.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; +import * as core from "../../../../core"; + +export type Error = FernRegistry.git.upsertRepository.Error._Unknown; + +export declare namespace Error { + interface _Unknown { + error: void; + content: core.Fetcher.Error; + } + + interface _Visitor<_Result> { + _other: (value: core.Fetcher.Error) => _Result; + } +} + +export const Error = { + _unknown: (fetcherError: core.Fetcher.Error): FernRegistry.git.upsertRepository.Error._Unknown => { + return { + error: undefined, + content: fetcherError, + }; + }, + + _visit: <_Result>( + value: FernRegistry.git.upsertRepository.Error, + visitor: FernRegistry.git.upsertRepository.Error._Visitor<_Result> + ): _Result => { + switch (value.error) { + default: + return visitor._other(value as any); + } + }, +} as const; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/index.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/index.ts new file mode 100644 index 0000000000..c9240f83b4 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/index.ts @@ -0,0 +1,2 @@ +export * from "./types"; +export * from "./client"; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/BaseRepository.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/BaseRepository.ts new file mode 100644 index 0000000000..dba876de87 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/BaseRepository.ts @@ -0,0 +1,18 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; + +export interface BaseRepository { + id: FernRegistry.RepositoryId; + name: string; + /** The organization name within Github, e.g. fern-api. */ + owner: string; + /** The full name of the repository, e.g. fern-api/fern. It includes the owner, as well as the name of the repository. */ + fullName: string; + url: string; + /** The Fern organization ID of the repository owner. */ + repositoryOwnerOrganizationId: FernRegistry.OrgId; + defaultBranchChecks: FernRegistry.CheckRun[]; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/CheckRun.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/CheckRun.ts new file mode 100644 index 0000000000..e7eb022e70 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/CheckRun.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface CheckRun { + checkId: string; + repositoryOwner: string; + repositoryName: string; + ref: string; + name: string; + status: string; + conclusion: string; + checkRunUrl: string; + createdAt: string; + completedAt?: string; + rawCheckRun?: unknown; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/FernConfigRepository.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/FernConfigRepository.ts new file mode 100644 index 0000000000..e1cdfe14cf --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/FernConfigRepository.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; + +export interface FernConfigRepository extends FernRegistry.BaseRepository {} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/FernRepository.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/FernRepository.ts new file mode 100644 index 0000000000..ef8b6656f1 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/FernRepository.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; + +export type FernRepository = FernRegistry.FernRepository.Sdk | FernRegistry.FernRepository.Config; + +export declare namespace FernRepository { + interface Sdk extends FernRegistry.SdkRepository { + type: "sdk"; + } + + interface Config extends FernRegistry.FernConfigRepository { + type: "config"; + } +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubRepositoryId.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubRepositoryId.ts new file mode 100644 index 0000000000..9f933918a6 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubRepositoryId.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GithubRepositoryId { + id: string; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubTeam.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubTeam.ts new file mode 100644 index 0000000000..9b639fdbce --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubTeam.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GithubTeam { + name: string; + teamId: string; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubUser.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubUser.ts new file mode 100644 index 0000000000..cce7e338cf --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/GithubUser.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GithubUser { + name: string; + email: string; + username: string; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/ListPullRequestsResponse.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/ListPullRequestsResponse.ts new file mode 100644 index 0000000000..2459047a99 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/ListPullRequestsResponse.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; + +export interface ListPullRequestsResponse { + pullRequests: FernRegistry.PullRequest[]; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/ListRepositoriesResponse.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/ListRepositoriesResponse.ts new file mode 100644 index 0000000000..ff966553e5 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/ListRepositoriesResponse.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; + +export interface ListRepositoriesResponse { + repositories: FernRegistry.FernRepository[]; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequest.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequest.ts new file mode 100644 index 0000000000..61aceed9e1 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequest.ts @@ -0,0 +1,21 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; + +export interface PullRequest { + pullRequestNumber: number; + repositoryName: string; + repositoryOwner: string; + author: FernRegistry.GithubUser; + reviewers: FernRegistry.PullRequestReviewer[]; + title: string; + url: string; + checks: FernRegistry.CheckRun[]; + state: FernRegistry.PullRequestState; + createdAt: string; + updatedAt?: string; + mergedAt?: string; + closedAt?: string; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestNotFound.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestNotFound.ts new file mode 100644 index 0000000000..c9469e1c7a --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestNotFound.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; + +export interface PullRequestNotFound extends FernRegistry.RepositoryNotFound { + pullRequestNumber: number; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestReviewer.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestReviewer.ts new file mode 100644 index 0000000000..95e4e0f138 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestReviewer.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; + +export type PullRequestReviewer = FernRegistry.PullRequestReviewer.User | FernRegistry.PullRequestReviewer.Team; + +export declare namespace PullRequestReviewer { + interface User extends FernRegistry.GithubUser { + type: "user"; + } + + interface Team extends FernRegistry.GithubTeam { + type: "team"; + } +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestState.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestState.ts new file mode 100644 index 0000000000..2617e443cc --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/PullRequestState.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type PullRequestState = "open" | "closed" | "merged"; + +export const PullRequestState = { + Open: "open", + Closed: "closed", + Merged: "merged", +} as const; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/RepositoryId.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/RepositoryId.ts new file mode 100644 index 0000000000..ab33e80890 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/RepositoryId.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; + +export type RepositoryId = FernRegistry.RepositoryId.Github; + +export declare namespace RepositoryId { + interface Github extends FernRegistry.GithubRepositoryId { + type: "github"; + } +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/RepositoryNotFound.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/RepositoryNotFound.ts new file mode 100644 index 0000000000..686ec4d0e0 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/RepositoryNotFound.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface RepositoryNotFound { + repositoryName: string; + repositoryOwner: string; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/SdkRepository.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/SdkRepository.ts new file mode 100644 index 0000000000..7d883baf88 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/SdkRepository.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as FernRegistry from "../../../index"; + +export interface SdkRepository extends FernRegistry.BaseRepository { + sdkLanguage: string; +} diff --git a/packages/fdr-sdk/src/client/generated/api/resources/git/types/index.ts b/packages/fdr-sdk/src/client/generated/api/resources/git/types/index.ts new file mode 100644 index 0000000000..9e96b8e7f1 --- /dev/null +++ b/packages/fdr-sdk/src/client/generated/api/resources/git/types/index.ts @@ -0,0 +1,16 @@ +export * from "./CheckRun"; +export * from "./GithubRepositoryId"; +export * from "./RepositoryId"; +export * from "./BaseRepository"; +export * from "./SdkRepository"; +export * from "./FernConfigRepository"; +export * from "./FernRepository"; +export * from "./GithubUser"; +export * from "./GithubTeam"; +export * from "./PullRequestReviewer"; +export * from "./PullRequestState"; +export * from "./PullRequest"; +export * from "./ListRepositoriesResponse"; +export * from "./ListPullRequestsResponse"; +export * from "./RepositoryNotFound"; +export * from "./PullRequestNotFound"; diff --git a/packages/fdr-sdk/src/client/generated/api/resources/index.ts b/packages/fdr-sdk/src/client/generated/api/resources/index.ts index ae2a6e1ef4..998f00caf4 100644 --- a/packages/fdr-sdk/src/client/generated/api/resources/index.ts +++ b/packages/fdr-sdk/src/client/generated/api/resources/index.ts @@ -8,6 +8,8 @@ export * as commons from "./commons"; export * from "./commons/types"; export * as diff from "./diff"; export * from "./diff/types"; +export * as git from "./git"; +export * from "./git/types"; export * as sdks from "./sdks"; export * as snippetsFactory from "./snippetsFactory"; export * from "./snippetsFactory/types"; @@ -20,6 +22,7 @@ export * from "./tokens/types"; export * as docsCache from "./docsCache"; export * from "./diff/client/requests"; export * from "./docsCache/client/requests"; +export * from "./git/client/requests"; export * from "./snippetsFactory/client/requests"; export * from "./snippets/client/requests"; export * from "./templates/client/requests"; diff --git a/servers/fdr/prisma/migrations/20240916140019_add_git_repo_and_pr/migration.sql b/servers/fdr/prisma/migrations/20240916140019_add_git_repo_and_pr/migration.sql new file mode 100644 index 0000000000..ab8228f577 --- /dev/null +++ b/servers/fdr/prisma/migrations/20240916140019_add_git_repo_and_pr/migration.sql @@ -0,0 +1,52 @@ +-- CreateEnum +CREATE TYPE "PullRequestState" AS ENUM ('open', 'closed', 'merged'); + +-- CreateEnum +CREATE TYPE "RepositorySystemType" AS ENUM ('github'); + +-- CreateEnum +CREATE TYPE "RepositoryContentType" AS ENUM ('sdk', 'config'); + +-- CreateTable +CREATE TABLE "PullRequest" ( + "pullRequestNumber" INTEGER NOT NULL, + "repositoryOwner" TEXT NOT NULL, + "repositoryName" TEXT NOT NULL, + "author" BYTEA NOT NULL, + "reviewers" BYTEA NOT NULL, + "checks" BYTEA NOT NULL, + "title" TEXT NOT NULL, + "url" TEXT NOT NULL, + "state" "PullRequestState" NOT NULL, + "createdAt" TIMESTAMP(3) NOT NULL, + "updatedAt" TIMESTAMP(3), + "mergedAt" TIMESTAMP(3), + "closedAt" TIMESTAMP(3), + + CONSTRAINT "PullRequest_pkey" PRIMARY KEY ("pullRequestNumber","repositoryOwner","repositoryName") +); + +-- CreateTable +CREATE TABLE "Repository" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "owner" TEXT NOT NULL, + "fullName" TEXT NOT NULL, + "url" TEXT NOT NULL, + "repositoryOwnerOrganizationId" TEXT NOT NULL, + "defaultBranchChecks" BYTEA NOT NULL, + "contentType" "RepositoryContentType" NOT NULL, + "systemType" "RepositorySystemType" NOT NULL, + "rawRepository" BYTEA NOT NULL, + + CONSTRAINT "Repository_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "Repository_fullName_key" ON "Repository"("fullName"); + +-- CreateIndex +CREATE UNIQUE INDEX "Repository_owner_name_key" ON "Repository"("owner", "name"); + +-- AddForeignKey +ALTER TABLE "PullRequest" ADD CONSTRAINT "PullRequest_repositoryOwner_repositoryName_fkey" FOREIGN KEY ("repositoryOwner", "repositoryName") REFERENCES "Repository"("owner", "name") ON DELETE CASCADE ON UPDATE CASCADE; diff --git a/servers/fdr/prisma/schema.prisma b/servers/fdr/prisma/schema.prisma index 54d60546e9..5faea330c7 100644 --- a/servers/fdr/prisma/schema.prisma +++ b/servers/fdr/prisma/schema.prisma @@ -225,4 +225,63 @@ model CliRelease { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt -} \ No newline at end of file +} + +enum PullRequestState { + open + closed + merged +} + +model PullRequest { + @@id([pullRequestNumber, repositoryOwner, repositoryName]) + pullRequestNumber Int + // PRs coming from GitHub do not seem to contain the repo ID, but rather the owner and repo name, so let's use that + // instead of always performing a look up to get ID from name and owner. + repositoryOwner String + repositoryName String + repository Repository @relation(fields: [repositoryOwner, repositoryName], references: [owner, name], onDelete: Cascade) + + author Bytes + reviewers Bytes + checks Bytes + + title String + url String + state PullRequestState + + createdAt DateTime + updatedAt DateTime? + mergedAt DateTime? + closedAt DateTime? +} + +enum RepositorySystemType { + github +} + +enum RepositoryContentType { + sdk + config +} + +model Repository { + @@unique([owner, name]) + + id String @id + name String + owner String + fullName String @unique + url String + repositoryOwnerOrganizationId String + + pulls PullRequest[] + defaultBranchChecks Bytes + + contentType RepositoryContentType + systemType RepositorySystemType + + // Allows us to maintain the full union object, but also querying by the base + // properties with the columns above + rawRepository Bytes +} diff --git a/servers/fdr/src/__test__/local/db/gitDao.test.ts b/servers/fdr/src/__test__/local/db/gitDao.test.ts new file mode 100644 index 0000000000..7fa6483407 --- /dev/null +++ b/servers/fdr/src/__test__/local/db/gitDao.test.ts @@ -0,0 +1,110 @@ +import { FernRepository } from "@fern-api/fdr-sdk/src/client/generated/api"; +import { PullRequest, PullRequestState } from "../../../api/generated/api"; +import { createMockFdrApplication } from "../../mock"; + +const fdrApplication = createMockFdrApplication({ + orgIds: ["acme", "octoai"], +}); + +it("repo happy path", async () => { + const repo1: FernRepository = { + type: "sdk", + id: { type: "github", id: "acme-123" }, + name: "repo1", + owner: "acme", + fullName: "acme/repo1", + repositoryOwnerOrganizationId: "acme", + url: "https://123.com", + defaultBranchChecks: [], + sdkLanguage: "python", + }; + await fdrApplication.dao.git().upsertRepository({ repository: repo1 }); + + const repo2: FernRepository = { + type: "config", + id: { type: "github", id: "octo-123" }, + name: "repo1", + owner: "octoai", + fullName: "octoai/repo1", + repositoryOwnerOrganizationId: "octoai", + url: "https://123.com", + defaultBranchChecks: [], + }; + await fdrApplication.dao.git().upsertRepository({ repository: repo2 }); + + const repos = await fdrApplication.dao.git().listRepository({ + repositoryName: undefined, + repositoryOwner: undefined, + organizationId: undefined, + }); + expect(repos.repositories).toEqual([repo1, repo2]); + + const repo1FromDb = await fdrApplication.dao + .git() + .getRepository({ repositoryOwner: "acme", repositoryName: "repo1" }); + expect(repo1FromDb).toEqual(repo1); +}); + +it("pulls happy path", async () => { + const repository: FernRepository = { + type: "sdk", + id: { type: "github", id: "12345" }, + name: "repoForPRs", + owner: "acme", + fullName: "acme/repoForPRs", + repositoryOwnerOrganizationId: "acme", + url: "https://123.com", + defaultBranchChecks: [], + sdkLanguage: "python", + }; + await fdrApplication.dao.git().upsertRepository({ repository }); + + const pull1: PullRequest = { + pullRequestNumber: 1, + repositoryOwner: "acme", + repositoryName: "repoForPRs", + author: { + name: "Armando", + email: "armando@buildwithfern.com", + username: "armando", + }, + reviewers: [], + title: "PR 1", + url: "https://123.com", + checks: [], + state: PullRequestState.Open, + createdAt: new Date().toISOString(), + }; + await fdrApplication.dao.git().upsertPullRequest({ pullRequest: pull1 }); + + const pull2: PullRequest = { + pullRequestNumber: 2, + repositoryOwner: "acme", + repositoryName: "repoForPRs", + author: { + name: "Armando", + email: "armando@buildwithfern.com", + username: "armando", + }, + reviewers: [], + title: "PR 2", + url: "https://123.com", + checks: [], + state: PullRequestState.Merged, + createdAt: new Date().toISOString(), + mergedAt: new Date().toISOString(), + }; + await fdrApplication.dao.git().upsertPullRequest({ pullRequest: pull2 }); + + const pulls = await fdrApplication.dao.git().listPullRequests({ + repositoryName: undefined, + repositoryOwner: undefined, + organizationId: undefined, + }); + expect(pulls.pullRequests).toEqual([pull2, pull1]); + + const pull1FromDb = await fdrApplication.dao + .git() + .getPullRequest({ repositoryOwner: "acme", repositoryName: "repoForPRs", pullRequestNumber: 1 }); + expect(pull1FromDb).toEqual(pull1); +}); diff --git a/servers/fdr/src/__test__/local/setupMockFdr.ts b/servers/fdr/src/__test__/local/setupMockFdr.ts index ffaffa7e0e..2c440fa8aa 100644 --- a/servers/fdr/src/__test__/local/setupMockFdr.ts +++ b/servers/fdr/src/__test__/local/setupMockFdr.ts @@ -16,6 +16,7 @@ import { getDocsWriteV2Service } from "../../controllers/docs/v2/getDocsWriteV2S import { getGeneratorsCliController } from "../../controllers/generators/getGeneratorsCliController"; import { getGeneratorsRootController } from "../../controllers/generators/getGeneratorsRootController"; import { getGeneratorsVersionsController } from "../../controllers/generators/getGeneratorsVersionsController"; +import { getGitController } from "../../controllers/git/getGitController"; import { getVersionsService } from "../../controllers/sdk/getVersionsService"; import { getSnippetsFactoryService } from "../../controllers/snippets/getSnippetsFactoryService"; import { getSnippetsService } from "../../controllers/snippets/getSnippetsService"; @@ -116,6 +117,7 @@ async function runMockFdr(port: number): Promise { versions: getGeneratorsVersionsController(fdrApplication), }, tokens: getTokensService(fdrApplication), + git: getGitController(fdrApplication), }); const server = app.listen(port); console.log(`Mock FDR server running on http://localhost:${port}/`); diff --git a/servers/fdr/src/api/generated/api/resources/git/errors/PullRequestNotFoundError.d.ts b/servers/fdr/src/api/generated/api/resources/git/errors/PullRequestNotFoundError.d.ts new file mode 100644 index 0000000000..c34678786b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/errors/PullRequestNotFoundError.d.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as errors from "../../../../errors/index"; +import * as FernRegistry from "../../../index"; +import express from "express"; +export declare class PullRequestNotFoundError extends errors.FernRegistryError { + private readonly body; + constructor(body: FernRegistry.PullRequestNotFound); + send(res: express.Response): Promise; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/errors/PullRequestNotFoundError.js b/servers/fdr/src/api/generated/api/resources/git/errors/PullRequestNotFoundError.js new file mode 100644 index 0000000000..bbc7fca1c7 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/errors/PullRequestNotFoundError.js @@ -0,0 +1,25 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import * as errors from "../../../../errors/index"; +export class PullRequestNotFoundError extends errors.FernRegistryError { + constructor(body) { + super("PullRequestNotFoundError"); + this.body = body; + Object.setPrototypeOf(this, PullRequestNotFoundError.prototype); + } + send(res) { + return __awaiter(this, void 0, void 0, function* () { + res.status(404).json(this.body); + }); + } +} diff --git a/servers/fdr/src/api/generated/api/resources/git/errors/RepositoryNotFoundError.d.ts b/servers/fdr/src/api/generated/api/resources/git/errors/RepositoryNotFoundError.d.ts new file mode 100644 index 0000000000..5e22661492 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/errors/RepositoryNotFoundError.d.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as errors from "../../../../errors/index"; +import * as FernRegistry from "../../../index"; +import express from "express"; +export declare class RepositoryNotFoundError extends errors.FernRegistryError { + private readonly body; + constructor(body: FernRegistry.RepositoryNotFound); + send(res: express.Response): Promise; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/errors/RepositoryNotFoundError.js b/servers/fdr/src/api/generated/api/resources/git/errors/RepositoryNotFoundError.js new file mode 100644 index 0000000000..14d185adf3 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/errors/RepositoryNotFoundError.js @@ -0,0 +1,25 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import * as errors from "../../../../errors/index"; +export class RepositoryNotFoundError extends errors.FernRegistryError { + constructor(body) { + super("RepositoryNotFoundError"); + this.body = body; + Object.setPrototypeOf(this, RepositoryNotFoundError.prototype); + } + send(res) { + return __awaiter(this, void 0, void 0, function* () { + res.status(404).json(this.body); + }); + } +} diff --git a/servers/fdr/src/api/generated/api/resources/git/errors/index.d.ts b/servers/fdr/src/api/generated/api/resources/git/errors/index.d.ts new file mode 100644 index 0000000000..681978f5f9 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/errors/index.d.ts @@ -0,0 +1,2 @@ +export * from "./PullRequestNotFoundError"; +export * from "./RepositoryNotFoundError"; diff --git a/servers/fdr/src/api/generated/api/resources/git/errors/index.js b/servers/fdr/src/api/generated/api/resources/git/errors/index.js new file mode 100644 index 0000000000..681978f5f9 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/errors/index.js @@ -0,0 +1,2 @@ +export * from "./PullRequestNotFoundError"; +export * from "./RepositoryNotFoundError"; diff --git a/servers/fdr/src/api/generated/api/resources/git/index.d.ts b/servers/fdr/src/api/generated/api/resources/git/index.d.ts new file mode 100644 index 0000000000..02a9604196 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/index.d.ts @@ -0,0 +1,3 @@ +export * from "./types"; +export * from "./service"; +export * from "./errors"; diff --git a/servers/fdr/src/api/generated/api/resources/git/index.js b/servers/fdr/src/api/generated/api/resources/git/index.js new file mode 100644 index 0000000000..02a9604196 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/index.js @@ -0,0 +1,3 @@ +export * from "./types"; +export * from "./service"; +export * from "./errors"; diff --git a/servers/fdr/src/api/generated/api/resources/git/service/GitService.d.ts b/servers/fdr/src/api/generated/api/resources/git/service/GitService.d.ts new file mode 100644 index 0000000000..33f386b2a7 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/service/GitService.d.ts @@ -0,0 +1,83 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../index"; +import express from "express"; +export interface GitServiceMethods { + getRepository(req: express.Request<{ + repositoryOwner: string; + repositoryName: string; + }, FernRegistry.FernRepository, never, never>, res: { + send: (responseBody: FernRegistry.FernRepository) => Promise; + cookie: (cookie: string, value: string, options?: express.CookieOptions) => void; + locals: any; + }, next: express.NextFunction): void | Promise; + listRepositories(req: express.Request, res: { + send: (responseBody: FernRegistry.ListRepositoriesResponse) => Promise; + cookie: (cookie: string, value: string, options?: express.CookieOptions) => void; + locals: any; + }, next: express.NextFunction): void | Promise; + upsertRepository(req: express.Request, res: { + send: () => Promise; + cookie: (cookie: string, value: string, options?: express.CookieOptions) => void; + locals: any; + }, next: express.NextFunction): void | Promise; + deleteRepository(req: express.Request<{ + repositoryOwner: string; + repositoryName: string; + }, never, never, never>, res: { + send: () => Promise; + cookie: (cookie: string, value: string, options?: express.CookieOptions) => void; + locals: any; + }, next: express.NextFunction): void | Promise; + getPullRequest(req: express.Request<{ + repositoryOwner: string; + repositoryName: string; + pullRequestNumber: number; + }, FernRegistry.PullRequest, never, never>, res: { + send: (responseBody: FernRegistry.PullRequest) => Promise; + cookie: (cookie: string, value: string, options?: express.CookieOptions) => void; + locals: any; + }, next: express.NextFunction): void | Promise; + listPullRequests(req: express.Request, res: { + send: (responseBody: FernRegistry.ListPullRequestsResponse) => Promise; + cookie: (cookie: string, value: string, options?: express.CookieOptions) => void; + locals: any; + }, next: express.NextFunction): void | Promise; + upsertPullRequest(req: express.Request, res: { + send: () => Promise; + cookie: (cookie: string, value: string, options?: express.CookieOptions) => void; + locals: any; + }, next: express.NextFunction): void | Promise; + deletePullRequest(req: express.Request<{ + repositoryOwner: string; + repositoryName: string; + pullRequestNumber: number; + }, never, never, never>, res: { + send: () => Promise; + cookie: (cookie: string, value: string, options?: express.CookieOptions) => void; + locals: any; + }, next: express.NextFunction): void | Promise; +} +/** + * Produces an internal schema to easily track and view pull requests across Fern-managed repositories. This API is named `git` to allow for flexibility in adding other git providers down the line (e.g. gitlab). + */ +export declare class GitService { + private readonly methods; + private router; + constructor(methods: GitServiceMethods, middleware?: express.RequestHandler[]); + addMiddleware(handler: express.RequestHandler): this; + toRouter(): express.Router; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/service/GitService.js b/servers/fdr/src/api/generated/api/resources/git/service/GitService.js new file mode 100644 index 0000000000..c34eb0cbfd --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/service/GitService.js @@ -0,0 +1,224 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +import express from "express"; +import * as errors from "../../../../errors/index"; +/** + * Produces an internal schema to easily track and view pull requests across Fern-managed repositories. This API is named `git` to allow for flexibility in adding other git providers down the line (e.g. gitlab). + */ +export class GitService { + constructor(methods, middleware = []) { + this.methods = methods; + this.router = express.Router({ mergeParams: true }).use(express.json({ + strict: false, + }), ...middleware); + } + addMiddleware(handler) { + this.router.use(handler); + return this; + } + toRouter() { + this.router.get("/repository/:repositoryOwner/:repositoryName", (req, res, next) => __awaiter(this, void 0, void 0, function* () { + try { + yield this.methods.getRepository(req, { + send: (responseBody) => __awaiter(this, void 0, void 0, function* () { + res.json(responseBody); + }), + cookie: res.cookie.bind(res), + locals: res.locals, + }, next); + next(); + } + catch (error) { + if (error instanceof errors.FernRegistryError) { + console.warn(`Endpoint 'getRepository' unexpectedly threw ${error.constructor.name}.` + + ` If this was intentional, please add ${error.constructor.name} to` + + " the endpoint's errors list in your Fern Definition."); + yield error.send(res); + } + else { + res.status(500).json("Internal Server Error"); + } + next(error); + } + })); + this.router.get("/repository", (req, res, next) => __awaiter(this, void 0, void 0, function* () { + try { + yield this.methods.listRepositories(req, { + send: (responseBody) => __awaiter(this, void 0, void 0, function* () { + res.json(responseBody); + }), + cookie: res.cookie.bind(res), + locals: res.locals, + }, next); + next(); + } + catch (error) { + if (error instanceof errors.FernRegistryError) { + console.warn(`Endpoint 'listRepositories' unexpectedly threw ${error.constructor.name}.` + + ` If this was intentional, please add ${error.constructor.name} to` + + " the endpoint's errors list in your Fern Definition."); + yield error.send(res); + } + else { + res.status(500).json("Internal Server Error"); + } + next(error); + } + })); + this.router.put("/repository", (req, res, next) => __awaiter(this, void 0, void 0, function* () { + try { + yield this.methods.upsertRepository(req, { + send: () => __awaiter(this, void 0, void 0, function* () { + res.sendStatus(204); + }), + cookie: res.cookie.bind(res), + locals: res.locals, + }, next); + next(); + } + catch (error) { + if (error instanceof errors.FernRegistryError) { + console.warn(`Endpoint 'upsertRepository' unexpectedly threw ${error.constructor.name}.` + + ` If this was intentional, please add ${error.constructor.name} to` + + " the endpoint's errors list in your Fern Definition."); + yield error.send(res); + } + else { + res.status(500).json("Internal Server Error"); + } + next(error); + } + })); + this.router.delete("/repository/:repositoryOwner/:repositoryName", (req, res, next) => __awaiter(this, void 0, void 0, function* () { + try { + yield this.methods.deleteRepository(req, { + send: () => __awaiter(this, void 0, void 0, function* () { + res.sendStatus(204); + }), + cookie: res.cookie.bind(res), + locals: res.locals, + }, next); + next(); + } + catch (error) { + if (error instanceof errors.FernRegistryError) { + console.warn(`Endpoint 'deleteRepository' unexpectedly threw ${error.constructor.name}.` + + ` If this was intentional, please add ${error.constructor.name} to` + + " the endpoint's errors list in your Fern Definition."); + yield error.send(res); + } + else { + res.status(500).json("Internal Server Error"); + } + next(error); + } + })); + this.router.get("/pull-request/:repositoryOwner/:repositoryName/:pullRequestNumber", (req, res, next) => __awaiter(this, void 0, void 0, function* () { + try { + yield this.methods.getPullRequest(req, { + send: (responseBody) => __awaiter(this, void 0, void 0, function* () { + res.json(responseBody); + }), + cookie: res.cookie.bind(res), + locals: res.locals, + }, next); + next(); + } + catch (error) { + if (error instanceof errors.FernRegistryError) { + console.warn(`Endpoint 'getPullRequest' unexpectedly threw ${error.constructor.name}.` + + ` If this was intentional, please add ${error.constructor.name} to` + + " the endpoint's errors list in your Fern Definition."); + yield error.send(res); + } + else { + res.status(500).json("Internal Server Error"); + } + next(error); + } + })); + this.router.get("/pull-request", (req, res, next) => __awaiter(this, void 0, void 0, function* () { + try { + yield this.methods.listPullRequests(req, { + send: (responseBody) => __awaiter(this, void 0, void 0, function* () { + res.json(responseBody); + }), + cookie: res.cookie.bind(res), + locals: res.locals, + }, next); + next(); + } + catch (error) { + if (error instanceof errors.FernRegistryError) { + console.warn(`Endpoint 'listPullRequests' unexpectedly threw ${error.constructor.name}.` + + ` If this was intentional, please add ${error.constructor.name} to` + + " the endpoint's errors list in your Fern Definition."); + yield error.send(res); + } + else { + res.status(500).json("Internal Server Error"); + } + next(error); + } + })); + this.router.put("/pull-request", (req, res, next) => __awaiter(this, void 0, void 0, function* () { + try { + yield this.methods.upsertPullRequest(req, { + send: () => __awaiter(this, void 0, void 0, function* () { + res.sendStatus(204); + }), + cookie: res.cookie.bind(res), + locals: res.locals, + }, next); + next(); + } + catch (error) { + if (error instanceof errors.FernRegistryError) { + console.warn(`Endpoint 'upsertPullRequest' unexpectedly threw ${error.constructor.name}.` + + ` If this was intentional, please add ${error.constructor.name} to` + + " the endpoint's errors list in your Fern Definition."); + yield error.send(res); + } + else { + res.status(500).json("Internal Server Error"); + } + next(error); + } + })); + this.router.delete("/pull-request/:repositoryOwner/:repositoryName/:pullRequestNumber", (req, res, next) => __awaiter(this, void 0, void 0, function* () { + try { + yield this.methods.deletePullRequest(req, { + send: () => __awaiter(this, void 0, void 0, function* () { + res.sendStatus(204); + }), + cookie: res.cookie.bind(res), + locals: res.locals, + }, next); + next(); + } + catch (error) { + if (error instanceof errors.FernRegistryError) { + console.warn(`Endpoint 'deletePullRequest' unexpectedly threw ${error.constructor.name}.` + + ` If this was intentional, please add ${error.constructor.name} to` + + " the endpoint's errors list in your Fern Definition."); + yield error.send(res); + } + else { + res.status(500).json("Internal Server Error"); + } + next(error); + } + })); + return this.router; + } +} diff --git a/servers/fdr/src/api/generated/api/resources/git/service/index.d.ts b/servers/fdr/src/api/generated/api/resources/git/service/index.d.ts new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/service/index.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/service/index.js b/servers/fdr/src/api/generated/api/resources/git/service/index.js new file mode 100644 index 0000000000..cb0ff5c3b5 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/service/index.js @@ -0,0 +1 @@ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/BaseRepository.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/BaseRepository.d.ts new file mode 100644 index 0000000000..587e3bf997 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/BaseRepository.d.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../index"; +export interface BaseRepository { + id: FernRegistry.RepositoryId; + name: string; + /** The organization name within Github, e.g. fern-api. */ + owner: string; + /** The full name of the repository, e.g. fern-api/fern. It includes the owner, as well as the name of the repository. */ + fullName: string; + url: string; + /** The Fern organization ID of the repository owner. */ + repositoryOwnerOrganizationId: FernRegistry.OrgId; + defaultBranchChecks: FernRegistry.CheckRun[]; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/BaseRepository.js b/servers/fdr/src/api/generated/api/resources/git/types/BaseRepository.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/BaseRepository.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/CheckRun.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/CheckRun.d.ts new file mode 100644 index 0000000000..31d288c991 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/CheckRun.d.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export interface CheckRun { + checkId: string; + repositoryOwner: string; + repositoryName: string; + ref: string; + name: string; + status: string; + conclusion: string; + checkRunUrl: string; + createdAt: string; + completedAt?: string; + rawCheckRun?: unknown; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/CheckRun.js b/servers/fdr/src/api/generated/api/resources/git/types/CheckRun.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/CheckRun.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/FernConfigRepository.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/FernConfigRepository.d.ts new file mode 100644 index 0000000000..4869476338 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/FernConfigRepository.d.ts @@ -0,0 +1,6 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../index"; +export interface FernConfigRepository extends FernRegistry.BaseRepository { +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/FernConfigRepository.js b/servers/fdr/src/api/generated/api/resources/git/types/FernConfigRepository.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/FernConfigRepository.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/FernRepository.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/FernRepository.d.ts new file mode 100644 index 0000000000..043364a512 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/FernRepository.d.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../index"; +export declare type FernRepository = FernRegistry.FernRepository.Sdk | FernRegistry.FernRepository.Config; +export declare namespace FernRepository { + interface Sdk extends FernRegistry.SdkRepository { + type: "sdk"; + } + interface Config extends FernRegistry.FernConfigRepository { + type: "config"; + } +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/FernRepository.js b/servers/fdr/src/api/generated/api/resources/git/types/FernRepository.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/FernRepository.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/GithubRepositoryId.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/GithubRepositoryId.d.ts new file mode 100644 index 0000000000..b056ee9dbf --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/GithubRepositoryId.d.ts @@ -0,0 +1,6 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export interface GithubRepositoryId { + id: string; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/GithubRepositoryId.js b/servers/fdr/src/api/generated/api/resources/git/types/GithubRepositoryId.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/GithubRepositoryId.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/GithubTeam.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/GithubTeam.d.ts new file mode 100644 index 0000000000..0d8b01d057 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/GithubTeam.d.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export interface GithubTeam { + name: string; + teamId: string; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/GithubTeam.js b/servers/fdr/src/api/generated/api/resources/git/types/GithubTeam.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/GithubTeam.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/GithubUser.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/GithubUser.d.ts new file mode 100644 index 0000000000..847133d3f0 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/GithubUser.d.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export interface GithubUser { + name: string; + email: string; + username: string; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/GithubUser.js b/servers/fdr/src/api/generated/api/resources/git/types/GithubUser.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/GithubUser.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/ListPullRequestsResponse.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/ListPullRequestsResponse.d.ts new file mode 100644 index 0000000000..5012ef57aa --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/ListPullRequestsResponse.d.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../index"; +export interface ListPullRequestsResponse { + pullRequests: FernRegistry.PullRequest[]; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/ListPullRequestsResponse.js b/servers/fdr/src/api/generated/api/resources/git/types/ListPullRequestsResponse.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/ListPullRequestsResponse.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/ListRepositoriesResponse.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/ListRepositoriesResponse.d.ts new file mode 100644 index 0000000000..9d41643f00 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/ListRepositoriesResponse.d.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../index"; +export interface ListRepositoriesResponse { + repositories: FernRegistry.FernRepository[]; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/ListRepositoriesResponse.js b/servers/fdr/src/api/generated/api/resources/git/types/ListRepositoriesResponse.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/ListRepositoriesResponse.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/PullRequest.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/PullRequest.d.ts new file mode 100644 index 0000000000..09d895e3d3 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/PullRequest.d.ts @@ -0,0 +1,19 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../index"; +export interface PullRequest { + pullRequestNumber: number; + repositoryName: string; + repositoryOwner: string; + author: FernRegistry.GithubUser; + reviewers: FernRegistry.PullRequestReviewer[]; + title: string; + url: string; + checks: FernRegistry.CheckRun[]; + state: FernRegistry.PullRequestState; + createdAt: string; + updatedAt?: string; + mergedAt?: string; + closedAt?: string; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/PullRequest.js b/servers/fdr/src/api/generated/api/resources/git/types/PullRequest.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/PullRequest.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/PullRequestNotFound.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestNotFound.d.ts new file mode 100644 index 0000000000..a1abf76d62 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestNotFound.d.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../index"; +export interface PullRequestNotFound extends FernRegistry.RepositoryNotFound { + pullRequestNumber: number; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/PullRequestNotFound.js b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestNotFound.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestNotFound.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/PullRequestReviewer.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestReviewer.d.ts new file mode 100644 index 0000000000..d24b29d79f --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestReviewer.d.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../index"; +export declare type PullRequestReviewer = FernRegistry.PullRequestReviewer.User | FernRegistry.PullRequestReviewer.Team; +export declare namespace PullRequestReviewer { + interface User extends FernRegistry.GithubUser { + type: "user"; + } + interface Team extends FernRegistry.GithubTeam { + type: "team"; + } +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/PullRequestReviewer.js b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestReviewer.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestReviewer.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/PullRequestState.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestState.d.ts new file mode 100644 index 0000000000..44558af59c --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestState.d.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export declare type PullRequestState = "open" | "closed" | "merged"; +export declare const PullRequestState: { + readonly Open: "open"; + readonly Closed: "closed"; + readonly Merged: "merged"; +}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/PullRequestState.js b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestState.js new file mode 100644 index 0000000000..e97c343e38 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/PullRequestState.js @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export const PullRequestState = { + Open: "open", + Closed: "closed", + Merged: "merged", +}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/RepositoryId.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/RepositoryId.d.ts new file mode 100644 index 0000000000..8bc243f1fc --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/RepositoryId.d.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../index"; +export declare type RepositoryId = FernRegistry.RepositoryId.Github; +export declare namespace RepositoryId { + interface Github extends FernRegistry.GithubRepositoryId { + type: "github"; + } +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/RepositoryId.js b/servers/fdr/src/api/generated/api/resources/git/types/RepositoryId.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/RepositoryId.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/RepositoryNotFound.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/RepositoryNotFound.d.ts new file mode 100644 index 0000000000..792ed63e85 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/RepositoryNotFound.d.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export interface RepositoryNotFound { + repositoryName: string; + repositoryOwner: string; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/RepositoryNotFound.js b/servers/fdr/src/api/generated/api/resources/git/types/RepositoryNotFound.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/RepositoryNotFound.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/SdkRepository.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/SdkRepository.d.ts new file mode 100644 index 0000000000..30ea78ec62 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/SdkRepository.d.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +import * as FernRegistry from "../../../index"; +export interface SdkRepository extends FernRegistry.BaseRepository { + sdkLanguage: string; +} diff --git a/servers/fdr/src/api/generated/api/resources/git/types/SdkRepository.js b/servers/fdr/src/api/generated/api/resources/git/types/SdkRepository.js new file mode 100644 index 0000000000..0b46289f5b --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/SdkRepository.js @@ -0,0 +1,4 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ +export {}; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/index.d.ts b/servers/fdr/src/api/generated/api/resources/git/types/index.d.ts new file mode 100644 index 0000000000..9e96b8e7f1 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/index.d.ts @@ -0,0 +1,16 @@ +export * from "./CheckRun"; +export * from "./GithubRepositoryId"; +export * from "./RepositoryId"; +export * from "./BaseRepository"; +export * from "./SdkRepository"; +export * from "./FernConfigRepository"; +export * from "./FernRepository"; +export * from "./GithubUser"; +export * from "./GithubTeam"; +export * from "./PullRequestReviewer"; +export * from "./PullRequestState"; +export * from "./PullRequest"; +export * from "./ListRepositoriesResponse"; +export * from "./ListPullRequestsResponse"; +export * from "./RepositoryNotFound"; +export * from "./PullRequestNotFound"; diff --git a/servers/fdr/src/api/generated/api/resources/git/types/index.js b/servers/fdr/src/api/generated/api/resources/git/types/index.js new file mode 100644 index 0000000000..9e96b8e7f1 --- /dev/null +++ b/servers/fdr/src/api/generated/api/resources/git/types/index.js @@ -0,0 +1,16 @@ +export * from "./CheckRun"; +export * from "./GithubRepositoryId"; +export * from "./RepositoryId"; +export * from "./BaseRepository"; +export * from "./SdkRepository"; +export * from "./FernConfigRepository"; +export * from "./FernRepository"; +export * from "./GithubUser"; +export * from "./GithubTeam"; +export * from "./PullRequestReviewer"; +export * from "./PullRequestState"; +export * from "./PullRequest"; +export * from "./ListRepositoriesResponse"; +export * from "./ListPullRequestsResponse"; +export * from "./RepositoryNotFound"; +export * from "./PullRequestNotFound"; diff --git a/servers/fdr/src/api/generated/api/resources/index.d.ts b/servers/fdr/src/api/generated/api/resources/index.d.ts index 4a0969d3ce..e6bdf1d332 100644 --- a/servers/fdr/src/api/generated/api/resources/index.d.ts +++ b/servers/fdr/src/api/generated/api/resources/index.d.ts @@ -8,6 +8,8 @@ export * as commons from "./commons"; export * from "./commons/types"; export * as diff from "./diff"; export * from "./diff/types"; +export * as git from "./git"; +export * from "./git/types"; export * as sdks from "./sdks"; export * as snippetsFactory from "./snippetsFactory"; export * from "./snippetsFactory/types"; @@ -24,5 +26,6 @@ export * from "./snippets/service/requests"; export * from "./templates/service/requests"; export * from "./tokens/service/requests"; export * from "./commons/errors"; +export * from "./git/errors"; export * from "./snippets/errors"; export * from "./templates/errors"; diff --git a/servers/fdr/src/api/generated/api/resources/index.js b/servers/fdr/src/api/generated/api/resources/index.js index 4a0969d3ce..e6bdf1d332 100644 --- a/servers/fdr/src/api/generated/api/resources/index.js +++ b/servers/fdr/src/api/generated/api/resources/index.js @@ -8,6 +8,8 @@ export * as commons from "./commons"; export * from "./commons/types"; export * as diff from "./diff"; export * from "./diff/types"; +export * as git from "./git"; +export * from "./git/types"; export * as sdks from "./sdks"; export * as snippetsFactory from "./snippetsFactory"; export * from "./snippetsFactory/types"; @@ -24,5 +26,6 @@ export * from "./snippets/service/requests"; export * from "./templates/service/requests"; export * from "./tokens/service/requests"; export * from "./commons/errors"; +export * from "./git/errors"; export * from "./snippets/errors"; export * from "./templates/errors"; diff --git a/servers/fdr/src/api/generated/register.d.ts b/servers/fdr/src/api/generated/register.d.ts index cc0e5262a6..c9a2597a61 100644 --- a/servers/fdr/src/api/generated/register.d.ts +++ b/servers/fdr/src/api/generated/register.d.ts @@ -4,6 +4,7 @@ import express from "express"; import { DiffService } from "./api/resources/diff/service/DiffService"; import { DocsCacheService } from "./api/resources/docsCache/service/DocsCacheService"; +import { GitService } from "./api/resources/git/service/GitService"; import { SnippetsFactoryService } from "./api/resources/snippetsFactory/service/SnippetsFactoryService"; import { SnippetsService } from "./api/resources/snippets/service/SnippetsService"; import { TemplatesService } from "./api/resources/templates/service/TemplatesService"; @@ -21,6 +22,7 @@ import { VersionsService as sdks_VersionsService } from "./api/resources/sdks/re export declare function register(expressApp: express.Express | express.Router, services: { diff: DiffService; docsCache: DocsCacheService; + git: GitService; snippetsFactory: SnippetsFactoryService; snippets: SnippetsService; templates: TemplatesService; diff --git a/servers/fdr/src/api/generated/register.js b/servers/fdr/src/api/generated/register.js index 8d1ff4e7a5..3e624c2fb5 100644 --- a/servers/fdr/src/api/generated/register.js +++ b/servers/fdr/src/api/generated/register.js @@ -13,6 +13,7 @@ export function register(expressApp, services) { expressApp.use("/docs-cache", services.docsCache.toRouter()); expressApp.use("/generators/cli", services.generators.cli.toRouter()); expressApp.use("/generators/versions", services.generators.versions.toRouter()); + expressApp.use("/generators/github", services.git.toRouter()); expressApp.use("/sdks", services.sdks.versions.toRouter()); expressApp.use("/snippets", services.snippetsFactory.toRouter()); expressApp.use("/snippets", services.snippets.toRouter()); diff --git a/servers/fdr/src/controllers/git/getGitController.ts b/servers/fdr/src/controllers/git/getGitController.ts new file mode 100644 index 0000000000..645bea073b --- /dev/null +++ b/servers/fdr/src/controllers/git/getGitController.ts @@ -0,0 +1,97 @@ +import { PullRequestNotFoundError, RepositoryNotFoundError } from "../../api/generated/api"; +import { GitService } from "../../api/generated/api/resources/git/service/GitService"; +import { FdrApplication } from "../../app"; + +export function getGitController(app: FdrApplication): GitService { + async function checkIsFernUser(authorization: string | undefined) { + await app.services.auth.checkUserBelongsToOrg({ + authHeader: authorization, + orgId: "fern", + }); + } + + return new GitService({ + getRepository: async (req, res) => { + await checkIsFernUser(req.headers.authorization); + + const nameAndOwner = { + repositoryName: req.params.repositoryName, + repositoryOwner: req.params.repositoryOwner, + }; + const maybeRepo = await app.dao.git().getRepository(nameAndOwner); + if (!maybeRepo) { + throw new RepositoryNotFoundError(nameAndOwner); + } + + res.send(maybeRepo); + }, + listRepositories: async (req, res) => { + await checkIsFernUser(req.headers.authorization); + + const repos = await app.dao.git().listRepository({ + page: req.query.page, + pageSize: req.query.pageSize, + repositoryName: req.query.repositoryName, + repositoryOwner: req.query.repositoryOwner, + organizationId: req.query.organizationId, + }); + + res.send(repos); + }, + upsertRepository: async (req, res) => { + await checkIsFernUser(req.headers.authorization); + + await app.dao.git().upsertRepository({ repository: req.body }); + }, + deleteRepository: async (req, res) => { + await checkIsFernUser(req.headers.authorization); + + await app.dao.git().deleteRepository({ + repositoryName: req.params.repositoryName, + repositoryOwner: req.params.repositoryOwner, + }); + }, + getPullRequest: async (req, res) => { + await checkIsFernUser(req.headers.authorization); + + const nameAndOwner = { + repositoryName: req.params.repositoryName, + repositoryOwner: req.params.repositoryOwner, + pullRequestNumber: req.params.pullRequestNumber, + }; + const maybePull = await app.dao.git().getPullRequest(nameAndOwner); + if (!maybePull) { + throw new PullRequestNotFoundError(nameAndOwner); + } + + res.send(maybePull); + }, + listPullRequests: async (req, res) => { + await checkIsFernUser(req.headers.authorization); + + const repos = await app.dao.git().listPullRequests({ + page: req.query.page, + pageSize: req.query.pageSize, + repositoryName: req.query.repositoryName, + repositoryOwner: req.query.repositoryOwner, + organizationId: req.query.organizationId, + }); + + res.send(repos); + }, + upsertPullRequest: async (req, res) => { + await checkIsFernUser(req.headers.authorization); + + await app.dao.git().upsertPullRequest({ pullRequest: req.body }); + }, + deletePullRequest: async (req, res) => { + await checkIsFernUser(req.headers.authorization); + + await app.dao.git().deletePullRequest({ + repositoryName: req.params.repositoryName, + repositoryOwner: req.params.repositoryOwner, + pullRequestNumber: req.params.pullRequestNumber, + }); + }, + }); +} diff --git a/servers/fdr/src/db/FdrDao.ts b/servers/fdr/src/db/FdrDao.ts index 95eecd944d..86e4e513ad 100644 --- a/servers/fdr/src/db/FdrDao.ts +++ b/servers/fdr/src/db/FdrDao.ts @@ -5,6 +5,7 @@ import { IndexSegmentDaoImpl, type IndexSegmentDao } from "./docs/IndexSegmentDa import { CliVersionsDaoImpl } from "./generators/CliVersionsDao"; import { GeneratorsDaoImpl } from "./generators/GeneratorDao"; import { GeneratorVersionsDaoImpl } from "./generators/GeneratorVersionsDao"; +import { GitDaoImpl } from "./git/GitDao"; import { DocsRegistrationDao } from "./registrations/DocsRegistrationDao"; import { SdkDao, SdkDaoImpl } from "./sdk/SdkDao"; import { SnippetAPIsDaoImpl, type SnippetAPIsDao } from "./snippetApis/SnippetAPIsDao"; @@ -23,6 +24,7 @@ export class FdrDao { private generatorsDao; private generatorVersionsDao; private cliVersionsDao; + private gitDao; constructor(prisma: PrismaClient) { this.docsV2Dao = new DocsV2DaoImpl(prisma); @@ -36,6 +38,7 @@ export class FdrDao { this.generatorsDao = new GeneratorsDaoImpl(prisma); this.generatorVersionsDao = new GeneratorVersionsDaoImpl(prisma); this.cliVersionsDao = new CliVersionsDaoImpl(prisma); + this.gitDao = new GitDaoImpl(prisma); } public docsV2(): DocsV2Dao { @@ -81,4 +84,8 @@ export class FdrDao { public cliVersions(): CliVersionsDaoImpl { return this.cliVersionsDao; } + + public git(): GitDaoImpl { + return this.gitDao; + } } diff --git a/servers/fdr/src/db/git/GitDao.ts b/servers/fdr/src/db/git/GitDao.ts new file mode 100644 index 0000000000..37a7612651 --- /dev/null +++ b/servers/fdr/src/db/git/GitDao.ts @@ -0,0 +1,335 @@ +import { APIV1Read, FdrAPI } from "@fern-api/fdr-sdk"; +import * as prisma from "@prisma/client"; +import { + CheckRun, + FernRepository, + GithubUser, + ListPullRequestsResponse, + ListRepositoriesResponse, + PullRequest, + PullRequestReviewer, +} from "../../api/generated/api"; +import { readBuffer, writeBuffer } from "../../util"; + +export interface LoadSnippetAPIRequest { + orgId: string; + apiName: string; +} + +export interface LoadSnippetAPIsRequest { + orgIds: string[]; + apiName: string | undefined; +} + +export type SnippetTemplatesByEndpoint = Record< + FdrAPI.EndpointPath, + Record +>; + +export type SnippetTemplatesByEndpointIdentifier = Record; + +export interface GitDao { + getRepository({ + repositoryOwner, + repositoryName, + }: { + repositoryOwner: string; + repositoryName: string; + }): Promise; + + listRepository({ + page, + pageSize, + repositoryOwner, + repositoryName, + organizationId, + }: { + page?: number | undefined; + pageSize?: number | undefined; + repositoryOwner: string | undefined; + repositoryName: string | undefined; + organizationId: string | undefined; + }): Promise; + + upsertRepository({ repository }: { repository: FernRepository }): Promise; + + deleteRepository({ + repositoryOwner, + repositoryName, + }: { + repositoryOwner: string; + repositoryName: string; + }): Promise; + + getPullRequest({ + repositoryOwner, + repositoryName, + pullRequestNumber, + }: { + repositoryOwner: string; + repositoryName: string; + pullRequestNumber: number; + }): Promise; + + listPullRequests({ + page, + pageSize, + repositoryOwner, + repositoryName, + organizationId, + }: { + page?: number | undefined; + pageSize?: number | undefined; + repositoryOwner: string | undefined; + repositoryName: string | undefined; + organizationId: string | undefined; + }): Promise; + + upsertPullRequest({ pullRequest }: { pullRequest: PullRequest }): Promise; + + deletePullRequest({ + repositoryOwner, + repositoryName, + pullRequestNumber, + }: { + repositoryOwner: string; + repositoryName: string; + pullRequestNumber: number; + }): Promise; +} + +export class GitDaoImpl implements GitDao { + constructor(private readonly prisma: prisma.PrismaClient) {} + async listPullRequests({ + page = 0, + pageSize = 20, + repositoryOwner, + repositoryName, + organizationId, + }: { + page?: number | undefined; + pageSize?: number | undefined; + repositoryOwner: string | undefined; + repositoryName: string | undefined; + organizationId: string | undefined; + }): Promise { + const where: Record = {}; + if (repositoryOwner != null) { + where["repositoryOwner"] = repositoryOwner; + } + if (repositoryName != null) { + where["repositoryName"] = repositoryName; + } + if (organizationId != null) { + where["repository"] = { + repositoryOwnerOrganizationId: organizationId, + }; + } + const pull = await this.prisma.pullRequest.findMany({ + skip: page * pageSize, + take: pageSize, + where, + orderBy: { + createdAt: "desc", + }, + }); + + return { pullRequests: pull.map(convertPrismaPullRequest).filter((g): g is PullRequest => g != null) }; + } + + async upsertPullRequest({ pullRequest }: { pullRequest: PullRequest }): Promise { + const data: prisma.PullRequest = { + pullRequestNumber: pullRequest.pullRequestNumber, + repositoryOwner: pullRequest.repositoryOwner, + repositoryName: pullRequest.repositoryName, + author: writeBuffer(pullRequest.author), + reviewers: writeBuffer(pullRequest.reviewers), + checks: writeBuffer(pullRequest.checks), + title: pullRequest.title, + url: pullRequest.url, + state: pullRequest.state, + createdAt: new Date(pullRequest.createdAt), + updatedAt: pullRequest.updatedAt ? new Date(pullRequest.updatedAt) : null, + closedAt: pullRequest.closedAt ? new Date(pullRequest.closedAt) : null, + mergedAt: pullRequest.mergedAt ? new Date(pullRequest.mergedAt) : null, + }; + + await this.prisma.pullRequest.upsert({ + where: { + pullRequestNumber_repositoryOwner_repositoryName: { + pullRequestNumber: pullRequest.pullRequestNumber, + repositoryOwner: pullRequest.repositoryOwner, + repositoryName: pullRequest.repositoryName, + }, + }, + update: data, + create: data, + }); + } + + async deletePullRequest({ + repositoryOwner, + repositoryName, + pullRequestNumber, + }: { + repositoryOwner: string; + repositoryName: string; + pullRequestNumber: number; + }): Promise { + await this.prisma.pullRequest.delete({ + where: { + pullRequestNumber_repositoryOwner_repositoryName: { + pullRequestNumber, + repositoryOwner, + repositoryName, + }, + }, + }); + } + + async getPullRequest({ + repositoryOwner, + repositoryName, + pullRequestNumber, + }: { + repositoryOwner: string; + repositoryName: string; + pullRequestNumber: number; + }): Promise { + return convertPrismaPullRequest( + await this.prisma.pullRequest.findUnique({ + where: { + pullRequestNumber_repositoryOwner_repositoryName: { + pullRequestNumber, + repositoryOwner, + repositoryName, + }, + }, + }), + ); + } + + async upsertRepository({ repository }: { repository: FernRepository }): Promise { + const data: prisma.Repository = { + id: repository.id.id, + name: repository.name, + owner: repository.owner, + fullName: repository.fullName, + url: repository.url, + repositoryOwnerOrganizationId: repository.repositoryOwnerOrganizationId, + defaultBranchChecks: writeBuffer(repository.defaultBranchChecks), + contentType: repository.type, + systemType: repository.id.type, + + rawRepository: writeBuffer(repository), + }; + + await this.prisma.repository.upsert({ + where: { + id: repository.id.id, + }, + update: data, + create: data, + }); + } + + async listRepository({ + page = 0, + pageSize = 20, + repositoryOwner, + repositoryName, + organizationId, + }: { + page?: number | undefined; + pageSize?: number | undefined; + repositoryOwner: string | undefined; + repositoryName: string | undefined; + organizationId: string | undefined; + }): Promise { + const where: Record = {}; + if (repositoryOwner != null) { + where["repositoryOwner"] = repositoryOwner; + } + if (repositoryName != null) { + where["repositoryName"] = repositoryName; + } + if (organizationId != null) { + where["repositoryOwnerOrganizationId"] = organizationId; + } + const repos = await this.prisma.repository.findMany({ + skip: page * pageSize, + take: pageSize, + where, + orderBy: { + fullName: "asc", + }, + }); + + return { repositories: repos.map(convertPrismaRepo).filter((g): g is FernRepository => g != null) }; + } + + async getRepository({ + repositoryOwner, + repositoryName, + }: { + repositoryOwner: string; + repositoryName: string; + }): Promise { + const maybeRepo = await this.prisma.repository.findUnique({ + where: { + owner_name: { + owner: repositoryOwner, + name: repositoryName, + }, + }, + }); + return convertPrismaRepo(maybeRepo); + } + + async deleteRepository({ + repositoryOwner, + repositoryName, + }: { + repositoryOwner: string; + repositoryName: string; + }): Promise { + await this.prisma.repository.delete({ + where: { + owner_name: { + owner: repositoryOwner, + name: repositoryName, + }, + }, + }); + } +} + +function convertPrismaRepo(maybeRepo: prisma.Repository | null): FernRepository | undefined { + if (!maybeRepo) { + return undefined; + } + + return readBuffer(maybeRepo.rawRepository) as FernRepository; +} + +function convertPrismaPullRequest(maybePR: prisma.PullRequest | null): PullRequest | undefined { + if (!maybePR) { + return undefined; + } + + return { + pullRequestNumber: maybePR.pullRequestNumber, + repositoryName: maybePR.repositoryName, + repositoryOwner: maybePR.repositoryOwner, + author: readBuffer(maybePR.author) as GithubUser, + reviewers: readBuffer(maybePR.reviewers) as PullRequestReviewer[], + checks: readBuffer(maybePR.checks) as CheckRun[], + title: maybePR.title, + url: maybePR.url, + state: maybePR.state, + createdAt: maybePR.createdAt.toISOString(), + updatedAt: maybePR.updatedAt?.toISOString(), + closedAt: maybePR.closedAt?.toISOString(), + mergedAt: maybePR.mergedAt?.toISOString(), + }; +} diff --git a/servers/fdr/src/server.ts b/servers/fdr/src/server.ts index 550d7d6544..7b9ac13aff 100644 --- a/servers/fdr/src/server.ts +++ b/servers/fdr/src/server.ts @@ -17,6 +17,7 @@ import { getDocsWriteV2Service } from "./controllers/docs/v2/getDocsWriteV2Servi import { getGeneratorsCliController } from "./controllers/generators/getGeneratorsCliController"; import { getGeneratorsRootController } from "./controllers/generators/getGeneratorsRootController"; import { getGeneratorsVersionsController } from "./controllers/generators/getGeneratorsVersionsController"; +import { getGitController } from "./controllers/git/getGitController"; import { getVersionsService } from "./controllers/sdk/getVersionsService"; import { getSnippetsFactoryService } from "./controllers/snippets/getSnippetsFactoryService"; import { getSnippetsService } from "./controllers/snippets/getSnippetsService"; @@ -124,6 +125,7 @@ async function startServer(): Promise { versions: getGeneratorsVersionsController(app), }, tokens: getTokensService(app), + git: getGitController(app), }); registerBackgroundTasks(app); app.logger.info(`Listening for requests on port ${PORT}`);