@json-to-office/core-docx 0.27.0 → 0.28.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.
@@ -27,6 +27,12 @@ export interface DocumentGeneratorOptions {
27
27
  deterministic?: boolean;
28
28
  /** Default build timestamp for generated metadata. */
29
29
  generatedAt?: string | Date;
30
+ /**
31
+ * Directory that relative asset paths (image `path` props) resolve against.
32
+ * Per-call `options.baseDir` overrides it; defaults to `process.cwd()`
33
+ * when neither is set (#142).
34
+ */
35
+ baseDir?: string;
30
36
  }
31
37
  /**
32
38
  * Create a document generator with chainable component registration.
@@ -1 +1 @@
1
- {"version":3,"file":"createDocumentGenerator.d.ts","sourceRoot":"","sources":["../../src/plugin/createDocumentGenerator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAK7C,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9E,OAAO,KAAK,EAEV,wBAAwB,EAOxB,2BAA2B,EAC5B,MAAM,SAAS,CAAC;AAmBjB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,kEAAkE;IAClE,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,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;IAChB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,oFAAoF;IACpF,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,2BAA2B,CAAC;IACzC,gFAAgF;IAChF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAsoBD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,GAChC,wBAAwB,CAAC,SAAS,EAAE,CAAC,CAgBvC"}
1
+ {"version":3,"file":"createDocumentGenerator.d.ts","sourceRoot":"","sources":["../../src/plugin/createDocumentGenerator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;AAK7C,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9E,OAAO,KAAK,EAEV,wBAAwB,EAOxB,2BAA2B,EAC5B,MAAM,SAAS,CAAC;AAmBjB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,kEAAkE;IAClE,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,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;IAChB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,oFAAoF;IACpF,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB;;;;OAIG;IACH,UAAU,CAAC,EAAE,2BAA2B,CAAC;IACzC,gFAAgF;IAChF,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,sDAAsD;IACtD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAyoBD;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,wBAAwB,GAChC,wBAAwB,CAAC,SAAS,EAAE,CAAC,CAiBvC"}
@@ -2870,9 +2870,34 @@ import {
2870
2870
  } from "docx";
2871
2871
 
2872
2872
  // src/utils/imageUtils.ts
2873
- init_widthUtils();
2874
2873
  import { readFileSync } from "fs";
2875
2874
  import probe from "probe-image-size";
2875
+
2876
+ // src/utils/generationContext.ts
2877
+ import { AsyncLocalStorage } from "async_hooks";
2878
+ import { isAbsolute, resolve } from "path";
2879
+ var generationDateStorage = new AsyncLocalStorage();
2880
+ function runWithGenerationDate(date, callback) {
2881
+ return generationDateStorage.run(date, callback);
2882
+ }
2883
+ function getGenerationDate() {
2884
+ return generationDateStorage.getStore() ?? /* @__PURE__ */ new Date();
2885
+ }
2886
+ var baseDirStorage = new AsyncLocalStorage();
2887
+ function runWithBaseDir(baseDir, callback) {
2888
+ return baseDir === void 0 ? callback() : baseDirStorage.run(resolve(baseDir), callback);
2889
+ }
2890
+ function getBaseDir() {
2891
+ return baseDirStorage.getStore();
2892
+ }
2893
+ function resolveFromBaseDir(filePath) {
2894
+ const base = baseDirStorage.getStore();
2895
+ if (!base || isAbsolute(filePath)) return filePath;
2896
+ return resolve(base, filePath);
2897
+ }
2898
+
2899
+ // src/utils/imageUtils.ts
2900
+ init_widthUtils();
2876
2901
  import { ImageRun } from "docx";
