# Type contracts for NATS-triggered pipelines
#
# A NatsPipeline binds a NATS subject (with optional wildcards) to an
# ordered list of steps.  `pipeline_type` must be "nats".
#
# Validate:
#   nickel export --format json --import-path site/nickel site/config/pipelines.ncl

let C = import "pipelines/contracts.ncl" in

let OneOf = fun allowed =>
  std.contract.from_predicate (fun v => std.array.elem v allowed)
in

let NonEmpty = std.contract.from_predicate (fun s =>
  std.is_string s && std.string.length s > 0)
in

{
  NatsPipeline = {
    pipeline_type | OneOf ["nats"]
      | doc "Discriminator — must be \"nats\" for this contract.",

    name | String | NonEmpty
      | doc "Human-readable identifier used in log output.",

    subject | String | NonEmpty
      | doc "Raw NATS subject (e.g. 'evol.website.prod.content.published').
             Wildcards (* and >) are valid per NATS subject syntax.",

    steps | Array C.PipelineStep
      | doc "Ordered actions executed sequentially on each message."
      | default = [],
  },

  NatsPipelinesFile = {
    pipelines | Array NatsPipeline
      | doc "List of NATS-triggered pipelines defined in this file."
      | default = [],
  },
}
