@docxkit/plugin-cover-page 0.3.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-PRESENT ntnyq <https://github.com/ntnyq>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,12 @@
1
+ # @docxkit/plugin-cover-page
2
+
3
+ Cover page plugin for docx-kit.
4
+
5
+ ## Usage
6
+
7
+ ```ts
8
+ import { coverPagePlugin } from '@docxkit/plugin-cover-page'
9
+
10
+ builder.use(coverPagePlugin)
11
+ builder.coverPage({ title: 'Annual Report', subtitle: '2026' })
12
+ ```
@@ -0,0 +1,748 @@
1
+ import { AlignmentType } from "docx";
2
+
3
+ //#region ../../packages/types/dist/utility.d.ts
4
+ /** Hexadecimal CSS color string, e.g. `"#ff0000"`. */
5
+ type HexColor = `#${string}`;
6
+ /**
7
+ * A literal union type that still allows arbitrary string values.
8
+ * Useful for autocomplete-friendly APIs with extensible values.
9
+ *
10
+ * @template T — The literal subtype (e.g. `'Arial' | 'Calibri'`)
11
+ * @template U — The base type, defaults to `string`
12
+ */
13
+ type LiteralUnion<T extends U, U = string> = T | (U & {});
14
+ /**
15
+ * A value that might be synchronous or wrapped in a Promise.
16
+ *
17
+ * @template T — The inner value type
18
+ */
19
+ type MaybePromise<T> = Promise<T> | T;
20
+ /**
21
+ * Augments a base value type with theme token references.
22
+ *
23
+ * Lets users write `$colors.primary` in any style field that accepts the
24
+ * base type — the token is resolved at compile time against the document
25
+ * theme.
26
+ */
27
+ type StyleToken<T extends number | string> = T | ThemeToken;
28
+ /** Supported theme token categories (must match {@link resolveSingleToken}). */
29
+ type StyleTokenCategory = '$colors' | '$fonts' | '$fontSize' | '$spacing';
30
+ /**
31
+ * A `$category.key` reference to a theme token, e.g. `"$colors.primary"`,
32
+ * `"$fontSize.lg"`, `"$spacing.xl"`. Resolved at compile time by
33
+ * {@link resolveThemeTokens}.
34
+ */
35
+ type ThemeToken = `${StyleTokenCategory}.${string}`;
36
+ /**
37
+ * CSS-like length value.
38
+ *
39
+ * Supports bare numbers, explicit unit strings
40
+ * (`%`, `cm`, `in`, `mm`, `pt`, `px`), and theme token references
41
+ * (e.g. `"$spacing.lg"`, `"$fontSize.base"`).
42
+ *
43
+ * Bare-number conventions vary by context:
44
+ * - `fontSize` → interpreted as `pt`
45
+ * - spacing / indent → interpreted as `pt`
46
+ * - image size → interpreted as `px`
47
+ */
48
+ type UnitValue = `${number}%` | `${number}cm` | `${number}in` | `${number}mm` | `${number}pt` | `${number}px` | number | ThemeToken;
49
+ //#endregion
50
+ //#region ../../packages/types/dist/style.d.ts
51
+ /**
52
+ * A single border side descriptor.
53
+ *
54
+ * Follows the CSS `border` shorthand convention (style, width, color).
55
+ */
56
+ interface BorderRule {
57
+ /** Border color (e.g. `"#333"`, named color, or theme token like `"$colors.primary"`). */
58
+ color?: HexColor | StyleToken<string>;
59
+ /** Line style. */
60
+ style?: BorderStyle$1;
61
+ /** Line width (bare number treated as pt). */
62
+ width?: UnitValue;
63
+ }
64
+ /** Available border line styles. */
65
+ type BorderStyle$1 = 'dashed' | 'dotted' | 'double' | 'none' | 'single';
66
+ /**
67
+ * Table-cell level style properties.
68
+ *
69
+ * Used by {@link compileCellStyle} for `TableCell` construction.
70
+ */
71
+ interface CellStyleRule {
72
+ /** Background / shading color (hex, named, or theme token like `"$colors.info"`). */
73
+ backgroundColor?: HexColor | StyleToken<string>;
74
+ /** Shorthand border for all four sides. */
75
+ border?: BorderRule;
76
+ /** Bottom border override. */
77
+ borderBottom?: BorderRule;
78
+ /** Left border override. */
79
+ borderLeft?: BorderRule;
80
+ /** Right border override. */
81
+ borderRight?: BorderRule;
82
+ /** Top border override. */
83
+ borderTop?: BorderRule;
84
+ /** Element height. */
85
+ height?: UnitValue;
86
+ /** Bottom margin (cell padding). */
87
+ marginBottom?: UnitValue;
88
+ /** Left margin (cell padding). */
89
+ marginLeft?: UnitValue;
90
+ /** Right margin (cell padding). */
91
+ marginRight?: UnitValue;
92
+ /** Top margin (cell padding). */
93
+ marginTop?: UnitValue;
94
+ /** Vertical alignment (mostly for table cells). */
95
+ verticalAlign?: VerticalAlign;
96
+ /** Element width. */
97
+ width?: UnitValue;
98
+ /**
99
+ * CSS-like margin shorthand (used as cell padding).
100
+ */
101
+ margin?: `${string} ${string}` | `${string} ${string} ${string} ${string}` | UnitValue;
102
+ }
103
+ /**
104
+ * CSS-like style descriptor for a run, paragraph, cell, or table.
105
+ *
106
+ * Combines text, paragraph, and cell-level properties.
107
+ * This is the user-facing style type — individual compiler functions
108
+ * narrow to {@link TextStyleRule}, {@link ParagraphStyleRule}, or
109
+ * {@link CellStyleRule} as appropriate.
110
+ */
111
+ interface DocxStyleRule extends CellStyleRule, ParagraphStyleRule, TextStyleRule {}
112
+ /**
113
+ * Font weight: keyword `"bold"` / `"normal"`, or numeric 100–900
114
+ * following the CSS `font-weight` spec.
115
+ */
116
+ type FontWeight = 'bold' | 'normal' | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900;
117
+ /** Text highlight / marker colors (matches Word highlight palette). */
118
+ type HighlightColor = 'black' | 'blue' | 'cyan' | 'darkBlue' | 'darkCyan' | 'darkGray' | 'darkGreen' | 'darkMagenta' | 'darkRed' | 'darkYellow' | 'green' | 'lightGray' | 'magenta' | 'none' | 'red' | 'white' | 'yellow';
119
+ /**
120
+ * Paragraph-level style properties.
121
+ *
122
+ * Used by {@link compileParagraphStyle} for `Paragraph` construction.
123
+ */
124
+ interface ParagraphStyleRule {
125
+ /** Shorthand border for all four sides. */
126
+ border?: BorderRule;
127
+ /** Bottom border override. */
128
+ borderBottom?: BorderRule;
129
+ /** Left border override. */
130
+ borderLeft?: BorderRule;
131
+ /** Right border override. */
132
+ borderRight?: BorderRule;
133
+ /** Top border override. */
134
+ borderTop?: BorderRule;
135
+ /** Keep lines together on same page. */
136
+ keepLines?: boolean;
137
+ /** Keep this paragraph with the next one. */
138
+ keepNext?: boolean;
139
+ /** Line height multiplier or explicit unit value. */
140
+ lineHeight?: number | UnitValue;
141
+ /** Bottom margin. */
142
+ marginBottom?: UnitValue;
143
+ /** Left margin. */
144
+ marginLeft?: UnitValue;
145
+ /** Right margin. */
146
+ marginRight?: UnitValue;
147
+ /** Top margin. */
148
+ marginTop?: UnitValue;
149
+ /** Force page break before this paragraph. */
150
+ pageBreakBefore?: boolean;
151
+ /** Horizontal text alignment. */
152
+ textAlign?: TextAlign;
153
+ /** First-line indent. */
154
+ textIndent?: UnitValue;
155
+ /**
156
+ * CSS-like margin shorthand.
157
+ *
158
+ * Supports 1-value, 2-value, and 4-value string syntax
159
+ * (e.g. `"10pt"`, `"10pt 20pt"`, `"10pt 20pt 30pt 40pt"`).
160
+ */
161
+ margin?: `${string} ${string}` | `${string} ${string} ${string} ${string}` | UnitValue;
162
+ }
163
+ /**
164
+ * A map of class name → style rule.
165
+ *
166
+ * Used to define reusable named styles referenced via `className` on nodes.
167
+ *
168
+ * @example
169
+ * ```ts
170
+ * const styles = defineStyles({
171
+ * red: { color: '#ff0000' },
172
+ * big: { fontSize: 20 },
173
+ * })
174
+ * ```
175
+ */
176
+ type StyleSheet = Record<string, StyleSheetEntry>;
177
+ /**
178
+ * A single entry in the stylesheet.
179
+ *
180
+ * Extends {@link DocxStyleRule} with an optional `extends` property
181
+ * that allows style classes to inherit from other classes.
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * defineStyles({
186
+ * baseText: { fontFamily: 'Arial', fontSize: 12, color: '#333' },
187
+ * heading: { extends: 'baseText', fontSize: 20, fontWeight: 'bold' },
188
+ * muted: { extends: 'baseText', color: '#888' },
189
+ * })
190
+ * ```
191
+ */
192
+ interface StyleSheetEntry extends DocxStyleRule {
193
+ /** Inherit style properties from one or more other style classes. */
194
+ extends?: string | string[];
195
+ }
196
+ /** Horizontal text alignment. */
197
+ type TextAlign = 'center' | 'justify' | 'left' | 'right';
198
+ /**
199
+ * Text-level style properties (font, color, size, weight, etc.).
200
+ *
201
+ * Used by {@link compileTextStyle} for `TextRun` construction.
202
+ *
203
+ * @remarks
204
+ * Convenience boolean shortcuts `bold` and `italic` are provided
205
+ * alongside the canonical `fontWeight` / `fontStyle` properties.
206
+ * When `bold: true` is set, it is equivalent to `fontWeight: 'bold'`.
207
+ * When `italic: true` is set, it is equivalent to `fontStyle: 'italic'`.
208
+ */
209
+ interface TextStyleRule {
210
+ /** Force text to uppercase (small caps-like). */
211
+ allCaps?: boolean;
212
+ /** Background / shading color (hex, named, or theme token like `"$colors.info"`). */
213
+ backgroundColor?: HexColor | StyleToken<string>;
214
+ /**
215
+ * Convenience boolean: `true` maps to `fontWeight: 'bold'`.
216
+ * Takes precedence over `fontWeight` when both are set.
217
+ */
218
+ bold?: boolean;
219
+ /** Character spacing (letter-spacing). */
220
+ characterSpacing?: number;
221
+ /** Text / foreground color (hex, named, or theme token like `"$colors.primary"`). */
222
+ color?: HexColor | StyleToken<string>;
223
+ /**
224
+ * Direct passthrough to the underlying `docx` library constructor options.
225
+ * Use for properties not yet covered by the CSS-like mapping.
226
+ */
227
+ docx?: Record<string, unknown>;
228
+ /**
229
+ * Font family name (e.g. `"Arial"`, or theme token like `"$fonts.heading"`).
230
+ */
231
+ fontFamily?: StyleToken<LiteralUnion<'Arial' | 'Calibri' | 'Times New Roman'>>;
232
+ /** Font size (bare number = pt). */
233
+ fontSize?: UnitValue;
234
+ /** Italic toggle (canonical form). Use `italic?: boolean` for convenience. */
235
+ fontStyle?: 'italic' | 'normal';
236
+ /** Font weight: keyword `"bold"` / `"normal"` or numeric 100–900. */
237
+ fontWeight?: FontWeight;
238
+ /** Text highlight color (background marker). */
239
+ highlight?: HighlightColor;
240
+ /**
241
+ * Convenience boolean: `true` maps to `fontStyle: 'italic'`.
242
+ * Takes precedence over `fontStyle` when both are set.
243
+ */
244
+ italic?: boolean;
245
+ /** Character spacing. */
246
+ letterSpacing?: UnitValue;
247
+ /** Small caps text variant. */
248
+ smallCaps?: boolean;
249
+ /** Strikethrough toggle. */
250
+ strike?: boolean;
251
+ /** Sub-script text. */
252
+ subScript?: boolean;
253
+ /** Super-script text. */
254
+ superScript?: boolean;
255
+ /** Underline style. */
256
+ underline?: 'double' | 'single' | boolean;
257
+ }
258
+ /** Vertical alignment (for table cells). */
259
+ type VerticalAlign = 'bottom' | 'middle' | 'top';
260
+ //#endregion
261
+ //#region ../../packages/types/dist/dsl/nodes.d.ts
262
+ /**
263
+ * Common properties shared by all nodes.
264
+ *
265
+ * @template TStyles — The user's stylesheet type
266
+ */
267
+ interface BaseNode<TStyles extends StyleSheet = StyleSheet> {
268
+ /**
269
+ * CSS-like class name(s) referencing stylesheet entries.
270
+ *
271
+ * Can be a single string, an array, or a space-separated string.
272
+ */
273
+ className?: string | ClassName<TStyles> | ClassName<TStyles>[];
274
+ /** Optional unique identifier (for templating / references). */
275
+ id?: string;
276
+ /** Inline style override for this specific node. */
277
+ style?: DocxStyleRule;
278
+ }
279
+ /**
280
+ * Union of all top-level content node types.
281
+ *
282
+ * @template TStyles — The user's stylesheet type
283
+ */
284
+ type BlockNode<TStyles extends StyleSheet = StyleSheet> = BulletListNode<TStyles> | HeadingNode<TStyles> | HyperlinkNode<TStyles> | ImageNode<TStyles> | NumberedListNode<TStyles> | PageBreakNode | ParagraphNode<TStyles> | PluginNode<string, unknown, TStyles> | SectionBreakNode | TableNode<Record<string, unknown>, TStyles>;
285
+ /**
286
+ * A structured list item (for rich bullet/numbered items).
287
+ *
288
+ * @template TStyles — The user's stylesheet type
289
+ */
290
+ interface BulletItem<TStyles extends StyleSheet = StyleSheet> extends BaseNode<TStyles> {
291
+ /** Item text content. */
292
+ text: string;
293
+ /** Optional inline children override (instead of text). */
294
+ children?: InlineNode<TStyles>[];
295
+ }
296
+ /**
297
+ * A bullet list node.
298
+ *
299
+ * Supports plain string items or structured items with children.
300
+ *
301
+ * @template TStyles — The user's stylesheet type
302
+ */
303
+ interface BulletListNode<TStyles extends StyleSheet = StyleSheet> extends BaseNode<TStyles> {
304
+ /** List items — strings or structured items. */
305
+ items: (string | BulletItem<TStyles>)[];
306
+ type: 'bulletList';
307
+ /** Bullet character / style. Default: `'•'`. */
308
+ bullet?: string;
309
+ /** Nested list level (0 = top-level). */
310
+ level?: number;
311
+ }
312
+ /**
313
+ * Extract valid class name keys from a stylesheet type.
314
+ *
315
+ * @template TStyles — The user's stylesheet type
316
+ */
317
+ type ClassName<TStyles extends StyleSheet> = Extract<keyof TStyles, string>;
318
+ /**
319
+ * A heading node (h1–h6).
320
+ *
321
+ * @template TStyles — The user's stylesheet type
322
+ */
323
+ interface HeadingNode<TStyles extends StyleSheet = StyleSheet> extends BaseNode<TStyles> {
324
+ /** Heading level (1 = largest, 6 = smallest). */
325
+ level: 1 | 2 | 3 | 4 | 5 | 6;
326
+ /** Heading text content. */
327
+ text: string;
328
+ type: 'heading';
329
+ }
330
+ /**
331
+ * A hyperlink node (inline content that creates a clickable link).
332
+ *
333
+ * @template TStyles — The user's stylesheet type
334
+ */
335
+ interface HyperlinkNode<TStyles extends StyleSheet = StyleSheet> extends BaseNode<TStyles> {
336
+ /** Display text or inline children. */
337
+ children: (string | TextNode<TStyles>)[];
338
+ type: 'hyperlink';
339
+ /** Link target URL. */
340
+ url: string;
341
+ }
342
+ /**
343
+ * An image node.
344
+ *
345
+ * Supports raw bytes (`Uint8Array`, `ArrayBuffer`, `Blob`) or a file path string.
346
+ *
347
+ * @template TStyles — The user's stylesheet type
348
+ */
349
+ interface ImageNode<TStyles extends StyleSheet = StyleSheet> extends BaseNode<TStyles> {
350
+ /** Image data as bytes, blob, or file path. */
351
+ data: string | ArrayBuffer | Blob | Uint8Array;
352
+ type: 'image';
353
+ /** Alt text for accessibility. */
354
+ alt?: string;
355
+ /** Display height. */
356
+ height?: UnitValue;
357
+ /** Image format hint. Auto-detected if omitted. */
358
+ imageType?: 'bmp' | 'gif' | 'jpeg' | 'jpg' | 'png';
359
+ /** Display width. */
360
+ width?: UnitValue;
361
+ /**
362
+ * Floating layout configuration.
363
+ *
364
+ * - `true` enables default floating
365
+ * - Object allows wrap mode and position offsets
366
+ */
367
+ floating?: boolean | {
368
+ /** Text wrap mode. */wrap?: 'square' | 'tight' | 'topAndBottom'; /** Horizontal offset. */
369
+ x?: UnitValue; /** Vertical offset. */
370
+ y?: UnitValue;
371
+ };
372
+ }
373
+ /**
374
+ * Union of inline content node types (appear inside paragraphs).
375
+ *
376
+ * @template TStyles — The user's stylesheet type
377
+ */
378
+ type InlineNode<TStyles extends StyleSheet = StyleSheet> = HyperlinkNode<TStyles> | ImageNode<TStyles> | TextNode<TStyles>;
379
+ /**
380
+ * A numbered / ordered list node.
381
+ *
382
+ * @template TStyles — The user's stylesheet type
383
+ */
384
+ interface NumberedListNode<TStyles extends StyleSheet = StyleSheet> extends BaseNode<TStyles> {
385
+ /** List items. */
386
+ items: (string | BulletItem<TStyles>)[];
387
+ type: 'numberedList';
388
+ /** Nested list level (0 = top-level). */
389
+ level?: number;
390
+ /** Starting number (default: 1). */
391
+ start?: number;
392
+ /**
393
+ * Numbering format.
394
+ *
395
+ * {@link `LevelFormat.DECIMAL`} by default.
396
+ * e.g. `'decimal'`, `'upperRoman'`, `'lowerLetter'`
397
+ */
398
+ numberingFormat?: 'decimal' | 'lowerLetter' | 'lowerRoman' | 'upperLetter' | 'upperRoman';
399
+ }
400
+ /**
401
+ * A forced page break.
402
+ */
403
+ interface PageBreakNode {
404
+ type: 'pageBreak';
405
+ }
406
+ /**
407
+ * A paragraph containing text and/or inline children.
408
+ *
409
+ * @template TStyles — The user's stylesheet type
410
+ */
411
+ interface ParagraphNode<TStyles extends StyleSheet = StyleSheet> extends BaseNode<TStyles> {
412
+ type: 'paragraph';
413
+ /** Inline children (text runs, inline images, etc.). */
414
+ children?: InlineNode<TStyles>[];
415
+ /** Plain-text content (used when `children` is not provided). */
416
+ text?: string;
417
+ }
418
+ /**
419
+ * A plugin-invocation node.
420
+ *
421
+ * Plugins extend the DSL with arbitrary content types.
422
+ *
423
+ * @template TName — Plugin name (string literal)
424
+ * @template TOptions — Plugin-specific options shape
425
+ * @template TStyles — The user's stylesheet type
426
+ */
427
+ interface PluginNode<TName extends string = string, TOptions = unknown, TStyles extends StyleSheet = StyleSheet> extends BaseNode<TStyles> {
428
+ /** Registered plugin name. */
429
+ name: TName;
430
+ /** Plugin-specific options. */
431
+ options: TOptions;
432
+ type: 'plugin';
433
+ }
434
+ /**
435
+ * Internal marker node that represents a section boundary.
436
+ *
437
+ * Created automatically by {@link DocxBuilder.section} — users should
438
+ * not create this node directly.
439
+ *
440
+ * When the compiler encounters this marker, it starts a new section
441
+ * with the provided configuration.
442
+ */
443
+ interface SectionBreakNode {
444
+ type: 'sectionBreak';
445
+ /** Optional per-section page/header/footer overrides. */
446
+ config?: SectionConfig;
447
+ }
448
+ /**
449
+ * A column definition for a table.
450
+ *
451
+ * @template TData — The row data type
452
+ */
453
+ interface TableColumn<TData extends Record<string, unknown> = Record<string, unknown>> {
454
+ /** Key in the data object this column maps to. */
455
+ key: Extract<keyof TData, string>;
456
+ /** Column header text. */
457
+ title: string;
458
+ /** Cell text alignment. */
459
+ align?: 'center' | 'left' | 'right';
460
+ /**
461
+ * Span multiple columns horizontally.
462
+ *
463
+ * Applied to all cells in this column.
464
+ */
465
+ colSpan?: number;
466
+ /**
467
+ * Span multiple rows vertically (per-cell via data hints).
468
+ *
469
+ * Set `rowSpan` on individual data objects using `_rowSpan: N` or keep it
470
+ * as a static column default.
471
+ */
472
+ rowSpan?: number;
473
+ /** Column width. Supports percentage strings (e.g. `"30%"`). */
474
+ width?: UnitValue;
475
+ /**
476
+ * Custom cell renderer.
477
+ *
478
+ * Receives the raw value, full row data, and row index.
479
+ * Returns a string or inline nodes.
480
+ */
481
+ render?: (value: TData[keyof TData], row: TData, index: number) => string | InlineNode[];
482
+ }
483
+ /**
484
+ * A table node with column definitions and data rows.
485
+ *
486
+ * @template TData — The row data type
487
+ * @template TStyles — The user's stylesheet type
488
+ */
489
+ interface TableNode<TData extends Record<string, unknown> = Record<string, unknown>, TStyles extends StyleSheet = StyleSheet> extends BaseNode<TStyles> {
490
+ /** Column definitions. */
491
+ columns: TableColumn<TData>[];
492
+ /** Row data objects. */
493
+ data: TData[];
494
+ type: 'table';
495
+ /** Show table borders. */
496
+ bordered?: boolean;
497
+ /** Default cell style for data rows. */
498
+ cellStyle?: DocxStyleRule;
499
+ /** Show header row (default: `true`). */
500
+ header?: boolean;
501
+ /** Style for header cells. */
502
+ headerCellStyle?: DocxStyleRule;
503
+ /** Alternate row shading. */
504
+ striped?: boolean;
505
+ }
506
+ /**
507
+ * A text run node (inline content).
508
+ *
509
+ * @template TStyles — The user's stylesheet type
510
+ */
511
+ interface TextNode<TStyles extends StyleSheet = StyleSheet> extends BaseNode<TStyles> {
512
+ /** Text content. */
513
+ text: string;
514
+ type: 'text';
515
+ }
516
+ //#endregion
517
+ //#region ../../packages/types/dist/document.d.ts
518
+ /**
519
+ * Top-level configuration passed to `createDocx()`.
520
+ *
521
+ * Covers page setup, stylesheet, theme tokens, element defaults,
522
+ * and document metadata.
523
+ *
524
+ * @template TStyles — The user's stylesheet type (inferred from `styles`).
525
+ */
526
+ interface DocxKitConfig<TStyles extends StyleSheet = StyleSheet> {
527
+ /** Page dimensions and margins. */
528
+ page?: PageConfig;
529
+ /** Named style classes (class → style rule map). */
530
+ styles?: TStyles;
531
+ /** Semantic design tokens for theming. */
532
+ theme?: DocxTheme;
533
+ /** Default styles applied as base for each element type. */
534
+ defaults?: {
535
+ /** Default table cell style. */cell?: DocxStyleRule; /** Default image style (applied to the paragraph wrapping the image). */
536
+ image?: DocxStyleRule; /** Default paragraph style. */
537
+ paragraph?: DocxStyleRule; /** Default table style. */
538
+ table?: DocxStyleRule; /** Default text run style. */
539
+ text?: DocxStyleRule;
540
+ };
541
+ /** OOXML core properties (appear in File → Info). */
542
+ metadata?: {
543
+ /** Document author. */creator?: string; /** Document description / summary. */
544
+ description?: string; /** Keywords / tags. */
545
+ keywords?: string[]; /** Last editor. */
546
+ lastModifiedBy?: string; /** Document subject. */
547
+ subject?: string; /** Document title. */
548
+ title?: string;
549
+ };
550
+ }
551
+ /**
552
+ * Theme tokens that can be referenced in styles via `$category.key` syntax.
553
+ *
554
+ * Allows defining a single source of truth for colors, fonts,
555
+ * font sizes, and spacing values. Token references are resolved
556
+ * at compile time by {@link resolveThemeTokens}.
557
+ */
558
+ interface DocxTheme {
559
+ /** Color palette tokens (name → hex). */
560
+ colors?: ThemeColors;
561
+ /** Font family tokens (name → font family string). */
562
+ fonts?: ThemeFonts;
563
+ /** Font size tokens (name → value). */
564
+ fontSize?: Record<string, UnitValue>;
565
+ /** Spacing tokens (name → value). */
566
+ spacing?: ThemeSpacing;
567
+ }
568
+ /**
569
+ * Header/footer configuration for a section.
570
+ *
571
+ * Supports standard, first-page, and even-page variants.
572
+ */
573
+ interface HeaderFooterConfig {
574
+ /** Default header/footer (appears on all pages). */
575
+ default?: HeaderFooterContent;
576
+ /** Even-page header/footer (overrides default on even pages). */
577
+ even?: HeaderFooterContent;
578
+ /** First-page-only header/footer (overrides default on page 1). */
579
+ first?: HeaderFooterContent;
580
+ }
581
+ /**
582
+ * Content for a header or footer.
583
+ *
584
+ * Supports both simple text strings (backward compatible, each maps to a `Paragraph`)
585
+ * and full {@link BlockNode} elements (paragraphs, images, tables, etc.).
586
+ */
587
+ interface HeaderFooterContent {
588
+ /** Content items — strings (simple) or BlockNode objects (rich). */
589
+ children: (string | BlockNode)[];
590
+ }
591
+ /** Page orientation. */
592
+ type Orientation = 'landscape' | 'portrait';
593
+ /**
594
+ * Page configuration (size, orientation, margin).
595
+ */
596
+ interface PageConfig {
597
+ /** Page orientation (`"portrait"` default). */
598
+ orientation?: Orientation;
599
+ /** Page size: preset name or explicit dimensions. */
600
+ size?: PageSize | {
601
+ height: UnitValue;
602
+ width: UnitValue;
603
+ };
604
+ /**
605
+ * Page margin.
606
+ *
607
+ * Supports 1-value, 2-value, and 4-value shorthand
608
+ * (e.g. `"20mm"`, `"20mm 15mm"`, `"20mm 15mm 25mm 15mm"`).
609
+ */
610
+ margin?: `${string} ${string}` | `${string} ${string} ${string} ${string}` | UnitValue;
611
+ }
612
+ /** Available page size presets. */
613
+ type PageSize = 'A3' | 'A4' | 'Legal' | 'Letter';
614
+ /**
615
+ * Per-section configuration.
616
+ *
617
+ * Each call to `.section(config)` starts a new document section, which
618
+ * can have its own page setup, headers, and footers independent of other
619
+ * sections.
620
+ */
621
+ interface SectionConfig {
622
+ /** Section footer(s). */
623
+ footer?: HeaderFooterConfig;
624
+ /** Section header(s). */
625
+ header?: HeaderFooterConfig;
626
+ /** Section-specific page dimensions (overrides document-level `page`). */
627
+ page?: PageConfig;
628
+ }
629
+ /**
630
+ * Theme color palette — semantic color tokens referenced by name.
631
+ */
632
+ interface ThemeColors {
633
+ [name: string]: string;
634
+ }
635
+ /**
636
+ * Theme font tokens — semantic font family names.
637
+ */
638
+ interface ThemeFonts {
639
+ [name: string]: string;
640
+ }
641
+ /**
642
+ * Theme spacing tokens — named spacing values.
643
+ */
644
+ interface ThemeSpacing {
645
+ [name: string]: UnitValue;
646
+ }
647
+ //#endregion
648
+ //#region ../../packages/types/dist/plugin.d.ts
649
+ /**
650
+ * A docx-kit plugin.
651
+ *
652
+ * Plugins have a unique `name`, an optional `setup` hook,
653
+ * and a required `render` function that receives user options
654
+ * and a rendering context.
655
+ *
656
+ * @template TName — The plugin name (string literal type)
657
+ * @template TOptions — The shape of the user-provided options
658
+ * @template TRender — The render output type produced by the plugin
659
+ */
660
+ interface DocxPlugin<TName extends string = string, TOptions = unknown, TRender = unknown> {
661
+ /** Unique plugin name, used as the node discriminator. */
662
+ name: TName;
663
+ /** One-time setup called when the plugin is registered. */
664
+ setup?: () => MaybePromise<void>;
665
+ /**
666
+ * Render plugin content into one or more `docx` objects
667
+ * (Paragraph, Table, etc.).
668
+ *
669
+ * @param options - — User-provided plugin options
670
+ * @param context - — Rendering context with helper utilities
671
+ */
672
+ render: (options: TOptions, context: PluginRenderContext) => MaybePromise<TRender>;
673
+ }
674
+ /**
675
+ * Rendering context passed to a plugin's `render()` function.
676
+ *
677
+ * Provides access to the document config, image utilities,
678
+ * and the ability to compile child nodes.
679
+ */
680
+ interface PluginRenderContext {
681
+ /** The full document config. */
682
+ config: DocxKitConfig;
683
+ /** Compile a child node (useful for nesting). */
684
+ compileNode: (node: BlockNode) => Promise<unknown>;
685
+ /** Utility helpers. */
686
+ utils: {
687
+ image: {
688
+ /**
689
+ * Convert a Blob to raw image bytes.
690
+ *
691
+ * @param blob - The image data as a Blob
692
+ * @returns A promise that resolves to a Uint8Array of the image bytes
693
+ */
694
+ fromBlob: (blob: Blob) => Promise<Uint8Array>;
695
+ /**
696
+ * Decode a base64 data-URL to raw image bytes.
697
+ * Works in both browser and Node.js environments.
698
+ */
699
+ fromDataUrl: (dataUrl: string) => MaybePromise<Uint8Array>;
700
+ };
701
+ };
702
+ }
703
+ //#endregion
704
+ //#region src/index.d.ts
705
+ /** Options for the Cover Page plugin. */
706
+ interface CoverPageOptions {
707
+ /** Main title text (required). */
708
+ title: string;
709
+ /** Horizontal text alignment. @default CENTER */
710
+ alignment?: (typeof AlignmentType)[keyof typeof AlignmentType];
711
+ /** Author or department name. */
712
+ author?: string;
713
+ /** Background color of the cover page in hex RRGGBB. */
714
+ backgroundColor?: string;
715
+ /** Date string (e.g. "2026-06-11"). */
716
+ date?: string;
717
+ /** Organization / company name. */
718
+ organization?: string;
719
+ /**
720
+ * Show a decorative horizontal rule between title and author.
721
+ * @default true
722
+ */
723
+ showRule?: boolean;
724
+ /** Sub-title text displayed below the title. */
725
+ subtitle?: string;
726
+ }
727
+ /**
728
+ * Create a Cover Page plugin instance.
729
+ *
730
+ * @returns A configured DocxPlugin for `'coverPage'`
731
+ *
732
+ * @example
733
+ * ```ts
734
+ * import { coverPagePlugin, createDocx } from 'docx-kit'
735
+ *
736
+ * const doc = createDocx()
737
+ * .use(coverPagePlugin())
738
+ * .plugin('coverPage', {
739
+ * title: '年度报告',
740
+ * subtitle: '2026',
741
+ * author: '战略发展部',
742
+ * organization: 'XX 科技集团',
743
+ * })
744
+ * ```
745
+ */
746
+ declare function coverPagePlugin(): DocxPlugin<"coverPage", CoverPageOptions, unknown>;
747
+ //#endregion
748
+ export { CoverPageOptions, coverPagePlugin };
package/dist/index.js ADDED
@@ -0,0 +1,124 @@
1
+ import { definePlugin } from "@docxkit/core";
2
+ import { AlignmentType, BorderStyle, Paragraph, ShadingType, TextRun } from "docx";
3
+ //#region src/index.ts
4
+ /**
5
+ * Cover Page plugin — generates a professional title page.
6
+ *
7
+ * Renders a centered block with title, subtitle, author, date,
8
+ * organization, and an optional decorative horizontal rule.
9
+ *
10
+ * @module plugins/cover-page
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const doc = createDocx()
15
+ * .use(coverPagePlugin())
16
+ * .plugin('coverPage', {
17
+ * title: 'Q3 运营报告',
18
+ * subtitle: '数据驱动 · 智能决策',
19
+ * author: '数据分析部',
20
+ * })
21
+ * .save('report.docx')
22
+ * ```
23
+ */
24
+ /**
25
+ * Create a Cover Page plugin instance.
26
+ *
27
+ * @returns A configured DocxPlugin for `'coverPage'`
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * import { coverPagePlugin, createDocx } from 'docx-kit'
32
+ *
33
+ * const doc = createDocx()
34
+ * .use(coverPagePlugin())
35
+ * .plugin('coverPage', {
36
+ * title: '年度报告',
37
+ * subtitle: '2026',
38
+ * author: '战略发展部',
39
+ * organization: 'XX 科技集团',
40
+ * })
41
+ * ```
42
+ */
43
+ function coverPagePlugin() {
44
+ return definePlugin({
45
+ name: "coverPage",
46
+ render(options) {
47
+ const alignment = options.alignment ?? AlignmentType.CENTER;
48
+ const showRule = options.showRule !== false;
49
+ const titlePara = new Paragraph({
50
+ alignment,
51
+ spacing: { after: 200 },
52
+ children: [new TextRun({
53
+ bold: true,
54
+ font: "Arial",
55
+ size: 56,
56
+ text: options.title
57
+ })],
58
+ ...options.backgroundColor ? { shading: {
59
+ fill: options.backgroundColor,
60
+ type: ShadingType.CLEAR
61
+ } } : {}
62
+ });
63
+ return [
64
+ new Paragraph({
65
+ children: [],
66
+ spacing: { before: 2400 }
67
+ }),
68
+ titlePara,
69
+ ...options.subtitle ? [new Paragraph({
70
+ alignment,
71
+ spacing: { after: 400 },
72
+ children: [new TextRun({
73
+ color: "555555",
74
+ font: "Arial",
75
+ size: 32,
76
+ text: options.subtitle
77
+ })]
78
+ })] : [],
79
+ ...showRule ? [new Paragraph({
80
+ alignment,
81
+ children: [],
82
+ spacing: { after: 400 },
83
+ border: { bottom: {
84
+ color: "4472C4",
85
+ size: 6,
86
+ space: 1,
87
+ style: BorderStyle.SINGLE
88
+ } }
89
+ })] : [],
90
+ ...options.author ? [new Paragraph({
91
+ alignment,
92
+ spacing: { after: 120 },
93
+ children: [new TextRun({
94
+ font: "Arial",
95
+ size: 28,
96
+ text: options.author
97
+ })]
98
+ })] : [],
99
+ ...options.organization ? [new Paragraph({
100
+ alignment,
101
+ spacing: { after: 120 },
102
+ children: [new TextRun({
103
+ color: "333333",
104
+ font: "Arial",
105
+ size: 24,
106
+ text: options.organization
107
+ })]
108
+ })] : [],
109
+ ...options.date ? [new Paragraph({
110
+ alignment,
111
+ spacing: { after: 0 },
112
+ children: [new TextRun({
113
+ color: "777777",
114
+ font: "Arial",
115
+ size: 24,
116
+ text: options.date
117
+ })]
118
+ })] : []
119
+ ];
120
+ }
121
+ });
122
+ }
123
+ //#endregion
124
+ export { coverPagePlugin };
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "@docxkit/plugin-cover-page",
3
+ "type": "module",
4
+ "version": "0.3.0",
5
+ "description": "Professional cover/title page — docx-kit plugin",
6
+ "keywords": [
7
+ "docx",
8
+ "docx-kit",
9
+ "docx-kit-plugin"
10
+ ],
11
+ "license": "MIT",
12
+ "author": {
13
+ "name": "ntnyq",
14
+ "email": "ntnyq13@gmail.com"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/ntnyq/docx-kit",
19
+ "directory": "packages-plugins/cover-page"
20
+ },
21
+ "exports": {
22
+ ".": {
23
+ "types": "./dist/index.d.ts",
24
+ "default": "./dist/index.js"
25
+ }
26
+ },
27
+ "main": "./dist/index.js",
28
+ "types": "./dist/index.d.ts",
29
+ "files": [
30
+ "dist"
31
+ ],
32
+ "publishConfig": {
33
+ "access": "public"
34
+ },
35
+ "sideEffects": false,
36
+ "peerDependencies": {
37
+ "docx": "^9.7.1",
38
+ "@docxkit/core": "0.3.0"
39
+ },
40
+ "devDependencies": {
41
+ "@docxkit/pdk": "0.3.0"
42
+ },
43
+ "scripts": {
44
+ "build": "tsdown",
45
+ "dev": "tsdown --watch"
46
+ }
47
+ }