101 lines · 3.6 KB · TypeScript
RawDownload
import { Context, Effect } from "effect";import type {  ChangeRequest,  ChangeRequestState,  SourceControlProviderError,  SourceControlProviderInfo,  SourceControlProviderKind,  SourceControlRepositoryCloneUrls,  SourceControlRepositoryVisibility,} from "@t3tools/contracts"; export interface SourceControlProviderContext {  readonly provider: SourceControlProviderInfo;  readonly remoteName: string;  readonly remoteUrl: string;} export interface SourceControlRefSelector {  readonly refName: string;  readonly owner?: string;  readonly repository?: string;} export function parseSourceControlOwnerRef(  headSelector: string,): SourceControlRefSelector | undefined {  const match = /^([^:/\s]+):(.+)$/u.exec(headSelector.trim());  const owner = match?.[1]?.trim();  const refName = match?.[2]?.trim();  return owner && refName ? { owner, refName } : undefined;} export function normalizeSourceBranch(headSelector: string): string {  return parseSourceControlOwnerRef(headSelector)?.refName ?? headSelector.trim();} export function sourceBranch(input: {  readonly headSelector: string;  readonly source?: SourceControlRefSelector;}): string {  return input.source?.refName ?? normalizeSourceBranch(input.headSelector);} export function sourceControlRefFromInput(input: {  readonly headSelector: string;  readonly source?: SourceControlRefSelector;}): SourceControlRefSelector | undefined {  return input.source ?? parseSourceControlOwnerRef(input.headSelector);} export interface SourceControlProviderShape {  readonly kind: SourceControlProviderKind;  readonly listChangeRequests: (input: {    readonly cwd: string;    readonly context?: SourceControlProviderContext;    readonly source?: SourceControlRefSelector;    readonly headSelector: string;    readonly state: ChangeRequestState | "all";    readonly limit?: number;  }) => Effect.Effect<ReadonlyArray<ChangeRequest>, SourceControlProviderError>;  readonly getChangeRequest: (input: {    readonly cwd: string;    readonly context?: SourceControlProviderContext;    readonly reference: string;  }) => Effect.Effect<ChangeRequest, SourceControlProviderError>;  readonly createChangeRequest: (input: {    readonly cwd: string;    readonly context?: SourceControlProviderContext;    readonly source?: SourceControlRefSelector;    readonly target?: SourceControlRefSelector;    readonly baseRefName: string;    readonly headSelector: string;    readonly title: string;    readonly bodyFile: string;  }) => Effect.Effect<void, SourceControlProviderError>;  readonly getRepositoryCloneUrls: (input: {    readonly cwd: string;    readonly context?: SourceControlProviderContext;    readonly repository: string;  }) => Effect.Effect<SourceControlRepositoryCloneUrls, SourceControlProviderError>;  readonly createRepository: (input: {    readonly cwd: string;    readonly repository: string;    readonly visibility: SourceControlRepositoryVisibility;  }) => Effect.Effect<SourceControlRepositoryCloneUrls, SourceControlProviderError>;  readonly getDefaultBranch: (input: {    readonly cwd: string;    readonly context?: SourceControlProviderContext;  }) => Effect.Effect<string | null, SourceControlProviderError>;  readonly checkoutChangeRequest: (input: {    readonly cwd: string;    readonly context?: SourceControlProviderContext;    readonly reference: string;    readonly force?: boolean;  }) => Effect.Effect<void, SourceControlProviderError>;} export class SourceControlProvider extends Context.Service<  SourceControlProvider,  SourceControlProviderShape>()("t3/source-control/SourceControlProvider") {}