lsd/packages/lsd-react/.storybook/scripts/extract-metadata.ts

150 lines
3.3 KiB
TypeScript

import type { ArgTypes } from '@storybook/react'
import * as fs from 'fs'
import * as fsp from 'fs/promises'
import { glob } from 'glob'
import path from 'path'
import { fileURLToPath } from 'url'
const DIRNAME = fileURLToPath(import.meta.url)
const ROOT_DIR = path.resolve(DIRNAME, '../../../')
const BUILD_DIR = path.resolve(ROOT_DIR, 'storybook-static')
const STORIES_JSON = path.resolve(BUILD_DIR, 'stories.json')
;(global as any).__STORYBOOK_MODULE_ADDONS__ = {}
;(global as any).__STORYBOOK_MODULE_PREVIEW_API__ = {}
type StoryInfo = {
id: string
name: string
title: string
kind: string
importPath: string
tags: string[]
story: string
parameters: {
__id: string
docsOnly: boolean
fileName: string
}
}
type StoriesJson = {
v: number
stories: StoryInfo[]
}
export const fromStories = async (
storiesJson: StoriesJson,
assetsDir: string,
) => {
const { stories: storiesMap } = storiesJson
const stories = Object.values(storiesMap).filter(
(story) => !story.parameters.docsOnly,
)
const components: Record<
string,
{
stories: StoryInfo[]
argTypes: ArgTypes
__docgenInfo: any
}
> = {}
const storyFiles = await glob(assetsDir + `/*.stories-*.js`)
for (const file of storyFiles) {
const mod = await import(file)
const { title, component, argTypes } = mod.default
components[component.displayName] = {
argTypes,
stories: stories.filter((story) => story.kind === title),
__docgenInfo: component.__docgenInfo,
}
}
return Object.entries(components)
.map(([name, details]) => ({
name,
...details,
}))
.sort((a, b) => a.name.localeCompare(b.name))
}
export const extractGlobalTypes = async (assetsDir: string) => {
const filenames = await glob(assetsDir + `/preview-*.js.map`)
let previewFilename: string | null = null
for (const filename of filenames) {
const file = await fsp.readFile(filename, 'utf8')
const json = JSON.parse(file)
if (
json.sources &&
json.sources.some((source: string) =>
source.endsWith('.storybook/preview.tsx'),
)
) {
previewFilename = filename.slice(0, -4)
break
}
}
if (!previewFilename) {
console.error('The preview.js file not found!')
return
}
const mod = await import(previewFilename)
return mod.default.globalTypes || []
}
export const extractMetadata = async (dir: string) => {
const assetsDir = path.join(dir, 'assets')
await fsp.writeFile(
path.join(assetsDir, 'package.json'),
Buffer.from(
JSON.stringify({
type: 'module',
}),
),
)
const stories = await import(path.join(dir, 'stories.json'), {
assert: { type: 'json' },
})
const components = await fromStories(stories.default, assetsDir)
// const globalTypes = await extractGlobalTypes(assetsDir)
fs.unlinkSync(path.join(assetsDir, 'package.json'))
return {
components,
// globalTypes,
}
}
export const run = async () => {
if (!fs.existsSync(BUILD_DIR)) {
console.error('The storybook-static dir not found!')
process.exit(1)
}
if (!fs.existsSync(STORIES_JSON)) {
console.error('The stories.json file not found!')
process.exit(1)
}
const metadata = await extractMetadata(BUILD_DIR)
await fsp.writeFile(
path.join(BUILD_DIR, '_metadata.json'),
Buffer.from(JSON.stringify(metadata)),
)
}
run()