| 1 | import * as Context from "effect/Context"; |
| 2 | import * as Effect from "effect/Effect"; |
| 3 | import * as Layer from "effect/Layer"; |
| 4 | import type { SourceControlProviderKind } from "@t3tools/contracts"; |
| 5 | |
| 6 | import * as BuiltInDrivers from "../sourceControl/builtInDrivers.ts"; |
| 7 | import type { PullRequestProviderApi } from "@t3tools/source-control-core/server/PullRequestProvider"; |
| 8 | |
| 9 | export class PullRequestProviderRegistry extends Context.Service< |
| 10 | PullRequestProviderRegistry, |
| 11 | { |
| 12 | /** Null for a host with no implementation, which the service reports as unsupported. */ |
| 13 | readonly get: (kind: SourceControlProviderKind) => PullRequestProviderApi | null; |
| 14 | readonly kinds: ReadonlyArray<SourceControlProviderKind>; |
| 15 | } |
| 16 | >()("t3/pullRequest/PullRequestProviderRegistry") {} |
| 17 | |
| 18 | /** Exported for tests, which stand a registry up from providers they supply themselves. */ |
| 19 | export function fromProviders( |
| 20 | providers: ReadonlyArray<PullRequestProviderApi>, |
| 21 | ): PullRequestProviderRegistry["Service"] { |
| 22 | const byKind = new Map(providers.map((provider) => [provider.kind, provider])); |
| 23 | return { |
| 24 | get: (kind) => byKind.get(kind) ?? null, |
| 25 | kinds: providers.map((provider) => provider.kind), |
| 26 | }; |
| 27 | } |
| 28 | |
| 29 | /** |
| 30 | * The hosts this build can read change requests from. A host with no entry here still shows up |
| 31 | * in the provider list as unimplemented, so its projects are explained rather than missing. |
| 32 | * |
| 33 | * @public Service construction is part of the canonical Effect module API. |
| 34 | */ |
| 35 | export const make = Effect.gen(function* () { |
| 36 | const drivers = yield* Effect.forEach(BuiltInDrivers.BUILT_IN_SOURCE_CONTROL_DRIVERS, (driver) => |
| 37 | driver.make.pipe(Effect.map((instance) => instance.pullRequests)), |
| 38 | ); |
| 39 | return fromProviders( |
| 40 | drivers.filter((provider): provider is PullRequestProviderApi => provider !== null), |
| 41 | ); |
| 42 | }); |
| 43 | |
| 44 | export const layer = Layer.effect(PullRequestProviderRegistry, make).pipe( |
| 45 | Layer.provide(BuiltInDrivers.layer), |
| 46 | ); |