2877
2902
  function parseWidthValue(width, availableWidthPx) {
2878
2903
  if (typeof width === "number") {
@@ -3048,7 +3073,7 @@ async function getImageBuffer(imagePath) {
3048
3073
  if (isValidUrl(imagePath)) {
3049
3074
  return await downloadImageFromUrl(imagePath);
3050
3075
  }
3051
- return { buffer: readFileSync(imagePath) };
3076
+ return { buffer: readFileSync(resolveFromBaseDir(imagePath)) };
3052
3077
  }
3053
3078
  async function getImageDimensions(imagePath) {
3054
3079
  try {
@@ -4120,16 +4145,6 @@ function parseTextWithHyperlinks(text, baseStyle = {}, options = {}) {
4120
4145
  return runs;
4121
4146
  }
4122
4147
 
4123
- // src/utils/generationContext.ts
4124
- import { AsyncLocalStorage } from "async_hooks";
4125
- var generationDateStorage = new AsyncLocalStorage();
4126
- function runWithGenerationDate(date, callback) {
4127
- return generationDateStorage.run(date, callback);
4128
- }
4129
- function getGenerationDate() {
4130
- return generationDateStorage.getStore() ?? /* @__PURE__ */ new Date();
4131
- }
4132
-
4133
4148
  // src/utils/placeholderProcessor.ts
4134
4149
  function styledPlaceholderText(text, context) {
4135
4150
  return new TextRun2({
@@ -4476,8 +4491,9 @@ async function renderComponentWithCache(component, theme, themeName, context, by
4476
4491
  const themeHash = createThemeHash(theme);
4477
4492
  const contextKey = context?.section ? `${context.section.currentLayout}:${context.section.columnCount}` : "no-section";
4478
4493
  const generationDateKey = getGenerationDate().toISOString();
4494
+ const baseDirKey = getBaseDir() ?? "";
4479
4495
  const childrenKey = "children" in component && component.children ? `:children:${JSON.stringify(component.children)}` : "";
4480
- const cacheKey = `component:${component.name}:${themeHash}:${contextKey}:${generationDateKey}:${componentProps}${childrenKey}`;
4496
+ const cacheKey = `component:${component.name}:${themeHash}:${contextKey}:${generationDateKey}:${baseDirKey}:${componentProps}${childrenKey}`;
4481
4497
  const cached = await componentCache.get(cacheKey);
4482
4498
  if (cached) {
4483
4499
  return cached.result;
@@ -7172,14 +7188,14 @@ function visualToImageOptions(props) {
7172
7188
  ...props.keepLines !== void 0 && { keepLines: props.keepLines }
7173
7189
  };
7174
7190
  }
7175
- async function rasterize(presentation, dpi, propsServerUrl, serviceConfig) {
7191
+ async function rasterize(presentation, dpi, propsServerUrl, serviceConfig, baseDir) {
7176
7192
  if (!isNodeEnvironment()) {
7177
7193
  throw new Error(
7178
7194
  "Visual rasterization requires a Node.js environment. It is not available in browser environments."
7179
7195
  );
7180
7196
  }
7181
7197
  if (serviceConfig?.render) {
7182
- return serviceConfig.render({ presentation, dpi });
7198
+ return serviceConfig.render({ presentation, dpi, baseDir });
7183
7199
  }
7184
7200
  const serverUrl = resolveServiceUrl(
7185
7201
  propsServerUrl,
@@ -7189,7 +7205,7 @@ async function rasterize(presentation, dpi, propsServerUrl, serviceConfig) {
7189
7205
  const response = await postJsonToService({
7190
7206
  url: serverUrl,
7191
7207
  path: "/rasterize",
7192
- body: { presentation, dpi },
7208
+ body: { presentation, dpi, ...baseDir !== void 0 && { baseDir } },
7193
7209
  headers: serviceConfig?.headers,
7194
7210
  serviceLabel: "PPTX rasterization service",
7195
7211
  onUnreachable: (url, cause) => `PPTX rasterization service is not reachable at ${url}. Configure services.pptx with a \`render\` callback or a running \`serverUrl\`.
@@ -7222,7 +7238,8 @@ async function renderVisualComponent(component, theme, themeName, context) {
7222
7238
  presentation,
7223
7239
  dpi,
7224
7240
  props.serverUrl,
7225
- serviceConfig
7241
+ serviceConfig,
7242
+ getBaseDir()
7226
7243
  );
7227
7244
  return await createImage(
7228
7245
  result.base64DataUri,
@@ -7316,10 +7333,13 @@ function coreProperties(metadata) {
7316
7333
  async function renderDocument(structure, layout, options) {
7317
7334
  return runWithGenerationDate(
7318
7335
  structure.metadata.date,
7319
- () => globalBookmarkRegistry.runScoped(
7320
- () => globalRevisionIdRegistry.runScoped(
7321
- () => globalNumberingRegistry.runScoped(
7322
- () => renderDocumentScoped(structure, layout, options)
7336
+ () => runWithBaseDir(
7337
+ options?.baseDir,
7338
+ () => globalBookmarkRegistry.runScoped(
7339
+ () => globalRevisionIdRegistry.runScoped(
7340
+ () => globalNumberingRegistry.runScoped(
7341
+ () => renderDocumentScoped(structure, layout, options)
7342
+ )
7323
7343
  )
7324
7344
  )
7325
7345
  )
@@ -8009,7 +8029,8 @@ function createBuilderImpl(state) {
8009
8029
  fonts: state.fonts,
8010
8030
  validation: state.validation,
8011
8031
  deterministic: state.deterministic,
8012
- generatedAt: state.generatedAt
8032
+ generatedAt: state.generatedAt,
8033
+ baseDir: state.baseDir
8013
8034
  };
8014
8035
  return createBuilderImpl(
8015
8036
  newState
@@ -8108,7 +8129,8 @@ function createBuilderImpl(state) {
8108
8129
  const layout = applyLayout(structure.sections, modedTheme, themeName);
8109
8130
  const generatedDocument = await renderDocument(structure, layout, {
8110
8131
  services: state.services,
8111
- bypassCache: !state.enableCache
8132
+ bypassCache: !state.enableCache,
8133
+ baseDir: options?.baseDir ?? state.baseDir
8112
8134
  });
8113
8135
  const preservedDefinition = preserveSet ? {
8114
8136
  ...modedRoot,
@@ -8238,7 +8260,8 @@ function createDocumentGenerator(options) {
8238
8260
  fonts: options.fonts,
8239
8261
  validation: options.validation,
8240
8262
  deterministic: options.deterministic ?? true,
8241
- generatedAt: options.generatedAt
8263
+ generatedAt: options.generatedAt,
8264
+ baseDir: options.baseDir
8242
8265
  };
8243
8266
  return createBuilderImpl(initialState);
8244
8267
  }
@@ -8292,7 +8315,7 @@ var WeatherV2PropsSchema = Type3.Object(
8292
8315
  }
8293
8316
  );
8294
8317
  async function fetchWeather(city, units) {
8295
- await new Promise((resolve) => setTimeout(resolve, 100));
8318
+ await new Promise((resolve2) => setTimeout(resolve2, 100));
8296
8319
  const mockData = {
8297
8320
  London: {
8298
8321
  temperature: units === "imperial" ? 59 : 15,
@@ -8325,7 +8348,7 @@ async function fetchWeather(city, units) {
8325
8348
  };
8326
8349
  }
8327
8350
  async function fetchForecast(city, units, days) {
8328
- await new Promise((resolve) => setTimeout(resolve, 50));
8351
+ await new Promise((resolve2) => setTimeout(resolve2, 50));
8329
8352
  const dayNames = ["Mon", "Tue", "Wed", "Thu", "Fri"];
8330
8353
  const base = units === "imperial" ? 65 : 18;
8331
8354
  return dayNames.slice(0, days).map((day, i) => ({