@gooddata/sdk-backend-tiger 11.55.0-alpha.1 → 11.55.0-alpha.3

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.
@@ -1,4 +1,4 @@
1
- export declare const LIB_VERSION = "11.55.0-alpha.1";
1
+ export declare const LIB_VERSION = "11.55.0-alpha.3";
2
2
  export declare const LIB_DESCRIPTION = "GoodData Backend SPI implementation for GoodData Cloud and GoodData.CN";
3
3
  export declare const LIB_NAME = "@gooddata/sdk-backend-tiger";
4
4
  //# sourceMappingURL=__version.d.ts.map
package/esm/__version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // (C) 2021 GoodData Corporation
2
2
  // DO NOT CHANGE THIS FILE, IT IS RE-GENERATED ON EVERY BUILD
3
- export const LIB_VERSION = "11.55.0-alpha.1";
3
+ export const LIB_VERSION = "11.55.0-alpha.3";
4
4
  export const LIB_DESCRIPTION = "GoodData Backend SPI implementation for GoodData Cloud and GoodData.CN";
5
5
  export const LIB_NAME = "@gooddata/sdk-backend-tiger";
@@ -161,7 +161,7 @@ export const DefaultFeatureFlags = {
161
161
  enableParameters: true,
162
162
  enableAnalyticalCatalogMetricEditor: false,
163
163
  enableAnalyticalCatalogVisualizationEditor: false,
164
- enableStringParameters: false,
164
+ enableStringParameters: true,
165
165
  enableLabsSmartFunctions: false,
166
166
  enableCustomTooltip: true,
167
167
  enableDataProfiling: false,
@@ -21,13 +21,6 @@ export declare class TigerWorkspaceCatalogAvailableItemsFactory implements IWork
21
21
  withSignal(signal: AbortSignal): IWorkspaceCatalogAvailableItemsFactory;
22
22
  load(): Promise<TigerWorkspaceCatalogWithAvailableItems>;
23
23
  }
24
- /**
25
- * Whether a reference points at a computed attribute - either because it says so, or because its
26
- * identifier is one of the workspace's computed attributes. The fabricated display form of a
27
- * computed attribute shares the computed attribute's id, so the identifier match holds for both the
28
- * attribute reference and its display form reference.
29
- */
30
- export declare const isComputedAttributeRef: (ref: ObjRef, computedAttributeIds: Set<string>) => boolean;
31
24
  /**
32
25
  * @internal
33
26
  */
