whitlockjc / json-refs

Various utilities for JSON Pointers (http://tools.ietf.org/html/rfc6901) and JSON References (http://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03).
MIT License
226 stars 64 forks source link

Add support for a deep copy of all duplicate references #147

Open J3tto opened 6 years ago

J3tto commented 6 years ago

Say i have 2 files, (main, common). Main contains multiple references to include the same common file in more than one location. Currently the common content is only included once and all other refs and referenced to the initial include location.

However based on my use case (creating a final OpenAPI yaml file for import to AWS Gateway) the main needs to contain a deep copy of all references from the common file in each location its referenced. (i.e. there should be no pointers or references in the final output after resolveRefs)

Could i request that an additional option is added to force and always make a deep copies of any referenced locations when using resolveRefs regardless of if its call multiple times. (happy of this to be supported for local only)

I understand result will contains lots of duplication and also have a runtime impact. My request and intention is to ensure that the final output is completely and free of any references for my particular use case.

Example (main):

...
common1:
  $ref: ./common.yaml
common2:
  $ref: ./common.yaml
....

Running this through resolveRefs (with new option to force copy with no ref) should result in:

...
common1:
  # full/deep copy of content of common here
common2:
  # full/deep copy of content of common here
....

Many thanks in advance.

J3tto commented 6 years ago

After a little more digging i've manged to implement a solution to this by recursively calling resolveRefs within loaderOptions:

var root = YAML.safeLoad(fs.readFileSync(file).toString());
var options = {
  filter        : ['relative', 'remote'],
  loaderOptions : {
    processContent : function (res, callback) {
        jsonrefs.resolveRefs(YAML.safeLoad(res.text), options).then(function (results) {
            callback(null, results.resolved);
        });
    }
  }
};
jsonrefs.resolveRefs(root, options).then(function (results) {
    console.log(YAML.safeDump(results.resolved));
});

Only limitation with my approach is that a each ref file can't have more than 1 import to the same location.