@json-to-office/jto 0.13.0 → 0.14.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.
Files changed (34) hide show
  1. package/dist/cli.js +115 -5
  2. package/dist/cli.js.map +1 -1
  3. package/dist/client/assets/HomePage-BTmw2QAf.js +99 -0
  4. package/dist/client/assets/HomePage-BTmw2QAf.js.map +1 -0
  5. package/dist/client/assets/{JsonEditorPage-B9IVUEsa.js → JsonEditorPage-CRONWw-J.js} +3 -3
  6. package/dist/client/assets/{JsonEditorPage-B9IVUEsa.js.map → JsonEditorPage-CRONWw-J.js.map} +1 -1
  7. package/dist/client/assets/{MonacoPluginProvider-B20CKO2l.js → MonacoPluginProvider-DhOIgTne.js} +3 -3
  8. package/dist/client/assets/{MonacoPluginProvider-B20CKO2l.js.map → MonacoPluginProvider-DhOIgTne.js.map} +1 -1
  9. package/dist/client/assets/{button-B_SFRCrX.js → button-ebCBEwlw.js} +2 -2
  10. package/dist/client/assets/{button-B_SFRCrX.js.map → button-ebCBEwlw.js.map} +1 -1
  11. package/dist/client/assets/{editor-B6lP0ii6.js → editor-CB9BVJGn.js} +2 -2
  12. package/dist/client/assets/{editor-B6lP0ii6.js.map → editor-CB9BVJGn.js.map} +1 -1
  13. package/dist/client/assets/{editor-monaco-json-ZXrPUjb-.js → editor-monaco-json-DaGk8WIJ.js} +2 -2
  14. package/dist/client/assets/{editor-monaco-json-ZXrPUjb-.js.map → editor-monaco-json-DaGk8WIJ.js.map} +1 -1
  15. package/dist/client/assets/index-Cy63RxyT.js +5 -0
  16. package/dist/client/assets/index-Cy63RxyT.js.map +1 -0
  17. package/dist/client/assets/index-DiQf3mCW.css +1 -0
  18. package/dist/client/assets/{preview-CuW78gw0.js → preview-B4bcm38l.js} +2 -2
  19. package/dist/client/assets/{preview-CuW78gw0.js.map → preview-B4bcm38l.js.map} +1 -1
  20. package/dist/client/assets/radix-ui-BQBCrmlJ.js +51 -0
  21. package/dist/client/assets/{radix-ui-BiXCNJNt.js.map → radix-ui-BQBCrmlJ.js.map} +1 -1
  22. package/dist/client/assets/{state-vendor-DTum9m7F.js → state-vendor-ByFYl9bq.js} +2 -2
  23. package/dist/client/assets/{state-vendor-DTum9m7F.js.map → state-vendor-ByFYl9bq.js.map} +1 -1
  24. package/dist/client/assets/{ui-vendor-D3QbouTA.js → ui-vendor-HKNXoiLD.js} +54 -44
  25. package/dist/client/assets/ui-vendor-HKNXoiLD.js.map +1 -0
  26. package/dist/client/index.html +5 -5
  27. package/package.json +5 -5
  28. package/dist/client/assets/HomePage-UtourY26.js +0 -99
  29. package/dist/client/assets/HomePage-UtourY26.js.map +0 -1
  30. package/dist/client/assets/index-CCAjuRfZ.js +0 -5
  31. package/dist/client/assets/index-CCAjuRfZ.js.map +0 -1
  32. package/dist/client/assets/index-DMEmT8G4.css +0 -1
  33. package/dist/client/assets/radix-ui-BiXCNJNt.js +0 -51
  34. package/dist/client/assets/ui-vendor-D3QbouTA.js.map +0 -1
package/dist/cli.js CHANGED
@@ -1331,7 +1331,7 @@ var init_health = __esm({
1331
1331
 
1332
1332
  // src/server/schemas/loose.ts
1333
1333
  import { Type } from "@sinclair/typebox";
1334
- var FontOptionsSchema, LooseDocumentGenerationRequestSchema, LooseDocumentValidationRequestSchema;
1334
+ var FontOptionsSchema, LooseDocumentGenerationRequestSchema, LooseDocumentValidationRequestSchema, LooseDocumentDiffRequestSchema;
1335
1335
  var init_loose = __esm({
1336
1336
  "src/server/schemas/loose.ts"() {
1337
1337
  "use strict";
@@ -1385,6 +1385,28 @@ var init_loose = __esm({
1385
1385
  },
1386
1386
  { additionalProperties: true }
1387
1387
  );
1388
+ LooseDocumentDiffRequestSchema = Type.Object(
1389
+ {
1390
+ oldDefinition: Type.Union([
1391
+ Type.String(),
1392
+ Type.Object({}, { additionalProperties: true })
1393
+ ]),
1394
+ newDefinition: Type.Union([
1395
+ Type.String(),
1396
+ Type.Object({}, { additionalProperties: true })
1397
+ ]),
1398
+ options: Type.Optional(
1399
+ Type.Object(
1400
+ {
1401
+ author: Type.Optional(Type.String({ maxLength: 128 })),
1402
+ date: Type.Optional(Type.String({ maxLength: 64 }))
1403
+ },
1404
+ { additionalProperties: false }
1405
+ )
1406
+ )
1407
+ },
1408
+ { additionalProperties: true }
1409
+ );
1388
1410
  }
1389
1411
  });
1390
1412
 
@@ -1603,6 +1625,93 @@ function createFormatRouter(adapter) {
1603
1625
  }
1604
1626
  }
1605
1627
  );
