@cube-dev/platform-client 0.6.0 → 0.7.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/CHANGELOG.md CHANGED
@@ -9,7 +9,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  <!-- Curate public-facing entries here before the next release. -->
11
11
 
12
+ ## [0.7.0] - 2026-09-09
13
+
14
+ ### Added
15
+
16
+ - New public REST API for rendering a published dashboard to PNG or PDF (CUB-4302): `POST /api/v1/deployments/{deploymentId}/dashboard-exports` (`DashboardExportsPublicController.startExport`) submits a render, `GET .../dashboard-exports/{jobId}` (`getExportStatus`) polls its status, and `GET .../dashboard-exports/{jobId}/download` (`downloadExport`) streams the finished file. Asynchronous because a render waits for every widget to finish querying — the job and its file are dropped 5 minutes after submission. By default the render runs under the caller's own security context (requires manage access to the dashboard's workbook); a tenant admin can instead pass `renderAs` to render as another console or embed user, the same subject vocabulary a scheduled notification's recipients use. New schemas: `StartDashboardExportInput`, `DashboardExportJobResponse`, `DashboardExportStatusResponse`, `ExportSubjectInput`.
17
+ - `CreateNotificationInput` / `UpdateNotificationInput` gained `memberSwitchers` — Field-switcher selections applied when the notification's dashboard is rendered — read back on the notification response too. New schema: `DashboardMemberSwitcherInput` / `DashboardMemberSwitcher`.
18
+ - `ConnectReportToWorkbookInput`, `CreateReportInput`, `UpdateReportInput` and `RefreshReportInput` gained `resultChecksum` — a client-computed fingerprint of the cells a write just placed on the sheet, echoed back on `ReportPlacement.resultChecksum` so a client can tell whether a placement has been hand-edited since. New schemas: `ReportPlacementResultChecksumInput` / `ReportPlacementResultChecksum`, `ReportPlacementResultChunkInput` / `ReportPlacementResultChunk`. `ConnectReportToWorkbookInput` also gained `addressOnly`, for an address-only correction (e.g. a renamed sheet tab) that should not erase the stored fingerprint.
19
+ - `PivotItems` / `PivotItemsInput` gained `displayScale` (`"model"` | `"absolute"` | `"thousands"` | `"millions"` | `"billions"`) and `showColumnTotals`.
20
+ - `WorkbookDashboardInput.dashboardDraft` now accepts a widget without an `id` — the server assigns one. New schema `DashboardConfigDraftInput` (with `DashboardWidgetDraftInput`); publishing or creating a dashboard still requires an `id` on every widget via the existing `DashboardConfigInput`.
21
+
12
22
  ## [0.6.0] - 2026-09-02
23
+
13
24
  ### Added
14
25
 
15
26
  - `User` (`GET /api/v1/users/me`, `UsersPublicController.getMe`) gained `userPolicies` — the caller's effective resource policies: direct grants, organization-wide grants and grants inherited from their groups. This is the set the console has always read over GraphQL; on REST it lets an embedded Creator Mode session resolve a workbook another embed user shared with it, which previously granted nothing beyond viewing. New schemas: `Policy`, `PolicyResourceType`.
package/dist/schema.d.ts CHANGED
@@ -305,6 +305,82 @@ export interface paths {
305
305
  patch?: never;
306
306
  trace?: never;
307
307
  };
