@colixsystems/widget-sdk 0.264.0 → 0.265.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/README.md CHANGED
@@ -86,7 +86,11 @@ See the design reference for the full architecture: [`docs/architecture/widget-m
86
86
 
87
87
  ## Status
88
88
 
89
- `v0.264.0` — pre-publish. The package surface (types, function names, export paths) is the v1 contract; runtime behaviour for some hooks is stubbed (each hook documents what's wired and what isn't). It is **not yet published to npm**.
89
+ `v0.265.0` — pre-publish. The package surface (types, function names, export paths) is the v1 contract; runtime behaviour for some hooks is stubbed (each hook documents what's wired and what isn't). It is **not yet published to npm**.
90
+
91
+ ### What's new in 0.265.0 (contract 1.215.0)
92
+
93
+ - **`usePdfExport` appends stored PDFs.** `openPdf(html, { appendFileIds })` and `exportToPdf(html, { appendFileIds })` take up to 20 Filestore file ids; every page of each PDF follows the rendered HTML, in order, on the web Player and in the native export alike (the merge runs server-side). An id the user cannot download, or a file that is not a readable PDF (password-protected, malformed), rejects the call with `err.details.file_id` naming it: 404 `FILE_NOT_FOUND`, 403 `FILE_DOWNLOAD_NOT_PERMITTED`, 422 `PDF_NOT_MERGEABLE`.
90
94
 
91
95
  ### What's new in 0.264.0 (contract 1.214.0)
92
96
 
package/dist/contract.cjs CHANGED
@@ -1539,7 +1539,7 @@ const HOOKS = [
1539
1539
  optionalArgs: ["spaceType", "folderId"],
1540
1540
  description:
1541
1541
  "Render an HTML string to a PDF server-side, then either OPEN it or SAVE " +
1542
- "it. `openPdf(html, { fileName? })` is THE way to give the user a PDF " +
1542
+ "it. `openPdf(html, { fileName?, appendFileIds? })` is THE way to give the user a PDF " +
1543
1543
  "to view, print, download or share: it renders the HTML and opens the " +
1544
1544
  "result — the browser's PDF viewer in a new tab on the web Player, the " +
1545
1545
  "OS print / share sheet in the native export — and SAVES NOTHING, so " +
@@ -1555,19 +1555,27 @@ const HOOKS = [
1555
1555
  "the end-user's Filestore space. The widget passes the SPACE " +
1556
1556
  "(`{ spaceType, folderId? }`); the hook resolves owner_id from the host " +
1557
1557
  "context and POSTs JSON through ctx.filestore.files.exportPdf. " +
1558
- "`exportToPdf(html, { fileName?, folderId? })` resolves to the created " +
1558
+ "`exportToPdf(html, { fileName?, folderId?, appendFileIds? })` resolves to the created " +
1559
1559
  "file row (mime_type `application/pdf`) or throws the wire error; " +
1560
1560
  "`err.status` 403/404 means the destination denied the add (403 " +
1561
1561
  "when the caller can see the position, 404 when it cannot), a 413 " +
1562
1562
  "that the rendered " +
1563
1563
  "PDF exceeded the size cap. The HTML is rendered by the host's PDF " +
1564
1564
  "service (headless Chromium) — the SAME server-side pipeline on the web " +
1565
- "Player and the native export, so no browser-only PDF library is used.",
1565
+ "Player and the native export, so no browser-only PDF library is used. " +
1566
+ "To put a record's attached PDFs INSIDE the document, pass their Filestore " +
1567
+ "file ids as `appendFileIds` (at most 20) to either call: every page of " +
1568
+ "each file follows the rendered HTML, in the order given. Do not try to " +
1569
+ "embed a PDF through an <img>, <iframe> or link. Each id must be a PDF the " +
1570
+ "user may download, or the call rejects naming it in `err.details.file_id`: " +
1571
+ "404 FILE_NOT_FOUND, 403 FILE_DOWNLOAD_NOT_PERMITTED, or 422 " +
1572
+ "PDF_NOT_MERGEABLE (not a PDF, password-protected, or unreadable). On a " +
1573
+ "422, drop that id and call again so the rest of the report still opens.",
1566
1574
  returnShape: {
1567
- openPdf: "(html, { fileName? }) => Promise<void>",
1575
+ openPdf: "(html, { fileName?, appendFileIds? }) => Promise<void>",
1568
1576
  opening: "boolean",
1569
1577
  canOpenPdf: "boolean",
1570
- exportToPdf: "(html, { fileName?, folderId? }) => Promise<FilestoreFile>",
1578
+ exportToPdf: "(html, { fileName?, folderId?, appendFileIds? }) => Promise<FilestoreFile>",
1571
1579
  exporting: "boolean",
1572
1580
  error: "Error | null",
1573
1581
  lastExported: "FilestoreFile | null",
@@ -6435,7 +6443,9 @@ const CONTRACT = deepFreeze({
6435
6443
  // 1.214.0: additive (sc-13746) — a datastoreTemplate column may be a
6436
6444
  // `UUID` (validated, stored lowercase); `"@uuid"` defaults it to a new
6437
6445
  // random id per row and may be `defaultLocked`.
6438
- version: "1.214.0",
6446
+ // 1.215.0: additive (sc-13938) — `usePdfExport` `openPdf` / `exportToPdf`
6447
+ // take `appendFileIds`: stored PDFs whose pages follow the rendered HTML.
6448
+ version: "1.215.0",
6439
6449
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
6440
6450
  hooks: HOOKS,
6441
6451
  primitives: PRIMITIVES,
package/dist/contract.js CHANGED
@@ -1536,7 +1536,7 @@ const HOOKS = [
1536
1536
  optionalArgs: ["spaceType", "folderId"],
1537
1537
  description:
1538
1538
  "Render an HTML string to a PDF server-side, then either OPEN it or SAVE " +
1539
- "it. `openPdf(html, { fileName? })` is THE way to give the user a PDF " +
1539
+ "it. `openPdf(html, { fileName?, appendFileIds? })` is THE way to give the user a PDF " +
1540
1540
  "to view, print, download or share: it renders the HTML and opens the " +
1541
1541
  "result — the browser's PDF viewer in a new tab on the web Player, the " +
1542
1542
  "OS print / share sheet in the native export — and SAVES NOTHING, so " +
@@ -1552,19 +1552,27 @@ const HOOKS = [
1552
1552
  "the end-user's Filestore space. The widget passes the SPACE " +
1553
1553
  "(`{ spaceType, folderId? }`); the hook resolves owner_id from the host " +
1554
1554
  "context and POSTs JSON through ctx.filestore.files.exportPdf. " +
1555
- "`exportToPdf(html, { fileName?, folderId? })` resolves to the created " +
1555
+ "`exportToPdf(html, { fileName?, folderId?, appendFileIds? })` resolves to the created " +
1556
1556
  "file row (mime_type `application/pdf`) or throws the wire error; " +
1557
1557
  "`err.status` 403/404 means the destination denied the add (403 " +
1558
1558
  "when the caller can see the position, 404 when it cannot), a 413 " +
1559
1559
  "that the rendered " +
1560
1560
  "PDF exceeded the size cap. The HTML is rendered by the host's PDF " +
1561
1561
  "service (headless Chromium) — the SAME server-side pipeline on the web " +
1562
- "Player and the native export, so no browser-only PDF library is used.",
1562
+ "Player and the native export, so no browser-only PDF library is used. " +
1563
+ "To put a record's attached PDFs INSIDE the document, pass their Filestore " +
1564
+ "file ids as `appendFileIds` (at most 20) to either call: every page of " +
1565
+ "each file follows the rendered HTML, in the order given. Do not try to " +
1566
+ "embed a PDF through an <img>, <iframe> or link. Each id must be a PDF the " +
1567
+ "user may download, or the call rejects naming it in `err.details.file_id`: " +
1568
+ "404 FILE_NOT_FOUND, 403 FILE_DOWNLOAD_NOT_PERMITTED, or 422 " +
1569
+ "PDF_NOT_MERGEABLE (not a PDF, password-protected, or unreadable). On a " +
1570
+ "422, drop that id and call again so the rest of the report still opens.",
1563
1571
  returnShape: {
1564
- openPdf: "(html, { fileName? }) => Promise<void>",
1572
+ openPdf: "(html, { fileName?, appendFileIds? }) => Promise<void>",
1565
1573
  opening: "boolean",
1566
1574
  canOpenPdf: "boolean",
1567
- exportToPdf: "(html, { fileName?, folderId? }) => Promise<FilestoreFile>",
1575
+ exportToPdf: "(html, { fileName?, folderId?, appendFileIds? }) => Promise<FilestoreFile>",
1568
1576
  exporting: "boolean",
1569
1577
  error: "Error | null",
1570
1578
  lastExported: "FilestoreFile | null",
@@ -6432,7 +6440,9 @@ const CONTRACT = deepFreeze({
6432
6440
  // 1.214.0: additive (sc-13746) — a datastoreTemplate column may be a
6433
6441
  // `UUID` (validated, stored lowercase); `"@uuid"` defaults it to a new
6434
6442
  // random id per row and may be `defaultLocked`.
6435
- version: "1.214.0",
6443
+ // 1.215.0: additive (sc-13938) — `usePdfExport` `openPdf` / `exportToPdf`
6444
+ // take `appendFileIds`: stored PDFs whose pages follow the rendered HTML.
6445
+ version: "1.215.0",
6436
6446
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
6437
6447
  hooks: HOOKS,
6438
6448
  primitives: PRIMITIVES,
package/dist/hooks.js CHANGED
@@ -5171,7 +5171,7 @@ export function usePdfExport(options) {
5171
5171
  try {
5172
5172
  await viewer.open({
5173
5173
  fileName: _pdfFileName(overrides && overrides.fileName),
5174
- load: () => files.renderPdf({ html }),
5174
+ load: () => files.renderPdf(_pdfRenderBody(html, overrides)),
5175
5175
  });
5176
5176
  } catch (err) {
5177
5177
  setError(err);
@@ -5204,6 +5204,7 @@ export function usePdfExport(options) {
5204
5204
  };
5205
5205
  if (folderId) body.folder_id = folderId;
5206
5206
  if (fileName) body.file_name = fileName;
5207
+ Object.assign(body, _pdfRenderBody(html, overrides));
5207
5208
  setExporting(true);
5208
5209
  setError(null);
5209
5210
  try {
@@ -5231,6 +5232,12 @@ export function usePdfExport(options) {
5231
5232
  };
5232
5233
  }
5233
5234
 
5235
+ // `appendFileIds`: stored PDFs whose pages follow the rendered HTML.
5236
+ function _pdfRenderBody(html, overrides) {
5237
+ const ids = overrides && overrides.appendFileIds;
5238
+ return Array.isArray(ids) && ids.length > 0 ? { html, append_file_ids: ids } : { html };
5239
+ }
5240
+
5234
5241
  function _canOpenPdf(viewer) {
5235
5242
  return Boolean(
5236
5243
  viewer &&
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colixsystems/widget-sdk",
3
- "version": "0.264.0",
3
+ "version": "0.265.0",
4
4
  "description": "Common widget interface for AppStudio. Implements WidgetManifest, WidgetContext, property schema, and helper hooks.",
5
5
  "homepage": "https://github.com/Colix-AB/AppStudio",
6
6
  "type": "module",
package/src/contract.js CHANGED
@@ -1536,7 +1536,7 @@ const HOOKS = [
1536
1536
  optionalArgs: ["spaceType", "folderId"],
1537
1537
  description:
1538
1538
  "Render an HTML string to a PDF server-side, then either OPEN it or SAVE " +
1539
- "it. `openPdf(html, { fileName? })` is THE way to give the user a PDF " +
1539
+ "it. `openPdf(html, { fileName?, appendFileIds? })` is THE way to give the user a PDF " +
1540
1540
  "to view, print, download or share: it renders the HTML and opens the " +
1541
1541
  "result — the browser's PDF viewer in a new tab on the web Player, the " +
1542
1542
  "OS print / share sheet in the native export — and SAVES NOTHING, so " +
@@ -1552,19 +1552,27 @@ const HOOKS = [
1552
1552
  "the end-user's Filestore space. The widget passes the SPACE " +
1553
1553
  "(`{ spaceType, folderId? }`); the hook resolves owner_id from the host " +
1554
1554
  "context and POSTs JSON through ctx.filestore.files.exportPdf. " +
1555
- "`exportToPdf(html, { fileName?, folderId? })` resolves to the created " +
1555
+ "`exportToPdf(html, { fileName?, folderId?, appendFileIds? })` resolves to the created " +
1556
1556
  "file row (mime_type `application/pdf`) or throws the wire error; " +
1557
1557
  "`err.status` 403/404 means the destination denied the add (403 " +
1558
1558
  "when the caller can see the position, 404 when it cannot), a 413 " +
1559
1559
  "that the rendered " +
1560
1560
  "PDF exceeded the size cap. The HTML is rendered by the host's PDF " +
1561
1561
  "service (headless Chromium) — the SAME server-side pipeline on the web " +
1562
- "Player and the native export, so no browser-only PDF library is used.",
1562
+ "Player and the native export, so no browser-only PDF library is used. " +
1563
+ "To put a record's attached PDFs INSIDE the document, pass their Filestore " +
1564
+ "file ids as `appendFileIds` (at most 20) to either call: every page of " +
1565
+ "each file follows the rendered HTML, in the order given. Do not try to " +
1566
+ "embed a PDF through an <img>, <iframe> or link. Each id must be a PDF the " +
1567
+ "user may download, or the call rejects naming it in `err.details.file_id`: " +
1568
+ "404 FILE_NOT_FOUND, 403 FILE_DOWNLOAD_NOT_PERMITTED, or 422 " +
1569
+ "PDF_NOT_MERGEABLE (not a PDF, password-protected, or unreadable). On a " +
1570
+ "422, drop that id and call again so the rest of the report still opens.",
1563
1571
  returnShape: {
1564
- openPdf: "(html, { fileName? }) => Promise<void>",
1572
+ openPdf: "(html, { fileName?, appendFileIds? }) => Promise<void>",
1565
1573
  opening: "boolean",
1566
1574
  canOpenPdf: "boolean",
1567
- exportToPdf: "(html, { fileName?, folderId? }) => Promise<FilestoreFile>",
1575
+ exportToPdf: "(html, { fileName?, folderId?, appendFileIds? }) => Promise<FilestoreFile>",
1568
1576
  exporting: "boolean",
1569
1577
  error: "Error | null",
1570
1578
  lastExported: "FilestoreFile | null",
@@ -6432,7 +6440,9 @@ const CONTRACT = deepFreeze({
6432
6440
  // 1.214.0: additive (sc-13746) — a datastoreTemplate column may be a
6433
6441
  // `UUID` (validated, stored lowercase); `"@uuid"` defaults it to a new
6434
6442
  // random id per row and may be `defaultLocked`.
6435
- version: "1.214.0",
6443
+ // 1.215.0: additive (sc-13938) — `usePdfExport` `openPdf` / `exportToPdf`
6444
+ // take `appendFileIds`: stored PDFs whose pages follow the rendered HTML.
6445
+ version: "1.215.0",
6436
6446
  sharedTranslationKeys: SHARED_TRANSLATION_KEYS,
6437
6447
  hooks: HOOKS,
6438
6448
  primitives: PRIMITIVES,