@json-to-office/core-docx 0.16.0 → 0.17.1
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/core/generator.d.ts +12 -1
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/index.js +93 -30
- package/dist/index.js.map +1 -1
- package/dist/plugin/createDocumentGenerator.d.ts +7 -1
- package/dist/plugin/createDocumentGenerator.d.ts.map +1 -1
- package/dist/plugin/example/index.js +69 -29
- package/dist/plugin/example/index.js.map +1 -1
- package/dist/plugin/types.d.ts +15 -0
- package/dist/plugin/types.d.ts.map +1 -1
- package/dist/plugin/validation.d.ts +14 -3
- package/dist/plugin/validation.d.ts.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/dist/core/generator.d.ts
CHANGED
|
@@ -12,8 +12,19 @@ import type { GenerationWarning } from '@json-to-office/shared';
|
|
|
12
12
|
export interface JsonGenerationOptions {
|
|
13
13
|
outputPath?: string;
|
|
14
14
|
validation?: {
|
|
15
|
-
|
|
15
|
+
/**
|
|
16
|
+
* Validate the document against the schema before building, throwing on
|
|
17
|
+
* errors. Defaults to `true` — invalid props are surfaced rather than
|
|
18
|
+
* silently dropped into a corrupt/incomplete document.
|
|
19
|
+
*/
|
|
20
|
+
enabled?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* When true, unknown/extra properties are stripped instead of rejected by
|
|
23
|
+
* strict (additionalProperties:false) schemas. Escape hatch for migration.
|
|
24
|
+
*/
|
|
16
25
|
allowUnknownFields?: boolean;
|
|
26
|
+
/** @deprecated No longer consulted; retained for back-compat. */
|
|
27
|
+
strict?: boolean;
|
|
17
28
|
};
|
|
18
29
|
customThemes?: {
|
|
19
30
|
[key: string]: ThemeConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/core/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,OAAO,EAAE,QAAQ,EAAU,MAAM,MAAM,CAAC;AAExC,OAAO,EACL,mBAAmB,EACnB,WAAW,EACX,yBAAyB,EAE1B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAwB,WAAW,EAAE,MAAM,WAAW,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAQ9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/core/generator.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -7287,9 +7287,32 @@ async function generateDocumentWithCustomThemes(documentIn, customThemes, servic
|
|
|
7287
7287
|
return renderedDocument;
|
|
7288
7288
|
}
|
|
7289
7289
|
async function generateDocumentFromJson(jsonConfig, options) {
|
|
7290
|
+
const validation = options?.validation;
|
|
7291
|
+
if (validation?.enabled !== false) {
|
|
7292
|
+
const result = validateJsonComponent(jsonConfig, {
|
|
7293
|
+
allowUnknownFields: validation?.allowUnknownFields
|
|
7294
|
+
});
|
|
7295
|
+
if (!result.valid) {
|
|
7296
|
+
throw new JsonValidationError(
|
|
7297
|
+
"Document validation failed",
|
|
7298
|
+
result.errors
|
|
7299
|
+
);
|
|
7300
|
+
}
|
|
7301
|
+
}
|
|
7290
7302
|
let componentToConvert;
|
|
7291
7303
|
if (typeof jsonConfig === "string") {
|
|
7292
|
-
|
|
7304
|
+
let parsed;
|
|
7305
|
+
try {
|
|
7306
|
+
parsed = JSON.parse(jsonConfig);
|
|
7307
|
+
} catch (error) {
|
|
7308
|
+
throw new JsonParsingError("Invalid JSON syntax", [
|
|
7309
|
+
{
|
|
7310
|
+
path: "",
|
|
7311
|
+
message: error instanceof Error ? error.message : "Invalid JSON",
|
|
7312
|
+
code: "JSON_PARSE_ERROR"
|
|
7313
|
+
}
|
|
7314
|
+
]);
|
|
7315
|
+
}
|
|
7293
7316
|
if (!isReportComponent(parsed)) {
|
|
7294
7317
|
throw new Error("Parsed JSON must be a docx component");
|
|
7295
7318
|
}
|
|
@@ -7690,22 +7713,20 @@ import {
|
|
|
7690
7713
|
ComponentValidationError as ComponentValidationError2,
|
|
7691
7714
|
UnknownPreservedComponentError
|
|
7692
7715
|
} from "@json-to-office/shared/plugin";
|
|
7693
|
-
function validateComponentProps(schema, props, componentName) {
|
|
7716
|
+
function validateComponentProps(schema, props, componentName, opts) {
|
|
7694
7717
|
return validateCustomComponentProps(schema.propsSchema, props, {
|
|
7695
|
-
clean: true,
|
|
7696
|
-
applyDefaults: true,
|
|
7718
|
+
clean: opts?.clean ?? true,
|
|
7719
|
+
applyDefaults: opts?.applyDefaults ?? true,
|
|
7697
7720
|
componentName
|
|
7698
7721
|
});
|
|
7699
7722
|
}
|
|
7700
|
-
function validateDocument(document, customComponents) {
|
|
7723
|
+
function validateDocument(document, customComponents, options) {
|
|
7724
|
+
const knownCustomNames = new Set(customComponents.map((c) => c.name));
|
|
7701
7725
|
const documentResult = validateDocumentUnified(document, {
|
|
7702
|
-
|
|
7703
|
-
|
|
7726
|
+
knownCustomNames,
|
|
7727
|
+
allowUnknownFields: options?.allowUnknownFields
|
|
7704
7728
|
});
|
|
7705
|
-
|
|
7706
|
-
return { ...documentResult, success: false };
|
|
7707
|
-
}
|
|
7708
|
-
const errors = [];
|
|
7729
|
+
const errors = [...documentResult.errors || []];
|
|
7709
7730
|
function validateComponents(components, pathPrefix = "children") {
|
|
7710
7731
|
components.forEach((componentData, index) => {
|
|
7711
7732
|
const customComponent = customComponents.find(
|
|
@@ -7722,7 +7743,9 @@ function validateDocument(document, customComponents) {
|
|
|
7722
7743
|
const validation = validateComponentProps(
|
|
7723
7744
|
versionEntry,
|
|
7724
7745
|
componentData.props,
|
|
7725
|
-
customComponent.name
|
|
7746
|
+
customComponent.name,
|
|
7747
|
+
// Reject unknown custom props unless the caller allows them.
|
|
7748
|
+
{ clean: options?.allowUnknownFields === true }
|
|
7726
7749
|
);
|
|
7727
7750
|
if (!validation.valid && validation.errors) {
|
|
7728
7751
|
const indexedErrors = validation.errors.map(
|
|
@@ -7933,7 +7956,7 @@ function createBuilderImpl(state) {
|
|
|
7933
7956
|
}
|
|
7934
7957
|
return getThemeWithFallback(themeName);
|
|
7935
7958
|
}
|
|
7936
|
-
async function processDocumentComponents(components, preserveSet, warningsCollector, resolvedTheme, depth = 0) {
|
|
7959
|
+
async function processDocumentComponents(components, preserveSet, warningsCollector, resolvedTheme, validateEmitted, depth = 0) {
|
|
7937
7960
|
if (depth > 20) {
|
|
7938
7961
|
throw new Error(
|
|
7939
7962
|
"Maximum component nesting depth exceeded (20). Check for circular component references."
|
|
@@ -7973,6 +7996,7 @@ function createBuilderImpl(state) {
|
|
|
7973
7996
|
preserveSet,
|
|
7974
7997
|
warningsCollector,
|
|
7975
7998
|
resolvedTheme,
|
|
7999
|
+
validateEmitted,
|
|
7976
8000
|
depth + 1
|
|
7977
8001
|
);
|
|
7978
8002
|
nestedChildren = nested.standard;
|
|
@@ -7993,11 +8017,15 @@ function createBuilderImpl(state) {
|
|
|
7993
8017
|
children: nestedChildren
|
|
7994
8018
|
});
|
|
7995
8019
|
const resultComponents = Array.isArray(result) ? result : [result];
|
|
8020
|
+
if (validateEmitted) {
|
|
8021
|
+
validateEmitted(resultComponents, versionLabel);
|
|
8022
|
+
}
|
|
7996
8023
|
const processedResult = await processDocumentComponents(
|
|
7997
8024
|
resultComponents,
|
|
7998
8025
|
preserveSet,
|
|
7999
8026
|
warningsCollector,
|
|
8000
8027
|
resolvedTheme,
|
|
8028
|
+
validateEmitted,
|
|
8001
8029
|
depth + 1
|
|
8002
8030
|
);
|
|
8003
8031
|
standardOut.push(...processedResult.standard);
|
|
@@ -8027,6 +8055,7 @@ function createBuilderImpl(state) {
|
|
|
8027
8055
|
preserveSet,
|
|
8028
8056
|
warningsCollector,
|
|
8029
8057
|
resolvedTheme,
|
|
8058
|
+
validateEmitted,
|
|
8030
8059
|
depth + 1
|
|
8031
8060
|
);
|
|
8032
8061
|
standardOut.push({
|
|
@@ -8087,10 +8116,42 @@ function createBuilderImpl(state) {
|
|
|
8087
8116
|
try {
|
|
8088
8117
|
const preserveSet = resolvePreserveSet(options);
|
|
8089
8118
|
const internalDocument = document;
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
8093
|
-
|
|
8119
|
+
const vOpts = {
|
|
8120
|
+
...state.validation,
|
|
8121
|
+
...options?.validation
|
|
8122
|
+
};
|
|
8123
|
+
if (vOpts.enabled !== false) {
|
|
8124
|
+
const result = validateDocument(
|
|
8125
|
+
internalDocument,
|
|
8126
|
+
state.components,
|
|
8127
|
+
{ allowUnknownFields: vOpts.allowUnknownFields }
|
|
8128
|
+
);
|
|
8129
|
+
if (!result.valid) {
|
|
8130
|
+
throw new ComponentValidationError2(
|
|
8131
|
+
(result.errors ?? []).map((e) => ({
|
|
8132
|
+
path: e.path ?? "",
|
|
8133
|
+
message: e.message
|
|
8134
|
+
})),
|
|
8135
|
+
internalDocument
|
|
8136
|
+
);
|
|
8137
|
+
}
|
|
8138
|
+
}
|
|
8139
|
+
const validateEmitted = vOpts.enabled === false ? void 0 : (emitted, componentLabel) => {
|
|
8140
|
+
const result = validateDocument(
|
|
8141
|
+
{ ...internalDocument, children: emitted },
|
|
8142
|
+
state.components,
|
|
8143
|
+
{ allowUnknownFields: vOpts.allowUnknownFields }
|
|
8144
|
+
);
|
|
8145
|
+
if (!result.valid) {
|
|
8146
|
+
throw new ComponentValidationError2(
|
|
8147
|
+
(result.errors ?? []).map((e) => ({
|
|
8148
|
+
path: e.path ?? "",
|
|
8149
|
+
message: `custom component '${componentLabel}' emitted invalid output \u2014 ${e.message}`
|
|
8150
|
+
})),
|
|
8151
|
+
emitted
|
|
8152
|
+
);
|
|
8153
|
+
}
|
|
8154
|
+
};
|
|
8094
8155
|
const baseThemeName = internalDocument.props.theme || "minimal";
|
|
8095
8156
|
const docTheme = resolveDocumentTheme(baseThemeName);
|
|
8096
8157
|
const warnings = [];
|
|
@@ -8113,7 +8174,8 @@ function createBuilderImpl(state) {
|
|
|
8113
8174
|
mode.doc.children || [],
|
|
8114
8175
|
preserveSet,
|
|
8115
8176
|
warnings,
|
|
8116
|
-
modedTheme
|
|
8177
|
+
modedTheme,
|
|
8178
|
+
validateEmitted
|
|
8117
8179
|
);
|
|
8118
8180
|
const processedDocument = {
|
|
8119
8181
|
...mode.doc,
|
|
@@ -8184,21 +8246,21 @@ function createBuilderImpl(state) {
|
|
|
8184
8246
|
function validate(document) {
|
|
8185
8247
|
try {
|
|
8186
8248
|
const internalDocument = document;
|
|
8187
|
-
validateDocument(
|
|
8249
|
+
const result = validateDocument(
|
|
8188
8250
|
internalDocument,
|
|
8189
8251
|
state.components
|
|
8190
8252
|
);
|
|
8191
|
-
|
|
8192
|
-
|
|
8193
|
-
if (error instanceof ComponentValidationError2) {
|
|
8194
|
-
return {
|
|
8195
|
-
valid: false,
|
|
8196
|
-
errors: error.errors.map((e) => ({
|
|
8197
|
-
path: e.path,
|
|
8198
|
-
message: e.message
|
|
8199
|
-
}))
|
|
8200
|
-
};
|
|
8253
|
+
if (result.valid) {
|
|
8254
|
+
return { valid: true };
|
|
8201
8255
|
}
|
|
8256
|
+
return {
|
|
8257
|
+
valid: false,
|
|
8258
|
+
errors: (result.errors ?? []).map((e) => ({
|
|
8259
|
+
path: e.path ?? "",
|
|
8260
|
+
message: e.message
|
|
8261
|
+
}))
|
|
8262
|
+
};
|
|
8263
|
+
} catch (error) {
|
|
8202
8264
|
return {
|
|
8203
8265
|
valid: false,
|
|
8204
8266
|
errors: [
|
|
@@ -8248,7 +8310,8 @@ function createDocumentGenerator(options) {
|
|
|
8248
8310
|
debug: options.debug ?? false,
|
|
8249
8311
|
enableCache: options.enableCache ?? false,
|
|
8250
8312
|
services: options.services,
|
|
8251
|
-
fonts: options.fonts
|
|
8313
|
+
fonts: options.fonts,
|
|
8314
|
+
validation: options.validation
|
|
8252
8315
|
};
|
|
8253
8316
|
return createBuilderImpl(initialState);
|
|
8254
8317
|
}
|