dumi 2.1.4 → 2.1.6

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.
@@ -4,6 +4,7 @@ declare class AtomAssetsParser {
4
4
  private resolveDir;
5
5
  private unresolvedFiles;
6
6
  private parser;
7
+ private resolver;
7
8
  private parseDeferrer;
8
9
  private watcher;
9
10
  private cbs;
@@ -21,5 +22,6 @@ declare class AtomAssetsParser {
21
22
  }>;
22
23
  watch(cb: AtomAssetsParser['cbs'][number]): void;
23
24
  unwatch(cb: AtomAssetsParser['cbs'][number]): void;
25
+ destroy(): void;
24
26
  }
25
27
  export default AtomAssetsParser;
@@ -42,28 +42,33 @@ var AtomAssetsParser = class {
42
42
  this.parser = new import_parser.SchemaParser({
43
43
  entryPath: absEntryFile,
44
44
  basePath: (0, import_utils.getProjectRoot)(opts.resolveDir),
45
- unPkgHost: opts.unpkgHost ?? "https://unpkg.com"
45
+ unPkgHost: opts.unpkgHost ?? "https://unpkg.com",
46
+ mode: "worker"
46
47
  });
47
48
  }
48
49
  async parse() {
49
- if (!this.parseDeferrer || this.unresolvedFiles.length) {
50
+ if (!this.parseDeferrer) {
50
51
  this.parseDeferrer = (async () => {
51
- this.unresolvedFiles.splice(0);
52
- await this.parser.patch([]);
53
- const resolver = new import_parser.SchemaResolver(await this.parser.parse());
52
+ await this.parser.patch(this.unresolvedFiles.splice(0));
53
+ const resolver = new import_parser.SchemaResolver(await this.parser.parse(), {
54
+ mode: "worker"
55
+ });
56
+ this.resolver = resolver;
54
57
  const result = {
55
58
  components: {},
56
59
  functions: {}
57
60
  };
58
61
  const fallbackProps = { type: "object", properties: {} };
59
62
  const fallbackSignature = { arguments: [] };
60
- resolver.componentList.forEach((id) => {
63
+ const componentList = await resolver.componentList;
64
+ const functionList = await resolver.functionList;
65
+ for (const id of componentList) {
61
66
  const needResolve = this.resolveFilter({
62
67
  id,
63
68
  type: "COMPONENT",
64
- ids: resolver.componentList
69
+ ids: componentList
65
70
  });
66
- let propsConfig = needResolve ? resolver.getComponent(id).props : fallbackProps;
71
+ let propsConfig = needResolve ? (await resolver.getComponent(id)).props : fallbackProps;
67
72
  const size = Buffer.byteLength(JSON.stringify(propsConfig));
68
73
  if (size > MAX_PARSE_SIZE) {
69
74
  propsConfig = fallbackProps;
@@ -75,14 +80,14 @@ var AtomAssetsParser = class {
75
80
  title: id,
76
81
  propsConfig
77
82
  };
78
- });
79
- resolver.functionList.forEach((id) => {
83
+ }
84
+ for (const id of functionList) {
80
85
  const needResolve = this.resolveFilter({
81
86
  id,
82
87
  type: "FUNCTION",
83
- ids: resolver.functionList
88
+ ids: functionList
84
89
  });
85
- let signature = needResolve ? resolver.getFunction(id).signature : fallbackSignature;
90
+ let signature = needResolve ? (await resolver.getFunction(id)).signature : fallbackSignature;
86
91
  const size = Buffer.byteLength(JSON.stringify(signature));
87
92
  if (size > MAX_PARSE_SIZE) {
88
93
  signature = fallbackSignature;
@@ -94,9 +99,15 @@ var AtomAssetsParser = class {
94
99
  title: id,
95
100
  signature
96
101
  };
97
- });
102
+ }
98
103
  return result;
99
104
  })();
105
+ this.parseDeferrer.finally(() => {
106
+ var _a;
107
+ (_a = this.resolver) == null ? void 0 : _a.$$destroyWorker();
108
+ this.resolver = void 0;
109
+ this.parseDeferrer = void 0;
110
+ });
100
111
  }
101
112
  return this.parseDeferrer;
102
113
  }
@@ -117,7 +128,7 @@ var AtomAssetsParser = class {
117
128
  ],
118
129
  ignoreInitial: true
119
130
  }).on("all", (ev, file) => {
120
- if (["add", "change"].includes(ev) && /\.(j|t)sx?$/.test(file)) {
131
+ if (["add", "change"].includes(ev) && /((?<!\.d)\.ts|\.(jsx?|tsx))$/.test(file)) {
121
132
  this.unresolvedFiles.push(import_path.default.join(this.resolveDir, file));
122
133
  lazyParse();
123
134
  }
@@ -128,6 +139,11 @@ var AtomAssetsParser = class {
128
139
  unwatch(cb) {
129
140
  this.cbs.splice(this.cbs.indexOf(cb), 1);
130
141
  }
142
+ destroy() {
143
+ var _a;
144
+ (_a = this.resolver) == null ? void 0 : _a.$$destroyWorker();
145
+ this.parser.$$destroyWorker();
146
+ }
131
147
  };
132
148
  var atom_default = AtomAssetsParser;
133
149
  // Annotate the CommonJS export names for ESM import in node:
@@ -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
@@ -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 & {
@@ -28,7 +28,8 @@ var configPlugins_default = (api) => {
28
28
  resolve: {
29
29
  docDirs: ["docs"],
30
30
  atomDirs: [{ type: "component", dir: "src" }],
31
- codeBlockMode: "active"
31
+ codeBlockMode: "active",
32
+ forceKebabCaseRouting: true
32
33
  },
33
34
  themeConfig: {
34
35
  footer: `Copyright \xA9 ${new Date().getFullYear()} | Powered by <a href="https://d.umijs.org" target="_blank" rel="noreferrer">dumi</a>`,
@@ -32,7 +32,8 @@ function getSchemas() {
32
32
  atomDirs: Joi.array().items(Joi.object({ type: Joi.string(), dir: Joi.string() })).optional(),
33
33
  entityDirs: Joi.forbidden().error(new Error("`entityDirs` is already deprecated, please rename it to `atomDirs` in `.dumirc.ts`")),
34
34
  codeBlockMode: Joi.string().valid("active", "passive").optional(),
35
- entryFile: Joi.string().optional()
35
+ entryFile: Joi.string().optional(),
36
+ forceKebabCaseRouting: Joi.bool().optional()
36
37
  }).optional(),
37
38
  extraRemarkPlugins: getUnifiedPluginSchema,
38
39
  extraRehypePlugins: getUnifiedPluginSchema,
@@ -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
  }
@@ -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);
@@ -71,6 +73,7 @@ var parser_default = (api) => {
71
73
  api.onGenerateFiles(async () => {
72
74
  if (api.env === "production") {
73
75
  writeAtomsMetaFile(await api.service.atomParser.parse());
76
+ api.service.atomParser.destroy();
74
77
  } else if (prevData) {
75
78
  writeAtomsMetaFile(prevData);
76
79
  }
@@ -42,16 +42,17 @@ function kebabCaseRoutePath(routePath) {
42
42
  };
43
43
  return routePath.replace(/(.)?([A-Z][^A-Z/])/g, replacer).replace(/(.)?([A-Z]+)/g, replacer);
44
44
  }
45
- function localizeUmiRoute(route, locales) {
45
+ function localizeUmiRoute(route, locales, forceKebabCase) {
46
46
  const locale = locales.find((locale2) => route.path.endsWith(`/${locale2.id}`) && import_path.default.parse(route.file).name.endsWith(`.${locale2.id}`));
47
+ const format = forceKebabCase ? kebabCaseRoutePath : (str) => str;
47
48
  if (locale) {
48
49
  const base = !("base" in locale) || locale.base === "/" ? "" : locale.base.replace(/^(\/)(.+)$/, "$2$1");
49
50
  const suffix = "suffix" in locale ? locale.suffix : "";
50
- route.path = `${base}${kebabCaseRoutePath(route.path.replace(new RegExp(`/${locale.id}$`), "").replace(/((^|\/)(index|README))$/, ""))}${suffix}`;
51
+ route.path = `${base}${format(route.path.replace(new RegExp(`/${locale.id}$`), "").replace(/((^|\/)(index|README))$/, ""))}${suffix}`;
51
52
  route.absPath = route.path !== "/" ? `/${route.path}` : route.path;
52
53
  } else {
53
- route.path = kebabCaseRoutePath(route.path);
54
- route.absPath = kebabCaseRoutePath(route.absPath);
54
+ route.path = format(route.path);
55
+ route.absPath = format(route.absPath);
55
56
  }
56
57
  }
57
58
  function flatRoute(route, docLayoutId) {
@@ -61,14 +62,16 @@ function flatRoute(route, docLayoutId) {
61
62
  }
62
63
  }
63
64
  function getClientPageFile(file, cwd) {
65
+ let clientFile;
64
66
  try {
65
- return import_plugin_utils.resolve.sync(`dumi/dist/${file}`, {
67
+ clientFile = import_plugin_utils.resolve.sync(`dumi/dist/${file}`, {
66
68
  basedir: cwd,
67
69
  preserveSymlinks: false
68
70
  });
69
71
  } catch {
70
- return require.resolve(`../${file}`);
72
+ clientFile = require.resolve(`../${file}`);
71
73
  }
74
+ return (0, import_plugin_utils.winPath)(clientFile);
72
75
  }
73
76
  var routes_default = (api) => {
74
77
  var _a, _b, _c;
@@ -172,7 +175,7 @@ var routes_default = (api) => {
172
175
  at ${route.file}`);
173
176
  } else if (!route.isLayout) {
174
177
  flatRoute(route, docLayoutId);
175
- localizeUmiRoute(route, api.config.locales);
178
+ localizeUmiRoute(route, api.config.locales, api.config.resolve.forceKebabCaseRouting);
176
179
  }
177
180
  });
178
181
  if (Object.values(pages).every((route) => route.path !== "*")) {
@@ -193,7 +193,7 @@ function rehypeDemo(opts) {
193
193
  const { default: remarkRehype } = await import("remark-rehype");
194
194
  const { default: rehypeStringify } = await import("rehype-stringify");
195
195
  const { convert } = require("html-to-text");
196
- 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);
197
197
  previewerProps.description = String(result.value);
198
198
  asset.description = convert(result.value, {
199
199
  wordwrap: false
@@ -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
@@ -33,6 +33,7 @@ interface IDumiExtendsConfig {
33
33
  }[];
34
34
  codeBlockMode: 'active' | 'passive';
35
35
  entryFile?: string;
36
+ forceKebabCaseRouting: boolean;
36
37
  };
37
38
  locales: ILocalesConfig;
38
39
  themeConfig: IThemeConfig;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dumi",
3
- "version": "2.1.4",
3
+ "version": "2.1.6",
4
4
  "description": "📖 Documentation Generator of React Component",
5
5
  "keywords": [
6
6
  "generator",
@@ -86,7 +86,7 @@
86
86
  "classnames": "2.3.2",
87
87
  "codesandbox": "^2.2.3",
88
88
  "deepmerge": "^4.2.2",
89
- "dumi-afx-deps": "^1.0.0-alpha.6",
89
+ "dumi-afx-deps": "^1.0.0-alpha.12",
90
90
  "dumi-assets-types": "2.0.0-alpha.0",
91
91
  "enhanced-resolve": "^5.10.0",
92
92
  "estree-util-to-js": "^1.1.0",
@@ -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);