@storybook/addon-docs
Version:
Document component usage and properties in Markdown
89 lines (72 loc) • 2.47 kB
JavaScript
import svelteDoc from 'sveltedoc-parser';
import dedent from 'ts-dedent';
import * as path from 'path';
import * as fs from 'fs';
import { getOptions } from 'loader-utils';
import { preprocess } from 'svelte/compiler';
import { logger } from '@storybook/node-logger'; // From https://github.com/sveltejs/svelte/blob/8db3e8d0297e052556f0b6dde310ef6e197b8d18/src/compiler/compile/utils/get_name_from_filename.ts
// Copied because it is not exported from the compiler
function getNameFromFilename(filename) {
if (!filename) return null;
const parts = filename.split(/[/\\]/).map(encodeURI);
if (parts.length > 1) {
const index_match = parts[parts.length - 1].match(/^index(\.\w+)/);
if (index_match) {
parts.pop();
parts[parts.length - 1] += index_match[1];
}
}
const base = parts.pop().replace(/%/g, 'u').replace(/\.[^.]+$/, '').replace(/[^a-zA-Z_$0-9]+/g, '_').replace(/^_/, '').replace(/_$/, '').replace(/^(\d)/, '_$1');
if (!base) {
throw new Error(`Could not derive component name from file ${filename}`);
}
return base[0].toUpperCase() + base.slice(1);
}
/**
* webpack loader for sveltedoc-parser
* @param source raw svelte component
*/
export default async function svelteDocgen(source) {
// eslint-disable-next-line no-underscore-dangle
const {
resource
} = this._module;
const svelteOptions = Object.assign({}, getOptions(this));
const {
preprocess: preprocessOptions,
logDocgen = false
} = svelteOptions;
let docOptions;
if (preprocessOptions) {
const src = fs.readFileSync(resource).toString();
const {
code: fileContent
} = await preprocess(src, preprocessOptions);
docOptions = {
fileContent
};
} else {
docOptions = {
filename: resource
};
} // set SvelteDoc options
const options = Object.assign({}, docOptions, {
version: 3
});
let docgen = '';
try {
const componentDoc = await svelteDoc.parse(options); // get filename for source content
const file = path.basename(resource); // populate filename in docgen
componentDoc.name = path.basename(file);
const componentName = getNameFromFilename(resource);
docgen = dedent`
${componentName}.__docgen = ${JSON.stringify(componentDoc)};
`;
} catch (error) {
if (logDocgen) {
logger.error(error);
}
} // inject __docgen prop in svelte component
const output = source + docgen;
return output;
}