@moneko/core 3.2.1-beta.2 → 3.2.1-beta.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/lib/dev.js CHANGED
@@ -1,90 +1,6 @@
1
- import FriendlyErrorsWebpackPlugin from '@soda/friendly-errors-webpack-plugin';
2
- import chalk from 'chalk';
3
- import webpack from 'webpack';
4
- import { merge } from 'webpack-merge';
5
- import { clientConfig } from './common.js';
6
- import { CONFIG } from './config.js';
7
- import { hasPkg } from './has-pkg.js';
8
- import { getIPv4, getPort } from './net.js';
9
- import { isReact } from './process-env.js';
10
- import { isFunction, resolveProgramPath } from './utils.js';
11
- const { HotModuleReplacementPlugin } = webpack;
12
- const { yellow, green } = chalk;
13
- const ip = getIPv4();
14
- const oldPord = CONFIG.devServer.port || 3000;
15
- const port = await getPort(oldPord, 65535, CONFIG.devServer.host);
16
- const skipPort = CONFIG.devServer.port !== port;
17
- const hasMockMiddlewares = hasPkg('@moneko/mock');
18
- const mockMiddlewares = hasMockMiddlewares && (await import('@moneko/mock')).default;
19
- const ReactRefresh = isReact && (await import('@pmmmwh/react-refresh-webpack-plugin')).default;
20
- const devtool = CONFIG.devtool === false || CONFIG.devtool ? CONFIG.devtool : 'eval-cheap-module-source-map';
21
- CONFIG.devServer.port = port;
22
- const initRouteBase = CONFIG.basename === '/';
23
- const protocol = CONFIG.devServer.https ? 'https:' : 'http:';
24
- const routeBase = initRouteBase ? '' : CONFIG.basename;
25
- const client = merge(clientConfig, {
26
- devtool: devtool,
27
- mode: 'development',
28
- devServer: {
29
- headers: {
30
- 'Access-Control-Allow-Origin': '*'
31
- },
32
- compress: CONFIG.devServer.compress,
33
- host: '0.0.0.0',
34
- port: port,
35
- historyApiFallback: initRouteBase || {
36
- index: routeBase.endsWith('/') ? routeBase : `${routeBase}/`,
37
- disableDotRule: true
38
- },
39
- https: CONFIG.devServer.https,
40
- proxy: CONFIG.proxy,
41
- allowedHosts: CONFIG.devServer.allowedHosts,
42
- client: {
43
- // 在浏览器中以百分比显示编译进度。
44
- progress: false,
45
- logging: 'info',
46
- // 当出现编译错误或警告时,在浏览器中显示全屏覆盖。
47
- overlay: false
48
- },
49
- static: {
50
- watch: {
51
- ignored: (f)=>{
52
- // 生成的类型定义不要监听,否则会引发全局的 reload 使 HMR 失去意义
53
- return f.endsWith('.d.ts') || /\/node_modules\//.test(f);
54
- }
55
- }
56
- },
57
- setupMiddlewares: (middlewares, devServer)=>{
58
- if (!devServer) {
59
- throw new Error('webpack-dev-server is not defined');
60
- }
61
- if (devServer.app && isFunction(mockMiddlewares)) {
62
- mockMiddlewares(devServer.app, resolveProgramPath('mock/'));
63
- }
64
- return middlewares;
65
- },
66
- open: false,
67
- hot: true
68
- },
69
- plugins: [
70
- new HotModuleReplacementPlugin(),
71
- ReactRefresh && new ReactRefresh(),
72
- new FriendlyErrorsWebpackPlugin({
73
- compilationSuccessInfo: {
74
- messages: [
75
- `You application is running here:
1
+ import e from"@soda/friendly-errors-webpack-plugin";import o from"chalk";import r from"webpack";import{merge as t}from"webpack-merge";import{clientConfig as s}from"./common.js";import{CONFIG as p}from"./config.js";import{hasPkg as i}from"./has-pkg.js";import{getIPv4 as a,getPort as m}from"./net.js";import{isReact as n}from"./process-env.js";import{isFunction as l,resolveProgramPath as d}from"./utils.js";let{HotModuleReplacementPlugin:c}=r,{yellow:v,green:f}=o,h=a(),w=p.devServer.port||3e3,u=await m(w,65535,p.devServer.host),g=p.devServer.port!==u,k=i("@moneko/mock"),$=k&&(await import("@moneko/mock")).default,S=n&&(await import("@pmmmwh/react-refresh-webpack-plugin")).default,b=!1===p.devtool||p.devtool?p.devtool:"eval-cheap-module-source-map";p.devServer.port=u;let y="/"===p.basename,j=p.devServer.https?"https:":"http:",x=y?"":p.basename,A=t(s,{devtool:b,mode:"development",devServer:{headers:{"Access-Control-Allow-Origin":"*"},compress:p.devServer.compress,host:"0.0.0.0",port:u,historyApiFallback:y||{index:x.endsWith("/")?x:`${x}/`,disableDotRule:!0},https:p.devServer.https,proxy:p.proxy,allowedHosts:p.devServer.allowedHosts,client:{// 在浏览器中以百分比显示编译进度。
2
+ progress:!1,logging:"info",// 当出现编译错误或警告时,在浏览器中显示全屏覆盖。
3
+ overlay:!1},static:{watch:{ignored:e=>e.endsWith(".d.ts")||/\/node_modules\//.test(e)}},setupMiddlewares:(e,o)=>{if(!o)throw Error("webpack-dev-server is not defined");return o.app&&l($)&&$(o.app,d("mock/")),e},open:!1,hot:!0},plugins:[new c,S&&new S,new e({compilationSuccessInfo:{messages:[`You application is running here:
76
4
 
77
- Local: ${chalk.cyan(`${protocol}//${CONFIG.devServer.host}:${port}${routeBase}`)}
78
- Network: ${chalk.cyan(`${protocol}//${ip}:${port}${routeBase}`)}`
79
- ],
80
- notes: skipPort ? [
81
- `Port ${yellow(oldPord)} is in use, trying ${green(port)} instead`
82
- ] : []
83
- },
84
- clearConsole: true
85
- })
86
- ].filter(Boolean)
87
- });
88
- export default [
89
- client
90
- ];
5
+ Local: ${o.cyan(`${j}//${p.devServer.host}:${u}${x}`)}
6
+ Network: ${o.cyan(`${j}//${h}:${u}${x}`)}`],notes:g?[`Port ${v(w)} is in use, trying ${f(u)} instead`]:[]},clearConsole:!0})].filter(Boolean)});export default[A];
package/lib/docs.js CHANGED
@@ -1,120 +1,2 @@
1
- import { stat } from 'fs';
2
- import { dirname, join } from 'path';
3
- import { watch } from 'chokidar';
4
- import { CONFIG } from './config.js';
5
- import generateApi from './generate-api.js';
6
- import { FRAMEWORK, FRAMEWORKNAME, createElement, isLibrary, isReact, isSolid } from './process-env.js';
7
- import ReactiveObject from './reactive-object.js';
8
- import { resolveProgramPath } from './utils.js';
9
- const base = '@app/comment';
10
- const apiEntry = '@app/docs';
11
- export const docs = new ReactiveObject();
12
- const cacheEnvApi = {
13
- [base]: {}
14
- };
15
- let replaceStr = `() => ${createElement}(SuspenseComp, { comp: $1 })`;
16
- let prefixStr = `import { ${createElement}${isSolid ? ',Dynamic' : ''} } from "${FRAMEWORKNAME}${isSolid ? '/web' : ''}";import SuspenseComp from "@app/suspense";`;
17
- if (![
18
- 'react',
19
- 'solid'
20
- ].includes(FRAMEWORK)) {
21
- replaceStr = '$1';
22
- prefixStr = '';
23
- }
24
- // 要执行的函数
25
- function handleFileChange(filePath, changeType) {
26
- const fil = filePath.replace(new RegExp(`^${CONFIG.alias['@pkg']}`), '');
27
- const __dir = dirname(fil).replace(/^\//, '');
28
- const apiDir = [
29
- base,
30
- __dir
31
- ].join('/');
32
- const name = fil.split('/').pop()?.replace(/\.tsx?/, '.md');
33
- if (!name) return;
34
- if (!cacheEnvApi[base][__dir]) {
35
- cacheEnvApi[base][__dir] = {};
36
- }
37
- const target = join(apiDir, name);
38
- function update() {
39
- const basestr = {};
40
- for(const k in cacheEnvApi){
41
- if (Object.prototype.hasOwnProperty.call(cacheEnvApi, k)) {
42
- const item = cacheEnvApi[k];
43
- if (k === base) {
44
- for(const kb in item){
45
- if (Object.prototype.hasOwnProperty.call(item, kb)) {
46
- basestr[kb] = Object.values(item[kb]);
47
- }
48
- }
49
- } else {
50
- docs.setData(k, item);
51
- }
52
- }
53
- }
54
- docs.setData(apiEntry, `${prefixStr}export default ${JSON.stringify(basestr).replace(/"rr\((.+?)\)rr"/g, replaceStr)}`);
55
- }
56
- if (changeType === 'deleted') {
57
- if (cacheEnvApi[base][__dir][name]) {
58
- delete cacheEnvApi[base][__dir][name];
59
- }
60
- update();
61
- } else {
62
- generateApi(filePath, (api)=>{
63
- cacheEnvApi[target] = api;
64
- if (api) {
65
- cacheEnvApi[base][__dir][name] = `rr(() => import(/* webpackChunkName: '${target}' */'${target}?raw').then((res) => ({default: ${isReact ? '() =>' : ''}${createElement}(${isSolid ? 'Dynamic' : "'n-md'"}, {text: res.default, ${isSolid ? "component: 'n-md', " : ''}css: 'table td a {display:inline-flex;align-items:center;gap:2px;}table td a n-img{display:inline-block;overflow:hidden;border-radius:var(--border-radius);inline-size:18px;block-size:18px;}'})})))rr`;
66
- } else if (cacheEnvApi[base][__dir][name]) {
67
- delete cacheEnvApi[base][__dir][name];
68
- }
69
- update();
70
- });
71
- }
72
- }
73
- function watchDirectory() {
74
- const files = [];
75
- const watcher = watch(resolveProgramPath('components'), {
76
- ignored: [
77
- /(^|\/)\../,
78
- /(^|\/)__tests__(\/|$)/
79
- ],
80
- persistent: true,
81
- ignoreInitial: false
82
- });
83
- function isTs(path, stats) {
84
- return /\.tsx?$/.test(path) && stats.isFile();
85
- }
86
- watcher.on('add', (path)=>{
87
- stat(path, (err, stats)=>{
88
- if (!err && isTs(path, stats)) {
89
- handleFileChange(path, 'added');
90
- files.push(path);
91
- }
92
- });
93
- });
94
- watcher.on('change', (path)=>{
95
- stat(path, (err, stats)=>{
96
- if (!err && isTs(path, stats)) {
97
- handleFileChange(path, 'change');
98
- }
99
- });
100
- });
101
- watcher.on('unlink', (path)=>{
102
- stat(path, (err, stats)=>{
103
- if (!err && isTs(path, stats)) {
104
- handleFileChange(path, 'deleted');
105
- files.splice(files.indexOf(path), 1);
106
- }
107
- });
108
- });
109
- watcher.on('ready', ()=>{
110
- files.forEach((f)=>{
111
- handleFileChange(f, 'change');
112
- });
113
- });
114
- process.on('SIGINT', function() {
115
- watcher.close();
116
- });
117
- }
118
- if (isLibrary) {
119
- watchDirectory();
120
- }
1
+ import{stat as e}from"fs";import{dirname as t,join as o}from"path";import{watch as r}from"chokidar";import{CONFIG as n}from"./config.js";import i from"./generate-api.js";import{FRAMEWORK as s,FRAMEWORKNAME as p,createElement as a,isLibrary as l,isReact as c,isSolid as d}from"./process-env.js";import m from"./reactive-object.js";import{resolveProgramPath as f}from"./utils.js";let u="@app/comment";export const docs=new m;let $={[u]:{}},g=`() => ${a}(SuspenseComp, { comp: $1 })`,b=`import { ${a}${d?",Dynamic":""} } from "${p}${d?"/web":""}";import SuspenseComp from "@app/suspense";`;// 要执行的函数
2
+ function h(e,r){let s=e.replace(RegExp(`^${n.alias["@pkg"]}`),""),p=t(s).replace(/^\//,""),l=[u,p].join("/"),m=s.split("/").pop()?.replace(/\.tsx?/,".md");if(!m)return;$[u][p]||($[u][p]={});let f=o(l,m);function h(){let e={};for(let t in $)if(Object.prototype.hasOwnProperty.call($,t)){let o=$[t];if(t===u)for(let t in o)Object.prototype.hasOwnProperty.call(o,t)&&(e[t]=Object.values(o[t]));else docs.setData(t,o)}docs.setData("@app/docs",`${b}export default ${JSON.stringify(e).replace(/"rr\((.+?)\)rr"/g,g)}`)}"deleted"===r?($[u][p][m]&&delete $[u][p][m],h()):i(e,e=>{$[f]=e,e?$[u][p][m]=`rr(() => import(/* webpackChunkName: '${f}' */'${f}?raw').then((res) => ({default: ${c?"() =>":""}${a}(${d?"Dynamic":"'n-md'"}, {text: res.default, ${d?"component: 'n-md', ":""}css: 'table td a {display:inline-flex;align-items:center;gap:2px;}table td a n-img{display:inline-block;overflow:hidden;border-radius:var(--border-radius);inline-size:18px;block-size:18px;}'})})))rr`:$[u][p][m]&&delete $[u][p][m],h()})}["react","solid"].includes(s)||(g="$1",b=""),l&&function(){let t=[],o=r(f("components"),{ignored:[/(^|\/)\../,/(^|\/)__tests__(\/|$)/],persistent:!0,ignoreInitial:!1});function n(e,t){return/\.tsx?$/.test(e)&&t.isFile()}o.on("add",o=>{e(o,(e,r)=>{!e&&n(o,r)&&(h(o,"added"),t.push(o))})}),o.on("change",t=>{e(t,(e,o)=>{!e&&n(t,o)&&h(t,"change")})}),o.on("unlink",o=>{e(o,(e,r)=>{!e&&n(o,r)&&(h(o,"deleted"),t.splice(t.indexOf(o),1))})}),o.on("ready",()=>{t.forEach(e=>{h(e,"change")})}),process.on("SIGINT",function(){o.close()})}();
package/lib/done.js CHANGED
@@ -1,12 +1 @@
1
- class DoneWebpackPlugin {
2
- options;
3
- constructor(options){
4
- this.options = Object.assign({}, options);
5
- }
6
- apply(compiler) {
7
- compiler.hooks.done.tap('DoneWebpackPlugin', ()=>{
8
- this.options.done?.();
9
- });
10
- }
11
- }
12
- export default DoneWebpackPlugin;
1
+ export default class{constructor(o){this.options=Object.assign({},o)}apply(o){o.hooks.done.tap("DoneWebpackPlugin",()=>{this.options.done?.()})}}
package/lib/esm.js CHANGED
@@ -1,7 +1 @@
1
- export default function esm(templateStrings, ...substitutions) {
2
- let js = templateStrings.raw[0];
3
- for(let i = 0; i < substitutions.length; i++){
4
- js += substitutions[i] + templateStrings.raw[i + 1];
5
- }
6
- return `data:text/javascript;base64,${Buffer.from(js).toString('base64')}`;
7
- }
1
+ export default function t(t,...e){let r=t.raw[0];for(let a=0;a<e.length;a++)r+=e[a]+t.raw[a+1];return`data:text/javascript;base64,${Buffer.from(r).toString("base64")}`}
package/lib/fallback.js CHANGED
@@ -1,6 +1 @@
1
- import { CONFIG } from './config.js';
2
- let fallback = 'export default null';
3
- if (CONFIG.fallbackCompPath) {
4
- fallback = `import Fallback from "${CONFIG.fallbackCompPath}";export default Fallback;`;
5
- }
6
- export default fallback;
1
+ import{CONFIG as l}from"./config.js";let a="export default null";l.fallbackCompPath&&(a=`import Fallback from "${l.fallbackCompPath}";export default Fallback;`);export default a;
@@ -1,345 +1,3 @@
1
- import { readFile } from 'fs';
2
- import { dirname } from 'path';
3
- import ts from 'typescript';
4
- import { CONFIG } from './config.js';
5
- const { ScriptKind, ScriptTarget, SyntaxKind, createSourceFile, forEachChild, getLeadingCommentRanges, isInterfaceDeclaration, isQuestionToken, isPropertySignature, isFunctionTypeNode, isUnionTypeNode, isMethodSignature } = ts;
6
- const allType = {};
7
- function getPropertyComment(propertyNode) {
8
- const comments = getLeadingCommentRanges(propertyNode.getSourceFile().text, propertyNode.pos);
9
- if (comments) {
10
- const commentText = propertyNode.getSourceFile().text.substring(comments[0].pos, comments[0].end);
11
- const match = commentText.match(/\/\*\*([\s\S]*?)\*\//);
12
- if (match) {
13
- return match[1].replace(/^\s*\* ?/gm, '').replace(/\s+$/, '').trim();
14
- }
15
- }
16
- return null;
17
- }
18
- function getDefaultValueFromComment(commentText) {
19
- if (!commentText) return null;
20
- const defaultValueRegex = /@default\s+([^\n]+)/;
21
- const defaultValueMatch = commentText.match(defaultValueRegex);
22
- return defaultValueMatch ? defaultValueMatch[1].trim() : null;
23
- }
24
- function getVersionFromComment(commentText) {
25
- if (!commentText) return null;
26
- const versionRegex = /@since\s+([^\n]+)/;
27
- const versionMatch = commentText.match(versionRegex);
28
- return versionMatch ? versionMatch[1].trim() : null;
29
- }
30
- function getAuthor(commentText) {
31
- if (!commentText) return null;
32
- const regex = /@author (\w+)\s*(?:<([^>]+)>)?/;
33
- const match = commentText.match(regex);
34
- if (match?.length) {
35
- const author = match[1].trim();
36
- let url = match[2]?.trim();
37
- const isEmail = /^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(url);
38
- if (!url) {
39
- url = `https://github.com/${author}`;
40
- } else if (isEmail) {
41
- url = `mailto:${url}`;
42
- }
43
- return `[![${author}](https://avatars.githubusercontent.com/${author}?s=64)${author}](${url})`;
44
- }
45
- return null;
46
- }
47
- function getIgnore(commentText) {
48
- if (!commentText) return null;
49
- const versionRegex = /@ignore\s+([^\n]+)/;
50
- const versionMatch = commentText.match(versionRegex);
51
- return versionMatch ? versionMatch[1].trim() : null;
52
- }
53
- const regex = /(?<!['"])(unknown|any|void|bigint|object|undefined|null|boolean|number|string|symbol)(?!['"])/g;
54
- function getTypeText(typeText, hasColor) {
55
- if (!typeText) return null;
56
- let modifiedTypeText = typeText.replace(/\b([A-Z][a-zA-Z0-9]*)\b/g, (item)=>{
57
- if (allType[item]) {
58
- const url = `/${[
59
- CONFIG.basename,
60
- allType[item]
61
- ].join('/').split('/').filter(Boolean).join('/')}`;
62
- return hasColor ? `[\\color{#009688}{${item}}](${url})` : `[${item}](${url})`;
63
- }
64
- return hasColor ? `\\color{#009688}{${item}}` : item;
65
- });
66
- if (hasColor) {
67
- modifiedTypeText = modifiedTypeText.replace(regex, (match)=>{
68
- return `\\color{#009688}{${match}}`;
69
- });
70
- }
71
- return modifiedTypeText;
72
- }
73
- function getMemberValue(memberNode) {
74
- const initializer = memberNode.initializer;
75
- if (initializer && ts.isStringLiteral(initializer)) {
76
- return ` '${initializer.text}'`;
77
- }
78
- return null;
79
- }
80
- function replacePairedSymbols(inputString) {
81
- if (!inputString) return null;
82
- const coloredContent = [];
83
- let matches;
84
- while(matches = /\\color{([^|}]*)\|?([^|}]*)\|?([^|}]*)\|?([^}]*)}{([^}]*)}/g.exec(inputString)){
85
- coloredContent.push(matches[0]);
86
- }
87
- return inputString.replace(/[{}[\]()=>]|keyof|typeof|true|false/g, (match)=>{
88
- if (coloredContent.some((content)=>content.includes(match))) {
89
- return match;
90
- }
91
- return `\\color{#569cd6}{${match}}`;
92
- });
93
- }
94
- function isFunctionTypeProperty(member) {
95
- if (member.type) {
96
- if (isUnionTypeNode(member.type)) {
97
- for (const typeNode of member.type.types){
98
- if (isFunctionTypeNode(typeNode)) {
99
- return true;
100
- }
101
- }
102
- } else {
103
- return isFunctionTypeNode(member.type);
104
- }
105
- }
106
- return false;
107
- }
108
- function replaceText(str) {
109
- return replacePairedSymbols(str)?.replace(/^\s*\|\s*|\s*\|\s*$/gm, '').replace(/\n/g, '<br/>').replace(/\*/g, '\\*').replace(/\|/g, '\\|').replace(/(['"])((?:(?!\1).)*)\1/g, '\\color{#ce9178}{$1$2$1}');
110
- }
111
- function getBaseInterfaces(interfaceNode) {
112
- const baseInterfaces = [];
113
- if (interfaceNode.heritageClauses) {
114
- for (const clause of interfaceNode.heritageClauses){
115
- if (clause.token === ts.SyntaxKind.ExtendsKeyword) {
116
- for (const typeNode of clause.types){
117
- baseInterfaces.push(typeNode.getText());
118
- }
119
- }
120
- }
121
- }
122
- return baseInterfaces;
123
- }
124
- function getComment(comment) {
125
- if (!comment) return null;
126
- return comment.replace(/^@[a-z].+/gm, '').replace(/(\n\s+)+/g, '<br />').replace(/\n/g, '<br />').replace(/(<br \/>)$/g, '');
127
- }
128
- function getMethodText(member) {
129
- if (isMethodSignature(member)) {
130
- return `(${member.parameters.map((param)=>`${param.name.getText()}: ${param.type?.getText() || 'any'}`).join(', ')}): ${member.type?.getText() || 'any'}`;
131
- }
132
- return member.type?.getText() || 'any';
133
- }
134
- function generateInterfaceDocumentation(node) {
135
- const typeName = node.name.text;
136
- Object.assign(allType, {
137
- [node.name.text]: dirname(node.getSourceFile().fileName).replace(CONFIG.alias['@pkg'], '')
138
- });
139
- const baseComment = getPropertyComment(node);
140
- const vers = getVersionFromComment(baseComment);
141
- const title = getComment(baseComment);
142
- const ignore = getIgnore(baseComment)?.split('|') || [];
143
- const ignoreComment = ignore.includes('comment');
144
- const ignoreInitial = ignore.includes('initial');
145
- const ignoreOptional = ignore.includes('optional');
146
- const ignoreVersion = ignore.includes('version');
147
- const ignoreAuthor = ignore.includes('author');
148
- const subTitle = title ? `\\color{|4||0.45}{${typeName}}` : typeName;
149
- const baseInterfaces = getBaseInterfaces(node)?.map((s)=>{
150
- return `<n-tag color="#4c81db" css=".tag{gap:0px;}">${getTypeText(replaceText(s))}</n-tag>`;
151
- });
152
- const heading = [
153
- title,
154
- subTitle,
155
- vers && `\\color{#52c11b|1||0.9}{${vers}}`,
156
- baseInterfaces.length > 0 && `<sub>\`extends\`</sub> ${baseInterfaces.join(' ')}`
157
- ].filter(Boolean).join(' ');
158
- let markdownContent = `## ${heading}`;
159
- const members = node.members.filter(// 排除 never
160
- (m)=>isPropertySignature(m) && m.type?.kind !== SyntaxKind.NeverKeyword || isMethodSignature(m));
161
- const rowsData = [];
162
- if (members.length) {
163
- members.forEach((member)=>{
164
- const type = getTypeText(replaceText(getMethodText(member)), true);
165
- const propertyComment = getPropertyComment(member);
166
- let name = replaceText(member.name.getText());
167
- if (name && !name.startsWith('\\color')) {
168
- if (isMethodSignature(member) || isFunctionTypeProperty(member) || type?.includes('=>')) {
169
- name = `\\color{#f9a913}{${name}}`;
170
- } else if (!/^["'](.+)["']$/.test(name)) {
171
- name = `\\color{#4c81db}{${name}}`;
172
- }
173
- }
174
- const isOptional = member.questionToken && isQuestionToken(member.questionToken);
175
- rowsData.push([
176
- name,
177
- !ignoreOptional && `\\color{${isOptional ? '#f9a913' : '#52c11b'}\\|\\|\\|0.9}{${isOptional ? '✘' : '✔'}}`,
178
- !ignoreComment && replaceText(getComment(propertyComment)),
179
- type,
180
- !ignoreInitial && replaceText(getDefaultValueFromComment(propertyComment)),
181
- !ignoreVersion && replaceText(getVersionFromComment(propertyComment)),
182
- !ignoreAuthor && (getAuthor(propertyComment) || getAuthor(baseComment))
183
- ]);
184
- });
185
- let hasAuthor = false, hasVersion = false, hasInitial = false, hasComment = false;
186
- rowsData.forEach((row)=>{
187
- if (!ignoreComment && row[2]) {
188
- hasComment = true;
189
- }
190
- if (!ignoreInitial && row[4]) {
191
- hasInitial = true;
192
- }
193
- if (!ignoreVersion && row[5]) {
194
- hasVersion = true;
195
- }
196
- if (!ignoreAuthor && row[6]) {
197
- hasAuthor = true;
198
- }
199
- });
200
- markdownContent += '\n';
201
- const cols = [
202
- '属性',
203
- !ignoreOptional && '必要',
204
- hasComment && '说明',
205
- '类型',
206
- hasInitial && '默认值',
207
- hasVersion && '版本',
208
- hasAuthor && '作者'
209
- ].filter(Boolean).join('|');
210
- markdownContent += `|${cols}|`;
211
- const algins = [
212
- ':-',
213
- !ignoreOptional && ':-',
214
- hasComment && ':-',
215
- ':-',
216
- hasInitial && ':-',
217
- hasVersion && ':-',
218
- hasAuthor && ':-'
219
- ].filter(Boolean);
220
- markdownContent += '\n';
221
- const alignStr = algins.join('|');
222
- markdownContent += `|${alignStr}|`;
223
- rowsData.forEach((row)=>{
224
- markdownContent += '\n';
225
- const rowStr = [
226
- row[0] || '-',
227
- !ignoreOptional && (row[1] || '-'),
228
- hasComment && (row[2] || '-'),
229
- row[3] || '-',
230
- hasInitial && (row[4] || '-'),
231
- hasVersion && (row[5] || '-'),
232
- hasAuthor && (row[6] || '-')
233
- ].filter(Boolean).join('|');
234
- markdownContent += `|${rowStr}|`;
235
- });
236
- markdownContent += '\n';
237
- }
238
- markdownContent += '\n';
239
- return markdownContent;
240
- }
241
- function generateEnumDocumentation(node) {
242
- const enumName = node.name.text;
243
- const baseComment = getPropertyComment(node);
244
- const title = getComment(baseComment);
245
- const vers = getVersionFromComment(baseComment);
246
- Object.assign(allType, {
247
- [node.name.text]: dirname(node.getSourceFile().fileName).replace(CONFIG.alias['@pkg'], '')
248
- });
249
- const subTitle = title ? `\\color{|4||0.45}{${enumName}}` : enumName;
250
- const heading = [
251
- title,
252
- subTitle,
253
- vers && `\\color{#52c11b|1||0.9}{${vers}}`
254
- ].filter(Boolean).join(' ');
255
- const ignore = getIgnore(baseComment)?.split('|') || [];
256
- const ignoreComment = ignore.includes('comment');
257
- const ignoreVersion = ignore.includes('version');
258
- const ignoreAuthor = ignore.includes('author');
259
- let markdownContent = `## ${heading}`;
260
- if (node.members.length) {
261
- const rowsData = [];
262
- node.members.forEach((member)=>{
263
- let name = replaceText(member.name.getText());
264
- const memberComment = getPropertyComment(member);
265
- const value = replaceText(getMemberValue(member));
266
- const version = replaceText(getVersionFromComment(memberComment));
267
- const comment = replaceText(getComment(memberComment));
268
- // markdownContent += '\n';
269
- if (name && !name.startsWith('\\color') && !/^["'](.+)["']$/.test(name)) {
270
- name = `\\color{#4c81db}{${name}}`;
271
- }
272
- rowsData.push([
273
- name,
274
- !ignoreComment && comment,
275
- value,
276
- !ignoreVersion && version,
277
- !ignoreAuthor && (getAuthor(memberComment) || getAuthor(baseComment))
278
- ]);
279
- // markdownContent += `| ${name} | ${comment} | ${value} | ${version} |`;
280
- });
281
- let hasAuthor = false, hasVersion = false, hasComment = false;
282
- rowsData.forEach((row)=>{
283
- if (!ignoreComment && row[1]) {
284
- hasComment = true;
285
- }
286
- if (!ignoreVersion && row[3]) {
287
- hasVersion = true;
288
- }
289
- if (!ignoreAuthor && row[4]) {
290
- hasAuthor = true;
291
- }
292
- });
293
- markdownContent += '\n';
294
- const cols = [
295
- '属性',
296
- hasComment && '说明',
297
- '值',
298
- hasVersion && '版本',
299
- hasAuthor && '作者'
300
- ].filter(Boolean).join('|');
301
- markdownContent += `|${cols}|`;
302
- const algins = [
303
- ':-',
304
- hasComment && ':-',
305
- ':-',
306
- hasVersion && ':-',
307
- hasAuthor && ':-'
308
- ].filter(Boolean);
309
- markdownContent += '\n';
310
- const alignStr = algins.join('|');
311
- markdownContent += `|${alignStr}|`;
312
- rowsData.forEach((row)=>{
313
- markdownContent += '\n';
314
- const rowStr = [
315
- row[0] || '-',
316
- hasComment && (row[1] || '-'),
317
- row[2] || '-',
318
- hasVersion && (row[3] || '-'),
319
- hasAuthor && (row[4] || '-')
320
- ].filter(Boolean).join('|');
321
- markdownContent += `|${rowStr}|`;
322
- });
323
- }
324
- markdownContent += '\n';
325
- markdownContent += '\n';
326
- return markdownContent;
327
- }
328
- export default function generateApi(path, call) {
329
- readFile(path, {
330
- encoding: 'utf-8'
331
- }, (err, content)=>{
332
- if (!err) {
333
- const sourceFile = createSourceFile(path, content, ScriptTarget.Latest, true, ScriptKind.TS);
334
- let markdownDocumentation = '';
335
- forEachChild(sourceFile, (node)=>{
336
- if (isInterfaceDeclaration(node)) {
337
- markdownDocumentation += generateInterfaceDocumentation(node);
338
- } else if (ts.isEnumDeclaration(node)) {
339
- markdownDocumentation += generateEnumDocumentation(node);
340
- }
341
- });
342
- call(markdownDocumentation);
343
- }
344
- });
345
- }
1
+ import{readFile as e}from"fs";import{dirname as t}from"path";import n from"typescript";import{CONFIG as r}from"./config.js";let{ScriptKind:l,ScriptTarget:o,SyntaxKind:i,createSourceFile:c,forEachChild:a,getLeadingCommentRanges:u,isInterfaceDeclaration:s,isQuestionToken:f,isPropertySignature:p,isFunctionTypeNode:m,isUnionTypeNode:g,isMethodSignature:$}=n,h={};function b(e){let t=u(e.getSourceFile().text,e.pos);if(t){let n=e.getSourceFile().text.substring(t[0].pos,t[0].end),r=n.match(/\/\*\*([\s\S]*?)\*\//);if(r)return r[1].replace(/^\s*\* ?/gm,"").replace(/\s+$/,"").trim()}return null}function d(e){if(!e)return null;let t=e.match(/@since\s+([^\n]+)/);return t?t[1].trim():null}function y(e){if(!e)return null;let t=e.match(/@author (\w+)\s*(?:<([^>]+)>)?/);if(t?.length){let e=t[1].trim(),n=t[2]?.trim(),r=/^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$/.test(n);return n?r&&(n=`mailto:${n}`):n=`https://github.com/${e}`,`[![${e}](https://avatars.githubusercontent.com/${e}?s=64)${e}](${n})`}return null}function x(e){if(!e)return null;let t=e.match(/@ignore\s+([^\n]+)/);return t?t[1].trim():null}let j=/(?<!['"])(unknown|any|void|bigint|object|undefined|null|boolean|number|string|symbol)(?!['"])/g;function T(e,t){if(!e)return null;let n=e.replace(/\b([A-Z][a-zA-Z0-9]*)\b/g,e=>{if(h[e]){let n=`/${[r.basename,h[e]].join("/").split("/").filter(Boolean).join("/")}`;return t?`[\\color{#009688}{${e}}](${n})`:`[${e}](${n})`}return t?`\\color{#009688}{${e}}`:e});return t&&(n=n.replace(j,e=>`\\color{#009688}{${e}}`)),n}function B(e){return(function(e){let t;if(!e)return null;let n=[];for(;t=/\\color{([^|}]*)\|?([^|}]*)\|?([^|}]*)\|?([^}]*)}{([^}]*)}/g.exec(e);)n.push(t[0]);return e.replace(/[{}[\]()=>]|keyof|typeof|true|false/g,e=>n.some(t=>t.includes(e))?e:`\\color{#569cd6}{${e}}`)})(e)?.replace(/^\s*\|\s*|\s*\|\s*$/gm,"").replace(/\n/g,"<br/>").replace(/\*/g,"\\*").replace(/\|/g,"\\|").replace(/(['"])((?:(?!\1).)*)\1/g,"\\color{#ce9178}{$1$2$1}")}function k(e){return e?e.replace(/^@[a-z].+/gm,"").replace(/(\n\s+)+/g,"<br />").replace(/\n/g,"<br />").replace(/(<br \/>)$/g,""):null}export default function w(u,j){e(u,{encoding:"utf-8"},(e,w)=>{if(!e){let e=c(u,w,o.Latest,!0,l.TS),E="";a(e,e=>{s(e)?E+=function(e){let l=e.name.text;Object.assign(h,{[e.name.text]:t(e.getSourceFile().fileName).replace(r.alias["@pkg"],"")});let o=b(e),c=d(o),a=k(o),u=x(o)?.split("|")||[],s=u.includes("comment"),j=u.includes("initial"),w=u.includes("optional"),E=u.includes("version"),S=u.includes("author"),v=a?`\\color{|4||0.45}{${l}}`:l,F=(function(e){let t=[];if(e.heritageClauses){for(let r of e.heritageClauses)if(r.token===n.SyntaxKind.ExtendsKeyword)for(let e of r.types)t.push(e.getText())}return t})(e)?.map(e=>`<n-tag color="#4c81db" css=".tag{gap:0px;}">${T(B(e))}</n-tag>`),z=[a,v,c&&`\\color{#52c11b|1||0.9}{${c}}`,F.length>0&&`<sub>\`extends\`</sub> ${F.join(" ")}`].filter(Boolean).join(" "),K=`## ${z}`,N=e.members.filter(// 排除 never
2
+ e=>p(e)&&e.type?.kind!==i.NeverKeyword||$(e)),q=[];if(N.length){N.forEach(e=>{let t=T(B($(e)?`(${e.parameters.map(e=>`${e.name.getText()}: ${e.type?.getText()||"any"}`).join(", ")}): ${e.type?.getText()||"any"}`:e.type?.getText()||"any"),!0),n=b(e),r=B(e.name.getText());!r||r.startsWith("\\color")||($(e)||function(e){if(e.type){if(!g(e.type))return m(e.type);for(let t of e.type.types)if(m(t))return!0}return!1}(e)||t?.includes("=>")?r=`\\color{#f9a913}{${r}}`:/^["'](.+)["']$/.test(r)||(r=`\\color{#4c81db}{${r}}`));let l=e.questionToken&&f(e.questionToken);q.push([r,!w&&`\\color{${l?"#f9a913":"#52c11b"}\\|\\|\\|0.9}{${l?"✘":"✔"}}`,!s&&B(k(n)),t,!j&&B(function(e){if(!e)return null;let t=e.match(/@default\s+([^\n]+)/);return t?t[1].trim():null}(n)),!E&&B(d(n)),!S&&(y(n)||y(o))])});let e=!1,t=!1,n=!1,r=!1;q.forEach(l=>{!s&&l[2]&&(r=!0),!j&&l[4]&&(n=!0),!E&&l[5]&&(t=!0),!S&&l[6]&&(e=!0)}),K+="\n";let l=["属性",!w&&"必要",r&&"说明","类型",n&&"默认值",t&&"版本",e&&"作者"].filter(Boolean).join("|");K+=`|${l}|`;let i=[":-",!w&&":-",r&&":-",":-",n&&":-",t&&":-",e&&":-"].filter(Boolean);K+="\n";let c=i.join("|");K+=`|${c}|`,q.forEach(l=>{K+="\n";let o=[l[0]||"-",!w&&(l[1]||"-"),r&&(l[2]||"-"),l[3]||"-",n&&(l[4]||"-"),t&&(l[5]||"-"),e&&(l[6]||"-")].filter(Boolean).join("|");K+=`|${o}|`}),K+="\n"}return K+="\n"}(e):n.isEnumDeclaration(e)&&(E+=function(e){let l=e.name.text,o=b(e),i=k(o),c=d(o);Object.assign(h,{[e.name.text]:t(e.getSourceFile().fileName).replace(r.alias["@pkg"],"")});let a=i?`\\color{|4||0.45}{${l}}`:l,u=[i,a,c&&`\\color{#52c11b|1||0.9}{${c}}`].filter(Boolean).join(" "),s=x(o)?.split("|")||[],f=s.includes("comment"),p=s.includes("version"),m=s.includes("author"),g=`## ${u}`;if(e.members.length){let t=[];e.members.forEach(e=>{let r=B(e.name.getText()),l=b(e),i=B(function(e){let t=e.initializer;return t&&n.isStringLiteral(t)?` '${t.text}'`:null}(e)),c=B(d(l)),a=B(k(l));!r||r.startsWith("\\color")||/^["'](.+)["']$/.test(r)||(r=`\\color{#4c81db}{${r}}`),t.push([r,!f&&a,i,!p&&c,!m&&(y(l)||y(o))]);// markdownContent += `| ${name} | ${comment} | ${value} | ${version} |`;
3
+ });let r=!1,l=!1,i=!1;t.forEach(e=>{!f&&e[1]&&(i=!0),!p&&e[3]&&(l=!0),!m&&e[4]&&(r=!0)}),g+="\n";let c=["属性",i&&"说明","值",l&&"版本",r&&"作者"].filter(Boolean).join("|");g+=`|${c}|`;let a=[":-",i&&":-",":-",l&&":-",r&&":-"].filter(Boolean);g+="\n";let u=a.join("|");g+=`|${u}|`,t.forEach(e=>{g+="\n";let t=[e[0]||"-",i&&(e[1]||"-"),e[2]||"-",l&&(e[3]||"-"),r&&(e[4]||"-")].filter(Boolean).join("|");g+=`|${t}|`})}return g+="\n\n"}(e))}),j(E)}})}
package/lib/has-pkg.js CHANGED
@@ -1,12 +1 @@
1
- import { accessSync, constants } from 'fs';
2
- import paths from './paths.js';
3
- export function hasPkg(name) {
4
- let flag;
5
- try {
6
- accessSync(`${paths.programPath}/node_modules/${name}/package.json`, constants.R_OK);
7
- flag = true;
8
- } catch (error) {
9
- flag = false;
10
- }
11
- return flag;
12
- }
1
+ import{accessSync as o,constants as r}from"fs";import t from"./paths.js";export function hasPkg(a){let e;try{o(`${t.programPath}/node_modules/${a}/package.json`,r.R_OK),e=!0}catch(o){e=!1}return e}