create-lumfall 1.0.0 → 1.1.1
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/README.md +24 -17
- package/cli.js +179 -24
- package/package.json +5 -7
- package/templates/basic/README.md +0 -113
- package/templates/basic/app/controller/demo.js +0 -28
- package/templates/basic/app/extend/README.md +0 -3
- package/templates/basic/app/middleware/README.md +0 -2
- package/templates/basic/app/middleware.js +0 -13
- package/templates/basic/app/pages/home/entry.home.js +0 -4
- package/templates/basic/app/pages/home/home.vue +0 -164
- package/templates/basic/app/router/demo.js +0 -17
- package/templates/basic/app/router-schema/demo.js +0 -29
- package/templates/basic/app/service/demo.js +0 -51
- package/templates/basic/app/webpack.config.js +0 -4
- package/templates/basic/build.js +0 -7
- package/templates/basic/config/config.beta.js +0 -4
- package/templates/basic/config/config.default.js +0 -32
- package/templates/basic/config/config.local.js +0 -4
- package/templates/basic/config/config.prod.js +0 -6
- package/templates/basic/package.json +0 -31
- package/templates/basic/server.js +0 -26
- package/templates/document/README.md +0 -145
- package/templates/document/app/extend/README.md +0 -6
- package/templates/document/app/middleware/README.md +0 -2
- package/templates/document/app/middleware.js +0 -2
- package/templates/document/app/pages/docs/assets/docs-logo.svg +0 -5
- package/templates/document/app/pages/docs/components/doc-layout.vue +0 -144
- package/templates/document/app/pages/docs/components/doc-navbar.vue +0 -103
- package/templates/document/app/pages/docs/components/doc-search.vue +0 -131
- package/templates/document/app/pages/docs/components/doc-sidebar.vue +0 -29
- package/templates/document/app/pages/docs/components/doc-toc.vue +0 -21
- package/templates/document/app/pages/docs/content.js +0 -28
- package/templates/document/app/pages/docs/docs-config.js +0 -154
- package/templates/document/app/pages/docs/docs.vue +0 -24
- package/templates/document/app/pages/docs/entry.docs.js +0 -26
- package/templates/document/app/pages/docs/markdown/highlight.js +0 -30
- package/templates/document/app/pages/docs/markdown/index.js +0 -129
- package/templates/document/app/pages/docs/search.js +0 -142
- package/templates/document/app/pages/docs/styles/docs.less +0 -1091
- package/templates/document/app/pages/docs/styles/vars.less +0 -87
- package/templates/document/app/pages/docs/theme.js +0 -47
- package/templates/document/app/pages/docs/utils.js +0 -58
- package/templates/document/app/pages/docs/views/doc-home.vue +0 -56
- package/templates/document/app/pages/docs/views/doc-page.vue +0 -147
- package/templates/document/app/webpack.config.js +0 -15
- package/templates/document/build.js +0 -6
- package/templates/document/config/config.beta.js +0 -2
- package/templates/document/config/config.default.js +0 -9
- package/templates/document/config/config.local.js +0 -2
- package/templates/document/config/config.prod.js +0 -2
- package/templates/document/docs/advanced/dashboard.md +0 -66
- package/templates/document/docs/advanced/health.md +0 -72
- package/templates/document/docs/advanced/monitoring.md +0 -60
- package/templates/document/docs/advanced/security.md +0 -88
- package/templates/document/docs/core/app-instance.md +0 -114
- package/templates/document/docs/core/controller-service.md +0 -113
- package/templates/document/docs/core/lifecycle.md +0 -60
- package/templates/document/docs/core/middleware.md +0 -83
- package/templates/document/docs/core/plugins.md +0 -77
- package/templates/document/docs/core/router-schema.md +0 -102
- package/templates/document/docs/dsl/api-contract.md +0 -88
- package/templates/document/docs/dsl/extend.md +0 -311
- package/templates/document/docs/dsl/menu.md +0 -101
- package/templates/document/docs/dsl/model-project.md +0 -122
- package/templates/document/docs/dsl/overview.md +0 -116
- package/templates/document/docs/dsl/reference.md +0 -175
- package/templates/document/docs/dsl/schema-actions.md +0 -135
- package/templates/document/docs/dsl/schema.md +0 -121
- package/templates/document/docs/frontend/build.md +0 -118
- package/templates/document/docs/frontend/curl.md +0 -75
- package/templates/document/docs/frontend/page.md +0 -99
- package/templates/document/docs/frontend/widgets.md +0 -151
- package/templates/document/docs/guide/config.md +0 -108
- package/templates/document/docs/guide/deployment.md +0 -115
- package/templates/document/docs/guide/getting-started.md +0 -199
- package/templates/document/docs/guide/introduction.md +0 -55
- package/templates/document/docs/guide/structure.md +0 -98
- package/templates/document/docs/reference/commands.md +0 -70
- package/templates/document/docs/reference/faq.md +0 -94
- package/templates/document/package.json +0 -36
- package/templates/document/scripts/build-static.js +0 -129
- package/templates/document/server.js +0 -13
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// highlight.js 按需注册:只打包文档站实际用到的语言,控制 vendor 体积。
|
|
2
|
-
import hljs from "highlight.js/lib/core";
|
|
3
|
-
import javascript from "highlight.js/lib/languages/javascript";
|
|
4
|
-
import typescript from "highlight.js/lib/languages/typescript";
|
|
5
|
-
import xml from "highlight.js/lib/languages/xml";
|
|
6
|
-
import css from "highlight.js/lib/languages/css";
|
|
7
|
-
import less from "highlight.js/lib/languages/less";
|
|
8
|
-
import json from "highlight.js/lib/languages/json";
|
|
9
|
-
import bash from "highlight.js/lib/languages/bash";
|
|
10
|
-
import yaml from "highlight.js/lib/languages/yaml";
|
|
11
|
-
import markdown from "highlight.js/lib/languages/markdown";
|
|
12
|
-
import plaintext from "highlight.js/lib/languages/plaintext";
|
|
13
|
-
|
|
14
|
-
[
|
|
15
|
-
["javascript", javascript],
|
|
16
|
-
["typescript", typescript],
|
|
17
|
-
["xml", xml],
|
|
18
|
-
["css", css],
|
|
19
|
-
["less", less],
|
|
20
|
-
["json", json],
|
|
21
|
-
["bash", bash],
|
|
22
|
-
["yaml", yaml],
|
|
23
|
-
["markdown", markdown],
|
|
24
|
-
["plaintext", plaintext],
|
|
25
|
-
].forEach(([name, language]) => hljs.registerLanguage(name, language));
|
|
26
|
-
|
|
27
|
-
// highlight.js 11 不内置 vue 语法,用 xml 规则近似高亮 .vue / 模板块
|
|
28
|
-
hljs.registerAliases(["vue", "html"], { languageName: "xml" });
|
|
29
|
-
|
|
30
|
-
export default hljs;
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
// markdown-it 渲染器:标题锚点 + TOC 收集、代码块外壳(语言标签 + 复制按钮)、
|
|
2
|
-
// 外链新窗口打开、文档内 .md 相对链接转站内路由、::: tip/warning/danger 提示块。
|
|
3
|
-
import MarkdownIt from "markdown-it";
|
|
4
|
-
import MarkdownItContainer from "markdown-it-container";
|
|
5
|
-
import hljs from "./highlight";
|
|
6
|
-
import { slugify, resolveDocHref } from "../utils";
|
|
7
|
-
|
|
8
|
-
const md = new MarkdownIt({
|
|
9
|
-
html: true,
|
|
10
|
-
linkify: true,
|
|
11
|
-
breaks: false,
|
|
12
|
-
typographer: false,
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
// ::: <type> [自定义标题] 提示块(tip / info / warning / danger)
|
|
16
|
-
const CONTAINER_DEFAULT_TITLES = {
|
|
17
|
-
tip: "提示",
|
|
18
|
-
info: "说明",
|
|
19
|
-
warning: "注意",
|
|
20
|
-
danger: "危险",
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
Object.keys(CONTAINER_DEFAULT_TITLES).forEach((type) => {
|
|
24
|
-
md.use(MarkdownItContainer, type, {
|
|
25
|
-
render(tokens, idx) {
|
|
26
|
-
if (tokens[idx].nesting === 1) {
|
|
27
|
-
const info = tokens[idx].info.trim().slice(type.length).trim();
|
|
28
|
-
const title = info || CONTAINER_DEFAULT_TITLES[type];
|
|
29
|
-
return (
|
|
30
|
-
`<div class="doc-container doc-container-${type}">` +
|
|
31
|
-
`<p class="doc-container-title">${md.utils.escapeHtml(title)}</p>`
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
return "</div>";
|
|
35
|
-
},
|
|
36
|
-
});
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
// 代码块:highlight.js 高亮(未识别语言则原样转义),外层加语言标签与复制按钮
|
|
40
|
-
md.renderer.rules.fence = (tokens, idx) => {
|
|
41
|
-
const token = tokens[idx];
|
|
42
|
-
const lang = (token.info || "").trim().split(/\s+/)[0];
|
|
43
|
-
|
|
44
|
-
let codeHtml;
|
|
45
|
-
if (lang && hljs.getLanguage(lang)) {
|
|
46
|
-
try {
|
|
47
|
-
codeHtml = hljs.highlight(token.content, {
|
|
48
|
-
language: lang,
|
|
49
|
-
ignoreIllegals: true,
|
|
50
|
-
}).value;
|
|
51
|
-
} catch (e) {
|
|
52
|
-
codeHtml = md.utils.escapeHtml(token.content);
|
|
53
|
-
}
|
|
54
|
-
} else {
|
|
55
|
-
codeHtml = md.utils.escapeHtml(token.content);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const langLabel = md.utils.escapeHtml(lang || "text");
|
|
59
|
-
return (
|
|
60
|
-
`<div class="doc-code-block">` +
|
|
61
|
-
`<div class="doc-code-bar"><span class="doc-code-lang">${langLabel}</span>` +
|
|
62
|
-
`<button class="doc-code-copy" type="button">复制</button></div>` +
|
|
63
|
-
`<pre><code class="hljs">${codeHtml}</code></pre></div>\n`
|
|
64
|
-
);
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
// 标题开标签:生成唯一 id(供 TOC / 锚点 / 搜索跳转),并收集 h2/h3 进 TOC
|
|
68
|
-
md.renderer.rules.heading_open = (tokens, idx, options, env, self) => {
|
|
69
|
-
const token = tokens[idx];
|
|
70
|
-
const level = Number(token.tag.slice(1));
|
|
71
|
-
const inline = tokens[idx + 1];
|
|
72
|
-
const text = (inline ? inline.content : "").trim();
|
|
73
|
-
|
|
74
|
-
const base = slugify(text) || `heading-${idx}`;
|
|
75
|
-
const count = env.slugCount[base] || 0;
|
|
76
|
-
env.slugCount[base] = count + 1;
|
|
77
|
-
const id = count ? `${base}-${count + 1}` : base;
|
|
78
|
-
|
|
79
|
-
token.attrSet("id", id);
|
|
80
|
-
env.currentHeadingId = id;
|
|
81
|
-
if (level >= 2 && level <= 3) {
|
|
82
|
-
env.toc.push({ level, text, id });
|
|
83
|
-
}
|
|
84
|
-
return self.renderToken(tokens, idx, options);
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
// 标题闭标签:在标题内部追加悬停可见的 # 锚点链接
|
|
88
|
-
md.renderer.rules.heading_close = (tokens, idx, options, env, self) => {
|
|
89
|
-
const id = env.currentHeadingId || "";
|
|
90
|
-
const anchor = id
|
|
91
|
-
? `<a class="doc-header-anchor" href="#${id}" aria-hidden="true">#</a>`
|
|
92
|
-
: "";
|
|
93
|
-
return anchor + self.renderToken(tokens, idx, options);
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
// 链接开标签:外链新窗口;文档内相对 .md 链接(./xx.md、../xx.md)转站内路由
|
|
97
|
-
const defaultLinkOpen =
|
|
98
|
-
md.renderer.rules.link_open ||
|
|
99
|
-
((tokens, idx, options, env, self) => self.renderToken(tokens, idx, options));
|
|
100
|
-
|
|
101
|
-
md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
|
|
102
|
-
const token = tokens[idx];
|
|
103
|
-
const href = token.attrGet("href") || "";
|
|
104
|
-
|
|
105
|
-
if (/^https?:\/\//i.test(href)) {
|
|
106
|
-
token.attrSet("target", "_blank");
|
|
107
|
-
token.attrSet("rel", "noopener noreferrer");
|
|
108
|
-
} else if (!href.startsWith("#") && env.docPath) {
|
|
109
|
-
const resolved = resolveDocHref(env.docPath, href);
|
|
110
|
-
if (resolved) {
|
|
111
|
-
token.attrSet("href", resolved.path + resolved.hash);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return defaultLinkOpen(tokens, idx, options, env, self);
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* 渲染 markdown
|
|
119
|
-
* @param {string} source markdown 原文
|
|
120
|
-
* @param {string} docPath 当前文档路径(相对 docs/),用于解析相对链接
|
|
121
|
-
* @returns {{ html: string, toc: Array<{level:number, text:string, id:string}> }}
|
|
122
|
-
*/
|
|
123
|
-
export function renderMarkdown(source, docPath) {
|
|
124
|
-
const env = { toc: [], slugCount: {}, docPath };
|
|
125
|
-
const html = md.render(source, env);
|
|
126
|
-
return { html, toc: env.toc };
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export default md;
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
// 站内搜索:对全部文档做轻量内存索引(标题 / 小节标题 / 正文),
|
|
2
|
-
// 返回带高亮摘要的结果。文档规模在几百页以内时体验足够,无需后端参与。
|
|
3
|
-
import { getAllDocs } from "./content";
|
|
4
|
-
import { slugify, escapeHtml } from "./utils";
|
|
5
|
-
|
|
6
|
-
let index = null;
|
|
7
|
-
|
|
8
|
-
/** 懒构建索引:文档内容在构建时已打进 bundle,这里只做文本预处理 */
|
|
9
|
-
function buildIndex() {
|
|
10
|
-
if (index) {
|
|
11
|
-
return index;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const all = getAllDocs();
|
|
15
|
-
index = Object.entries(all).map(([docPath, source]) => {
|
|
16
|
-
// 去掉代码块再提取文本,避免把代码当正文搜索
|
|
17
|
-
const withoutCode = String(source).replace(/```[\s\S]*?```/g, " ");
|
|
18
|
-
|
|
19
|
-
const headings = [];
|
|
20
|
-
const headingRe = /^(#{2,3})\s+(.+?)\s*#*\s*$/gm;
|
|
21
|
-
let match;
|
|
22
|
-
while ((match = headingRe.exec(withoutCode))) {
|
|
23
|
-
headings.push({
|
|
24
|
-
level: match[1].length,
|
|
25
|
-
text: match[2].replace(/[#*`]/g, "").trim(),
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const text = withoutCode
|
|
30
|
-
.replace(/<[^>]+>/g, " ")
|
|
31
|
-
.replace(/[#>*`~[\]()!_|:-]/g, " ")
|
|
32
|
-
.replace(/\s+/g, " ")
|
|
33
|
-
.trim()
|
|
34
|
-
.toLowerCase();
|
|
35
|
-
|
|
36
|
-
return { docPath, headings, text };
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
return index;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function buildTitleMap(sidebar) {
|
|
43
|
-
const map = {};
|
|
44
|
-
(sidebar || []).forEach((group) => {
|
|
45
|
-
(group.items || []).forEach((item) => {
|
|
46
|
-
map[item.path.replace(/^\/view\/docs\//, "")] = item.text;
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
return map;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** 把关键词片段包上 <mark>,先转义再替换,保证安全 */
|
|
53
|
-
function highlight(text, keyword) {
|
|
54
|
-
if (!keyword) {
|
|
55
|
-
return escapeHtml(text);
|
|
56
|
-
}
|
|
57
|
-
const escaped = escapeHtml(text);
|
|
58
|
-
const pattern = keyword
|
|
59
|
-
.split(/\s+/)
|
|
60
|
-
.filter(Boolean)
|
|
61
|
-
.map((term) => term.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"))
|
|
62
|
-
.join("|");
|
|
63
|
-
if (!pattern) {
|
|
64
|
-
return escaped;
|
|
65
|
-
}
|
|
66
|
-
return escaped.replace(new RegExp(`(${pattern})`, "gi"), "<mark>$1</mark>");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* 搜索文档
|
|
71
|
-
* @param {string} keyword 关键词,支持空格分词
|
|
72
|
-
* @param {object} docsConfig 文档站配置(取侧边栏标题)
|
|
73
|
-
* @returns {Array<{docPath, title, titleHtml, heading, anchor, snippet}>}
|
|
74
|
-
*/
|
|
75
|
-
export function searchDocs(keyword, docsConfig) {
|
|
76
|
-
const terms = String(keyword || "")
|
|
77
|
-
.trim()
|
|
78
|
-
.toLowerCase()
|
|
79
|
-
.split(/\s+/)
|
|
80
|
-
.filter(Boolean);
|
|
81
|
-
if (!terms.length) {
|
|
82
|
-
return [];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const titleMap = buildTitleMap(docsConfig.sidebar);
|
|
86
|
-
const results = [];
|
|
87
|
-
|
|
88
|
-
buildIndex().forEach(({ docPath, headings, text }) => {
|
|
89
|
-
const title = titleMap[docPath] || docPath;
|
|
90
|
-
const titleLower = title.toLowerCase();
|
|
91
|
-
|
|
92
|
-
let score = 0;
|
|
93
|
-
let matchedHeading = null;
|
|
94
|
-
|
|
95
|
-
terms.forEach((term) => {
|
|
96
|
-
if (titleLower.includes(term)) {
|
|
97
|
-
score += 100;
|
|
98
|
-
}
|
|
99
|
-
// 中文场景:标题无空格分词,按整串 contains;正文按出现次数计分
|
|
100
|
-
const occurrences = text.split(term).length - 1;
|
|
101
|
-
score += occurrences;
|
|
102
|
-
|
|
103
|
-
if (!matchedHeading) {
|
|
104
|
-
const heading = headings.find((h) => h.text.toLowerCase().includes(term));
|
|
105
|
-
if (heading) {
|
|
106
|
-
matchedHeading = heading;
|
|
107
|
-
score += 30;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
if (score <= 0) {
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// 摘要:取第一个命中的关键词前后各 70 字符
|
|
117
|
-
let snippet = "";
|
|
118
|
-
const firstTerm = terms[0];
|
|
119
|
-
const pos = text.indexOf(firstTerm);
|
|
120
|
-
if (pos >= 0) {
|
|
121
|
-
const start = Math.max(0, pos - 70);
|
|
122
|
-
const end = Math.min(text.length, pos + firstTerm.length + 70);
|
|
123
|
-
snippet = `${start > 0 ? "…" : ""}${text.slice(start, end).trim()}${
|
|
124
|
-
end < text.length ? "…" : ""
|
|
125
|
-
}`;
|
|
126
|
-
} else {
|
|
127
|
-
snippet = text.slice(0, 140);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
results.push({
|
|
131
|
-
docPath,
|
|
132
|
-
title,
|
|
133
|
-
titleHtml: highlight(title, keyword),
|
|
134
|
-
heading: matchedHeading ? matchedHeading.text : "",
|
|
135
|
-
anchor: matchedHeading ? slugify(matchedHeading.text) : "",
|
|
136
|
-
snippet: highlight(snippet, keyword),
|
|
137
|
-
score,
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
return results.sort((a, b) => b.score - a.score).slice(0, 10);
|
|
142
|
-
}
|