reference.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. export * as ConfigReference from "./reference"
  2. import { Schema } from "effect"
  3. export class Git extends Schema.Class<Git>("ConfigV2.Reference.Git")({
  4. repository: Schema.String,
  5. branch: Schema.String.pipe(Schema.optional),
  6. }) {}
  7. export class Local extends Schema.Class<Local>("ConfigV2.Reference.Local")({
  8. path: Schema.String,
  9. }) {}
  10. export const Entry = Schema.Union([Schema.String, Git, Local])
  11. export type Entry = typeof Entry.Type
  12. export const Info = Schema.Record(Schema.String, Entry)
  13. export type Info = typeof Info.Type
  14. export type NormalizedEntry =
  15. | { readonly kind: "local"; readonly path: string }
  16. | { readonly kind: "git"; readonly repository: string; readonly branch?: string }
  17. | { readonly kind: "invalid"; readonly message: string }
  18. export type NormalizedInfo = Record<string, NormalizedEntry>
  19. export function validateAlias(name: string) {
  20. if (name.length === 0) return "Reference alias must not be empty"
  21. if (/[\/\s`,]/.test(name)) return "Reference alias must not contain /, whitespace, comma, or backtick"
  22. }
  23. export function normalizeEntry(entry: Entry): NormalizedEntry {
  24. if (typeof entry === "string") {
  25. if (entry.startsWith(".") || entry.startsWith("/") || entry.startsWith("~")) return { kind: "local", path: entry }
  26. return { kind: "git", repository: entry }
  27. }
  28. if ("path" in entry) return { kind: "local", path: entry.path }
  29. return { kind: "git", repository: entry.repository, branch: entry.branch }
  30. }
  31. export function normalize(info: Info): NormalizedInfo {
  32. return Object.fromEntries(
  33. Object.entries(info).map(([name, entry]) => {
  34. const message = validateAlias(name)
  35. return [name, message ? { kind: "invalid" as const, message } : normalizeEntry(entry)]
  36. }),
  37. )
  38. }