Here's a question that'll probably out me as someone who doesn't understand the concept: Is is possible to spec a "closed" map, one that has some number of required and optional keys, but no other keys?
I'm trying to translate the JSON schema concept of
additionalProperties = false
probably s/map-of #{...}
will try that.
nope
I guess that's a spec2 thing?
This will be supported in spec2, malli already supports it
you could also try to do this using a predicate, (s/and ... (fn [map] check-the-keys))
š” Thank you!
the important part of our perspective in spec 2 is that we think that "closed" should be a property of the check, not a property of the spec
good point!
@alexmiller Are you considering doing some journal updates again in the future? I for one really enjoyed them.
I think I see. So, I have an API that's dumb as a bag of rocks and will spit out any blob of json that includes anything other than, say, five keys. There are many combinations of those that are allowed, but it will throw a hissy fit if a key isn't one of those five.
Only one of them is required and the rest optional, which all fit nicely into (s/keys :req-un [,,,] :opt-un [,,,])
until I did a typo in one of the opt-uns.
passes the spec; fails in life.
> should be a property of theĀ check, not a property of theĀ spec (FWIW!) while one can see the value of this, it's also hard to see how this would not conflict with DRY. If one tried to DRY out n identical calls as a reusable "thing", what would be that thing be? It seems to me that inherently, the 'thing' would effectively become a spec (whether it's an actual spec, or a de-facto spec: e.g. a defn)
makes sense to me
Actually, this was a bit too easy. Must have missed something?
(s/def ::environments #{:int :test :stage :live})
(s/def ::valid-top-level-keys #{:name :description :values})
(s/def ::name string?)
(s/def ::description string?)
(s/def ::values (s/map-of ::environments string?))
(s/def ::config (s/and
(s/keys :req-un [::name]
:opt-un [::values ::description])
(s/map-of ::valid-top-level-keys any?)))
(s/def ::release-config (s/coll-of ::config))
(comment
(s/valid? ::release-config [{:name "something" :description "some description"}])
(s/valid? ::release-config [{:name "something" :desciption "some description with typo"}])
)
I was already doing something similar with the :environments spec.