Skip to content

Commit

Permalink
add gitlab provider
Browse files Browse the repository at this point in the history
  • Loading branch information
vincentli77 committed Oct 7, 2023
1 parent be85622 commit 3be1d15
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/api/repository.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface LocalProviderConfig {
}

interface RemoteProviderConfig {
type: 'github' /* | 'gitlab' */
type: 'github' | 'gitlab'
repositories: string[]
token?: string
}
Expand Down
6 changes: 5 additions & 1 deletion src/api/repository.provider.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { GithubProvider } from '../provider/github.provider'
import { GitlabProvider } from '../provider/gitlab.provider'
import { LocalProvider } from '../provider/local.provider'
import { FileSystemManager } from '../utils/fileSystem.utils'
import { ProviderConfig } from './repository.controller'

export type Provider = LocalProvider | GithubProvider
export type Provider = LocalProvider | GithubProvider | GitlabProvider

export class RepositoryProvider {
private provider!: Provider
Expand All @@ -19,6 +20,9 @@ export class RepositoryProvider {
case 'github':
this.provider = new GithubProvider(config.repositories, config.token)
break
case 'gitlab':
this.provider = new GitlabProvider(config.repositories, config.token)
break
default:
break
}
Expand Down
5 changes: 3 additions & 2 deletions src/api/repository.strategy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ErrorManager } from '../utils/error.utils'
import { ProviderConfig } from './repository.controller'

const knownRepositories = ['github.com'] as const
const knownRepositories = ['github.com', 'gitlab.com'] as const

export interface ProviderStrategy {
isMatch(docLocation: string): boolean
Expand Down Expand Up @@ -31,9 +31,10 @@ export class RepositoryProviderStrategy implements ProviderStrategy {
return { type: this.extractRepositoryName(domain), repositories: [docLocation] }
}

private extractRepositoryName(domain: string): 'github' | never {
private extractRepositoryName(domain: string): 'github' | 'gitlab' | never {
const type = domain.split('.')[0]
if (type === 'github') return type
if (type === 'gitlab') return type

ErrorManager.outputError(`Unrecognized repository type: ${type}`)
throw new Error(`Unrecognized repository type: ${type}`)
Expand Down
73 changes: 73 additions & 0 deletions src/provider/gitlab.provider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Documentation } from '../association.manager'
import { FileSystemManager } from '../utils/fileSystem.utils'
import { ReplacerTextProvider } from '../utils/replacerText.utils'

interface GitlabResponse {
type: string
name: string
path: string
}

export class GitlabProvider {
private baseUrl = 'https://gitlab.com/api/v4'
private fileSystem
private repository
private transformImageURL

constructor(repository: string[], token?: string) {
this.repository = this.getProjectId(repository)
this.fileSystem = new FileSystemManager()
this.transformImageURL = new ReplacerTextProvider(repository[0], token)
}

public async getDocumentations(): Promise<Documentation[]> {
const documentations: Documentation[] = []
const data = await this.getRepoContent(
`/projects/${this.repository.id.replace('/', '%2F')}/repository/tree?ref=main&recursive=true`
)

await this.fetchDocumentation(data, documentations)
return documentations
}

private fetchDocumentation = async (
repositoryContents: GitlabResponse[],
documentations: Documentation[]
): Promise<void> => {
for (const repositoryContent of repositoryContents) {
if (
repositoryContent.type === 'blob' &&
this.fileSystem.isFileOfInterest(repositoryContent.name)
) {
const documentation = await this.getFile(repositoryContent)
documentation.content = this.transformImageURL.replacer(documentation.content)
documentations.push(documentation)
}
}
}

public async getRepoContent(route: string) {
const response = await fetch(this.baseUrl + route)
return await response.json()
}

public async getFile(file: GitlabResponse): Promise<Documentation> {
const projectIdEncoded = encodeURIComponent(this.repository.id)
const filePathEncoded = encodeURIComponent(file.path)
const url = `https://gitlab.com/api/v4/projects/${projectIdEncoded}/repository/files/${filePathEncoded}/raw`
const response = await fetch(url)
const content = await response.text()

return {
type: this.fileSystem.getExtension(file.name)!,

Check warning on line 62 in src/provider/gitlab.provider.ts

View workflow job for this annotation

GitHub Actions / Running tests...

Forbidden non-null assertion

Check warning on line 62 in src/provider/gitlab.provider.ts

View workflow job for this annotation

GitHub Actions / Running tests...

Forbidden non-null assertion
name: file.name,
content: content,
path: `https://gitlab.com/${this.repository.id}/-/blob/main/${file.path}`,
}
}

public getProjectId(repository: string[]) {
const urlParts = repository[0].split('/')
return { id: `${urlParts[3]}/${urlParts[4]}`, token: repository[1] }
}
}

0 comments on commit 3be1d15

Please sign in to comment.