dumi 2.0.0-beta.2 → 2.0.0-beta.5

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.
Files changed (45) hide show
  1. package/dist/assetParsers/atom.d.ts +21 -0
  2. package/dist/assetParsers/atom.js +112 -0
  3. package/dist/assetParsers/block.d.ts +1 -4
  4. package/dist/assetParsers/block.js +2 -12
  5. package/dist/client/theme-api/DumiDemo.js +1 -1
  6. package/dist/client/theme-api/DumiPage.d.ts +4 -0
  7. package/dist/client/theme-api/DumiPage.js +39 -0
  8. package/dist/client/theme-api/context.d.ts +2 -0
  9. package/dist/client/theme-api/context.js +1 -0
  10. package/dist/client/theme-api/index.d.ts +3 -1
  11. package/dist/client/theme-api/index.js +3 -1
  12. package/dist/client/theme-api/types.d.ts +14 -1
  13. package/dist/client/theme-api/useAtomAssets.d.ts +4 -0
  14. package/dist/client/theme-api/useAtomAssets.js +9 -0
  15. package/dist/client/theme-api/useSidebarData.js +4 -2
  16. package/dist/features/compile.js +2 -1
  17. package/dist/features/configPlugins/schema.js +3 -2
  18. package/dist/features/meta.d.ts +2 -0
  19. package/dist/features/meta.js +53 -19
  20. package/dist/features/parser.d.ts +3 -0
  21. package/dist/features/parser.js +66 -0
  22. package/dist/features/routes.js +15 -5
  23. package/dist/features/tabs.d.ts +5 -0
  24. package/dist/features/tabs.js +106 -0
  25. package/dist/features/theme/index.js +2 -1
  26. package/dist/loaders/markdown/index.js +4 -9
  27. package/dist/loaders/markdown/transformer/rehypeJsxify.js +1 -1
  28. package/dist/loaders/markdown/transformer/remarkMeta.js +7 -2
  29. package/dist/loaders/page/index.d.ts +1 -0
  30. package/dist/loaders/page/index.js +41 -0
  31. package/dist/preset.js +3 -1
  32. package/dist/types.d.ts +7 -1
  33. package/dist/utils.d.ts +7 -0
  34. package/dist/utils.js +18 -2
  35. package/package.json +3 -2
  36. package/theme-default/builtins/API/index.d.ts +5 -0
  37. package/theme-default/builtins/API/index.js +57 -0
  38. package/theme-default/locales/en-US.json +9 -1
  39. package/theme-default/locales/zh-CN.json +9 -1
  40. package/theme-default/slots/Content/index.less +19 -1
  41. package/theme-default/slots/ContentTabs/index.d.ts +11 -0
  42. package/theme-default/slots/ContentTabs/index.js +35 -0
  43. package/theme-default/slots/ContentTabs/index.less +57 -0
  44. package/theme-default/styles/variables.less +1 -0
  45. package/dist/client/tsconfig.json +0 -13
