dumi 2.0.0-beta.5 → 2.0.0-beta.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.
@@ -0,0 +1,12 @@
1
+ import type { IApi } from "../types";
2
+ import type { ExampleAsset } from 'dumi-assets-types';
3
+ declare const examples: ExampleAsset[];
4
+ /**
5
+ * internal function to add example assets
6
+ */
7
+ export declare function addExampleAssets(data: typeof examples): void;
8
+ /**
9
+ * plugin for generate assets.json
10
+ */
11
+ declare const _default: (api: IApi) => void;
12
+ export default _default;
@@ -0,0 +1,67 @@
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/assets.ts
23
+ var assets_exports = {};
24
+ __export(assets_exports, {
25
+ addExampleAssets: () => addExampleAssets,
26
+ default: () => assets_default
27
+ });
28
+ module.exports = __toCommonJS(assets_exports);
29
+ var import_fs = __toESM(require("fs"));
30
+ var import_path = __toESM(require("path"));
31
+ var import_plugin_utils = require("umi/plugin-utils");
32
+ var examples = [];
33
+ function addExampleAssets(data) {
34
+ examples.push(...data);
35
+ }
36
+ var assets_default = (api) => {
37
+ api.describe({
38
+ config: {
39
+ schema: (Joi) => Joi.object()
40
+ },
41
+ enableBy: ({ env }) => env === "production" && Boolean(api.args.assets)
42
+ });
43
+ api.onBuildComplete(async () => {
44
+ const { components } = await api.service.atomParser.parse();
45
+ const assets = await api.applyPlugins({
46
+ key: "modifyAssetsMetadata",
47
+ initialValue: {
48
+ name: api.config.themeConfig.title || api.pkg.name,
49
+ npmPackageName: api.pkg.name,
50
+ version: api.pkg.version,
51
+ description: api.pkg.description,
52
+ logo: api.config.themeConfig.logo,
53
+ homepage: api.pkg.homepage,
54
+ repository: api.pkg.repository,
55
+ assets: {
56
+ atoms: Object.values(components),
57
+ examples: import_plugin_utils.lodash.uniqBy(examples, "id")
58
+ }
59
+ }
60
+ });
61
+ import_fs.default.writeFileSync(import_path.default.join(api.cwd, "assets.json"), JSON.stringify(assets, null, 2), "utf-8");
62
+ });
63
+ };
64
+ // Annotate the CommonJS export names for ESM import in node:
65
+ 0 && (module.exports = {
66
+ addExampleAssets
67
+ });
@@ -26,6 +26,7 @@ __export(compile_exports, {
26
26
  });
27
27
  module.exports = __toCommonJS(compile_exports);
28
28
  var import_react = __toESM(require("../techStacks/react"));
29
+ var import_assets = require("./assets");
29
30
  var compile_default = (api) => {
30
31
  api.register({
31
32
  key: "registerTechStack",
@@ -52,7 +53,10 @@ var compile_default = (api) => {
52
53
  };
53
54
  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
55
  ...loaderBaseOpts,
55
- mode: "meta"
56
+ mode: "meta",
57
+ onResolveDemos(demos) {
58
+ (0, import_assets.addExampleAssets)(demos.map(({ asset }) => asset));
59
+ }
56
60
  }).end().end().oneOf("md").use("babel-loader").loader(babelInUmi.loader).options(babelInUmi.options).end().use("md-loader").loader(loaderPath).options({
57
61
  ...loaderBaseOpts,
58
62
  builtins: api.service.themeData.builtins
@@ -25,7 +25,7 @@ __export(parser_exports, {
25
25
  default: () => parser_default
26
26
  });
27
27
  module.exports = __toCommonJS(parser_exports);
28
- var import_atom = __toESM(require("../assetParsers/atom"));
28
+ var import_assert = __toESM(require("assert"));
29
29
  var import_meta = require("./meta");
30
30
  var parser_default = (api) => {
31
31
  const writeAtomsMetaFile = (data) => {
@@ -43,15 +43,14 @@ var parser_default = (api) => {
43
43
  }
44
44
  });
45
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
- }
46
+ var _a, _b;
47
+ (0, import_assert.default)((_a = api.userConfig.resolve) == null ? void 0 : _a.entryFile, "`resolve.entryFile` must be configured when `apiParser` enable");
48
+ (0, import_assert.default)((_b = api.pkg.devDependencies) == null ? void 0 : _b["typescript"], "typescript must be installed when `apiParser` enable");
51
49
  return memo;
52
50
  });
