@rspress/plugin-preview 1.8.0 → 1.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -19,12 +19,6 @@ type Options = {
19
19
  * @default 'follow'
20
20
  */
21
21
  iframePosition?: 'fixed' | 'follow';
22
- /**
23
- * whether the demo can open in codesandbox
24
- * @default false
25
- * @experimental
26
- */
27
- enableCodesandbox?: boolean;
28
22
  /**
29
23
  * determine how to handle a internal code block without meta
30
24
  * @default 'preview'
package/dist/index.js CHANGED
@@ -326,7 +326,7 @@ var demoBlockComponentPath = import_path.default.join(
326
326
  var json = JSON.parse(
327
327
  import_fs_extra.default.readFileSync((0, import_path2.resolve)(process.cwd(), "./package.json"), "utf8")
328
328
  );
329
- var remarkCodeToDemo = ({ isMobile, getRouteMeta, iframePosition, enableCodesandbox }) => {
329
+ var remarkCodeToDemo = ({ isMobile, getRouteMeta, iframePosition, defaultRenderMode }) => {
330
330
  const routeMeta2 = getRouteMeta();
331
331
  return (tree, vfile) => {
332
332
  const demos = [];
@@ -378,11 +378,6 @@ var remarkCodeToDemo = ({ isMobile, getRouteMeta, iframePosition, enableCodesand
378
378
  type: "mdxJsxAttribute",
379
379
  name: "packageName",
380
380
  value: json.name
381
- },
382
- {
383
- type: "mdxJsxAttribute",
384
- name: "enableCodesandbox",
385
- value: enableCodesandbox
386
381
  }
387
382
  ],
388
383
  children: [
@@ -422,8 +417,20 @@ var remarkCodeToDemo = ({ isMobile, getRouteMeta, iframePosition, enableCodesand
422
417
  }
423
418
  if (node.lang === "jsx" || node.lang === "tsx") {
424
419
  const value = injectDemoBlockImport(node.value, demoBlockComponentPath);
425
- const isPure = node?.meta?.includes("pure");
426
- if (isPure) {
420
+ const hasPureMeta = node?.meta?.includes("pure");
421
+ const hasPreviewMeta = node?.meta?.includes("preview");
422
+ let noTransform;
423
+ switch (defaultRenderMode) {
424
+ case "pure":
425
+ noTransform = !hasPreviewMeta;
426
+ break;
427
+ case "preview":
428
+ noTransform = hasPureMeta;
429
+ break;
430
+ default:
431
+ break;
432
+ }
433
+ if (noTransform) {
427
434
  return;
428
435
  }
429
436
  const isMobileMode = node?.meta?.includes("mobile") || !node?.meta?.includes("web") && isMobile;
@@ -532,7 +539,6 @@ var demoMeta = {};
532
539
  function pluginPreview(options) {
533
540
  const isMobile = options?.isMobile ?? false;
534
541
  const iframePosition = options?.iframePosition ?? "follow";
535
- const enableCodesandbox = options?.enableCodesandbox ?? false;
536
542
  const defaultRenderMode = options?.defaultRenderMode ?? "preview";
537
543
  const demoRuntimeModule = new import_rspack_plugin_virtual_module.RspackVirtualModulePlugin({});
538
544
  const globalUIComponents = iframePosition === "fixed" ? [(0, import_path3.join)(staticPath, "global-components", "Device.tsx")] : [];
@@ -694,7 +700,7 @@ import Demo from ${JSON.stringify(demoComponentPath)}
694
700
  remarkPlugins: [
695
701
  [
696
702
  remarkCodeToDemo,
697
- { isMobile, getRouteMeta, iframePosition, enableCodesandbox }
703
+ { isMobile, getRouteMeta, iframePosition, defaultRenderMode }
698
704
  ]
699
705
  ],
700
706
  globalComponents: [
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["index","is","visit","path","routeMeta","externalDemoIndex","fs","meta","pageName"],"sources":["../../../node_modules/.pnpm/unist-util-is@5.2.1/node_modules/unist-util-is/lib/index.js","../../../node_modules/.pnpm/unist-util-is@5.2.1/node_modules/unist-util-is/index.js","../../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/color.js","../../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/index.js","../../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/index.js","../../../node_modules/.pnpm/unist-util-visit@4.1.1/node_modules/unist-util-visit/index.js","../src/index.ts","../src/codeToDemo.ts","../src/utils.ts","../src/constant.ts"],"sourcesContent":["/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n */\n\n/**\n * @typedef {Record<string, unknown>} Props\n * @typedef {null | undefined | string | Props | TestFunctionAnything | Array<string | Props | TestFunctionAnything>} Test\n * Check for an arbitrary node, unaware of TypeScript inferral.\n *\n * @callback TestFunctionAnything\n * Check if a node passes a test, unaware of TypeScript inferral.\n * @param {unknown} this\n * The given context.\n * @param {Node} node\n * A node.\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {boolean | void}\n * Whether this node passes the test.\n */\n\n/**\n * @template {Node} Kind\n * Node type.\n * @typedef {Kind['type'] | Partial<Kind> | TestFunctionPredicate<Kind> | Array<Kind['type'] | Partial<Kind> | TestFunctionPredicate<Kind>>} PredicateTest\n * Check for a node that can be inferred by TypeScript.\n */\n\n/**\n * Check if a node passes a certain test.\n *\n * @template {Node} Kind\n * Node type.\n * @callback TestFunctionPredicate\n * Complex test function for a node that can be inferred by TypeScript.\n * @param {Node} node\n * A node.\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {node is Kind}\n * Whether this node passes the test.\n */\n\n/**\n * @callback AssertAnything\n * Check that an arbitrary value is a node, unaware of TypeScript inferral.\n * @param {unknown} [node]\n * Anything (typically a node).\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {boolean}\n * Whether this is a node and passes a test.\n */\n\n/**\n * Check if a node is a node and passes a certain node test.\n *\n * @template {Node} Kind\n * Node type.\n * @callback AssertPredicate\n * Check that an arbitrary value is a specific node, aware of TypeScript.\n * @param {unknown} [node]\n * Anything (typically a node).\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {node is Kind}\n * Whether this is a node and passes a test.\n */\n\n/**\n * Check if `node` is a `Node` and whether it passes the given test.\n *\n * @param node\n * Thing to check, typically `Node`.\n * @param test\n * A check for a specific node.\n * @param index\n * The node’s position in its parent.\n * @param parent\n * The node’s parent.\n * @returns\n * Whether `node` is a node and passes a test.\n */\nexport const is =\n /**\n * @type {(\n * (() => false) &\n * (<Kind extends Node = Node>(node: unknown, test: PredicateTest<Kind>, index: number, parent: Parent, context?: unknown) => node is Kind) &\n * (<Kind extends Node = Node>(node: unknown, test: PredicateTest<Kind>, index?: null | undefined, parent?: null | undefined, context?: unknown) => node is Kind) &\n * ((node: unknown, test: Test, index: number, parent: Parent, context?: unknown) => boolean) &\n * ((node: unknown, test?: Test, index?: null | undefined, parent?: null | undefined, context?: unknown) => boolean)\n * )}\n */\n (\n /**\n * @param {unknown} [node]\n * @param {Test} [test]\n * @param {number | null | undefined} [index]\n * @param {Parent | null | undefined} [parent]\n * @param {unknown} [context]\n * @returns {boolean}\n */\n // eslint-disable-next-line max-params\n function is(node, test, index, parent, context) {\n const check = convert(test)\n\n if (\n index !== undefined &&\n index !== null &&\n (typeof index !== 'number' ||\n index < 0 ||\n index === Number.POSITIVE_INFINITY)\n ) {\n throw new Error('Expected positive finite index')\n }\n\n if (\n parent !== undefined &&\n parent !== null &&\n (!is(parent) || !parent.children)\n ) {\n throw new Error('Expected parent node')\n }\n\n if (\n (parent === undefined || parent === null) !==\n (index === undefined || index === null)\n ) {\n throw new Error('Expected both parent and index')\n }\n\n // @ts-expect-error Looks like a node.\n return node && node.type && typeof node.type === 'string'\n ? Boolean(check.call(context, node, index, parent))\n : false\n }\n )\n\n/**\n * Generate an assertion from a test.\n *\n * Useful if you’re going to test many nodes, for example when creating a\n * utility where something else passes a compatible test.\n *\n * The created function is a bit faster because it expects valid input only:\n * a `node`, `index`, and `parent`.\n *\n * @param test\n * * when nullish, checks if `node` is a `Node`.\n * * when `string`, works like passing `(node) => node.type === test`.\n * * when `function` checks if function passed the node is true.\n * * when `object`, checks that all keys in test are in node, and that they have (strictly) equal values.\n * * when `array`, checks if any one of the subtests pass.\n * @returns\n * An assertion.\n */\nexport const convert =\n /**\n * @type {(\n * (<Kind extends Node>(test: PredicateTest<Kind>) => AssertPredicate<Kind>) &\n * ((test?: Test) => AssertAnything)\n * )}\n */\n (\n /**\n * @param {Test} [test]\n * @returns {AssertAnything}\n */\n function (test) {\n if (test === undefined || test === null) {\n return ok\n }\n\n if (typeof test === 'string') {\n return typeFactory(test)\n }\n\n if (typeof test === 'object') {\n return Array.isArray(test) ? anyFactory(test) : propsFactory(test)\n }\n\n if (typeof test === 'function') {\n return castFactory(test)\n }\n\n throw new Error('Expected function, string, or object as test')\n }\n )\n\n/**\n * @param {Array<string | Props | TestFunctionAnything>} tests\n * @returns {AssertAnything}\n */\nfunction anyFactory(tests) {\n /** @type {Array<AssertAnything>} */\n const checks = []\n let index = -1\n\n while (++index < tests.length) {\n checks[index] = convert(tests[index])\n }\n\n return castFactory(any)\n\n /**\n * @this {unknown}\n * @param {Array<unknown>} parameters\n * @returns {boolean}\n */\n function any(...parameters) {\n let index = -1\n\n while (++index < checks.length) {\n if (checks[index].call(this, ...parameters)) return true\n }\n\n return false\n }\n}\n\n/**\n * Turn an object into a test for a node with a certain fields.\n *\n * @param {Props} check\n * @returns {AssertAnything}\n */\nfunction propsFactory(check) {\n return castFactory(all)\n\n /**\n * @param {Node} node\n * @returns {boolean}\n */\n function all(node) {\n /** @type {string} */\n let key\n\n for (key in check) {\n // @ts-expect-error: hush, it sure works as an index.\n if (node[key] !== check[key]) return false\n }\n\n return true\n }\n}\n\n/**\n * Turn a string into a test for a node with a certain type.\n *\n * @param {string} check\n * @returns {AssertAnything}\n */\nfunction typeFactory(check) {\n return castFactory(type)\n\n /**\n * @param {Node} node\n */\n function type(node) {\n return node && node.type === check\n }\n}\n\n/**\n * Turn a custom test into a test for a node that passes that test.\n *\n * @param {TestFunctionAnything} check\n * @returns {AssertAnything}\n */\nfunction castFactory(check) {\n return assertion\n\n /**\n * @this {unknown}\n * @param {unknown} node\n * @param {Array<unknown>} parameters\n * @returns {boolean}\n */\n function assertion(node, ...parameters) {\n return Boolean(\n node &&\n typeof node === 'object' &&\n 'type' in node &&\n // @ts-expect-error: fine.\n Boolean(check.call(this, node, ...parameters))\n )\n }\n}\n\nfunction ok() {\n return true\n}\n","/**\n * @typedef {import('./lib/index.js').Test} Test\n * @typedef {import('./lib/index.js').TestFunctionAnything} TestFunctionAnything\n * @typedef {import('./lib/index.js').AssertAnything} AssertAnything\n */\n\n/**\n * @template {import('unist').Node} Kind\n * @typedef {import('./lib/index.js').PredicateTest<Kind>} PredicateTest\n */\n\n/**\n * @template {import('unist').Node} Kind\n * @typedef {import('./lib/index.js').TestFunctionPredicate<Kind>} TestFunctionPredicate\n */\n\n/**\n * @template {import('unist').Node} Kind\n * @typedef {import('./lib/index.js').AssertPredicate<Kind>} AssertPredicate\n */\n\nexport {is, convert} from './lib/index.js'\n","/**\n * @param {string} d\n * @returns {string}\n */\nexport function color(d) {\n return '\\u001B[33m' + d + '\\u001B[39m'\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n * @typedef {import('unist-util-is').Test} Test\n */\n\n/**\n * @typedef {boolean | 'skip'} Action\n * Union of the action types.\n *\n * @typedef {number} Index\n * Move to the sibling at `index` next (after node itself is completely\n * traversed).\n *\n * Useful if mutating the tree, such as removing the node the visitor is\n * currently on, or any of its previous siblings.\n * Results less than 0 or greater than or equal to `children.length` stop\n * traversing the parent.\n *\n * @typedef {[(Action | null | undefined | void)?, (Index | null | undefined)?]} ActionTuple\n * List with one or two values, the first an action, the second an index.\n *\n * @typedef {Action | ActionTuple | Index | null | undefined | void} VisitorResult\n * Any value that can be returned from a visitor.\n */\n\n/**\n * @template {Node} [Visited=Node]\n * Visited node type.\n * @template {Parent} [Ancestor=Parent]\n * Ancestor type.\n * @callback Visitor\n * Handle a node (matching `test`, if given).\n *\n * Visitors are free to transform `node`.\n * They can also transform the parent of node (the last of `ancestors`).\n *\n * Replacing `node` itself, if `SKIP` is not returned, still causes its\n * descendants to be walked (which is a bug).\n *\n * When adding or removing previous siblings of `node` (or next siblings, in\n * case of reverse), the `Visitor` should return a new `Index` to specify the\n * sibling to traverse after `node` is traversed.\n * Adding or removing next siblings of `node` (or previous siblings, in case\n * of reverse) is handled as expected without needing to return a new `Index`.\n *\n * Removing the children property of an ancestor still results in them being\n * traversed.\n * @param {Visited} node\n * Found node.\n * @param {Array<Ancestor>} ancestors\n * Ancestors of `node`.\n * @returns {VisitorResult}\n * What to do next.\n *\n * An `Index` is treated as a tuple of `[CONTINUE, Index]`.\n * An `Action` is treated as a tuple of `[Action]`.\n *\n * Passing a tuple back only makes sense if the `Action` is `SKIP`.\n * When the `Action` is `EXIT`, that action can be returned.\n * When the `Action` is `CONTINUE`, `Index` can be returned.\n */\n\n/**\n * @template {Node} [Tree=Node]\n * Tree type.\n * @template {Test} [Check=string]\n * Test type.\n * @typedef {Visitor<import('./complex-types.js').Matches<import('./complex-types.js').InclusiveDescendant<Tree>, Check>, Extract<import('./complex-types.js').InclusiveDescendant<Tree>, Parent>>} BuildVisitor\n * Build a typed `Visitor` function from a tree and a test.\n *\n * It will infer which values are passed as `node` and which as `parents`.\n */\n\nimport {convert} from 'unist-util-is'\nimport {color} from './color.js'\n\n/**\n * Continue traversing as normal.\n */\nexport const CONTINUE = true\n\n/**\n * Stop traversing immediately.\n */\nexport const EXIT = false\n\n/**\n * Do not traverse this node’s children.\n */\nexport const SKIP = 'skip'\n\n/**\n * Visit nodes, with ancestral information.\n *\n * This algorithm performs *depth-first* *tree traversal* in *preorder*\n * (**NLR**) or if `reverse` is given, in *reverse preorder* (**NRL**).\n *\n * You can choose for which nodes `visitor` is called by passing a `test`.\n * For complex tests, you should test yourself in `visitor`, as it will be\n * faster and will have improved type information.\n *\n * Walking the tree is an intensive task.\n * Make use of the return values of the visitor when possible.\n * Instead of walking a tree multiple times, walk it once, use `unist-util-is`\n * to check if a node matches, and then perform different operations.\n *\n * You can change the tree.\n * See `Visitor` for more info.\n *\n * @param tree\n * Tree to traverse.\n * @param test\n * `unist-util-is`-compatible test\n * @param visitor\n * Handle each node.\n * @param reverse\n * Traverse in reverse preorder (NRL) instead of the default preorder (NLR).\n * @returns\n * Nothing.\n */\nexport const visitParents =\n /**\n * @type {(\n * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: BuildVisitor<Tree, Check>, reverse?: boolean | null | undefined) => void) &\n * (<Tree extends Node>(tree: Tree, visitor: BuildVisitor<Tree>, reverse?: boolean | null | undefined) => void)\n * )}\n */\n (\n /**\n * @param {Node} tree\n * @param {Test} test\n * @param {Visitor<Node>} visitor\n * @param {boolean | null | undefined} [reverse]\n * @returns {void}\n */\n function (tree, test, visitor, reverse) {\n if (typeof test === 'function' && typeof visitor !== 'function') {\n reverse = visitor\n // @ts-expect-error no visitor given, so `visitor` is test.\n visitor = test\n test = null\n }\n\n const is = convert(test)\n const step = reverse ? -1 : 1\n\n factory(tree, undefined, [])()\n\n /**\n * @param {Node} node\n * @param {number | undefined} index\n * @param {Array<Parent>} parents\n */\n function factory(node, index, parents) {\n /** @type {Record<string, unknown>} */\n // @ts-expect-error: hush\n const value = node && typeof node === 'object' ? node : {}\n\n if (typeof value.type === 'string') {\n const name =\n // `hast`\n typeof value.tagName === 'string'\n ? value.tagName\n : // `xast`\n typeof value.name === 'string'\n ? value.name\n : undefined\n\n Object.defineProperty(visit, 'name', {\n value:\n 'node (' + color(node.type + (name ? '<' + name + '>' : '')) + ')'\n })\n }\n\n return visit\n\n function visit() {\n /** @type {ActionTuple} */\n let result = []\n /** @type {ActionTuple} */\n let subresult\n /** @type {number} */\n let offset\n /** @type {Array<Parent>} */\n let grandparents\n\n if (!test || is(node, index, parents[parents.length - 1] || null)) {\n result = toResult(visitor(node, parents))\n\n if (result[0] === EXIT) {\n return result\n }\n }\n\n // @ts-expect-error looks like a parent.\n if (node.children && result[0] !== SKIP) {\n // @ts-expect-error looks like a parent.\n offset = (reverse ? node.children.length : -1) + step\n // @ts-expect-error looks like a parent.\n grandparents = parents.concat(node)\n\n // @ts-expect-error looks like a parent.\n while (offset > -1 && offset < node.children.length) {\n // @ts-expect-error looks like a parent.\n subresult = factory(node.children[offset], offset, grandparents)()\n\n if (subresult[0] === EXIT) {\n return subresult\n }\n\n offset =\n typeof subresult[1] === 'number' ? subresult[1] : offset + step\n }\n }\n\n return result\n }\n }\n }\n )\n\n/**\n * Turn a return value into a clean result.\n *\n * @param {VisitorResult} value\n * Valid return values from visitors.\n * @returns {ActionTuple}\n * Clean result.\n */\nfunction toResult(value) {\n if (Array.isArray(value)) {\n return value\n }\n\n if (typeof value === 'number') {\n return [CONTINUE, value]\n }\n\n return [value]\n}\n","// Note: types exported from `index.d.ts`\nexport {CONTINUE, EXIT, SKIP, visitParents} from './lib/index.js'\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n * @typedef {import('unist-util-is').Test} Test\n * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult\n * @typedef {import('./complex-types.js').Visitor} Visitor\n */\n\nimport {visitParents} from 'unist-util-visit-parents'\n\n/**\n * Visit children of tree which pass test.\n *\n * @param tree\n * Tree to walk\n * @param [test]\n * `unist-util-is`-compatible test\n * @param visitor\n * Function called for nodes that pass `test`.\n * @param reverse\n * Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).\n */\nexport const visit =\n /**\n * @type {(\n * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types.js').BuildVisitor<Tree, Check>, reverse?: boolean) => void) &\n * (<Tree extends Node>(tree: Tree, visitor: import('./complex-types.js').BuildVisitor<Tree>, reverse?: boolean) => void)\n * )}\n */\n (\n /**\n * @param {Node} tree\n * @param {Test} test\n * @param {import('./complex-types.js').Visitor} visitor\n * @param {boolean} [reverse]\n */\n function (tree, test, visitor, reverse) {\n if (typeof test === 'function' && typeof visitor !== 'function') {\n reverse = visitor\n visitor = test\n test = null\n }\n\n visitParents(tree, test, overload, reverse)\n\n /**\n * @param {Node} node\n * @param {Array<Parent>} parents\n */\n function overload(node, parents) {\n const parent = parents[parents.length - 1]\n return visitor(\n node,\n parent ? parent.children.indexOf(node) : null,\n parent\n )\n }\n }\n )\n\nexport {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents'\n","import { join, parse, extname } from 'path';\nimport { type Code } from 'mdast';\nimport { RspackVirtualModulePlugin } from 'rspack-plugin-virtual-module';\nimport {\n type RspressPlugin,\n type RouteMeta,\n RSPRESS_TEMP_DIR,\n normalizePosixPath,\n} from '@rspress/shared';\nimport { uniqBy } from 'lodash';\nimport { remarkCodeToDemo } from './codeToDemo';\nimport { generateId, injectDemoBlockImport } from './utils';\nimport {\n demoBlockComponentPath,\n demoComponentPath,\n staticPath,\n} from './constant';\n\nexport type Options = {\n /**\n * preview in mobile mode or not\n * when isMobile is true, 1. aside will hide. 2. default preview component by iframe\n * @default false\n */\n isMobile?: boolean;\n /**\n * position of the iframe\n * @default 'follow'\n */\n iframePosition?: 'fixed' | 'follow';\n /**\n * whether the demo can open in codesandbox\n * @default false\n * @experimental\n */\n enableCodesandbox?: boolean;\n /**\n * determine how to handle a internal code block without meta\n * @default 'preview'\n */\n defaultRenderMode?: 'pure' | 'preview';\n};\n\ninterface Heading {\n type: string;\n depth?: number;\n children?: ChildNode[];\n}\n\ninterface ChildNode {\n type: 'link' | 'text' | 'inlineCode';\n value: string;\n children?: ChildNode[];\n}\n\n// eslint-disable-next-line import/no-mutable-exports\nexport let routeMeta: RouteMeta[];\nexport const demoRoutes: { path: string }[] = [];\nexport const demoMeta: Record<\n string,\n { id: string; virtualModulePath: string; title: string }[]\n> = {};\n\n/**\n * The plugin is used to preview component.\n */\nexport function pluginPreview(options?: Options): RspressPlugin {\n const isMobile = options?.isMobile ?? false;\n const iframePosition = options?.iframePosition ?? 'follow';\n const enableCodesandbox = options?.enableCodesandbox ?? false;\n const defaultRenderMode = options?.defaultRenderMode ?? 'preview';\n\n const demoRuntimeModule = new RspackVirtualModulePlugin({});\n const globalUIComponents =\n iframePosition === 'fixed'\n ? [join(staticPath, 'global-components', 'Device.tsx')]\n : [];\n const getRouteMeta = () => routeMeta;\n return {\n name: '@rspress/plugin-preview',\n config(config) {\n config.markdown = config.markdown || {};\n config.markdown.mdxRs = false;\n return config;\n },\n addPages(_config, _isProd) {\n return [\n {\n routePath: '/~demo/:id',\n content: `---\npageType: \"blank\"\n---\n\nimport Demo from ${JSON.stringify(demoComponentPath)}\n\n<Demo iframePosition=\"${iframePosition}\"/>\n `,\n },\n ];\n },\n async routeGenerated(routes: RouteMeta[]) {\n // init routeMeta\n routeMeta = routes;\n\n const files = routes.map(route => route.absolutePath);\n // Write the demo code ahead of time\n // Fix: rspack build error because demo file is not exist, probably the demo file was written in rspack build process?\n await Promise.all(\n files.map(async (filepath, _index) => {\n const isMdxFile = /\\.mdx?$/.test(filepath);\n if (!isMdxFile) {\n return;\n }\n const { createProcessor } = await import('@mdx-js/mdx');\n const { visit } = await import('unist-util-visit');\n const { default: fs } = await import('@modern-js/utils/fs-extra');\n const { default: remarkGFM } = await import('remark-gfm');\n let title = parse(filepath).name;\n try {\n const processor = createProcessor({\n format: extname(filepath).slice(1) as 'mdx' | 'md',\n remarkPlugins: [remarkGFM],\n });\n const source = await fs.readFile(filepath, 'utf-8');\n const ast = processor.parse(source);\n let index = 1;\n const { pageName } = routeMeta.find(\n meta =>\n normalizePosixPath(meta.absolutePath) ===\n normalizePosixPath(filepath),\n )!;\n\n const registerDemo = (\n demoId: string,\n demoPath: string,\n isMobileMode: boolean,\n ) => {\n if (isMobileMode) {\n // only add demoMeta in mobile mode\n demoMeta[filepath] = demoMeta[filepath] ?? [];\n const isExist = demoMeta[filepath].find(\n item => item.id === demoId,\n );\n if (!isExist) {\n demoMeta[filepath].push({\n id: demoId,\n title,\n virtualModulePath: demoPath,\n });\n }\n }\n };\n visit(ast, 'heading', (node: Heading) => {\n if (node.depth === 1) {\n if (node.children) {\n title = node.children[0].value;\n }\n }\n });\n\n visit(ast, 'mdxJsxFlowElement', (node: any) => {\n if (node.name === 'code') {\n const src = node.attributes.find(\n (attr: { name: string; value: string }) =>\n attr.name === 'src',\n )?.value;\n const isMobileMode =\n node.attributes.find(\n (attr: { name: string; value: boolean }) =>\n attr.name === 'isMobile',\n )?.value ?? isMobile;\n if (!src) {\n return;\n }\n const id = generateId(pageName, index++);\n registerDemo(id, src, isMobileMode);\n }\n });\n\n visit(ast, 'code', (node: Code) => {\n if (node.lang === 'jsx' || node.lang === 'tsx') {\n const { value, meta } = node;\n const hasPureMeta = meta?.includes('pure');\n const hasPreviewMeta = meta?.includes('preview');\n\n let noTransform;\n switch (defaultRenderMode) {\n case 'pure':\n noTransform = !hasPreviewMeta;\n break;\n case 'preview':\n noTransform = hasPureMeta;\n break;\n default:\n break;\n }\n\n // do not anything for pure mode\n if (noTransform) {\n return;\n }\n\n // every code block can change their preview mode by meta\n const isMobileMode =\n node?.meta?.includes('mobile') ||\n (!node?.meta?.includes('web') && isMobile);\n\n const { pageName } = routeMeta.find(\n meta =>\n normalizePosixPath(meta.absolutePath) ===\n normalizePosixPath(filepath),\n )!;\n const id = generateId(pageName, index++);\n\n const demoDir = join(\n process.cwd(),\n 'node_modules',\n RSPRESS_TEMP_DIR,\n `virtual-demo`,\n );\n\n const virtualModulePath = join(demoDir, `${id}.tsx`);\n registerDemo(id, virtualModulePath, isMobileMode);\n\n fs.ensureDirSync(join(demoDir));\n fs.writeFileSync(\n virtualModulePath,\n injectDemoBlockImport(value, demoBlockComponentPath),\n );\n }\n });\n } catch (e) {\n console.error(e);\n throw e;\n }\n }),\n );\n /**\n * expect the meta of each demo file is like this:\n * {\n * id,\n * component,\n * }\n */\n const virtualMeta = `\n ${files\n .map((filepath, index) => {\n return `import Route${index} from '${filepath}?meta';`;\n })\n .join('\\n')}\n export const demos = [${files\n .map((_, index) => `Route${index}`)\n .flat()\n .join(',')}];\n `;\n demoRuntimeModule.writeModule('virtual-meta', virtualMeta);\n },\n builderConfig: {\n source: {\n include: [join(__dirname, '..')],\n },\n tools: {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error\n // @ts-ignore\n rspack: {\n plugins: [demoRuntimeModule],\n },\n bundlerChain(chain) {\n chain.module\n .rule('Raw')\n .resourceQuery(/raw/)\n .type('asset/source')\n .end()\n .rule('MDX')\n .oneOf('MDXMeta')\n .before('MDXCompile')\n .resourceQuery(/meta/)\n .use('mdx-meta-loader')\n .loader(join(__dirname, '../mdx-meta-loader.cjs'))\n .end();\n\n chain.resolve.extensions.prepend('.md').prepend('.mdx');\n },\n },\n },\n markdown: {\n remarkPlugins: [\n [\n remarkCodeToDemo,\n { isMobile, getRouteMeta, iframePosition, enableCodesandbox },\n ],\n ],\n globalComponents: [\n join(staticPath, 'global-components', 'Container.tsx'),\n ],\n },\n globalUIComponents,\n globalStyles: join(\n staticPath,\n 'global-styles',\n `${isMobile ? 'mobile' : 'web'}.css`,\n ),\n addSSGRoutes() {\n if (iframePosition === 'fixed') {\n const normalizeRoutes = demoRoutes.map(({ path: item }) => {\n const fragments = item.split('/').filter(Boolean);\n const demoId = fragments.pop()?.replace(/_(\\d+)$/, '');\n return { path: `/${fragments.join('/')}/${demoId}` };\n });\n // Unique the routes accrodint to the path\n return uniqBy(normalizeRoutes, 'path');\n }\n return demoRoutes;\n },\n };\n}\n\nexport { normalizeId } from './utils';\n","import { join, resolve } from 'path';\nimport { visit } from 'unist-util-visit';\nimport fs from '@modern-js/utils/fs-extra';\nimport {\n RSPRESS_TEMP_DIR,\n normalizePosixPath,\n type RouteMeta,\n} from '@rspress/shared';\nimport type { Plugin } from 'unified';\nimport type { Root } from 'mdast';\nimport type { MdxjsEsm } from 'mdast-util-mdxjs-esm';\nimport { injectDemoBlockImport, generateId } from './utils';\nimport { demoBlockComponentPath } from './constant';\nimport { demoRoutes } from '.';\n\n// FIXME: remove it\nconst json = JSON.parse(\n fs.readFileSync(resolve(process.cwd(), './package.json'), 'utf8'),\n);\n\n/**\n * remark plugin to transform code to demo\n */\nexport const remarkCodeToDemo: Plugin<\n [\n {\n isMobile: boolean;\n getRouteMeta: () => RouteMeta[];\n iframePosition: 'fixed' | 'follow';\n enableCodesandbox: boolean;\n },\n ],\n Root\n> = ({ isMobile, getRouteMeta, iframePosition, enableCodesandbox }) => {\n const routeMeta = getRouteMeta();\n\n return (tree, vfile) => {\n const demos: MdxjsEsm[] = [];\n const route = routeMeta.find(\n meta =>\n normalizePosixPath(meta.absolutePath) ===\n normalizePosixPath(vfile.path || vfile.history[0]),\n );\n if (!route) {\n return;\n }\n const { pageName } = route;\n let index = 1;\n let externalDemoIndex = 0;\n\n function constructDemoNode(\n demoId: string,\n demoPath: string,\n currentNode: any,\n isMobileMode: boolean,\n // Only for external demo\n externalDemoIndex?: number,\n ) {\n const demoRoute = `/~demo/${demoId}`;\n if (isMobileMode) {\n // only add demoRoutes in mobile mode\n demoRoutes.push({\n path: demoRoute,\n });\n } else {\n demos.push(getASTNodeImport(`Demo${demoId}`, demoPath));\n }\n\n // get external demo content\n const tempVar = `externalDemoContent${externalDemoIndex}`;\n if (externalDemoIndex !== undefined) {\n // Such as `import externalDemoContent0 from '!!xxx?raw'`\n // `!!` prefix is used to avoid other loaders in rspack\n demos.push(getASTNodeImport(tempVar, `!!${demoPath}?raw`));\n }\n\n if (isMobileMode && iframePosition === 'fixed') {\n // Only show the code block\n externalDemoIndex !== undefined &&\n Object.assign(currentNode, getExternalDemoContent(tempVar));\n } else {\n // Use container to show the code and view\n Object.assign(currentNode, {\n type: 'mdxJsxFlowElement',\n name: 'Container',\n attributes: [\n {\n type: 'mdxJsxAttribute',\n name: 'isMobile',\n value: isMobileMode,\n },\n {\n type: 'mdxJsxAttribute',\n name: 'url',\n value: demoRoute,\n },\n {\n type: 'mdxJsxAttribute',\n name: 'content',\n value: currentNode.value,\n },\n {\n type: 'mdxJsxAttribute',\n name: 'packageName',\n value: json.name,\n },\n {\n type: 'mdxJsxAttribute',\n name: 'enableCodesandbox',\n value: enableCodesandbox,\n },\n ],\n children: [\n externalDemoIndex === undefined\n ? {\n ...currentNode,\n hasVisited: true,\n }\n : getExternalDemoContent(tempVar),\n isMobileMode\n ? {\n type: 'mdxJsxFlowElement',\n name: null,\n }\n : {\n type: 'mdxJsxFlowElement',\n name: `Demo${demoId}`,\n },\n ],\n });\n }\n }\n // 1. External demo , use <code src=\"xxx\" /> to declare demo\n visit(tree, 'mdxJsxFlowElement', (node: any) => {\n if (node.name === 'code') {\n const src = node.attributes.find(\n (attr: { name: string; value: string }) => attr.name === 'src',\n )?.value;\n const isMobileMode =\n node.attributes.find(\n (attr: { name: string; value: boolean }) =>\n attr.name === 'isMobile',\n )?.value ?? isMobile;\n if (!src) {\n return;\n }\n const id = generateId(pageName, index++);\n constructDemoNode(id, src, node, isMobileMode, externalDemoIndex++);\n }\n });\n\n // 2. Internal demo, use ```j/tsx to declare demo\n visit(tree, 'code', node => {\n // hasVisited is a custom property\n if ('hasVisited' in node) {\n return;\n }\n\n if (node.lang === 'jsx' || node.lang === 'tsx') {\n const value = injectDemoBlockImport(node.value, demoBlockComponentPath);\n\n const isPure = node?.meta?.includes('pure');\n\n // do nothing for pure mode\n if (isPure) {\n return;\n }\n\n // every code block can change their preview mode by meta\n const isMobileMode =\n node?.meta?.includes('mobile') ||\n (!node?.meta?.includes('web') && isMobile);\n\n const demoDir = join(\n process.cwd(),\n 'node_modules',\n RSPRESS_TEMP_DIR,\n `virtual-demo`,\n );\n const id = generateId(pageName, index++);\n const virtualModulePath = join(demoDir, `${id}.tsx`);\n fs.ensureDirSync(join(demoDir));\n // Only when the content of the file changes, the file will be written\n // Avoid to trigger the hmr indefinitely\n if (fs.existsSync(virtualModulePath)) {\n const content = fs.readFileSync(virtualModulePath, 'utf-8');\n if (content !== value) {\n fs.writeFileSync(virtualModulePath, value);\n }\n }\n constructDemoNode(id, virtualModulePath, node, isMobileMode);\n }\n });\n\n tree.children.unshift(...demos);\n };\n};\n\nconst getASTNodeImport = (name: string, from: string) =>\n ({\n type: 'mdxjsEsm',\n value: `import ${name} from ${JSON.stringify(from)}`,\n data: {\n estree: {\n type: 'Program',\n sourceType: 'module',\n body: [\n {\n type: 'ImportDeclaration',\n specifiers: [\n {\n type: 'ImportDefaultSpecifier',\n local: { type: 'Identifier', name },\n },\n ],\n source: {\n type: 'Literal',\n value: from,\n raw: `${JSON.stringify(from)}`,\n },\n },\n ],\n },\n },\n } as MdxjsEsm);\n\nconst getExternalDemoContent = (tempVar: string) => ({\n /**\n * We create a empty parent node here. If we don't do this, the `pre` tag won't be rendered as our custom mdx component and will be rendered as a normal `pre` tag, which will cause the code block to be displayed incorrectly.\n */\n type: 'mdxJsxFlowElement',\n name: '',\n attributes: [],\n children: [\n {\n type: 'mdxJsxFlowElement',\n name: 'pre',\n attributes: [],\n children: [\n {\n type: 'mdxJsxFlowElement',\n name: 'code',\n attributes: [\n {\n type: 'mdxJsxAttribute',\n name: 'className',\n value: 'language-tsx',\n },\n {\n type: 'mdxJsxAttribute',\n name: 'children',\n value: {\n type: 'mdxJsxExpressionAttribute',\n value: tempVar,\n data: {\n estree: {\n type: 'Program',\n body: [\n {\n type: 'ExpressionStatement',\n expression: {\n type: 'Identifier',\n name: tempVar,\n },\n },\n ],\n },\n },\n },\n },\n ],\n },\n ],\n },\n ],\n});\n","/**\n * Converts a string to a valid variable name. If the string is already a valid variable name, returns the original string.\n * @param str - The string to convert.\n * @returns The converted string.\n */\nexport const toValidVarName = (str: string): string => {\n // Check if the string is a valid variable name\n if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(str)) {\n return str; // If it is a valid variable name, return the original string\n } else {\n // If it is not a valid variable name, convert it to a valid variable name\n return str.replace(/[^0-9a-zA-Z_$]/g, '_').replace(/^([0-9])/, '_$1');\n }\n};\n\nexport const generateId = (pageName: string, index: number) => {\n return `_${toValidVarName(pageName)}_${index}`;\n};\n\n/**\n * remove .html extension and validate\n * @param routePath id from pathname\n * @returns normalized id\n */\nexport const normalizeId = (routePath: string) => {\n const result = routePath.replace(/\\.(.*)?$/, '');\n return toValidVarName(result);\n};\n\nexport const injectDemoBlockImport = (str: string, path: string): string => {\n return `\n import DemoBlock from '${path}';\n ${str}\n `;\n};\n","import path from 'path';\n\nexport const staticPath = path.join(__dirname, '..', 'static');\n\nexport const demoComponentPath = path.join(\n __dirname,\n '..',\n 'dist',\n 'virtual-demo.js',\n);\n\nexport const demoBlockComponentPath = path.join(\n staticPath,\n 'global-components',\n 'DemoBlock.tsx',\n);\n"]}
1
+ {"version":3,"mappings":"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","names":["index","is","visit","path","routeMeta","externalDemoIndex","fs","meta","pageName"],"sources":["../../../node_modules/.pnpm/unist-util-is@5.2.1/node_modules/unist-util-is/lib/index.js","../../../node_modules/.pnpm/unist-util-is@5.2.1/node_modules/unist-util-is/index.js","../../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/color.js","../../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/lib/index.js","../../../node_modules/.pnpm/unist-util-visit-parents@5.1.3/node_modules/unist-util-visit-parents/index.js","../../../node_modules/.pnpm/unist-util-visit@4.1.1/node_modules/unist-util-visit/index.js","../src/index.ts","../src/codeToDemo.ts","../src/utils.ts","../src/constant.ts"],"sourcesContent":["/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n */\n\n/**\n * @typedef {Record<string, unknown>} Props\n * @typedef {null | undefined | string | Props | TestFunctionAnything | Array<string | Props | TestFunctionAnything>} Test\n * Check for an arbitrary node, unaware of TypeScript inferral.\n *\n * @callback TestFunctionAnything\n * Check if a node passes a test, unaware of TypeScript inferral.\n * @param {unknown} this\n * The given context.\n * @param {Node} node\n * A node.\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {boolean | void}\n * Whether this node passes the test.\n */\n\n/**\n * @template {Node} Kind\n * Node type.\n * @typedef {Kind['type'] | Partial<Kind> | TestFunctionPredicate<Kind> | Array<Kind['type'] | Partial<Kind> | TestFunctionPredicate<Kind>>} PredicateTest\n * Check for a node that can be inferred by TypeScript.\n */\n\n/**\n * Check if a node passes a certain test.\n *\n * @template {Node} Kind\n * Node type.\n * @callback TestFunctionPredicate\n * Complex test function for a node that can be inferred by TypeScript.\n * @param {Node} node\n * A node.\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {node is Kind}\n * Whether this node passes the test.\n */\n\n/**\n * @callback AssertAnything\n * Check that an arbitrary value is a node, unaware of TypeScript inferral.\n * @param {unknown} [node]\n * Anything (typically a node).\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {boolean}\n * Whether this is a node and passes a test.\n */\n\n/**\n * Check if a node is a node and passes a certain node test.\n *\n * @template {Node} Kind\n * Node type.\n * @callback AssertPredicate\n * Check that an arbitrary value is a specific node, aware of TypeScript.\n * @param {unknown} [node]\n * Anything (typically a node).\n * @param {number | null | undefined} [index]\n * The node’s position in its parent.\n * @param {Parent | null | undefined} [parent]\n * The node’s parent.\n * @returns {node is Kind}\n * Whether this is a node and passes a test.\n */\n\n/**\n * Check if `node` is a `Node` and whether it passes the given test.\n *\n * @param node\n * Thing to check, typically `Node`.\n * @param test\n * A check for a specific node.\n * @param index\n * The node’s position in its parent.\n * @param parent\n * The node’s parent.\n * @returns\n * Whether `node` is a node and passes a test.\n */\nexport const is =\n /**\n * @type {(\n * (() => false) &\n * (<Kind extends Node = Node>(node: unknown, test: PredicateTest<Kind>, index: number, parent: Parent, context?: unknown) => node is Kind) &\n * (<Kind extends Node = Node>(node: unknown, test: PredicateTest<Kind>, index?: null | undefined, parent?: null | undefined, context?: unknown) => node is Kind) &\n * ((node: unknown, test: Test, index: number, parent: Parent, context?: unknown) => boolean) &\n * ((node: unknown, test?: Test, index?: null | undefined, parent?: null | undefined, context?: unknown) => boolean)\n * )}\n */\n (\n /**\n * @param {unknown} [node]\n * @param {Test} [test]\n * @param {number | null | undefined} [index]\n * @param {Parent | null | undefined} [parent]\n * @param {unknown} [context]\n * @returns {boolean}\n */\n // eslint-disable-next-line max-params\n function is(node, test, index, parent, context) {\n const check = convert(test)\n\n if (\n index !== undefined &&\n index !== null &&\n (typeof index !== 'number' ||\n index < 0 ||\n index === Number.POSITIVE_INFINITY)\n ) {\n throw new Error('Expected positive finite index')\n }\n\n if (\n parent !== undefined &&\n parent !== null &&\n (!is(parent) || !parent.children)\n ) {\n throw new Error('Expected parent node')\n }\n\n if (\n (parent === undefined || parent === null) !==\n (index === undefined || index === null)\n ) {\n throw new Error('Expected both parent and index')\n }\n\n // @ts-expect-error Looks like a node.\n return node && node.type && typeof node.type === 'string'\n ? Boolean(check.call(context, node, index, parent))\n : false\n }\n )\n\n/**\n * Generate an assertion from a test.\n *\n * Useful if you’re going to test many nodes, for example when creating a\n * utility where something else passes a compatible test.\n *\n * The created function is a bit faster because it expects valid input only:\n * a `node`, `index`, and `parent`.\n *\n * @param test\n * * when nullish, checks if `node` is a `Node`.\n * * when `string`, works like passing `(node) => node.type === test`.\n * * when `function` checks if function passed the node is true.\n * * when `object`, checks that all keys in test are in node, and that they have (strictly) equal values.\n * * when `array`, checks if any one of the subtests pass.\n * @returns\n * An assertion.\n */\nexport const convert =\n /**\n * @type {(\n * (<Kind extends Node>(test: PredicateTest<Kind>) => AssertPredicate<Kind>) &\n * ((test?: Test) => AssertAnything)\n * )}\n */\n (\n /**\n * @param {Test} [test]\n * @returns {AssertAnything}\n */\n function (test) {\n if (test === undefined || test === null) {\n return ok\n }\n\n if (typeof test === 'string') {\n return typeFactory(test)\n }\n\n if (typeof test === 'object') {\n return Array.isArray(test) ? anyFactory(test) : propsFactory(test)\n }\n\n if (typeof test === 'function') {\n return castFactory(test)\n }\n\n throw new Error('Expected function, string, or object as test')\n }\n )\n\n/**\n * @param {Array<string | Props | TestFunctionAnything>} tests\n * @returns {AssertAnything}\n */\nfunction anyFactory(tests) {\n /** @type {Array<AssertAnything>} */\n const checks = []\n let index = -1\n\n while (++index < tests.length) {\n checks[index] = convert(tests[index])\n }\n\n return castFactory(any)\n\n /**\n * @this {unknown}\n * @param {Array<unknown>} parameters\n * @returns {boolean}\n */\n function any(...parameters) {\n let index = -1\n\n while (++index < checks.length) {\n if (checks[index].call(this, ...parameters)) return true\n }\n\n return false\n }\n}\n\n/**\n * Turn an object into a test for a node with a certain fields.\n *\n * @param {Props} check\n * @returns {AssertAnything}\n */\nfunction propsFactory(check) {\n return castFactory(all)\n\n /**\n * @param {Node} node\n * @returns {boolean}\n */\n function all(node) {\n /** @type {string} */\n let key\n\n for (key in check) {\n // @ts-expect-error: hush, it sure works as an index.\n if (node[key] !== check[key]) return false\n }\n\n return true\n }\n}\n\n/**\n * Turn a string into a test for a node with a certain type.\n *\n * @param {string} check\n * @returns {AssertAnything}\n */\nfunction typeFactory(check) {\n return castFactory(type)\n\n /**\n * @param {Node} node\n */\n function type(node) {\n return node && node.type === check\n }\n}\n\n/**\n * Turn a custom test into a test for a node that passes that test.\n *\n * @param {TestFunctionAnything} check\n * @returns {AssertAnything}\n */\nfunction castFactory(check) {\n return assertion\n\n /**\n * @this {unknown}\n * @param {unknown} node\n * @param {Array<unknown>} parameters\n * @returns {boolean}\n */\n function assertion(node, ...parameters) {\n return Boolean(\n node &&\n typeof node === 'object' &&\n 'type' in node &&\n // @ts-expect-error: fine.\n Boolean(check.call(this, node, ...parameters))\n )\n }\n}\n\nfunction ok() {\n return true\n}\n","/**\n * @typedef {import('./lib/index.js').Test} Test\n * @typedef {import('./lib/index.js').TestFunctionAnything} TestFunctionAnything\n * @typedef {import('./lib/index.js').AssertAnything} AssertAnything\n */\n\n/**\n * @template {import('unist').Node} Kind\n * @typedef {import('./lib/index.js').PredicateTest<Kind>} PredicateTest\n */\n\n/**\n * @template {import('unist').Node} Kind\n * @typedef {import('./lib/index.js').TestFunctionPredicate<Kind>} TestFunctionPredicate\n */\n\n/**\n * @template {import('unist').Node} Kind\n * @typedef {import('./lib/index.js').AssertPredicate<Kind>} AssertPredicate\n */\n\nexport {is, convert} from './lib/index.js'\n","/**\n * @param {string} d\n * @returns {string}\n */\nexport function color(d) {\n return '\\u001B[33m' + d + '\\u001B[39m'\n}\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n * @typedef {import('unist-util-is').Test} Test\n */\n\n/**\n * @typedef {boolean | 'skip'} Action\n * Union of the action types.\n *\n * @typedef {number} Index\n * Move to the sibling at `index` next (after node itself is completely\n * traversed).\n *\n * Useful if mutating the tree, such as removing the node the visitor is\n * currently on, or any of its previous siblings.\n * Results less than 0 or greater than or equal to `children.length` stop\n * traversing the parent.\n *\n * @typedef {[(Action | null | undefined | void)?, (Index | null | undefined)?]} ActionTuple\n * List with one or two values, the first an action, the second an index.\n *\n * @typedef {Action | ActionTuple | Index | null | undefined | void} VisitorResult\n * Any value that can be returned from a visitor.\n */\n\n/**\n * @template {Node} [Visited=Node]\n * Visited node type.\n * @template {Parent} [Ancestor=Parent]\n * Ancestor type.\n * @callback Visitor\n * Handle a node (matching `test`, if given).\n *\n * Visitors are free to transform `node`.\n * They can also transform the parent of node (the last of `ancestors`).\n *\n * Replacing `node` itself, if `SKIP` is not returned, still causes its\n * descendants to be walked (which is a bug).\n *\n * When adding or removing previous siblings of `node` (or next siblings, in\n * case of reverse), the `Visitor` should return a new `Index` to specify the\n * sibling to traverse after `node` is traversed.\n * Adding or removing next siblings of `node` (or previous siblings, in case\n * of reverse) is handled as expected without needing to return a new `Index`.\n *\n * Removing the children property of an ancestor still results in them being\n * traversed.\n * @param {Visited} node\n * Found node.\n * @param {Array<Ancestor>} ancestors\n * Ancestors of `node`.\n * @returns {VisitorResult}\n * What to do next.\n *\n * An `Index` is treated as a tuple of `[CONTINUE, Index]`.\n * An `Action` is treated as a tuple of `[Action]`.\n *\n * Passing a tuple back only makes sense if the `Action` is `SKIP`.\n * When the `Action` is `EXIT`, that action can be returned.\n * When the `Action` is `CONTINUE`, `Index` can be returned.\n */\n\n/**\n * @template {Node} [Tree=Node]\n * Tree type.\n * @template {Test} [Check=string]\n * Test type.\n * @typedef {Visitor<import('./complex-types.js').Matches<import('./complex-types.js').InclusiveDescendant<Tree>, Check>, Extract<import('./complex-types.js').InclusiveDescendant<Tree>, Parent>>} BuildVisitor\n * Build a typed `Visitor` function from a tree and a test.\n *\n * It will infer which values are passed as `node` and which as `parents`.\n */\n\nimport {convert} from 'unist-util-is'\nimport {color} from './color.js'\n\n/**\n * Continue traversing as normal.\n */\nexport const CONTINUE = true\n\n/**\n * Stop traversing immediately.\n */\nexport const EXIT = false\n\n/**\n * Do not traverse this node’s children.\n */\nexport const SKIP = 'skip'\n\n/**\n * Visit nodes, with ancestral information.\n *\n * This algorithm performs *depth-first* *tree traversal* in *preorder*\n * (**NLR**) or if `reverse` is given, in *reverse preorder* (**NRL**).\n *\n * You can choose for which nodes `visitor` is called by passing a `test`.\n * For complex tests, you should test yourself in `visitor`, as it will be\n * faster and will have improved type information.\n *\n * Walking the tree is an intensive task.\n * Make use of the return values of the visitor when possible.\n * Instead of walking a tree multiple times, walk it once, use `unist-util-is`\n * to check if a node matches, and then perform different operations.\n *\n * You can change the tree.\n * See `Visitor` for more info.\n *\n * @param tree\n * Tree to traverse.\n * @param test\n * `unist-util-is`-compatible test\n * @param visitor\n * Handle each node.\n * @param reverse\n * Traverse in reverse preorder (NRL) instead of the default preorder (NLR).\n * @returns\n * Nothing.\n */\nexport const visitParents =\n /**\n * @type {(\n * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: BuildVisitor<Tree, Check>, reverse?: boolean | null | undefined) => void) &\n * (<Tree extends Node>(tree: Tree, visitor: BuildVisitor<Tree>, reverse?: boolean | null | undefined) => void)\n * )}\n */\n (\n /**\n * @param {Node} tree\n * @param {Test} test\n * @param {Visitor<Node>} visitor\n * @param {boolean | null | undefined} [reverse]\n * @returns {void}\n */\n function (tree, test, visitor, reverse) {\n if (typeof test === 'function' && typeof visitor !== 'function') {\n reverse = visitor\n // @ts-expect-error no visitor given, so `visitor` is test.\n visitor = test\n test = null\n }\n\n const is = convert(test)\n const step = reverse ? -1 : 1\n\n factory(tree, undefined, [])()\n\n /**\n * @param {Node} node\n * @param {number | undefined} index\n * @param {Array<Parent>} parents\n */\n function factory(node, index, parents) {\n /** @type {Record<string, unknown>} */\n // @ts-expect-error: hush\n const value = node && typeof node === 'object' ? node : {}\n\n if (typeof value.type === 'string') {\n const name =\n // `hast`\n typeof value.tagName === 'string'\n ? value.tagName\n : // `xast`\n typeof value.name === 'string'\n ? value.name\n : undefined\n\n Object.defineProperty(visit, 'name', {\n value:\n 'node (' + color(node.type + (name ? '<' + name + '>' : '')) + ')'\n })\n }\n\n return visit\n\n function visit() {\n /** @type {ActionTuple} */\n let result = []\n /** @type {ActionTuple} */\n let subresult\n /** @type {number} */\n let offset\n /** @type {Array<Parent>} */\n let grandparents\n\n if (!test || is(node, index, parents[parents.length - 1] || null)) {\n result = toResult(visitor(node, parents))\n\n if (result[0] === EXIT) {\n return result\n }\n }\n\n // @ts-expect-error looks like a parent.\n if (node.children && result[0] !== SKIP) {\n // @ts-expect-error looks like a parent.\n offset = (reverse ? node.children.length : -1) + step\n // @ts-expect-error looks like a parent.\n grandparents = parents.concat(node)\n\n // @ts-expect-error looks like a parent.\n while (offset > -1 && offset < node.children.length) {\n // @ts-expect-error looks like a parent.\n subresult = factory(node.children[offset], offset, grandparents)()\n\n if (subresult[0] === EXIT) {\n return subresult\n }\n\n offset =\n typeof subresult[1] === 'number' ? subresult[1] : offset + step\n }\n }\n\n return result\n }\n }\n }\n )\n\n/**\n * Turn a return value into a clean result.\n *\n * @param {VisitorResult} value\n * Valid return values from visitors.\n * @returns {ActionTuple}\n * Clean result.\n */\nfunction toResult(value) {\n if (Array.isArray(value)) {\n return value\n }\n\n if (typeof value === 'number') {\n return [CONTINUE, value]\n }\n\n return [value]\n}\n","// Note: types exported from `index.d.ts`\nexport {CONTINUE, EXIT, SKIP, visitParents} from './lib/index.js'\n","/**\n * @typedef {import('unist').Node} Node\n * @typedef {import('unist').Parent} Parent\n * @typedef {import('unist-util-is').Test} Test\n * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult\n * @typedef {import('./complex-types.js').Visitor} Visitor\n */\n\nimport {visitParents} from 'unist-util-visit-parents'\n\n/**\n * Visit children of tree which pass test.\n *\n * @param tree\n * Tree to walk\n * @param [test]\n * `unist-util-is`-compatible test\n * @param visitor\n * Function called for nodes that pass `test`.\n * @param reverse\n * Traverse in reverse preorder (NRL) instead of preorder (NLR) (default).\n */\nexport const visit =\n /**\n * @type {(\n * (<Tree extends Node, Check extends Test>(tree: Tree, test: Check, visitor: import('./complex-types.js').BuildVisitor<Tree, Check>, reverse?: boolean) => void) &\n * (<Tree extends Node>(tree: Tree, visitor: import('./complex-types.js').BuildVisitor<Tree>, reverse?: boolean) => void)\n * )}\n */\n (\n /**\n * @param {Node} tree\n * @param {Test} test\n * @param {import('./complex-types.js').Visitor} visitor\n * @param {boolean} [reverse]\n */\n function (tree, test, visitor, reverse) {\n if (typeof test === 'function' && typeof visitor !== 'function') {\n reverse = visitor\n visitor = test\n test = null\n }\n\n visitParents(tree, test, overload, reverse)\n\n /**\n * @param {Node} node\n * @param {Array<Parent>} parents\n */\n function overload(node, parents) {\n const parent = parents[parents.length - 1]\n return visitor(\n node,\n parent ? parent.children.indexOf(node) : null,\n parent\n )\n }\n }\n )\n\nexport {CONTINUE, EXIT, SKIP} from 'unist-util-visit-parents'\n","import { join, parse, extname } from 'path';\nimport { type Code } from 'mdast';\nimport { RspackVirtualModulePlugin } from 'rspack-plugin-virtual-module';\nimport {\n type RspressPlugin,\n type RouteMeta,\n RSPRESS_TEMP_DIR,\n normalizePosixPath,\n} from '@rspress/shared';\nimport { uniqBy } from 'lodash';\nimport { remarkCodeToDemo } from './codeToDemo';\nimport { generateId, injectDemoBlockImport } from './utils';\nimport {\n demoBlockComponentPath,\n demoComponentPath,\n staticPath,\n} from './constant';\n\nexport type Options = {\n /**\n * preview in mobile mode or not\n * when isMobile is true, 1. aside will hide. 2. default preview component by iframe\n * @default false\n */\n isMobile?: boolean;\n /**\n * position of the iframe\n * @default 'follow'\n */\n iframePosition?: 'fixed' | 'follow';\n /**\n * determine how to handle a internal code block without meta\n * @default 'preview'\n */\n defaultRenderMode?: 'pure' | 'preview';\n};\n\ninterface Heading {\n type: string;\n depth?: number;\n children?: ChildNode[];\n}\n\ninterface ChildNode {\n type: 'link' | 'text' | 'inlineCode';\n value: string;\n children?: ChildNode[];\n}\n\n// eslint-disable-next-line import/no-mutable-exports\nexport let routeMeta: RouteMeta[];\nexport const demoRoutes: { path: string }[] = [];\nexport const demoMeta: Record<\n string,\n { id: string; virtualModulePath: string; title: string }[]\n> = {};\n\n/**\n * The plugin is used to preview component.\n */\nexport function pluginPreview(options?: Options): RspressPlugin {\n const isMobile = options?.isMobile ?? false;\n const iframePosition = options?.iframePosition ?? 'follow';\n const defaultRenderMode = options?.defaultRenderMode ?? 'preview';\n\n const demoRuntimeModule = new RspackVirtualModulePlugin({});\n const globalUIComponents =\n iframePosition === 'fixed'\n ? [join(staticPath, 'global-components', 'Device.tsx')]\n : [];\n const getRouteMeta = () => routeMeta;\n return {\n name: '@rspress/plugin-preview',\n config(config) {\n config.markdown = config.markdown || {};\n config.markdown.mdxRs = false;\n return config;\n },\n addPages(_config, _isProd) {\n return [\n {\n routePath: '/~demo/:id',\n content: `---\npageType: \"blank\"\n---\n\nimport Demo from ${JSON.stringify(demoComponentPath)}\n\n<Demo iframePosition=\"${iframePosition}\"/>\n `,\n },\n ];\n },\n async routeGenerated(routes: RouteMeta[]) {\n // init routeMeta\n routeMeta = routes;\n\n const files = routes.map(route => route.absolutePath);\n // Write the demo code ahead of time\n // Fix: rspack build error because demo file is not exist, probably the demo file was written in rspack build process?\n await Promise.all(\n files.map(async (filepath, _index) => {\n const isMdxFile = /\\.mdx?$/.test(filepath);\n if (!isMdxFile) {\n return;\n }\n const { createProcessor } = await import('@mdx-js/mdx');\n const { visit } = await import('unist-util-visit');\n const { default: fs } = await import('@modern-js/utils/fs-extra');\n const { default: remarkGFM } = await import('remark-gfm');\n let title = parse(filepath).name;\n try {\n const processor = createProcessor({\n format: extname(filepath).slice(1) as 'mdx' | 'md',\n remarkPlugins: [remarkGFM],\n });\n const source = await fs.readFile(filepath, 'utf-8');\n const ast = processor.parse(source);\n let index = 1;\n const { pageName } = routeMeta.find(\n meta =>\n normalizePosixPath(meta.absolutePath) ===\n normalizePosixPath(filepath),\n )!;\n\n const registerDemo = (\n demoId: string,\n demoPath: string,\n isMobileMode: boolean,\n ) => {\n if (isMobileMode) {\n // only add demoMeta in mobile mode\n demoMeta[filepath] = demoMeta[filepath] ?? [];\n const isExist = demoMeta[filepath].find(\n item => item.id === demoId,\n );\n if (!isExist) {\n demoMeta[filepath].push({\n id: demoId,\n title,\n virtualModulePath: demoPath,\n });\n }\n }\n };\n visit(ast, 'heading', (node: Heading) => {\n if (node.depth === 1) {\n if (node.children) {\n title = node.children[0].value;\n }\n }\n });\n\n visit(ast, 'mdxJsxFlowElement', (node: any) => {\n if (node.name === 'code') {\n const src = node.attributes.find(\n (attr: { name: string; value: string }) =>\n attr.name === 'src',\n )?.value;\n const isMobileMode =\n node.attributes.find(\n (attr: { name: string; value: boolean }) =>\n attr.name === 'isMobile',\n )?.value ?? isMobile;\n if (!src) {\n return;\n }\n const id = generateId(pageName, index++);\n registerDemo(id, src, isMobileMode);\n }\n });\n\n visit(ast, 'code', (node: Code) => {\n if (node.lang === 'jsx' || node.lang === 'tsx') {\n const { value, meta } = node;\n const hasPureMeta = meta?.includes('pure');\n const hasPreviewMeta = meta?.includes('preview');\n\n let noTransform;\n switch (defaultRenderMode) {\n case 'pure':\n noTransform = !hasPreviewMeta;\n break;\n case 'preview':\n noTransform = hasPureMeta;\n break;\n default:\n break;\n }\n\n // do not anything for pure mode\n if (noTransform) {\n return;\n }\n\n // every code block can change their preview mode by meta\n const isMobileMode =\n node?.meta?.includes('mobile') ||\n (!node?.meta?.includes('web') && isMobile);\n\n const { pageName } = routeMeta.find(\n meta =>\n normalizePosixPath(meta.absolutePath) ===\n normalizePosixPath(filepath),\n )!;\n const id = generateId(pageName, index++);\n\n const demoDir = join(\n process.cwd(),\n 'node_modules',\n RSPRESS_TEMP_DIR,\n `virtual-demo`,\n );\n\n const virtualModulePath = join(demoDir, `${id}.tsx`);\n registerDemo(id, virtualModulePath, isMobileMode);\n\n fs.ensureDirSync(join(demoDir));\n fs.writeFileSync(\n virtualModulePath,\n injectDemoBlockImport(value, demoBlockComponentPath),\n );\n }\n });\n } catch (e) {\n console.error(e);\n throw e;\n }\n }),\n );\n /**\n * expect the meta of each demo file is like this:\n * {\n * id,\n * component,\n * }\n */\n const virtualMeta = `\n ${files\n .map((filepath, index) => {\n return `import Route${index} from '${filepath}?meta';`;\n })\n .join('\\n')}\n export const demos = [${files\n .map((_, index) => `Route${index}`)\n .flat()\n .join(',')}];\n `;\n demoRuntimeModule.writeModule('virtual-meta', virtualMeta);\n },\n builderConfig: {\n source: {\n include: [join(__dirname, '..')],\n },\n tools: {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment, @typescript-eslint/prefer-ts-expect-error\n // @ts-ignore\n rspack: {\n plugins: [demoRuntimeModule],\n },\n bundlerChain(chain) {\n chain.module\n .rule('Raw')\n .resourceQuery(/raw/)\n .type('asset/source')\n .end()\n .rule('MDX')\n .oneOf('MDXMeta')\n .before('MDXCompile')\n .resourceQuery(/meta/)\n .use('mdx-meta-loader')\n .loader(join(__dirname, '../mdx-meta-loader.cjs'))\n .end();\n\n chain.resolve.extensions.prepend('.md').prepend('.mdx');\n },\n },\n },\n markdown: {\n remarkPlugins: [\n [\n remarkCodeToDemo,\n { isMobile, getRouteMeta, iframePosition, defaultRenderMode },\n ],\n ],\n globalComponents: [\n join(staticPath, 'global-components', 'Container.tsx'),\n ],\n },\n globalUIComponents,\n globalStyles: join(\n staticPath,\n 'global-styles',\n `${isMobile ? 'mobile' : 'web'}.css`,\n ),\n addSSGRoutes() {\n if (iframePosition === 'fixed') {\n const normalizeRoutes = demoRoutes.map(({ path: item }) => {\n const fragments = item.split('/').filter(Boolean);\n const demoId = fragments.pop()?.replace(/_(\\d+)$/, '');\n return { path: `/${fragments.join('/')}/${demoId}` };\n });\n // Unique the routes accrodint to the path\n return uniqBy(normalizeRoutes, 'path');\n }\n return demoRoutes;\n },\n };\n}\n\nexport { normalizeId } from './utils';\n","import { join, resolve } from 'path';\nimport { visit } from 'unist-util-visit';\nimport fs from '@modern-js/utils/fs-extra';\nimport {\n RSPRESS_TEMP_DIR,\n normalizePosixPath,\n type RouteMeta,\n} from '@rspress/shared';\nimport type { Plugin } from 'unified';\nimport type { Root } from 'mdast';\nimport type { MdxjsEsm } from 'mdast-util-mdxjs-esm';\nimport { injectDemoBlockImport, generateId } from './utils';\nimport { demoBlockComponentPath } from './constant';\nimport { demoRoutes } from '.';\n\n// FIXME: remove it\nconst json = JSON.parse(\n fs.readFileSync(resolve(process.cwd(), './package.json'), 'utf8'),\n);\n\n/**\n * remark plugin to transform code to demo\n */\nexport const remarkCodeToDemo: Plugin<\n [\n {\n isMobile: boolean;\n getRouteMeta: () => RouteMeta[];\n iframePosition: 'fixed' | 'follow';\n defaultRenderMode: 'pure' | 'preview';\n },\n ],\n Root\n> = ({ isMobile, getRouteMeta, iframePosition, defaultRenderMode }) => {\n const routeMeta = getRouteMeta();\n\n return (tree, vfile) => {\n const demos: MdxjsEsm[] = [];\n const route = routeMeta.find(\n meta =>\n normalizePosixPath(meta.absolutePath) ===\n normalizePosixPath(vfile.path || vfile.history[0]),\n );\n if (!route) {\n return;\n }\n const { pageName } = route;\n let index = 1;\n let externalDemoIndex = 0;\n\n function constructDemoNode(\n demoId: string,\n demoPath: string,\n currentNode: any,\n isMobileMode: boolean,\n // Only for external demo\n externalDemoIndex?: number,\n ) {\n const demoRoute = `/~demo/${demoId}`;\n if (isMobileMode) {\n // only add demoRoutes in mobile mode\n demoRoutes.push({\n path: demoRoute,\n });\n } else {\n demos.push(getASTNodeImport(`Demo${demoId}`, demoPath));\n }\n\n // get external demo content\n const tempVar = `externalDemoContent${externalDemoIndex}`;\n if (externalDemoIndex !== undefined) {\n // Such as `import externalDemoContent0 from '!!xxx?raw'`\n // `!!` prefix is used to avoid other loaders in rspack\n demos.push(getASTNodeImport(tempVar, `!!${demoPath}?raw`));\n }\n\n if (isMobileMode && iframePosition === 'fixed') {\n // Only show the code block\n externalDemoIndex !== undefined &&\n Object.assign(currentNode, getExternalDemoContent(tempVar));\n } else {\n // Use container to show the code and view\n Object.assign(currentNode, {\n type: 'mdxJsxFlowElement',\n name: 'Container',\n attributes: [\n {\n type: 'mdxJsxAttribute',\n name: 'isMobile',\n value: isMobileMode,\n },\n {\n type: 'mdxJsxAttribute',\n name: 'url',\n value: demoRoute,\n },\n {\n type: 'mdxJsxAttribute',\n name: 'content',\n value: currentNode.value,\n },\n {\n type: 'mdxJsxAttribute',\n name: 'packageName',\n value: json.name,\n },\n ],\n children: [\n externalDemoIndex === undefined\n ? {\n ...currentNode,\n hasVisited: true,\n }\n : getExternalDemoContent(tempVar),\n isMobileMode\n ? {\n type: 'mdxJsxFlowElement',\n name: null,\n }\n : {\n type: 'mdxJsxFlowElement',\n name: `Demo${demoId}`,\n },\n ],\n });\n }\n }\n // 1. External demo , use <code src=\"xxx\" /> to declare demo\n visit(tree, 'mdxJsxFlowElement', (node: any) => {\n if (node.name === 'code') {\n const src = node.attributes.find(\n (attr: { name: string; value: string }) => attr.name === 'src',\n )?.value;\n const isMobileMode =\n node.attributes.find(\n (attr: { name: string; value: boolean }) =>\n attr.name === 'isMobile',\n )?.value ?? isMobile;\n if (!src) {\n return;\n }\n const id = generateId(pageName, index++);\n constructDemoNode(id, src, node, isMobileMode, externalDemoIndex++);\n }\n });\n\n // 2. Internal demo, use ```j/tsx to declare demo\n visit(tree, 'code', node => {\n // hasVisited is a custom property\n if ('hasVisited' in node) {\n return;\n }\n\n if (node.lang === 'jsx' || node.lang === 'tsx') {\n const value = injectDemoBlockImport(node.value, demoBlockComponentPath);\n\n const hasPureMeta = node?.meta?.includes('pure');\n const hasPreviewMeta = node?.meta?.includes('preview');\n\n let noTransform;\n switch (defaultRenderMode) {\n case 'pure':\n noTransform = !hasPreviewMeta;\n break;\n case 'preview':\n noTransform = hasPureMeta;\n break;\n default:\n break;\n }\n\n // do not anything for pure mode\n if (noTransform) {\n return;\n }\n\n // every code block can change their preview mode by meta\n const isMobileMode =\n node?.meta?.includes('mobile') ||\n (!node?.meta?.includes('web') && isMobile);\n\n const demoDir = join(\n process.cwd(),\n 'node_modules',\n RSPRESS_TEMP_DIR,\n `virtual-demo`,\n );\n const id = generateId(pageName, index++);\n const virtualModulePath = join(demoDir, `${id}.tsx`);\n fs.ensureDirSync(join(demoDir));\n // Only when the content of the file changes, the file will be written\n // Avoid to trigger the hmr indefinitely\n if (fs.existsSync(virtualModulePath)) {\n const content = fs.readFileSync(virtualModulePath, 'utf-8');\n if (content !== value) {\n fs.writeFileSync(virtualModulePath, value);\n }\n }\n constructDemoNode(id, virtualModulePath, node, isMobileMode);\n }\n });\n\n tree.children.unshift(...demos);\n };\n};\n\nconst getASTNodeImport = (name: string, from: string) =>\n ({\n type: 'mdxjsEsm',\n value: `import ${name} from ${JSON.stringify(from)}`,\n data: {\n estree: {\n type: 'Program',\n sourceType: 'module',\n body: [\n {\n type: 'ImportDeclaration',\n specifiers: [\n {\n type: 'ImportDefaultSpecifier',\n local: { type: 'Identifier', name },\n },\n ],\n source: {\n type: 'Literal',\n value: from,\n raw: `${JSON.stringify(from)}`,\n },\n },\n ],\n },\n },\n } as MdxjsEsm);\n\nconst getExternalDemoContent = (tempVar: string) => ({\n /**\n * We create a empty parent node here. If we don't do this, the `pre` tag won't be rendered as our custom mdx component and will be rendered as a normal `pre` tag, which will cause the code block to be displayed incorrectly.\n */\n type: 'mdxJsxFlowElement',\n name: '',\n attributes: [],\n children: [\n {\n type: 'mdxJsxFlowElement',\n name: 'pre',\n attributes: [],\n children: [\n {\n type: 'mdxJsxFlowElement',\n name: 'code',\n attributes: [\n {\n type: 'mdxJsxAttribute',\n name: 'className',\n value: 'language-tsx',\n },\n {\n type: 'mdxJsxAttribute',\n name: 'children',\n value: {\n type: 'mdxJsxExpressionAttribute',\n value: tempVar,\n data: {\n estree: {\n type: 'Program',\n body: [\n {\n type: 'ExpressionStatement',\n expression: {\n type: 'Identifier',\n name: tempVar,\n },\n },\n ],\n },\n },\n },\n },\n ],\n },\n ],\n },\n ],\n});\n","/**\n * Converts a string to a valid variable name. If the string is already a valid variable name, returns the original string.\n * @param str - The string to convert.\n * @returns The converted string.\n */\nexport const toValidVarName = (str: string): string => {\n // Check if the string is a valid variable name\n if (/^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(str)) {\n return str; // If it is a valid variable name, return the original string\n } else {\n // If it is not a valid variable name, convert it to a valid variable name\n return str.replace(/[^0-9a-zA-Z_$]/g, '_').replace(/^([0-9])/, '_$1');\n }\n};\n\nexport const generateId = (pageName: string, index: number) => {\n return `_${toValidVarName(pageName)}_${index}`;\n};\n\n/**\n * remove .html extension and validate\n * @param routePath id from pathname\n * @returns normalized id\n */\nexport const normalizeId = (routePath: string) => {\n const result = routePath.replace(/\\.(.*)?$/, '');\n return toValidVarName(result);\n};\n\nexport const injectDemoBlockImport = (str: string, path: string): string => {\n return `\n import DemoBlock from '${path}';\n ${str}\n `;\n};\n","import path from 'path';\n\nexport const staticPath = path.join(__dirname, '..', 'static');\n\nexport const demoComponentPath = path.join(\n __dirname,\n '..',\n 'dist',\n 'virtual-demo.js',\n);\n\nexport const demoBlockComponentPath = path.join(\n staticPath,\n 'global-components',\n 'DemoBlock.tsx',\n);\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspress/plugin-preview",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "A plugin for rspress to preview the code block in markdown/mdx file.",
5
5
  "bugs": "https://github.com/web-infra-dev/rspress/issues",
6
6
  "repository": {
@@ -21,13 +21,12 @@
21
21
  ],
22
22
  "dependencies": {
23
23
  "@mdx-js/mdx": "2.2.1",
24
- "@modern-js/utils": "2.41.0",
24
+ "@modern-js/utils": "2.42.0",
25
25
  "qrcode.react": "^3.1.0",
26
26
  "remark-gfm": "3.0.1",
27
27
  "rspack-plugin-virtual-module": "0.1.12",
28
- "codesandbox": "2.2.3",
29
28
  "lodash": "4.17.21",
30
- "@rspress/shared": "1.8.0"
29
+ "@rspress/shared": "1.8.2"
31
30
  },
32
31
  "devDependencies": {
33
32
  "@types/mdast": "^3.0.10",
@@ -1,22 +1,18 @@
1
1
  import { useCallback, useState } from 'react';
2
2
  import { withBase, useLang, NoSSR } from '@rspress/core/runtime';
3
- import { getParameters } from 'codesandbox/lib/api/define';
4
3
  import MobileOperation from './common/mobile-operation';
5
4
  import IconCode from './icons/Code';
6
- import IconCodesandbox from './icons/Codesandbox';
7
5
 
8
6
  type ContainerProps = {
9
7
  children: React.ReactNode[];
10
8
  isMobile: 'true' | 'false';
11
- enableCodesandbox: 'true' | 'false';
12
9
  url: string;
13
10
  content: string;
14
11
  packageName: string;
15
12
  };
16
13
 
17
14
  const Container: React.FC<ContainerProps> = props => {
18
- const { children, isMobile, url, content, packageName, enableCodesandbox } =
19
- props;
15
+ const { children, isMobile, url } = props;
20
16
  const [showCode, setShowCode] = useState(false);
21
17
  const lang = useLang();
22
18
 
@@ -39,54 +35,6 @@ const Container: React.FC<ContainerProps> = props => {
39
35
  setIframeKey(Math.random());
40
36
  }, []);
41
37
 
42
- const gotoCodeSandBox = () => {
43
- const sandBoxConfig = {
44
- files: {
45
- 'package.json': {
46
- isBinary: false,
47
- content: JSON.stringify({
48
- dependencies: {
49
- react: '18',
50
- 'react-dom': '18',
51
- [packageName]: 'latest',
52
- },
53
- }),
54
- },
55
- [`demo.tsx`]: {
56
- isBinary: false,
57
- content,
58
- },
59
- [`index.tsx`]: {
60
- isBinary: false,
61
- content: [
62
- `import React from 'react'`,
63
- `import ReactDOM from 'react-dom'`,
64
- `import Demo from './demo'`,
65
- `ReactDOM.render(<Demo />, document.getElementById('root'))`,
66
- ].join('\n'),
67
- },
68
- },
69
- };
70
-
71
- // to specific demo file
72
- const query = `file=/demo.tsx`;
73
- const form = document.createElement('form');
74
- form.action = `https://codesandbox.io/api/v1/sandboxes/define?query=${encodeURIComponent(
75
- query,
76
- )}`;
77
- form.target = '_blank';
78
- form.method = 'POST';
79
- form.style.display = 'none';
80
- const field = document.createElement('input');
81
- field.name = 'parameters';
82
- field.type = 'hidden';
83
- field.setAttribute('value', getParameters(sandBoxConfig));
84
- form.appendChild(field);
85
- document.body.appendChild(form);
86
- form.submit();
87
- document.body.removeChild(form);
88
- };
89
-
90
38
  return (
91
39
  <NoSSR>
92
40
  <div className="rspress-preview">
@@ -95,13 +43,7 @@ const Container: React.FC<ContainerProps> = props => {
95
43
  <div className="rspress-preview-code">{children?.[0]}</div>
96
44
  <div className="rspress-preview-device">
97
45
  <iframe src={getPageUrl()} key={iframeKey}></iframe>
98
- <MobileOperation
99
- url={url}
100
- refresh={refresh}
101
- gotoCodeSandBox={
102
- enableCodesandbox === 'true' ? gotoCodeSandBox : undefined
103
- }
104
- />
46
+ <MobileOperation url={url} refresh={refresh} />
105
47
  </div>
106
48
  </div>
107
49
  ) : (
@@ -116,18 +58,6 @@ const Container: React.FC<ContainerProps> = props => {
116
58
  {children?.[1]}
117
59
  </div>
118
60
  <div className="rspress-preview-operations web">
119
- {enableCodesandbox === 'true' && (
120
- <button
121
- onClick={gotoCodeSandBox}
122
- aria-label={
123
- lang === 'zh'
124
- ? '在 Codesandbox 打开'
125
- : 'Open in Codesandbox'
126
- }
127
- >
128
- <IconCodesandbox />
129
- </button>
130
- )}
131
61
  <button
132
62
  onClick={toggleCode}
133
63
  aria-label={lang === 'zh' ? '收起代码' : 'Collapse Code'}
@@ -4,19 +4,16 @@ import { withBase, useLang } from '@rspress/core/runtime';
4
4
  import IconLaunch from '../icons/Launch';
5
5
  import IconQrcode from '../icons/Qrcode';
6
6
  import IconRefresh from '../icons/Refresh';
7
- import IconCodesandbox from '../icons/Codesandbox';
8
7
  import './index.scss';
9
8
 
10
9
  const locales = {
11
10
  zh: {
12
11
  refresh: '刷新页面',
13
12
  open: '在新页面打开',
14
- codesandbox: '在 Codesandbox 打开',
15
13
  },
16
14
  en: {
17
15
  refresh: 'Refresh',
18
16
  open: 'Open in new page',
19
- codesandbox: 'Open in Codesandbox',
20
17
  },
21
18
  };
22
19
 
@@ -24,10 +21,9 @@ export default (props: {
24
21
  url: string;
25
22
  className?: string;
26
23
  refresh: () => void;
27
- gotoCodeSandBox?: () => void;
28
24
  }) => {
29
25
  const [showQRCode, setShowQRCode] = useState(false);
30
- const { url, className = '', refresh, gotoCodeSandBox } = props;
26
+ const { url, className = '', refresh } = props;
31
27
  const lang = useLang();
32
28
  const triggerRef = useRef(null);
33
29
  const t = lang === 'zh' ? locales.zh : locales.en;
@@ -90,11 +86,6 @@ export default (props: {
90
86
 
91
87
  return (
92
88
  <div className={`rspress-preview-operations mobile ${className}`}>
93
- {gotoCodeSandBox && (
94
- <button onClick={gotoCodeSandBox} aria-label={t.codesandbox}>
95
- <IconCodesandbox />
96
- </button>
97
- )}
98
89
  <button onClick={refresh} aria-label={t.refresh}>
99
90
  <IconRefresh />
100
91
  </button>
@@ -1,22 +0,0 @@
1
- const Codesandbox = ({ color = 'currentColor', ...props }) => (
2
- <svg
3
- width="1em"
4
- height="1em"
5
- viewBox="0 0 48 48"
6
- fill="none"
7
- stroke={color}
8
- strokeWidth="4"
9
- xmlns="http://www.w3.org/2000/svg"
10
- {...props}
11
- >
12
- <path
13
- d="M25.0016 1.5998L42.9016 11.8998C43.5016 12.2998 43.9016 12.8998 43.9016 13.5998V34.2998C43.9016 34.9998 43.5016 35.6998 42.9016 35.9998L25.0016 46.3998C24.4016 46.7998 23.6016 46.7998 23.0016 46.3998L5.10156 36.0998C4.50156 35.6998 4.10156 35.0998 4.10156 34.3998V13.6998C4.10156 12.9998 4.50156 12.2998 5.10156 11.9998L23.0016 1.5998C23.6016 1.1998 24.4016 1.1998 25.0016 1.5998ZM38.5016 13.9998L30.6016 9.49981L24.0016 13.9998L17.5016 9.9998L10.2016 14.2998L24.0016 22.9998L38.5016 13.9998ZM22.0016 40.3998V26.2998L8.00156 17.3998V25.2998L16.0016 30.7998V36.9998L22.0016 40.3998ZM26.0016 40.3998L32.0016 36.8998V31.6998L40.0016 26.1998V17.2998L26.0016 26.1998V40.3998Z"
14
- fill="currentColor"
15
- stroke="none"
16
- stroke-width="none"
17
- stroke-linecap="butt"
18
- ></path>
19
- </svg>
20
- );
21
-
22
- export default Codesandbox;