80 lines
2.4 KiB
JavaScript
80 lines
2.4 KiB
JavaScript
import axios from 'axios';
|
|
import matter from 'gray-matter';
|
|
import merge from 'lodash-es/merge.js';
|
|
|
|
import Debug from 'debug';
|
|
import {EOL} from 'node:os';
|
|
|
|
// return updated content
|
|
const getContent = (remote, og, config) => {
|
|
switch (config.content) {
|
|
case 'append': return `${og.content}${EOL}${remote.content}`;
|
|
case 'prepend': return `${remote.content}${EOL}${og.content}`;
|
|
case 'replace': return remote.content;
|
|
default: return remote.content;
|
|
}
|
|
};
|
|
|
|
// return updated frontmatter
|
|
const getFrontmatter = (remote, og, config) => {
|
|
switch (config.frontmatter) {
|
|
case 'merge': return merge({}, og.data, remote.data);
|
|
case 'rebase': return merge({}, remote.data, og.data);
|
|
case 'replace': return remote.data;
|
|
case 'omit':
|
|
case 'skip':
|
|
case false:
|
|
return og.data;
|
|
default: return remote.data;
|
|
}
|
|
};
|
|
|
|
// return a standard url-loader config object with defaults
|
|
const normalize = config => {
|
|
// if config is a string then reset to an object
|
|
if (typeof config === 'string') config = {source: config};
|
|
// return with mixed in defaults
|
|
return merge({}, {content: 'replace', frontmatter: 'replace'}, config);
|
|
};
|
|
|
|
export default function({debug = Debug('@lando/url-loader')}) { // eslint-disable-line
|
|
return {
|
|
name: 'url-loader',
|
|
enforce: 'pre',
|
|
async transform(code, id) {
|
|
if (id.endsWith('.md')) {
|
|
// get original content stuff
|
|
const og = matter(code);
|
|
|
|
// if we have a url-loader then proceed
|
|
if (og?.data?.['url-loader']) {
|
|
// normalize loader
|
|
const config = normalize(og.data['url-loader']);
|
|
debug('fetching content for %o from %o with %o', id, config.source, {config});
|
|
|
|
// attempt to get raw remote source code
|
|
try {
|
|
new URL(config.source);
|
|
config.response = await axios.get(config.source);
|
|
} catch (error) {
|
|
error.message = `Fetching ${config.source} for ${id} failed with: ${error.message}`;
|
|
throw error;
|
|
}
|
|
|
|
// parse remote content
|
|
const remote = matter(config?.response?.data ?? '');
|
|
|
|
// build new content/frontmatter
|
|
const content = getContent(remote, og, config);
|
|
const frontmatter = getFrontmatter(remote, og, config);
|
|
|
|
// stringify and retturn
|
|
return matter.stringify(content, frontmatter);
|
|
}
|
|
}
|
|
|
|
return null;
|
|
},
|
|
};
|
|
};
|