dumi 2.1.3 → 2.1.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.
@@ -50,7 +50,7 @@ function getCSBData(opts) {
50
50
 
51
51
  files['sandbox.config.json'] = {
52
52
  content: JSON.stringify({
53
- template: isTSX ? 'create-react-app-typescript' : 'create-react-app'
53
+ template: 'create-react-app'
54
54
  }, null, 2),
55
55
  isBinary: false
56
56
  }; // append package.json
@@ -115,8 +115,8 @@ export interface IRouteMeta {
115
115
  }[];
116
116
  tabs?: {
117
117
  key: string;
118
- name?: string;
119
- nameIntlId?: string;
118
+ title?: string;
119
+ titleIntlId?: string;
120
120
  components: {
121
121
  default: ComponentType;
122
122
  Extra: ComponentType;
@@ -161,7 +161,7 @@ export interface ISidebarGroup {
161
161
  }
162
162
  export interface IThemeConfig {
163
163
  name?: string;
164
- logo?: string;
164
+ logo?: string | false;
165
165
  nav?: (INavItem & {
166
166
  children?: INavItem[];
167
167
  })[] | Record<string, (INavItem & {
@@ -47,7 +47,7 @@ function safeExcludeInMFSU(api, excludes) {
47
47
  var derivative_default = (api) => {
48
48
  api.describe({ key: "dumi:derivative" });
49
49
  api.onCheck(() => {
50
- var _a, _b, _c;
50
+ var _a, _b, _c, _d;
51
51
  (0, import_assert.default)(!api.config.mpa, "MPA mode is not supported in dumi!");
52
52
  (0, import_assert.default)(!api.config.vite, "Vite mode is not supported yet!");
53
53
  if (typeof api.config.mfsu === "object") {
@@ -62,14 +62,14 @@ var derivative_default = (api) => {
62
62
  try {
63
63
  const tsconfig = require(import_path.default.join(api.cwd, "tsconfig.json"));
64
64
  const expected = [".dumi/**/*"];
65
- if ((_c = api.service.configManager) == null ? void 0 : _c.mainConfigFile) {
65
+ if ((_d = (_c = api.service.configManager) == null ? void 0 : _c.mainConfigFile) == null ? void 0 : _d.endsWith(".ts")) {
66
66
  expected.push((0, import_plugin_utils.winPath)(import_path.default.relative(api.cwd, api.service.configManager.mainConfigFile)));
67
67
  }
68
68
  if (!expected.every((f) => {
69
69
  var _a2;
70
70
  return (_a2 = tsconfig.include) == null ? void 0 : _a2.includes(f);
71
71
  })) {
72
- import_plugin_utils.logger.warn(`Please append ${expected.map((e) => `\`${e}\``).join(" & ")} into \`include\` option of \`tsconfig.json\`, to make sure \`defineConfig\` works.`);
72
+ import_plugin_utils.logger.warn(`Please append ${expected.map((e) => `\`${e}\``).join(" & ")} into \`include\` option of \`tsconfig.json\`, to make sure the types exported by framework works.`);
73
73
  }
74
74
  } catch {
75
75
  }
@@ -109,6 +109,9 @@ var derivative_default = (api) => {
109
109
  });
110
110
  api.modifyConfig((memo) => {
111
111
  var _a;
112
+ if (api.userConfig.mfsu === true) {
113
+ memo.mfsu = {};
114
+ }
112
115
  if ((_a = api.userConfig.alias) == null ? void 0 : _a["@"]) {
113
116
  memo.alias["@"] = api.userConfig.alias["@"];
114
117
  } else {
@@ -119,10 +119,17 @@ export const patchRoutes = ({ routes }) => {
119
119
  route.meta = deepmerge(route.meta, filesMeta[route.id]);
120
120
 
121
121
  // apply real tab data from id
122
- route.meta.tabs = route.meta.tabs?.map(id => ({
123
- ...tabs[id],
124
- meta: filesMeta[id],
125
- }));
122
+ route.meta.tabs = route.meta.tabs?.map((id) => {
123
+ const meta = {
124
+ frontmatter: { title: tabs[id].title },
125
+ toc: [],
126
+ texts: [],
127
+ }
128
+ return {
129
+ ...tabs[id],
130
+ meta: filesMeta[id] || meta,
131
+ }
132
+ });
126
133
  }
127
134
  }
128
135
  });
@@ -61,7 +61,9 @@ var parser_default = (api) => {
61
61
  unpkgHost: api.config.apiParser.unpkgHost,
62
62
  resolveFilter: api.config.apiParser.resolveFilter
63
63
  });
64
- if (api.env === "development") {
64
+ });
65
+ api.onDevCompileDone(({ isFirstCompile }) => {
66
+ if (isFirstCompile) {
65
67
  api.service.atomParser.watch((data) => {
66
68
  prevData = data;
67
69
  writeAtomsMetaFile(prevData);
@@ -61,14 +61,16 @@ function flatRoute(route, docLayoutId) {
61
61
  }
62
62
  }
63
63
  function getClientPageFile(file, cwd) {
64
+ let clientFile;
64
65
  try {
65
- return import_plugin_utils.resolve.sync(`dumi/dist/${file}`, {
66
+ clientFile = import_plugin_utils.resolve.sync(`dumi/dist/${file}`, {
66
67
  basedir: cwd,
67
68
  preserveSymlinks: false
68
69
  });
69
70
  } catch {
70
- return require.resolve(`../${file}`);
71
+ clientFile = require.resolve(`../${file}`);
71
72
  }
73
+ return (0, import_plugin_utils.winPath)(clientFile);
72
74
  }
73
75
  var routes_default = (api) => {
74
76
  var _a, _b, _c;
@@ -3,8 +3,8 @@ export interface IContentTab {
3
3
  key: string;
4
4
  id?: string;
5
5
  test?: RegExp;
6
- name?: string;
7
- nameIntlId?: string;
6
+ title?: string;
7
+ titleIntlId?: string;
8
8
  component: string;
9
9
  }
10
10
  export declare function isTabRouteFile(file: string): boolean;
@@ -86,8 +86,8 @@ var tabs_default = (api) => {
86
86
  index: tabs.length + index,
87
87
  key: tab.key,
88
88
  id: tab.id,
89
- name: tab.name,
90
- nameIntlId: tab.nameIntlId,
89
+ title: tab.title || import_plugin_utils.lodash.startCase(import_path.default.parse(tab.component).name),
90
+ titleIntlId: tab.titleIntlId,
91
91
  file: tab.component
92
92
  })));
93
93
  return routes;
@@ -101,11 +101,14 @@ var tabs_default = (api) => {
101
101
  }
102
102
  });
103
103
  tabs.forEach((tab) => {
104
- metaFiles.push({
105
- id: tab.id,
106
- file: tab.file,
107
- index: metaFiles.length
108
- });
104
+ const isFromPlugin = tabsFromPlugins.some((item) => item.id === tab.id);
105
+ if (!isFromPlugin) {
106
+ metaFiles.push({
107
+ id: tab.id,
108
+ file: tab.file,
109
+ index: metaFiles.length
110
+ });
111
+ }
109
112
  });
110
113
  return metaFiles;
111
114
  }
@@ -120,7 +123,7 @@ import * as tab{{{index}}} from '{{{file}}}';
120
123
 
121
124
  export const tabs = {
122
125
  {{#tabs}}
123
- '{{{id}}}': { key: '{{{key}}}', name: '{{{name}}}', nameIntlId: '{{{nameIntlId}}}', components: tab{{{index}}} },
126
+ '{{{id}}}': { key: '{{{key}}}', title: '{{{title}}}', titleIntlId: '{{{titleIntlId}}}', components: tab{{{index}}} },
124
127
  {{/tabs}}
125
128
  }
126
129
  `, { tabs })
@@ -163,6 +163,12 @@ function rehypeDemo(opts) {
163
163
  "snapshot",
164
164
  "keywords"
165
165
  ];
166
+ const techStackOpts = {
167
+ type: codeType,
168
+ mdAbsPath: opts.fileAbsPath,
169
+ fileAbsPath: codeType === "external" ? parseOpts.fileAbsPath : void 0,
170
+ entryPointCode: parseOpts.entryPointCode
171
+ };
166
172
  Object.keys(restAttrs).forEach((key) => {
167
173
  if (restAttrs[key] === "")
168
174
  restAttrs[key] = true;
@@ -179,12 +185,7 @@ function rehypeDemo(opts) {
179
185
  component
180
186
  };
181
187
  }
182
- Object.assign(previewerProps, await ((_b = techStack.generatePreviewerProps) == null ? void 0 : _b.call(techStack, originalProps, {
183
- type: codeType,
184
- mdAbsPath: opts.fileAbsPath,
185
- fileAbsPath: codeType === "external" ? parseOpts.fileAbsPath : void 0,
186
- entryPointCode: parseOpts.entryPointCode
187
- })) || originalProps);
188
+ Object.assign(previewerProps, await ((_b = techStack.generatePreviewerProps) == null ? void 0 : _b.call(techStack, originalProps, techStackOpts)) || originalProps);
188
189
  if (previewerProps.description) {
189
190
  const { unified } = await import("unified");
190
191
  const { default: remarkParse } = await import("remark-parse");
@@ -192,7 +193,7 @@ function rehypeDemo(opts) {
192
193
  const { default: remarkRehype } = await import("remark-rehype");
193
194
  const { default: rehypeStringify } = await import("rehype-stringify");
194
195
  const { convert } = require("html-to-text");
195
- const result = await unified().use(remarkParse).use(remarkGfm).use(remarkRehype, { allowDangerousHtml: true }).use(rehypeStringify).process(previewerProps.description);
196
+ const result = await unified().use(remarkParse).use(remarkGfm).use(remarkRehype, { allowDangerousHtml: true }).use(rehypeStringify, { allowDangerousHtml: true }).process(previewerProps.description);
196
197
  previewerProps.description = String(result.value);
197
198
  asset.description = convert(result.value, {
198
199
  wordwrap: false
@@ -201,7 +202,7 @@ function rehypeDemo(opts) {
201
202
  return {
202
203
  id: asset.id,
203
204
  component,
204
- asset: techStack.generateMetadata ? await techStack.generateMetadata(asset) : asset,
205
+ asset: techStack.generateMetadata ? await techStack.generateMetadata(asset, techStackOpts) : asset,
205
206
  sources
206
207
  };
207
208
  }));
@@ -27,20 +27,96 @@ __export(react_exports, {
27
27
  module.exports = __toCommonJS(react_exports);
28
28
  var import_core = require("@swc/core");
29
29
  var import_Visitor = __toESM(require("@swc/core/Visitor"));
30
+ function createReturnStmt(exp, span) {
31
+ return {
32
+ type: "ReturnStatement",
33
+ span,
34
+ argument: {
35
+ type: "ObjectExpression",
36
+ span,
37
+ properties: [
38
+ {
39
+ type: "KeyValueProperty",
40
+ key: {
41
+ type: "Identifier",
42
+ span,
43
+ value: "default",
44
+ optional: false
45
+ },
46
+ value: exp
47
+ }
48
+ ]
49
+ }
50
+ };
51
+ }
30
52
  var ReactDemoVisitor = class extends import_Visitor.default {
53
+ visitImportDeclaration(n) {
54
+ if (!n.typeOnly) {
55
+ const namespaceImport = n.specifiers.find((s) => s.type === "ImportNamespaceSpecifier");
56
+ const id = namespaceImport ? namespaceImport.local : {
57
+ type: "ObjectPattern",
58
+ span: n.span,
59
+ properties: n.specifiers.map((s) => {
60
+ var _a;
61
+ if (s.type === "ImportDefaultSpecifier" || s.type === "ImportSpecifier" && ((_a = s.imported) == null ? void 0 : _a.type) === "Identifier") {
62
+ return {
63
+ type: "KeyValuePatternProperty",
64
+ span: s.span,
65
+ key: s.type === "ImportSpecifier" ? s.imported : {
66
+ type: "Identifier",
67
+ span: s.span,
68
+ value: "default",
69
+ optional: false
70
+ },
71
+ value: s.local
72
+ };
73
+ }
74
+ return {
75
+ type: "AssignmentPatternProperty",
76
+ span: s.span,
77
+ key: s.local
78
+ };
79
+ }),
80
+ optional: false
81
+ };
82
+ return {
83
+ type: "VariableDeclaration",
84
+ kind: "const",
85
+ declare: false,
86
+ span: n.span,
87
+ declarations: [
88
+ {
89
+ type: "VariableDeclarator",
90
+ span: n.span,
91
+ definite: false,
92
+ id,
93
+ init: {
94
+ span: n.span,
95
+ type: "AwaitExpression",
96
+ argument: {
97
+ type: "CallExpression",
98
+ span: n.span,
99
+ callee: {
100
+ type: "Import",
101
+ span: n.span
102
+ },
103
+ arguments: [{ expression: n.source }]
104
+ }
105
+ }
106
+ }
107
+ ]
108
+ };
109
+ }
110
+ return n;
111
+ }
31
112
  visitExportDefaultDeclaration(n) {
32
- return {
33
- type: "ReturnStatement",
34
- span: n.span,
35
- argument: n.decl
36
- };
113
+ if (n.decl.type !== "TsInterfaceDeclaration") {
114
+ return createReturnStmt(n.decl, n.span);
115
+ }
116
+ return n;
37
117
  }
38
118
  visitExportDefaultExpression(n) {
39
- return {
40
- type: "ReturnStatement",
41
- span: n.span,
42
- argument: n.expression
43
- };
119
+ return createReturnStmt(n.expression, n.span);
44
120
  }
45
121
  visitTsType(n) {
46
122
  return n;
@@ -66,14 +142,13 @@ var ReactTechStack = class {
66
142
  target: "es2022"
67
143
  },
68
144
  module: {
69
- type: "commonjs",
70
- strictMode: false
145
+ type: "es6"
71
146
  },
72
147
  plugin: (m) => new ReactDemoVisitor().visitProgram(m)
73
148
  });
74
- return `(function () {
149
+ return `React.lazy(async () => {
75
150
  ${code}
76
- })()`;
151
+ })`;
77
152
  }
78
153
  return raw;
79
154
  }
package/dist/types.d.ts CHANGED
@@ -71,16 +71,16 @@ export declare abstract class IDumiTechStack {
71
71
  /**
72
72
  * generator for return asset metadata
73
73
  */
74
- abstract generateMetadata?(asset: ExampleBlockAsset): Promise<ExampleBlockAsset> | ExampleBlockAsset;
75
- /**
76
- * generator for return previewer props
77
- */
78
- abstract generatePreviewerProps?(props: IDumiDemoProps['previewerProps'], opts: {
74
+ abstract generateMetadata?(asset: ExampleBlockAsset, opts: {
79
75
  type: Parameters<IDumiTechStack['transformCode']>[1]['type'];
80
76
  mdAbsPath: string;
81
77
  fileAbsPath?: string;
82
78
  entryPointCode?: string;
83
- }): Promise<IDumiDemoProps['previewerProps']> | IDumiDemoProps['previewerProps'];
79
+ }): Promise<ExampleBlockAsset> | ExampleBlockAsset;
80
+ /**
81
+ * generator for return previewer props
82
+ */
83
+ abstract generatePreviewerProps?(props: IDumiDemoProps['previewerProps'], opts: Parameters<NonNullable<IDumiTechStack['generateMetadata']>>[1]): Promise<IDumiDemoProps['previewerProps']> | IDumiDemoProps['previewerProps'];
84
84
  }
85
85
  export declare type IApi = IUmiApi & {
86
86
  config: IDumiConfig & {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dumi",
3
- "version": "2.1.3",
3
+ "version": "2.1.5",
4
4
  "description": "📖 Documentation Generator of React Component",
5
5
  "keywords": [
6
6
  "generator",
@@ -107,7 +107,7 @@
107
107
  "prism-themes": "^1.9.0",
108
108
  "prismjs": "^1.29.0",
109
109
  "raw-loader": "^4.0.2",
110
- "rc-tabs": "12.1.0-alpha.1",
110
+ "rc-tabs": "^12.5.6",
111
111
  "react-copy-to-clipboard": "^5.1.0",
112
112
  "react-error-boundary": "^3.1.4",
113
113
  "react-intl": "^6.1.1",
@@ -28,9 +28,9 @@ var ContentTabs = function ContentTabs(_ref) {
28
28
  "data-active": key === tab.key || undefined
29
29
  }, /*#__PURE__*/React.createElement("button", {
30
30
  type: "button"
31
- }, tab.nameIntlId ? intl.formatMessage({
32
- id: tab.nameIntlId
33
- }) : tab.name || tab.meta.frontmatter.title));
31
+ }, tab.titleIntlId ? intl.formatMessage({
32
+ id: tab.titleIntlId
33
+ }) : tab.meta.frontmatter.title));
34
34
  })) : null;
35
35
  };
36
36
 
@@ -10,7 +10,7 @@ var Logo = function Logo() {
10
10
  return /*#__PURE__*/React.createElement(Link, {
11
11
  className: "dumi-default-logo",
12
12
  to: 'base' in locale ? locale.base : '/'
13
- }, /*#__PURE__*/React.createElement("img", {
13
+ }, themeConfig.logo !== false && /*#__PURE__*/React.createElement("img", {
14
14
  src: themeConfig.logo || 'data:image/png;base64,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',
15
15
  alt: themeConfig.name
16
16
  }), themeConfig.name);