Shape API reference#
Compiling a shape#
TS—Shape(spec, options?) returns a validator function that also carries
methods. A bad spec (Min('x'), Pick of an unknown property) throws here, at
compile time. The validator mutates the value it is given to inject
defaults.
const { Shape } = require('shape')
const shape = Shape(spec, options)
Go—compilation returns a *Schema.
s, err := shape.Shape(spec)
s := shape.MustShape(spec) // panics on a bad spec
s, err := shape.ShapeWith(spec, options)
s := shape.MustShapeWith(spec, options)
Validating#
| TS | Go | Result |
|---|---|---|
shape(value, ctx?) |
s.Validate(value) / s.ValidateCtx(value, ctx) |
produced value (defaults injected). TS throws on failure; Go returns an error. |
shape.match(value, ctx?) |
s.Match(value) |
boolean—no mutation, no error building. |
shape.valid(value, ctx?) |
s.Valid(value) |
boolean—alias-style validity check; in TS a type guard, and a ctx you pass collects the errors in ctx.err. |
shape.error(value, ctx?) |
s.Error(value) |
list of issues—TS ErrDesc[], Go []FieldError—empty/nil when valid. |
shape['~standard'].validate(value) |
s.Standard().Validate(value) |
{ value } or { issues }, never throws—see Standard Schema. |
Introspection#
| TS | Go | Result |
|---|---|---|
shape.spec() |
s.Spec() |
JSON-friendly structural description. |
shape.node() |
s.Node() |
the compiled root node. |
shape.stringify(...) |
s.String() |
DSL-ish string rendering. |
shape.jsonify() |
n/a | JSON form used by stringify. |
shape.toString() |
n/a | [Shape <name> <stringify>], also used by util.inspect. |
shape.json() |
s.JSON() |
the declarative JSON of the shape, which build reads back—see Serialize a shape. |
build(json) |
Build(json) |
the shape that JSON describes. |
shape.jsonSchema() |
s.JSONSchema() |
a JSON Schema (draft 2020-12) for the values accepted—see the how-to. |
fromJsonSchema(schema) |
FromJSONSchema(schema) |
a spec built from a JSON Schema, to compile with Shape—see the how-to. |
Shape.isShape(v) |
shape.IsShape(v) |
is v a compiled shape? |
The validation context#
Pass a context object to influence a run and to collect errors.
TS Context (all optional):
| Field | Meaning |
|---|---|
err |
an array to collect errors into (instead of throwing), or false to suppress—the run then returns the value as far as it got |
log(point, state) |
traversal callback for debugging; point is so/eo (start/end object), sa/ea (start/end array) or kv (a value) |
skip |
{ depth, keys }—treat the nodes at a depth (a number or a list; the root is 0) or the top-level properties named in keys as Skip: optional, no default injected |
prefix / suffix |
text wrapped around a thrown error message, as prefix: message suffix |
| (your own) | any extra keys are visible to custom validators via state.ctx |
Go *shape.Context: Err []FieldError, Custom map[string]any, plus
internal fields; pass it to ValidateCtx.
Options#
Passed as the second argument to Shape/ShapeWith. Defaults shown.
| Concept | TS | Go | Default |
|---|---|---|---|
| Name (for error prefixes) | name |
—(uses MakeArgu name) |
random G$…—a name not starting with G$ is prepended to thrown messages as name: … |
Key expressions ("x: Min(1)") |
keyexpr.active |
KeyExpr.Disable |
on |
| Meta sidecar keys | meta.active, meta.suffix |
Meta.Active, Meta.Suffix |
off, $$ |
| Value expressions | valexpr.active, valexpr.keymark |
ValExpr.Active, ValExpr.KeyMark |
off, $$ |
// TS
Shape(spec, {
name: 'options',
keyexpr: { active: true },
meta: { active: false, suffix: '$$' },
valexpr: { active: false, keymark: '$$' },
})
// Go
shape.ShapeWith(spec, shape.ShapeOptions{
KeyExpr: shape.KeyExprOptions{Disable: false},
Meta: shape.MetaOptions{Active: false, Suffix: "$$"},
ValExpr: shape.ValExprOptions{Active: false, KeyMark: "$$"},
})
String DSL helpers#
| TS | Go |
|---|---|
expr(source) |
shape.Expr(source) / shape.MustExpr(source) |
build(value, options?) |
shape.Build(value) |
expr compiles one expression string into a node, to compile with Shape;
build walks a JSON structure and compiles it, reading every string as an
expression, the example of a key expression as a value, and a $$ key as an
expression applied to the object that holds it, with its $$0, $$1, ...
sidecars as arguments. It returns the compiled shape. This is the dialect
json() writes, so build(shape.json()) is the shape again. See
Use the string DSL and
Serialize a shape.
Argument validation#
MakeArgu(name) builds a positional-argument validator, Argu(args, whence?, spec), which validates an arguments array (or arguments) against spec—an
object whose properties are the positions, in order—and returns the produced
object; whence names the call site in errors. Argu(whence, spec) without
args returns a reusable (args) => object. See
Go API: Argu and the
arrays how-to.
Other TS exports#
Every builder is also a property of Shape (Shape.Min), and has a G-prefixed
alias (GMin) for when the plain name clashes. The remaining exports are
utilities used by the builders and the string DSL:
| Export | Purpose |
|---|---|
nodize(value, depth?, meta?) |
normalise a spec value into a node; an existing node is returned as is |
buildize(self?, shape?) |
the node a builder works on: nodize(shape) merged over the chained node self, with the chainable builder methods attached |
makeErr(state, text?, why?, use?) |
build an ErrDesc for update.err from inside a custom validator; $VALUE/$PATH in text are expanded, why defaults to check |
stringify(value, dequote?, expand?, ignore?, replacer?) |
the DSL-ish rendering used in messages and shape.stringify; dequote drops the quotes around a string, ignore.key/ignore.val list strings or regular expressions to omit |
truncate(str, len?) |
cut str to len characters (default 30) with a trailing ... |
Shape.jsonSchema(node) |
the JSON Schema for a compiled node; shape.jsonSchema() is the shape's own |
G$(node) |
mark a plain object as an already-built node |
Shape.isShape(v) |
is v a compiled shape? |