308
+ "/api/v1/deployments/{deploymentId}/dashboard-exports": {
309
+ parameters: {
310
+ query?: never;
311
+ header?: never;
312
+ path?: never;
313
+ cookie?: never;
314
+ };
315
+ get?: never;
316
+ put?: never;
317
+ /**
318
+ * Export a dashboard as PNG or PDF
319
+ * @description Submit a render of a published dashboard. Identify it with either `dashboardId` (numeric) or `dashboardPublicId` (string) — supply exactly one; it must belong to this deployment, otherwise `404` is returned.
320
+ *
321
+ * Returns as soon as the job is accepted, because a render waits for every widget to finish querying. Poll `GET /dashboard-exports/{jobId}` until `status` is `completed`, then fetch the file from `GET /dashboard-exports/{jobId}/download`. The job and its file are dropped at `expiresAt` (5 minutes) — download before then or submit again.
322
+ *
323
+ * Pass `filters`, `timeGrains` and `memberSwitchers` to render the board with specific control values, exactly as a scheduled notification does; omit them to render its saved defaults.
324
+ *
325
+ * By default the dashboard renders under the calling user's own security context, so the file shows what that user would see. Requires **manage** access to the dashboard's workbook — the same permission the console's own "Download as PNG / PDF" actions require, because a whole-dashboard render is a bulk data export.
326
+ *
327
+ * To export on someone else's behalf, pass `renderAs`: the queries behind the image then run under that user's security context instead of yours. **Requires the caller to be a tenant administrator.** Name a console user by `userId` or `email` (`type: USER`), or an embed user by `embedTenantName` + `externalId` (`type: EMBED_USER`). A deactivated console user is not a valid subject and returns `404`; an email is matched case-insensitively.
328
+ *
329
+ * An embed subject is provisioned if it does not exist yet, and `groups`, `userAttributes` and `securityContext` apply to **this render only** — they are carried on the render's own session and are NOT written to the user's stored context, so exporting for someone never changes what their live embedded sessions see. (Use the embed-tenant users API to change a user's stored context.) An embed subject additionally requires the dashboard's workbook to be shared with that embed tenant, otherwise `403` is returned.
330
+ *
331
+ * Returns `403` when the workspace has data downloads restricted — including for an on-behalf-of export, which deliberately does **not** bypass that setting the way a built-in scheduled notification does — and `429` when there are already too many exports in flight for the identity being rendered as.
332
+ */
333
+ post: operations["DashboardExportsPublicController.startExport"];
334
+ delete?: never;
335
+ options?: never;
336
+ head?: never;
337
+ patch?: never;
338
+ trace?: never;
339
+ };
340
+ "/api/v1/deployments/{deploymentId}/dashboard-exports/{jobId}": {
341
+ parameters: {
342
+ query?: never;
343
+ header?: never;
344
+ path?: never;
345
+ cookie?: never;
346
+ };
347
+ /**
348
+ * Get the status of a dashboard export
349
+ * @description Progress of a submitted render. Poll until `status` is `completed` (then download it) or `failed` (then read `error`); `pending` and `processing` both mean keep waiting.
350
+ *
351
+ * Returns `404` once the job has expired, and for a job submitted by a different user — a job is only ever visible to whoever started it.
352
+ */
353
+ get: operations["DashboardExportsPublicController.getExportStatus"];
354
+ put?: never;
355
+ post?: never;
356
+ delete?: never;
357
+ options?: never;
358
+ head?: never;
359
+ patch?: never;
360
+ trace?: never;
361
+ };
362
+ "/api/v1/deployments/{deploymentId}/dashboard-exports/{jobId}/download": {
363
+ parameters: {
364
+ query?: never;
365
+ header?: never;
366
+ path?: never;
367
+ cookie?: never;
368
+ };
369
+ /**
370
+ * Download a completed dashboard export
371
+ * @description Stream the rendered file as an attachment, named `dashboard.png` / `dashboard.pdf` unless `?filename=` supplies a different stem (the extension always follows the rendered format).
372
+ *
373
+ * Returns `409` while the job is still rendering — poll `GET /dashboard-exports/{jobId}` first — `422` if the render failed (terminal: submit a new export rather than retrying this one), and `404` once the job has expired or if it belongs to a different user.
374
+ */
375
+ get: operations["DashboardExportsPublicController.downloadExport"];
376
+ put?: never;
377
+ post?: never;
378
+ delete?: never;
379
+ options?: never;
380
+ head?: never;
381
+ patch?: never;
382
+ trace?: never;
383
+ };
308
384
  "/api/v1/deployments/{deploymentId}/dbt-sync": {
309
385
  parameters: {
310
386
  query?: never;
@@ -2911,11 +2987,13 @@ export interface components {
2911
2987
  private?: boolean | null;
2912
2988
  };
2913
2989
  ConnectReportToWorkbookInput: {
2990
+ addressOnly?: boolean | null;
2914
2991
  anchorCell?: string | null;
2915
2992
  endResultCell?: string | null;
2916
2993
  externalWorkbookId: string;
2917
2994
  host?: components["schemas"]["ConnectReportToWorkbookInputHost"] | null;
2918
2995
  placementId?: string | null;
2996
+ resultChecksum?: components["schemas"]["ReportPlacementResultChecksumInput"] | null;
2919
2997
  resultLocation: string;
2920
2998
  sheetId?: string | null;
2921
2999
  sheetName?: string | null;
@@ -2990,6 +3068,7 @@ export interface components {
2990
3068
  dayOfWeek?: number | null;
2991
3069
  filters?: components["schemas"]["DashboardFilterInput"][] | null;
2992
3070
  hour?: number | null;
3071
+ memberSwitchers?: components["schemas"]["DashboardMemberSwitcherInput"][] | null;
2993
3072
  minute?: number | null;
2994
3073
  notificationAiSummary?: boolean | null;
2995
3074
  notificationEnabled?: boolean | null;
@@ -3039,6 +3118,7 @@ export interface components {
3039
3118
  name?: string | null;
3040
3119
  pivotItems?: components["schemas"]["PivotItemsInput"] | null;
3041
3120
  publicId?: string | null;
3121
+ resultChecksum?: components["schemas"]["ReportPlacementResultChecksumInput"] | null;
3042
3122
  resultLocation?: string | null;
3043
3123
  sheetId?: string | null;
3044
3124
  source?: components["schemas"]["CreateReportInputSource"] | null;
@@ -3189,6 +3269,20 @@ export interface components {
3189
3269
  title?: string | null;
3190
3270
  widgets?: components["schemas"]["DashboardWidget"][] | null;
3191
3271
  };
3272
+ DashboardConfigDraftInput: {
3273
+ app?: components["schemas"]["DashboardAppSourceInput"] | null;
3274
+ description?: string | null;
3275
+ kind?: components["schemas"]["DashboardConfigDraftInputKind"] | null;
3276
+ layout?: components["schemas"]["DashboardLayoutInput"] | null;
3277
+ settings?: {
3278
+ [key: string]: any;
3279
+ } | null;
3280
+ theme?: components["schemas"]["DashboardThemeInput"] | null;
3281
+ title?: string | null;
3282
+ widgets?: components["schemas"]["DashboardWidgetDraftInput"][] | null;
3283
+ };
3284
+ /** @enum {string} */
3285
+ DashboardConfigDraftInputKind: "CLASSIC" | "APP";
3192
3286
  DashboardConfigInput: {
3193
3287
  app?: components["schemas"]["DashboardAppSourceInput"] | null;
3194
3288
  description?: string | null;
@@ -3211,6 +3305,23 @@ export interface components {
3211
3305
  allowEmbed: boolean;
3212
3306
  publicId: string;
3213
3307
  };
3308
+ DashboardExportJobResponse: {
3309
+ /**
3310
+ * Format: date-time
3311
+ * @description When the job (and its rendered file) is evicted from the renderer cache. Download before this, or submit a new export.
3312
+ */
3313
+ expiresAt: string;
3314
+ /** @description Job id to poll for status and to download the finished file with. */
3315
+ jobId: string;
3316
+ };
3317
+ DashboardExportStatusResponse: {
3318
+ contentType?: string | null;
3319
+ error?: string | null;
3320
+ progress?: number | null;
3321
+ status: components["schemas"]["DashboardExportStatusResponseStatus"];
3322
+ };
3323
+ /** @enum {string} */
3324
+ DashboardExportStatusResponseStatus: "pending" | "processing" | "completed" | "failed";
3214
3325
  DashboardFilter: {
3215
3326
  caseSensitive?: any | null;
3216
3327
  endInclusive?: any | null;
@@ -3246,6 +3357,16 @@ export interface components {
3246
3357
  margin?: number[] | null;
3247
3358
  rowHeight?: number | null;
3248
3359
  };
3360
+ DashboardMemberSwitcher: {
3361
+ member: string;
3362
+ selected: string;
3363
+ };
3364
+ DashboardMemberSwitcherInput: {
3365
+ /** @description Path of the member the control replaces, e.g. "Orders.status" */
3366
+ member: string;
3367
+ /** @description Name of the member to show in its place, e.g. "city" (no view prefix) */
3368
+ selected: string;
3369
+ };
3249
3370
  DashboardResponsiveLayouts: {
3250
3371
  lg?: components["schemas"]["DashboardWidgetPosition"] | null;
3251
3372
  md?: components["schemas"]["DashboardWidgetPosition"] | null;
@@ -3295,6 +3416,20 @@ export interface components {
3295
3416
  } | null;
3296
3417
  type: components["schemas"]["DashboardWidgetDtoType"];
3297
3418
  };
3419
+ DashboardWidgetDraftInput: {
3420
+ config?: {
3421
+ [key: string]: any;
3422
+ } | null;
3423
+ id?: string | null;
3424
+ position: components["schemas"]["DashboardWidgetPositionInput"];
3425
+ responsiveLayouts?: components["schemas"]["DashboardResponsiveLayoutsInput"] | null;
3426
+ style?: {
3427
+ [key: string]: any;
3428
+ } | null;
3429
+ type: components["schemas"]["DashboardWidgetDraftInputType"];
3430
+ };
3431
+ /** @enum {string} */
3432
+ DashboardWidgetDraftInputType: "CHART" | "TEXT" | "FILTER" | "AI" | "TIME_GRAIN" | "FIELD" | "PARENT" | "SPACER" | "DIVIDER" | "CONTAINER";
3298
3433
  /** @enum {string} */
3299
3434
  DashboardWidgetDtoType: "CHART" | "TEXT" | "FILTER" | "AI" | "TIME_GRAIN" | "FIELD" | "PARENT" | "SPACER" | "DIVIDER" | "CONTAINER";
3300
3435
  DashboardWidgetInput: {
@@ -3753,6 +3888,20 @@ export interface components {
3753
3888
  items: components["schemas"]["EnvVariableItem"][];
3754
3889
  pageInfo?: components["schemas"]["PageInfo"] | null;
3755
3890
  };
3891
+ ExportSubjectInput: {
3892
+ email?: string | null;
3893
+ embedTenantName?: string | null;
3894
+ externalId?: string | null;
3895
+ groups?: string[] | null;
3896
+ securityContext?: {
3897
+ [key: string]: any;
3898
+ } | null;
3899
+ type: components["schemas"]["ExportSubjectInputType"];
3900
+ userAttributes?: components["schemas"]["UserAttributeInput"][] | null;
3901
+ userId?: number | null;
3902
+ };
3903
+ /** @enum {string} */
3904
+ ExportSubjectInputType: "USER" | "EMBED_USER";
3756
3905
  FileHash: {
3757
3906
  hash: string;
3758
3907
  };
@@ -3972,6 +4121,7 @@ export interface components {
3972
4121
  humanReadableSchedule: string;
3973
4122
  id: number;
3974
4123
  isEnabled: boolean;
4124
+ memberSwitchers?: components["schemas"]["DashboardMemberSwitcher"][] | null;
3975
4125
  /** @description Whether this notification carries an AI-generated "what changed" summary in its body. */
3976
4126
  notificationAiSummary: boolean;
3977
4127
  notificationEnabled: boolean;
@@ -4072,21 +4222,29 @@ export interface components {
4072
4222
  };
4073
4223
  PivotItems: {
4074
4224
  columns: string[];
4225
+ displayScale?: components["schemas"]["PivotItemsDisplayScale"] | null;
4075
4226
  filters: string[];
4076
4227
  measures: string[];
4077
4228
  measuresAxis?: components["schemas"]["PivotItemsMeasuresAxis"] | null;
4078
4229
  measuresPosition?: components["schemas"]["PivotItemsMeasuresPosition"] | null;
4079
4230
  rows: string[];
4231
+ showColumnTotals?: boolean | null;
4080
4232
  };
4233
+ /** @enum {string} */
4234
+ PivotItemsDisplayScale: "model" | "absolute" | "thousands" | "millions" | "billions";
4081
4235
  PivotItemsInput: {
4082
4236
  columns: string[];
4237
+ displayScale?: components["schemas"]["PivotItemsInputDisplayScale"] | null;
4083
4238
  filters: string[];
4084
4239
  measures: string[];
4085
4240
  measuresAxis?: components["schemas"]["PivotItemsInputMeasuresAxis"] | null;
4086
4241
  measuresPosition?: components["schemas"]["PivotItemsInputMeasuresPosition"] | null;
4087
4242
  rows: string[];
4243
+ showColumnTotals?: boolean | null;
4088
4244
  };
4089
4245
  /** @enum {string} */
4246
+ PivotItemsInputDisplayScale: "model" | "absolute" | "thousands" | "millions" | "billions";
4247
+ /** @enum {string} */
4090
4248
  PivotItemsInputMeasuresAxis: "columns" | "rows";
4091
4249
  /** @enum {string} */
4092
4250
  PivotItemsInputMeasuresPosition: "before" | "after";
@@ -4167,6 +4325,7 @@ export interface components {
4167
4325
  anchorCell?: string | null;
4168
4326
  externalWorkbookId?: string | null;
4169
4327
  placementId?: string | null;
4328
+ resultChecksum?: components["schemas"]["ReportPlacementResultChecksumInput"] | null;
4170
4329
  resultLocation?: string | null;
4171
4330
  sheetId?: string | null;
4172
4331
  sheetName?: string | null;
@@ -4344,6 +4503,7 @@ export interface components {
4344
4503
  queryChecksum?: string | null;
4345
4504
  refreshedAt?: string | null;
4346
4505
  refreshedByUserId?: number | null;
4506
+ resultChecksum?: components["schemas"]["ReportPlacementResultChecksum"] | null;
4347
4507
  resultLocation: string;
4348
4508
  sheetId?: string | null;
4349
4509
  sheetName?: string | null;
@@ -4353,6 +4513,24 @@ export interface components {
4353
4513
  };
4354
4514
  /** @enum {string} */
4355
4515
  ReportPlacementHost: "GOOGLE_SHEETS" | "EXCEL";
4516
+ ReportPlacementResultChecksum: {
4517
+ chunks: components["schemas"]["ReportPlacementResultChunk"][];
4518
+ v: number;
4519
+ };
4520
+ ReportPlacementResultChecksumInput: {
4521
+ chunks: components["schemas"]["ReportPlacementResultChunkInput"][];
4522
+ v: number;
4523
+ };
4524
+ ReportPlacementResultChunk: {
4525
+ from: number;
4526
+ hash: string;
4527
+ to?: number | null;
4528
+ };
4529
+ ReportPlacementResultChunkInput: {
4530
+ from: number;
4531
+ hash: string;
4532
+ to?: number | null;
4533
+ };
4356
4534
  /** @enum {string} */
4357
4535
  ReportPlacementSyncStatus: "UP_TO_DATE" | "CHANGED" | "UNKNOWN";
4358
4536
  ReportSnapshot: {
@@ -4459,6 +4637,17 @@ export interface components {
4459
4637
  }[];
4460
4638
  pageInfo?: components["schemas"]["PageInfo"] | null;
4461
4639
  };
4640
+ StartDashboardExportInput: {
4641
+ dashboardId?: number | null;
4642
+ dashboardPublicId?: string | null;
4643
+ filters?: components["schemas"]["DashboardFilterInput"][] | null;
4644
+ format: components["schemas"]["StartDashboardExportInputFormat"];
4645
+ memberSwitchers?: components["schemas"]["DashboardMemberSwitcherInput"][] | null;
4646
+ renderAs?: components["schemas"]["ExportSubjectInput"] | null;
4647
+ timeGrains?: components["schemas"]["DashboardTimeGrainInput"][] | null;
4648
+ };
4649
+ /** @enum {string} */
4650
+ StartDashboardExportInputFormat: "png" | "pdf";
4462
4651
  StartDbtSyncInput: {
4463
4652
  branchName?: string | null;
4464
4653
  ref?: string | null;
@@ -4565,6 +4754,7 @@ export interface components {
4565
4754
  filters?: components["schemas"]["DashboardFilterInput"][] | null;
4566
4755
  hour?: number | null;
4567
4756
  isEnabled?: boolean | null;
4757
+ memberSwitchers?: components["schemas"]["DashboardMemberSwitcherInput"][] | null;
4568
4758
  minute?: number | null;
4569
4759
  notificationAiSummary?: boolean | null;
4570
4760
  notificationEnabled?: boolean | null;
@@ -4619,6 +4809,7 @@ export interface components {
4619
4809
  pivotItems?: components["schemas"]["PivotItems"] | null;
4620
4810
  placementId?: string | null;
4621
4811
  publicId?: string | null;
4812
+ resultChecksum?: components["schemas"]["ReportPlacementResultChecksumInput"] | null;
4622
4813
  resultLocation?: string | null;
4623
4814
  sheetId?: string | null;
4624
4815
  sqlQuery?: string | null;
@@ -4901,7 +5092,7 @@ export interface components {
4901
5092
  dashboardPublished?: components["schemas"]["DashboardConfig"] | null;
4902
5093
  };
4903
5094
  WorkbookDashboardInput: {
4904
- dashboardDraft?: components["schemas"]["DashboardConfigInput"] | null;
5095
+ dashboardDraft?: components["schemas"]["DashboardConfigDraftInput"] | null;
4905
5096
  };
4906
5097
  /** @enum {string} */
4907
5098
  WorkbookDtoType: "FOLDER" | "WORKBOOK" | "REPORT";
@@ -5573,6 +5764,86 @@ export interface operations {
5573
5764
  };
5574
5765
  };
5575
5766
  };
5767
+ "DashboardExportsPublicController.startExport": {
5768
+ parameters: {
5769
+ query?: never;
5770
+ header?: never;
5771
+ path: {
5772
+ /** @description Numeric id of the deployment that owns the dashboard. */
5773
+ deploymentId: number;
5774
+ };
5775
+ cookie?: never;
5776
+ };
5777
+ /** @description StartDashboardExportInput */
5778
+ requestBody: {
5779
+ content: {
5780
+ "application/json": components["schemas"]["StartDashboardExportInput"];
5781
+ };
5782
+ };
5783
+ responses: {
5784
+ 200: {
5785
+ headers: {
5786
+ [name: string]: any;
5787
+ };
5788
+ content: {
5789
+ "application/json": components["schemas"]["DashboardExportJobResponse"];
5790
+ };
5791
+ };
5792
+ };
5793
+ };
5794
+ "DashboardExportsPublicController.getExportStatus": {
5795
+ parameters: {
5796
+ query?: never;
5797
+ header?: never;
5798
+ path: {
5799
+ /** @description Numeric id of the deployment that owns the dashboard. */
5800
+ deploymentId: number;
5801
+ /** @description Job id returned when the export was submitted. */
5802
+ jobId: string;
5803
+ };
5804
+ cookie?: never;
5805
+ };
5806
+ requestBody?: never;
5807
+ responses: {
5808
+ 200: {
5809
+ headers: {
5810
+ [name: string]: any;
5811
+ };
5812
+ content: {
5813
+ "application/json": components["schemas"]["DashboardExportStatusResponse"];
5814
+ };
5815
+ };
5816
+ };
5817
+ };
5818
+ "DashboardExportsPublicController.downloadExport": {
5819
+ parameters: {
5820
+ query?: {
5821
+ /** @description Filename stem for the attachment, without extension. Defaults to `dashboard`. */
5822
+ filename?: string;
5823
+ };
5824
+ header?: never;
5825
+ path: {
5826
+ /** @description Numeric id of the deployment that owns the dashboard. */
5827
+ deploymentId: number;
5828
+ /** @description Job id returned when the export was submitted. */
5829
+ jobId: string;
5830
+ };
5831
+ cookie?: never;
5832
+ };
5833
+ requestBody?: never;
5834
+ responses: {
5835
+ /** @description The rendered dashboard. */
5836
+ 200: {
5837
+ headers: {
5838
+ [name: string]: any;
5839
+ };
5840
+ content: {
5841
+ "application/pdf": string;
5842
+ "image/png": string;
5843
+ };
5844
+ };
5845
+ };
5846
+ };
5576
5847
  "DbtSyncPublicController.listDbtSyncs": {
5577
5848
  parameters: {
5578
5849
  query?: {