Skip to content

Commit 60cc613

Browse files
authored
Merge pull request #62 from TypingMind/plugin-word-generator
Add plugin word generator
2 parents b6ce768 + 2dfbe2d commit 60cc613

File tree

6 files changed

+831
-0
lines changed

6 files changed

+831
-0
lines changed

package-lock.json

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

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"body-parser": "^1.20.2",
2626
"cheerio": "^1.0.0-rc.12",
2727
"cors": "^2.8.5",
28+
"docx": "^9.1.0",
2829
"dotenv": "^16.4.5",
2930
"envalid": "^8.0.0",
3031
"express": "^4.19.2",

src/api-docs/openAPIDocumentGenerator.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { OpenApiGeneratorV3, OpenAPIRegistry } from '@asteasolutions/zod-to-open
33
import { articleReaderRegistry } from '@/routes/articleReader/articleReaderRouter';
44
import { healthCheckRegistry } from '@/routes/healthCheck/healthCheckRouter';
55
import { powerpointGeneratorRegistry } from '@/routes/powerpointGenerator/powerpointGeneratorRouter';
6+
import { wordGeneratorRegistry } from '@/routes/wordGenerator/wordGeneratorRouter';
67
import { transcriptRegistry } from '@/routes/youtubeTranscript/transcriptRouter';
78

89
export function generateOpenAPIDocument() {
@@ -11,6 +12,7 @@ export function generateOpenAPIDocument() {
1112
transcriptRegistry,
1213
articleReaderRegistry,
1314
powerpointGeneratorRegistry,
15+
wordGeneratorRegistry,
1416
]);
1517
const generator = new OpenApiGeneratorV3(registry.definitions);
1618

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
2+
import { z } from 'zod';
3+
4+
extendZodWithOpenApi(z);
5+
6+
// Define Word Generator Response Schema
7+
export type WordGeneratorResponse = z.infer<typeof WordGeneratorResponseSchema>;
8+
export const WordGeneratorResponseSchema = z.object({
9+
filepath: z.string().openapi({
10+
description: 'The file path where the generated Word document is saved.',
11+
}),
12+
});
13+
14+
// Define Cell Schema
15+
const CellSchema = z.object({
16+
text: z.string().optional().openapi({
17+
description: 'Text content within a cell.',
18+
}),
19+
});
20+
21+
// Define Row Schema
22+
const RowSchema = z.object({
23+
cells: z.array(CellSchema).optional().openapi({
24+
description: 'Array of cells within a row.',
25+
}),
26+
});
27+
28+
// Define Content Schema
29+
const ContentSchema = z.object({
30+
type: z.enum(['paragraph', 'listing', 'table', 'pageBreak', 'emptyLine']).openapi({
31+
description: 'Type of the content item.',
32+
}),
33+
text: z.string().optional().openapi({
34+
description: 'Text content for paragraphs or listings.',
35+
}),
36+
items: z.array(z.string()).optional().openapi({
37+
description: 'Items in a list for listing type content.',
38+
}),
39+
headers: z.array(z.string()).optional().openapi({
40+
description: 'Headers for table content.',
41+
}),
42+
rows: z.array(RowSchema).optional().openapi({
43+
description: 'Rows for table content.',
44+
}),
45+
});
46+
47+
// Define the base schema for a section
48+
const BaseSectionSchema = z.object({
49+
heading: z.string().optional().openapi({
50+
description: 'Heading of the section.',
51+
}),
52+
headingLevel: z.number().int().min(1).optional().openapi({
53+
description: 'Level of the heading (e.g., 1 for main heading, 2 for subheading).',
54+
}),
55+
content: z.array(ContentSchema).optional().openapi({
56+
description: 'Content contained within the section, including paragraphs, tables, etc.',
57+
}),
58+
});
59+
60+
// Extend the base schema with subSections
61+
const SectionSchema = BaseSectionSchema.extend({
62+
subSections: z.array(BaseSectionSchema).optional().openapi({
63+
description: 'Subsections within the main section.',
64+
}),
65+
});
66+
67+
// Request Body Schema
68+
export const WordGeneratorRequestBodySchema = z.object({
69+
title: z.string().openapi({
70+
description: 'Title of the document.',
71+
}),
72+
header: z.object({
73+
text: z.string().openapi({
74+
description: 'Text content for the header.',
75+
}),
76+
alignment: z.enum(['left', 'center', 'right']).default('left').openapi({
77+
description: 'Alignment of the header text.',
78+
}),
79+
}),
80+
footer: z.object({
81+
text: z.string().openapi({
82+
description: 'Text content for the footer.',
83+
}),
84+
alignment: z.enum(['left', 'center', 'right']).default('left').openapi({
85+
description: 'Alignment of the footer text.',
86+
}),
87+
}),
88+
sections: z.array(SectionSchema).openapi({
89+
description: 'Sections of the document, which may include sub-sections.',
90+
}),
91+
wordConfig: z
92+
.object({
93+
fontSize: z.number().default(12).openapi({
94+
description: 'Font size for the slides, default is 12 pt.',
95+
}),
96+
lineHeight: z.enum(['1', '1.15', '1.25', '1.5', '2']).default('1').openapi({
97+
description: 'Line height for text content.',
98+
}),
99+
fontFamily: z
100+
.enum(['Arial', 'Calibri', 'Times New Roman', 'Courier New', 'Verdana', 'Tahoma', 'Georgia', 'Comic Sans MS'])
101+
.default('Arial')
102+
.openapi({
103+
description: 'Font family for the slides, default is Arial.',
104+
}),
105+
showPageNumber: z.boolean().default(false).openapi({
106+
description: 'Option to display page numbers in the document.',
107+
}),
108+
showTableOfContent: z.boolean().default(false).openapi({
109+
description: 'Option to display a table of contents.',
110+
}),
111+
showNumberingInHeader: z.boolean().default(false).openapi({
112+
description: 'Option to display numbering in the header.',
113+
}),
114+
numberingReference: z
115+
.enum([
116+
'1.1.1.1 (Decimal)',
117+
'I.1.a.i (Roman -> Decimal > Lower Letter -> Lower Roman)',
118+
'I.A.1.a (Roman -> Upper Letter -> Decimal -> Lower Letter)',
119+
'1)a)i)(i) (Decimal -> Lower Letter -> Lower Roman -> Lower Roman with Parentheses)',
120+
'A.1.a.i (Upper Letter -> Decimal -> Lower Letter -> Lower Roman)',
121+
])
122+
.default('1.1.1.1 (Decimal)')
123+
.openapi({
124+
description: 'Set numbering hierarchy format for the document.',
125+
}),
126+
pageOrientation: z.enum(['portrait', 'landscape']).default('portrait').openapi({
127+
description: 'Set the page orientation for the document.',
128+
}),
129+
margins: z.enum(['normal', 'narrow', 'moderate', 'wide', 'mirrored']).default('normal').openapi({
130+
description: 'Set page margins for the document.',
131+
}),
132+
})
133+
.openapi({
134+
description: 'Word configuration settings for generating the document.',
135+
}),
136+
});
137+
138+
export type WordGeneratorRequestBody = z.infer<typeof WordGeneratorRequestBodySchema>;

0 commit comments

Comments
 (0)