@godcreator/word-report 0.1.0 → 0.2.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.
package/README.md CHANGED
@@ -4,7 +4,6 @@
4
4
 
5
5
  文档站平台、按功能划分的功能包,以及两个 gwb 工作台插件。任何站点都是「fumadocs 官方 React Router 模板 + 挑选的功能包」:
6
6
  平台包 `@godcreator/god-docsite` 带唯一的站点模板与建站器,功能包各自经 fumadocs 与 React Router 原生的扩展点接入站点。
7
- 仓正在重构,设计未定,以代码和 `AGENTS.md` 为准。
8
7
 
9
8
  | 包(`packages/`) | 做什么 |
10
9
  | --- | --- |
@@ -46,7 +45,7 @@ pnpm doc:render # 只重新生成生成物
46
45
 
47
46
  ## 文档在哪
48
47
 
49
- `docs-site/` 是全仓唯一的文档站:总览、fumadocs 原理、写页面、Gitea 与 NAS、维护。轨迹卡在 `docs-site/trajectory/`。
48
+ `docs-site/` 是全仓唯一的文档站:总览、建站与写页面、包(一个包一页)、插件、Gitea 与 NAS、维护、背景(fumadocs 原理)。轨迹卡在 `docs-site/trajectory/`。
50
49
  随插件发布的说明书正本在 `docs-site/content/docs/outputs/skills/`,生成到 `plugins/docsite/skills/` 与 `plugins/collab/skills/`。
51
50
 
52
51
  **这份 README 与仓根 `CLAUDE.md` 是生成物**(正本在 `docs-site/content/docs/outputs/`),`AGENTS.md` 手写;改 mdx 正本再在 `docs-site/` 里 `pnpm doc:render`。
@@ -59,8 +58,8 @@ pnpm build # 按依赖序构建全部包、两个插件与各站
59
58
  pnpm check # 逐个包跑 check(typecheck、快的一级测试,有 lint 的再 lint),一分钟左右
60
59
  pnpm test:slow # 慢的一级测试(各包的 *.slow.test.ts:真建站、大量调 git 的),只在显式要求时跑,近三分钟
61
60
  pnpm test:deps # 包之间的依赖方向、包内分层、模块之间不许有环(规则在 tests/dependency-rules.cjs,要先 pnpm build)
62
- pnpm verify # 最终交付之前(推送、交给人验收、发版前):build → check → test:slow → test:deps → test:scaffold → test:e2e
63
- pnpm test:pack # 发版前再跑:把包打成 tarball 装进测试站的副本,跑同样的端到端检查
61
+ pnpm verify # 全量:build → check → test:slow → test:deps → test:scaffold → test:e2e;只在升共用依赖时跑,平时看改到了什么只跑相关的几项(见 AGENTS.md)
62
+ pnpm test:pack # 把包打成 tarball 装进测试站的副本,跑同样的端到端检查;改了包的 exports、files、依赖时跑
64
63
 
65
64
  cd docs-site
66
65
  pnpm doc
@@ -1,4 +1,5 @@
1
1
  import { r as AssemblyResult } from "./types-BYcLlSjZ.mjs";
2
+ import { CommentsAccess, PageThreadSummary } from "@godcreator/comments/site";
2
3
  //#region src/site/page-data.d.ts
3
4
  /** 报告列表里的一行:报告读不对时 problem 是原话,标题退回报告 id */
