intro
Directives
Directives are small functions for accessing and manipulating data, composable in pipelines to achieve more complex transformations. Their primary use case is for mapping arguments and results in resolver configurations.
They have a minimal set of options and can access the values in the currentQuery context.
type Directive = [
function: string,
{
[key: string]: string;
}
];
set
This simple directive returns the provided value as a string. It's great for directly setting a literal value, or for
starting off a directive pipeline with a value available in the currentQuery syntax.
Options
-
valuerequiredThe string that should be set.
get
In its simplest form, get will get the value at path and pass it into the directive pipeline. Most directives
pipelines start with get and the mapping shorthand is itself a get operation. If the value at path evaluates to
undefined the value of $previousDirective, if any, will be sent on. If a defaultValue is set, this will be passed on
instead.
get can also take an array of string paths. In this case it will return multiple values. This can be useful for
further directives, like format or zipAndMerge.
Finally, get supports tokens, which are evaluated against the context, in the path. This allows for extended logic,
like using a $loop.key to maintain a reference to the same array item in a loop. A path with a token looks like
this: $finalResolver[{$loop.key}].params[{$args.someParamName}]. See the examples below for more.
Under the hood, get uses jsonpath-plus so you have a fair amount
of power getting values into your directive.
Options
-
path(string | string[], required) This is property path to get from the context. -
defaultValue(any, optional) A value to use if the path returnsundefined -
passThroughOnUndefined(boolean, optional) Ifpathreturnsundefined, and nodefaultValueis set, return the previous value. Defaults totrue. -
flatten(boolean, optional) When your path returns a multidimensional array, flatten it to a single dimension. For example, if the path$args.colors[*]returned[['Red'], ['Blue']]settingflattenwould instead return['Red', 'Blue']to the directive pipeline. -
wrap(boolean, optional) Whether to wrap your results in an array. Default isfalse, so only actual array results will return an array, otherwise you'll get the primitive value as-is. For example, if the path$args.pagecontained the number5, settingwrapwould instead return[5]to the directive pipeline.
Example
In the example below, input.title would be set to the value of either the takeshapeUpdate or takeshapeCreate step,
if one is undefined and the other has a value. If both have a value, input.title will be the value of
takeshapeCreate since that step is run later in the pipeline.
If we disabled passThroughOnUndefined and the takeshapeCreate step returned undefined our result would be
undefined, not the value of takeshapeUpdate.
{
"args": {
"ops": [
{
"path": "input.title",
"mapping": [
["get", { "path": "$resolvers.takeshapeUpdate.result.name" }],
["get", { "path": "$resolvers.takeshapeCreate.result.name" }]
]
},
{
"path": "input.vendor",
"mapping": "get", { "path": "$resolvers.takeshapeCreate.result.vendor", "defaultValue": "Kirkland" }
}
]
}
}
And in this example, we're getting multiple values and passing them to the format directive. Each of the values
returns a string.
{
"results": {
"ops": [
{
"path": "name",
"mapping": [
["get", { "path": ["$resolvers.takeshapeUpdate.result.name", "$args.nameSuffix"] }],
["format", { "template": "%s, %s" }]
]
}
]
}
}
In the following example, we'll use path tokens to maintain the same index in a source array while populating a results array.
{
"results": {
"ops": [
{
"path": "items",
"mapping": [
["get", { "path": "$finalResolver.length" }],
["array", {}]
]
},
{
"path": "items[*].newParams",
"mapping": "get", { "path": "$finalResolver[{$loop.key}].params" }
}
]
}
}
trim
Removes matching leading and trailing characters from a string.
Options
**chars** Defines the leading and trailing characters to remove from a string. For example, if you want to remove quotes from a string. Defaults to remove whitespace characters.
toUpper
Converts the string, as a whole, to upper case.
prepend
Prepends the text provided in options to the string.
Options
**text** required The text you'd like to prepend to the string
expressionEval
Use the expression-eval module and our own custom context.
Options
expression****required
Context
- The same
currentQuerycontext from above, plus - A number of callable functions
- ~180 functions exported from
lodash/fp formatexported fromutilmapDeepa custom function for deep mappings, for example, all[foo.name](http://foo.name)object paths at any depth in an array of objectsnewObjectprovides a new object, given the limitations of the expression evaluation approachgetImageUrlfrom@takeshape/routing
- ~180 functions exported from
zipAndMerge
zipWith from lodash, using merge also from lodash to deeply merge objects at the same indexes in multiple arrays.
This will operate on whatever was output from the directive at the previous step, but is a noop if that value is not an array.
replace
Replaces patterns or a regexp in a string provided by the $previousDirective.
replace from lodash.
Options
replacement(string, required)pattern(string, required if no regexp)regexp(string, required if no pattern)regexpFlag(string, optional)
filter
Filters any string, array or object passed in from the $previousDirective.
filter from lodash.
Options
-
predicate(string | Object | Array, required if no expression)- A
lodash.filteriteratee predicates.
- A
-
expression(string, required if no predicate)-
An
expressionEvalexpression as described above. You have access to the full query context, and get the additional context variables$value,$indexand$collectionfor comparison. For example,$value.species !== 'Human'would compare thespeciesproperty in an object to the literal stringHuman. -
If you happen to be using a
stringas your input, the iteratee context variables will be$char,$indexand$string.
-
format
A printf-like format utility, using
util.formatWithOptions from the
Node.js standard library.
If the $previousDirective provides an array, that array will be spread onto the params of util.formatWithOptions. If
a non-array value is found it will be supplied as the single param for formatting.
Options
-
template(string, required)- A string with replacement specifiers. Common specifiers are
%sfor a string, and%dfor a number. A full list can be found here.
- A string with replacement specifiers. Common specifiers are
-
options(Object, optional)- Options for
util.inspect. Full list here.
- Options for
array
A utility for initializing an array. The array directive takes a single option, initial which will be the value
passed to the
Array constructor. If no
initial option is set, the results of the $previousDirective are used instead.
If the number passed is a number, then an array of that length will be initialized. Any other value will be set as the sole element of the new array.
If both initial and $previousDirective are undefined, an empty array will be returned.
Options
-
initial(any, optional)- An optional value to set as the initial value in the Array constructor.
Examples
One of the most useful applications of this directive is to initialize ops values of a length equivalent to some other
iterable value in your context. In this example, if your $finalResolver was an array of 10 items, your results item
path will be initialized with an empty array of length 10.
{
"results": {
"ops": [
{
"path": "items",
"mapping": [
["get", { "path": "$finalResolver.length" }],
["array", {}]
]
},
{
"path": "items[*].newParams",
"mapping": "get", { "path": "$finalResolver[{$loop.key}].params" }
}
]
}
}
md5
Compute the md5 hash of $previousDirective or value.
Options
value(string, optional)
Examples
In this example we create an composite id. First we get several properties of the source object, we then concatenate them and finally we hash the result to create a shorter id.
{
"id": {
"@tag": "id",
"@resolver": {
"name": "util:noop",
"results": {
"ops": [
{
"path": "$",
"mapping": [
["get", { "path": ["$source.company", "$source.jobtitle", "$source:city"] }],
["format", { "template": "%s:%s:%s" }],
["md5", {}]
]
}
]
}
}
}
}
sha1
Compute the sha1 hash of $previousDirective or value.
Options
value(string, optional)
sha256
Compute the sha256 hash of $previousDirective or value.
Options
value(string, optional)
encodeBase64
Encode $previousDirective or value from utf8 into base64
Options
value(string, optional)
decodeBase64
Decode $previousDirective or value from base64 into utf8
Options
value(string, optional)
htmlStrip
Strip HTML tags from a string
Options
Options are forwarded to string-strip-html.