@@ -0,0 +1,21 @@
1
+ import { AtomComponentAsset, AtomFunctionAsset } from 'dumi-assets-types';
2
+ declare class AtomAssetsParser {
3
+ private entryDir;
4
+ private resolveDir;
5
+ private unresolvedFiles;
6
+ private parser;
7
+ private resolverDeferrer;
8
+ private watcher;
9
+ private cbs;
10
+ constructor(opts: {
11
+ entryFile: string;
12
+ resolveDir: string;
13
+ watch?: boolean;
14
+ });
15
+ parse(): Promise<{
16
+ components: Record<string, AtomComponentAsset>;
17
+ functions: Record<string, AtomFunctionAsset>;
18
+ }>;
19
+ watch(cb: AtomAssetsParser['cbs'][number]): void;
20
+ }
21
+ export default AtomAssetsParser;
@@ -0,0 +1,112 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/assetParsers/atom.ts
23
+ var atom_exports = {};
24
+ __export(atom_exports, {
25
+ default: () => atom_default
26
+ });
27
+ module.exports = __toCommonJS(atom_exports);
28
+ var import_parser = require("dumi-afx-deps/compiled/parser");
29
+ var import_path = __toESM(require("path"));
30
+ var import_plugin_utils = require("umi/plugin-utils");
31
+ var MAX_PARSE_SIZE = 1024 * 512;
32
+ var AtomAssetsParser = class {
33
+ constructor(opts) {
34
+ this.unresolvedFiles = [];
35
+ this.watcher = null;
36
+ this.cbs = [];
37
+ this.resolveDir = opts.resolveDir;
38
+ this.entryDir = import_path.default.relative(opts.resolveDir, import_path.default.dirname(opts.entryFile));
39
+ this.parser = new import_parser.SchemaParser({
40
+ entryPath: opts.entryFile,
41
+ basePath: opts.resolveDir,
42
+ unPkgHost: "https://unpkg.com"
43
+ });
44
+ }
45
+ async parse() {
46
+ if (!this.resolverDeferrer || this.unresolvedFiles.length) {
47
+ this.resolverDeferrer = (async () => {
48
+ await this.parser.patch(this.unresolvedFiles);
49
+ return new import_parser.SchemaResolver(await this.parser.parse());
50
+ })();
51
+ }
52
+ return this.resolverDeferrer.then((resolver) => {
53
+ const components = {};
54
+ const functions = {};
55
+ resolver.componentList.forEach((id) => {
56
+ let propsConfig = resolver.getComponent(id).props;
57
+ const size = Buffer.byteLength(JSON.stringify(propsConfig));
58
+ if (size > MAX_PARSE_SIZE) {
59
+ propsConfig = { type: "object", properties: {} };
60
+ import_plugin_utils.logger.warn(`Parsed component ${id} props size ${size} exceeds 512KB, skip it.`);
61
+ }
62
+ components[id] = {
63
+ type: "COMPONENT",
64
+ id,
65
+ title: id,
66
+ propsConfig
67
+ };
68
+ });
69
+ resolver.functionList.forEach((id) => {
70
+ let signature = resolver.getFunction(id).signature;
71
+ const size = Buffer.byteLength(JSON.stringify(signature));
72
+ if (size > MAX_PARSE_SIZE) {
73
+ signature = { arguments: [] };
74
+ import_plugin_utils.logger.warn(`Parsed function ${id} signature size ${size} exceeds 512KB, skip it.`);
75
+ }
76
+ functions[id] = {
77
+ type: "FUNCTION",
78
+ id,
79
+ title: id,
80
+ signature
81
+ };
82
+ });
83
+ return { components, functions };
84
+ });
85
+ }
86
+ watch(cb) {
87
+ this.cbs.push(cb);
88
+ if (!this.watcher) {
89
+ const lazyParse = import_plugin_utils.lodash.debounce(() => {
90
+ this.parse().then((data) => this.cbs.forEach((cb2) => cb2(data)));
91
+ }, 100);
92
+ this.watcher = import_plugin_utils.chokidar.watch(this.entryDir, {
93
+ cwd: this.resolveDir,
94
+ ignored: [
95
+ "**/.*",
96
+ "**/.*/**",
97
+ "**/_*",
98
+ "**/_*/**",
99
+ "**/*.{md,less,scss,sass,styl,css}"
100
+ ]
101
+ }).on("all", (ev, file) => {
102
+ if (["add", "change"].includes(ev) && /\.(j|t)sx?$/.test(file)) {
103
+ this.unresolvedFiles.push(file);
104
+ lazyParse();
105
+ }
106
+ });
107
+ }
108
+ }
109
+ };
110
+ var atom_default = AtomAssetsParser;
111
+ // Annotate the CommonJS export names for ESM import in node:
112
+ 0 && (module.exports = {});
@@ -1,13 +1,10 @@
1
+ import { parseCodeFrontmatter } from "../utils";
1
2
  import type { ExampleBlockAsset } from 'dumi-assets-types';
2
3
  export interface IParsedBlockAsset {
3
4
  asset: ExampleBlockAsset;
4
5
  sources: Record<string, string>;
5
6
  frontmatter: ReturnType<typeof parseCodeFrontmatter>['frontmatter'];
6
7
  }