4
5
  type ReportSummary = {
@@ -24,16 +25,22 @@ type ReportTocItem = {
24
25
  url: string;
25
26
  depth: number;
26
27
  };
28
+ /** 报告页上的评论:归属这一页的评论串,以及本机身份能不能写 */
29
+ type ReportPageComments = {
30
+ threads: PageThreadSummary[];
31
+ access: CommentsAccess;
32
+ };
27
33
  type ReportPageData = {
28
34
  siteName: string;
29
35
  hrefBase: string;
30
36
  reportId: string;
31
37
  report: AssemblyResult;
32
38
  toc: ReportTocItem[];
39
+ comments: ReportPageComments;
33
40
  };
34
41
  /** 报告页地址 */
35
42
  declare const reportHrefOf: (hrefBase: string, reportId: string) => string;
36
43
  /** 报告里一张图的地址:组装后图的路径是 assets/<文档 id>/<文件名>,挂在报告页地址下面 */
37
44
  declare const reportAssetHrefOf: (hrefBase: string, reportId: string, compiledPath: string) => string;
38
45
  //#endregion
39
- export { reportAssetHrefOf as a, ReportTocItem as i, ReportPageData as n, reportHrefOf as o, ReportSummary as r, ReportListData as t };
46
+ export { ReportTocItem as a, ReportSummary as i, ReportPageComments as n, reportAssetHrefOf as o, ReportPageData as r, reportHrefOf as s, ReportListData as t };
@@ -0,0 +1,7 @@
1
+ //#region src/site/page-data.ts
2
+ /** 报告页地址 */
3
+ const reportHrefOf = (hrefBase, reportId) => `${hrefBase}/${reportId}`;
4
+ /** 报告里一张图的地址:组装后图的路径是 assets/<文档 id>/<文件名>,挂在报告页地址下面 */
5
+ const reportAssetHrefOf = (hrefBase, reportId, compiledPath) => `${reportHrefOf(hrefBase, reportId)}/${compiledPath}`;
6
+ //#endregion
7
+ export { reportHrefOf as n, reportAssetHrefOf as t };
@@ -1,10 +1,14 @@
1
- import { i as ReportTocItem, n as ReportPageData, r as ReportSummary, t as ReportListData } from "./page-data-UaiHPCZA.mjs";
1
+ import { a as ReportTocItem, i as ReportSummary, n as ReportPageComments, r as ReportPageData, t as ReportListData } from "./page-data-DIsywo6U.mjs";
2
2
  //#region src/site/loaders.server.d.ts
3
- /** 报告功能的站点信息:站点目录(报告在它的 reports/ 下)、站名、报告页的地址前缀 */
3
+ /**
4
+ * 报告功能的站点信息:站点目录(报告在它的 reports/ 下)、站名、报告页的地址前缀,
5
+ * 以及按评论归属键取一页评论的函数(报告页的归属键是它的地址,如 /reports/sample)
6
+ */
4
7
  type WordReportSite = {
5
8
  siteDir: string;
6
9
  siteName: string;
7
10
  hrefBase: string;
11
+ pageComments: (page: string) => ReportPageComments;
8
12
  };
9
13
  /** loader 用到的路由参数:报告页是 :report,图片再加 * */
10
14
  type ReportRouteArgs = {
@@ -17,4 +21,4 @@ declare function reportPageLoader({ params }: ReportRouteArgs, site: WordReportS
17
21
  /** 报告里的一张图:地址是组装后的路径 assets/<文档 id>/<文件名>,只给这份报告用到的图 */
18
22
  declare function reportAssetLoader({ params }: ReportRouteArgs, site: WordReportSite): Promise<Response>;
19
23
  //#endregion
20
- export { type ReportListData, type ReportPageData, ReportRouteArgs, type ReportSummary, type ReportTocItem, WordReportSite, reportAssetLoader, reportListLoader, reportPageLoader };
24
+ export { type ReportListData, type ReportPageComments, type ReportPageData, ReportRouteArgs, type ReportSummary, type ReportTocItem, WordReportSite, reportAssetLoader, reportListLoader, reportPageLoader };
@@ -1,5 +1,6 @@
1
1
  import { t as assembleDocument } from "./assemble-Czu-J7tB.mjs";
2
2
  import { i as reportIdsOf, n as readReportFiles, r as reportEntryOf, t as REPORT_ID_PATTERN } from "./report-files-DwLdh0QQ.mjs";
3
+ import { n as reportHrefOf } from "./page-data-DLPoVgXy.mjs";
3
4
  import path from "node:path";
4
5
  import { createReadStream } from "node:fs";
5
6
  import { Readable } from "node:stream";
@@ -78,7 +79,8 @@ async function reportPageLoader({ params }, site) {
78
79
  hrefBase: site.hrefBase,
79
80
  reportId,
80
81
  report: result,
81
- toc: tocOf(result)
82
+ toc: tocOf(result),
83
+ comments: site.pageComments(reportHrefOf(site.hrefBase, reportId))
82
84
  };
83
85
  }
84
86
  const imageContentTypes = {
package/dist/site.d.mts CHANGED
@@ -1,8 +1,17 @@
1
1
  import { g as ReportDocument, r as AssemblyResult } from "./types-BYcLlSjZ.mjs";
2
- import { a as reportAssetHrefOf, i as ReportTocItem, n as ReportPageData, o as reportHrefOf, r as ReportSummary, t as ReportListData } from "./page-data-UaiHPCZA.mjs";
2
+ import { a as ReportTocItem, i as ReportSummary, n as ReportPageComments, o as reportAssetHrefOf, r as ReportPageData, s as reportHrefOf, t as ReportListData } from "./page-data-DIsywo6U.mjs";
3
+ import { CommentAvatar, CommentBodyComponent } from "@godcreator/comments/site";
3
4
  //#region src/site/report-pages.d.ts
4
5
  declare function ReportListPage(): import("react").JSX.Element;
5
- declare function ReportDocumentPage(): import("react").JSX.Element;
6
+ interface ReportDocumentPageProps {
7
+ /** 评论表单提交到的地址:站点的评论写入路由(comments 功能的 /comments) */
8
+ commentAction: string;
9
+ /** 站点的评论正文组件与头像组件(站点 app/lib/content 里的 CommentBody、commentAvatar) */
10
+ CommentBody: CommentBodyComponent;
11
+ AvatarComponent?: CommentAvatar;
12
+ }
13
+ /** 报告页:正文是评论范围,右下角是本页评论;评论归属键是报告页的地址 */
14
+ declare function ReportDocumentPage({ commentAction, CommentBody, AvatarComponent }: ReportDocumentPageProps): import("react").JSX.Element;
6
15
  //#endregion
7
16
  //#region src/site/report-view.d.ts
8
17
  type AssetUrl = (sourcePath: string, compiledPath: string) => string;
@@ -29,4 +38,4 @@ declare function reportMeta(input: ReportDocument | AssemblyResult): {
29
38
  markdown: string;
30
39
  };
31
40
  //#endregion
32
- export { type AssetUrl, ReportDocumentPage, type ReportListData, ReportListPage, ReportPage, type ReportPageData, type ReportPageProps, type ReportSummary, type ReportTocItem, ReportView, type ReportViewProps, reportAssetHrefOf, reportHrefOf, reportMeta };
41
+ export { type AssetUrl, ReportDocumentPage, type ReportDocumentPageProps, type ReportListData, ReportListPage, ReportPage, type ReportPageComments, type ReportPageData, type ReportPageProps, type ReportSummary, type ReportTocItem, ReportView, type ReportViewProps, reportAssetHrefOf, reportHrefOf, reportMeta };
package/dist/site.mjs CHANGED
@@ -1,15 +1,11 @@
1
1
  import { t as assembleDocument } from "./assemble-Czu-J7tB.mjs";
2
+ import { n as reportHrefOf, t as reportAssetHrefOf } from "./page-data-DLPoVgXy.mjs";
2
3
  import { Link, useLoaderData } from "react-router";
3
4
  import { DocsBody, DocsPage, DocsTitle } from "@fumadocs/base-ui/layouts/docs/page";
5
+ import { CommentsDock, commentScopeProps } from "@godcreator/comments/site";
4
6
  import { Fragment } from "react";
5
7
  import katex from "katex";
6
8
  import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
7
- //#region src/site/page-data.ts
8
- /** 报告页地址 */
9
- const reportHrefOf = (hrefBase, reportId) => `${hrefBase}/${reportId}`;
10
- /** 报告里一张图的地址:组装后图的路径是 assets/<文档 id>/<文件名>,挂在报告页地址下面 */
11
- const reportAssetHrefOf = (hrefBase, reportId, compiledPath) => `${reportHrefOf(hrefBase, reportId)}/${compiledPath}`;
12
- //#endregion
13
9
  //#region src/site/report-view.tsx
14
10
  function RenderError({ children }) {
15
11
  return /* @__PURE__ */ jsx("div", {
@@ -340,15 +336,16 @@ function ReportListPage() {
340
336
  }) })
341
337
  ] });
