Skip to content

Commit 60896ad

Browse files
committed
[add] Block transforming of Wiki Catalog & Task
[add] Document Rendering example
1 parent 58719d5 commit 60896ad

File tree

7 files changed

+174
-75
lines changed

7 files changed

+174
-75
lines changed

ReadMe.md

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Unofficial [TypeScript][1] SDK for [FeiShu/Lark API][2], which is based on [MobX
2323
- [BI Table example](https://idea2app.feishu.cn/wiki/Jzqbwv4biiY1Ckkqf95cS97Ynig)
2424
- [API document](https://idea2app.github.io/MobX-Lark/)
2525

26-
### 1. Initialization
26+
### 1. Initialize Lark app
2727

2828
#### User access token (front-end)
2929

@@ -64,7 +64,7 @@ export const larkApp = new LarkApp({
6464
});
6565
```
6666

67-
### 2. Defination
67+
### 2. Define a model
6868

6969
For example, we use a BI Table as a database:
7070

@@ -92,7 +92,7 @@ export class ClientModel extends BiDataTable<Client>() {
9292
}
9393
```
9494

95-
### 3. Querying
95+
### 3. Query data
9696

9797
Use Next.js page router for example:
9898

@@ -126,6 +126,27 @@ const ClientIndexPage: FC<{ fullList: Client[] }> = ({ fullList }) => (
126126
export default ClientIndexPage;
127127
```
128128

129+
### 4. Render a document
130+
131+
```ts
132+
import { writeFile } from 'fs/promises';
133+
import { DocumentModel, renderBlocks } from 'mobx-lark';
134+
import { renderToStaticMarkup } from 'react-dom/server';
135+
136+
import { lark } from '../utility/lark';
137+
138+
class MyDocumentModel extends DocumentModel {
139+
client = lark.client;
140+
}
141+
const documentStore = new MyDocumentModel('idea2app.feishu.cn');
142+
143+
const blocks = await documentStore.getOneBlocks('a_docx_token');
144+
145+
const markup = renderToStaticMarkup(renderBlocks(blocks));
146+
147+
await writeFile('document.html', markup);
148+
```
149+
129150
## Scaffolds
130151

131152
1. https://github.com/idea2app/Lark-Next-Bootstrap-ts

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"mobx": "^6.13.7",
3232
"mobx-restful": "^2.1.0",
3333
"regenerator-runtime": "^0.14.1",
34-
"web-utility": "^4.5.0"
34+
"web-utility": "^4.5.1"
3535
},
3636
"peerDependencies": {
3737
"react": ">=16"

pnpm-lock.yaml

Lines changed: 37 additions & 40 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/module/Document/index.ts

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { HTTPError } from 'koajax';
22
import { BaseListModel } from 'mobx-restful';
3-
import { cache } from 'web-utility';
3+
import { cache, formatDate, uniqueID } from 'web-utility';
44

55
import { isLarkError, LarkData } from '../../type';
66
import { createPageStream } from '../base';
7+
import { TaskModel } from '../Task';
78
import { User } from '../User/type';
9+
import { WikiNode, WikiNodeModel } from '../Wiki';
810
import {
911
BiTableBlock,
1012
Block,
@@ -14,10 +16,15 @@ import {
1416
IframeBlock,
1517
IframeComponentType,
1618
ImageBlock,
19+
OrderedBlock,
20+
QuoteContainerBlock,
1721
SheetBlock,
22+
SubPageList,
23+
TaskBlock,
1824
TextBlock,
1925
TextElement,
20-
TextRun
26+
TextRun,
27+
WikiCatalog
2128
} from './type';
2229

2330
export * from './type';
@@ -93,10 +100,33 @@ export abstract class DocumentModel extends BaseListModel<Document> {
93100
}
94101
}
95102

103+
async #getWikiSubDocuments(token: string) {
104+
const { client } = this;
105+
106+
class MyWikiNodeModel extends WikiNodeModel {
107+
client = client;
108+
}
109+
const { body } = await client.get<LarkData<{ node: WikiNode }>>(
110+
`wiki/v2/spaces/get_node?token=${token}`
111+
);
112+
const { space_id } = body!.data!.node;
113+
114+
const wikiNodeStore = new MyWikiNodeModel(this.domain, space_id);
115+
116+
return wikiNodeStore.getAll({ parent_node_token: token });
117+
}
118+
96119
async *#resolveBlocks(
97120
stream: AsyncIterable<Block<any, any, any>>,
98121
resolveFileURL?: FileURLResolver
99122
) {
123+
const { client } = this;
124+
125+
class MyTaskModel extends TaskModel {
126+
client = client;
127+
}
128+
const taskStore = new MyTaskModel();
129+
100130
for await (let block of stream) {
101131
if (block.block_type === BlockType.text) {
102132
const { text } = block as TextBlock;
@@ -135,6 +165,61 @@ export abstract class DocumentModel extends BaseListModel<Document> {
135165
`https://${this.domain}/base/${token}?table=${table}`
136166
);
137167
continue;
168+
} else if (
169+
block.block_type === BlockType.wiki_catalog ||
170+
block.block_type === BlockType.sub_page_list
171+
) {
172+
const parentBlock = {
173+
...block,
174+
block_type: BlockType.quote_container,
175+
quote_container: {},
176+
children: []
177+
} as QuoteContainerBlock;
178+
179+
yield parentBlock;
180+
181+
const { wiki_token } =
182+
'wiki_catalog' in block
183+
? (block as WikiCatalog).wiki_catalog
184+
: (block as SubPageList).sub_page_list;
185+
186+
for (const { title, node_token } of await this.#getWikiSubDocuments(wiki_token)) {
187+
const text_run = {
188+
content: title,
189+
text_element_style: {
190+
link: { url: `https://${this.domain}/wiki/${node_token}` }
191+
}
192+
} as TextRun;
193+
194+
const block_id = uniqueID();
195+
196+
yield {
197+
parent_id: parentBlock.block_id,
198+
block_id,
199+
block_type: BlockType.ordered,
200+
ordered: { elements: [{ text_run }] }
201+
} as OrderedBlock;
202+
203+
parentBlock.children!.push(block_id);
204+
}
205+
continue;
206+
} else if (block.block_type === BlockType.task) {
207+
const { task_id } = (block as TaskBlock).task;
208+
209+
const { url, summary, members, due, status } = await taskStore.getOne(task_id);
210+
const content = [
211+
summary,
212+
members.map(({ name }) => `@${name}`).join(' '),
213+
due && formatDate(due.timestamp)
214+
]
215+
.filter(Boolean)
216+
.join(' ');
217+
const newBlock = this.#createLinkBlock(block, url, content);
218+
219+
newBlock.text.style = { done: status === 'done' };
220+
221+
yield newBlock;
222+
continue;
138223
}
139224
yield block;
140225
}

src/module/Document/type/Document.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,7 @@ export type BiTableBlock = Block<
1616
'bitable',
1717
{ token: string; view_type: BiTableViewType }
1818
>;
19+
20+
export type WikiCatalog = Block<BlockType.wiki_catalog, 'wiki_catalog', { wiki_token: string }>;
21+
22+
export type SubPageList = Block<BlockType.sub_page_list, 'sub_page_list', { wiki_token: string }>;

0 commit comments

Comments
 (0)