@rspress/plugin-api-docgen 1.37.2 → 1.37.3

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
@@ -1,63 +1,68 @@
1
- import { RspressPlugin } from '@rspress/shared';
2
- import { ParserOptions } from 'react-docgen-typescript';
3
- import { CompilerOptions } from 'typescript';
4
-
5
- type Entries = Record<string, string>;
6
- type ToolEntries = {
7
- documentation: Entries;
8
- 'react-docgen-typescript': Entries;
9
- };
10
- type ApiParseTool = 'documentation' | 'react-docgen-typescript';
11
- type DocumentationArgs = {
12
- external?: Array<string>;
13
- shallow?: boolean;
14
- order?: Array<unknown>;
15
- access?: Array<string>;
16
- hljs?: {
17
- highlightAuto?: boolean;
18
- languages?: string;
19
- };
20
- inferPrivate?: string;
21
- extension?: string | Array<string>;
22
- noReferenceLinks?: boolean;
23
- };
24
- type ParseToolOptions = {
25
- 'react-docgen-typescript'?: ParserOptions & {
26
- tsconfigPath?: Record<string, string>;
27
- compilerOptions?: Record<string, CompilerOptions>;
28
- };
29
- documentation?: DocumentationArgs;
30
- };
31
- type PluginOptions = {
32
- /**
33
- * Module entries
34
- * @zh 传入自动生成文档的模块名称及相对路径
35
- */
36
- entries?: Entries | ToolEntries;
37
- /**
38
- * apiParseTool
39
- * @experimental
40
- * @zh 解析工具
41
- * @default 'react-docgen-typescript'
42
- */
43
- apiParseTool?: ApiParseTool;
44
- /**
45
- * parserToolOptions
46
- * @experimental
47
- * @zh 解析器参数
48
- */
49
- parseToolOptions?: ParseToolOptions;
50
- /**
51
- * appDirectory
52
- * @zh 项目根目录
53
- * @default process.cwd()
54
- */
55
- appDir?: string;
56
- };
57
-
58
- /**
59
- * The plugin is used to generate api doc for files.
60
- */
61
- declare function pluginApiDocgen(options?: PluginOptions): RspressPlugin;
62
-
63
- export { type PluginOptions, pluginApiDocgen };
1
+ import type { CompilerOptions } from 'typescript';
2
+ import type { ParserOptions } from 'react-docgen-typescript';
3
+ import type { RspressPlugin } from '@rspress/shared';
4
+
5
+ declare type ApiParseTool = 'documentation' | 'react-docgen-typescript';
6
+
7
+ declare type DocumentationArgs = {
8
+ external?: Array<string>;
9
+ shallow?: boolean;
10
+ order?: Array<unknown>;
11
+ access?: Array<string>;
12
+ hljs?: {
13
+ highlightAuto?: boolean;
14
+ languages?: string;
15
+ };
16
+ inferPrivate?: string;
17
+ extension?: string | Array<string>;
18
+ noReferenceLinks?: boolean;
19
+ };
20
+
21
+ declare type Entries = Record<string, string>;
22
+
23
+ declare type ParseToolOptions = {
24
+ 'react-docgen-typescript'?: ParserOptions & {
25
+ tsconfigPath?: Record<string, string>;
26
+ compilerOptions?: Record<string, CompilerOptions>;
27
+ };
28
+ documentation?: DocumentationArgs;
29
+ };
30
+
31
+ /**
32
+ * The plugin is used to generate api doc for files.
33
+ */
34
+ export declare function pluginApiDocgen(options?: PluginOptions): RspressPlugin;
35
+
36
+ export declare type PluginOptions = {
37
+ /**
38
+ * Module entries
39
+ * @zh 传入自动生成文档的模块名称及相对路径
40
+ */
41
+ entries?: Entries | ToolEntries;
42
+ /**
43
+ * apiParseTool
44
+ * @experimental
45
+ * @zh 解析工具
46
+ * @default 'react-docgen-typescript'
47
+ */
48
+ apiParseTool?: ApiParseTool;
49
+ /**
50
+ * parserToolOptions
51
+ * @experimental
52
+ * @zh 解析器参数
53
+ */
54
+ parseToolOptions?: ParseToolOptions;
55
+ /**
56
+ * appDirectory
57
+ * @zh 项目根目录
58
+ * @default process.cwd()
59
+ */
60
+ appDir?: string;
61
+ };
62
+
63
+ declare type ToolEntries = {
64
+ documentation: Entries;
65
+ 'react-docgen-typescript': Entries;
66
+ };
67
+
68
+ export { }
package/dist/index.js CHANGED
@@ -1,335 +1,322 @@
1
1
  "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
2
+ var __webpack_modules__ = {
3
+ documentation: function(module) {
4
+ module.exports = import("documentation");
5
+ }
19
6
  };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