342
338
  }
343
- function ReportDocumentPage() {
344
- const { report, toc, reportId, siteName, hrefBase } = useLoaderData();
339
+ /** 报告页:正文是评论范围,右下角是本页评论;评论归属键是报告页的地址 */
340
+ function ReportDocumentPage({ commentAction, CommentBody, AvatarComponent }) {
341
+ const { report, toc, reportId, siteName, hrefBase, comments } = useLoaderData();
345
342
  const { metadata } = report.document;
346
343
  const metaLine = [
347
344
  metadata.revision,
348
345
  metadata.date,
349
346
  metadata.authors?.join("、")
350
347
  ].filter((part) => part !== void 0 && part !== "");
351
- return /* @__PURE__ */ jsxs(DocsPage, {
348
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(DocsPage, {
352
349
  toc,
353
350
  children: [
354
351
  /* @__PURE__ */ jsx("title", { children: `${metadata.title} · ${siteName}` }),
@@ -362,12 +359,22 @@ function ReportDocumentPage() {
362
359
  to: hrefBase,
363
360
  children: "← 全部报告"
364
361
  }),
365
- /* @__PURE__ */ jsx(DocsBody, { children: /* @__PURE__ */ jsx(ReportView, {
366
- report,
367
- assetUrl: (_source, compiledPath) => reportAssetHrefOf(hrefBase, reportId, compiledPath)
368
- }) })
362
+ /* @__PURE__ */ jsx(DocsBody, {
363
+ ...commentScopeProps,
364
+ children: /* @__PURE__ */ jsx(ReportView, {
365
+ report,
366
+ assetUrl: (_source, compiledPath) => reportAssetHrefOf(hrefBase, reportId, compiledPath)
367
+ })
368
+ })
369
369
  ]
370
- });
370
+ }), /* @__PURE__ */ jsx(CommentsDock, {
371
+ pagePath: reportHrefOf(hrefBase, reportId),
372
+ action: commentAction,
373
+ threads: comments.threads,
374
+ access: comments.access,
375
+ BodyComponent: CommentBody,
376
+ ...AvatarComponent !== void 0 ? { AvatarComponent } : {}
377
+ })] });
371
378
  }
