README
json-schema-transducer
This module generates a function using JMESPath to convert from a data to another data which a JSON Schema defines.
If a data which a JSON schema defines becomes assigned from another data, there needs a mapper, a converter or a transducer. This module generates such a transducer function from a JMESPath query in the JSON Schema description to describe how to extract and transform the value from an input data. Thus, a JSON Schema remains valid, and there is no need to prepare other resource or code to implement a transducer.
JMESPath Query in JSON Schema Description
The query to extract the JSON value from an input data is describe in Extended Markdown code block syntax at a JSON Schema descrption. The query must be in JMESPath. The value of the element which has such a description is a result to evaluate the JMESPath query for the input data.
The query in a description must have the prefix "query:
".
The body of the query must be enclosed a single backtick (`) or three backtick (```).
Example:
{
"title": "json-schema-transducer sample",
"description": "This description does not include a query because each elements are extracted individually.",
"type": "object",
"properties": {
"address": {
"description": "\"address\" is derived by query:`User.Address.Name`",
"type": "string"
},
"country-name": {
"description": "query:```User.Country``` equals to country-name",
"type": "string"
}
}
}
The above example includes two properties, "address" and "country-name".
"address" has the description which has a JMESPath query User.Address.Name
.
And also "country-name" has the description which has a JMESPath query User.Country
.
This JSON Schema generates a function to transduce from a User
object to a json-schema-transducer sample
data:
const transducer = require('json-schema-transducer');
try {
const transduce = await transducer(schema);
} catch (e) {
// failed to generate a transducer.
console.log(e);
}
console.log(
tranceduce(
{
"User": {
"Name": {
"First": "John",
"Last": "Coltrane",
},
"Address": {
"Name": "Village Vanguard",
"Code": "AS-42"
},
"Country": "US"
}
}
)
);
// {
// "address": "Village Vanguard",
// "country-name": "US"
// }
Relative JMEPath
If there exists queries at the different layers in a schema, the JMESPath expressions of the children must be relative.
{
"title": "Pets",
"description": "query:`[*]`",
"type": "array",
"properties": {
"Pet": {
"type": "object",
"properties": {
"HouseNumber": {
"type": "number",
"description": "pet.house_number"
}
}
}
}
}
In the above example, the Pet
s (not Pets
) are extracted from the element objects in Pets
([*]
).
Therefore, Pet
has an extension like pet.house_number
, not [*].pet.house_number
.
Extract and Transform of oneOf, anyOf, and allOf
A result of oneOf
, anyOf
, or allOf
is extracted as follows:
- try to get a result of an item of
oneOf
,anyOf
, orallOf
array. - copy the properties in the result to one new object by
Object.assign
. - cleanup the result object (to delete
null
and not to delete empty object{}
, empty array[]
and empty string''
). - In the case
oneOf
orallOf
, if the new object is notnull
, the new object is returned. In the caseanyOf
, go back to the first.
Complied with this manner, please construct JMESPath expressions of all items to be suitable for what the schema expect.
For example, see Or Expressions
or And Expressions
in JMESPath.
Note that this module search the first item of allOf
conditions which has type
and try to extract the value by the query which the condition has.
Example
Please see __tests__.
Not Supported
- Object:
- Property names and Pattern Properties: This module does not support
Property names
andPattern Properties
directly because the transducer can not determine the property name. However, a JMESPath expression in the same layer oftype: "object"
, not inpropertyNames
orpatternProperties
, can generate an object which will match the pattern as a result. - Property dependencie and Schema dependencies: Currently, there is no reasonable representation by JMESPath expressions in different layers which describe the dependencies.
- Property names and Pattern Properties: This module does not support
- Combining schemas:
- not: There does not exists reasonable representation.