-
30
- // src/index.ts
31
- var src_exports = {};
32
- __export(src_exports, {
33
- pluginApiDocgen: () => pluginApiDocgen
7
+ /************************************************************************/ // The module cache
8
+ var __webpack_module_cache__ = {};
9
+ // The require function
10
+ function __webpack_require__(moduleId) {
11
+ // Check if module is in cache
12
+ var cachedModule = __webpack_module_cache__[moduleId];
13
+ if (void 0 !== cachedModule) return cachedModule.exports;
14
+ // Create a new module (and put it into the cache)
15
+ var module = __webpack_module_cache__[moduleId] = {
16
+ exports: {}
17
+ };
18
+ // Execute the module function
19
+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
20
+ // Return the exports of the module
21
+ return module.exports;
22
+ }
23
+ /************************************************************************/ // webpack/runtime/compat_get_default_export
24
+ (()=>{
25
+ // getDefaultExport function for compatibility with non-ESM modules
26
+ __webpack_require__.n = function(module) {
27
+ var getter = module && module.__esModule ? function() {
28
+ return module['default'];
29
+ } : function() {
30
+ return module;
31
+ };
32
+ __webpack_require__.d(getter, {
33
+ a: getter
34
+ });
35
+ return getter;
36
+ };
37
+ })();
38
+ // webpack/runtime/define_property_getters
39
+ (()=>{
40
+ __webpack_require__.d = function(exports1, definition) {
41
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
42
+ enumerable: true,
43
+ get: definition[key]
44
+ });
45
+ };
46
+ })();
47
+ // webpack/runtime/has_own_property
48
+ (()=>{
49
+ __webpack_require__.o = function(obj, prop) {
50
+ return Object.prototype.hasOwnProperty.call(obj, prop);
51
+ };
52
+ })();
53
+ // webpack/runtime/make_namespace_object
54
+ (()=>{
55
+ // define __esModule on exports
56
+ __webpack_require__.r = function(exports1) {
57
+ if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
58
+ value: 'Module'
59
+ });
60
+ Object.defineProperty(exports1, '__esModule', {
61
+ value: true
62
+ });
63
+ };
64
+ })();
65
+ /************************************************************************/ var __webpack_exports__ = {};
66
+ // ESM COMPAT FLAG
67
+ __webpack_require__.r(__webpack_exports__);
68
+ // EXPORTS
69
+ __webpack_require__.d(__webpack_exports__, {
70
+ pluginApiDocgen: ()=>/* binding */ pluginApiDocgen
34
71
  });