1628
+ if (adapter.name === "docx") {
1629
+ router.post(
1630
+ "/diff",
1631
+ bodyLimit({
1632
+ // Two full documents per request — same cap rationale as
1633
+ // /preview/libreoffice-from-json, doubled.
1634
+ maxSize: 32 * 1024 * 1024,
1635
+ onError: () => {
1636
+ throw new HTTPException3(413, { message: "Request body too large" });
1637
+ }
1638
+ }),
1639
+ rateLimiter({
1640
+ limit: process.env.NODE_ENV === "production" ? 30 : 1e3,
1641
+ window: 15 * 60 * 1e3,
1642
+ keyGenerator: (c) => c.req.header("X-Real-IP") || c.req.header("X-Forwarded-For")?.split(",").pop()?.trim() || "anonymous"
1643
+ }),
1644
+ contentTypeMw,
1645
+ tbValidator(LooseDocumentDiffRequestSchema),
1646
+ async (c) => {
1647
+ const { oldDefinition, newDefinition, options } = getValidated(c, "json");
1648
+ const requestId = c.get("requestId");
1649
+ const parseDef = (label, def) => {
1650
+ if (typeof def !== "string") return def;
1651
+ try {
1652
+ return JSON.parse(def);
1653
+ } catch {
1654
+ throw new HTTPException3(400, {
1655
+ message: `${label} document is not valid JSON`
1656
+ });
1657
+ }
1658
+ };
1659
+ try {
1660
+ const oldDoc = parseDef("Old", oldDefinition);
1661
+ const newDoc = parseDef("New", newDefinition);
1662
+ const sharedDocx = await import("@json-to-office/shared-docx");
1663
+ for (const [label, doc] of [
1664
+ ["Old", oldDoc],
1665
+ ["New", newDoc]
1666
+ ]) {
1667
+ const result = sharedDocx.validate.jsonDocument(
1668
+ JSON.stringify(doc)
1669
+ );
1670
+ if (!result.valid) {
1671
+ return c.json(
1672
+ {
1673
+ success: false,
1674
+ error: `${label} document failed validation`,
1675
+ errors: (result.errors || []).slice(0, 20),
1676
+ meta: { timestamp: (/* @__PURE__ */ new Date()).toISOString(), requestId }
1677
+ },
1678
+ 400
1679
+ );
1680
+ }
1681
+ }
1682
+ const revisionDate = options?.date ? new Date(options.date) : /* @__PURE__ */ new Date();
1683
+ if (isNaN(revisionDate.getTime())) {
1684
+ throw new HTTPException3(400, {
1685
+ message: `Invalid date: "${options?.date}" (expected ISO 8601)`
1686
+ });
1687
+ }
1688
+ const { diffDocuments } = sharedDocx;
1689
+ const { document, summary } = diffDocuments(
1690
+ oldDoc,
1691
+ newDoc,
1692
+ {
1693
+ author: options?.author || "playground",
1694
+ date: revisionDate.toISOString()
1695
+ }
1696
+ );
1697
+ return c.json({
1698
+ success: true,
1699
+ data: { document, summary },
1700
+ meta: { timestamp: (/* @__PURE__ */ new Date()).toISOString(), requestId }
1701
+ });
1702
+ } catch (error) {
1703
+ if (error instanceof HTTPException3) throw error;
1704
+ logger.error("Document diff failed", { error, requestId });
1705
+ if (error instanceof Error && error.message.includes("top-level component")) {
1706
+ throw new HTTPException3(400, { message: error.message });
1707
+ }
1708
+ throw new HTTPException3(500, {
1709
+ message: "Internal server error during document diff"
1710
+ });
1711
+ }
1712
+ }
1713
+ );
1714
+ }
1606
1715
  router.post(
1607
1716
  "/preview/libreoffice",
1608
1717
  rateLimiter({
@@ -1664,9 +1773,10 @@ function createFormatRouter(adapter) {
1664
1773
  router.post(
1665
1774
  "/preview/libreoffice-from-json",
1666
1775
  bodyLimit({
1667
- // Doc JSON + custom themes. 2 MB covers large report fixtures; anything
1668
- // bigger is almost certainly an attempt to OOM the worker.
1669
- maxSize: 2 * 1024 * 1024,
1776
+ // Doc JSON + custom themes. 16 MB accommodates real-world docs that
1777
+ // inline base64 image assets (logos, screenshots, chart images); the
1778
+ // earlier 2 MB cap rejected legitimate payloads with 413.
1779
+ maxSize: 16 * 1024 * 1024,
1670
1780
  onError: () => {
1671
1781
  throw new HTTPException3(413, { message: "Request body too large" });
1672
1782
  }
@@ -3353,7 +3463,7 @@ ${chalk.cyan("Health:")} ${url}/health
3353
3463
  }
3354
3464
 
3355
3465
  // src/cli.ts
3356
- var PACKAGE_VERSION = true ? "0.13.0" : "dev-mode";
3466
+ var PACKAGE_VERSION = true ? "0.14.0" : "dev-mode";
3357
3467
  var program = new Command2();
3358
3468
  program.name("jto").description("JSON to Office CLI - Generate .docx and .pptx from JSON").version(PACKAGE_VERSION);
3359
3469
  registerCoreCommands(program, {