53
- api.onStart(() => {
54
- api.service.atomParser = new import_atom.default({
51
+ api.onStart(async () => {
52
+ const { default: AtomAssetsParser } = await import("../assetParsers/atom");
53
+ api.service.atomParser = new AtomAssetsParser({
55
54
  entryFile: api.config.resolve.entryFile,
56
55
  resolveDir: api.cwd
57
56
  });
@@ -1,5 +1,14 @@
1
1
  import type { IApi } from "../types";
2
+ export interface IContentTab {
3
+ key: string;
4
+ id?: string;
5
+ test?: RegExp;
6
+ component: string;
7
+ }
2
8
  export declare function isTabRouteFile(file: string): boolean;
3
9
  export declare function getTabKeyFromFile(file: string): string;
10
+ /**
11
+ * plugin for add conventional tab and plugin tab into page content
12
+ */
4
13
  declare const _default: (api: IApi) => void;
5
14
  export default _default;
@@ -38,8 +38,19 @@ function getTabKeyFromFile(file) {
38
38
  return file.match(/\$tab-([^.]+)/)[1];
39
39
  }
40
40
  var tabs_default = (api) => {
41
+ let tabsFromPlugins;
42
+ const routesTabMapping = {};
41
43
  const tabs = [];
42
44
  api.describe({ key: void 0 });
45
+ api.modifyConfig(async (memo) => {
46
+ tabsFromPlugins = await api.applyPlugins({
47
+ key: "addContentTab"
48
+ });
49
+ tabsFromPlugins.forEach((tab) => {
50
+ tab.id ?? (tab.id = `plugin-tab${tab.test ? `-${tab.test}` : ""}-${tab.key}`);
51
+ });
52
+ return memo;
53
+ });
43
54
  api.modifyRoutes((routes) => {
44
55
  tabs.length = 0;
45
56
  Object.values(routes).forEach((route) => {
@@ -52,24 +63,35 @@ var tabs_default = (api) => {
52
63
  tabs.push({
53
64
  index: tabs.length,
54
65
  key: tabKey,
55
- id: `${routeId}`,
56
- file: route.file,
57
- parentFile
66
+ id: routeId,
67
+ file: route.file
68
+ });
69
+ routesTabMapping[parentFile] ?? (routesTabMapping[parentFile] = []);
70
+ routesTabMapping[parentFile].push(routeId);
71
+ } else {
72
+ tabsFromPlugins.forEach((tab) => {
73
+ var _a;
74
+ if (!tab.test || route.absPath.match(tab.test)) {
75
+ routesTabMapping[_a = route.file] ?? (routesTabMapping[_a] = []);
76
+ routesTabMapping[route.file].push(tab.id);
77
+ }
58
78
  });
59
79
  }
60
80
  });
81
+ tabs.push(...tabsFromPlugins.map((tab) => ({
82
+ index: tabs.length,
83
+ key: tab.key,
84
+ id: tab.id,
85
+ file: tab.component
86
+ })));
61
87
  return routes;
62
88
  });
63
89
  api.register({
64
90
  key: "dumi.modifyMetaFiles",
65
91
  fn: (metaFiles) => {
66
- const tabsMapping = tabs.reduce((ret, tab) => ({
67
- ...ret,
68
- [tab.parentFile]: [...ret[tab.parentFile] || [], tab]
69
- }), {});
70
92
  Object.values(metaFiles).forEach((metaFile) => {
71
- if (tabsMapping[metaFile.file]) {
72
- metaFile.tabs = JSON.stringify(tabsMapping[metaFile.file].map(({ id }) => id));
93
+ if (routesTabMapping[metaFile.file]) {
94
+ metaFile.tabs = JSON.stringify(routesTabMapping[metaFile.file]);
73
95
  }
74
96
  });
75
97
  tabs.forEach((tab) => {
@@ -1,11 +1,12 @@
1
1
  import type { IThemeLoadResult } from "../../features/theme/loader";
2
- import { type IMdTransformerOptions } from './transformer';
2
+ import { type IMdTransformerOptions, type IMdTransformerResult } from './transformer';
3
3
  interface IMdLoaderDefaultModeOptions extends Omit<IMdTransformerOptions, 'fileAbsPath'> {
4
4
  mode?: 'markdown';
5
5
  builtins: IThemeLoadResult['builtins'];
6
6
  }
7
7
  interface IMdLoaderDemosModeOptions extends Omit<IMdLoaderDefaultModeOptions, 'builtins' | 'mode'> {
8
8
  mode: 'meta';
9
+ onResolveDemos?: (demos: IMdTransformerResult['meta']['demos']) => void;
9
10
  }
10
11
  export declare type IMdLoaderOptions = IMdLoaderDefaultModeOptions | IMdLoaderDemosModeOptions;
11
12
  export default function mdLoader(this: any, raw: string): void;
@@ -47,6 +47,9 @@ function mdLoader(raw) {
47
47
  if (opts.mode === "meta") {
48
48
  const { demos, frontmatter, toc, embeds = [] } = ret.meta;
49
49
  embeds.forEach((file) => this.addDependency(file));
50
+ if (demos && opts.onResolveDemos) {
51
+ opts.onResolveDemos(demos);
52
+ }
50
53
  cb(null, import_plugin_utils.Mustache.render(`import React from 'react';
51
54
 
52
55
  export const demos = {
@@ -64,10 +67,12 @@ export const toc = {{{toc}}}
64
67
  frontmatter: JSON.stringify(frontmatter),
65
68
  toc: JSON.stringify(toc),
66
69
  renderAsset: function renderAsset() {
70
+ let asset = this.asset;
67
71
  Object.keys(this.sources).forEach((file) => {
68
- this.asset.dependencies[file].value = `{{{require('!!raw-loader!${this.sources[file]}?raw').default}}}`;
72
+ asset = import_plugin_utils.lodash.cloneDeep(this.asset);
73
+ asset.dependencies[file].value = `{{{require('!!raw-loader!${this.sources[file]}?raw').default}}}`;
69
74
  });
70
- return JSON.stringify(this.asset, null, 2).replace(/"{{{|}}}"/g, "");
75
+ return JSON.stringify(asset, null, 2).replace(/"{{{|}}}"/g, "");
71
76
  }
72
77
  }));
73
78
  } else {
@@ -153,14 +153,20 @@ function rehypeDemo(opts) {
153
153
  deferrers.push((0, import_block.default)(parseOpts).then(async ({ asset, sources, frontmatter }) => {
154
154
  var _a3;
155
155
  const { src, className, ...restAttrs } = codeNode.properties || {};
156
- if (restAttrs.title) {
157
- asset.title = String(restAttrs.title);
158
- }
156
+ const validAssetAttrs = [
157
+ "title",
158
+ "snapshot",
159
+ "keywords"
160
+ ];
159
161
  Object.keys(restAttrs).forEach((key) => {
160
162
  if (restAttrs[key] === "")
161
163
  restAttrs[key] = true;
162
164
  });
163
165
  const originalProps = Object.assign({}, frontmatter, restAttrs);
166
+ validAssetAttrs.forEach((key) => {
167
+ if (originalProps[key])
168
+ asset[key] = originalProps[key];
169
+ });
164
170
  Object.assign(previewerProps, await ((_a3 = techStack.generatePreviewerProps) == null ? void 0 : _a3.call(techStack, originalProps, {
165
171
  type: codeType,
166
172
  mdAbsPath: opts.fileAbsPath,
package/dist/preset.js CHANGED
@@ -39,7 +39,8 @@ var preset_default = (api) => {
39
39
  require.resolve("./features/tabs"),
40
40
  require.resolve("./features/theme"),
41
41
  require.resolve("./features/locales"),
42
- require.resolve("./features/parser")
42
+ require.resolve("./features/parser"),
43
+ require.resolve("./features/assets")
43
44
  ]
44
45
  };
45
46
  };
@@ -24,7 +24,12 @@ __export(registerMethods_exports, {
24
24
  module.exports = __toCommonJS(registerMethods_exports);
25
25
  var registerMethods_default = (api) => {
26
26
  api.describe({ key: "dumi:registerMethods" });
27
- ["registerTechStack"].forEach((name) => {
27
+ [
28
+ "registerTechStack",
29
+ "addContentTab",
30
+ "modifyAssetsMetadata",
31
+ "modifyTheme"
32
+ ].forEach((name) => {
28
33
  api.registerMethod({ name });
29
34
  });
30
35
  };
package/dist/types.d.ts CHANGED
@@ -1,9 +1,10 @@
1
1
  import type AtomAssetsParser from "./assetParsers/atom";
2
2
  import type { IDumiDemoProps } from "./client/theme-api/DumiDemo";
3
3
  import type { ILocalesConfig, IThemeConfig } from "./client/theme-api/types";
4
+ import type { IContentTab } from "./features/tabs";
4
5
  import type { IThemeLoadResult } from "./features/theme/loader";
5
6
  import type { IModify } from '@umijs/core';
6
- import type { ExampleBlockAsset } from 'dumi-assets-types';
7
+ import type { AssetsPackage, ExampleBlockAsset } from 'dumi-assets-types';
7
8
  import type { Element } from 'hast';
8
9
  import type { IApi as IUmiApi } from 'umi';
9
10
  declare type IUmiConfig = IUmiApi['config'];
@@ -77,5 +78,13 @@ export declare type IApi = IUmiApi & {
77
78
  * modify original theme data
78
79
  */
79
80
  modifyTheme: IModify<IThemeLoadResult, null>;
81
+ /**
82
+ * add content tab
83
+ */
84
+ addContentTab: (fn: () => IContentTab) => void;
85
+ /**
86
+ * modify assets metadata
87
+ */
88
+ modifyAssetsMetadata: IModify<AssetsPackage, null>;
80
89
  };
81
90
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dumi",
3
- "version": "2.0.0-beta.5",
3
+ "version": "2.0.0-beta.6",
4
4
  "description": "Framework for developing UI components",
5
5
  "keywords": [],
6
6
  "license": "MIT",