35
- module.exports = __toCommonJS(src_exports);
36
- var import_node_path3 = __toESM(require("path"));
37
- var import_node_fs2 = __toESM(require("fs"));
38
-
39
- // src/docgen.ts
40
- var import_node_path2 = __toESM(require("path"));
41
- var import_node_fs = __toESM(require("fs"));
42
- var import_logger = require("@rspress/shared/logger");
43
- var import_chokidar = __toESM(require("chokidar"));
44
- var import_react_docgen_typescript = require("react-docgen-typescript");
45
- var import_shared = require("@rspress/shared");
46
-
47
- // src/constants.ts
48
- var import_node_path = __toESM(require("path"));
49
- var PACKAGE_ROOT = import_node_path.default.join(__dirname, "..");
50
- var apiDocMap = {};
51
-
52
- // src/locales.ts
53
- var locales = {
54
- zh: {
55
- copy: "复制",
56
- copied: "复制成功",
57
- expand: "展开代码",
58
- collapse: "收起代码",
59
- className: "节点类名",
60
- style: "节点样式",
61
- children: "子节点",
62
- disabled: "是否禁用",
63
- required: "必填",
64
- property: "属性",
65
- description: "说明",
66
- type: "类型",
67
- defaultValue: "默认值",
68
- overview: "概览"
69
- },
70
- en: {
71
- copy: "Copy",
72
- copied: "Copied Success!",
73
- expand: "Expand Code",
74
- collapse: "Collapse Code",
75
- className: "Additional css class",
76
- style: "Additional style",
77
- children: "Children",
78
- disabled: "Whether to disable ",
79
- required: "Required",
80
- property: "Property",
81
- description: "Description",
82
- type: "Type",
83
- defaultValue: "Default Value",
84
- overview: "Overview"
85
- }
86
- };
87
-
88
- // src/docgen.ts
89
- var isToolEntries = (obj) => {
90
- return obj.documentation || obj["react-docgen-typescript"];
91
- };
92
- var docgen = async ({
93
- entries,
94
- languages,
95
- apiParseTool,
96
- appDir,
97
- parseToolOptions,
98
- isProd
99
- }) => {
100
- const watchFileMap = {};
101
- const genApiDoc = async (entry, tool) => {
102
- if (Object.keys(entry).length === 0) {
103
- return;
72
+ const external_node_path_namespaceObject = require("node:path");
73
+ var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
74
+ const external_node_fs_namespaceObject = require("node:fs");
75
+ var external_node_fs_default = /*#__PURE__*/ __webpack_require__.n(external_node_fs_namespaceObject);
76
+ const logger_namespaceObject = require("@rspress/shared/logger");
77
+ const external_chokidar_namespaceObject = require("chokidar");
78
+ var external_chokidar_default = /*#__PURE__*/ __webpack_require__.n(external_chokidar_namespaceObject);
79
+ const external_react_docgen_typescript_namespaceObject = require("react-docgen-typescript");
80
+ const shared_namespaceObject = require("@rspress/shared");
81
+ external_node_path_default().join(__dirname, '..');
82
+ const apiDocMap = {};
83
+ const locales = {
84
+ zh: {
85
+ copy: '复制',
86
+ copied: '复制成功',
87
+ expand: '展开代码',
88
+ collapse: '收起代码',
89
+ className: '节点类名',
90
+ style: '节点样式',
91
+ children: '子节点',
92
+ disabled: '是否禁用',
93
+ required: '必填',
94
+ property: '属性',
95
+ description: '说明',
96
+ type: '类型',
97
+ defaultValue: '默认值',
98
+ overview: '概览'
99
+ },
100
+ en: {
101
+ copy: 'Copy',
102
+ copied: 'Copied Success!',
103
+ expand: 'Expand Code',
104
+ collapse: 'Collapse Code',
105
+ className: 'Additional css class',
106
+ style: 'Additional style',
107
+ children: 'Children',
108
+ disabled: 'Whether to disable ',
109
+ required: 'Required',
110
+ property: 'Property',
111
+ description: 'Description',
112
+ type: 'Type',
113
+ defaultValue: 'Default Value',
114
+ overview: 'Overview'
104
115
  }
105
- await Promise.all(
106
- Object.entries(entry).map(async ([key, value]) => {
107
- const moduleSourceFilePath = import_node_path2.default.resolve(appDir, value);
108
- watchFileMap[moduleSourceFilePath] = {
109
- apiParseTool,
110
- moduleName: key
111
- };
112
- try {
113
- if (tool === "documentation") {
114
- const documentation = await import("documentation");
115
- const documentationRes = await documentation.build(
116
- [moduleSourceFilePath],
117
- {
118
- ...parseToolOptions.documentation
119
- }
120
- );
121
- const apiDoc = await documentation.formats.md(documentationRes, {
122
- noReferenceLinks: parseToolOptions.documentation?.noReferenceLinks ?? true
123
- });
124
- apiDocMap[key] = apiDoc;
125
- } else {
126
- const { tsconfigPath, compilerOptions, ...restOptions } = parseToolOptions?.["react-docgen-typescript"] ?? {};
127
- const parserOpts = {
128
- // https://github.com/styleguidist/react-docgen-typescript/blob/master/README.md?plain=1#L111
129
- propFilter: (prop) => {
130
- if (prop.declarations !== void 0 && prop.declarations.length > 0) {
131
- const hasPropAdditionalDescription = prop.declarations.find(
132
- (declaration) => {
133
- return !declaration.fileName.includes("node_modules");
134
- }
135
- );
136
- return Boolean(hasPropAdditionalDescription);
137
- }
138
- return true;
139
- },
140
- ...restOptions
116
+ };
117
+ const isToolEntries = (obj)=>obj.documentation || obj['react-docgen-typescript'];
118
+ const docgen = async ({ entries, languages, apiParseTool, appDir, parseToolOptions, isProd })=>{
119
+ const watchFileMap = {};
120
+ const genApiDoc = async (entry, tool)=>{
121
+ if (0 === Object.keys(entry).length) return;
122
+ await Promise.all(Object.entries(entry).map(async ([key, value])=>{
123
+ const moduleSourceFilePath = external_node_path_default().resolve(appDir, value);
124
+ watchFileMap[moduleSourceFilePath] = {
125
+ apiParseTool,
126
+ moduleName: key
141
127
  };
142
- let fileParser = (0, import_react_docgen_typescript.withDefaultConfig)(parserOpts);
143
- if (tsconfigPath?.[key]) {
144
- fileParser = (0, import_react_docgen_typescript.withCustomConfig)(tsconfigPath[key], parserOpts);
145
- } else if (compilerOptions?.[key]) {
146
- fileParser = (0, import_react_docgen_typescript.withCompilerOptions)(
147
- compilerOptions[key],
148
- parserOpts
149
- );
150
- }
151
- const componentDoc = fileParser.parse(moduleSourceFilePath);
152
- if (componentDoc.length === 0) {
153
- import_logger.logger.warn(
154
- "[module-doc-plugin]",
155
- `Unable to parse API document in ${moduleSourceFilePath}`
156
- );
128
+ try {
129
+ if ('documentation' === tool) {
130
+ var _parseToolOptions_documentation;
131
+ const documentation = await Promise.resolve().then(__webpack_require__.bind(__webpack_require__, "documentation"));
132
+ const documentationRes = await documentation.build([
133
+ moduleSourceFilePath
134
+ ], {
135
+ ...parseToolOptions.documentation
136
+ });
137
+ const apiDoc = await documentation.formats.md(documentationRes, {
138
+ noReferenceLinks: (null === (_parseToolOptions_documentation = parseToolOptions.documentation) || void 0 === _parseToolOptions_documentation ? void 0 : _parseToolOptions_documentation.noReferenceLinks) ?? true
139
+ });
140
+ apiDocMap[key] = apiDoc;
141
+ } else {
142
+ const { tsconfigPath, compilerOptions, ...restOptions } = (null == parseToolOptions ? void 0 : parseToolOptions['react-docgen-typescript']) ?? {};
143
+ const parserOpts = {
144
+ // https://github.com/styleguidist/react-docgen-typescript/blob/master/README.md?plain=1#L111
145
+ propFilter: (prop)=>{
146
+ if (void 0 !== prop.declarations && prop.declarations.length > 0) {
147
+ const hasPropAdditionalDescription = prop.declarations.find((declaration)=>!declaration.fileName.includes('node_modules'));
148
+ return Boolean(hasPropAdditionalDescription);
149
+ }
150
+ return true;
151
+ },
152
+ ...restOptions
153
+ };
154
+ let fileParser = (0, external_react_docgen_typescript_namespaceObject.withDefaultConfig)(parserOpts);
155
+ if (null == tsconfigPath ? void 0 : tsconfigPath[key]) fileParser = (0, external_react_docgen_typescript_namespaceObject.withCustomConfig)(tsconfigPath[key], parserOpts);
156
+ else if (null == compilerOptions ? void 0 : compilerOptions[key]) fileParser = (0, external_react_docgen_typescript_namespaceObject.withCompilerOptions)(compilerOptions[key], parserOpts);
157
+ const componentDoc = fileParser.parse(moduleSourceFilePath);
158
+ if (0 === componentDoc.length) logger_namespaceObject.logger.warn('[module-doc-plugin]', `Unable to parse API document in ${moduleSourceFilePath}`);
159
+ if (languages.length > 0) languages.forEach((language)=>{
160
+ apiDocMap[`${key}-${language}`] = generateTable(componentDoc, language);
161
+ });
162
+ else apiDocMap[key] = generateTable(componentDoc, 'en');
163
+ }
164
+ } catch (e) {
165
+ if (e instanceof Error) logger_namespaceObject.logger.error('[module-doc-plugin]', `Generate API table error: ${e.message}`);
157
166
  }
158
- if (languages.length > 0) {
159
- languages.forEach((language) => {
160
- apiDocMap[`${key}-${language}`] = generateTable(
161
- componentDoc,
162
- language
163
- );
164
- });
165
- } else {
166
- apiDocMap[key] = generateTable(componentDoc, "en");
167
+ }));
168
+ };
169
+ logger_namespaceObject.logger.info('[module-doc-plugin]', 'Start to generate API table...');
170
+ if (isToolEntries(entries)) {
171
+ const reactEntries = entries['react-docgen-typescript'];
172
+ const documentationEntries = entries.documentation;
173
+ await Promise.all([
174
+ genApiDoc(reactEntries, 'react-docgen-typescript'),
175
+ genApiDoc(documentationEntries, 'documentation')
176
+ ]);
177
+ } else await genApiDoc(entries, apiParseTool);
178
+ if (!isProd) {
179
+ const watcher = external_chokidar_default().watch(Object.keys(watchFileMap), {
180
+ ignoreInitial: true,
181
+ ignorePermissionErrors: true,
182
+ ignored: [
183
+ /node_modules/
184
+ ]
185
+ });
186
+ let isUpdate = false;
187
+ watcher.on('change', (changed)=>{
188
+ if (isUpdate) return;
189
+ isUpdate = true;
190
+ logger_namespaceObject.logger.info('[module-doc-plugin]', 'updating API');
191
+ const watchFileInfo = watchFileMap[changed];
192
+ if (watchFileInfo) {
193
+ const { apiParseTool, moduleName } = watchFileInfo;
194
+ const updateSiteData = ()=>{
195
+ const siteDataPath = external_node_path_default().join(process.cwd(), 'node_modules', shared_namespaceObject.RSPRESS_TEMP_DIR, 'runtime', 'virtual-site-data.mjs');
196
+ import(siteDataPath).then((siteData)=>{
197
+ const data = {
198
+ ...siteData.default
199
+ };
200
+ data.pages.forEach((page)=>{
201
+ page.apiDocMap = apiDocMap;
202
+ });
203
+ external_node_fs_default().writeFileSync(siteDataPath, `export default ${JSON.stringify(data)}`);
204
+ isUpdate = false;
205
+ });
206
+ };
207
+ genApiDoc({
208
+ [moduleName]: changed
209
+ }, apiParseTool).then(updateSiteData);
167
210
  }
168
- }
169
- } catch (e) {
170
- if (e instanceof Error) {
171
- import_logger.logger.error(
172
- "[module-doc-plugin]",
173
- `Generate API table error: ${e.message}`
174
- );
175
- }
176
- }
177
- })
178
- );
179
- };
180
- import_logger.logger.info("[module-doc-plugin]", "Start to generate API table...");
181
- if (isToolEntries(entries)) {
182
- const reactEntries = entries["react-docgen-typescript"];
183
- const documentationEntries = entries.documentation;
184
- await Promise.all([
185
- genApiDoc(reactEntries, "react-docgen-typescript"),
186
- genApiDoc(documentationEntries, "documentation")
187
- ]);
188
- } else {
189
- await genApiDoc(entries, apiParseTool);
190
- }
191
- if (!isProd) {
192
- const watcher = import_chokidar.default.watch(Object.keys(watchFileMap), {
193
- ignoreInitial: true,
194
- ignorePermissionErrors: true,
195
- ignored: [/node_modules/]
196
- });
197
- let isUpdate = false;
198
- watcher.on("change", (changed) => {
199
- if (isUpdate) {
200
- return;
201
- }
202
- isUpdate = true;
203
- import_logger.logger.info("[module-doc-plugin]", "updating API");
204
- const watchFileInfo = watchFileMap[changed];
205
- if (watchFileInfo) {
206
- const { apiParseTool: apiParseTool2, moduleName } = watchFileInfo;
207
- const updateSiteData = () => {
208
- const siteDataPath = import_node_path2.default.join(
209
- process.cwd(),
210
- "node_modules",
211
- import_shared.RSPRESS_TEMP_DIR,
212
- "runtime",
213
- "virtual-site-data.mjs"
214
- );
215
- import(siteDataPath).then((siteData) => {
216
- const data = { ...siteData.default };
217
- data.pages.forEach((page) => {
218
- page.apiDocMap = apiDocMap;
219
- });
220
- import_node_fs.default.writeFileSync(
221
- siteDataPath,
222
- `export default ${JSON.stringify(data)}`
223
- );
224
- isUpdate = false;
225
- });
226
- };
227
- genApiDoc({ [moduleName]: changed }, apiParseTool2).then(updateSiteData);
228
- }
229
- });
230
- }
231
- import_logger.logger.success("[module-doc-plugin]", "Generate API table successfully!");
211
+ });
212
+ }
213
+ logger_namespaceObject.logger.success('[module-doc-plugin]', 'Generate API table successfully!');
232
214
  };
233
215
  function generateTable(componentDoc, language) {
234
- return componentDoc.map((param) => {
235
- const { props } = param;
236
- const t = locales[language];
237
- const PROP_TABLE_HEADER = `|${t.property}|${t.description}|${t.type}|${t.defaultValue}|
238
- |:---:|:---:|:---:|:---:|`;
239
- const tableContent = Object.keys(props).filter((propName) => {
240
- const { name, description } = props[propName];
241
- return description || ["className", "style", "disabled", "children"].indexOf(name) > -1;
242
- }).map((propName) => {
243
- const { defaultValue, description, name, required, type } = props[propName];
244
- const getType = () => `\`${type.name.replace(/\|/g, "\\|")}\`${required ? ` **(${t.required})**` : ""}`;
245
- const getDefaultValue = () => `\`${defaultValue?.value || "-"}\``;
246
- const getDescription = () => {
247
- switch (name) {
248
- case "className":
249
- return description || t.className;
250
- case "style":
251
- return description || t.style;
252
- case "children":
253
- return description || t.children;
254
- case "disabled":
255
- return description || t.disabled;
256
- default:
257
- return description;
258
- }
259
- };
260
- const formattedDescription = getDescription().replace(/\n/g, "&#10;");
261
- return `|${[name, formattedDescription, getType(), getDefaultValue()].map((str) => str.replace(/(?<!\\)\|/g, "&#124;")).join("|")}|`;
262
- });
263
- return `
264
- ${param.displayName ? `### ${param.displayName}
265
- ` : ""}
266
- ${param.description ? `**${param.description}**
267
- ` : ""}
216
+ return componentDoc.map((param)=>{
217
+ const { props } = param;
218
+ const t = locales[language];
219
+ const PROP_TABLE_HEADER = `|${t.property}|${t.description}|${t.type}|${t.defaultValue}|\n|:---:|:---:|:---:|:---:|`;
220
+ const tableContent = Object.keys(props).filter((propName)=>{
221
+ const { name, description } = props[propName];
222
+ return description || [
223
+ 'className',
224
+ 'style',
225
+ 'disabled',
226
+ 'children'
227
+ ].indexOf(name) > -1;
228
+ }).map((propName)=>{
229
+ const { defaultValue, description, name, required, type } = props[propName];
230
+ const getType = ()=>`\`${type.name.replace(/\|/g, '\\|')}\`${required ? ` **(${t.required})**` : ''}`;
231
+ const getDefaultValue = ()=>`\`${(null == defaultValue ? void 0 : defaultValue.value) || '-'}\``;
232
+ const getDescription = ()=>{
233
+ switch(name){
234
+ case 'className':
235
+ return description || t.className;
236
+ case 'style':
237
+ return description || t.style;
238
+ case 'children':
239
+ return description || t.children;
240
+ case 'disabled':
241
+ return description || t.disabled;
242
+ default:
243
+ return description;
244
+ }
245
+ };
246
+ const formattedDescription = getDescription() // allow newline
247
+ .replace(/\n/g, '&#10;');
248
+ return `|${[
249
+ name,
250
+ formattedDescription,
251
+ getType(),
252
+ getDefaultValue()
253
+ ].map((str)=>str.replace(/(?<!\\)\|/g, '&#124;')).join('|')}|`;
254
+ });
255
+ return `
256
+ ${param.displayName ? `### ${param.displayName}\n` : ''}
257
+ ${param.description ? `**${param.description}**\n` : ''}
268
258
  ${PROP_TABLE_HEADER}
269
- ${tableContent.join("\n")}
259
+ ${tableContent.join('\n')}
270
260
  `;
271
- }).join("\n");
261
+ }).join('\n');
272
262
  }
273
-
274
- // src/index.ts
275
- function pluginApiDocgen(options) {
276
- const {
277
- entries = {},
278
- apiParseTool = "react-docgen-typescript",
279
- appDir = process.cwd(),
280
- parseToolOptions = {}
281
- } = options || {};
282
- return {
283
- name: "@modern-js/doc-plugin-api-docgen",
284
- config(config) {
285
- config.markdown = config.markdown || {};
286
- config.markdown.mdxRs = false;
287
- return config;
288
- },
289
- async beforeBuild(config, isProd) {
290
- const languages = (config.themeConfig?.locales?.map((locale) => locale.lang) || config.locales?.map((locale) => locale.lang) || [config.lang]).filter((lang) => lang === "zh" || lang === "en");
291
- await docgen({
292
- entries,
293
- apiParseTool,
294
- languages,
295
- appDir,
296
- parseToolOptions,
297
- isProd
298
- });
299
- },
300
- async modifySearchIndexData(pages) {
301
- const apiCompRegExp = /(<API\s+moduleName=['"](\S+)['"]\s*(.*)?\/>)|(<API\s+moduleName=['"](\S+)['"]\s*(.*)?>(.*)?<\/API>)/;
302
- await Promise.all(
303
- pages.map(async (page) => {
304
- const { _filepath, lang } = page;
305
- let content = await import_node_fs2.default.promises.readFile(_filepath, "utf-8");
306
- let matchResult = new RegExp(apiCompRegExp).exec(content);
307
- if (!matchResult) {
308
- return;
309
- }
310
- while (matchResult !== null) {
311
- const [matchContent, moduleName] = matchResult;
312
- const apiDoc = apiDocMap[moduleName] || apiDocMap[`${moduleName}-${lang}`];
313
- content = content.replace(matchContent, apiDoc);
314
- matchResult = new RegExp(apiCompRegExp).exec(content);
315
- }
316
- page.content = content;
317
- })
318
- );
319
- },
320
- extendPageData(pageData) {
321
- pageData.apiDocMap = { ...apiDocMap };
322
- },
323
- markdown: {
324
- globalComponents: [
325
- import_node_path3.default.join(__dirname, "..", "static", "global-components", "API.tsx")
326
- ]
327
- }
328
- };
263
+ /**
264
+ * The plugin is used to generate api doc for files.
265
+ */ function pluginApiDocgen(options) {
266
+ const { entries = {}, apiParseTool = 'react-docgen-typescript', appDir = process.cwd(), parseToolOptions = {} } = options || {};
267
+ return {
268
+ name: '@modern-js/doc-plugin-api-docgen',
269
+ config (config) {
270
+ config.markdown = config.markdown || {};
271
+ config.markdown.mdxRs = false;
272
+ return config;
273
+ },
274
+ async beforeBuild (config, isProd) {
275
+ var _config_themeConfig_locales, _config_themeConfig, _config_locales;
276
+ // only support zh and en
277
+ const languages = ((null === (_config_themeConfig = config.themeConfig) || void 0 === _config_themeConfig ? void 0 : null === (_config_themeConfig_locales = _config_themeConfig.locales) || void 0 === _config_themeConfig_locales ? void 0 : _config_themeConfig_locales.map((locale)=>locale.lang)) || (null === (_config_locales = config.locales) || void 0 === _config_locales ? void 0 : _config_locales.map((locale)=>locale.lang)) || [
278
+ config.lang
279
+ ]).filter((lang)=>'zh' === lang || 'en' === lang);
280
+ await docgen({
281
+ entries,
282
+ apiParseTool,
283
+ languages,
284
+ appDir,
285
+ parseToolOptions,
286
+ isProd
287
+ });
288
+ },
289
+ async modifySearchIndexData (pages) {
290
+ // Update the search index of module doc which includes `<API moduleName="foo" />` and `<API moduleName="foo" ></API>
291
+ const apiCompRegExp = /(<API\s+moduleName=['"](\S+)['"]\s*(.*)?\/>)|(<API\s+moduleName=['"](\S+)['"]\s*(.*)?>(.*)?<\/API>)/;
292
+ await Promise.all(pages.map(async (page)=>{
293
+ const { _filepath, lang } = page;
294
+ let content = await external_node_fs_default().promises.readFile(_filepath, 'utf-8');
295
+ let matchResult = new RegExp(apiCompRegExp).exec(content);
296
+ if (!matchResult) return;
297
+ while(null !== matchResult){
298
+ const [matchContent, moduleName] = matchResult;
299
+ const apiDoc = apiDocMap[moduleName] || apiDocMap[`${moduleName}-${lang}`];
300
+ content = content.replace(matchContent, apiDoc);
301
+ matchResult = new RegExp(apiCompRegExp).exec(content);
302
+ }
303
+ page.content = content;
304
+ }));
305
+ },
306
+ extendPageData (pageData) {
307
+ pageData.apiDocMap = {
308
+ ...apiDocMap
309
+ };
310
+ },
311
+ markdown: {
312
+ globalComponents: [
313
+ external_node_path_default().join(__dirname, '..', 'static', 'global-components', 'API.tsx')
314
+ ]
315
+ }
316
+ };
329
317
  }
330
- // Annotate the CommonJS export names for ESM import in node:
331
- 0 && (module.exports = {
332
- pluginApiDocgen
318
+ var __webpack_export_target__ = exports;
319
+ for(var i in __webpack_exports__)__webpack_export_target__[i] = __webpack_exports__[i];
320
+ if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
321
+ value: true
333
322
  });
334
-
335
- //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rspress/plugin-api-docgen",
3
- "version": "1.37.2",
3
+ "version": "1.37.3",
4
4
  "description": "A plugin for rspress to generate api doc.",
5
5
  "bugs": "https://github.com/web-infra-dev/rspress/issues",
6
6
  "repository": {
@@ -21,9 +21,11 @@
21
21
  "react-docgen-typescript": "2.2.2",
22
22
  "react-markdown": "8.0.7",
23
23
  "remark-gfm": "3.0.1",
24
- "@rspress/shared": "1.37.2"
24
+ "@rspress/shared": "1.37.3"
25
25
  },
26
26
  "devDependencies": {
27
+ "@microsoft/api-extractor": "^7.48.0",
28
+ "@rslib/core": "0.1.0",
27
29
  "@types/mdast": "^4.0.4",
28
30
  "@types/node": "^18.11.17",
29
31
  "@types/react": "^18.3.12",
@@ -39,7 +41,7 @@
39
41
  "peerDependencies": {
40
42
  "react": ">=17.0.0",
41
43
  "react-router-dom": "^6.8.1",
42
- "@rspress/core": "^1.37.2",
44
+ "@rspress/core": "^1.37.3",
43
45
  "typescript": "^5.5.3"
44
46
  },
45
47
  "peerDependenciesMeta": {
@@ -58,8 +60,8 @@
58
60
  "registry": "https://registry.npmjs.org/"
59
61
  },
60
62
  "scripts": {
61
- "dev": "modern build -w",
62
- "build": "modern build",
63
+ "dev": "rslib build -w",
64
+ "build": "rslib build",
63
65
  "reset": "rimraf ./**/node_modules",
64
66
  "test": "vitest run --passWithNoTests"
65
67
  }
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"mappings":"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","names":["import_node_path","import_node_fs","path","chokidar","apiParseTool","fs"],"ignoreList":[],"sources":["../src/index.ts","../src/docgen.ts","../src/constants.ts","../src/locales.ts"],"sourcesContent":["import path from 'node:path';\nimport type { RspressPlugin } from '@rspress/shared';\nimport fs from 'node:fs';\nimport type {\n PluginOptions,\n SupportLanguages,\n ExtendedPageData,\n} from './types';\nimport { docgen } from './docgen';\nimport { apiDocMap } from './constants';\n\n/**\n * The plugin is used to generate api doc for files.\n */\nexport function pluginApiDocgen(options?: PluginOptions): RspressPlugin {\n const {\n entries = {},\n apiParseTool = 'react-docgen-typescript',\n appDir = process.cwd(),\n parseToolOptions = {},\n } = options || {};\n return {\n name: '@modern-js/doc-plugin-api-docgen',\n config(config) {\n config.markdown = config.markdown || {};\n config.markdown.mdxRs = false;\n return config;\n },\n async beforeBuild(config, isProd) {\n // only support zh and en\n const languages = (\n config.themeConfig?.locales?.map(locale => locale.lang) ||\n config.locales?.map(locale => locale.lang) || [config.lang]\n ).filter(lang => lang === 'zh' || lang === 'en') as SupportLanguages[];\n await docgen({\n entries,\n apiParseTool,\n languages,\n appDir,\n parseToolOptions,\n isProd,\n });\n },\n async modifySearchIndexData(pages) {\n // Update the search index of module doc which includes `<API moduleName=\"foo\" />` and `<API moduleName=\"foo\" ></API>\n const apiCompRegExp =\n /(<API\\s+moduleName=['\"](\\S+)['\"]\\s*(.*)?\\/>)|(<API\\s+moduleName=['\"](\\S+)['\"]\\s*(.*)?>(.*)?<\\/API>)/;\n await Promise.all(\n pages.map(async page => {\n const { _filepath, lang } = page;\n let content = await fs.promises.readFile(_filepath, 'utf-8');\n let matchResult = new RegExp(apiCompRegExp).exec(content);\n if (!matchResult) {\n return;\n }\n while (matchResult !== null) {\n const [matchContent, moduleName] = matchResult;\n const apiDoc =\n apiDocMap[moduleName] || apiDocMap[`${moduleName}-${lang}`];\n content = content.replace(matchContent, apiDoc);\n matchResult = new RegExp(apiCompRegExp).exec(content);\n }\n page.content = content;\n }),\n );\n },\n extendPageData(pageData) {\n (pageData as ExtendedPageData).apiDocMap = { ...apiDocMap };\n },\n markdown: {\n globalComponents: [\n path.join(__dirname, '..', 'static', 'global-components', 'API.tsx'),\n ],\n },\n };\n}\n\nexport type { PluginOptions };\n","import path from 'node:path';\nimport type { ComponentDoc, PropItem } from 'react-docgen-typescript';\nimport fs from 'node:fs';\nimport { logger } from '@rspress/shared/logger';\nimport chokidar from 'chokidar';\nimport {\n withDefaultConfig,\n withCustomConfig,\n withCompilerOptions,\n} from 'react-docgen-typescript';\nimport { RSPRESS_TEMP_DIR } from '@rspress/shared';\nimport { apiDocMap } from './constants';\nimport { locales } from './locales';\nimport type {\n DocGenOptions,\n Entries,\n ToolEntries,\n ApiParseTool,\n WatchFileInfo,\n} from './types';\n\nconst isToolEntries = (obj: Record<string, any>): obj is ToolEntries => {\n return obj.documentation || obj['react-docgen-typescript'];\n};\n\nexport const docgen = async ({\n entries,\n languages,\n apiParseTool,\n appDir,\n parseToolOptions,\n isProd,\n}: DocGenOptions) => {\n const watchFileMap: Record<string, WatchFileInfo> = {};\n const genApiDoc = async (entry: Entries, tool: ApiParseTool) => {\n if (Object.keys(entry).length === 0) {\n return;\n }\n await Promise.all(\n Object.entries(entry).map(async ([key, value]) => {\n const moduleSourceFilePath = path.resolve(appDir, value);\n watchFileMap[moduleSourceFilePath] = {\n apiParseTool,\n moduleName: key,\n };\n try {\n if (tool === 'documentation') {\n const documentation = await import('documentation');\n\n const documentationRes = await documentation.build(\n [moduleSourceFilePath],\n {\n ...parseToolOptions.documentation,\n },\n );\n const apiDoc = await documentation.formats.md(documentationRes, {\n noReferenceLinks:\n parseToolOptions.documentation?.noReferenceLinks ?? true,\n });\n apiDocMap[key] = apiDoc;\n } else {\n const { tsconfigPath, compilerOptions, ...restOptions } =\n parseToolOptions?.['react-docgen-typescript'] ?? {};\n const parserOpts = {\n // https://github.com/styleguidist/react-docgen-typescript/blob/master/README.md?plain=1#L111\n propFilter: (prop: PropItem) => {\n if (\n prop.declarations !== undefined &&\n prop.declarations.length > 0\n ) {\n const hasPropAdditionalDescription = prop.declarations.find(\n declaration => {\n return !declaration.fileName.includes('node_modules');\n },\n );\n\n return Boolean(hasPropAdditionalDescription);\n }\n\n return true;\n },\n ...restOptions,\n };\n let fileParser = withDefaultConfig(parserOpts);\n if (tsconfigPath?.[key]) {\n fileParser = withCustomConfig(tsconfigPath[key], parserOpts);\n } else if (compilerOptions?.[key]) {\n fileParser = withCompilerOptions(\n compilerOptions[key],\n parserOpts,\n );\n }\n const componentDoc = fileParser.parse(moduleSourceFilePath);\n if (componentDoc.length === 0) {\n logger.warn(\n '[module-doc-plugin]',\n `Unable to parse API document in ${moduleSourceFilePath}`,\n );\n }\n if (languages.length > 0) {\n languages.forEach(language => {\n apiDocMap[`${key}-${language}`] = generateTable(\n componentDoc,\n language,\n );\n });\n } else {\n apiDocMap[key] = generateTable(componentDoc, 'en');\n }\n }\n } catch (e) {\n if (e instanceof Error) {\n logger.error(\n '[module-doc-plugin]',\n `Generate API table error: ${e.message}`,\n );\n }\n }\n }),\n );\n };\n logger.info('[module-doc-plugin]', 'Start to generate API table...');\n\n if (isToolEntries(entries)) {\n const reactEntries = entries['react-docgen-typescript'];\n const documentationEntries = entries.documentation;\n await Promise.all([\n genApiDoc(reactEntries, 'react-docgen-typescript'),\n genApiDoc(documentationEntries, 'documentation'),\n ]);\n } else {\n await genApiDoc(entries, apiParseTool);\n }\n if (!isProd) {\n const watcher = chokidar.watch(Object.keys(watchFileMap), {\n ignoreInitial: true,\n ignorePermissionErrors: true,\n ignored: [/node_modules/],\n });\n let isUpdate = false;\n watcher.on('change', changed => {\n if (isUpdate) {\n return;\n }\n isUpdate = true;\n logger.info('[module-doc-plugin]', 'updating API');\n const watchFileInfo = watchFileMap[changed];\n if (watchFileInfo) {\n const { apiParseTool, moduleName } = watchFileInfo;\n\n const updateSiteData = () => {\n const siteDataPath = path.join(\n process.cwd(),\n 'node_modules',\n RSPRESS_TEMP_DIR,\n 'runtime',\n 'virtual-site-data.mjs',\n );\n import(siteDataPath).then(siteData => {\n const data = { ...siteData.default };\n data.pages.forEach((page: Record<string, unknown>) => {\n page.apiDocMap = apiDocMap;\n });\n fs.writeFileSync(\n siteDataPath,\n `export default ${JSON.stringify(data)}`,\n );\n isUpdate = false;\n });\n };\n genApiDoc({ [moduleName]: changed }, apiParseTool).then(updateSiteData);\n }\n });\n }\n\n logger.success('[module-doc-plugin]', 'Generate API table successfully!');\n};\n\nfunction generateTable(componentDoc: ComponentDoc[], language: 'zh' | 'en') {\n return componentDoc\n .map(param => {\n const { props } = param;\n const t = locales[language];\n const PROP_TABLE_HEADER = `|${t.property}|${t.description}|${t.type}|${t.defaultValue}|\\n|:---:|:---:|:---:|:---:|`;\n\n const tableContent = Object.keys(props)\n .filter(propName => {\n const { name, description } = props[propName];\n return (\n description ||\n ['className', 'style', 'disabled', 'children'].indexOf(name) > -1\n );\n })\n .map(propName => {\n const { defaultValue, description, name, required, type } =\n props[propName];\n const getType = () =>\n `\\`${type.name.replace(/\\|/g, '\\\\|')}\\`${\n required ? ` **(${t.required})**` : ''\n }`;\n const getDefaultValue = () => `\\`${defaultValue?.value || '-'}\\``;\n\n const getDescription = () => {\n switch (name) {\n case 'className':\n return description || t.className;\n case 'style':\n return description || t.style;\n case 'children':\n return description || t.children;\n case 'disabled':\n return description || t.disabled;\n default:\n return description;\n }\n };\n\n const formattedDescription = getDescription()\n // allow newline\n .replace(/\\n/g, '&#10;');\n\n return `|${[name, formattedDescription, getType(), getDefaultValue()]\n .map(str => str.replace(/(?<!\\\\)\\|/g, '&#124;'))\n .join('|')}|`;\n });\n\n return `\n ${param.displayName ? `### ${param.displayName}\\n` : ''}\n ${param.description ? `**${param.description}**\\n` : ''}\n ${PROP_TABLE_HEADER}\n ${tableContent.join('\\n')}\n `;\n })\n .join('\\n');\n}\n","import path from 'node:path';\n\nexport const PACKAGE_ROOT = path.join(__dirname, '..');\n\nexport const apiDocMap: Record<string, string> = {};\n","export const locales = {\n zh: {\n copy: '复制',\n copied: '复制成功',\n expand: '展开代码',\n collapse: '收起代码',\n className: '节点类名',\n style: '节点样式',\n children: '子节点',\n disabled: '是否禁用',\n required: '必填',\n property: '属性',\n description: '说明',\n type: '类型',\n defaultValue: '默认值',\n overview: '概览',\n },\n en: {\n copy: 'Copy',\n copied: 'Copied Success!',\n expand: 'Expand Code',\n collapse: 'Collapse Code',\n className: 'Additional css class',\n style: 'Additional style',\n children: 'Children',\n disabled: 'Whether to disable ',\n required: 'Required',\n property: 'Property',\n description: 'Description',\n type: 'Type',\n defaultValue: 'Default Value',\n overview: 'Overview',\n },\n};\n"]}