UNPKG

@storybook/addon-docs

Version:

Storybook Docs: Document UI components automatically with stories and MDX

859 lines (842 loc) • 36.8 kB
import CJS_COMPAT_NODE_URL_i8b6sw2p56j from 'node:url'; import CJS_COMPAT_NODE_PATH_i8b6sw2p56j from 'node:path'; import CJS_COMPAT_NODE_MODULE_i8b6sw2p56j from "node:module"; var __filename = CJS_COMPAT_NODE_URL_i8b6sw2p56j.fileURLToPath(import.meta.url); var __dirname = CJS_COMPAT_NODE_PATH_i8b6sw2p56j.dirname(__filename); var require = CJS_COMPAT_NODE_MODULE_i8b6sw2p56j.createRequire(import.meta.url); // ------------------------------------------------------------ // end of CJS compatibility banner, injected by Storybook's esbuild configuration // ------------------------------------------------------------ import "./_node-chunks/chunk-M535JOIG.js"; // src/preset.ts import { isAbsolute as isAbsolute2 } from "node:path"; import { fileURLToPath as fileURLToPath2 } from "node:url"; import { logger as logger2 } from "storybook/internal/node-logger"; // ../../core/src/shared/utils/module.ts import { createRequire, register } from "node:module"; import { fileURLToPath, pathToFileURL } from "node:url"; // ../../../node_modules/exsolve/dist/index.mjs import assert from "node:assert"; import v8 from "node:v8"; import { format, inspect } from "node:util"; var own$1 = {}.hasOwnProperty, classRegExp = /^([A-Z][a-z\d]*)+$/, kTypes = /* @__PURE__ */ new Set([ "string", "function", "number", "object", "Function", "Object", "boolean", "bigint", "symbol" ]), messages = /* @__PURE__ */ new Map(), nodeInternalPrefix = "__node_internal_", userStackTraceLimit; function formatList(array, type = "and") { return array.length < 3 ? array.join(` ${type} `) : `${array.slice(0, -1).join(", ")}, ${type} ${array.at(-1)}`; } function createError(sym, value, constructor) { return messages.set(sym, value), makeNodeErrorWithCode(constructor, sym); } function makeNodeErrorWithCode(Base, key) { return function(...parameters) { let limit = Error.stackTraceLimit; isErrorStackTraceLimitWritable() && (Error.stackTraceLimit = 0); let error = new Base(); isErrorStackTraceLimitWritable() && (Error.stackTraceLimit = limit); let message = getMessage(key, parameters, error); return Object.defineProperties(error, { message: { value: message, enumerable: !1, writable: !0, configurable: !0 }, toString: { value() { return `${this.name} [${key}]: ${this.message}`; }, enumerable: !1, writable: !0, configurable: !0 } }), captureLargerStackTrace(error), error.code = key, error; }; } function isErrorStackTraceLimitWritable() { try { if (v8.startupSnapshot.isBuildingSnapshot()) return !1; } catch { } let desc = Object.getOwnPropertyDescriptor(Error, "stackTraceLimit"); return desc === void 0 ? Object.isExtensible(Error) : own$1.call(desc, "writable") && desc.writable !== void 0 ? desc.writable : desc.set !== void 0; } function hideStackFrames(wrappedFunction) { let hidden = nodeInternalPrefix + wrappedFunction.name; return Object.defineProperty(wrappedFunction, "name", { value: hidden }), wrappedFunction; } var captureLargerStackTrace = hideStackFrames(function(error) { let stackTraceLimitIsWritable = isErrorStackTraceLimitWritable(); return stackTraceLimitIsWritable && (userStackTraceLimit = Error.stackTraceLimit, Error.stackTraceLimit = Number.POSITIVE_INFINITY), Error.captureStackTrace(error), stackTraceLimitIsWritable && (Error.stackTraceLimit = userStackTraceLimit), error; }); function getMessage(key, parameters, self) { let message = messages.get(key); if (assert.ok(message !== void 0, "expected `message` to be found"), typeof message == "function") return assert.ok(message.length <= parameters.length, `Code: ${key}; The provided arguments length (${parameters.length}) does not match the required ones (${message.length}).`), Reflect.apply(message, self, parameters); let regex = /%[dfijoOs]/g, expectedLength = 0; for (; regex.exec(message) !== null; ) expectedLength++; return assert.ok(expectedLength === parameters.length, `Code: ${key}; The provided arguments length (${parameters.length}) does not match the required ones (${expectedLength}).`), parameters.length === 0 ? message : (parameters.unshift(message), Reflect.apply(format, null, parameters)); } function determineSpecificType(value) { if (value == null) return String(value); if (typeof value == "function" && value.name) return `function ${value.name}`; if (typeof value == "object") return value.constructor && value.constructor.name ? `an instance of ${value.constructor.name}` : `${inspect(value, { depth: -1 })}`; let inspected = inspect(value, { colors: !1 }); return inspected.length > 28 && (inspected = `${inspected.slice(0, 25)}...`), `type ${typeof value} (${inspected})`; } var ERR_INVALID_ARG_TYPE = createError("ERR_INVALID_ARG_TYPE", (name, expected, actual) => { assert.ok(typeof name == "string", "'name' must be a string"), Array.isArray(expected) || (expected = [expected]); let message = "The "; if (name.endsWith(" argument")) message += `${name} `; else { let type = name.includes(".") ? "property" : "argument"; message += `"${name}" ${type} `; } message += "must be "; let types = [], instances = [], other = []; for (let value of expected) assert.ok(typeof value == "string", "All expected entries have to be of type string"), kTypes.has(value) ? types.push(value.toLowerCase()) : classRegExp.exec(value) === null ? (assert.ok(value !== "object", 'The value "object" should be written as "Object"'), other.push(value)) : instances.push(value); if (instances.length > 0) { let pos = types.indexOf("object"); pos !== -1 && (types.slice(pos, 1), instances.push("Object")); } return types.length > 0 && (message += `${types.length > 1 ? "one of type" : "of type"} ${formatList(types, "or")}`, (instances.length > 0 || other.length > 0) && (message += " or ")), instances.length > 0 && (message += `an instance of ${formatList(instances, "or")}`, other.length > 0 && (message += " or ")), other.length > 0 && (other.length > 1 ? message += `one of ${formatList(other, "or")}` : (other[0]?.toLowerCase() !== other[0] && (message += "an "), message += `${other[0]}`)), message += `. Received ${determineSpecificType(actual)}`, message; }, TypeError), ERR_INVALID_MODULE_SPECIFIER = createError( "ERR_INVALID_MODULE_SPECIFIER", /** * @param {string} request * @param {string} reason * @param {string} [base] */ (request, reason, base) => `Invalid module "${request}" ${reason}${base ? ` imported from ${base}` : ""}`, TypeError ), ERR_INVALID_PACKAGE_CONFIG = createError("ERR_INVALID_PACKAGE_CONFIG", (path$1, base, message) => `Invalid package config ${path$1}${base ? ` while importing ${base}` : ""}${message ? `. ${message}` : ""}`, Error), ERR_INVALID_PACKAGE_TARGET = createError("ERR_INVALID_PACKAGE_TARGET", (packagePath, key, target, isImport = !1, base) => { let relatedError = typeof target == "string" && !isImport && target.length > 0 && !target.startsWith("./"); return key === "." ? (assert.ok(isImport === !1), `Invalid "exports" main target ${JSON.stringify(target)} defined in the package config ${packagePath}package.json${base ? ` imported from ${base}` : ""}${relatedError ? '; targets must start with "./"' : ""}`) : `Invalid "${isImport ? "imports" : "exports"}" target ${JSON.stringify(target)} defined for '${key}' in the package config ${packagePath}package.json${base ? ` imported from ${base}` : ""}${relatedError ? '; targets must start with "./"' : ""}`; }, Error), ERR_MODULE_NOT_FOUND = createError("ERR_MODULE_NOT_FOUND", (path$1, base, exactUrl = !1) => `Cannot find ${exactUrl ? "module" : "package"} '${path$1}' imported from ${base}`, Error), ERR_NETWORK_IMPORT_DISALLOWED = createError("ERR_NETWORK_IMPORT_DISALLOWED", "import of '%s' by %s is not supported: %s", Error), ERR_PACKAGE_IMPORT_NOT_DEFINED = createError("ERR_PACKAGE_IMPORT_NOT_DEFINED", (specifier, packagePath, base) => `Package import specifier "${specifier}" is not defined${packagePath ? ` in package ${packagePath || ""}package.json` : ""} imported from ${base}`, TypeError), ERR_PACKAGE_PATH_NOT_EXPORTED = createError( "ERR_PACKAGE_PATH_NOT_EXPORTED", /** * @param {string} packagePath * @param {string} subpath * @param {string} [base] */ (packagePath, subpath, base) => subpath === "." ? `No "exports" main defined in ${packagePath}package.json${base ? ` imported from ${base}` : ""}` : `Package subpath '${subpath}' is not defined by "exports" in ${packagePath}package.json${base ? ` imported from ${base}` : ""}`, Error ), ERR_UNSUPPORTED_DIR_IMPORT = createError("ERR_UNSUPPORTED_DIR_IMPORT", "Directory import '%s' is not supported resolving ES modules imported from %s", Error), ERR_UNSUPPORTED_RESOLVE_REQUEST = createError("ERR_UNSUPPORTED_RESOLVE_REQUEST", 'Failed to resolve module specifier "%s" from "%s": Invalid relative URL or base scheme is not hierarchical.', TypeError), ERR_UNKNOWN_FILE_EXTENSION = createError("ERR_UNKNOWN_FILE_EXTENSION", (extension, path$1) => `Unknown file extension "${extension}" for ${path$1}`, TypeError), ERR_INVALID_ARG_VALUE = createError("ERR_INVALID_ARG_VALUE", (name, value, reason = "is invalid") => { let inspected = inspect(value); return inspected.length > 128 && (inspected = `${inspected.slice(0, 128)}...`), `The ${name.includes(".") ? "property" : "argument"} '${name}' ${reason}. Received ${inspected}`; }, TypeError), hasOwnProperty$1 = {}.hasOwnProperty; var hasOwnProperty = {}.hasOwnProperty; var RegExpPrototypeSymbolReplace = RegExp.prototype[Symbol.replace], own = {}.hasOwnProperty; var isWindows = process.platform === "win32", globalCache = globalThis.__EXSOLVE_CACHE__ ||= /* @__PURE__ */ new Map(); // ../../../node_modules/pathe/dist/shared/pathe.ff20891b.mjs var _DRIVE_LETTER_START_RE = /^[A-Za-z]:\//; function normalizeWindowsPath(input = "") { return input && input.replace(/\\/g, "/").replace(_DRIVE_LETTER_START_RE, (r) => r.toUpperCase()); } var _UNC_REGEX = /^[/\\]{2}/, _IS_ABSOLUTE_RE = /^[/\\](?![/\\])|^[/\\]{2}(?!\.)|^[A-Za-z]:[/\\]/, _DRIVE_LETTER_RE = /^[A-Za-z]:$/; var normalize = function(path3) { if (path3.length === 0) return "."; path3 = normalizeWindowsPath(path3); let isUNCPath = path3.match(_UNC_REGEX), isPathAbsolute = isAbsolute(path3), trailingSeparator = path3[path3.length - 1] === "/"; return path3 = normalizeString(path3, !isPathAbsolute), path3.length === 0 ? isPathAbsolute ? "/" : trailingSeparator ? "./" : "." : (trailingSeparator && (path3 += "/"), _DRIVE_LETTER_RE.test(path3) && (path3 += "/"), isUNCPath ? isPathAbsolute ? `//${path3}` : `//./${path3}` : isPathAbsolute && !isAbsolute(path3) ? `/${path3}` : path3); }, join = function(...arguments_) { if (arguments_.length === 0) return "."; let joined; for (let argument of arguments_) argument && argument.length > 0 && (joined === void 0 ? joined = argument : joined += `/${argument}`); return joined === void 0 ? "." : normalize(joined.replace(/\/\/+/g, "/")); }; function normalizeString(path3, allowAboveRoot) { let res = "", lastSegmentLength = 0, lastSlash = -1, dots = 0, char = null; for (let index = 0; index <= path3.length; ++index) { if (index < path3.length) char = path3[index]; else { if (char === "/") break; char = "/"; } if (char === "/") { if (!(lastSlash === index - 1 || dots === 1)) if (dots === 2) { if (res.length < 2 || lastSegmentLength !== 2 || res[res.length - 1] !== "." || res[res.length - 2] !== ".") { if (res.length > 2) { let lastSlashIndex = res.lastIndexOf("/"); lastSlashIndex === -1 ? (res = "", lastSegmentLength = 0) : (res = res.slice(0, lastSlashIndex), lastSegmentLength = res.length - 1 - res.lastIndexOf("/")), lastSlash = index, dots = 0; continue; } else if (res.length > 0) { res = "", lastSegmentLength = 0, lastSlash = index, dots = 0; continue; } } allowAboveRoot && (res += res.length > 0 ? "/.." : "..", lastSegmentLength = 2); } else res.length > 0 ? res += `/${path3.slice(lastSlash + 1, index)}` : res = path3.slice(lastSlash + 1, index), lastSegmentLength = index - lastSlash - 1; lastSlash = index, dots = 0; } else char === "." && dots !== -1 ? ++dots : dots = -1; } return res; } var isAbsolute = function(p) { return _IS_ABSOLUTE_RE.test(p); }; var dirname = function(p) { let segments = normalizeWindowsPath(p).replace(/\/$/, "").split("/").slice(0, -1); return segments.length === 1 && _DRIVE_LETTER_RE.test(segments[0]) && (segments[0] += "/"), segments.join("/") || (isAbsolute(p) ? "/" : "."); }; // ../../core/src/shared/utils/module.ts var importMetaResolve = (...args) => typeof import.meta.resolve != "function" && process.env.VITEST === "true" ? (console.warn( "importMetaResolve from within Storybook is being used in a Vitest test, but it shouldn't be. Please report this at https://github.com/storybookjs/storybook/issues/new?template=bug_report.yml" ), pathToFileURL(args[0]).href) : import.meta.resolve(...args), resolvePackageDir = (pkg, parent) => { try { return dirname(fileURLToPath(importMetaResolve(join(pkg, "package.json"), parent))); } catch { try { return dirname(fileURLToPath(importMetaResolve(join(pkg, "package.json")))); } catch { let req = createRequire(parent ?? import.meta.url); return dirname(req.resolve(join(pkg, "package.json"))); } } }; // src/mdx-service/server.ts import { getComponentIdFromEntry as getComponentIdFromEntry2, groupBy as groupBy2, registerService } from "storybook/internal/common"; import { Tag as Tag2 } from "storybook/internal/core-server"; // src/manifest.ts import * as fs from "node:fs/promises"; import * as path2 from "node:path"; import { getComponentIdFromEntry, groupBy } from "storybook/internal/common"; import { Tag, analyzeMdx, mdxManifestRef } from "storybook/internal/core-server"; import { logger } from "storybook/internal/node-logger"; // src/extract-docs-summary.ts function extractDocsSummary(content) { let result = content; result = result.replace(/^\s*import\s+(?:[\s\S]*?from\s+)?['"][^'"]+['"];?\s*$/gm, ""); let prevResult = ""; for (; prevResult !== result; ) prevResult = result, result = result.replace(/\{[^{}]*\}/g, ""); for (result = result.replace(/<[^>]+\/>/g, ""), prevResult = ""; prevResult !== result; ) prevResult = result, result = result.replace(/<(\w+)[^>]*>([\s\S]*?)<\/\1>/g, "$2"); if (result = result.replace(/<[^>]+>/g, ""), result = result.replace(/\s+/g, " ").trim(), !!result) return result.length > 90 ? `${result.slice(0, 90)}...` : result; } // src/manifest.ts async function createDocsManifestEntry(entry) { let absolutePath = path2.join(process.cwd(), entry.importPath); try { let content = await fs.readFile(absolutePath, "utf-8"), { summary } = await analyzeMdx(content), derivedSummary = summary ?? extractDocsSummary(content); return { id: entry.id, name: entry.name, path: entry.importPath, title: entry.title, content, ...derivedSummary !== void 0 && { summary: derivedSummary } }; } catch (err) { return { id: entry.id, name: entry.name, path: entry.importPath, title: entry.title, error: { name: err instanceof Error ? err.name : "Error", message: err instanceof Error ? err.message : String(err) } }; } } function createDocsManifestRefEntry(entry, componentId) { return { id: entry.id, name: entry.name, mdx: { $ref: mdxManifestRef(componentId, entry.id) } }; } async function buildUnattachedDocs(entries, build) { let docs2 = await Promise.all( entries.map(async (entry) => [entry.id, await build(entry, entry.id)]) ); return Object.fromEntries(docs2); } async function applyAttachedDocs(entries, existingComponents, build) { if (!existingComponents || entries.length === 0) return existingComponents; let docs2 = await Promise.all( entries.map(async (entry) => { let componentId = getComponentIdFromEntry(entry); return { componentId, doc: await build(entry, componentId) }; }) ), components = { ...existingComponents.components }; for (let { componentId, doc } of docs2) { let component = components[componentId] ?? { id: componentId, name: componentId }; components[componentId] = { ...component, docs: { ...component.docs, [doc.id]: doc } }; } return { ...existingComponents, components }; } var manifests = async (existingManifests = {}, { manifestEntries, presets }) => { let startPerformance = performance.now(), features = await presets?.apply?.("features"), useMdxService = features?.experimentalDocgenServer === !0 && features?.componentsManifest === !0, docsEntries = manifestEntries.filter( (entry) => entry.type === "docs" ); if (docsEntries.length === 0) return existingManifests; let { attachedEntries = [], unattachedEntries = [] } = groupBy(docsEntries, (entry) => { switch (!0) { case entry.tags?.includes(Tag.UNATTACHED_MDX): return "unattachedEntries"; case entry.tags?.includes(Tag.ATTACHED_MDX): return "attachedEntries"; default: return "ignored"; } }); if (unattachedEntries.length === 0 && attachedEntries.length === 0) return existingManifests; let existingManifestsWithDocs = existingManifests, build = useMdxService ? createDocsManifestRefEntry : createDocsManifestEntry, [unattachedDocs, updatedComponents] = await Promise.all([ buildUnattachedDocs(unattachedEntries, build), applyAttachedDocs(attachedEntries, existingManifestsWithDocs.components, build) ]), processedCount = unattachedEntries.length + attachedEntries.length; logger.verbose( `Docs manifest generation took ${performance.now() - startPerformance}ms for ${processedCount} entries (${unattachedEntries.length} unattached, ${attachedEntries.length} attached)` ); let result = { ...existingManifestsWithDocs }; return Object.keys(unattachedDocs).length > 0 && (result.docs = { v: useMdxService ? 1 : 0, docs: unattachedDocs }), updatedComponents && (result.components = updatedComponents), result; }; // src/mdx-service/definition.ts import { MDX_SERVICE_ID, mdxQueryStaticPath } from "storybook/internal/core-server"; // ../../../node_modules/valibot/dist/index.mjs var store$4, DEFAULT_CONFIG = { lang: void 0, message: void 0, abortEarly: void 0, abortPipeEarly: void 0 }; function getGlobalConfig(config$1) { return !config$1 && !store$4 ? DEFAULT_CONFIG : { lang: config$1?.lang ?? store$4?.lang, message: config$1?.message, abortEarly: config$1?.abortEarly ?? store$4?.abortEarly, abortPipeEarly: config$1?.abortPipeEarly ?? store$4?.abortPipeEarly }; } var store$3; function getGlobalMessage(lang) { return store$3?.get(lang); } var store$2; function getSchemaMessage(lang) { return store$2?.get(lang); } var store$1; function getSpecificMessage(reference, lang) { return store$1?.get(reference)?.get(lang); } function _stringify(input) { let type = typeof input; return type === "string" ? `"${input}"` : type === "number" || type === "bigint" || type === "boolean" ? `${input}` : type === "object" || type === "function" ? (input && Object.getPrototypeOf(input)?.constructor?.name) ?? "null" : type; } function _addIssue(context, label, dataset, config$1, other) { let input = other && "input" in other ? other.input : dataset.value, expected = other?.expected ?? context.expects ?? null, received = other?.received ?? _stringify(input), issue = { kind: context.kind, type: context.type, input, expected, received, message: `Invalid ${label}: ${expected ? `Expected ${expected} but r` : "R"}eceived ${received}`, requirement: context.requirement, path: other?.path, issues: other?.issues, lang: config$1.lang, abortEarly: config$1.abortEarly, abortPipeEarly: config$1.abortPipeEarly }, isSchema = context.kind === "schema", message$1 = other?.message ?? context.message ?? getSpecificMessage(context.reference, issue.lang) ?? (isSchema ? getSchemaMessage(issue.lang) : null) ?? config$1.message ?? getGlobalMessage(issue.lang); message$1 !== void 0 && (issue.message = typeof message$1 == "function" ? message$1(issue) : message$1), isSchema && (dataset.typed = !1), dataset.issues ? dataset.issues.push(issue) : dataset.issues = [issue]; } var _standardCache = /* @__PURE__ */ new WeakMap(); function _getStandardProps(context) { let cached = _standardCache.get(context); return cached || (cached = { version: 1, vendor: "valibot", validate(value$1) { return context["~run"]({ value: value$1 }, getGlobalConfig()); } }, _standardCache.set(context, cached)), cached; } function _isValidObjectKey(object$1, key) { return Object.prototype.hasOwnProperty.call(object$1, key) && key !== "__proto__" && key !== "prototype" && key !== "constructor"; } var EMOJI_REGEX = new RegExp("^(?:[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|(?![\\p{Emoji_Modifier_Base}\\u{1F1E6}-\\u{1F1FF}])\\p{Emoji_Presentation}))*)+$", "u"); function getFallback(schema, dataset, config$1) { return typeof schema.fallback == "function" ? schema.fallback(dataset, config$1) : schema.fallback; } function getDefault(schema, dataset, config$1) { return typeof schema.default == "function" ? schema.default(dataset, config$1) : schema.default; } function object(entries$1, message$1) { return { kind: "schema", type: "object", reference: object, expects: "Object", async: !1, entries: entries$1, message: message$1, get "~standard"() { return _getStandardProps(this); }, "~run"(dataset, config$1) { let input = dataset.value; if (input && typeof input == "object") { dataset.typed = !0, dataset.value = {}; for (let key in this.entries) { let valueSchema = this.entries[key]; if (key in input || (valueSchema.type === "exact_optional" || valueSchema.type === "optional" || valueSchema.type === "nullish") && valueSchema.default !== void 0) { let value$1 = key in input ? input[key] : getDefault(valueSchema), valueDataset = valueSchema["~run"]({ value: value$1 }, config$1); if (valueDataset.issues) { let pathItem = { type: "object", origin: "value", input, key, value: value$1 }; for (let issue of valueDataset.issues) issue.path ? issue.path.unshift(pathItem) : issue.path = [pathItem], dataset.issues?.push(issue); if (dataset.issues || (dataset.issues = valueDataset.issues), config$1.abortEarly) { dataset.typed = !1; break; } } valueDataset.typed || (dataset.typed = !1), dataset.value[key] = valueDataset.value; } else if (valueSchema.fallback !== void 0) dataset.value[key] = getFallback(valueSchema); else if (valueSchema.type !== "exact_optional" && valueSchema.type !== "optional" && valueSchema.type !== "nullish" && (_addIssue(this, "key", dataset, config$1, { input: void 0, expected: `"${key}"`, path: [{ type: "object", origin: "key", input, key, value: input[key] }] }), config$1.abortEarly)) break; } } else _addIssue(this, "type", dataset, config$1); return dataset; } }; } function optional(wrapped, default_) { return { kind: "schema", type: "optional", reference: optional, expects: `(${wrapped.expects} | undefined)`, async: !1, wrapped, default: default_, get "~standard"() { return _getStandardProps(this); }, "~run"(dataset, config$1) { return dataset.value === void 0 && (this.default !== void 0 && (dataset.value = getDefault(this, dataset, config$1)), dataset.value === void 0) ? (dataset.typed = !0, dataset) : this.wrapped["~run"](dataset, config$1); } }; } function record(key, value$1, message$1) { return { kind: "schema", type: "record", reference: record, expects: "Object", async: !1, key, value: value$1, message: message$1, get "~standard"() { return _getStandardProps(this); }, "~run"(dataset, config$1) { let input = dataset.value; if (input && typeof input == "object") { dataset.typed = !0, dataset.value = {}; for (let entryKey in input) if (_isValidObjectKey(input, entryKey)) { let entryValue = input[entryKey], keyDataset = this.key["~run"]({ value: entryKey }, config$1); if (keyDataset.issues) { let pathItem = { type: "object", origin: "key", input, key: entryKey, value: entryValue }; for (let issue of keyDataset.issues) issue.path = [pathItem], dataset.issues?.push(issue); if (dataset.issues || (dataset.issues = keyDataset.issues), config$1.abortEarly) { dataset.typed = !1; break; } } let valueDataset = this.value["~run"]({ value: entryValue }, config$1); if (valueDataset.issues) { let pathItem = { type: "object", origin: "value", input, key: entryKey, value: entryValue }; for (let issue of valueDataset.issues) issue.path ? issue.path.unshift(pathItem) : issue.path = [pathItem], dataset.issues?.push(issue); if (dataset.issues || (dataset.issues = valueDataset.issues), config$1.abortEarly) { dataset.typed = !1; break; } } (!keyDataset.typed || !valueDataset.typed) && (dataset.typed = !1), keyDataset.typed && (dataset.value[keyDataset.value] = valueDataset.value); } } else _addIssue(this, "type", dataset, config$1); return dataset; } }; } function string(message$1) { return { kind: "schema", type: "string", reference: string, expects: "string", async: !1, message: message$1, get "~standard"() { return _getStandardProps(this); }, "~run"(dataset, config$1) { return typeof dataset.value == "string" ? dataset.typed = !0 : _addIssue(this, "type", dataset, config$1), dataset; } }; } function undefined_(message$1) { return { kind: "schema", type: "undefined", reference: undefined_, expects: "undefined", async: !1, message: message$1, get "~standard"() { return _getStandardProps(this); }, "~run"(dataset, config$1) { return dataset.value === void 0 ? dataset.typed = !0 : _addIssue(this, "type", dataset, config$1), dataset; } }; } function void_(message$1) { return { kind: "schema", type: "void", reference: void_, expects: "void", async: !1, message: message$1, get "~standard"() { return _getStandardProps(this); }, "~run"(dataset, config$1) { return dataset.value === void 0 ? dataset.typed = !0 : _addIssue(this, "type", dataset, config$1), dataset; } }; } // src/mdx-service/definition.ts import { defineService } from "storybook/open-service"; var mdxInputSchema = object({ id: string() }), mdxErrorSchema = object({ name: string(), message: string() }), mdxDocPayloadSchema = object({ id: string(), name: string(), path: string(), title: string(), content: optional(string()), summary: optional(string()), error: optional(mdxErrorSchema) }), mdxPayloadSchema = object({ id: string(), name: string(), docs: record(string(), mdxDocPayloadSchema) }), mdxOutputSchema = optional(mdxPayloadSchema), mdxServiceDef = defineService({ id: MDX_SERVICE_ID, internal: !0, // this service really only ensures that the MDX docs are available in manifests, so there is no need to expose it to the public API initialState: { components: {} }, queries: { mdxForComponent: { input: mdxInputSchema, output: mdxOutputSchema, handler: (input, ctx) => ctx.self.state.components[input.id], load: async (input, ctx) => { await ctx.self.commands._extractMdxForComponent(input); }, staticPath: (input) => mdxQueryStaticPath(input.id) }, mdxForAllComponents: { input: void_(), output: record(string(), mdxPayloadSchema), handler: (_input, ctx) => ctx.self.state.components, load: async (_input, ctx) => { await ctx.self.commands._extractAllMdx(void 0); } } }, commands: { _extractMdxForComponent: { internal: !0, input: mdxInputSchema, output: mdxOutputSchema }, _extractAllMdx: { internal: !0, input: undefined_(), output: void_() } } }); // src/mdx-service/server.ts function groupMdxEntriesByComponent(index) { return groupBy2( Object.values(index.entries).filter( (entry) => entry.type === "docs" && ((entry.tags?.includes(Tag2.ATTACHED_MDX) ?? !1) || (entry.tags?.includes(Tag2.UNATTACHED_MDX) ?? !1)) ), (entry) => entry.tags?.includes(Tag2.ATTACHED_MDX) ? getComponentIdFromEntry2(entry) : entry.id ); } var defaultMdxProvider = async ({ componentId, entries }) => { if (entries.length === 0) return; let docs2 = await Promise.all(entries.map(createDocsManifestEntry)); return { id: componentId, name: componentId, docs: Object.fromEntries(docs2.map((doc) => [doc.id, doc])) }; }; function registerMdxService({ getIndex, provider = defaultMdxProvider }) { return registerService(mdxServiceDef, { queries: { mdxForComponent: { staticInputs: async () => { let index = await getIndex(), grouped = groupMdxEntriesByComponent(index); return Object.keys(grouped).map((id) => ({ id })); } } }, commands: { _extractMdxForComponent: { handler: async (input, ctx) => { let index = await getIndex(), entries = groupMdxEntriesByComponent(index)[input.id] ?? []; if (entries.length === 0) return; let payload = await provider({ componentId: input.id, entries }); if (payload) return ctx.self.setState((state) => { state.components[input.id] = payload; }), payload; } }, _extractAllMdx: { handler: async (_input, ctx) => { let index = await getIndex(), grouped = groupMdxEntriesByComponent(index), extracted = await Promise.all( Object.entries(grouped).map(async ([id, entries]) => { let payload = await provider({ componentId: id, entries }); return payload ? [id, payload] : void 0; }) ); ctx.self.setState((state) => { for (let result of extracted) { if (!result) continue; let [id, payload] = result; state.components[id] = payload; } }); } } } }); } // src/preset.ts var getResolvedReact = async (options) => { let resolvedReact2 = await options.presets.apply("resolvedReact", {}); return { react: resolvedReact2.react ?? resolvePackageDir("react"), reactDom: resolvedReact2.reactDom ?? resolvePackageDir("react-dom"), // In Webpack, symlinked MDX files will cause @mdx-js/react to not be resolvable if it is not hoisted // This happens for the SB monorepo's template stories when a sandbox has a different react version than // addon-docs, causing addon-docs's dependencies not to be hoisted. // This might also affect regular users who have a similar setup. // Explicitly alias @mdx-js/react to avoid this issue. mdx: resolvedReact2.mdx ?? fileURLToPath2(import.meta.resolve("@mdx-js/react")) }; }; async function webpack(webpackConfig = {}, options) { let { module = {} } = webpackConfig, { csfPluginOptions = {}, mdxPluginOptions = {} } = options, enrichCsf = await options.presets.apply("experimental_enrichCsf"), rehypeSlug = (await import("./_node-chunks/rehype-slug-L6ETBLLW.js")).default, rehypeExternalLinks = (await import("./_node-chunks/rehype-external-links-L7QHCVSL.js")).default, mdxLoaderOptions = await options.presets.apply("mdxLoaderOptions", { ...mdxPluginOptions, mdxCompileOptions: { providerImportSource: fileURLToPath2( import.meta.resolve("@storybook/addon-docs/mdx-react-shim") ), ...mdxPluginOptions.mdxCompileOptions, rehypePlugins: [ ...mdxPluginOptions?.mdxCompileOptions?.rehypePlugins ?? [], rehypeSlug, rehypeExternalLinks ] } }); logger2.info("Addon-docs: using MDX3"); let { react, reactDom, mdx } = await getResolvedReact(options), alias; return Array.isArray(webpackConfig.resolve?.alias) ? (alias = [...webpackConfig.resolve?.alias], alias.push( { name: "react", alias: react }, { name: "react-dom", alias: reactDom }, { name: "@mdx-js/react", alias: mdx } )) : alias = { ...webpackConfig.resolve?.alias, react, "react-dom": reactDom, "@mdx-js/react": mdx }, { ...webpackConfig, plugins: [ ...webpackConfig.plugins || [], ...csfPluginOptions ? [ (await import("@storybook/csf-plugin")).webpack({ ...csfPluginOptions, enrichCsf }) ] : [] ], resolve: { ...webpackConfig.resolve, alias }, module: { ...module, rules: [ ...module.rules || [], { test: /\.mdx$/, exclude: /(stories|story)\.mdx$/, use: [ { loader: fileURLToPath2(import.meta.resolve("@storybook/addon-docs/mdx-loader")), options: mdxLoaderOptions } ] } ] } }; } var docs = (input = {}, options) => { if (options?.build?.test?.disableAutoDocs) return; let result = { ...input, defaultName: "Docs" }, docsMode = options.docs; return docsMode && (result.docsMode = docsMode), result; }, addons = [ import.meta.resolve("@storybook/react-dom-shim/preset") ], viteFinal = async (config, options) => { let { plugins = [] } = config, { mdxPlugin } = await import("./_node-chunks/mdx-plugin-OL2HJD73.js"), { react, reactDom, mdx } = await getResolvedReact(options), packageDeduplicationPlugin = { name: "storybook:package-deduplication", enforce: "pre", config: () => ({ resolve: { alias: { react, // Vite doesn't respect export maps when resolving an absolute path, so we need to do that manually here ...isAbsolute2(reactDom) && { "react-dom/server": `${reactDom}/server.browser.js` }, "react-dom": reactDom, "@mdx-js/react": mdx } } }) }; return plugins.unshift(packageDeduplicationPlugin), plugins.unshift(mdxPlugin(options)), { ...config, plugins }; }, webpackX = webpack, docsX = docs, resolvedReact = async (existing) => ({ react: existing?.react ?? resolvePackageDir("react"), reactDom: existing?.reactDom ?? resolvePackageDir("react-dom"), mdx: existing?.mdx ?? fileURLToPath2(import.meta.resolve("@mdx-js/react")) }), services = async (_value, options) => { let features = await options.presets.apply("features"); if (features?.experimentalDocgenServer && features?.componentsManifest && !options.ignorePreview) { let generator = await options.presets.apply("storyIndexGenerator"); registerMdxService({ getIndex: () => generator.getIndex() }); } }, optimizeViteDeps = [ "@storybook/addon-docs", "@storybook/addon-docs/blocks", "@storybook/addon-docs > @mdx-js/react", "@storybook/addon-docs > @storybook/react-dom-shim", "react-dom/client", "react/jsx-runtime", "react" ]; export { addons, docsX as docs, manifests as experimental_manifests, optimizeViteDeps, resolvedReact, services, viteFinal, webpackX as webpack };