@json-to-office/core-pptx 0.3.0 → 0.8.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.
@@ -4,5 +4,6 @@
4
4
  import type PptxGenJS from 'pptxgenjs';
5
5
  import type { PptxThemeConfig, PipelineWarning } from '../types';
6
6
  import type { PptxHighchartsProps } from '@json-to-office/shared-pptx';
7
- export declare function renderHighchartsComponent(slide: PptxGenJS.Slide, props: PptxHighchartsProps, _theme: PptxThemeConfig, _warnings?: PipelineWarning[]): Promise<void>;
7
+ import type { HighchartsServiceConfig } from '@json-to-office/shared';
8
+ export declare function renderHighchartsComponent(slide: PptxGenJS.Slide, props: PptxHighchartsProps, _theme: PptxThemeConfig, _warnings?: PipelineWarning[], servicesConfig?: HighchartsServiceConfig): Promise<void>;
8
9
  //# sourceMappingURL=highcharts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"highcharts.d.ts","sourceRoot":"","sources":["../../src/components/highcharts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAyDvE,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,eAAe,EACvB,SAAS,CAAC,EAAE,eAAe,EAAE,GAC5B,OAAO,CAAC,IAAI,CAAC,CAaf"}
1
+ {"version":3,"file":"highcharts.d.ts","sourceRoot":"","sources":["../../src/components/highcharts.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAmEtE,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,KAAK,EAAE,mBAAmB,EAC1B,MAAM,EAAE,eAAe,EACvB,SAAS,CAAC,EAAE,eAAe,EAAE,EAC7B,cAAc,CAAC,EAAE,uBAAuB,GACvC,OAAO,CAAC,IAAI,CAAC,CAaf"}
@@ -3,11 +3,12 @@
3
3
  */
4
4
  import type PptxGenJS from 'pptxgenjs';
5
5
  import type { PptxThemeConfig, PptxComponentInput, PipelineWarning, SlideContext } from '../types';
6
+ import type { ServicesConfig } from '@json-to-office/shared';
6
7
  export { renderTextComponent } from './text';
7
8
  export { renderImageComponent } from './image';
8
9
  export { renderShapeComponent } from './shape';
9
10
  export { renderTableComponent } from './table';
10
11
  export { renderHighchartsComponent } from './highcharts';
11
12
  export { renderChartComponent } from './chart';
12
- export declare function renderComponent(slide: PptxGenJS.Slide, component: PptxComponentInput, theme: PptxThemeConfig, pptx: PptxGenJS, warnings?: PipelineWarning[], slideCtx?: SlideContext): Promise<void>;
13
+ export declare function renderComponent(slide: PptxGenJS.Slide, component: PptxComponentInput, theme: PptxThemeConfig, pptx: PptxGenJS, warnings?: PipelineWarning[], slideCtx?: SlideContext, services?: ServicesConfig): Promise<void>;
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AASnG,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE/C,wBAAsB,eAAe,CACnC,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,SAAS,EAAE,kBAAkB,EAC7B,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,SAAS,EACf,QAAQ,CAAC,EAAE,eAAe,EAAE,EAC5B,QAAQ,CAAC,EAAE,YAAY,GACtB,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,SAAS,MAAM,WAAW,CAAC;AACvC,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,eAAe,EACf,YAAY,EACb,MAAM,UAAU,CAAC;AAClB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAS7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE/C,wBAAsB,eAAe,CACnC,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,SAAS,EAAE,kBAAkB,EAC7B,KAAK,EAAE,eAAe,EACtB,IAAI,EAAE,SAAS,EACf,QAAQ,CAAC,EAAE,eAAe,EAAE,EAC5B,QAAQ,CAAC,EAAE,YAAY,EACvB,QAAQ,CAAC,EAAE,cAAc,GACxB,OAAO,CAAC,IAAI,CAAC,CAuCf"}
@@ -5,11 +5,13 @@
5
5
  /// <reference types="node" />
6
6
  import PptxGenJS from 'pptxgenjs';
7
7
  import type { PresentationComponentDefinition, PptxThemeConfig, PipelineWarning } from '../types';
8
+ import type { ServicesConfig } from '@json-to-office/shared';
8
9
  /**
9
10
  * Options for the generation pipeline
10
11
  */
11
12
  export interface GenerationOptions {
12
13
  customThemes?: Record<string, PptxThemeConfig>;
14
+ services?: ServicesConfig;
13
15
  }
14
16
  /**
15
17
  * Result from generateBufferWithWarnings
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/core/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,OAAO,SAAS,MAAM,WAAW,CAAC;AAGlC,OAAO,KAAK,EAAE,+BAA+B,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAKlG;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,OAAO,GAClB,UAAU,IAAI,+BAA+B,CAI/C;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,+BAA+B,EACzC,OAAO,CAAC,EAAE,iBAAiB,EAC3B,QAAQ,CAAC,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC,SAAS,CAAC,CAOpB;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,GAAG,+BAA+B,EACpD,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,GAAG,+BAA+B,EACpD,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,CAkB3B;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,GAAG,+BAA+B,EACpD,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAIf;AAuBD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;CAQjC,CAAC"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/core/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,OAAO,SAAS,MAAM,WAAW,CAAC;AAGlC,OAAO,KAAK,EACV,+BAA+B,EAC/B,eAAe,EACf,eAAe,EAChB,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAI7D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAC/C,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B;AAED;;GAEG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,OAAO,GAClB,UAAU,IAAI,+BAA+B,CAI/C;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,+BAA+B,EACzC,OAAO,CAAC,EAAE,iBAAiB,EAC3B,QAAQ,CAAC,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC,SAAS,CAAC,CAOpB;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,UAAU,EAAE,MAAM,GAAG,+BAA+B,EACpD,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAGjB;AAED;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,UAAU,EAAE,MAAM,GAAG,+BAA+B,EACpD,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,gBAAgB,CAAC,CAkB3B;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,MAAM,GAAG,+BAA+B,EACpD,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAGf;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAIf;AAyBD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,EACf,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAIf;AAED;;GAEG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;CAQjC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/core/render.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,qBAAqB,EAAE,eAAe,EAAgB,MAAM,UAAU,CAAC;AAOrF,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,qBAAqB,EAChC,QAAQ,CAAC,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC,SAAS,CAAC,CAiJpB"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/core/render.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EACV,qBAAqB,EACrB,eAAe,EAEhB,MAAM,UAAU,CAAC;AAUlB,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,qBAAqB,EAChC,QAAQ,CAAC,EAAE,eAAe,EAAE,GAC3B,OAAO,CAAC,SAAS,CAAC,CAuOpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"structure.d.ts","sourceRoot":"","sources":["../../src/core/structure.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAEV,+BAA+B,EAC/B,qBAAqB,EAGtB,MAAM,UAAU,CAAC;AAIlB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,+BAA+B,EACzC,OAAO,CAAC,EAAE,iBAAiB,GAC1B,qBAAqB,CA4EvB"}
1
+ {"version":3,"file":"structure.d.ts","sourceRoot":"","sources":["../../src/core/structure.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAEV,+BAA+B,EAC/B,qBAAqB,EAGtB,MAAM,UAAU,CAAC;AAQlB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIrD,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,+BAA+B,EACzC,OAAO,CAAC,EAAE,iBAAiB,GAC1B,qBAAqB,CA6GvB"}
package/dist/index.js CHANGED
@@ -212,11 +212,113 @@ function getPptxTheme(name) {
212
212
  }
213
213
  var pptxThemes = PPTX_THEMES;
214
214
 
215
+ // src/utils/componentDefaults.ts
216
+ import { mergeWithDefaults } from "@json-to-office/shared";
217
+ function getComponentDefaults(theme) {
218
+ return theme.componentDefaults || {};
219
+ }
220
+ function getTextDefaults(theme) {
221
+ return getComponentDefaults(theme).text || {};
222
+ }
223
+ function getImageDefaults(theme) {
224
+ return getComponentDefaults(theme).image || {};
225
+ }
226
+ function getShapeDefaults(theme) {
227
+ return getComponentDefaults(theme).shape || {};
228
+ }
229
+ function getTableDefaults(theme) {
230
+ return getComponentDefaults(theme).table || {};
231
+ }
232
+ function getHighchartsDefaults(theme) {
233
+ return getComponentDefaults(theme).highcharts || {};
234
+ }
235
+ function getChartDefaults(theme) {
236
+ return getComponentDefaults(theme).chart || {};
237
+ }
238
+ function getCustomComponentDefaults(theme, componentName) {
239
+ const defaults = getComponentDefaults(theme);
240
+ return defaults?.[componentName] || {};
241
+ }
242
+ function resolveTextProps(props, theme) {
243
+ return mergeWithDefaults(props, getTextDefaults(theme));
244
+ }
245
+ function resolveImageProps(props, theme) {
246
+ return mergeWithDefaults(props, getImageDefaults(theme));
247
+ }
248
+ function resolveShapeProps(props, theme) {
249
+ return mergeWithDefaults(props, getShapeDefaults(theme));
250
+ }
251
+ function resolveTableProps(props, theme) {
252
+ return mergeWithDefaults(props, getTableDefaults(theme));
253
+ }
254
+ function resolveHighchartsProps(props, theme) {
255
+ return mergeWithDefaults(props, getHighchartsDefaults(theme));
256
+ }
257
+ function resolveChartProps(props, theme) {
258
+ return mergeWithDefaults(props, getChartDefaults(theme));
259
+ }
260
+ function resolveCustomComponentProps(props, theme, componentName) {
261
+ const defaults = getCustomComponentDefaults(theme, componentName);
262
+ return mergeWithDefaults(props, defaults);
263
+ }
264
+ var TYPE_GETTERS = {
265
+ text: getTextDefaults,
266
+ image: getImageDefaults,
267
+ shape: getShapeDefaults,
268
+ table: getTableDefaults,
269
+ highcharts: getHighchartsDefaults,
270
+ chart: getChartDefaults
271
+ };
272
+ function getDefaultsForType(componentName, theme) {
273
+ const getter = TYPE_GETTERS[componentName];
274
+ return getter ? getter(theme) : getCustomComponentDefaults(theme, componentName);
275
+ }
276
+
277
+ // src/utils/resolveComponentTree.ts
278
+ var RESOLVER_MAP = {
279
+ text: resolveTextProps,
280
+ image: resolveImageProps,
281
+ shape: resolveShapeProps,
282
+ table: resolveTableProps,
283
+ highcharts: resolveHighchartsProps,
284
+ chart: resolveChartProps
285
+ };
286
+ function resolveComponentDefaults(component, theme) {
287
+ const resolver = RESOLVER_MAP[component.name];
288
+ const resolvedProps = resolver ? resolver(component.props, theme) : resolveCustomComponentProps(
289
+ component.props,
290
+ theme,
291
+ component.name
292
+ );
293
+ return { ...component, props: resolvedProps };
294
+ }
295
+ function resolveComponentTree(components, theme) {
296
+ return components.map((component) => {
297
+ const resolved = resolveComponentDefaults(component, theme);
298
+ if (resolved.children && resolved.children.length > 0) {
299
+ return {
300
+ ...resolved,
301
+ children: resolveComponentTree(resolved.children, theme)
302
+ };
303
+ }
304
+ return resolved;
305
+ });
306
+ }
307
+
215
308
  // src/core/structure.ts
309
+ import { mergeWithDefaults as mergeWithDefaults2 } from "@json-to-office/shared";
216
310
  function processPresentation(document, options) {
217
311
  const { props, children = [] } = document;
218
312
  const themeName = props.theme ?? "default";
219
- const theme = options?.customThemes?.[themeName] ?? getPptxTheme(themeName);
313
+ const baseTheme = options?.customThemes?.[themeName] ?? getPptxTheme(themeName);
314
+ const presDefaults = props.componentDefaults;
315
+ const theme = presDefaults ? {
316
+ ...baseTheme,
317
+ componentDefaults: mergeWithDefaults2(
318
+ presDefaults,
319
+ baseTheme.componentDefaults || {}
320
+ )
321
+ } : baseTheme;
220
322
  const slideWidth = props.slideWidth ?? 10;
221
323
  const slideHeight = props.slideHeight ?? 7.5;
222
324
  let templates;
@@ -225,7 +327,12 @@ function processPresentation(document, options) {
225
327
  const effectiveGrid = mergeGridConfigs(props.grid, m.grid);
226
328
  const resolvedPhs = m.placeholders?.map((ph) => {
227
329
  if (!ph.grid) return ph;
228
- const abs = resolveGridPosition(ph.grid, effectiveGrid, slideWidth, slideHeight);
330
+ const abs = resolveGridPosition(
331
+ ph.grid,
332
+ effectiveGrid,
333
+ slideWidth,
334
+ slideHeight
335
+ );
229
336
  return {
230
337
  ...ph,
231
338
  x: ph.x ?? abs.x,
@@ -235,8 +342,14 @@ function processPresentation(document, options) {
235
342
  grid: void 0
236
343
  };
237
344
  });
238
- const resolvedObjects = m.objects?.map(
239
- (obj) => resolveComponentGridPosition(obj, effectiveGrid, slideWidth, slideHeight)
345
+ const defaultedObjects = m.objects ? resolveComponentTree(m.objects, theme) : void 0;
346
+ const resolvedObjects = defaultedObjects?.map(
347
+ (obj) => resolveComponentGridPosition(
348
+ obj,
349
+ effectiveGrid,
350
+ slideWidth,
351
+ slideHeight
352
+ )
240
353
  );
241
354
  return { ...m, placeholders: resolvedPhs, objects: resolvedObjects };
242
355
  });
@@ -250,8 +363,9 @@ function processPresentation(document, options) {
250
363
  slideComponents.push(slideChild);
251
364
  }
252
365
  }
366
+ const resolvedComponents = resolveComponentTree(slideComponents, theme);
253
367
  slides.push({
254
- components: slideComponents,
368
+ components: resolvedComponents,
255
369
  background: child.props.background,
256
370
  notes: child.props.notes,
257
371
  layout: child.props.layout,
@@ -275,7 +389,8 @@ function processPresentation(document, options) {
275
389
  rtlMode: props.rtlMode ?? false,
276
390
  pageNumberFormat: props.pageNumberFormat ?? "9",
277
391
  slides,
278
- templates
392
+ templates,
393
+ services: options?.services
279
394
  };
280
395
  }
281
396
 
@@ -779,19 +894,27 @@ function isNodeEnvironment() {
779
894
  // src/components/highcharts.ts
780
895
  var PX_PER_INCH = 96;
781
896
  var DEFAULT_EXPORT_SERVER_URL = "http://localhost:7801";
782
- function getExportServerUrl(propsUrl) {
783
- return propsUrl || process.env.HIGHCHARTS_SERVER_URL || DEFAULT_EXPORT_SERVER_URL;
897
+ function getExportServerUrl(propsUrl, servicesUrl) {
898
+ const raw = propsUrl || servicesUrl || DEFAULT_EXPORT_SERVER_URL;
899
+ return raw.startsWith("http") ? raw : `http://${raw}`;
784
900
  }
785
- async function generateChart(config) {
901
+ async function generateChart(config, servicesConfig) {
786
902
  if (!isNodeEnvironment()) {
787
903
  throw new Error(
788
904
  "Highcharts export server requires a Node.js environment. Chart generation is not available in browser environments."
789
905
  );
790
906
  }
791
- const serverUrl = getExportServerUrl(config.serverUrl);
907
+ const serverUrl = getExportServerUrl(
908
+ config.serverUrl,
909
+ servicesConfig?.serverUrl
910
+ );
911
+ const headers = {
912
+ "Content-Type": "application/json",
913
+ ...servicesConfig?.headers
914
+ };
792
915
  const response = await fetch(`${serverUrl}/export`, {
793
916
  method: "POST",
794
- headers: { "Content-Type": "application/json" },
917
+ headers,
795
918
  body: JSON.stringify({
796
919
  infile: config.options,
797
920
  type: "png",
@@ -816,8 +939,8 @@ Cause: ${error instanceof Error ? error.message : String(error)}`
816
939
  height: config.options.chart?.height ?? 720
817
940
  };
818
941
  }
819
- async function renderHighchartsComponent(slide, props, _theme, _warnings) {
820
- const chart = await generateChart(props);
942
+ async function renderHighchartsComponent(slide, props, _theme, _warnings, servicesConfig) {
943
+ const chart = await generateChart(props, servicesConfig);
821
944
  const w = props.w ?? chart.width / PX_PER_INCH;
822
945
  const h = props.h ?? chart.height / PX_PER_INCH;
823
946
  slide.addImage({
@@ -927,7 +1050,7 @@ function renderChartComponent(slide, props, theme, _pptx, warnings) {
927
1050
  }
928
1051
 
929
1052
  // src/components/index.ts
930
- async function renderComponent(slide, component, theme, pptx, warnings, slideCtx) {
1053
+ async function renderComponent(slide, component, theme, pptx, warnings, slideCtx, services) {
931
1054
  if (component.enabled === false) return;
932
1055
  const { name, props } = component;
933
1056
  const p = props;
@@ -945,13 +1068,24 @@ async function renderComponent(slide, component, theme, pptx, warnings, slideCtx
945
1068
  renderTableComponent(slide, p, theme, pptx, warnings);
946
1069
  break;
947
1070
  case "highcharts":
948
- await renderHighchartsComponent(slide, p, theme, warnings);
1071
+ await renderHighchartsComponent(
1072
+ slide,
1073
+ p,
1074
+ theme,
1075
+ warnings,
1076
+ services?.highcharts
1077
+ );
949
1078
  break;
950
1079
  case "chart":
951
1080
  renderChartComponent(slide, p, theme, pptx, warnings);
952
1081
  break;
953
1082
  default:
954
- warn(warnings, W.UNKNOWN_COMPONENT, `Unknown PPTX component type: ${name}`, { component: name });
1083
+ warn(
1084
+ warnings,
1085
+ W.UNKNOWN_COMPONENT,
1086
+ `Unknown PPTX component type: ${name}`,
1087
+ { component: name }
1088
+ );
955
1089
  }
956
1090
  }
957
1091
 
@@ -984,6 +1118,7 @@ function buildSlideTemplateProps(def, theme, warnings) {
984
1118
  }
985
1119
 
986
1120
  // src/core/render.ts
1121
+ import { mergeWithDefaults as mergeWithDefaults3 } from "@json-to-office/shared";
987
1122
  async function renderPresentation(processed, warnings) {
988
1123
  const pptx = new PptxGenJS();
989
1124
  if (processed.metadata.title) pptx.title = processed.metadata.title;
@@ -1003,10 +1138,16 @@ async function renderPresentation(processed, warnings) {
1003
1138
  headFontFace: processed.theme.fonts.heading,
1004
1139
  bodyFontFace: processed.theme.fonts.body
1005
1140
  };
1006
- const templateMap = new Map(processed.templates?.map((m) => [m.name, m]) ?? []);
1141
+ const templateMap = new Map(
1142
+ processed.templates?.map((m) => [m.name, m]) ?? []
1143
+ );
1007
1144
  if (processed.templates) {
1008
1145
  for (const templateDef of processed.templates) {
1009
- const templateProps = buildSlideTemplateProps(templateDef, processed.theme, warnings);
1146
+ const templateProps = buildSlideTemplateProps(
1147
+ templateDef,
1148
+ processed.theme,
1149
+ warnings
1150
+ );
1010
1151
  pptx.defineSlideMaster(templateProps);
1011
1152
  }
1012
1153
  }
@@ -1021,7 +1162,13 @@ async function renderPresentation(processed, warnings) {
1021
1162
  const slide = slideData.template ? pptx.addSlide({ masterName: slideData.template }) : pptx.addSlide();
1022
1163
  if (slideData.background) {
1023
1164
  if (slideData.background.color) {
1024
- slide.background = { color: resolveColor(slideData.background.color, processed.theme, warnings) };
1165
+ slide.background = {
1166
+ color: resolveColor(
1167
+ slideData.background.color,
1168
+ processed.theme,
1169
+ warnings
1170
+ )
1171
+ };
1025
1172
  } else if (slideData.background.image) {
1026
1173
  if (slideData.background.image.path) {
1027
1174
  slide.background = { path: slideData.background.image.path };
@@ -1035,12 +1182,25 @@ async function renderPresentation(processed, warnings) {
1035
1182
  }
1036
1183
  const templateDef = slideData.template ? templateMap.get(slideData.template) : void 0;
1037
1184
  if (slideData.template && !templateDef) {
1038
- warn(warnings, W.MISSING_TEMPLATE, `Unknown template "${slideData.template}". Available: ${[...templateMap.keys()].join(", ")}`, { slide: slideIdx });
1185
+ warn(
1186
+ warnings,
1187
+ W.MISSING_TEMPLATE,
1188
+ `Unknown template "${slideData.template}". Available: ${[...templateMap.keys()].join(", ")}`,
1189
+ { slide: slideIdx }
1190
+ );
1039
1191
  }
1040
1192
  const effectiveGrid = mergeGridConfigs(processed.grid, templateDef?.grid);
1041
1193
  if (templateDef?.objects) {
1042
1194
  for (const obj of templateDef.objects) {
1043
- await renderComponent(slide, obj, processed.theme, pptx, warnings, slideCtx);
1195
+ await renderComponent(
1196
+ slide,
1197
+ obj,
1198
+ processed.theme,
1199
+ pptx,
1200
+ warnings,
1201
+ slideCtx,
1202
+ processed.services
1203
+ );
1044
1204
  }
1045
1205
  }
1046
1206
  for (const component of slideData.components) {
@@ -1051,15 +1211,32 @@ async function renderPresentation(processed, warnings) {
1051
1211
  processed.slideHeight,
1052
1212
  warnings
1053
1213
  );
1054
- await renderComponent(slide, resolved, processed.theme, pptx, warnings, slideCtx);
1214
+ await renderComponent(
1215
+ slide,
1216
+ resolved,
1217
+ processed.theme,
1218
+ pptx,
1219
+ warnings,
1220
+ slideCtx,
1221
+ processed.services
1222
+ );
1055
1223
  }
1056
1224
  if (slideData.placeholders) {
1057
1225
  if (templateDef) {
1058
- const phMap = new Map(templateDef.placeholders?.map((p) => [p.name, p]) ?? []);
1059
- for (const [phName, component] of Object.entries(slideData.placeholders)) {
1226
+ const phMap = new Map(
1227
+ templateDef.placeholders?.map((p) => [p.name, p]) ?? []
1228
+ );
1229
+ for (const [phName, component] of Object.entries(
1230
+ slideData.placeholders
1231
+ )) {
1060
1232
  const phDef = phMap.get(phName);
1061
1233
  if (!phDef) {
1062
- warn(warnings, W.UNKNOWN_PLACEHOLDER, `Unknown placeholder "${phName}" in template "${slideData.template}". Available: ${[...phMap.keys()].join(", ")}`, { slide: slideIdx });
1234
+ warn(
1235
+ warnings,
1236
+ W.UNKNOWN_PLACEHOLDER,
1237
+ `Unknown placeholder "${phName}" in template "${slideData.template}". Available: ${[...phMap.keys()].join(", ")}`,
1238
+ { slide: slideIdx }
1239
+ );
1063
1240
  continue;
1064
1241
  }
1065
1242
  const gridResolved = resolveComponentGridPosition(
@@ -1069,28 +1246,61 @@ async function renderPresentation(processed, warnings) {
1069
1246
  processed.slideHeight,
1070
1247
  warnings
1071
1248
  );
1249
+ const typeDefaults = getDefaultsForType(
1250
+ component.name,
1251
+ processed.theme
1252
+ );
1072
1253
  const posDefaults = {};
1073
1254
  if (phDef.x != null) posDefaults.x = phDef.x;
1074
1255
  if (phDef.y != null) posDefaults.y = phDef.y;
1075
1256
  if (phDef.w != null) posDefaults.w = phDef.w;
1076
1257
  if (phDef.h != null) posDefaults.h = phDef.h;
1077
- const props = { ...posDefaults, ...phDef.defaults?.props ?? {}, ...gridResolved.props };
1078
- await renderComponent(slide, { ...gridResolved, props }, processed.theme, pptx, warnings, slideCtx);
1258
+ let props = mergeWithDefaults3(posDefaults, typeDefaults);
1259
+ props = mergeWithDefaults3(phDef.defaults?.props ?? {}, props);
1260
+ props = mergeWithDefaults3(gridResolved.props, props);
1261
+ await renderComponent(
1262
+ slide,
1263
+ { ...gridResolved, props },
1264
+ processed.theme,
1265
+ pptx,
1266
+ warnings,
1267
+ slideCtx,
1268
+ processed.services
1269
+ );
1079
1270
  }
1080
1271
  } else {
1081
- for (const [phName, component] of Object.entries(slideData.placeholders)) {
1082
- const hasPosition = component.props.x != null || component.props.y != null || component.props.grid;
1272
+ for (const [phName, component] of Object.entries(
1273
+ slideData.placeholders
1274
+ )) {
1275
+ const defaulted = resolveComponentDefaults(
1276
+ component,
1277
+ processed.theme
1278
+ );
1279
+ const hasPosition = defaulted.props.x != null || defaulted.props.y != null || defaulted.props.grid;
1083
1280
  if (hasPosition) {
1084
1281
  const resolved = resolveComponentGridPosition(
1085
- component,
1282
+ defaulted,
1086
1283
  effectiveGrid,
1087
1284
  processed.slideWidth,
1088
1285
  processed.slideHeight,
1089
1286
  warnings
1090
1287
  );
1091
- await renderComponent(slide, resolved, processed.theme, pptx, warnings, slideCtx);
1288
+ await renderComponent(
1289
+ slide,
1290
+ resolved,
1291
+ processed.theme,
1292
+ pptx,
1293
+ warnings,
1294
+ slideCtx,
1295
+ processed.services
1296
+ );
1092
1297
  } else {
1093
- warn(warnings, W.PLACEHOLDER_NO_POSITION, `Placeholder "${phName}" has no template and no explicit position \u2014 skipped`, { slide: slideIdx });
1298
+ warn(
1299
+ warnings,
1300
+ W.PLACEHOLDER_NO_POSITION,
1301
+ `Placeholder "${phName}" has no template and no explicit position \u2014 skipped`,
1302
+ { slide: slideIdx }
1303
+ );
1094
1304
  }
1095
1305
  }
1096
1306
  }
@@ -1413,7 +1623,8 @@ function createBuilderImpl(state) {
1413
1623
  componentNames: newComponentNames,
1414
1624
  theme: state.theme,
1415
1625
  customThemes: state.customThemes,
1416
- debug: state.debug
1626
+ debug: state.debug,
1627
+ services: state.services
1417
1628
  };
1418
1629
  return createBuilderImpl(
1419
1630
  newState
@@ -1438,7 +1649,8 @@ function createBuilderImpl(state) {
1438
1649
  children: processedChildren
1439
1650
  };
1440
1651
  const processed = processPresentation(processedDocument, {
1441
- customThemes: state.customThemes
1652
+ customThemes: state.customThemes,
1653
+ services: state.services
1442
1654
  });
1443
1655
  const pptx = await renderPresentation(processed, warnings);
1444
1656
  const data = await pptx.write({ outputType: "nodebuffer" });
@@ -1548,7 +1760,8 @@ function createPresentationGenerator(options = {}) {
1548
1760
  componentNames: /* @__PURE__ */ new Set(),
1549
1761
  theme: options.theme,
1550
1762
  customThemes: options.customThemes,
1551
- debug: options.debug ?? false
1763
+ debug: options.debug ?? false,
1764
+ services: options.services
1552
1765
  };
1553
1766
  return createBuilderImpl(initialState);
1554
1767
  }