@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 CHANGED
@@ -6178,42 +6178,15 @@ async function renderHighchartsComponent(component, theme, _themeName) {
6178
6178
  import { Type } from "@sinclair/typebox";
6179
6179
 
6180
6180
  // src/plugin/createComponent.ts
6181
- import { isValidSemver } from "@json-to-office/shared";
6181
+ import {
6182
+ createVersion as sharedCreateVersion,
6183
+ createComponent as sharedCreateComponent
6184
+ } from "@json-to-office/shared/plugin";
6182
6185
  function createVersion(version) {
6183
- return version;
6186
+ return sharedCreateVersion(version);
6184
6187
  }
6185
6188
  function createComponent(component) {
6186
- if (!component.name) {
6187
- throw new Error("Component name is required");
6188
- }
6189
- if (!component.versions || typeof component.versions !== "object") {
6190
- throw new Error(`Component "${component.name}" requires a versions map`);
6191
- }
6192
- const versionKeys = Object.keys(component.versions);
6193
- if (versionKeys.length === 0) {
6194
- throw new Error(
6195
- `Component "${component.name}" must have at least one version`
6196
- );
6197
- }
6198
- for (const key of versionKeys) {
6199
- if (!isValidSemver(key)) {
6200
- throw new Error(
6201
- `Component "${component.name}": invalid semver key "${key}". Expected format: major.minor.patch`
6202
- );
6203
- }
6204
- const entry = component.versions[key];
6205
- if (!entry.propsSchema) {
6206
- throw new Error(
6207
- `Component "${component.name}" version "${key}" requires a propsSchema`
6208
- );
6209
- }
6210
- if (!entry.render || typeof entry.render !== "function") {
6211
- throw new Error(
6212
- `Component "${component.name}" version "${key}" requires a render function`
6213
- );
6214
- }
6215
- }
6216
- return component;
6189
+ return sharedCreateComponent(component);
6217
6190
  }
6218
6191
 
6219
6192
  // src/components/text-space-after.ts
@@ -7092,62 +7065,29 @@ async function runExample(example, options = {}) {
7092
7065
  }
7093
7066
 
7094
7067
  // src/plugin/createDocumentGenerator.ts
7068
+ init_styles();
7095
7069
  import { Packer as Packer2 } from "docx";
7096
7070
 
7097
7071
  // src/plugin/version-resolver.ts
7098
- import { latestVersion } from "@json-to-office/shared-docx";
7099
- function resolveComponentVersion(componentName, versions, requestedVersion) {
7100
- const versionKeys = Object.keys(versions);
7101
- if (requestedVersion) {
7102
- const entry = versions[requestedVersion];
7103
- if (!entry) {
7104
- throw new Error(
7105
- `Component "${componentName}" does not have version "${requestedVersion}". Available versions: ${versionKeys.join(", ")}`
7106
- );
7107
- }
7108
- return entry;
7109
- }
7110
- const latest = latestVersion(versionKeys);
7111
- return versions[latest];
7112
- }
7072
+ import { resolveComponentVersion } from "@json-to-office/shared/plugin";
7113
7073
 
7114
7074
  // src/plugin/validation.ts
7115
7075
  import {
7116
7076
  validateCustomComponentProps,
7077
+ ComponentValidationError
7078
+ } from "@json-to-office/shared/plugin";
7079
+ import {
7117
7080
  validateDocument as validateDocumentUnified
7118
7081
  } from "@json-to-office/shared-docx/validation/unified";
7119
- var DuplicateComponentError = class _DuplicateComponentError extends Error {
7120
- componentName;
7121
- code = "DUPLICATE_COMPONENT";
7122
- constructor(componentName) {
7123
- super(
7124
- `Cannot register component "${componentName}": a component with this name is already registered. Component names must be unique within a document generator.`
7125
- );
7126
- this.name = "DuplicateComponentError";
7127
- this.componentName = componentName;
7128
- if (Error.captureStackTrace) {
7129
- Error.captureStackTrace(this, _DuplicateComponentError);
7130
- }
7131
- }
7132
- };
7133
- var ComponentValidationError = class extends Error {
7134
- errors;
7135
- props;
7136
- constructor(errors, props) {
7137
- const propsStr = props !== void 0 ? `
7138
- Props: ${JSON.stringify(props, null, 2)}` : "";
7139
- const message = `Document validation failed:
7140
- ${errors.map((e) => ` ${e.path}: ${e.message}`).join("\n")}${propsStr}`;
7141
- super(message);
7142
- this.name = "ComponentValidationError";
7143
- this.errors = errors;
7144
- this.props = props;
7145
- }
7146
- };
7147
- function validateComponentProps(schema, props) {
7082
+ import {
7083
+ DuplicateComponentError,
7084
+ ComponentValidationError as ComponentValidationError2
7085
+ } from "@json-to-office/shared/plugin";
7086
+ function validateComponentProps(schema, props, componentName) {
7148
7087
  return validateCustomComponentProps(schema.propsSchema, props, {
7149
7088
  clean: true,
7150
- applyDefaults: true
7089
+ applyDefaults: true,
7090
+ componentName
7151
7091
  });
7152
7092
  }
7153
7093
  function validateDocument(document, customComponents) {
@@ -7174,7 +7114,8 @@ function validateDocument(document, customComponents) {
7174
7114
  );
7175
7115
  const validation = validateComponentProps(
7176
7116
  versionEntry,
7177
- componentData.props
7117
+ componentData.props,
7118
+ customComponent.name
7178
7119
  );
7179
7120
  if (!validation.valid && validation.errors) {
7180
7121
  const indexedErrors = validation.errors.map(
@@ -7209,7 +7150,7 @@ var cleanComponentProps = getValidatedProps;
7209
7150
 
7210
7151
  // src/plugin/schema.ts
7211
7152
  import { Type as Type2 } from "@sinclair/typebox";
7212
- import { latestVersion as latestVersion2 } from "@json-to-office/shared-docx";
7153
+ import { latestVersion } from "@json-to-office/shared-docx";
7213
7154
  import {
7214
7155
  ReportPropsSchema,
7215
7156
  SectionPropsSchema,
@@ -7264,7 +7205,7 @@ function generateComponentSchemas(customComponents) {
7264
7205
  const schemas = {};
7265
7206
  for (const component of customComponents) {
7266
7207
  const versionKeys = Object.keys(component.versions);
7267
- const latest = latestVersion2(versionKeys);
7208
+ const latest = latestVersion(versionKeys);
7268
7209
  for (const v of versionKeys) {
7269
7210
  const entry = component.versions[v];
7270
7211
  const cacheKey = `component_${component.name}@${v}`;
@@ -7362,45 +7303,29 @@ function mergeSchemas(customComponents, standardSchemas) {
7362
7303
  };
7363
7304
  }
7364
7305
 
7365
- // src/styles/theme-resolver.ts
7366
- init_themes();
7367
- function resolveTheme2(theme) {
7368
- if (typeof theme === "string") {
7369
- const resolvedTheme = getTheme(theme);
7370
- if (resolvedTheme) {
7371
- return resolvedTheme;
7372
- }
7373
- return getTheme("minimal");
7374
- }
7375
- if (theme) {
7376
- return theme;
7377
- }
7378
- return getTheme("minimal");
7379
- }
7380
-
7381
- // src/styles/theme-validator.ts
7382
- import { validateTheme as validateThemeUnified } from "@json-to-office/shared-docx/validation/unified";
7383
- function validateTheme(theme) {
7384
- if (!theme) {
7385
- return void 0;
7386
- }
7387
- if (typeof theme === "string") {
7388
- return theme;
7389
- }
7390
- const result = validateThemeUnified(theme);
7391
- if (!result.valid) {
7392
- const errorSummary = result.errors?.map((e) => e.message).join(", ") || "Invalid theme";
7393
- throw new Error(`Invalid theme: ${errorSummary}`);
7394
- }
7395
- return result.data;
7396
- }
7397
-
7398
7306
  // src/plugin/createDocumentGenerator.ts
7399
7307
  function createBuilderImpl(state) {
7400
- const validatedTheme = validateTheme(state.theme);
7401
- const fullTheme = resolveTheme2(validatedTheme);
7402
7308
  const componentMap = new Map(state.components.map((c) => [c.name, c]));
7403
- async function processDocumentComponents(components, warningsCollector) {
7309
+ function resolveDocumentTheme(themeName) {
7310
+ if (state.customThemes) {
7311
+ if (state.customThemes[themeName]) {
7312
+ return state.customThemes[themeName];
7313
+ }
7314
+ const key = Object.keys(state.customThemes).find(
7315
+ (k) => k.toLowerCase() === themeName.toLowerCase()
7316
+ );
7317
+ if (key) {
7318
+ return state.customThemes[key];
7319
+ }
7320
+ }
7321
+ return getThemeWithFallback(themeName);
7322
+ }
7323
+ async function processDocumentComponents(components, warningsCollector, resolvedTheme, depth = 0) {
7324
+ if (depth > 20) {
7325
+ throw new Error(
7326
+ "Maximum component nesting depth exceeded (20). Check for circular component references."
7327
+ );
7328
+ }
7404
7329
  const processedComponents = [];
7405
7330
  for (const componentData of components) {
7406
7331
  const componentName = componentData?.name;
@@ -7430,7 +7355,9 @@ function createBuilderImpl(state) {
7430
7355
  if (componentWithName.children && Array.isArray(componentWithName.children)) {
7431
7356
  nestedChildren = await processDocumentComponents(
7432
7357
  componentWithName.children,
7433
- warningsCollector
7358
+ warningsCollector,
7359
+ resolvedTheme,
7360
+ depth + 1
7434
7361
  );
7435
7362
  }
7436
7363
  const versionLabel = componentWithName.version ? `${customComponent.name}@${componentWithName.version}` : customComponent.name;
@@ -7444,14 +7371,16 @@ function createBuilderImpl(state) {
7444
7371
  };
7445
7372
  const result = await versionEntry.render({
7446
7373
  props: cleanedProps,
7447
- theme: fullTheme,
7374
+ theme: resolvedTheme,
7448
7375
  addWarning,
7449
7376
  children: nestedChildren
7450
7377
  });
7451
7378
  const resultComponents = Array.isArray(result) ? result : [result];
7452
7379
  const processedResult = await processDocumentComponents(
7453
7380
  resultComponents,
7454
- warningsCollector
7381
+ warningsCollector,
7382
+ resolvedTheme,
7383
+ depth + 1
7455
7384
  );
7456
7385
  processedComponents.push(...processedResult);
7457
7386
  if (state.debug) {
@@ -7461,7 +7390,7 @@ function createBuilderImpl(state) {
7461
7390
  );
7462
7391
  }
7463
7392
  } catch (error) {
7464
- if (error instanceof ComponentValidationError) {
7393
+ if (error instanceof ComponentValidationError2) {
7465
7394
  throw error;
7466
7395
  }
7467
7396
  throw new Error(
@@ -7472,7 +7401,9 @@ function createBuilderImpl(state) {
7472
7401
  if ("children" in componentData && Array.isArray(componentData.children)) {
7473
7402
  const processedNested = await processDocumentComponents(
7474
7403
  componentData.children,
7475
- warningsCollector
7404
+ warningsCollector,
7405
+ resolvedTheme,
7406
+ depth + 1
7476
7407
  );
7477
7408
  processedComponents.push({
7478
7409
  ...componentData,
@@ -7486,18 +7417,19 @@ function createBuilderImpl(state) {
7486
7417
  return processedComponents;
7487
7418
  }
7488
7419
  function addComponent(component) {
7489
- if (state.componentNames.has(component.name)) {
7490
- throw new DuplicateComponentError(component.name);
7491
- }
7492
7420
  if (!component.name) {
7493
7421
  throw new Error("Component name is required");
7494
7422
  }
7423
+ if (state.componentNames.has(component.name)) {
7424
+ throw new DuplicateComponentError(component.name);
7425
+ }
7495
7426
  const newComponentNames = new Set(state.componentNames);
7496
7427
  newComponentNames.add(component.name);
7497
7428
  const newState = {
7498
7429
  components: [...state.components, component],
7499
7430
  componentNames: newComponentNames,
7500
7431
  theme: state.theme,
7432
+ customThemes: state.customThemes,
7501
7433
  debug: state.debug,
7502
7434
  enableCache: state.enableCache
7503
7435
  };
@@ -7512,10 +7444,13 @@ function createBuilderImpl(state) {
7512
7444
  internalDocument,
7513
7445
  state.components
7514
7446
  );
7447
+ const themeName = internalDocument.props.theme || "minimal";
7448
+ const docTheme = resolveDocumentTheme(themeName);
7515
7449
  const warnings = [];
7516
7450
  const processedComponents = await processDocumentComponents(
7517
7451
  internalDocument.children || [],
7518
- warnings
7452
+ warnings,
7453
+ docTheme
7519
7454
  );
7520
7455
  const processedDocument = {
7521
7456
  ...internalDocument,
@@ -7524,10 +7459,10 @@ function createBuilderImpl(state) {
7524
7459
  const [finalReportComponent] = normalizeDocument(processedDocument);
7525
7460
  const structure = await processDocument(
7526
7461
  finalReportComponent,
7527
- fullTheme,
7528
- "custom"
7462
+ docTheme,
7463
+ themeName
7529
7464
  );
7530
- const layout = applyLayout(structure.sections, fullTheme, "custom");
7465
+ const layout = applyLayout(structure.sections, docTheme, themeName);
7531
7466
  const generatedDocument = await renderDocument(structure, layout);
7532
7467
  return {
7533
7468
  document: generatedDocument,
@@ -7563,7 +7498,7 @@ function createBuilderImpl(state) {
7563
7498
  );
7564
7499
  return { valid: true };
7565
7500
  } catch (error) {
7566
- if (error instanceof ComponentValidationError) {
7501
+ if (error instanceof ComponentValidationError2) {
7567
7502
  return {
7568
7503
  valid: false,
7569
7504
  errors: error.errors.map((e) => ({
@@ -7603,10 +7538,13 @@ function createBuilderImpl(state) {
7603
7538
  internalDocument,
7604
7539
  state.components
7605
7540
  );
7541
+ const themeName = internalDocument.props.theme || "minimal";
7542
+ const docTheme = resolveDocumentTheme(themeName);
7606
7543
  const warnings = [];
7607
7544
  const processedComponents = await processDocumentComponents(
7608
7545
  internalDocument.children || [],
7609
- warnings
7546
+ warnings,
7547
+ docTheme
7610
7548
  );
7611
7549
  const processedDocument = {
7612
7550
  ...internalDocument,
@@ -7638,6 +7576,7 @@ function createDocumentGenerator(options) {
7638
7576
  components: [],
7639
7577
  componentNames: /* @__PURE__ */ new Set(),
7640
7578
  theme: options.theme,
7579
+ customThemes: options.customThemes,
7641
7580
  debug: options.debug ?? false,
7642
7581
  enableCache: options.enableCache ?? false
7643
7582
  };
@@ -7656,7 +7595,7 @@ var export_mergeConfigs = cache_exports.mergeConfigs;
7656
7595
  export {
7657
7596
  CacheKeyGenerator,
7658
7597
  export_ComponentCacheAnalytics as ComponentCacheAnalytics,
7659
- ComponentValidationError,
7598
+ ComponentValidationError2 as ComponentValidationError,
7660
7599
  DocumentGenerator as CoreDocumentGenerator,
7661
7600
  export_DEFAULT_CACHE_CONFIG as DEFAULT_CACHE_CONFIG,
7662
7601
  export_MemoryCache as MemoryCache,