@sanity/codegen
Version:
Codegen toolkit for Sanity.io
75 lines (74 loc) • 2.69 kB
JavaScript
import { parse } from '@babel/core';
// helper function to parse a source file
export function parseSourceFile(_source, _filename, babelOptions) {
let source = _source;
let filename = _filename;
if (filename.endsWith('.astro')) {
// append .ts to the filename so babel will parse it as typescript
filename += '.ts';
source = parseAstro(source);
} else if (filename.endsWith('.vue')) {
// append .ts to the filename so babel will parse it as typescript
filename += '.ts';
source = parseVue(source);
} else if (filename.endsWith('.svelte')) {
// append .ts to the filename so babel will parse it as typescript
filename += '.ts';
source = parseSvelte(source);
}
const result = parse(source, {
...babelOptions,
filename
});
if (!result) {
throw new Error(`Failed to parse ${filename}`);
}
return result;
}
function parseAstro(source) {
// find all code fences, the js code is between --- and ---
// Handle both Unix (\n) and Windows (\r\n) line endings
const codeFences = source.match(/---\r?\n([\s\S]*?)\r?\n---/g);
if (!codeFences) {
return '';
}
return codeFences.map((codeFence)=>{
// Split on either \n or \r\n
return codeFence.split(/\r?\n/).slice(1, -1).join('\n');
}).join('\n');
}
function parseVue(source) {
// find all script tags, the js code is between <script> and </script>
const scriptRegex = /<script(?:\s+generic=["'][^"']*["'])?[^>]*>([\s\S]*?)<\/script>/g;
// const matches = [...source.matchAll(scriptRegex)]
// TODO: swap once this code runs in `ES2020`
const matches = matchAllPolyfill(source, scriptRegex);
if (matches.length === 0) {
return '';
}
return matches.map((match)=>match[1]).join('\n');
}
function parseSvelte(source) {
// find all script tags, the js code is between <script> and </script>
const scriptRegex = /<script[^>]*>([\s\S]*?)<\/script>/g;
// const matches = [...source.matchAll(scriptRegex)]
// TODO: swap once this code runs in `ES2020`
const matches = matchAllPolyfill(source, scriptRegex);
if (matches.length === 0) {
return '';
}
return matches.map((match)=>match[1]).join('\n');
}
// TODO: remove once this code runs in `ES2020`
function matchAllPolyfill(str, regex) {
if (!regex.global) {
throw new Error('matchAll polyfill requires a global regex (with /g flag)');
}
const matches = [];
let match;
while((match = regex.exec(str)) !== null){
matches.push(match);
}
return matches;
}
//# sourceMappingURL=parseSource.js.map