372
379
  //#endregion
373
380
  //#region src/site/report-meta.ts
package/engine/README.md CHANGED
@@ -13,16 +13,16 @@
13
13
  .\.venv\Scripts\python.exe -m unittest discover -s tests -v
14
14
  ```
15
15
 
16
- ## 报告包的数据入口
16
+ ## word-report 交给引擎的数据
17
17
 
18
- 网站只用于阅读和评论。`@godcreator/docsite-reports` 的 `report-docx` CLI 与 `./export` API 先把分章内容编译成完整 `format: docreport` / `schemaVersion: 1` 文档与 `assets/`,交给以下入口。它们不依赖 gwb。`--data-only` 必须传递;这个模式不导入快照目录中的 `report.py`。未展开的文档引用不会通过正式 Schema。
18
+ 网站只用于阅读和评论。`@godcreator/word-report` 的命令行 `report-docx` 与 `./node` 出口的 `reportExport` 先把分章内容编译成完整 `format: docreport` / `schemaVersion: 1` 文档与 `assets/`,交给以下入口。它们不依赖 gwb。`--data-only` 必须传递;这个模式不导入快照目录中的 `report.py`。未展开的文档引用不会通过正式 Schema。
19
19
 
20
20
  ```powershell
21
21
  .\.venv\Scripts\python.exe -m docreport validate <快照目录> --data-only
22
22
  .\.venv\Scripts\python.exe -m docreport build <快照目录> --data-only --out out\<新的运行目录>
