markdown-story-indexer.js (2143B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 /* eslint-env node */ 5 6 const { loadCsf } = require("@storybook/csf-tools"); 7 const { compile } = require("@storybook/mdx2-csf"); 8 const { getStoryTitle, getMDXSource } = require("./markdown-story-utils.js"); 9 const fs = require("fs"); 10 11 /** 12 * Function that tells Storybook how to index markdown based stories. This is 13 * responsible for Storybook knowing how to populate the sidebar in the 14 * Storybook UI, then retrieve the relevant file when a story is selected. In 15 * order to get the data Storybook needs, we have to convert the markdown to 16 * MDX, the convert that to CSF. 17 * More info on indexers can be found here: storybook.js.org/docs/api/main-config-indexers 18 * 19 * @param {string} fileName - Path to the file being processed. 20 * @param {object} opts - Options to configure the indexer. 21 * @returns Array of IndexInput objects. 22 */ 23 module.exports = async (fileName, opts) => { 24 // eslint-disable-next-line no-unsanitized/method 25 const content = fs.readFileSync(fileName, "utf8"); 26 const title = getStoryTitle(fileName); 27 const code = getMDXSource(content, title); 28 29 // Compile MDX into CSF 30 const csfCode = await compile(code, opts); 31 32 // Parse CSF component 33 let csf = loadCsf(csfCode, { fileName, makeTitle: () => title }).parse(); 34 35 // Return an array of story indexes. 36 // Cribbed from https://github.com/storybookjs/storybook/blob/4169cd5b4ec9111de69f64a5e06edab9a6d2b0b8/code/addons/docs/src/preset.ts#L189 37 const { indexInputs, stories } = csf; 38 return indexInputs.map((input, index) => { 39 const docsOnly = stories[index].parameters?.docsOnly; 40 const tags = input.tags ? input.tags : []; 41 if (docsOnly) { 42 tags.push("stories-mdx-docsOnly"); 43 } 44 // the mdx-csf compiler automatically adds the 'stories-mdx' tag to meta, 45 // here' we're just making sure it is always there 46 if (!tags.includes("stories-mdx")) { 47 tags.push("stories-mdx"); 48 } 49 return { ...input, tags }; 50 }); 51 };