location.ts 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. import { Context, Effect, Layer, Schema } from "effect"
  2. import { Project } from "./project"
  3. import { AbsolutePath } from "./schema"
  4. import { WorkspaceV2 } from "./workspace"
  5. export * as Location from "./location"
  6. export class Ref extends Schema.Class<Ref>("Location.Ref")({
  7. directory: AbsolutePath,
  8. workspaceID: Schema.optional(WorkspaceV2.ID).pipe(Schema.withConstructorDefault(Effect.succeed(undefined))),
  9. }) {}
  10. export class Info extends Schema.Class<Info>("Location.Info")({
  11. directory: AbsolutePath,
  12. workspaceID: WorkspaceV2.ID.pipe(Schema.optional),
  13. project: Schema.Struct({
  14. id: Project.ID,
  15. directory: AbsolutePath,
  16. }),
  17. }) {}
  18. export interface Interface extends Info {
  19. readonly vcs?: Project.Vcs
  20. }
  21. export function response<S extends Schema.Top>(data: S) {
  22. return Schema.Struct({ location: Info, data })
  23. }
  24. export class Service extends Context.Service<Service, Interface>()("@opencode/Location") {}
  25. export const layer = (ref: Ref) =>
  26. Layer.effect(
  27. Service,
  28. Effect.gen(function* () {
  29. const project = yield* Project.Service
  30. const resolved = yield* project.resolve(ref.directory)
  31. return Service.of({
  32. directory: ref.directory,
  33. workspaceID: ref.workspaceID,
  34. project: { id: resolved.id, directory: resolved.directory },
  35. vcs: resolved.vcs,
  36. })
  37. }),
  38. )