for-humanity 0.12.0 → 0.13.0

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.
Files changed (226) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +16 -9
  3. package/dist/browser.js +16 -16
  4. package/dist/cli.css +2 -968
  5. package/dist/cli.js +92 -2318
  6. package/dist/config.js +1 -0
  7. package/dist/constant/copy.d.ts +100 -0
  8. package/dist/constant/site.d.ts +20 -0
  9. package/dist/constant/status.d.ts +19 -0
  10. package/dist/copy-C1uzvEnr.js +103 -0
  11. package/dist/group-path-XAThmzvC.js +10 -0
  12. package/dist/load-site-CbpLEhwu.js +2379 -0
  13. package/dist/logger-Dv1i9xSV.js +9 -0
  14. package/dist/mermaid/THIRD-PARTY-NOTICES.txt +3134 -0
  15. package/dist/mermaid/chunk--TN-qHgG.js +2 -0
  16. package/dist/mermaid/chunk-0kM1Lv4D.js +2 -0
  17. package/dist/mermaid/chunk-3FHei3pH.js +2001 -0
  18. package/dist/mermaid/chunk-3_2p2GqN.js +2 -0
  19. package/dist/mermaid/chunk-6HLei9i0.js +84 -0
  20. package/dist/mermaid/chunk-7Sz3kAwl.js +2214 -0
  21. package/dist/mermaid/chunk-7Tarqbpa.js +18047 -0
  22. package/dist/mermaid/chunk-9kkt8lzL.js +10 -0
  23. package/dist/mermaid/chunk-B--pNBQF.js +884 -0
  24. package/dist/mermaid/chunk-B4F-pysn.js +4241 -0
  25. package/dist/mermaid/chunk-B58sEIY_.js +14 -0
  26. package/dist/mermaid/chunk-B9_UWzSH.js +1517 -0
  27. package/dist/mermaid/chunk-BB8uZHwY.js +75 -0
  28. package/dist/mermaid/chunk-BFfk0LEc.js +717 -0
  29. package/dist/mermaid/chunk-BKri0qr7.js +89 -0
  30. package/dist/mermaid/chunk-BL404pH5.js +26 -0
  31. package/dist/mermaid/chunk-BLeiQSWo.js +354 -0
  32. package/dist/mermaid/chunk-BOmH_UFd.js +2 -0
  33. package/dist/mermaid/chunk-BSej9Nhy.js +1361 -0
  34. package/dist/mermaid/chunk-BYzrzvCI.js +12 -0
  35. package/dist/mermaid/chunk-BariMtWr.js +3020 -0
  36. package/dist/mermaid/chunk-BcrBoMwH.js +2352 -0
  37. package/dist/mermaid/chunk-Bok8z-Yo.js +67 -0
  38. package/dist/mermaid/chunk-BpTHLKQM.js +1970 -0
  39. package/dist/mermaid/chunk-BqjuxRsC.js +733 -0
  40. package/dist/mermaid/chunk-BuvPd-s5.js +1073 -0
  41. package/dist/mermaid/chunk-BvVehae3.js +5069 -0
  42. package/dist/mermaid/chunk-C-JABYpd.js +3075 -0
  43. package/dist/mermaid/chunk-C9XlTm4w.js +2 -0
  44. package/dist/mermaid/chunk-CApNbSU9.js +6 -0
  45. package/dist/mermaid/chunk-CCM2AH-C.js +9 -0
  46. package/dist/mermaid/chunk-CD1E0F_N.js +2 -0
  47. package/dist/mermaid/chunk-CDWvKG7D.js +2 -0
  48. package/dist/mermaid/chunk-CEVPpC1F.js +34 -0
  49. package/dist/mermaid/chunk-CLDr12lf.js +47504 -0
  50. package/dist/mermaid/chunk-CLVYqOBI.js +61 -0
  51. package/dist/mermaid/chunk-CLeOkFb5.js +15 -0
  52. package/dist/mermaid/chunk-CLgRAtOz.js +37 -0
  53. package/dist/mermaid/chunk-CMqFNUBl.js +134 -0
  54. package/dist/mermaid/chunk-CTPaBJXB.js +2 -0
  55. package/dist/mermaid/chunk-CVi6IGBL.js +2 -0
  56. package/dist/mermaid/chunk-CWV_EN-4.js +4745 -0
  57. package/dist/mermaid/chunk-CZ0dAs3g.js +2 -0
  58. package/dist/mermaid/chunk-C_YGy4Fn.js +236 -0
  59. package/dist/mermaid/chunk-CcVH22Yt.js +100 -0
  60. package/dist/mermaid/chunk-CgG6CD9_.js +7175 -0
  61. package/dist/mermaid/chunk-CgOP6IDB.js +3397 -0
  62. package/dist/mermaid/chunk-Cgg2UTSf.js +13 -0
  63. package/dist/mermaid/chunk-ChJfJJ1A.js +214 -0
  64. package/dist/mermaid/chunk-Ck5XRA46.js +447 -0
  65. package/dist/mermaid/chunk-Ckuw16cl.js +203 -0
  66. package/dist/mermaid/chunk-CpAbRCbF.js +1880 -0
  67. package/dist/mermaid/chunk-CuYekbSv.js +2 -0
  68. package/dist/mermaid/chunk-CwS4wZ5a.js +2 -0
  69. package/dist/mermaid/chunk-D-bcrBO3.js +82 -0
  70. package/dist/mermaid/chunk-D3IEAkCW.js +76 -0
  71. package/dist/mermaid/chunk-D8XfBJ_K.js +645 -0
  72. package/dist/mermaid/chunk-D9Ddd9y4.js +2228 -0
  73. package/dist/mermaid/chunk-DBh1mIbK.js +12 -0
  74. package/dist/mermaid/chunk-DD6Df6Ic.js +5 -0
  75. package/dist/mermaid/chunk-DGVDaXjx.js +8 -0
  76. package/dist/mermaid/chunk-DK9KqIXj.js +632 -0
  77. package/dist/mermaid/chunk-DORnIAsy.js +4487 -0
  78. package/dist/mermaid/chunk-DU69_VcF.js +363 -0
  79. package/dist/mermaid/chunk-DVNvSFoz.js +2144 -0
  80. package/dist/mermaid/chunk-DZe-4kde.js +20 -0
  81. package/dist/mermaid/chunk-D_a06Rz4.js +287 -0
  82. package/dist/mermaid/chunk-DfyFJJi2.js +972 -0
  83. package/dist/mermaid/chunk-DhKYPp1Z.js +2 -0
  84. package/dist/mermaid/chunk-DjFqgNTG.js +94 -0
  85. package/dist/mermaid/chunk-DmbDDrr-.js +65 -0
  86. package/dist/mermaid/chunk-DpuxlyL_.js +696 -0
  87. package/dist/mermaid/chunk-DqGhppWe.js +2 -0
  88. package/dist/mermaid/chunk-DqPZxHXa.js +5 -0
  89. package/dist/mermaid/chunk-Dt_1Jyif.js +293 -0
  90. package/dist/mermaid/chunk-DyQBE_NW.js +1935 -0
  91. package/dist/mermaid/chunk-JckyC4mW.js +1009 -0
  92. package/dist/mermaid/chunk-K7Myuj2-.js +1334 -0
  93. package/dist/mermaid/chunk-KuPYb48V.js +275 -0
  94. package/dist/mermaid/chunk-MFVRUoO0.js +4020 -0
  95. package/dist/mermaid/chunk-MbInCS_6.js +28 -0
  96. package/dist/mermaid/chunk-MexOLyKV.js +355 -0
  97. package/dist/mermaid/chunk-NnbDtJzg.js +21856 -0
  98. package/dist/mermaid/chunk-SGpOYZbI.js +2139 -0
  99. package/dist/mermaid/chunk-TbxLDlcU.js +198 -0
  100. package/dist/mermaid/chunk-TftHqGLg.js +490 -0
  101. package/dist/mermaid/chunk-UjQ8vA_Z.js +4138 -0
  102. package/dist/mermaid/chunk-YgmVTKqc.js +16 -0
  103. package/dist/mermaid/chunk-_a9EZE1v.js +1798 -0
  104. package/dist/mermaid/chunk-dTb8jqeP.js +2 -0
  105. package/dist/mermaid/chunk-fFdMfF8S.js +2240 -0
  106. package/dist/mermaid/chunk-feYbMzBj.js +1267 -0
  107. package/dist/mermaid/chunk-g3Pn8DkW.js +46 -0
  108. package/dist/mermaid/chunk-hM77LvCb.js +19832 -0
  109. package/dist/mermaid/chunk-hUDb-eAW.js +527 -0
  110. package/dist/mermaid/chunk-tpABtZ-3.js +4252 -0
  111. package/dist/mermaid/chunk-xIbz3oFK.js +59 -0
  112. package/dist/mermaid/chunk-yBz-vst0.js +976 -0
  113. package/dist/mermaid/mermaid-BhtR3wyB.js +1145 -0
  114. package/dist/run-site-command-C80YoNOe.js +129 -0
  115. package/dist/site-config-bllORGpm.js +90 -0
  116. package/dist/site.js +1 -0
  117. package/dist/start-dev-server-C4_Lu1nZ.js +176 -0
  118. package/dist/to-change-queue-DbEnZGNK.js +34 -0
  119. package/dist/to-error-message-pF6_7wGK.js +16 -0
  120. package/dist/type/group-path.d.ts +7 -0
  121. package/dist/type/site-config.d.ts +57 -0
  122. package/package.json +34 -17
  123. package/src/component/widget/cursor-face/_constant/cursor-face.ts +0 -14
  124. package/src/component/widget/cursor-face/wg-cursor-face.css +0 -15
  125. package/src/component/widget/cursor-face/wg-cursor-face.tsx +0 -153
  126. package/src/component/widget/navigation/_constant/locale.ts +0 -9
  127. package/src/component/widget/navigation/_constant/navigation-data-schema.ts +0 -33
  128. package/src/component/widget/navigation/_constant/navigation.ts +0 -9
  129. package/src/component/widget/navigation/_constant/reading-line.ts +0 -4
  130. package/src/component/widget/navigation/_function/restore-navigation-scroll.ts +0 -59
  131. package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-branches.ts +0 -15
  132. package/src/component/widget/navigation/_function/to-doc-groups/_to-doc-group-branches.ts +0 -70
  133. package/src/component/widget/navigation/_function/to-doc-groups/to-doc-groups.ts +0 -15
  134. package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-document.ts +0 -13
  135. package/src/component/widget/navigation/_function/to-navigation-data/_to-navigation-group.ts +0 -13
  136. package/src/component/widget/navigation/_function/to-navigation-data/to-navigation-data.ts +0 -18
  137. package/src/component/widget/navigation/_function/to-navigation-json.ts +0 -8
  138. package/src/component/widget/navigation/_function/to-toc-groups.ts +0 -38
  139. package/src/component/widget/navigation/_type/doc-branch.ts +0 -11
  140. package/src/component/widget/navigation/_type/doc-group.ts +0 -24
  141. package/src/component/widget/navigation/_type/navigation-data.ts +0 -75
  142. package/src/component/widget/navigation/_type/navigation-focus-snapshot.ts +0 -17
  143. package/src/component/widget/navigation/_type/toc-group.ts +0 -39
  144. package/src/component/widget/navigation/_wg-navigation-nav-list.css +0 -48
  145. package/src/component/widget/navigation/_wg-navigation-nav-list.tsx +0 -61
  146. package/src/component/widget/navigation/_wg-navigation-nav.css +0 -21
  147. package/src/component/widget/navigation/_wg-navigation-nav.tsx +0 -33
  148. package/src/component/widget/navigation/_wg-navigation-scroll.tsx +0 -117
  149. package/src/component/widget/navigation/_wg-navigation-toc.css +0 -91
  150. package/src/component/widget/navigation/_wg-navigation-toc.tsx +0 -114
  151. package/src/component/widget/navigation/wg-navigation.css +0 -282
  152. package/src/component/widget/navigation/wg-navigation.tsx +0 -420
  153. package/src/component/widget/prose/_constant/heading-highlight.ts +0 -4
  154. package/src/component/widget/prose/_constant/section.ts +0 -7
  155. package/src/component/widget/prose/_constant/status.ts +0 -9
  156. package/src/component/widget/prose/_function/has-block-content.ts +0 -30
  157. package/src/component/widget/prose/_function/rehype-head.ts +0 -31
  158. package/src/component/widget/prose/_function/rehype-sections/_to-section-headings.ts +0 -20
  159. package/src/component/widget/prose/_function/rehype-sections/rehype-sections.ts +0 -21
  160. package/src/component/widget/prose/_function/rehype-tables.ts +0 -22
  161. package/src/component/widget/prose/_function/remark-blocks.ts +0 -112
  162. package/src/component/widget/prose/_function/remark-flow.ts +0 -26
  163. package/src/component/widget/prose/_function/remark-links.ts +0 -33
  164. package/src/component/widget/prose/_function/remark-parts.ts +0 -26
  165. package/src/component/widget/prose/_function/remark-status.ts +0 -59
  166. package/src/component/widget/prose/_function/remark-swatch.ts +0 -16
  167. package/src/component/widget/prose/_function/remark-unknown-directives.ts +0 -25
  168. package/src/component/widget/prose/wg-prose.css +0 -484
  169. package/src/component/widget/prose/wg-prose.tsx +0 -43
  170. package/src/component/widget/shell/wg-shell.css +0 -63
  171. package/src/component/widget/shell/wg-shell.tsx +0 -88
  172. package/src/component/widget/shell-controls/wg-shell-controls.css +0 -4
  173. package/src/component/widget/shell-controls/wg-shell-controls.tsx +0 -170
  174. package/src/constant/asset.ts +0 -63
  175. package/src/constant/copy.ts +0 -133
  176. package/src/constant/doc.ts +0 -13
  177. package/src/constant/font.ts +0 -34
  178. package/src/constant/site.ts +0 -24
  179. package/src/constant/status.ts +0 -15
  180. package/src/entry/browser/browser.tsx +0 -22
  181. package/src/entry/cli/_constant/cli.ts +0 -19
  182. package/src/entry/cli/_constant/crawling.ts +0 -14
  183. package/src/entry/cli/_constant/snippet.ts +0 -21
  184. package/src/entry/cli/_function/create-app.tsx +0 -57
  185. package/src/entry/cli/_function/create-dev-app.ts +0 -87
  186. package/src/entry/cli/_function/create-processor/_rehype-assets.ts +0 -70
  187. package/src/entry/cli/_function/create-processor/_rehype-heading-ids.ts +0 -34
  188. package/src/entry/cli/_function/create-processor/_remark-report.ts +0 -15
  189. package/src/entry/cli/_function/create-processor/_remark-snippets.ts +0 -117
  190. package/src/entry/cli/_function/create-processor/_shiki-transformers.ts +0 -91
  191. package/src/entry/cli/_function/create-processor/create-processor.ts +0 -64
  192. package/src/entry/cli/_function/read-docs.ts +0 -128
  193. package/src/entry/cli/_function/read-home.ts +0 -32
  194. package/src/entry/cli/_function/to-crawling-app.ts +0 -42
  195. package/src/entry/cli/cli.test.ts +0 -804
  196. package/src/entry/cli/cli.ts +0 -206
  197. package/src/env.d.ts +0 -6
  198. package/src/page/doc/pg-doc.tsx +0 -35
  199. package/src/page/home/pg-home.tsx +0 -40
  200. package/src/store/navigation/create-navigation-stores.test.ts +0 -74
  201. package/src/store/navigation/create-navigation-stores.ts +0 -59
  202. package/src/store/navigation/navigation-state.ts +0 -36
  203. package/src/store/navigation/navigation-storage.ts +0 -9
  204. package/src/store/navigation/to-navigation-scroll-state.ts +0 -42
  205. package/src/style/base.css +0 -28
  206. package/src/style/token.css +0 -188
  207. package/src/type/doc-content.ts +0 -15
  208. package/src/type/doc-data.ts +0 -38
  209. package/src/type/doc-file-data.ts +0 -21
  210. package/src/type/doc-heading.ts +0 -17
  211. package/src/type/doc-outline.ts +0 -16
  212. package/src/type/doc-section.ts +0 -9
  213. package/src/type/doc.ts +0 -20
  214. package/src/type/group-path.ts +0 -7
  215. package/src/type/site-assets.ts +0 -25
  216. package/src/type/site-config.ts +0 -73
  217. package/src/type/vfile-data.d.ts +0 -10
  218. package/src/util/async/to-change-queue.test.ts +0 -58
  219. package/src/util/async/to-change-queue.ts +0 -43
  220. package/src/util/dom/find-hash-target.ts +0 -18
  221. package/src/util/dom/reveal-hash-target.ts +0 -15
  222. package/src/util/error/to-error-message.ts +0 -10
  223. package/src/util/file/to-asset-path.ts +0 -26
  224. package/src/util/font/to-font-css.test.ts +0 -41
  225. package/src/util/font/to-font-css.ts +0 -28
  226. package/src/util/mermaid/render-flow.js +0 -321
