@json-to-office/core-docx 2.0.0 → 2.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.
@@ -4619,34 +4619,36 @@ function validateDocument(document, customComponents, options) {
4619
4619
  const errors = [...documentResult.errors || []];
4620
4620
  function validateComponents(components, pathPrefix = "children") {
4621
4621
  components.forEach((componentData, index) => {
4622
- const customComponent = customComponents.find(
4623
- (cc) => cc.name === componentData.name
4624
- );
4625
- if (!customComponent) {
4622
+ if (!componentData || typeof componentData !== "object" || Array.isArray(componentData)) {
4626
4623
  return;
4627
4624
  }
4628
- const versionEntry = resolveComponentVersion(
4629
- customComponent.name,
4630
- customComponent.versions,
4631
- componentData.version
4632
- );
4633
- const validation = validateComponentProps(
4634
- versionEntry,
4635
- componentData.props,
4636
- customComponent.name,
4637
- // Reject unknown custom props unless the caller allows them.
4638
- { clean: options?.allowUnknownFields === true }
4625
+ const customComponent = customComponents.find(
4626
+ (cc) => cc.name === componentData.name
4639
4627
  );
4640
- if (!validation.valid && validation.errors) {
4641
- const indexedErrors = validation.errors.map(
4642
- (error) => ({
4643
- ...error,
4644
- path: `${pathPrefix}[${index}].${error.path}`
4645
- })
4628
+ if (customComponent) {
4629
+ const versionEntry = resolveComponentVersion(
4630
+ customComponent.name,
4631
+ customComponent.versions,
4632
+ componentData.version
4633
+ );
4634
+ const validation = validateComponentProps(
4635
+ versionEntry,
4636
+ componentData.props,
4637
+ customComponent.name,
4638
+ // Reject unknown custom props unless the caller allows them.
4639
+ { clean: options?.allowUnknownFields === true }
4646
4640
  );
4647
- errors.push(...indexedErrors);
4641
+ if (!validation.valid && validation.errors) {
4642
+ const indexedErrors = validation.errors.map(
4643
+ (error) => ({
4644
+ ...error,
4645
+ path: `${pathPrefix}[${index}].${error.path}`
4646
+ })
4647
+ );
4648
+ errors.push(...indexedErrors);
4649
+ }
4648
4650
  }
4649
- if (componentData.children && Array.isArray(componentData.children)) {
4651
+ if (Array.isArray(componentData.children)) {
4650
4652
  validateComponents(
4651
4653
  componentData.children,
4652
4654
  `${pathPrefix}[${index}].children`
@@ -12452,167 +12454,262 @@ function createDocumentGenerator(options) {
12452
12454
 
12453
12455
  // src/plugin/example/weather.component.ts
12454
12456
  import { Type as Type2 } from "@sinclair/typebox";
12455
-
12456
- // src/plugin/createComponent.ts
12457
- import {
12458
- createVersion as sharedCreateVersion,
12459
- createComponent as sharedCreateComponent
12460
- } from "@json-to-office/shared/plugin";
12461
- function createVersion(version) {
12462
- return sharedCreateVersion(version);
12463
- }
12464
- function createComponent(component) {
12465
- return sharedCreateComponent(component);
12466
- }
12467
-
12468
- // src/plugin/example/weather.component.ts
12457
+ import { createComponent, createVersion } from "@json-to-office/core-docx";
12458
+ var WEATHER_API_HOSTS = [
12459
+ "https://geocoding-api.open-meteo.com",
12460
+ "https://api.open-meteo.com"
12461
+ ];
12462
+ var GEOCODING_URL = "https://geocoding-api.open-meteo.com/v1/search";
12463
+ var FORECAST_URL = "https://api.open-meteo.com/v1/forecast";
12464
+ var REQUEST_TIMEOUT_MS = 8e3;
12465
+ var UnitsSchema = Type2.Optional(
12466
+ Type2.Union([Type2.Literal("metric"), Type2.Literal("imperial")], {
12467
+ default: "metric",
12468
+ description: "metric = \xB0C and km/h, imperial = \xB0F and mph"
12469
+ })
12470
+ );
12469
12471
  var WeatherV1PropsSchema = Type2.Object(
12470
12472
  {
12471
12473
  city: Type2.String({
12472
- description: "City name for weather data"
12474
+ minLength: 1,
12475
+ description: 'City to look up, e.g. "Milan" or "Milan, Italy"'
12473
12476
  }),
12474
- units: Type2.Optional(
12475
- Type2.Union([Type2.Literal("metric"), Type2.Literal("imperial")], {
12476
- default: "metric",
12477
- description: "Temperature units"
12478
- })
12479
- ),
12477
+ units: UnitsSchema,
12480
12478
  showDetails: Type2.Optional(
12481
12479
  Type2.Boolean({
12482
12480
  default: true,
12483
- description: "Show detailed weather information"
12481
+ description: "Show humidity, wind and pressure under the reading"
12484
12482
  })
12485
12483
  )
12486
12484
  },
12487
- {
12488
- additionalProperties: false
12489
- }
12485
+ { additionalProperties: false }
12490
12486
  );
12491
12487
  var WeatherV2PropsSchema = Type2.Object(
12492
12488
  {
12493
12489
  city: Type2.String({
12494
- description: "City name for weather data"
12490
+ minLength: 1,
12491
+ description: 'City to look up, e.g. "Milan" or "Milan, Italy"'
12495
12492
  }),
12496
- units: Type2.Optional(
12497
- Type2.Union([Type2.Literal("metric"), Type2.Literal("imperial")], {
12498
- default: "metric",
12499
- description: "Temperature units"
12500
- })
12501
- ),
12493
+ units: UnitsSchema,
12502
12494
  days: Type2.Optional(
12503
12495
  Type2.Number({
12504
- default: 1,
12496
+ default: 3,
12505
12497
  minimum: 1,
12506
- maximum: 5,
12507
- description: "Number of forecast days (1-5)"
12498
+ maximum: 7,
12499
+ description: "Number of forecast days (1-7)"
12508
12500
  })
12509
12501
  )
12510
12502
  },
12511
- {
12512
- additionalProperties: false
12513
- }
12503
+ { additionalProperties: false }
12514
12504
  );
12515
- async function fetchWeather(city, units) {
12516
- await new Promise((resolve2) => setTimeout(resolve2, 100));
12517
- const mockData = {
12518
- London: {
12519
- temperature: units === "imperial" ? 59 : 15,
12520
- description: "Partly cloudy",
12521
- humidity: 65,
12522
- windSpeed: units === "imperial" ? 10 : 16,
12523
- pressure: 1013
12524
- },
12525
- "New York": {
12526
- temperature: units === "imperial" ? 72 : 22,
12527
- description: "Sunny",
12528
- humidity: 45,
12529
- windSpeed: units === "imperial" ? 8 : 13,
12530
- pressure: 1015
12531
- },
12532
- Tokyo: {
12533
- temperature: units === "imperial" ? 68 : 20,
12534
- description: "Clear",
12535
- humidity: 55,
12536
- windSpeed: units === "imperial" ? 5 : 8,
12537
- pressure: 1012
12538
- }
12539
- };
12540
- return mockData[city] || {
12541
- temperature: units === "imperial" ? 70 : 21,
12542
- description: "Clear",
12543
- humidity: 50,
12544
- windSpeed: units === "imperial" ? 7 : 11,
12545
- pressure: 1013
12546
- };
12547
- }
12548
- async function fetchForecast(city, units, days) {
12549
- await new Promise((resolve2) => setTimeout(resolve2, 50));
12550
- const dayNames = ["Mon", "Tue", "Wed", "Thu", "Fri"];
12551
- const base = units === "imperial" ? 65 : 18;
12552
- return dayNames.slice(0, days).map((day, i) => ({
12553
- day,
12554
- high: base + (5 - i) * (units === "imperial" ? 2 : 1),
12555
- low: base - (3 + i) * (units === "imperial" ? 2 : 1),
12556
- description: ["Sunny", "Partly cloudy", "Cloudy", "Showers", "Clear"][i]
12505
+ var WEATHER_CODES = {
12506
+ 0: "Clear sky",
12507
+ 1: "Mainly clear",
12508
+ 2: "Partly cloudy",
12509
+ 3: "Overcast",
12510
+ 45: "Fog",
12511
+ 48: "Depositing rime fog",
12512
+ 51: "Light drizzle",
12513
+ 53: "Moderate drizzle",
12514
+ 55: "Dense drizzle",
12515
+ 56: "Light freezing drizzle",
12516
+ 57: "Dense freezing drizzle",
12517
+ 61: "Slight rain",
12518
+ 63: "Moderate rain",
12519
+ 65: "Heavy rain",
12520
+ 66: "Light freezing rain",
12521
+ 67: "Heavy freezing rain",
12522
+ 71: "Slight snow",
12523
+ 73: "Moderate snow",
12524
+ 75: "Heavy snow",
12525
+ 77: "Snow grains",
12526
+ 80: "Slight rain showers",
12527
+ 81: "Moderate rain showers",
12528
+ 82: "Violent rain showers",
12529
+ 85: "Slight snow showers",
12530
+ 86: "Heavy snow showers",
12531
+ 95: "Thunderstorm",
12532
+ 96: "Thunderstorm with slight hail",
12533
+ 99: "Thunderstorm with heavy hail"
12534
+ };
12535
+ function describeCode(code) {
12536
+ return typeof code === "number" && WEATHER_CODES[code] ? WEATHER_CODES[code] : "Unknown conditions";
12537
+ }
12538
+ var WeatherLookupError = class extends Error {
12539
+ constructor(message) {
12540
+ super(message);
12541
+ this.name = "WeatherLookupError";
12542
+ }
12543
+ };
12544
+ async function getJson(url, what) {
12545
+ let response;
12546
+ try {
12547
+ response = await fetch(url, {
12548
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
12549
+ headers: { accept: "application/json" }
12550
+ });
12551
+ } catch (error) {
12552
+ const reason = error instanceof Error ? error.message : String(error);
12553
+ throw new WeatherLookupError(
12554
+ `Could not reach Open-Meteo for ${what}: ${reason}. In the playground, list ${WEATHER_API_HOSTS.join(" and ")} under this plugin's Network switch.`
12555
+ );
12556
+ }
12557
+ if (!response.ok) {
12558
+ throw new WeatherLookupError(
12559
+ `Open-Meteo answered ${response.status} for ${what}.`
12560
+ );
12561
+ }
12562
+ return response.json();
12563
+ }
12564
+ async function geocode(city) {
12565
+ const url = `${GEOCODING_URL}?name=${encodeURIComponent(city)}&count=1&language=en&format=json`;
12566
+ const body = await getJson(url, `"${city}"`);
12567
+ const first = body.results?.[0];
12568
+ if (!first || typeof first.latitude !== "number") {
12569
+ throw new WeatherLookupError(
12570
+ `Open-Meteo has no place called "${city}". Try adding a country, e.g. "${city}, Italy".`
12571
+ );
12572
+ }
12573
+ return {
12574
+ name: String(first.name ?? city),
12575
+ country: typeof first.country === "string" ? first.country : void 0,
12576
+ admin1: typeof first.admin1 === "string" ? first.admin1 : void 0,
12577
+ latitude: first.latitude,
12578
+ longitude: first.longitude,
12579
+ timezone: typeof first.timezone === "string" ? first.timezone : void 0
12580
+ };
12581
+ }
12582
+ function placeLabel(place) {
12583
+ return [place.name, place.admin1, place.country].filter(Boolean).join(", ");
12584
+ }
12585
+ function unitParams(units) {
12586
+ return units === "imperial" ? "&temperature_unit=fahrenheit&wind_speed_unit=mph&precipitation_unit=inch" : "";
12587
+ }
12588
+ async function fetchCurrent(place, units) {
12589
+ const url = `${FORECAST_URL}?latitude=${place.latitude}&longitude=${place.longitude}&current=temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,surface_pressure,weather_code&timezone=auto${unitParams(units)}`;
12590
+ const body = await getJson(url, `weather in ${place.name}`);
12591
+ const current = body.current;
12592
+ if (!current || typeof current.temperature_2m !== "number") {
12593
+ throw new WeatherLookupError(
12594
+ `Open-Meteo returned no current reading for ${place.name}.`
12595
+ );
12596
+ }
12597
+ const round = (value, fallback = 0) => typeof value === "number" ? Math.round(value) : fallback;
12598
+ return {
12599
+ temperature: Math.round(current.temperature_2m),
12600
+ apparent: round(
12601
+ current.apparent_temperature,
12602
+ Math.round(current.temperature_2m)
12603
+ ),
12604
+ conditions: describeCode(current.weather_code),
12605
+ humidity: round(current.relative_humidity_2m),
12606
+ windSpeed: round(current.wind_speed_10m),
12607
+ pressure: round(current.surface_pressure),
12608
+ observedAt: typeof current.time === "string" ? current.time : ""
12609
+ };
12610
+ }
12611
+ async function fetchForecast(place, units, days) {
12612
+ const url = `${FORECAST_URL}?latitude=${place.latitude}&longitude=${place.longitude}&daily=weather_code,temperature_2m_max,temperature_2m_min,precipitation_probability_max&forecast_days=${days}&timezone=auto${unitParams(units)}`;
12613
+ const body = await getJson(url, `the forecast for ${place.name}`);
12614
+ const daily = body.daily;
12615
+ const dates = daily?.time;
12616
+ if (!Array.isArray(dates) || dates.length === 0) {
12617
+ throw new WeatherLookupError(
12618
+ `Open-Meteo returned no forecast for ${place.name}.`
12619
+ );
12620
+ }
12621
+ const at = (key, i) => daily?.[key]?.[i];
12622
+ return dates.slice(0, days).map((date, i) => ({
12623
+ date: String(date),
12624
+ high: Math.round(Number(at("temperature_2m_max", i) ?? 0)),
12625
+ low: Math.round(Number(at("temperature_2m_min", i) ?? 0)),
12626
+ conditions: describeCode(at("weather_code", i)),
12627
+ precipitation: Math.round(
12628
+ Number(at("precipitation_probability_max", i) ?? 0)
12629
+ )
12557
12630
  }));
12558
12631
  }
12632
+ function formatDay(iso) {
12633
+ const date = /* @__PURE__ */ new Date(`${iso}T00:00:00Z`);
12634
+ if (Number.isNaN(date.getTime())) return iso;
12635
+ return date.toLocaleDateString("en-GB", {
12636
+ weekday: "short",
12637
+ day: "numeric",
12638
+ month: "short",
12639
+ timeZone: "UTC"
12640
+ });
12641
+ }
12559
12642
  var weatherComponent = createComponent({
12560
12643
  name: "weather",
12561
12644
  versions: {
12562
12645
  "1.0.0": createVersion({
12563
12646
  propsSchema: WeatherV1PropsSchema,
12564
- description: "Displays current weather information for a city",
12647
+ description: "Current weather for a city, fetched live from Open-Meteo (needs network access to api.open-meteo.com and geocoding-api.open-meteo.com)",
12565
12648
  render: async ({ props, addWarning }) => {
12566
- const weather = await fetchWeather(props.city, props.units || "metric");
12567
- addWarning("Fetched weather data", { city: props.city });
12568
- const tempUnit = props.units === "imperial" ? "\xB0F" : "\xB0C";
12569
- const speedUnit = props.units === "imperial" ? "mph" : "km/h";
12649
+ const units = props.units ?? "metric";
12650
+ const place = await geocode(props.city);
12651
+ const weather = await fetchCurrent(place, units);
12652
+ addWarning(`Fetched live weather from Open-Meteo`, {
12653
+ place: placeLabel(place),
12654
+ observedAt: weather.observedAt
12655
+ });
12656
+ const degrees = units === "imperial" ? "\xB0F" : "\xB0C";
12657
+ const speed = units === "imperial" ? "mph" : "km/h";
12570
12658
  const components = [
12571
12659
  {
12572
12660
  name: "heading",
12573
- props: {
12574
- level: 3,
12575
- text: `Weather in ${props.city}`
12576
- }
12661
+ props: { level: 3, text: `Weather in ${placeLabel(place)}` }
12577
12662
  },
12578
12663
  {
12579
12664
  name: "paragraph",
12580
12665
  props: {
12581
- text: `${weather.temperature}${tempUnit} - ${weather.description}`,
12666
+ text: `${weather.temperature}${degrees} \u2014 ${weather.conditions}`,
12582
12667
  font: { bold: true, size: 14 }
12583
12668
  }
12584
12669
  }
12585
12670
  ];
12586
- if (props.showDetails) {
12671
+ if (props.showDetails ?? true) {
12587
12672
  components.push({
12588
12673
  name: "list",
12589
12674
  props: {
12590
12675
  items: [
12676
+ `Feels like: ${weather.apparent}${degrees}`,
12591
12677
  `Humidity: ${weather.humidity}%`,
12592
- `Wind Speed: ${weather.windSpeed} ${speedUnit}`,
12678
+ `Wind: ${weather.windSpeed} ${speed}`,
12593
12679
  `Pressure: ${weather.pressure} hPa`
12594
12680
  ]
12595
12681
  }
12596
12682
  });
12597
12683
  }
12684
+ components.push({
12685
+ name: "paragraph",
12686
+ props: {
12687
+ text: `Source: Open-Meteo${weather.observedAt ? `, observed ${weather.observedAt.replace("T", " ")}` : ""}`,
12688
+ font: { size: 8, italic: true }
12689
+ }
12690
+ });
12598
12691
  return components;
12599
12692
  }
12600
12693
  }),
12601
12694
  "2.0.0": createVersion({
12602
12695
  propsSchema: WeatherV2PropsSchema,
12603
- description: "Multi-day forecast displayed as a table",
12696
+ description: "Multi-day forecast table for a city, fetched live from Open-Meteo",
12604
12697
  render: async ({ props, addWarning }) => {
12605
- const units = props.units || "metric";
12606
- const days = props.days || 3;
12607
- const tempUnit = units === "imperial" ? "\xB0F" : "\xB0C";
12608
- const forecast = await fetchForecast(props.city, units, days);
12609
- addWarning("Fetched forecast data", { city: props.city, days });
12610
- const components = [
12698
+ const units = props.units ?? "metric";
12699
+ const days = props.days ?? 3;
12700
+ const place = await geocode(props.city);
12701
+ const forecast = await fetchForecast(place, units, days);
12702
+ addWarning("Fetched live forecast from Open-Meteo", {
12703
+ place: placeLabel(place),
12704
+ days: forecast.length
12705
+ });
12706
+ const degrees = units === "imperial" ? "\xB0F" : "\xB0C";
12707
+ return [
12611
12708
  {
12612
12709
  name: "heading",
12613
12710
  props: {
12614
12711
  level: 3,
12615
- text: `${days}-Day Forecast for ${props.city}`
12712
+ text: `${forecast.length}-day forecast for ${placeLabel(place)}`
12616
12713
  }
12617
12714
  },
12618
12715
  {
@@ -12621,53 +12718,37 @@ var weatherComponent = createComponent({
12621
12718
  columns: [
12622
12719
  {
12623
12720
  header: { content: "Day" },
12624
- cells: forecast.map((f) => ({ content: f.day }))
12721
+ cells: forecast.map((day) => ({
12722
+ content: formatDay(day.date)
12723
+ }))
12724
+ },
12725
+ {
12726
+ header: { content: `High (${degrees})` },
12727
+ cells: forecast.map((day) => ({ content: String(day.high) }))
12625
12728
  },
12626
12729
  {
12627
- header: { content: `High (${tempUnit})` },
12628
- cells: forecast.map((f) => ({ content: String(f.high) }))
12730
+ header: { content: `Low (${degrees})` },
12731
+ cells: forecast.map((day) => ({ content: String(day.low) }))
12629
12732
  },
12630
12733
  {
12631
- header: { content: `Low (${tempUnit})` },
12632
- cells: forecast.map((f) => ({ content: String(f.low) }))
12734
+ header: { content: "Rain" },
12735
+ cells: forecast.map((day) => ({
12736
+ content: `${day.precipitation}%`
12737
+ }))
12633
12738
  },
12634
12739
  {
12635
12740
  header: { content: "Conditions" },
12636
- cells: forecast.map((f) => ({ content: f.description }))
12741
+ cells: forecast.map((day) => ({ content: day.conditions }))
12637
12742
  }
12638
12743
  ]
12639
12744
  }
12640
- }
12641
- ];
12642
- return components;
12643
- }
12644
- })
12645
- }
12646
- });
12647
-
12648
- // src/plugin/example/columns-layout.component.ts
12649
- import { Type as Type3 } from "@sinclair/typebox";
12650
- var ColumnsLayoutPropsSchema = Type3.Object(
12651
- {},
12652
- {
12653
- additionalProperties: false
12654
- }
12655
- );
12656
- var columnsLayoutComponent = createComponent({
12657
- name: "columnsLayout",
12658
- versions: {
12659
- "1.0.0": createVersion({
12660
- propsSchema: ColumnsLayoutPropsSchema,
12661
- hasChildren: true,
12662
- description: "Renders a list of components in a 2-column layout",
12663
- render: async ({ children }) => {
12664
- return [
12745
+ },
12665
12746
  {
12666
- name: "columns",
12747
+ name: "paragraph",
12667
12748
  props: {
12668
- columns: 2
12669
- },
12670
- children: children || []
12749
+ text: "Source: Open-Meteo",
12750
+ font: { size: 8, italic: true }
12751
+ }
12671
12752
  }
12672
12753
  ];
12673
12754
  }
@@ -12675,91 +12756,6 @@ var columnsLayoutComponent = createComponent({
12675
12756
  }
12676
12757
  });
12677
12758
 
12678
- // src/plugin/example/nested-section.component.ts
12679
- import { Type as Type4 } from "@sinclair/typebox";
12680
- var NestedSectionsSchema = Type4.Object(
12681
- {},
12682
- {
12683
- additionalProperties: false
12684
- }
12685
- );
12686
- var nestedSectionsComponent = createComponent({
12687
- name: "nestedSections",
12688
- versions: {
12689
- "1.0.0": createVersion({
12690
- propsSchema: NestedSectionsSchema,
12691
- description: "Generates nested sections for embedding in documents",
12692
- render: async () => {
12693
- const components = [];
12694
- components.push({
12695
- name: "section",
12696
- props: {
12697
- meta: { title: "First level 1 section" }
12698
- },
12699
- children: [
12700
- {
12701
- name: "heading",
12702
- props: { text: "First level 1 section", level: 1 }
12703
- },
12704
- {
12705
- name: "heading",
12706
- props: {
12707
- text: "Level 2 heading of first level 1 section",
12708
- level: 2
12709
- }
12710
- },
12711
- {
12712
- name: "paragraph",
12713
- props: {
12714
- text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
12715
- }
12716
- },
12717
- {
12718
- name: "heading",
12719
- props: {
12720
- text: "Level 2 heading of first level 1 section",
12721
- level: 2
12722
- }
12723
- },
12724
- {
12725
- name: "paragraph",
12726
- props: {
12727
- text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
12728
- }
12729
- }
12730
- ]
12731
- });
12732
- components.push({
12733
- name: "section",
12734
- props: {
12735
- meta: { title: "Second level 1 section" }
12736
- },
12737
- children: [
12738
- {
12739
- name: "heading",
12740
- props: { text: "Second level 1 section", level: 1 }
12741
- },
12742
- {
12743
- name: "heading",
12744
- props: {
12745
- text: "Level 2 heading of second level 1 section",
12746
- level: 2
12747
- }
12748
- },
12749
- {
12750
- name: "paragraph",
12751
- props: {
12752
- text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
12753
- }
12754
- }
12755
- ]
12756
- });
12757
- return components;
12758
- }
12759
- })
12760
- }
12761
- });
12762
-
12763
12759
  // src/plugin/example/index.ts
12764
12760
  init_themes();
12765
12761
  import * as fs3 from "fs/promises";
@@ -12772,48 +12768,43 @@ var plugin_demo_default = {
12772
12768
  $schema: "../../../../../output/examples/plugin-demo-schema.json",
12773
12769
  name: "docx",
12774
12770
  props: {
12775
- title: "Plugin Demo"
12771
+ title: "Weather Plugin Demo"
12776
12772
  },
12777
12773
  children: [
12778
- {
12779
- name: "nestedSections",
12780
- props: {}
12781
- },
12782
12774
  {
12783
12775
  name: "section",
12784
12776
  props: {
12785
12777
  meta: {
12786
- title: "Weather Information"
12778
+ title: "Today"
12787
12779
  }
12788
12780
  },
12789
12781
  children: [
12790
12782
  {
12791
12783
  name: "heading",
12792
12784
  props: {
12793
- text: "Weather Information",
12785
+ text: "Today",
12794
12786
  level: 1,
12795
- spacing: {
12796
- before: 0,
12797
- after: 0
12798
- }
12787
+ spacing: { before: 0, after: 0 }
12799
12788
  }
12800
12789
  },
12801
12790
  {
12802
12791
  name: "paragraph",
12803
12792
  props: {
12804
- content: "Here's the current weather for major cities:"
12793
+ content: "Each block below is rendered by the weather plugin, which calls Open-Meteo while the document is generated."
12805
12794
  }
12806
12795
  },
12807
12796
  {
12808
12797
  name: "weather",
12798
+ version: "1.0.0",
12809
12799
  props: {
12810
- city: "London",
12800
+ city: "Milan",
12811
12801
  units: "metric",
12812
12802
  showDetails: true
12813
12803
  }
12814
12804
  },
12815
12805
  {
12816
12806
  name: "weather",
12807
+ version: "1.0.0",
12817
12808
  props: {
12818
12809
  city: "New York",
12819
12810
  units: "imperial",
@@ -12826,97 +12817,25 @@ var plugin_demo_default = {
12826
12817
  name: "section",
12827
12818
  props: {
12828
12819
  meta: {
12829
- title: "Sales Data"
12830
- }
12831
- },
12832
- children: [
12833
- {
12834
- name: "heading",
12835
- props: {
12836
- text: "Sales Data",
12837
- level: 1,
12838
- spacing: {
12839
- before: 0,
12840
- after: 0
12841
- }
12842
- }
12843
- },
12844
- {
12845
- name: "paragraph",
12846
- props: {
12847
- content: "Recent sales performance:"
12848
- }
12849
- },
12850
- {
12851
- name: "dataTable",
12852
- props: {
12853
- query: "SELECT * FROM sales ORDER BY date DESC",
12854
- title: "Q1 Sales Report",
12855
- showRowNumbers: true,
12856
- maxRows: 10
12857
- }
12858
- }
12859
- ]
12860
- },
12861
- {
12862
- name: "section",
12863
- props: {
12864
- meta: {
12865
- title: "Quick Links"
12820
+ title: "The week ahead"
12866
12821
  }
12867
12822
  },
12868
12823
  children: [
12869
12824
  {
12870
12825
  name: "heading",
12871
12826
  props: {
12872
- text: "Quick Links",
12827
+ text: "The week ahead",
12873
12828
  level: 1,
12874
- spacing: {
12875
- before: 0,
12876
- after: 0
12877
- }
12829
+ spacing: { before: 0, after: 0 }
12878
12830
  }
12879
12831
  },
12880
12832
  {
12881
- name: "paragraph",
12882
- props: {
12883
- content: "Scan these QR codes to access our resources:"
12884
- }
12885
- }
12886
- ]
12887
- },
12888
- {
12889
- name: "section",
12890
- props: {
12891
- meta: {
12892
- title: "More Data Examples"
12893
- }
12894
- },
12895
- children: [
12896
- {
12897
- name: "heading",
12898
- props: {
12899
- text: "More Data Examples",
12900
- level: 1,
12901
- spacing: {
12902
- before: 0,
12903
- after: 0
12904
- }
12905
- }
12906
- },
12907
- {
12908
- name: "dataTable",
12909
- props: {
12910
- query: 'SELECT * FROM users WHERE role = "Admin"',
12911
- title: "System Administrators"
12912
- }
12913
- },
12914
- {
12915
- name: "dataTable",
12833
+ name: "weather",
12834
+ version: "2.0.0",
12916
12835
  props: {
12917
- query: "SELECT * FROM inventory WHERE stock < 50",
12918
- title: "Low Stock Items",
12919
- showRowNumbers: false
12836
+ city: "Tokyo",
12837
+ units: "metric",
12838
+ days: 5
12920
12839
  }
12921
12840
  }
12922
12841
  ]
@@ -12934,7 +12853,7 @@ async function runPluginDemo() {
12934
12853
  theme: minimalTheme,
12935
12854
  debug: true
12936
12855
  // Enable debug logging
12937
- }).addComponent(weatherComponent).addComponent(columnsLayoutComponent).addComponent(nestedSectionsComponent);
12856
+ }).addComponent(weatherComponent);
12938
12857
  console.log(
12939
12858
  "\u2705 Registered components:",
12940
12859
  generator.getComponentNames().join(", ")
@@ -12982,10 +12901,7 @@ async function runPluginDemo() {
12982
12901
  await fs3.writeFile(outputPath, new Uint8Array(result.buffer));
12983
12902
  console.log(`\u2705 Document saved to: ${outputPath}`);
12984
12903
  const schemaPath = path2.join(outputDir, "plugin-demo-schema.json");
12985
- await exportPluginSchema(
12986
- [weatherComponent, columnsLayoutComponent, nestedSectionsComponent],
12987
- schemaPath
12988
- );
12904
+ await exportPluginSchema([weatherComponent], schemaPath);
12989
12905
  console.log(`\u2705 Schema saved to: ${schemaPath}`);
12990
12906
  } catch (error) {
12991
12907
  console.error("\u274C Error generating document:", error);