23
23
  ```
24
24
 
25
- 需要版式数据时,可加 `--layout <layout.json>`,内容为已有 `validate_layout` 支持的节点 ID 字典:段落样式、图片宽度、表格列宽与行高、顶层章节起页与方向。默认采用 `templates/project-report.dotx`。报告包的 CLI/API 不接受任意 Python 布局程序。
25
+ 需要版式数据时,可加 `--layout <layout.json>`,内容为已有 `validate_layout` 支持的节点 ID 字典:段落样式、图片宽度、表格列宽与行高、顶层章节起页与方向。默认采用 `templates/project-report.dotx`。word-report 的命令行与 `reportExport` 不接受任意 Python 布局程序。
26
26
 
27
27
  已有 demo 保留其受信任的 `report.py` 与原入口,用于原有版式和专属验收回归:
28
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@godcreator/word-report",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "author": {
5
5
  "name": "godcreator"
6
6
  },
@@ -42,6 +42,7 @@
42
42
  "LICENSE"
43
43
  ],
44
44
  "dependencies": {
45
+ "@godcreator/comments": "^0.1.3",
45
46
  "sharp": "^0.35.5"
46
47
  },
47
48
  "peerDependencies": {
@@ -1,10 +1,12 @@
1
1
  import type { Route } from './+types/report'
2
2
  import { ReportDocumentPage } from '@godcreator/word-report/site'
3
3
  import { reportPageLoader } from '@godcreator/word-report/site/server'
4
+ import { commentAvatar, CommentBody } from '@/lib/content'
4
5
  import { wordReportSite } from './site.server'
5
6
 
6
7
  export const loader = (args: Route.LoaderArgs) => reportPageLoader(args, wordReportSite())
7
8
 
9
+ /** 评论写进站点的评论写入路由 /comments(comments 功能),和内容页一样 */
8
10
  export default function Report() {
9
- return <ReportDocumentPage />
11
+ return <ReportDocumentPage commentAction="/comments" CommentBody={CommentBody} AvatarComponent={commentAvatar} />
10
12
  }
@@ -2,7 +2,7 @@ import { relative, type RouteConfig } from '@react-router/dev/routes'
2
2
 
3
3
  const { route } = relative(import.meta.dirname)
4
4
 
5
- // 地址与 site.server.ts 的 reportHrefBase 一致;参数名 report、* 是 reportPageLoader、reportAssetLoader 读的
5
+ // 地址与 href.ts 的 reportHrefBase 一致;参数名 report、* 是 reportPageLoader、reportAssetLoader 读的
6
6
  export default [
7
7
  route('reports', './list.tsx'),
8
8
  route('reports/:report', './report.tsx'),
@@ -1,9 +1,19 @@
1
+ import { commentsAccessOf } from '@godcreator/comments/site'
2
+ import { pageThreadsOf } from '@godcreator/comments/site/server'
1
3
  import type { WordReportSite } from '@godcreator/word-report/site/server'
2
4
  import { site } from '@/lib/site.server'
3
5
  import { reportHrefBase } from './href'
4
6
 
5
- /** 报告功能的站点信息,每次请求现组装:报告在站点根下的 reports/,站名取页面树根(content/meta.json 的 title) */
7
+ /** 报告功能的站点信息,每次请求现组装:报告在站点根下的 reports/,站名取页面树根(content/meta.json 的 title),评论取站点的评论集合 */
6
8
  export function wordReportSite(): WordReportSite {
7
9
  const name = site.source.getPageTree().name
8
- return { siteDir: site.dir, siteName: typeof name === 'string' ? name : '', hrefBase: reportHrefBase }
10
+ return {
11
+ siteDir: site.dir,
12
+ siteName: typeof name === 'string' ? name : '',
13
+ hrefBase: reportHrefBase,
14
+ pageComments: (page) => ({
15
+ threads: pageThreadsOf({ entries: site.commentEntries, people: site.people(), page }),
16
+ access: commentsAccessOf(site.identity()),
17
+ }),
18
+ }
9
19
  }