实现一个Git提供者很简单。它是一个实现了GitProvider
接口的类或对象。
export interface GitProvider {onPut: (key: string, value: string) => Promise<void>onDelete: (key: string) => Promise<void>}
onPut
用于将内容保存到Git。每当在CMS中保存一个值时都会调用它。
onDelete
用于从Git中删除内容。每当在CMS中删除一个值时都会调用它。
以下是GitHub Git提供者的源代码。它是如何实现GitProvider
接口的一个很好的例子。
import { Octokit } from '@octokit/rest'import { Base64 } from 'js-base64'import type { GitProvider } from '@tinacms/graphql'type OctokitOptions = ConstructorParameters<typeof Octokit>[0]export interface GitHubProviderOptions {owner: stringrepo: stringtoken: stringbranch: stringcommitMessage?: stringrootPath?: stringoctokitOptions?: OctokitOptions}export class MyGitHubProvider implements GitProvider {octokit: Octokitowner: stringrepo: stringbranch: stringrootPath?: stringcommitMessage?: stringconstructor(args: GitHubProviderOptions) {this.owner = args.ownerthis.repo = args.repothis.branch = args.branchthis.commitMessage = args.commitMessagethis.rootPath = args.rootPaththis.octokit = new Octokit({auth: args.token,...(args.octokitOptions || {}),})}async onPut(key: string, value: string) {let shaconst keyWithPath = this.rootPath ? `${this.rootPath}/${key}` : keytry {const {// @ts-ignoredata: { sha: existingSha },} = await this.octokit.repos.getContent({owner: this.owner,repo: this.repo,path: keyWithPath,ref: this.branch,})sha = existingSha} catch (e) {}await this.octokit.repos.createOrUpdateFileContents({owner: this.owner,repo: this.repo,path: keyWithPath,message: this.commitMessage || 'Edited with TinaCMS',content: Base64.encode(value),branch: this.branch,sha,})}async onDelete(key: string) {let shaconst keyWithPath = this.rootPath ? `${this.rootPath}/${key}` : keytry {const {// @ts-ignoredata: { sha: existingSha },} = await this.octokit.repos.getContent({owner: this.owner,repo: this.repo,path: keyWithPath,ref: this.branch,})sha = existingSha} catch (e) {}if (sha) {await this.octokit.repos.deleteFile({owner: this.owner,repo: this.repo,path: keyWithPath,message: this.commitMessage || 'Edited with TinaCMS',branch: this.branch,sha,})} else {throw new Error(`无法在仓库${this.owner}/${this.repo}中找到文件${keyWithPath}`)}}}
现在可以将其用作createDatabase
函数的一个属性。
database.ts,js:
import { createDatabase, createLocalDatabase } from '@tinacms/datalayer'import { MyGitHubProvider } from './my-git-provider'//...export default isLocal ? createLocalDatabase() ? createDatabase({gitProvider: new MyGitHubProvider({//... 选项}),// ...})