@@ -1 +1 @@
1
- {"version":3,"file":"availableItemsFactory.d.ts","sourceRoot":"","sources":["../../../../src/backend/workspace/catalog/availableItemsFactory.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,KAAK,sCAAsC,EAC3C,KAAK,iDAAiD,EACzD,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,WAAW,EAChB,KAAK,eAAe,EAEpB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,kBAAkB,EACvB,KAAK,MAAM,EAoBd,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,EAAE,uCAAuC,EAAE,MAAM,gCAAgC,CAAC;AAgDzF,qBAAa,0CAA2C,YAAW,sCAAsC;IAEjG,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAMxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAX5B,YACqB,QAAQ,EAAE,2BAA2B,EACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,EAAE,EACvB,KAAK,EAAE,WAAW,EAAE,EACpB,OAAO,GAAE,iDAKzB,EACgB,MAAM,CAAC,yBAAa,EACrC;IAEG,WAAW,CACd,OAAO,EAAE,OAAO,CAAC,iDAAiD,CAAC,GACpE,sCAAsC,CAaxC;IAEM,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,sCAAsC,CAEzE;IAEM,QAAQ,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,sCAAsC,CAEhF;IAEM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,sCAAsC,CAEzE;IAEM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,sCAAsC,CAEzE;IAEM,QAAQ,CAAC,KAAK,EAAE,mBAAmB,EAAE,GAAG,sCAAsC,CAEpF;IAEM,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,sCAAsC,CAErF;IAEM,UAAU,CAAC,UAAU,EAAE,OAAO,GAAG,sCAAsC,CAI7E;IAEM,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,sCAAsC,CAS7E;IAEY,IAAI,IAAI,OAAO,CAAC,uCAAuC,CAAC,CAgFpE;CACJ;AAED;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,6DACuE,CAAC;AAE3G;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAMxF;AAED,gBAAgB;AAChB,eAAO,MAAM,8BAA8B,iGA8B1C,CAAC"}
1
+ {"version":3,"file":"availableItemsFactory.d.ts","sourceRoot":"","sources":["../../../../src/backend/workspace/catalog/availableItemsFactory.ts"],"names":[],"mappings":"AAOA,OAAO,EACH,KAAK,sCAAsC,EAC3C,KAAK,iDAAiD,EACzD,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,WAAW,EAChB,KAAK,eAAe,EAEpB,KAAK,mBAAmB,EACxB,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,kBAAkB,EACvB,KAAK,MAAM,EAmBd,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAE3E,OAAO,EAAE,uCAAuC,EAAE,MAAM,gCAAgC,CAAC;AAiDzF,qBAAa,0CAA2C,YAAW,sCAAsC;IAEjG,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAMxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;IAX5B,YACqB,QAAQ,EAAE,2BAA2B,EACrC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,aAAa,EAAE,EACvB,KAAK,EAAE,WAAW,EAAE,EACpB,OAAO,GAAE,iDAKzB,EACgB,MAAM,CAAC,yBAAa,EACrC;IAEG,WAAW,CACd,OAAO,EAAE,OAAO,CAAC,iDAAiD,CAAC,GACpE,sCAAsC,CAaxC;IAEM,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,sCAAsC,CAEzE;IAEM,QAAQ,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,sCAAsC,CAEhF;IAEM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,sCAAsC,CAEzE;IAEM,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,sCAAsC,CAEzE;IAEM,QAAQ,CAAC,KAAK,EAAE,mBAAmB,EAAE,GAAG,sCAAsC,CAEpF;IAEM,UAAU,CAAC,OAAO,EAAE,kBAAkB,GAAG,sCAAsC,CAErF;IAEM,UAAU,CAAC,UAAU,EAAE,OAAO,GAAG,sCAAsC,CAI7E;IAEM,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,sCAAsC,CAS7E;IAEY,IAAI,IAAI,OAAO,CAAC,uCAAuC,CAAC,CAwDpE;CACJ;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAMxF;AAED,gBAAgB;AAChB,eAAO,MAAM,8BAA8B,iGA8B1C,CAAC"}
@@ -2,7 +2,7 @@
2
2
  import { compact, intersectionWith, uniq } from "lodash-es";
3
3
  import { InvariantError } from "ts-invariant";
4
4
  import { ActionsApi_ComputeValidObjects } from "@gooddata/api-client-tiger/endpoints/validObjects";
5
- import { areObjRefsEqual, attributeLocalId, insightAttributes, insightFilters, insightMeasures, isAttribute, isCatalogAttribute, isCatalogAttributeHierarchy, isCatalogComputedAttribute, isCatalogFact, isCatalogMeasure, isFilter, isIdentifierRef, isLocalIdRef, isMeasure, isMeasureValueFilter, isRankingFilter, measureLocalId, } from "@gooddata/sdk-model";
5
+ import { areObjRefsEqual, attributeLocalId, insightAttributes, insightFilters, insightMeasures, isAttribute, isCatalogAttribute, isCatalogAttributeHierarchy, isCatalogComputedAttribute, isCatalogFact, isCatalogMeasure, isFilter, isLocalIdRef, isMeasure, isMeasureValueFilter, isRankingFilter, measureLocalId, } from "@gooddata/sdk-model";
6
6
  import { jsonApiIdToObjRef } from "../../../convertors/fromBackend/ObjRefConverter.js";
7
7
  import { convertAfmFilters } from "../../../convertors/toBackend/afm/AfmFiltersConverter.js";
8
8
  import { convertAttribute } from "../../../convertors/toBackend/afm/AttributeConverter.js";
@@ -11,6 +11,7 @@ import { TigerWorkspaceCatalogWithAvailableItems } from "./catalogWithAvailableI
11
11
  //ivec investigate
12
12
  const typesMatching = {
13
13
  attribute: "attributes",
14
+ computedAttribute: "computedAttributes",
14
15
  fact: "facts",
15
16
  measure: "measures",
16
17
  // dateDatasets are not supported by tiger in this context
@@ -111,19 +112,7 @@ export class TigerWorkspaceCatalogAvailableItemsFactory {
111
112
  const relevantItems = insight
112
113
  ? [...insightMeasures(insight), ...insightAttributes(insight), ...insightFilters(insight)]
113
114
  : items;
114
- // The validObjects action does not accept a computed attribute yet, and one in the query
115
- // makes it fail for the WHOLE insight - which takes the catalog availability and the date
116
- // datasets down with it. Leaving computed attributes out narrows the answer (their own
117
- // restrictions are not applied) instead of losing it.
118
- //
119
- // Identified against the CATALOG rather than against the reference's own type: an insight
120
- // built before the reference carried the computed attribute type still points at one with a
121
- // plain displayForm type, and such a reference must be dropped too or the request 400s.
122
- // TODO INE (CQ-2796): include them once the action accepts them
123
- const computedAttributeIds = new Set(this.items.filter(isCatalogComputedAttribute).map((item) => item.computedAttribute.id));
124
- const attributes = relevantItems
125
- .filter(isAttribute)
126
- .filter((attribute) => !isComputedAttributeRef(attribute.attribute.displayForm, computedAttributeIds));
115
+ const attributes = relevantItems.filter(isAttribute);
127
116
  const measures = relevantItems.filter(isMeasure);
128
117
  const filters = relevantItems.filter(isFilter);
129
118
  const attributeLocalIds = new Set(attributes.map((attribute) => attributeLocalId(attribute)));
@@ -153,25 +142,10 @@ export class TigerWorkspaceCatalogAvailableItemsFactory {
153
142
  const allAvailableItems = [
154
143
  ...availableItems,
155
144
  ...(types.includes("attributeHierarchy") ? this.items.filter(isCatalogAttributeHierarchy) : []),
156
- // The action cannot evaluate a computed attribute yet, so one would never come back in
157
- // the response and filterAvailableItems would drop it - hence the pass-through. Only
158
- // when the query was actually sent: an empty query already answers with every item, and
159
- // appending would list the computed attributes twice.
160
- // TODO INE (CQ-2796): drop this once the action evaluates them
161
- ...(types.includes("computedAttribute") && !afmValidObjectsQueryEmpty
162
- ? this.items.filter(isCatalogComputedAttribute)
163
- : []),
164
145
  ];
165
146
  return new TigerWorkspaceCatalogWithAvailableItems(this.groups, this.items, allAvailableItems, this.options);
166
147
  }
167
148
  }
168
- /**
169
- * Whether a reference points at a computed attribute - either because it says so, or because its
170
- * identifier is one of the workspace's computed attributes. The fabricated display form of a
171
- * computed attribute shares the computed attribute's id, so the identifier match holds for both the
172
- * attribute reference and its display form reference.
173
- */
174
- export const isComputedAttributeRef = (ref, computedAttributeIds) => isIdentifierRef(ref) && (ref.type === "computedAttribute" || computedAttributeIds.has(ref.identifier));
175
149
  /**
176
150
  * @internal
177
151
  */
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/backend/workspace/computedAttributes/index.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EACR,6BAA6B,EAC7B,4BAA4B,EAC5B,uBAAuB,EACvB,mCAAmC,EACtC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,gCAAgC,EACrC,KAAK,0CAA0C,EAC/C,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,MAAM,EAEd,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAI3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,qBAAa,gCAAiC,YAAW,mCAAmC;IAEpF,OAAO,CAAC,QAAQ,CAAC,QAAQ;aACT,SAAS,EAAE,MAAM;IAFrC,YACqB,QAAQ,EAAE,2BAA2B,EACtC,SAAS,EAAE,MAAM,EACjC;IAEE,uBAAuB,CACzB,iBAAiB,EAAE,0CAA0C,GAC9D,OAAO,CAAC,gCAAgC,CAAC,CAgB3C;IAEK,uBAAuB,CACzB,iBAAiB,EAAE,gCAAgC,GACpD,OAAO,CAAC,gCAAgC,CAAC,CAkB3C;IAEK,2BAA2B,CAC7B,iBAAiB,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,uBAAuB,GAC1E,OAAO,CAAC,gCAAgC,CAAC,CA4B3C;IAEK,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASxD;IAEY,oBAAoB,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,4BAAiC,GAC3C,OAAO,CAAC,gCAAgC,CAAC,CAW3C;IAEY,oCAAoC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CA2BjG;IAEY,sCAAsC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAkCvG;IAEM,0BAA0B,IAAI,uBAAuB,CAE3D;CACJ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/backend/workspace/computedAttributes/index.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACR,6BAA6B,EAC7B,4BAA4B,EAC5B,uBAAuB,EACvB,mCAAmC,EACtC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,gCAAgC,EACrC,KAAK,0CAA0C,EAC/C,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,MAAM,EAGd,MAAM,qBAAqB,CAAC;AAO7B,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAI3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE,qBAAa,gCAAiC,YAAW,mCAAmC;IAEpF,OAAO,CAAC,QAAQ,CAAC,QAAQ;aACT,SAAS,EAAE,MAAM;IAFrC,YACqB,QAAQ,EAAE,2BAA2B,EACtC,SAAS,EAAE,MAAM,EACjC;IAEE,uBAAuB,CACzB,iBAAiB,EAAE,0CAA0C,GAC9D,OAAO,CAAC,gCAAgC,CAAC,CAgB3C;IAEK,uBAAuB,CACzB,iBAAiB,EAAE,gCAAgC,GACpD,OAAO,CAAC,gCAAgC,CAAC,CAkB3C;IAEK,2BAA2B,CAC7B,iBAAiB,EAAE,OAAO,CAAC,mBAAmB,CAAC,GAAG,uBAAuB,GAC1E,OAAO,CAAC,gCAAgC,CAAC,CA4B3C;IAEK,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CASxD;IAEY,oBAAoB,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,4BAAiC,GAC3C,OAAO,CAAC,gCAAgC,CAAC,CAW3C;IAEY,oCAAoC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CA2BjG;IAEY,sCAAsC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,6BAA6B,CAAC,CAsDvG;IAEM,0BAA0B,IAAI,uBAAuB,CAE3D;CACJ"}
@@ -1,9 +1,11 @@
1
1
  // (C) 2026 GoodData Corporation
2
+ import { uniqBy } from "lodash-es";
2
3
  import { MetadataUtilities } from "@gooddata/api-client-tiger";
3
- import { EntitiesApi_CreateEntityComputedAttributes, EntitiesApi_DeleteEntityComputedAttributes, EntitiesApi_GetAllEntitiesMetrics, EntitiesApi_GetAllEntitiesVisualizationObjects, EntitiesApi_GetEntityComputedAttributes, EntitiesApi_PatchEntityComputedAttributes, EntitiesApi_UpdateEntityComputedAttributes, } from "@gooddata/api-client-tiger/endpoints/entitiesObjects";
4
- import { isIdentifierRef, } from "@gooddata/sdk-model";
4
+ import { DashboardsApi_GetAllEntitiesAnalyticalDashboards, EntitiesApi_CreateEntityComputedAttributes, EntitiesApi_DeleteEntityComputedAttributes, EntitiesApi_GetAllEntitiesMetrics, EntitiesApi_GetAllEntitiesVisualizationObjects, EntitiesApi_GetEntityComputedAttributes, EntitiesApi_PatchEntityComputedAttributes, EntitiesApi_UpdateEntityComputedAttributes, } from "@gooddata/api-client-tiger/endpoints/entitiesObjects";
5
+ import { insightId, isIdentifierRef, } from "@gooddata/sdk-model";
5
6
  import { convertComputedAttributeFromBackend } from "../../../convertors/fromBackend/ComputedAttributeConverter.js";
6
7
  import { visualizationObjectsItemToInsight } from "../../../convertors/fromBackend/InsightConverter.js";
8
+ import { convertAnalyticalDashboardWithLinks } from "../../../convertors/fromBackend/MetadataConverter.js";
7
9
  import { convertMetricFromBackend } from "../../../convertors/fromBackend/MetricConverter.js";
8
10
  import { convertComputedAttributeToBackend } from "../../../convertors/toBackend/ComputedAttributeConverter.js";
9
11
  import { objRefToIdentifier } from "../../../utils/api.js";
@@ -119,16 +121,15 @@ export class TigerWorkspaceComputedAttributes {
119
121
  }
120
122
  async getComputedAttributeReferencingObjects(ref) {
121
123
  const id = objRefToIdentifier(ref, this.authCall);
122
- // A visualization grouping by a computed attribute is the referent that exists today. The
123
- // backend allows the delete; the catalog refuses it and lists these titles instead.
124
+ // Visualizations grouping by the computed attribute, metrics that reference it, and
125
+ // dashboards that filter by it or embed those visualizations. The backend allows the
126
+ // delete; the catalog refuses it and lists these titles instead.
124
127
  const insights = this.authCall((client) => MetadataUtilities.getAllPagesOf(client, EntitiesApi_GetAllEntitiesVisualizationObjects, {
125
128
  workspaceId: this.workspace,
126
- // return only visualizationObjects that have a link to the given computed attribute
127
129
  filter: `computedAttributes.id==${id}`,
128
130
  })
129
131
  .then(MetadataUtilities.mergeEntitiesResults)
130
132
  .then((visualizationObjects) => visualizationObjects.data.map((visualizationObject) => visualizationObjectsItemToInsight(visualizationObject, visualizationObjects.included))));
131
- // Reports nothing until a metric can reference a computed attribute (pending backend support).
132
133
  const measures = this.authCall((client) => MetadataUtilities.getAllPagesOf(client, EntitiesApi_GetAllEntitiesMetrics, {
133
134
  workspaceId: this.workspace,
134
135
  include: ["computedAttributes"],
@@ -137,7 +138,18 @@ export class TigerWorkspaceComputedAttributes {
137
138
  .then(MetadataUtilities.mergeEntitiesResults)
138
139
  .then((metrics) => metrics.data.map((metric) => convertMetricFromBackend(metric, metrics.included))));
139
140
  const [insightList, measureList] = await Promise.all([insights, measures]);
140
- return { insights: insightList, measures: measureList };
141
+ const dashboardFilterParts = [`labels.id==${id}`];
142
+ if (insightList.length > 0) {
143
+ const insightIds = insightList.map((insight) => `"${insightId(insight)}"`).join(",");
144
+ dashboardFilterParts.push(`visualizationObjects.id=in=(${insightIds})`);
145
+ }
146
+ const analyticalDashboards = await this.authCall((client) => MetadataUtilities.getAllPagesOf(client, DashboardsApi_GetAllEntitiesAnalyticalDashboards, {
147
+ workspaceId: this.workspace,
148
+ filter: dashboardFilterParts.join(","),
149
+ })
150
+ .then(MetadataUtilities.mergeEntitiesResults)
151
+ .then((dashboards) => uniqBy(dashboards.data.map((dashboard) => convertAnalyticalDashboardWithLinks(dashboard)), (dashboard) => dashboard.id)));
152
+ return { insights: insightList, measures: measureList, analyticalDashboards };
141
153
  }
142
154
  getComputedAttributesQuery() {
143
155
  return new ComputedAttributesQuery(this.authCall, { workspaceId: this.workspace });
@@ -60,7 +60,7 @@ export class SemanticSearchQuery {
60
60
  async query(options) {
61
61
  const response = await this.authCall((client) => GenAiApi_AiSearch(client.axios, client.basePath, {
62
62
  workspaceId: this.workspaceId,
63
- searchRequest: this.config,
63
+ aiSearchRequest: this.config,
64
64
  }, options));
65
65
  // Casting because api-client has loose typing for object type
66
66
  return response.data;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/backend/workspace/insights/index.ts"],"names":[],"mappings":"AA+BA,OAAO,EACH,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,8BAA8B,EAEtC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,MAAM,EASd,MAAM,qBAAqB,CAAC;AAiB7B,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAM3E,qBAAa,sBAAuB,YAAW,yBAAyB;IAEhE,OAAO,CAAC,QAAQ,CAAC,QAAQ;aACT,SAAS,EAAE,MAAM;IAFrC,YACqB,QAAQ,EAAE,2BAA2B,EACtC,SAAS,EAAE,MAAM,EACjC;IAEG,qBAAqB,gDAS1B;IAEK,uBAAuB,uCAE5B;IAEK,WAAW,iFA6BhB;IAEK,gBAAgB,uBAErB;IAEF,OAAO,CAAC,4BAA4B,CAqBlC;IAEF,OAAO,CAAC,eAAe,CAmCrB;IAEF;;;OAGG;IACI,0BAA0B;;;OAyB/B;IAEF,OAAO,CAAC,wBAAwB,CAiB9B;IAEK,UAAU,mEAKf;IAEK,aAAa,qDAkClB;IAEK,aAAa,2CAqBlB;IAEK,iBAAiB,6FA2BtB;IAEK,gBAAgB,wFAerB;IAEK,aAAa,iCASlB;IAEK,2BAA2B,6GAKhC;IAEK,4BAA4B,gDAoBjC;IAEK,0BAA0B,GAAU,CAAC,2EAY1C;CACL"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/backend/workspace/insights/index.ts"],"names":[],"mappings":"AA+BA,OAAO,EACH,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,8BAA8B,EAEtC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,QAAQ,EACb,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,yBAAyB,EAC9B,KAAK,mBAAmB,EACxB,KAAK,MAAM,EASd,MAAM,qBAAqB,CAAC;AAkB7B,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAM3E,qBAAa,sBAAuB,YAAW,yBAAyB;IAEhE,OAAO,CAAC,QAAQ,CAAC,QAAQ;aACT,SAAS,EAAE,MAAM;IAFrC,YACqB,QAAQ,EAAE,2BAA2B,EACtC,SAAS,EAAE,MAAM,EACjC;IAEG,qBAAqB,gDAS1B;IAEK,uBAAuB,uCAE5B;IAEK,WAAW,iFA6BhB;IAEK,gBAAgB,uBAErB;IAEF,OAAO,CAAC,4BAA4B,CAqBlC;IAEF,OAAO,CAAC,eAAe,CAmCrB;IAEF;;;OAGG;IACI,0BAA0B;;;OAyB/B;IAEF,OAAO,CAAC,wBAAwB,CAiB9B;IAEK,UAAU,mEAKf;IAEK,aAAa,qDAoClB;IAEK,aAAa,2CAuBlB;IAEK,iBAAiB,6FA2BtB;IAEK,gBAAgB,wFAerB;IAEK,aAAa,iCASlB;IAEK,2BAA2B,6GAKhC;IAEK,4BAA4B,gDAoBjC;IAEK,0BAA0B,GAAU,CAAC,2EAY1C;CACL"}
@@ -12,6 +12,7 @@ import { convertVisualizationObjectsToInsights, insightFromInsightDefinition, }
12
12
  import { isInheritedObject } from "../../../convertors/fromBackend/ObjectInheritance.js";
13
13
  import { convertUserIdentifier } from "../../../convertors/fromBackend/UsersConverter.js";
14
14
  import { convertVisualizationObject } from "../../../convertors/fromBackend/visualizationObjects/VisualizationObjectConverter.js";
15
+ import { convertConditionalFormatting } from "../../../convertors/toBackend/ConditionalFormattingConverter.js";
15
16
  import { convertInsight } from "../../../convertors/toBackend/InsightConverter.js";
16
17
  import { objRefToIdentifier, objRefToUri } from "../../../utils/api.js";
17
18
  import { InsightsQuery } from "./insightsQuery.js";
@@ -160,6 +161,8 @@ export class TigerWorkspaceInsights {
160
161
  attributes: {
161
162
  description: insightSummary(insight),
162
163
  content: convertInsight(insight),
164
+ // dual-write: content (authoritative) + the typed projection
165
+ conditionalFormatting: convertConditionalFormatting(insight),
163
166
  title: insightTitle(insight),
164
167
  tags: insightTags(insight),
165
168
  ...(insight.insight.isHidden === undefined
@@ -185,6 +188,8 @@ export class TigerWorkspaceInsights {
185
188
  attributes: {
186
189
  description: insightSummary(insight),
187
190
  content: convertInsight(insight),
191
+ // dual-write: content (authoritative) + the typed projection
192
+ conditionalFormatting: convertConditionalFormatting(insight),
188
193
  title: insightTitle(insight),
189
194
  tags: insightTags(insight),
190
195
  isHidden: insight.insight.isHidden,
@@ -0,0 +1,27 @@
1
+ import { type JsonApiVisualizationObjectInAttributesConditionalFormatting } from "@gooddata/api-client-tiger";
2
+ import { type IInsightDefinition } from "@gooddata/sdk-model";
3
+ /**
4
+ * Projects the insight's conditional formatting (persisted free-form under
5
+ * `properties.controls.conditionalFormatting`) into the typed visualizationObject entity attribute.
6
+ *
7
+ * Dual-write: `content` — which still carries the same rules inside `properties` — stays
8
+ * authoritative; this typed attribute is a parallel, server-validated projection that readers switch
9
+ * to later. Two boundary guarantees:
10
+ * - Returns `null` (never `undefined`) when there is no formatting, so the PUT body explicitly clears
11
+ * the projection rather than relying on the server's omitted-attribute semantics — otherwise a
12
+ * cleared CF could leave a stale typed projection diverging from the authoritative `content`.
13
+ * - A malformed blob (`content` is free-form and unvalidated) also degrades to `null`: the projection
14
+ * must never break a save, since `content` remains the source of truth.
15
+ *
16
+ * `version` and `customTargets` are intentionally NOT carried — the typed schema does not model them
17
+ * yet, and `content` stays authoritative until the switch, so nothing is lost. This is an allow-list:
18
+ * a field added to {@link IConditionalFormatting} will not auto-propagate; extend this projection (and
19
+ * its test) when the typed schema grows.
20
+ *
21
+ * The projection is a structural copy except for relative-date granularities, which the SDK stores in
22
+ * its own vocabulary (`GDC.time.*`) while the typed schema uses tiger's (`YEAR`, `MONTH_OF_YEAR`, ...);
23
+ * those are translated via the canonical granularity mapping, and a granularity tiger does not model
24
+ * degrades the projection to `null` like any other malformed-blob case.
25
+ */
26
+ export declare function convertConditionalFormatting(insight: IInsightDefinition): JsonApiVisualizationObjectInAttributesConditionalFormatting | null;
27
+ //# sourceMappingURL=ConditionalFormattingConverter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConditionalFormattingConverter.d.ts","sourceRoot":"","sources":["../../../src/convertors/toBackend/ConditionalFormattingConverter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,2DAA2D,EAAE,MAAM,4BAA4B,CAAC;AAE9G,OAAO,EAIH,KAAK,kBAAkB,EAE1B,MAAM,qBAAqB,CAAC;AAI7B;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,4BAA4B,CACxC,OAAO,EAAE,kBAAkB,GAC5B,2DAA2D,GAAG,IAAI,CAsCpE"}
@@ -0,0 +1,72 @@
1
+ // (C) 2026 GoodData Corporation
2
+ import { NotSupported } from "@gooddata/sdk-backend-spi";
3
+ import { insightProperties, } from "@gooddata/sdk-model";
4
+ import { toTigerGranularity } from "../fromBackend/dateGranularityConversions.js";
5
+ /**
6
+ * Projects the insight's conditional formatting (persisted free-form under
7
+ * `properties.controls.conditionalFormatting`) into the typed visualizationObject entity attribute.
8
+ *
9
+ * Dual-write: `content` — which still carries the same rules inside `properties` — stays
10
+ * authoritative; this typed attribute is a parallel, server-validated projection that readers switch
11
+ * to later. Two boundary guarantees:
12
+ * - Returns `null` (never `undefined`) when there is no formatting, so the PUT body explicitly clears
13
+ * the projection rather than relying on the server's omitted-attribute semantics — otherwise a
14
+ * cleared CF could leave a stale typed projection diverging from the authoritative `content`.
15
+ * - A malformed blob (`content` is free-form and unvalidated) also degrades to `null`: the projection
16
+ * must never break a save, since `content` remains the source of truth.
17
+ *
18
+ * `version` and `customTargets` are intentionally NOT carried — the typed schema does not model them
19
+ * yet, and `content` stays authoritative until the switch, so nothing is lost. This is an allow-list:
20
+ * a field added to {@link IConditionalFormatting} will not auto-propagate; extend this projection (and
21
+ * its test) when the typed schema grows.
22
+ *
23
+ * The projection is a structural copy except for relative-date granularities, which the SDK stores in
24
+ * its own vocabulary (`GDC.time.*`) while the typed schema uses tiger's (`YEAR`, `MONTH_OF_YEAR`, ...);
25
+ * those are translated via the canonical granularity mapping, and a granularity tiger does not model
26
+ * degrades the projection to `null` like any other malformed-blob case.
27
+ */
28
+ export function convertConditionalFormatting(insight) {
29
+ const conditionalFormatting = insightProperties(insight)["controls"]?.["conditionalFormatting"];
30
+ if (!conditionalFormatting ||
31
+ !Array.isArray(conditionalFormatting.rules) ||
32
+ conditionalFormatting.rules.some((rule) => !Array.isArray(rule?.conditions) ||
33
+ rule.conditions.some((condition) => !condition || typeof condition !== "object"))) {
34
+ return null;
35
+ }
36
+ // Array.isArray() narrows the readonly rules array to any[]; re-annotate to keep element types.
37
+ const rules = conditionalFormatting.rules;
38
+ try {
39
+ return {
40
+ enabled: conditionalFormatting.enabled,
41
+ rules: rules.map((rule) => ({
42
+ id: rule.id,
43
+ target: rule.target,
44
+ conditions: rule.conditions.map((condition) => ({
45
+ id: condition.id,
46
+ operator: condition.operator,
47
+ value: convertValue(condition.value),
48
+ format: condition.format,
49
+ })),
50
+ })),
51
+ };
52
+ }
53
+ catch (error) {
54
+ // toTigerGranularity throws NotSupported for a granularity the free-form blob may carry but
55
+ // tiger does not model; the projection degrades like any other malformed-blob case.
56
+ if (error instanceof NotSupported) {
57
+ return null;
58
+ }
59
+ throw error;
60
+ }
61
+ }
62
+ function convertValue(value) {
63
+ if (value.kind === "relativeDate") {
64
+ return {
65
+ kind: value.kind,
66
+ granularity: toTigerGranularity(value.granularity),
67
+ from: value.from,
68
+ to: value.to,
69
+ };
70
+ }
71
+ return value;
72
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gooddata/sdk-backend-tiger",
3
- "version": "11.55.0-alpha.1",
3
+ "version": "11.55.0-alpha.3",
4
4
  "description": "GoodData Backend SPI implementation for GoodData Cloud and GoodData.CN",
5
5
  "license": "MIT",
6
6
  "author": "GoodData",
@@ -34,12 +34,12 @@
34
34
  "ts-invariant": "0.10.3",
35
35
  "tslib": "2.8.1",
36
36
  "uuid": "11.1.1",
37
- "@gooddata/api-client-tiger": "11.55.0-alpha.1",
38
- "@gooddata/sdk-backend-base": "11.55.0-alpha.1",
39
- "@gooddata/sdk-backend-spi": "11.55.0-alpha.1",
40
- "@gooddata/sdk-code-convertors": "11.55.0-alpha.1",
41
- "@gooddata/sdk-model": "11.55.0-alpha.1",
42
- "@gooddata/util": "11.55.0-alpha.1"
37
+ "@gooddata/api-client-tiger": "11.55.0-alpha.3",
38
+ "@gooddata/sdk-backend-base": "11.55.0-alpha.3",
39
+ "@gooddata/sdk-backend-spi": "11.55.0-alpha.3",
40
+ "@gooddata/sdk-code-convertors": "11.55.0-alpha.3",
41
+ "@gooddata/util": "11.55.0-alpha.3",
42
+ "@gooddata/sdk-model": "11.55.0-alpha.3"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@gooddata/fixtures": "3.7.0",
@@ -53,23 +53,21 @@
53
53
  "dependency-cruiser": "17.3.10",
54
54
  "dotenv": "16.4.5",
55
55
  "eslint": "^9.39.2",
56
- "eslint-import-resolver-typescript": "4.4.4",
57
56
  "eslint-plugin-headers": "1.3.3",
58
57
  "eslint-plugin-import-esm": "1.2.1",
59
- "eslint-plugin-import-x": "4.16.1",
60
58
  "eslint-plugin-jsdoc": "62.1.0",
61
59
  "eslint-plugin-no-barrel-files": "1.2.2",
62
60
  "eslint-plugin-sonarjs": "3.0.6",
63
61
  "npm-run-all": "4.1.5",
64
62
  "oxfmt": "0.52.0",
65
- "oxlint": "1.51.0",
63
+ "oxlint": "1.57.0",
66
64
  "oxlint-tsgolint": "0.15.0",
67
65
  "typescript": "5.9.3",
68
66
  "vitest": "4.1.8",
69
- "@gooddata/catalog-export": "11.55.0-alpha.1",
70
- "@gooddata/reference-workspace": "11.55.0-alpha.1",
71
- "@gooddata/oxlint-config": "11.55.0-alpha.1",
72
- "@gooddata/eslint-config": "11.55.0-alpha.1"
67
+ "@gooddata/catalog-export": "11.55.0-alpha.3",
68
+ "@gooddata/eslint-config": "11.55.0-alpha.3",
69
+ "@gooddata/oxlint-config": "11.55.0-alpha.3",
70
+ "@gooddata/reference-workspace": "11.55.0-alpha.3"
73
71
  },
74
72
  "scripts": {
75
73
  "_phase:build": "npm run build",