extends Feature

 

The extends feature in definition.json was developed to eliminate code duplication from one JSON to another and extend them instead. 

In cases where there are two similar tenants such as m. and www. JSONs that share a common configuration with the exception of certain fields, they can be extended by adding the following flag:

"extends":"www.sampleurl.com/index/src/definition.json"

In this case, m. is extending www. and the JSONs are merged according to the following given behavior:

  • When a field exists only in m. or only in www. it is added to the result

  • When a field exists in both m. and www. the value in m. is selected.

The merge is recursive and works for any field regardless of how deep the JSON tree is. 

Arrays

Arrays can not be merged by default. If www. has a field with the value ["a", "b"] and m. has the same field with the value ["c"], the result is ["c"]. For that reason, a way to define how to make a merge of two arrays has been implemented. Basically, what is defined in the file extends a series of operations to be applied on the original array. These operations are: modify, insert, insertall and delete.

  • modify: Allows the ability to modify elements of the array, or of a property of an element of an array.

  • insert: Inserts the specified elements in the determined position of an array.

  • insertAll: Inserts all the elements of the arrays specified in the determined position of an array.

  • delete: Delete elements of an array, elements within arrays within an array and even eliminate properties of objects.

The operations on the array are not commutative since they alter the state of the array. For example, given the array [1, 2], when we apply delete [1, 0] the result is [] and is the same as applying delete [0,0], but if we apply delete [0, 1] the result is [ 2], since after eliminating element 0 from the array index, 1 is no longer valid.

 

Examples: 

Original JSON

Extends

Result

{
"layouts": [
["photo", 1, 0],
"thumb",
"photo",
{
"name": "photo",
"count": 4,
"section": "comida"
}
]
}

{
 "extends": "default.json",
"layouts": {
"modify": {
"1": "photo2",
"2": {"simple" : "object"},
"3.section": "sports"
}
}
}

{
"layouts": [
["photo", 1, 0],
"photo2",
{"simple" : "object"},
{
"name": "photo",
"count": 4,
"section": "sports"
}
],
"extends": "default.json"
}

{
"layouts": [
["photo", 1, 0],
"thumb",
"photo"
]
}

{
"extends": "default.json",
"layouts": {
"insert": {
"0": ["S1", "S2", "S3"],
"-1": "At The end"
}
}
}

{
"layouts": [
["S1", "S2", "S3"],
["photo", 1, 0],
"thumb",
"photo",
"At The end"
],
"extends":"default.json"
}

{
"layouts": [
["photo", 1, 0],
"thumb",
"photo"
]
}

{
"extends": "default.json",
"layouts": {
"insertAll": {
"0": ["S1", "S2", "S3"],
"-1": "At The end"
}
}
}

{
"layouts": [
"S1",
"S2",
"S3",
["photo", 1, 0],
"thumb",
"photo",
"At The end"
],
"extends":"default.json"
}

{
"layouts": [
["photo", 1, 0],
"thumb",
"photo"
]
}

{
"extends": "default.json",
"layouts": {
"delete": [2, 1]
}
}


{
"layouts": [
["photo", 1, 0]
],
"extends":"default.json"
}

{
"layouts": [
["photo", 1, 0],
"thumb",
{
"sections" : [1,2,3]
}
]
}

{
"extends": "default.json",
"layouts": {
"delete": {
"0" : 1,
"2.sections" : 1,
"$this" : 1
}
}
}

{
"layouts": [
["photo", 0],
{
"sections" : [1,3]
}
],
"extends":"default.json"
}

{
"layouts": [
["photo", 1, 0],
"thumb",
{
"sections" : [1,2,3]
}
]
}

{
"extends": "default.json",
"layouts": {
"delete": {
"2" : "sections"
}
}
}

{
"layouts": [
["photo", 1, 0],
"thumb",
{
}
],
"extends":"default.json"
}

 

Path variables

Exercise caution when a definition is extended from another tenant. The path values have their root in the current tenant, not in the one being extended. 

For example:

configuration / whiteCollarScript : "index/src/whitecollar/main.js"

Ensure that the file exists in the tenant you are working on. Otherwise, specify the tenant like in the following:

configuration / whiteCollarScript : "../<someTenant>/index/src/whitecollar/main.js"

 

Verifications

To ensure the merge is behaving as expected, the result can be compared with the original definition by performing the following steps:

  1. Open a terminal.
  2. Go into the definition.json folder. 
  3. Save a copy.

    cp definition.json definition.original.json
  4. Add the extends flag and remove the unnecessary code that is already defined in the parent. 
  5. Run the merger manually.

    mrf-json `pwd`/definition.json > definition.merged.json 
  6.  Compare the "definition.orginal.json" with "definition.merged.json" but be sure not to commit these files.