danielmahon/gatsby-remark-relative-images

Convert absolute paths in JSON files

jeremy-ecoenergy opened this issue · 3 comments

Do you have any plans to also process JSON files? That would be really handy!

e.g. I have JSON files in the /data folder that contain absolute paths to images ("/assets/etc.jpg") that, similarly, need to be converted to relative paths.

@jeremy-ecoenergy I will definitely consider in the near future, once I make sure v2 is working as intended for markdown/mdx. Can you provide an example json file and expected result? Are you using NetlifyCMS to generate the json?

Not using NetlifyCMS, entered by hand. We are using Forestry though.

JSON file before:

[
    {
        "name": "Foo",
        "tags": ["1", "2"],
        "image": "../../static/assets/testimonials/a.jpg",
        "text": "Etc etc"
    }
]

After:

[
    {
        "name": "Foo",
        "tags": ["1", "2"],
        "image": "/assets/testimonials/a.jpg",
        "text": "Etc etc"
    }
]

(The same way it works for Frontmatter in Markdown files now.)

I made a quick functions pasted onCreateNode for JSON. It is highly adapted from your original code with a few adjustment for json

if (node.internal.type.toUpperCase().includes('JSON')) {
const files = getNodesByType('File');

const getParentPath = getNode(node.parent).absolutePath;
const directory = path.dirname(getParentPath);

const options = {
  staticFolderName: 'static',
  include: [],
  exclude: [],
};

// Deeply iterate through frontmatter data for absolute paths
traverse(node).forEach(function (value) {
  if (!isString(value)) return;
  if (!path.isAbsolute(value) || !path.extname(value)) return;

  // console.log(
  //   'traverse find ',
  //   value,
  //   path.extname(value),
  //   path.isAbsolute(value)
  // );

  const paths = this.path.reduce((acc, current) => {
    acc.push(acc.length > 0 ? [acc, current].join('.') : current);
    return acc;
  }, []);

  let shouldTransform = options.include.length < 1;

  if (options.include.some((a) => paths.includes(a))) {
    shouldTransform = true;
  }

  if (options.exclude.some((a) => paths.includes(a))) {
    shouldTransform = false;
  }

  if (!shouldTransform) return;

  const file = findMatchingFile(value, files, options);

  const newValue = path.relative(directory, file.absolutePath);

  this.update(newValue);
});
}