()
| 18 | let distDir = 'dist/docs-examples'; |
| 19 | |
| 20 | async function extractExamples() { |
| 21 | try { |
| 22 | await fs.rm(distDir, {recursive: true}); |
| 23 | } catch {} |
| 24 | await fs.mkdir(distDir, {recursive: true}); |
| 25 | |
| 26 | let pages = []; |
| 27 | for await (let page of fs.glob('packages/dev/s2-docs/pages/**/*.mdx')) { |
| 28 | pages.push(page); |
| 29 | } |
| 30 | |
| 31 | await Promise.all( |
| 32 | pages.map(async page => { |
| 33 | let code = await fs.readFile(page, 'utf8'); |
| 34 | |
| 35 | code = code.replace( |
| 36 | /(<ExampleSwitcher type="component" examples={(\[.*?\])}>)((?:.|\n)*?)<\/ExampleSwitcher>/g, |
| 37 | (m, start, examples, inner) => { |
| 38 | if (inner.includes('COMPONENT')) { |
| 39 | let components = json5.parse(examples); |
| 40 | inner = components |
| 41 | .map(component => inner.replace(/COMPONENT/g, component)) |
| 42 | .join('\n\n'); |
| 43 | return start + inner + '</ExampleSwitcher>'; |
| 44 | } |
| 45 | |
| 46 | return m; |
| 47 | } |
| 48 | ); |
| 49 | |
| 50 | // Replace /* PROPS */ placeholders with initialProps values from code fence metadata |
| 51 | // Match initialProps={{ ... }} handling one level of nested braces |
| 52 | // Skip blocks with propsObject attribute since those props don't go directly on the component |
| 53 | code = code.replace( |
| 54 | /```tsx([^\n]*initialProps=\{\{((?:[^{}]|\{[^{}]*\})*)\}\}[^\n]*)\n([\s\S]*?)```/g, |
| 55 | (m, meta, propsStr, inner) => { |
| 56 | // Skip if props go to a different object (e.g. propsObject="layoutOptions") |
| 57 | if (meta.includes('propsObject=')) { |
| 58 | return m; |
| 59 | } |
| 60 | if (inner.includes('/* PROPS */')) { |
| 61 | // Parse the initialProps using json5, e.g. "isLoading: true" -> {isLoading: true} |
| 62 | let parsed = json5.parse(`{${propsStr}}`); |
| 63 | // Convert to JSX props string, but skip props that are already in the code |
| 64 | let props = Object.entries(parsed) |
| 65 | .map(([key, value]) => { |
| 66 | // Skip if this prop is already present in the inner code (to avoid duplicates) |
| 67 | let propRegex = new RegExp(`\\b${key.replace('-', '\\-')}\\s*=`); |
| 68 | if (propRegex.test(inner)) { |
| 69 | return ''; |
| 70 | } |
| 71 | if (typeof value === 'string') { |
| 72 | return ` ${key}="${value}"`; |
| 73 | } |
| 74 | return ` ${key}={${JSON.stringify(value)}}`; |
| 75 | }) |
| 76 | .join(''); |
| 77 | inner = inner.replace(/\/\* PROPS \*\//g, props); |
no test coverage detected