@json-to-office/core-docx 0.1.1 → 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/dist/index.js +71 -132
- package/dist/index.js.map +1 -1
- package/dist/plugin/createComponent.d.ts +8 -106
- package/dist/plugin/createComponent.d.ts.map +1 -1
- package/dist/plugin/createDocumentGenerator.d.ts +3 -1
- package/dist/plugin/createDocumentGenerator.d.ts.map +1 -1
- package/dist/plugin/example/index.js +79 -131
- package/dist/plugin/example/index.js.map +1 -1
- package/dist/plugin/validation.d.ts +6 -22
- package/dist/plugin/validation.d.ts.map +1 -1
- package/dist/plugin/version-resolver.d.ts +1 -9
- package/dist/plugin/version-resolver.d.ts.map +1 -1
- package/dist/templates/themes/index.d.ts +4 -796
- package/dist/templates/themes/index.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -1,113 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { TSchema } from '@sinclair/typebox';
|
|
2
2
|
import type { ComponentDefinition } from '@json-to-office/shared-docx';
|
|
3
|
-
import type { AddWarningFunction } from '@json-to-office/shared-docx';
|
|
4
3
|
import type { ThemeConfig } from '../styles';
|
|
4
|
+
import type { RenderContext as SharedRenderContext, RenderFunction as SharedRenderFunction, ComponentVersion as SharedComponentVersion, ComponentVersionMap as SharedComponentVersionMap, CustomComponent as SharedCustomComponent } from '@json-to-office/shared/plugin';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*/
|
|
8
|
-
export interface RenderContext<T> {
|
|
9
|
-
/** The validated props for this component */
|
|
10
|
-
props: T;
|
|
11
|
-
/** The resolved theme configuration */
|
|
12
|
-
theme: ThemeConfig;
|
|
13
|
-
/** Function to add warnings during processing */
|
|
14
|
-
addWarning: AddWarningFunction;
|
|
15
|
-
/** For container components: processed nested children */
|
|
16
|
-
children?: unknown[];
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Render function that transforms custom component props into standard components.
|
|
20
|
-
*/
|
|
21
|
-
export type RenderFunction<TProps, TComponentDefinition = ComponentDefinition> = (context: RenderContext<TProps>) => Promise<TComponentDefinition[]>;
|
|
22
|
-
/**
|
|
23
|
-
* A single version entry within a versioned component.
|
|
24
|
-
* Each version is self-contained with its own schema, render, and metadata.
|
|
25
|
-
*/
|
|
26
|
-
export interface ComponentVersion<TComponentDefinition = ComponentDefinition, TPropsSchema extends TSchema = TSchema> {
|
|
27
|
-
/** TypeBox schema for props validation */
|
|
28
|
-
propsSchema: TPropsSchema;
|
|
29
|
-
/** Async render function to transform props into standard components */
|
|
30
|
-
render: RenderFunction<Static<TPropsSchema>, TComponentDefinition>;
|
|
31
|
-
/** Whether this version supports nested children */
|
|
32
|
-
hasChildren?: boolean;
|
|
33
|
-
/** Optional description for this version */
|
|
34
|
-
description?: string;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Map of semver version strings to their version definitions.
|
|
38
|
-
*/
|
|
39
|
-
export type ComponentVersionMap<TComponentDefinition = ComponentDefinition> = Record<string, ComponentVersion<TComponentDefinition, any>>;
|
|
40
|
-
/**
|
|
41
|
-
* Custom component definition with multiple semver-keyed versions.
|
|
42
|
-
* Each version is self-contained with its own schema + render.
|
|
43
|
-
*
|
|
44
|
-
* @typeParam TComponentDefinition - The component definition type for render return
|
|
45
|
-
* @typeParam TVersions - The versions map type
|
|
46
|
-
* @typeParam TName - The literal string type for the component name
|
|
47
|
-
*/
|
|
48
|
-
export interface CustomComponent<TComponentDefinition = ComponentDefinition, TVersions extends ComponentVersionMap<TComponentDefinition> = ComponentVersionMap<TComponentDefinition>, TName extends string = string> {
|
|
49
|
-
/** Unique name for the component type */
|
|
50
|
-
name: TName;
|
|
51
|
-
/** Map of semver version strings to version definitions */
|
|
52
|
-
versions: TVersions;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Create a single version entry with full type inference for props.
|
|
56
|
-
*
|
|
57
|
-
* Wrapping each version with `createVersion` lets TypeScript infer the
|
|
58
|
-
* props type from `propsSchema` and propagate it to the `render` function,
|
|
59
|
-
* so `props` is fully typed instead of `any`.
|
|
60
|
-
*
|
|
61
|
-
* @example
|
|
62
|
-
* ```typescript
|
|
63
|
-
* createVersion({
|
|
64
|
-
* propsSchema: Type.Object({ city: Type.String() }),
|
|
65
|
-
* render: async ({ props }) => {
|
|
66
|
-
* // props.city is inferred as string
|
|
67
|
-
* return [{ name: 'paragraph', props: { text: props.city } }];
|
|
68
|
-
* },
|
|
69
|
-
* })
|
|
70
|
-
* ```
|
|
6
|
+
* DOCX render context with ThemeConfig baked in
|
|
71
7
|
*/
|
|
8
|
+
export type RenderContext<T> = SharedRenderContext<T, ThemeConfig>;
|
|
9
|
+
export type RenderFunction<TProps, TComponentDefinition = ComponentDefinition> = SharedRenderFunction<TProps, TComponentDefinition, ThemeConfig>;
|
|
10
|
+
export type ComponentVersion<TComponentDefinition = ComponentDefinition, TPropsSchema extends TSchema = TSchema> = SharedComponentVersion<TComponentDefinition, TPropsSchema, ThemeConfig>;
|
|
11
|
+
export type ComponentVersionMap<TComponentDefinition = ComponentDefinition> = SharedComponentVersionMap<TComponentDefinition, ThemeConfig>;
|
|
12
|
+
export type CustomComponent<TComponentDefinition = ComponentDefinition, TVersions extends ComponentVersionMap<TComponentDefinition> = ComponentVersionMap<TComponentDefinition>, TName extends string = string> = SharedCustomComponent<TComponentDefinition, TVersions, TName>;
|
|
72
13
|
export declare function createVersion<TPropsSchema extends TSchema, TComponentDefinition = ComponentDefinition>(version: ComponentVersion<TComponentDefinition, TPropsSchema>): ComponentVersion<TComponentDefinition, TPropsSchema>;
|
|
73
|
-
/**
|
|
74
|
-
* Create a custom component with multiple semver-keyed versions.
|
|
75
|
-
*
|
|
76
|
-
* Use {@link createVersion} for each version entry to get full type inference
|
|
77
|
-
* for `props` in render functions.
|
|
78
|
-
*
|
|
79
|
-
* @example Basic single-version usage
|
|
80
|
-
* ```typescript
|
|
81
|
-
* const weatherComponent = createComponent({
|
|
82
|
-
* name: 'weather' as const,
|
|
83
|
-
* versions: {
|
|
84
|
-
* '1.0.0': createVersion({
|
|
85
|
-
* propsSchema: Type.Object({ city: Type.String() }),
|
|
86
|
-
* render: async ({ props }) => [{
|
|
87
|
-
* name: 'paragraph',
|
|
88
|
-
* props: { text: `Weather in ${props.city}` }
|
|
89
|
-
* }]
|
|
90
|
-
* })
|
|
91
|
-
* }
|
|
92
|
-
* });
|
|
93
|
-
* ```
|
|
94
|
-
*
|
|
95
|
-
* @example Multi-version with breaking changes
|
|
96
|
-
* ```typescript
|
|
97
|
-
* const weatherComponent = createComponent({
|
|
98
|
-
* name: 'weather' as const,
|
|
99
|
-
* versions: {
|
|
100
|
-
* '1.0.0': createVersion({
|
|
101
|
-
* propsSchema: WeatherV1PropsSchema,
|
|
102
|
-
* render: async ({ props }) => [...],
|
|
103
|
-
* }),
|
|
104
|
-
* '2.0.0': createVersion({
|
|
105
|
-
* propsSchema: WeatherV2PropsSchema,
|
|
106
|
-
* render: async ({ props }) => [...],
|
|
107
|
-
* }),
|
|
108
|
-
* },
|
|
109
|
-
* });
|
|
110
|
-
* ```
|
|
111
|
-
*/
|
|
112
14
|
export declare function createComponent<TComponentDefinition = ComponentDefinition, TVersions extends ComponentVersionMap<TComponentDefinition> = ComponentVersionMap<TComponentDefinition>, TName extends string = string>(component: CustomComponent<TComponentDefinition, TVersions, TName>): CustomComponent<TComponentDefinition, TVersions, TName>;
|
|
113
15
|
//# sourceMappingURL=createComponent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createComponent.d.ts","sourceRoot":"","sources":["../../src/plugin/createComponent.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"createComponent.d.ts","sourceRoot":"","sources":["../../src/plugin/createComponent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAK7C,OAAO,KAAK,EACV,aAAa,IAAI,mBAAmB,EACpC,cAAc,IAAI,oBAAoB,EACtC,gBAAgB,IAAI,sBAAsB,EAC1C,mBAAmB,IAAI,yBAAyB,EAChD,eAAe,IAAI,qBAAqB,EACzC,MAAM,+BAA+B,CAAC;AAIvC;;GAEG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,mBAAmB,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;AAEnE,MAAM,MAAM,cAAc,CACxB,MAAM,EACN,oBAAoB,GAAG,mBAAmB,IACxC,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,EAAE,WAAW,CAAC,CAAC;AAEpE,MAAM,MAAM,gBAAgB,CAC1B,oBAAoB,GAAG,mBAAmB,EAC1C,YAAY,SAAS,OAAO,GAAG,OAAO,IACpC,sBAAsB,CAAC,oBAAoB,EAAE,YAAY,EAAE,WAAW,CAAC,CAAC;AAE5E,MAAM,MAAM,mBAAmB,CAAC,oBAAoB,GAAG,mBAAmB,IACxE,yBAAyB,CAAC,oBAAoB,EAAE,WAAW,CAAC,CAAC;AAE/D,MAAM,MAAM,eAAe,CACzB,oBAAoB,GAAG,mBAAmB,EAC1C,SAAS,SACP,mBAAmB,CAAC,oBAAoB,CAAC,GAAG,mBAAmB,CAAC,oBAAoB,CAAC,EACvF,KAAK,SAAS,MAAM,GAAG,MAAM,IAC3B,qBAAqB,CAAC,oBAAoB,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;AAIlE,wBAAgB,aAAa,CAC3B,YAAY,SAAS,OAAO,EAC5B,oBAAoB,GAAG,mBAAmB,EAE1C,OAAO,EAAE,gBAAgB,CAAC,oBAAoB,EAAE,YAAY,CAAC,GAC5D,gBAAgB,CAAC,oBAAoB,EAAE,YAAY,CAAC,CAEtD;AAED,wBAAgB,eAAe,CAC7B,oBAAoB,GAAG,mBAAmB,EAC1C,SAAS,SACP,mBAAmB,CAAC,oBAAoB,CAAC,GAAG,mBAAmB,CAAC,oBAAoB,CAAC,EACvF,KAAK,SAAS,MAAM,GAAG,MAAM,EAE7B,SAAS,EAAE,eAAe,CAAC,oBAAoB,EAAE,SAAS,EAAE,KAAK,CAAC,GACjE,eAAe,CAAC,oBAAoB,EAAE,SAAS,EAAE,KAAK,CAAC,CAEzD"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ThemeConfig } from '../styles';
|
|
2
2
|
import type { DocumentGeneratorBuilder } from './types';
|
|
3
3
|
/**
|
|
4
4
|
* Options for creating a document generator
|
|
@@ -6,6 +6,8 @@ import type { DocumentGeneratorBuilder } from './types';
|
|
|
6
6
|
export interface DocumentGeneratorOptions {
|
|
7
7
|
/** Theme configuration */
|
|
8
8
|
theme: ThemeConfig;
|
|
9
|
+
/** Custom themes keyed by name, resolved per-document via document.props.theme */
|
|
10
|
+
customThemes?: Record<string, ThemeConfig>;
|
|
9
11
|
/** Enable caching for better performance */
|
|
10
12
|
enableCache?: boolean;
|
|
11
13
|
/** Enable debug logging */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createDocumentGenerator.d.ts","sourceRoot":"","sources":["../../src/plugin/createDocumentGenerator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"createDocumentGenerator.d.ts","sourceRoot":"","sources":["../../src/plugin/createDocumentGenerator.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAwB,MAAM,WAAW,CAAC;AAEnE,OAAO,KAAK,EAEV,wBAAwB,EAKzB,MAAM,SAAS,CAAC;AAcjB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,0BAA0B;IAC1B,KAAK,EAAE,WAAW,CAAC;IACnB,kFAAkF;IAClF,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C,4CAA4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA2bD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,GAChC,wBAAwB,CAAC,SAAS,EAAE,CAAC,CAWvC"}
|
|
@@ -678,7 +678,7 @@ function loadThemesFromJson() {
|
|
|
678
678
|
_themesCache = themes2;
|
|
679
679
|
return themes2;
|
|
680
680
|
}
|
|
681
|
-
var _themesCache, themes, getTheme, minimalTheme, corporateTheme, modernTheme;
|
|
681
|
+
var _themesCache, themes, getTheme, getThemeWithFallback, minimalTheme, corporateTheme, modernTheme;
|
|
682
682
|
var init_themes = __esm({
|
|
683
683
|
"src/templates/themes/index.ts"() {
|
|
684
684
|
"use strict";
|
|
@@ -691,6 +691,15 @@ var init_themes = __esm({
|
|
|
691
691
|
getTheme = (themeName) => {
|
|
692
692
|
return themes[themeName];
|
|
693
693
|
};
|
|
694
|
+
getThemeWithFallback = (themeName, fallbackTheme = "minimal") => {
|
|
695
|
+
const theme = getTheme(themeName) || getTheme(fallbackTheme);
|
|
696
|
+
if (!theme) {
|
|
697
|
+
throw new Error(
|
|
698
|
+
`Failed to load theme: ${themeName}. Fallback theme '${fallbackTheme}' also not found.`
|
|
699
|
+
);
|
|
700
|
+
}
|
|
701
|
+
return theme;
|
|
702
|
+
};
|
|
694
703
|
minimalTheme = themes["minimal"];
|
|
695
704
|
corporateTheme = themes["corporate"];
|
|
696
705
|
modernTheme = themes["modern"];
|
|
@@ -2033,62 +2042,29 @@ var init_numberingConfig = __esm({
|
|
|
2033
2042
|
import { Packer as Packer2 } from "docx";
|
|
2034
2043
|
|
|
2035
2044
|
// src/plugin/createDocumentGenerator.ts
|
|
2045
|
+
init_styles();
|
|
2036
2046
|
import { Packer } from "docx";
|
|
2037
2047
|
|
|
2038
2048
|
// src/plugin/version-resolver.ts
|
|
2039
|
-
import {
|
|
2040
|
-
function resolveComponentVersion(componentName, versions, requestedVersion) {
|
|
2041
|
-
const versionKeys = Object.keys(versions);
|
|
2042
|
-
if (requestedVersion) {
|
|
2043
|
-
const entry = versions[requestedVersion];
|
|
2044
|
-
if (!entry) {
|
|
2045
|
-
throw new Error(
|
|
2046
|
-
`Component "${componentName}" does not have version "${requestedVersion}". Available versions: ${versionKeys.join(", ")}`
|
|
2047
|
-
);
|
|
2048
|
-
}
|
|
2049
|
-
return entry;
|
|
2050
|
-
}
|
|
2051
|
-
const latest = latestVersion(versionKeys);
|
|
2052
|
-
return versions[latest];
|
|
2053
|
-
}
|
|
2049
|
+
import { resolveComponentVersion } from "@json-to-office/shared/plugin";
|
|
2054
2050
|
|
|
2055
2051
|
// src/plugin/validation.ts
|
|
2056
2052
|
import {
|
|
2057
2053
|
validateCustomComponentProps,
|
|
2054
|
+
ComponentValidationError
|
|
2055
|
+
} from "@json-to-office/shared/plugin";
|
|
2056
|
+
import {
|
|
2058
2057
|
validateDocument as validateDocumentUnified
|
|
2059
2058
|
} from "@json-to-office/shared-docx/validation/unified";
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
`Cannot register component "${componentName}": a component with this name is already registered. Component names must be unique within a document generator.`
|
|
2066
|
-
);
|
|
2067
|
-
this.name = "DuplicateComponentError";
|
|
2068
|
-
this.componentName = componentName;
|
|
2069
|
-
if (Error.captureStackTrace) {
|
|
2070
|
-
Error.captureStackTrace(this, _DuplicateComponentError);
|
|
2071
|
-
}
|
|
2072
|
-
}
|
|
2073
|
-
};
|
|
2074
|
-
var ComponentValidationError = class extends Error {
|
|
2075
|
-
errors;
|
|
2076
|
-
props;
|
|
2077
|
-
constructor(errors, props) {
|
|
2078
|
-
const propsStr = props !== void 0 ? `
|
|
2079
|
-
Props: ${JSON.stringify(props, null, 2)}` : "";
|
|
2080
|
-
const message = `Document validation failed:
|
|
2081
|
-
${errors.map((e) => ` ${e.path}: ${e.message}`).join("\n")}${propsStr}`;
|
|
2082
|
-
super(message);
|
|
2083
|
-
this.name = "ComponentValidationError";
|
|
2084
|
-
this.errors = errors;
|
|
2085
|
-
this.props = props;
|
|
2086
|
-
}
|
|
2087
|
-
};
|
|
2088
|
-
function validateComponentProps(schema, props) {
|
|
2059
|
+
import {
|
|
2060
|
+
DuplicateComponentError,
|
|
2061
|
+
ComponentValidationError as ComponentValidationError2
|
|
2062
|
+
} from "@json-to-office/shared/plugin";
|
|
2063
|
+
function validateComponentProps(schema, props, componentName) {
|
|
2089
2064
|
return validateCustomComponentProps(schema.propsSchema, props, {
|
|
2090
2065
|
clean: true,
|
|
2091
|
-
applyDefaults: true
|
|
2066
|
+
applyDefaults: true,
|
|
2067
|
+
componentName
|
|
2092
2068
|
});
|
|
2093
2069
|
}
|
|
2094
2070
|
function validateDocument(document, customComponents) {
|
|
@@ -2115,7 +2091,8 @@ function validateDocument(document, customComponents) {
|
|
|
2115
2091
|
);
|
|
2116
2092
|
const validation = validateComponentProps(
|
|
2117
2093
|
versionEntry,
|
|
2118
|
-
componentData.props
|
|
2094
|
+
componentData.props,
|
|
2095
|
+
customComponent.name
|
|
2119
2096
|
);
|
|
2120
2097
|
if (!validation.valid && validation.errors) {
|
|
2121
2098
|
const indexedErrors = validation.errors.map(
|
|
@@ -2150,7 +2127,7 @@ var cleanComponentProps = getValidatedProps;
|
|
|
2150
2127
|
|
|
2151
2128
|
// src/plugin/schema.ts
|
|
2152
2129
|
import { Type } from "@sinclair/typebox";
|
|
2153
|
-
import { latestVersion
|
|
2130
|
+
import { latestVersion } from "@json-to-office/shared-docx";
|
|
2154
2131
|
import {
|
|
2155
2132
|
ReportPropsSchema,
|
|
2156
2133
|
SectionPropsSchema,
|
|
@@ -6185,42 +6162,15 @@ async function renderHighchartsComponent(component, theme, _themeName) {
|
|
|
6185
6162
|
import { Type as Type2 } from "@sinclair/typebox";
|
|
6186
6163
|
|
|
6187
6164
|
// src/plugin/createComponent.ts
|
|
6188
|
-
import {
|
|
6165
|
+
import {
|
|
6166
|
+
createVersion as sharedCreateVersion,
|
|
6167
|
+
createComponent as sharedCreateComponent
|
|
6168
|
+
} from "@json-to-office/shared/plugin";
|
|
6189
6169
|
function createVersion(version) {
|
|
6190
|
-
return version;
|
|
6170
|
+
return sharedCreateVersion(version);
|
|
6191
6171
|
}
|
|
6192
6172
|
function createComponent(component) {
|
|
6193
|
-
|
|
6194
|
-
throw new Error("Component name is required");
|
|
6195
|
-
}
|
|
6196
|
-
if (!component.versions || typeof component.versions !== "object") {
|
|
6197
|
-
throw new Error(`Component "${component.name}" requires a versions map`);
|
|
6198
|
-
}
|
|
6199
|
-
const versionKeys = Object.keys(component.versions);
|
|
6200
|
-
if (versionKeys.length === 0) {
|
|
6201
|
-
throw new Error(
|
|
6202
|
-
`Component "${component.name}" must have at least one version`
|
|
6203
|
-
);
|
|
6204
|
-
}
|
|
6205
|
-
for (const key of versionKeys) {
|
|
6206
|
-
if (!isValidSemver(key)) {
|
|
6207
|
-
throw new Error(
|
|
6208
|
-
`Component "${component.name}": invalid semver key "${key}". Expected format: major.minor.patch`
|
|
6209
|
-
);
|
|
6210
|
-
}
|
|
6211
|
-
const entry = component.versions[key];
|
|
6212
|
-
if (!entry.propsSchema) {
|
|
6213
|
-
throw new Error(
|
|
6214
|
-
`Component "${component.name}" version "${key}" requires a propsSchema`
|
|
6215
|
-
);
|
|
6216
|
-
}
|
|
6217
|
-
if (!entry.render || typeof entry.render !== "function") {
|
|
6218
|
-
throw new Error(
|
|
6219
|
-
`Component "${component.name}" version "${key}" requires a render function`
|
|
6220
|
-
);
|
|
6221
|
-
}
|
|
6222
|
-
}
|
|
6223
|
-
return component;
|
|
6173
|
+
return sharedCreateComponent(component);
|
|
6224
6174
|
}
|
|
6225
6175
|
|
|
6226
6176
|
// src/components/text-space-after.ts
|
|
@@ -6694,45 +6644,29 @@ function normalizeDocument(document) {
|
|
|
6694
6644
|
return [normalized];
|
|
6695
6645
|
}
|
|
6696
6646
|
|
|
6697
|
-
// src/styles/theme-resolver.ts
|
|
6698
|
-
init_themes();
|
|
6699
|
-
function resolveTheme2(theme) {
|
|
6700
|
-
if (typeof theme === "string") {
|
|
6701
|
-
const resolvedTheme = getTheme(theme);
|
|
6702
|
-
if (resolvedTheme) {
|
|
6703
|
-
return resolvedTheme;
|
|
6704
|
-
}
|
|
6705
|
-
return getTheme("minimal");
|
|
6706
|
-
}
|
|
6707
|
-
if (theme) {
|
|
6708
|
-
return theme;
|
|
6709
|
-
}
|
|
6710
|
-
return getTheme("minimal");
|
|
6711
|
-
}
|
|
6712
|
-
|
|
6713
|
-
// src/styles/theme-validator.ts
|
|
6714
|
-
import { validateTheme as validateThemeUnified } from "@json-to-office/shared-docx/validation/unified";
|
|
6715
|
-
function validateTheme(theme) {
|
|
6716
|
-
if (!theme) {
|
|
6717
|
-
return void 0;
|
|
6718
|
-
}
|
|
6719
|
-
if (typeof theme === "string") {
|
|
6720
|
-
return theme;
|
|
6721
|
-
}
|
|
6722
|
-
const result = validateThemeUnified(theme);
|
|
6723
|
-
if (!result.valid) {
|
|
6724
|
-
const errorSummary = result.errors?.map((e) => e.message).join(", ") || "Invalid theme";
|
|
6725
|
-
throw new Error(`Invalid theme: ${errorSummary}`);
|
|
6726
|
-
}
|
|
6727
|
-
return result.data;
|
|
6728
|
-
}
|
|
6729
|
-
|
|
6730
6647
|
// src/plugin/createDocumentGenerator.ts
|
|
6731
6648
|
function createBuilderImpl(state) {
|
|
6732
|
-
const validatedTheme = validateTheme(state.theme);
|
|
6733
|
-
const fullTheme = resolveTheme2(validatedTheme);
|
|
6734
6649
|
const componentMap = new Map(state.components.map((c) => [c.name, c]));
|
|
6735
|
-
|
|
6650
|
+
function resolveDocumentTheme(themeName) {
|
|
6651
|
+
if (state.customThemes) {
|
|
6652
|
+
if (state.customThemes[themeName]) {
|
|
6653
|
+
return state.customThemes[themeName];
|
|
6654
|
+
}
|
|
6655
|
+
const key = Object.keys(state.customThemes).find(
|
|
6656
|
+
(k) => k.toLowerCase() === themeName.toLowerCase()
|
|
6657
|
+
);
|
|
6658
|
+
if (key) {
|
|
6659
|
+
return state.customThemes[key];
|
|
6660
|
+
}
|
|
6661
|
+
}
|
|
6662
|
+
return getThemeWithFallback(themeName);
|
|
6663
|
+
}
|
|
6664
|
+
async function processDocumentComponents(components, warningsCollector, resolvedTheme, depth = 0) {
|
|
6665
|
+
if (depth > 20) {
|
|
6666
|
+
throw new Error(
|
|
6667
|
+
"Maximum component nesting depth exceeded (20). Check for circular component references."
|
|
6668
|
+
);
|
|
6669
|
+
}
|
|
6736
6670
|
const processedComponents = [];
|
|
6737
6671
|
for (const componentData of components) {
|
|
6738
6672
|
const componentName = componentData?.name;
|
|
@@ -6762,7 +6696,9 @@ function createBuilderImpl(state) {
|
|
|
6762
6696
|
if (componentWithName.children && Array.isArray(componentWithName.children)) {
|
|
6763
6697
|
nestedChildren = await processDocumentComponents(
|
|
6764
6698
|
componentWithName.children,
|
|
6765
|
-
warningsCollector
|
|
6699
|
+
warningsCollector,
|
|
6700
|
+
resolvedTheme,
|
|
6701
|
+
depth + 1
|
|
6766
6702
|
);
|
|
6767
6703
|
}
|
|
6768
6704
|
const versionLabel = componentWithName.version ? `${customComponent.name}@${componentWithName.version}` : customComponent.name;
|
|
@@ -6776,14 +6712,16 @@ function createBuilderImpl(state) {
|
|
|
6776
6712
|
};
|
|
6777
6713
|
const result = await versionEntry.render({
|
|
6778
6714
|
props: cleanedProps,
|
|
6779
|
-
theme:
|
|
6715
|
+
theme: resolvedTheme,
|
|
6780
6716
|
addWarning,
|
|
6781
6717
|
children: nestedChildren
|
|
6782
6718
|
});
|
|
6783
6719
|
const resultComponents = Array.isArray(result) ? result : [result];
|
|
6784
6720
|
const processedResult = await processDocumentComponents(
|
|
6785
6721
|
resultComponents,
|
|
6786
|
-
warningsCollector
|
|
6722
|
+
warningsCollector,
|
|
6723
|
+
resolvedTheme,
|
|
6724
|
+
depth + 1
|
|
6787
6725
|
);
|
|
6788
6726
|
processedComponents.push(...processedResult);
|
|
6789
6727
|
if (state.debug) {
|
|
@@ -6793,7 +6731,7 @@ function createBuilderImpl(state) {
|
|
|
6793
6731
|
);
|
|
6794
6732
|
}
|
|
6795
6733
|
} catch (error) {
|
|
6796
|
-
if (error instanceof
|
|
6734
|
+
if (error instanceof ComponentValidationError2) {
|
|
6797
6735
|
throw error;
|
|
6798
6736
|
}
|
|
6799
6737
|
throw new Error(
|
|
@@ -6804,7 +6742,9 @@ function createBuilderImpl(state) {
|
|
|
6804
6742
|
if ("children" in componentData && Array.isArray(componentData.children)) {
|
|
6805
6743
|
const processedNested = await processDocumentComponents(
|
|
6806
6744
|
componentData.children,
|
|
6807
|
-
warningsCollector
|
|
6745
|
+
warningsCollector,
|
|
6746
|
+
resolvedTheme,
|
|
6747
|
+
depth + 1
|
|
6808
6748
|
);
|
|
6809
6749
|
processedComponents.push({
|
|
6810
6750
|
...componentData,
|
|
@@ -6818,18 +6758,19 @@ function createBuilderImpl(state) {
|
|
|
6818
6758
|
return processedComponents;
|
|
6819
6759
|
}
|
|
6820
6760
|
function addComponent(component) {
|
|
6821
|
-
if (state.componentNames.has(component.name)) {
|
|
6822
|
-
throw new DuplicateComponentError(component.name);
|
|
6823
|
-
}
|
|
6824
6761
|
if (!component.name) {
|
|
6825
6762
|
throw new Error("Component name is required");
|
|
6826
6763
|
}
|
|
6764
|
+
if (state.componentNames.has(component.name)) {
|
|
6765
|
+
throw new DuplicateComponentError(component.name);
|
|
6766
|
+
}
|
|
6827
6767
|
const newComponentNames = new Set(state.componentNames);
|
|
6828
6768
|
newComponentNames.add(component.name);
|
|
6829
6769
|
const newState = {
|
|
6830
6770
|
components: [...state.components, component],
|
|
6831
6771
|
componentNames: newComponentNames,
|
|
6832
6772
|
theme: state.theme,
|
|
6773
|
+
customThemes: state.customThemes,
|
|
6833
6774
|
debug: state.debug,
|
|
6834
6775
|
enableCache: state.enableCache
|
|
6835
6776
|
};
|
|
@@ -6844,10 +6785,13 @@ function createBuilderImpl(state) {
|
|
|
6844
6785
|
internalDocument,
|
|
6845
6786
|
state.components
|
|
6846
6787
|
);
|
|
6788
|
+
const themeName = internalDocument.props.theme || "minimal";
|
|
6789
|
+
const docTheme = resolveDocumentTheme(themeName);
|
|
6847
6790
|
const warnings = [];
|
|
6848
6791
|
const processedComponents = await processDocumentComponents(
|
|
6849
6792
|
internalDocument.children || [],
|
|
6850
|
-
warnings
|
|
6793
|
+
warnings,
|
|
6794
|
+
docTheme
|
|
6851
6795
|
);
|
|
6852
6796
|
const processedDocument = {
|
|
6853
6797
|
...internalDocument,
|
|
@@ -6856,10 +6800,10 @@ function createBuilderImpl(state) {
|
|
|
6856
6800
|
const [finalReportComponent] = normalizeDocument(processedDocument);
|
|
6857
6801
|
const structure = await processDocument(
|
|
6858
6802
|
finalReportComponent,
|
|
6859
|
-
|
|
6860
|
-
|
|
6803
|
+
docTheme,
|
|
6804
|
+
themeName
|
|
6861
6805
|
);
|
|
6862
|
-
const layout = applyLayout(structure.sections,
|
|
6806
|
+
const layout = applyLayout(structure.sections, docTheme, themeName);
|
|
6863
6807
|
const generatedDocument = await renderDocument(structure, layout);
|
|
6864
6808
|
return {
|
|
6865
6809
|
document: generatedDocument,
|
|
@@ -6895,7 +6839,7 @@ function createBuilderImpl(state) {
|
|
|
6895
6839
|
);
|
|
6896
6840
|
return { valid: true };
|
|
6897
6841
|
} catch (error) {
|
|
6898
|
-
if (error instanceof
|
|
6842
|
+
if (error instanceof ComponentValidationError2) {
|
|
6899
6843
|
return {
|
|
6900
6844
|
valid: false,
|
|
6901
6845
|
errors: error.errors.map((e) => ({
|
|
@@ -6935,10 +6879,13 @@ function createBuilderImpl(state) {
|
|
|
6935
6879
|
internalDocument,
|
|
6936
6880
|
state.components
|
|
6937
6881
|
);
|
|
6882
|
+
const themeName = internalDocument.props.theme || "minimal";
|
|
6883
|
+
const docTheme = resolveDocumentTheme(themeName);
|
|
6938
6884
|
const warnings = [];
|
|
6939
6885
|
const processedComponents = await processDocumentComponents(
|
|
6940
6886
|
internalDocument.children || [],
|
|
6941
|
-
warnings
|
|
6887
|
+
warnings,
|
|
6888
|
+
docTheme
|
|
6942
6889
|
);
|
|
6943
6890
|
const processedDocument = {
|
|
6944
6891
|
...internalDocument,
|
|
@@ -6970,6 +6917,7 @@ function createDocumentGenerator(options) {
|
|
|
6970
6917
|
components: [],
|
|
6971
6918
|
componentNames: /* @__PURE__ */ new Set(),
|
|
6972
6919
|
theme: options.theme,
|
|
6920
|
+
customThemes: options.customThemes,
|
|
6973
6921
|
debug: options.debug ?? false,
|
|
6974
6922
|
enableCache: options.enableCache ?? false
|
|
6975
6923
|
};
|