7
- declare function parseCodeFrontmatter(raw: string): {
8
- code: string;
9
- frontmatter: Record<string, any> | null;
10
- };
11
8
  declare function parseBlockAsset(opts: {
12
9
  fileAbsPath: string;
13
10
  id: string;
@@ -25,21 +25,11 @@ __export(block_exports, {
25
25
  default: () => block_default
26
26
  });
27
27
  module.exports = __toCommonJS(block_exports);
28
+ var import_utils = require("../utils");
28
29
  var import_esbuild = require("@umijs/bundler-utils/compiled/esbuild");
29
30
  var import_fs = __toESM(require("fs"));
30
- var import_js_yaml = __toESM(require("js-yaml"));
31
31
  var import_path = __toESM(require("path"));
32
32
  var import_plugin_utils = require("umi/plugin-utils");
33
- function parseCodeFrontmatter(raw) {
34
- const [, comment = "", code = ""] = raw.replace(/^\n\s*/, "").match(/^(\/\*\*[^]*?\n\s*\*\/)?(?:\s|\n)*([^]+)?$/);
35
- const yamlComment = comment.replace(/^\/|\/$/g, "").replace(/(^|\n)\s*\*+/g, "$1");
36
- let frontmatter = null;
37
- try {
38
- frontmatter = import_js_yaml.default.load(yamlComment);
39
- } catch {
40
- }
41
- return { code: frontmatter ? code : raw, frontmatter };
42
- }
43
33
  async function parseBlockAsset(opts) {
44
34
  const asset = {
45
35
  type: "BLOCK",
@@ -101,7 +91,7 @@ async function parseBlockAsset(opts) {
101
91
  value: opts.entryPointCode ?? import_fs.default.readFileSync(args.path, "utf-8")
102
92
  };
103
93
  if (isEntryPoint) {
104
- const { code, frontmatter } = parseCodeFrontmatter(asset.dependencies[filename].value);
94
+ const { code, frontmatter } = (0, import_utils.parseCodeFrontmatter)(asset.dependencies[filename].value);
105
95
  if (frontmatter) {
106
96
  asset.dependencies[filename].value = code;
107
97
  result.frontmatter = frontmatter;
@@ -14,6 +14,6 @@ export var DumiDemo = function DumiDemo(props) {
14
14
  return /*#__PURE__*/React.createElement(Previewer, _extends({
15
15
  asset: asset,
16
16
  demoUrl: // allow user override demoUrl by frontmatter
17
- props.previewerProps.demoUrl || "".concat(SP_ROUTE_PREFIX, "demos/").concat(props.demo.id)
17
+ props.previewerProps.demoUrl || "/".concat(SP_ROUTE_PREFIX, "demos/").concat(props.demo.id)
18
18
  }, props.previewerProps), /*#__PURE__*/createElement(component));
19
19
  };
@@ -0,0 +1,4 @@
1
+ import { type FC, type ReactNode } from 'react';
2
+ export declare const DumiPage: FC<{
3
+ children: ReactNode;
4
+ }>;
@@ -0,0 +1,39 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+
3
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
4
+
5
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
6
+
7
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
8
+
9
+ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
10
+
11
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
12
+
13
+ import { useRouteMeta, useSiteData } from 'dumi';
14
+ import ContentTabs from 'dumi/theme/slots/ContentTabs';
15
+ import React, { useEffect, useState } from 'react';
16
+ export var DumiPage = function DumiPage(props) {
17
+ var _useRouteMeta = useRouteMeta(),
18
+ tabs = _useRouteMeta.tabs;
19
+
20
+ var _useState = useState(),
21
+ _useState2 = _slicedToArray(_useState, 2),
22
+ tab = _useState2[0],
23
+ setTab = _useState2[1];
24
+
25
+ var _useSiteData = useSiteData(),
26
+ setLoading = _useSiteData.setLoading; // update loading status when page loaded
27
+
28
+
29
+ useEffect(function () {
30
+ setLoading(false);
31
+ }, []);
32
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ContentTabs, {
33
+ tabs: tabs,
34
+ tabKey: tab === null || tab === void 0 ? void 0 : tab.key,
35
+ onChange: function onChange(val) {
36
+ setTab(val);
37
+ }
38
+ }), tab ? /*#__PURE__*/React.createElement(tab.components.default) : props.children);
39
+ };
@@ -1,3 +1,4 @@
1
+ import type { AtomComponentAsset } from 'dumi-assets-types';
1
2
  import { type ComponentType } from 'react';
2
3
  import type { ILocalesConfig, IPreviewerProps, IThemeConfig } from './types';
3
4
  interface ISiteContext {
@@ -5,6 +6,7 @@ interface ISiteContext {
5
6
  component: ComponentType;
6
7
  asset: IPreviewerProps['asset'];
7
8
  }>;
9
+ components: Record<string, AtomComponentAsset>;
8
10
  locales: NonNullable<ILocalesConfig>;
9
11
  themeConfig: IThemeConfig;
10
12
  loading: boolean;
@@ -1,6 +1,7 @@
1
1
  import { createContext, useContext } from 'react';
2
2
  export var SiteContext = /*#__PURE__*/createContext({
3
3
  demos: {},
4
+ components: {},
4
5
  locales: [],
5
6
  themeConfig: {},
6
7
  loading: false,
@@ -1,8 +1,10 @@
1
- export { useIntl } from 'react-intl';
1
+ export { createIntlCache, defineMessages, FormattedDate, FormattedDateParts, FormattedDisplayName, FormattedList, FormattedMessage, FormattedNumber, FormattedNumberParts, FormattedPlural, FormattedRelativeTime, FormattedTime, FormattedTimeParts, injectIntl, IntlContext, IntlProvider, RawIntlProvider, useIntl, } from 'react-intl';
2
2
  export { useSiteData } from './context';
3
3
  export { DumiDemo } from './DumiDemo';
4
4
  export { DumiDemoGrid } from './DumiDemoGrid';
5
+ export { DumiPage } from './DumiPage';
5
6
  export type { IPreviewerProps } from './types';
7
+ export { useAtomAssets } from './useAtomAssets';
6
8
  export { useLocale } from './useLocale';
7
9
  export { useNavData } from './useNavData';
8
10
  export { useRouteMeta } from './useRouteMeta';
@@ -1,7 +1,9 @@
1
- export { useIntl } from 'react-intl';
1
+ export { createIntlCache, defineMessages, FormattedDate, FormattedDateParts, FormattedDisplayName, FormattedList, FormattedMessage, FormattedNumber, FormattedNumberParts, FormattedPlural, FormattedRelativeTime, FormattedTime, FormattedTimeParts, injectIntl, IntlContext, IntlProvider, RawIntlProvider, useIntl } from 'react-intl';
2
2
  export { useSiteData } from "./context";
3
3
  export { DumiDemo } from "./DumiDemo";
4
4
  export { DumiDemoGrid } from "./DumiDemoGrid";
5
+ export { DumiPage } from "./DumiPage";
6
+ export { useAtomAssets } from "./useAtomAssets";
5
7
  export { useLocale } from "./useLocale";
6
8
  export { useNavData } from "./useNavData";
7
9
  export { useRouteMeta } from "./useRouteMeta";
@@ -1,5 +1,5 @@
1
1
  import type { ExampleBlockAsset } from 'dumi-assets-types';
2
- import type { ReactNode } from 'react';
2
+ import type { ComponentType, ReactNode } from 'react';
3
3
  export interface IPreviewerProps {
4
4
  /**
5
5
  * title of current demo
@@ -68,6 +68,17 @@ export interface IRouteMeta {
68
68
  depth: number;
69
69
  title: string;
70
70
  }[];
71
+ tabs?: {
72
+ key: string;
73
+ components: {
74
+ default: ComponentType;
75
+ Extra: ComponentType;
76
+ Action: ComponentType;
77
+ };
78
+ frontmatter: Omit<IRouteMeta['frontmatter'], 'description' | 'keywords' | 'nav' | 'group'>;
79
+ toc: IRouteMeta['toc'];
80
+ [key: string]: any;
81
+ }[];
71
82
  [key: string]: any;
72
83
  }
73
84
  declare type IBasicLocale = {
@@ -88,6 +99,8 @@ export interface INavItem {
88
99
  interface ISidebarItem {
89
100
  title: string;
90
101
  link: string;
102
+ order: number;
103
+ frontmatter: IRouteMeta['frontmatter'];
91
104
  [key: string]: any;
92
105
  }
93
106
  export interface ISidebarGroup {
@@ -0,0 +1,4 @@
1
+ import { AtomComponentAsset } from 'dumi-assets-types';
2
+ export declare const useAtomAssets: () => {
3
+ components: Record<string, AtomComponentAsset>;
4
+ };
@@ -0,0 +1,9 @@
1
+ import { useSiteData } from 'dumi';
2
+ export var useAtomAssets = function useAtomAssets() {
3
+ var _useSiteData = useSiteData(),
4
+ components = _useSiteData.components;
5
+
6
+ return {
7
+ components: components
8
+ };
9
+ };
@@ -71,7 +71,8 @@ export var useFullSidebarData = function useFullSidebarData() {
71
71
  children: [].concat(_toConsumableArray(((_ret$parentPath$title2 = ret[parentPath][titleKey]) === null || _ret$parentPath$title2 === void 0 ? void 0 : _ret$parentPath$title2.children) || []), [{
72
72
  title: route.meta.frontmatter.title,
73
73
  link: "/".concat(route.path),
74
- order: route.meta.frontmatter.order || 0
74
+ order: route.meta.frontmatter.order || 0,
75
+ frontmatter: route.meta.frontmatter
75
76
  }])
76
77
  };
77
78
  }
@@ -125,7 +126,8 @@ export var useSidebarData = function useSidebarData() {
125
126
  // /a/b => /a
126
127
  // /en-US/a => /en-US/a
127
128
  // /en-US/a/b => /en-US/a
129
+ // /en-US/a/b/ => /en-US/a (also strip trailing /)
128
130
 
129
- var parentPath = clearPath ? pathname.replace(/(\/[^/]+)(\/[^/]+)$/, '$1') : pathname;
131
+ var parentPath = clearPath ? pathname.replace(/(\/[^/]+)(\/[^/]+\/?)$/, '$1') : pathname;
130
132
  return parentPath ? sidebar[parentPath] : [];
131
133
  };
@@ -50,13 +50,14 @@ var compile_default = (api) => {
50
50
  extraRemarkPlugins: api.config.extraRemarkPlugins,
51
51
  extraRehypePlugins: api.config.extraRehypePlugins
52
52
  };
53
- memo.module.rule("dumi-md").type("javascript/auto").test(/\.md$/).oneOf("md-meta").resourceQuery(/meta$/).use("md-meta-loader").loader(loaderPath).options({
53
+ memo.module.rule("dumi-md").type("javascript/auto").test(/\.md$/).oneOf("md-meta").resourceQuery(/meta$/).use("babel-loader").loader(babelInUmi.loader).options(babelInUmi.options).end().use("md-meta-loader").loader(loaderPath).options({
54
54
  ...loaderBaseOpts,
55
55
  mode: "meta"
56
56
  }).end().end().oneOf("md").use("babel-loader").loader(babelInUmi.loader).options(babelInUmi.options).end().use("md-loader").loader(loaderPath).options({
57
57
  ...loaderBaseOpts,
58
58
  builtins: api.service.themeData.builtins
59
59
  });
60
+ memo.module.rule("dumi-page").type("javascript/auto").test(/\.(j|t)sx?$/).resourceQuery(/meta$/).use("page-meta-loader").loader(require.resolve("../loaders/page"));
60
61
  memo.module.rule("dumi-demo").type("javascript/auto").test(/\..+$/).enforce("pre").resourceQuery(/techStack/).use("demo-loader").loader(require.resolve("../loaders/demo")).options({ techStacks, cwd: api.cwd });
61
62
  memo.module.rule("dumi-raw").resourceQuery(/raw/).use("raw-loader").loader(require.resolve("raw-loader"));
62
63
  if (api.env === "development") {
@@ -28,9 +28,10 @@ function getUnifiedPluginSchema(Joi) {
28
28
  function getSchemas() {
29
29
  return {
30
30
  resolve: (Joi) => Joi.object({
31
- docDirs: Joi.array().items(Joi.string()).optional(),
31
+ docDirs: Joi.array().items(Joi.alternatives(Joi.string(), Joi.object({ dir: Joi.string(), type: Joi.string().optional() }))).optional(),
32
32
  entityDirs: Joi.array().items(Joi.object({ type: Joi.string(), dir: Joi.string() })).optional(),
33
- codeBlockMode: Joi.string().valid("active", "passive").optional()
33
+ codeBlockMode: Joi.string().valid("active", "passive").optional(),
34
+ entryFile: Joi.string().optional()
34
35
  }).optional(),
35
36
  extraRemarkPlugins: getUnifiedPluginSchema,
36
37
  extraRehypePlugins: getUnifiedPluginSchema,
@@ -1,3 +1,5 @@
1
1
  import type { IApi } from "../types";
2
+ export declare const TABS_META_PATH = "dumi/meta/tabs.ts";
3
+ export declare const ATOMS_META_PATH = "dumi/meta/atoms.ts";
2
4
  declare const _default: (api: IApi) => void;
3
5
  export default _default;
@@ -19,18 +19,23 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  // src/features/meta.ts
20
20
  var meta_exports = {};
21
21
  __export(meta_exports, {
22
+ ATOMS_META_PATH: () => ATOMS_META_PATH,
23
+ TABS_META_PATH: () => TABS_META_PATH,
22
24
  default: () => meta_default
23
25
  });
24
26
  module.exports = __toCommonJS(meta_exports);
25
27
  var import_plugin_utils = require("umi/plugin-utils");
28
+ var import_tabs = require("./tabs");
29
+ var TABS_META_PATH = "dumi/meta/tabs.ts";
30
+ var ATOMS_META_PATH = "dumi/meta/atoms.ts";
26
31
  var meta_default = (api) => {
27
- const mdRouteFiles = [];
32
+ const metaFiles = [];
28
33
  api.modifyRoutes((routes) => {
29
- mdRouteFiles.length = 0;
34
+ metaFiles.length = 0;
30
35
  Object.values(routes).forEach((route) => {
31
- if (route.file.endsWith(".md")) {
32
- mdRouteFiles.push({
33
- index: mdRouteFiles.length,
36
+ if (!route.isLayout && !/\*|:/.test(route.path) && !(0, import_tabs.isTabRouteFile)(route.file)) {
37
+ metaFiles.push({
38
+ index: metaFiles.length,
34
39
  file: route.file,
35
40
  id: route.id
36
41
  });
@@ -38,34 +43,60 @@ var meta_default = (api) => {
38
43
  });
39
44
  return routes;
40
45
  });
41
- api.onGenerateFiles(() => {
46
+ api.onGenerateFiles(async () => {
47
+ api.writeTmpFile({
48
+ noPluginDir: true,
49
+ path: ATOMS_META_PATH,
50
+ content: "export const components = null;"
51
+ });
42
52
  api.writeTmpFile({
43
53
  noPluginDir: true,
44
54
  path: "dumi/meta/index.ts",
45
- content: import_plugin_utils.Mustache.render(`{{#mdRouteFiles}}
55
+ content: import_plugin_utils.Mustache.render(`{{#metaFiles}}
46
56
  import { demos as d{{{index}}}, frontmatter as fm{{{index}}}, toc as toc{{{index}}} } from '{{{file}}}?type=meta';
47
- {{/mdRouteFiles}}
57
+ {{/metaFiles}}
58
+
59
+ export { components } from './atoms';
60
+ export { tabs } from './tabs';
48
61
 
49
62
  export const demos = {
50
- {{#mdRouteFiles}}
63
+ {{#metaFiles}}
51
64
  ...d{{{index}}},
52
- {{/mdRouteFiles}}
65
+ {{/metaFiles}}
53
66
  };
54
67
 
55
- export const routesMeta = {
56
- {{#mdRouteFiles}}
57
- '{{{id}}}': { frontmatter: fm{{{index}}}, toc: toc{{{index}}} },
58
- {{/mdRouteFiles}}
59
- }`, { mdRouteFiles })
68
+ export const filesMeta = {
69
+ {{#metaFiles}}
70
+ '{{{id}}}': {
71
+ frontmatter: fm{{{index}}},
72
+ toc: toc{{{index}}},
73
+ {{#tabs}}
74
+ tabs: {{{tabs}}},
75
+ {{/tabs}}
76
+ },
77
+ {{/metaFiles}}
78
+ }`, {
79
+ metaFiles: await api.applyPlugins({
80
+ type: api.ApplyPluginsType.modify,
81
+ key: "dumi.modifyMetaFiles",
82
+ initialValue: metaFiles
83
+ })
84
+ })
60
85
  });
61
86
  api.writeTmpFile({
62
87
  noPluginDir: true,
63
88
  path: "dumi/meta/runtime.ts",
64
- content: `import { routesMeta } from '.';
89
+ content: `import { filesMeta, tabs } from '.';
65
90
  export const patchRoutes = ({ routes }) => {
66
91
  Object.values(routes).forEach((route) => {
67
- if (routesMeta[route.id]) {
68
- route.meta = { ...route.meta, ...routesMeta[route.id] };
92
+ if (filesMeta[route.id]) {
93
+ route.meta = { ...route.meta, ...filesMeta[route.id] };
94
+
95
+ // apply real tab data from id
96
+ route.meta.tabs = route.meta.tabs?.map(id => ({
97
+ ...tabs[id],
98
+ ...filesMeta[id],
99
+ }));
69
100
  }
70
101
  });
71
102
  }
@@ -75,4 +106,7 @@ export const patchRoutes = ({ routes }) => {
75
106
  api.addRuntimePlugin(() => "@@/dumi/meta/runtime.ts");
76
107
  };
77
108
  // Annotate the CommonJS export names for ESM import in node:
78
- 0 && (module.exports = {});
109
+ 0 && (module.exports = {
110
+ ATOMS_META_PATH,
111
+ TABS_META_PATH
112
+ });
@@ -0,0 +1,3 @@
1
+ import type { IApi } from "../types";
2
+ declare const _default: (api: IApi) => void;
3
+ export default _default;
@@ -0,0 +1,66 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
20
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+
22
+ // src/features/parser.ts
23
+ var parser_exports = {};
24
+ __export(parser_exports, {
25
+ default: () => parser_default
26
+ });
27
+ module.exports = __toCommonJS(parser_exports);
28
+ var import_atom = __toESM(require("../assetParsers/atom"));
29
+ var import_meta = require("./meta");
30
+ var parser_default = (api) => {
31
+ const writeAtomsMetaFile = (data) => {
32
+ api.writeTmpFile({
33
+ noPluginDir: true,
34
+ path: import_meta.ATOMS_META_PATH,
35
+ content: `export const components = ${JSON.stringify(data.components, null, 2)};`
36
+ });
37
+ };
38
+ api.describe({
39
+ key: "apiParser",
40
+ enableBy: api.EnableBy.config,
41
+ config: {
42
+ schema: (Joi) => Joi.object()
43
+ }
44
+ });
45
+ api.modifyDefaultConfig((memo) => {
46
+ var _a;
47
+ if (!((_a = api.userConfig.resolve) == null ? void 0 : _a.entryFile)) {
48
+ api.logger.error("`resolve.entryFile` must be configured when `apiParser` enable");
49
+ process.exit(1);
50
+ }
51
+ return memo;
52
+ });
53
+ api.onStart(() => {
54
+ api.service.atomParser = new import_atom.default({
55
+ entryFile: api.config.resolve.entryFile,
56
+ resolveDir: api.cwd
57
+ });
58
+ if (api.env === "production") {
59
+ api.service.atomParser.parse().then(writeAtomsMetaFile);
60
+ } else {
61
+ api.service.atomParser.watch(writeAtomsMetaFile);
62
+ }
63
+ });
64
+ };
65
+ // Annotate the CommonJS export names for ESM import in node:
66
+ 0 && (module.exports = {});
@@ -32,6 +32,9 @@ var import_path = __toESM(require("path"));
32
32
  var import_pluralize = require("pluralize");
33
33
  var import_plugin_utils = require("umi/plugin-utils");
34
34
  var CTX_LAYOUT_ID = "dumi-context-layout";
35
+ function normalizeDocDir(docDir) {
36
+ return typeof docDir === "object" ? docDir : { dir: docDir };
37
+ }
35
38
  function localizeUmiRoute(route, locales) {
36
39
  const locale = locales.find((locale2) => route.path.endsWith(`/${locale2.id}`) && import_path.default.parse(route.file).name.endsWith(`.${locale2.id}`));
37
40
  if (locale) {
@@ -44,9 +47,11 @@ function localizeUmiRoute(route, locales) {
44
47
  var routes_default = (api) => {
45
48
  var _a, _b, _c;
46
49
  const extraWatchPaths = [
47
- ...((_b = (_a = api.userConfig.resolve) == null ? void 0 : _a.entityDirs) == null ? void 0 : _b.map(({ dir }) => dir)) || ["docs"],
48
- ...((_c = api.userConfig.resolve) == null ? void 0 : _c.docDirs) || []
49
- ].map((dir) => import_path.default.join(api.cwd, dir, "**/*.md"));
50
+ ...((_a = api.userConfig.resolve) == null ? void 0 : _a.entityDirs) || [],
51
+ ...((_c = (_b = api.userConfig.resolve) == null ? void 0 : _b.docDirs) == null ? void 0 : _c.map(normalizeDocDir)) || [
52
+ { dir: "docs" }
53
+ ]
54
+ ].map(({ dir }) => import_path.default.join(api.cwd, dir, "**/*.md"));
50
55
  const pagesDir = import_path.default.join(api.cwd, ".dumi/pages");
51
56
  api.describe({ key: "dumi:routes" });
52
57
  api.addTmpGenerateWatcherPaths(() => extraWatchPaths);
@@ -110,7 +115,7 @@ var routes_default = (api) => {
110
115
  route.file = import_path.default.resolve(pagesDir, route.file);
111
116
  routes[route.id] = route;
112
117
  });
113
- docDirs.forEach((dir) => {
118
+ docDirs.map(normalizeDocDir).forEach(({ type, dir }) => {
114
119
  const base = import_path.default.join(api.cwd, dir);
115
120
  const dirRoutes = (0, import_core.getConventionRoutes)({
116
121
  base,
@@ -119,6 +124,11 @@ var routes_default = (api) => {
119
124
  Object.entries(dirRoutes).forEach(([key, route]) => {
120
125
  route.id = `${dir}/${key}`;
121
126
  route.parentId = docLayoutId;
127
+ if (type) {
128
+ const pluralType = (0, import_pluralize.plural)(type);
129
+ route.path = `${pluralType}/${route.path}`.replace(/\/+$/, "/");
130
+ route.absPath = `/${route.path}`;
131
+ }
122
132
  route.file = import_path.default.resolve(base, route.file);
123
133
  localizeUmiRoute(route, api.config.locales);
124
134
  routes[route.id] = route;
@@ -162,7 +172,7 @@ var routes_default = (api) => {
162
172
  const layouts = [
163
173
  {
164
174
  id: CTX_LAYOUT_ID,
165
- file: "@/.umi/dumi/theme/ContextWrapper.tsx"
175
+ file: `${api.paths.absTmpPath}/dumi/theme/ContextWrapper.tsx`
166
176
  }
167
177
  ];
168
178
  const { GlobalLayout } = api.service.themeData.layouts;
@@ -0,0 +1,5 @@
1
+ import type { IApi } from "../types";
2
+ export declare function isTabRouteFile(file: string): boolean;
3
+ export declare function getTabKeyFromFile(file: string): string;
4
+ declare const _default: (api: IApi) => void;
5
+ export default _default;