schema.ts 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { Schema } from "effect"
  2. export const RequestSnapshotSchema = Schema.Struct({
  3. method: Schema.String,
  4. url: Schema.String,
  5. headers: Schema.Record(Schema.String, Schema.String),
  6. body: Schema.String,
  7. })
  8. export type RequestSnapshot = Schema.Schema.Type<typeof RequestSnapshotSchema>
  9. export const ResponseSnapshotSchema = Schema.Struct({
  10. status: Schema.Number,
  11. headers: Schema.Record(Schema.String, Schema.String),
  12. body: Schema.String,
  13. bodyEncoding: Schema.optional(Schema.Literals(["text", "base64"])),
  14. })
  15. export type ResponseSnapshot = Schema.Schema.Type<typeof ResponseSnapshotSchema>
  16. export const CassetteMetadataSchema = Schema.Record(Schema.String, Schema.Unknown)
  17. export type CassetteMetadata = Schema.Schema.Type<typeof CassetteMetadataSchema>
  18. export const HttpInteractionSchema = Schema.Struct({
  19. transport: Schema.tag("http"),
  20. request: RequestSnapshotSchema,
  21. response: ResponseSnapshotSchema,
  22. })
  23. export type HttpInteraction = Schema.Schema.Type<typeof HttpInteractionSchema>
  24. export const WebSocketFrameSchema = Schema.Union([
  25. Schema.Struct({ kind: Schema.tag("text"), body: Schema.String }),
  26. Schema.Struct({ kind: Schema.tag("binary"), body: Schema.String, bodyEncoding: Schema.Literal("base64") }),
  27. ])
  28. export type WebSocketFrame = Schema.Schema.Type<typeof WebSocketFrameSchema>
  29. export const WebSocketInteractionSchema = Schema.Struct({
  30. transport: Schema.tag("websocket"),
  31. open: Schema.Struct({
  32. url: Schema.String,
  33. headers: Schema.Record(Schema.String, Schema.String),
  34. }),
  35. client: Schema.Array(WebSocketFrameSchema),
  36. server: Schema.Array(WebSocketFrameSchema),
  37. })
  38. export type WebSocketInteraction = Schema.Schema.Type<typeof WebSocketInteractionSchema>
  39. export const InteractionSchema = Schema.Union([HttpInteractionSchema, WebSocketInteractionSchema]).pipe(
  40. Schema.toTaggedUnion("transport"),
  41. )
  42. export type Interaction = Schema.Schema.Type<typeof InteractionSchema>
  43. export const isHttpInteraction = InteractionSchema.guards.http
  44. export const isWebSocketInteraction = InteractionSchema.guards.websocket
  45. export const httpInteractions = (cassette: Cassette) => cassette.interactions.filter(isHttpInteraction)
  46. export const webSocketInteractions = (cassette: Cassette) => cassette.interactions.filter(isWebSocketInteraction)
  47. export const CassetteSchema = Schema.Struct({
  48. version: Schema.Literal(1),
  49. metadata: Schema.optional(CassetteMetadataSchema),
  50. interactions: Schema.Array(InteractionSchema),
  51. })
  52. export type Cassette = Schema.Schema.Type<typeof CassetteSchema>
  53. export const decodeCassette = Schema.decodeUnknownSync(CassetteSchema)
  54. export const encodeCassette = Schema.encodeSync(CassetteSchema)