@@ -0,0 +1,129 @@
1
+ import { d as copy_error_missing_build, n as copy_error_config } from "./copy-C1uzvEnr.js";
2
+ import { t as logger } from "./logger-Dv1i9xSV.js";
3
+ import { n as site_config_absent, t as siteConfigSchema } from "./site-config-bllORGpm.js";
4
+ import { n as font_cache_control, r as asset_font_dir, t as loadSite } from "./load-site-CbpLEhwu.js";
5
+ import { n as config_file_names, t as toErrorMessage } from "./to-error-message-pF6_7wGK.js";
6
+ import { copyFile, mkdir, rm, writeFile } from "node:fs/promises";
7
+ import { z } from "zod";
8
+ import { existsSync } from "node:fs";
9
+ import { dirname, join, relative, resolve } from "node:path";
10
+ import { toSSG } from "hono/ssg";
11
+ import { fileURLToPath, pathToFileURL } from "node:url";
12
+ import { createJiti } from "jiti";
13
+ //#region src/app/_function/read-site-config.ts
14
+ /**
15
+ * 문서 루트의 설정 조회, TypeScript 실행과 스키마 검증
16
+ *
17
+ * - 중복 파일 거부, 실제 적용되는 설정의 모호성 방지
18
+ * - Node의 기본 TypeScript 지원 여부와 무관하게 같은 설정 실행
19
+ */
20
+ var readSiteConfig = async (root) => {
21
+ const files = config_file_names.map((name) => join(root, name)).filter((file) => existsSync(file));
22
+ if (files.length > 1) throw new Error(`${copy_error_config}: 설정 파일은 하나만 사용하세요 (${config_file_names.join(", ")})`);
23
+ const file = files[0];
24
+ if (file === void 0) return siteConfigSchema.parse(site_config_absent);
25
+ const input = file.endsWith(".mjs") ? await import(pathToFileURL(file).href) : await createJiti(import.meta.url, {
26
+ interopDefault: false,
27
+ tryNative: false
28
+ }).import(file);
29
+ const parsed = z.object({ default: siteConfigSchema }).safeParse(input);
30
+ if (!parsed.success) throw new Error(`${copy_error_config}: ${parsed.error.issues.map((issue) => `${issue.path.join(".")} ${issue.message}`).join(", ")}`);
31
+ return parsed.data.default;
32
+ };
33
+ //#endregion
34
+ //#region src/entry/preview/to-preview-config.ts
35
+ /**
36
+ * 빌드된 사이트 전용 Vite 설정. 소비 프로젝트의 설정과 환경 파일 자동 로드 제외
37
+ */
38
+ var toPreviewConfig = (params) => {
39
+ const outDir = resolve(params.root, "dist");
40
+ if (!existsSync(join(outDir, "index.html"))) throw new Error(`${copy_error_missing_build}: ${outDir}`);
41
+ return {
42
+ configFile: false,
43
+ envDir: false,
44
+ root: params.root,
45
+ publicDir: false,
46
+ appType: "mpa",
47
+ build: { outDir },
48
+ preview: {
49
+ port: params.port,
50
+ strictPort: true,
51
+ host: "localhost"
52
+ },
53
+ plugins: [{
54
+ name: "for-humanity:preview",
55
+ configurePreviewServer: (server) => {
56
+ server.middlewares.use((request, response, next) => {
57
+ if (request.url?.startsWith(`${asset_font_dir}/`)) response.setHeader("Cache-Control", font_cache_control);
58
+ next();
59
+ });
60
+ return () => {
61
+ server.middlewares.use((request, response, next) => {
62
+ response.removeHeader("Cache-Control");
63
+ if (request.url !== void 0 && request.url.split("?")[0] === request.originalUrl?.split("?")[0]) request.url = request.url.replace(/\/?(?=\?|$)/, "/index.html");
64
+ next();
65
+ });
66
+ };
67
+ }
68
+ }]
69
+ };
70
+ };
71
+ //#endregion
72
+ //#region src/entry/cli/_function/run-site-command.ts
73
+ /**
74
+ * 사이트 명령 실행과 실패 시 종료 코드 1
75
+ */
76
+ var runSiteCommand = async (params) => {
77
+ try {
78
+ if (params.args._.length > 1) throw new Error("문서 폴더는 하나만 지정하세요");
79
+ const kitRoot = fileURLToPath(new URL("../", import.meta.url));
80
+ const docsRoot = resolve(params.args.dir);
81
+ const outDir = join(docsRoot, "dist");
82
+ const siteConfig = await readSiteConfig(docsRoot);
83
+ if (params.command === "preview") {
84
+ (await (await import("vite")).preview(toPreviewConfig({
85
+ root: docsRoot,
86
+ port: siteConfig.port
87
+ }))).printUrls();
88
+ return;
89
+ }
90
+ if (params.command === "dev") {
91
+ await (await import("./start-dev-server-C4_Lu1nZ.js")).startDevServer({
92
+ root: docsRoot,
93
+ kitRoot,
94
+ site: siteConfig,
95
+ source: false
96
+ });
97
+ return;
98
+ }
99
+ const snapshot = await loadSite({
100
+ root: docsRoot,
101
+ kitRoot,
102
+ site: siteConfig
103
+ });
104
+ await rm(outDir, {
105
+ recursive: true,
106
+ force: true
107
+ });
108
+ const result = await toSSG(snapshot.pages, {
109
+ writeFile,
110
+ mkdir
111
+ }, { dir: outDir });
112
+ if (!result.success) throw result.error;
113
+ const crawling = snapshot.crawling === void 0 ? void 0 : await toSSG(snapshot.crawling, {
114
+ writeFile,
115
+ mkdir
116
+ }, { dir: outDir });
117
+ if (crawling?.success === false) throw crawling.error;
118
+ for (const [url, file] of snapshot.files) {
119
+ await mkdir(dirname(join(outDir, url)), { recursive: true });
120
+ await copyFile(file, join(outDir, url));
121
+ }
122
+ logger.success(`${crawling === void 0 ? result.files.length : result.files.length + crawling.files.length} files, ${snapshot.files.size} assets → ${relative(process.cwd(), outDir)}`);
123
+ } catch (error) {
124
+ logger.error(toErrorMessage(error));
125
+ process.exitCode = 1;
126
+ }
127
+ };
128
+ //#endregion
129
+ export { runSiteCommand };
@@ -0,0 +1,90 @@
1
+ import { C as copy_site_title_default, f as copy_error_navigation_clash, m as copy_error_site_url } from "./copy-C1uzvEnr.js";
2
+ import { t as groupPathSchema } from "./group-path-XAThmzvC.js";
3
+ import { z } from "zod";
4
+ //#region src/constant/site.ts
5
+ /**
6
+ * 설정 파일 부재 시 입력. 스키마 기본값 적용
7
+ */
8
+ var site_config_absent = {};
9
+ /**
10
+ * 탐색 순서 생략 시 모든 묶음을 이름순 배치
11
+ */
12
+ var site_navigation_default = [];
13
+ /**
14
+ * dev, preview 서버 기본 포트
15
+ */
16
+ var site_port_default = 4321;
17
+ /**
18
+ * 포트 번호 상한. TCP
19
+ */
20
+ var site_port_max = 65535;
21
+ //#endregion
22
+ //#region src/constant/status.ts
23
+ /**
24
+ * 상태 표지 종류. verified 초록, unverified amber
25
+ */
26
+ var status_kind = {
27
+ verified: "verified",
28
+ unverified: "unverified"
29
+ };
30
+ /**
31
+ * 기본 상태 문구. 확인됨은 뒤의 날짜 포함
32
+ */
33
+ var status_default_phrases = [{
34
+ phrase: "확인됨",
35
+ kind: status_kind.verified,
36
+ date: true
37
+ }, {
38
+ phrase: "확인되지 않았다",
39
+ kind: status_kind.unverified
40
+ }];
41
+ //#endregion
42
+ //#region src/type/site-config.ts
43
+ /**
44
+ * 사이트 설정의 입력 검증과 기본값 적용
45
+ */
46
+ var siteConfigSchema = z.object({
47
+ /**
48
+ * 사이드바 이름과 탭 제목
49
+ */
50
+ title: z.string().default(copy_site_title_default),
51
+ /**
52
+ * HTML 설명 메타데이터. 선택
53
+ */
54
+ description: z.string().optional(),
55
+ /**
56
+ * 공개 사이트 루트 URL. 지정할 때만 robots.txt와 sitemap.xml 생성
57
+ */
58
+ url: z.url({ protocol: /^https?$/ }).transform((value) => new URL(value)).refine((value) => value.username === "" && value.password === "" && value.pathname === "/" && value.search === "" && value.hash === "", copy_error_site_url).transform((value) => value.origin).optional(),
59
+ /**
60
+ * dev, preview 서버 포트. 같은 기계에서 문서 프로젝트 둘을 나란히 띄울 때 한쪽에 지정
61
+ */
62
+ port: z.int().min(1).max(site_port_max).default(site_port_default),
63
+ /**
64
+ * 데스크톱 커서 옆 픽셀 얼굴. 기본 꺼짐. favicon 은 설정과 무관
65
+ */
66
+ cursorFace: z.boolean().default(false),
67
+ /**
68
+ * 탐색 묶음 경로의 읽는 순서. 미지정 형제 묶음은 뒤에서 이름순
69
+ */
70
+ navigation: z.array(groupPathSchema).refine((groups) => new Set(groups.map((path) => JSON.stringify(path))).size === groups.length, copy_error_navigation_clash).default(site_navigation_default.map((name) => [name])),
71
+ /**
72
+ * 본문에서 상태 표지로 표시할 문구
73
+ */
74
+ status: z.array(z.object({
75
+ /**
76
+ * 찾을 문구 원문
77
+ */
78
+ phrase: z.string().min(1).refine((phrase) => phrase.trim().length > 0),
79
+ /**
80
+ * 상태 표지의 색 종류
81
+ */
82
+ kind: z.enum(status_kind),
83
+ /**
84
+ * 문구 뒤의 YYYY-MM-DD 날짜 포함 여부
85
+ */
86
+ date: z.boolean().optional()
87
+ })).default(status_default_phrases)
88
+ });
89
+ //#endregion
90
+ export { site_config_absent as n, siteConfigSchema as t };
package/dist/site.js ADDED
@@ -0,0 +1 @@
1
+ export { t as loadSite } from "./load-site-CbpLEhwu.js";
@@ -0,0 +1,176 @@
1
+ import { p as copy_error_prefix } from "./copy-C1uzvEnr.js";
2
+ import { t as toChangeQueue } from "./to-change-queue-DbEnZGNK.js";
3
+ import { n as config_file_names, t as toErrorMessage } from "./to-error-message-pF6_7wGK.js";
4
+ import { z } from "zod";
5
+ import { realpathSync } from "node:fs";
6
+ import { extname, isAbsolute, join, relative, sep } from "node:path";
7
+ import { fileURLToPath, pathToFileURL } from "node:url";
8
+ import { createServer } from "vite";
9
+ import devServer from "@hono/vite-dev-server";
10
+ import { debounce, escapeRegExp } from "es-toolkit";
11
+ //#region src/entry/dev/_constant/dev.ts
12
+ /**
13
+ * 생성물과 설치 파일의 변경 제외, 재빌드 반복 방지
14
+ */
15
+ var dev_ignored_paths = [
16
+ "**/dist/**",
17
+ "**/node_modules/**",
18
+ "**/.git/**",
19
+ "**/.cache/**"
20
+ ];
21
+ //#endregion
22
+ //#region src/entry/dev/to-dev-config.ts
23
+ /**
24
+ * 단일 Vite 서버의 Hono 연결과 문서 갱신 설정
25
+ *
26
+ * - 소비 프로젝트의 Vite 설정과 환경 파일은 자동 실행하지 않음
27
+ * - 마지막 정상 스냅샷 유지, 준비 중 새 변경과 서버 종료 이후 결과 제외
28
+ */
29
+ var toDevConfig = (params) => {
30
+ const root = realpathSync(params.root);
31
+ const kitRoot = realpathSync(params.kitRoot);
32
+ let currentSite;
33
+ let dispose;
34
+ let prepare;
35
+ let ready;
36
+ const viteEnvPath = fileURLToPath(new URL("./dist/client/env.mjs", import.meta.resolve("vite/package.json")));
37
+ const viteClientPaths = [/^\/@vite\/(client|env)(?:\?|$)/, ...[`/${relative(kitRoot, viteEnvPath)}`, `/@fs/${viteEnvPath.replace(/^\//, "")}`].map((path) => new RegExp(`^${escapeRegExp(path.replaceAll("\\", "/"))}(?:\\?|$)`))];
38
+ return {
39
+ configFile: false,
40
+ envDir: false,
41
+ root: kitRoot,
42
+ cacheDir: join(kitRoot, "node_modules/.vite/for-humanity"),
43
+ publicDir: false,
44
+ appType: "custom",
45
+ resolve: { alias: { "@": join(kitRoot, "src") } },
46
+ oxc: { jsx: { importSource: "hono/jsx" } },
47
+ optimizeDeps: params.source ? {
48
+ entries: ["src/entry/browser/browser.tsx"],
49
+ include: ["hono/jsx/dom/jsx-runtime", "hono/jsx/dom/jsx-dev-runtime"]
50
+ } : { noDiscovery: true },
51
+ server: {
52
+ port: params.site.port,
53
+ strictPort: true,
54
+ host: "localhost",
55
+ fs: {
56
+ allow: [kitRoot],
57
+ deny: [
58
+ ".env",
59
+ ".env.*",
60
+ "*.{crt,pem}",
61
+ "**/.git/**",
62
+ "**/*.md",
63
+ "**/*.mdx",
64
+ "**/for-humanity.config.*",
65
+ ...params.source ? [`${root.replaceAll("\\", "/")}/**`] : []
66
+ ]
67
+ }
68
+ },
69
+ plugins: [{
70
+ name: "for-humanity:documents",
71
+ enforce: "pre",
72
+ resolveId: function(id, importer, options) {
73
+ if (!options.ssr && /^hono\/jsx\/jsx-(dev-)?runtime$/.test(id)) return this.resolve(id.replace("hono/jsx/", "hono/jsx/dom/"), importer, { skipSelf: true });
74
+ },
75
+ configureServer: (server) => {
76
+ const state = {
77
+ generation: 0,
78
+ closed: false
79
+ };
80
+ const refresh = toChangeQueue({
81
+ run: async () => {
82
+ if (state.closed) return;
83
+ const generation = state.generation;
84
+ const module = params.source ? await server.ssrLoadModule("/src/app/load-site.ts") : await import(pathToFileURL(join(kitRoot, "dist/site.js")).href);
85
+ const nextSite = await z.custom((value) => typeof value === "function").parse(module.loadSite)({
86
+ ...params,
87
+ root,
88
+ kitRoot,
89
+ browser: params.source ? {
90
+ kind: "module",
91
+ path: "/src/entry/browser/browser.tsx"
92
+ } : void 0,
93
+ stylePaths: params.source ? z.array(z.string()).parse((await server.ssrLoadModule("/src/entry/dev/_constant/style.ts")).style_paths) : void 0
94
+ });
95
+ if (state.closed || generation !== state.generation) return;
96
+ currentSite = nextSite;
97
+ if (generation > 0) server.hot.send({ type: "full-reload" });
98
+ },
99
+ onError: (error) => server.config.logger.error(`${copy_error_prefix}: ${toErrorMessage(error)}`)
100
+ });
101
+ const reload = debounce(refresh, 150);
102
+ /**
103
+ * 문서와 소스 변경 시 스냅샷 갱신, 기존 CSS 수정은 Vite HMR 사용
104
+ */
105
+ const handleChange = (event, file) => {
106
+ const documentPath = relative(root, file);
107
+ const segments = documentPath.split(sep);
108
+ const isDocument = documentPath !== ".." && !isAbsolute(documentPath) && !documentPath.startsWith(`..${sep}`) && !segments.some((part) => [
109
+ "dist",
110
+ "node_modules",
111
+ ".git",
112
+ ".cache"
113
+ ].includes(part));
114
+ const extension = extname(file);
115
+ const isSource = params.source && file.startsWith(`${join(kitRoot, "src")}${sep}`) && ([".ts", ".tsx"].includes(extension) || extension === ".css" && event !== "change");
116
+ if (ready === void 0 || !isDocument && !isSource || config_file_names.some((name) => documentPath === name)) return;
117
+ state.generation += 1;
118
+ reload();
119
+ };
120
+ server.watcher.add(root);
121
+ server.watcher.on("all", handleChange);
122
+ dispose = () => {
123
+ state.closed = true;
124
+ reload.cancel();
125
+ server.watcher.off("all", handleChange);
126
+ };
127
+ prepare = refresh;
128
+ },
129
+ closeBundle: () => dispose?.()
130
+ }, devServer({
131
+ exclude: params.source ? [
132
+ ...viteClientPaths,
133
+ /^\/@id\//,
134
+ /^\/node_modules\/\.vite\//,
135
+ /^\/@fs\//,
136
+ /^\/src\/(component|page|style|store|constant|type|util)\//,
137
+ /^\/src\/entry\/browser\//
138
+ ] : viteClientPaths,
139
+ ignoreWatching: dev_ignored_paths,
140
+ handleHotUpdate: (context) => context.file.endsWith(".css") ? void 0 : [],
141
+ loadModule: async () => {
142
+ ready ??= prepare?.();
143
+ await ready;
144
+ if (currentSite === void 0) throw new Error("문서 준비에 실패했습니다. 위 오류를 수정하면 다시 반영합니다.");
145
+ const app = currentSite.app;
146
+ return { fetch: async (request, env) => app.fetch(request, env) };
147
+ }
148
+ })]
149
+ };
150
+ };
151
+ //#endregion
152
+ //#region src/entry/dev/start-dev-server.ts
153
+ /**
154
+ * 개발 서버 시작과 프로세스 종료 시 파일 감시, 통신 정리
155
+ */
156
+ var startDevServer = async (params) => {
157
+ const server = await createServer(toDevConfig(params));
158
+ try {
159
+ await server.listen();
160
+ server.printUrls();
161
+ } catch (error) {
162
+ await server.close();
163
+ throw error;
164
+ }
165
+ /**
166
+ * 실행기 종료 신호에서 Vite 자원 해제 후 종료
167
+ */
168
+ const handleExit = async () => {
169
+ await server.close();
170
+ process.exit(0);
171
+ };
172
+ process.once("SIGINT", handleExit);
173
+ process.once("SIGTERM", handleExit);
174
+ };
175
+ //#endregion
176
+ export { startDevServer };
@@ -0,0 +1,34 @@
1
+ //#region src/util/async/to-change-queue.ts
2
+ /**
3
+ * 변경 요청의 직렬 처리, 실행 중 요청은 다음 1회로 병합
4
+ *
5
+ * - 활성 실행의 반환 Promise는 대기 요청까지 끝나면 완료, 중첩 요청은 즉시 반환
6
+ */
7
+ var toChangeQueue = (options) => {
8
+ const state = {
9
+ requested: 0,
10
+ completed: 0,
11
+ running: false
12
+ };
13
+ return async () => {
14
+ state.requested += 1;
15
+ if (state.running) return;
16
+ state.running = true;
17
+ try {
18
+ while (state.completed !== state.requested) {
19
+ const requested = state.requested;
20
+ try {
21
+ await options.run();
22
+ } catch (error) {
23
+ options.onError(error);
24
+ } finally {
25
+ state.completed = requested;
26
+ }
27
+ }
28
+ } finally {
29
+ state.running = false;
30
+ }
31
+ };
32
+ };
33
+ //#endregion
34
+ export { toChangeQueue as t };
@@ -0,0 +1,16 @@
1
+ //#region src/app/_constant/config.ts
2
+ /**
3
+ * 문서 루트에서 지원하는 설정 파일, 둘 이상 존재하면 오류
4
+ */
5
+ var config_file_names = ["for-humanity.config.ts", "for-humanity.config.mjs"];
6
+ //#endregion
7
+ //#region src/util/error/to-error-message.ts
8
+ /**
9
+ * CLI, dev 공통 오류 문구. 문법 오류의 파일과 줄 번호 포함
10
+ */
11
+ var toErrorMessage = (error) => {
12
+ if (error instanceof Error && "file" in error && typeof error.file === "string" && "line" in error && typeof error.line === "number") return `${error.file}:${error.line}: ${error.message}`;
13
+ return error instanceof Error ? error.message : String(error);
14
+ };
15
+ //#endregion
16
+ export { config_file_names as n, toErrorMessage as t };
@@ -0,0 +1,7 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * 탐색 묶음 경로. 기존 단일 이름과 중첩 배열을 한 번만 정규화
4
+ *
5
+ * - 쉼표, 슬래시는 이름 그대로 유지하며 빈 경로, 단계는 거부
6
+ */
7
+ export declare const groupPathSchema: z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<string[], string | string[]>>;
@@ -0,0 +1,57 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * 사이트 설정의 입력 검증과 기본값 적용
4
+ */
5
+ export declare const siteConfigSchema: z.ZodObject<{
6
+ title: z.ZodDefault<z.ZodString>;
7
+ description: z.ZodOptional<z.ZodString>;
8
+ url: z.ZodOptional<z.ZodPipe<z.ZodPipe<z.ZodURL, z.ZodTransform<URL, string>>, z.ZodTransform<string, URL>>>;
9
+ port: z.ZodDefault<z.ZodInt>;
10
+ cursorFace: z.ZodDefault<z.ZodBoolean>;
11
+ navigation: z.ZodDefault<z.ZodArray<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<string[], string | string[]>>>>;
12
+ status: z.ZodDefault<z.ZodArray<z.ZodObject<{
13
+ phrase: z.ZodString;
14
+ kind: z.ZodEnum<{
15
+ readonly verified: "verified";
16
+ readonly unverified: "unverified";
17
+ }>;
18
+ date: z.ZodOptional<z.ZodBoolean>;
19
+ }, z.core.$strip>>>;
20
+ }, z.core.$strip>;
21
+ /**
22
+ * 기본값을 적용한 사이트 설정
23
+ */
24
+ export type ResolvedSiteConfig = z.infer<typeof siteConfigSchema>;
25
+ /**
26
+ * 작성자가 지정하는 사이트 설정, 기본값 적용 전 입력
27
+ */
28
+ export interface SiteConfig {
29
+ /**
30
+ * 사이드바 이름과 탭 제목, 생략 시 for humanity
31
+ */
32
+ title?: z.input<typeof siteConfigSchema>["title"];
33
+ /**
34
+ * 검색 결과에 표시할 사이트 설명
35
+ */
36
+ description?: z.input<typeof siteConfigSchema>["description"];
37
+ /**
38
+ * 공개 HTTP(S) 루트 주소, 지정 시 robots.txt와 sitemap.xml 생성
39
+ */
40
+ url?: z.input<typeof siteConfigSchema>["url"];
41
+ /**
42
+ * dev와 preview 포트, 1부터 65535까지 정수, 기본값 4321
43
+ */
44
+ port?: z.input<typeof siteConfigSchema>["port"];
45
+ /**
46
+ * 데스크톱 커서 얼굴 표시, 기본값 false
47
+ */
48
+ cursorFace?: z.input<typeof siteConfigSchema>["cursorFace"];
49
+ /**
50
+ * 탐색 묶음의 표시 순서, 문자열 또는 중첩 이름 경로
51
+ */
52
+ navigation?: z.input<typeof siteConfigSchema>["navigation"];
53
+ /**
54
+ * 상태 표지 목록, 빈 배열 지정 시 상태 표지 미표시
55
+ */
56
+ status?: z.input<typeof siteConfigSchema>["status"];
57
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "for-humanity",
3
- "version": "0.12.0",
4
- "description": "Documents written for humans to read: a docs kit with a sidebar, parts, sections and flowcharts, built on Hono JSX",
3
+ "version": "0.13.0",
4
+ "description": "Documents written for humans to read: a docs kit with a sidebar, parts, sections and Mermaid diagrams, built on Hono JSX",
5
5
  "keywords": [
6
6
  "docs",
7
7
  "documentation",
@@ -26,22 +26,25 @@
26
26
  },
27
27
  "files": [
28
28
  "dist",
29
- "src",
29
+ "src/asset",
30
30
  "CHANGELOG.md"
31
31
  ],
32
32
  "engines": {
33
- "node": ">=22"
33
+ "node": ">=22.12.0"
34
34
  },
35
35
  "scripts": {
36
- "build:kit": "node script/build-kit.mjs",
37
- "sync:readme": "node util/sync-readme.mjs",
38
- "sync:docs": "pnpm sync:readme && node util/sync-changelog.mjs",
39
- "dev": "pnpm sync:docs && pnpm build:kit && node dist/cli.js dev templates/document",
36
+ "build:kit": "vite build --mode node && vite build --mode browser && vite build --mode mermaid && tsc -p tsconfig.package.json",
37
+ "sync:readme": "tsx util/sync-readme.ts",
38
+ "sync:docs": "pnpm sync:readme && tsx util/sync-changelog.ts",
39
+ "dev": "pnpm sync:docs && pnpm build:kit && tsx src/entry/dev/dev.ts",
40
40
  "build": "pnpm sync:docs && pnpm build:kit && node dist/cli.js build templates/document",
41
- "build:pages": "pnpm build && node util/prepare-pages.mjs",
41
+ "build:pages": "pnpm build && tsx util/prepare-pages.ts",
42
42
  "preview": "node dist/cli.js preview templates/document",
43
- "test": "node script/test.mjs",
44
- "test:navigation": "pnpm build:kit && node util/navigation/check-navigation.test.mjs",
43
+ "test": "pnpm build:kit && vitest run",
44
+ "test:watch": "pnpm build:kit && vitest",
45
+ "test:browser": "pnpm build:kit && playwright test",
46
+ "test:navigation": "pnpm build:kit && playwright test navigation",
47
+ "test:mermaid": "pnpm build:kit && playwright test mermaid",
45
48
  "lint": "biome check && stylelint \"src/**/*.css\"",
46
49
  "lint:fix": "biome check --write && stylelint \"src/**/*.css\" --fix",
47
50
  "typecheck": "tsc --noEmit",
@@ -49,15 +52,17 @@
49
52
  "prepack": "pnpm build:kit"
50
53
  },
51
54
  "dependencies": {
52
- "@hono/node-server": "^2.1.3",
55
+ "@hono/vite-dev-server": "^0.26.1",
53
56
  "@shikijs/rehype": "^4.4.3",
54
57
  "@shikijs/transformers": "4.4.3",
55
- "beautiful-mermaid": "^1.1.3",
58
+ "citty": "^0.2.2",
56
59
  "clsx": "^2.1.1",
60
+ "consola": "^3.4.2",
57
61
  "es-toolkit": "^1.52.0",
58
62
  "github-slugger": "^2.0.0",
59
63
  "hast-util-to-string": "3.0.1",
60
64
  "hono": "^4.13.12",
65
+ "jiti": "^2.7.0",
61
66
  "mdast-util-find-and-replace": "^3.0.2",
62
67
  "mdast-util-to-string": "^4.0.0",
63
68
  "rehype-raw": "^7.0.0",
@@ -69,24 +74,36 @@
69
74
  "remark-rehype": "^11.1.2",
70
75
  "remark-smartypants": "^3.0.3",
71
76
  "shiki": "4.4.3",
77
+ "unhead": "^3.4.3",
72
78
  "unified": "^11.0.5",
73
79
  "unist-util-visit": "^5.1.0",
74
80
  "vfile": "^6.0.3",
81
+ "vite": "^8.3.4",
75
82
  "yaml": "^2.9.1",
76
83
  "zod": "^4.6.5",
77
84
  "zustand": "^5.0.15"
78
85
  },
79
86
  "devDependencies": {
80
87
  "@biomejs/biome": "^2.5.14",
88
+ "@playwright/test": "1.63.0",
81
89
  "@types/hast": "^3.0.5",
82
90
  "@types/mdast": "^4.0.4",
83
91
  "@types/node": "^26.6.3",
84
- "esbuild": "^0.28.2",
85
92
  "mdast-util-to-hast": "^13.2.1",
86
- "playwright": "^1.63.0",
93
+ "mermaid": "12.2.0",
87
94
  "stylelint": "^17.15.0",
88
95
  "stylelint-config-standard": "^40.0.0",
89
- "typescript": "^7.0.2"
96
+ "tsx": "^4.23.15",
97
+ "typescript": "^7.0.2",
98
+ "vitest": "^5.0.4"
90
99
  },
91
- "packageManager": "pnpm@12.9.1+sha512.06b055fff5cd20dc12781de173ced3310ce0951bf2ec620211a16045d5444d5c93a663210764ef29a653a610459ba0368f0e74f84d80c54723cf95aae7bc0d6d"
100
+ "packageManager": "pnpm@12.9.1+sha512.06b055fff5cd20dc12781de173ced3310ce0951bf2ec620211a16045d5444d5c93a663210764ef29a653a610459ba0368f0e74f84d80c54723cf95aae7bc0d6d",
101
+ "types": "./dist/type/site-config.d.ts",
102
+ "exports": {
103
+ ".": {
104
+ "types": "./dist/type/site-config.d.ts",
105
+ "import": "./dist/config.js"
106
+ },
107
+ "./*": "./*"
108
+ }
92
109
  }
@@ -1,14 +0,0 @@
1
- /**
2
- * 얼굴이 클릭 지점과 겹치지 않는 거리 · 화면 가장자리에도 같은 여백 적용
3
- */
4
- export const cursor_face_offset_px = 16;
5
-
6
- /**
7
- * 포인터 얼굴의 고정 표시 크기 · 좌표 계산과 SSR에서 같은 값 사용
8
- */
9
- export const cursor_face_size_px = 24;
10
-
11
- /**
12
- * 같은 탭의 문서 이동에서 커서 위치를 한 번 이어받는 저장소 키
13
- */
14
- export const cursor_face_storage_key = "fh-cursor-face";
@@ -1,15 +0,0 @@
1
- .wg_cursorFace__root {
2
- /* 뷰포트 기준 · 본문 흐름과 포인터 입력에 참여하지 않는 장식 */
3
- position: fixed;
4
- top: 0;
5
- left: 0;
6
- z-index: var(--app-z-index-popper);
7
- visibility: hidden;
8
- pointer-events: none;
9
- user-select: none;
10
- image-rendering: pixelated;
11
- }
12
-
13
- .wg_cursorFace__root--visible {
14
- visibility: visible;
15
- }