@gooddata/sdk-backend-tiger 11.62.0-alpha.2 → 11.62.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.
- package/esm/__version.d.ts +1 -1
- package/esm/__version.js +1 -1
- package/esm/backend/settings/mapping.js +2 -0
- package/esm/backend/workspace/attributes/elements/dependentDateFilters.d.ts.map +1 -1
- package/esm/backend/workspace/attributes/elements/dependentDateFilters.js +26 -10
- package/esm/backend/workspace/dashboards/referenceAvailability.d.ts +13 -10
- package/esm/backend/workspace/dashboards/referenceAvailability.d.ts.map +1 -1
- package/esm/backend/workspace/dashboards/referenceAvailability.js +28 -13
- package/esm/backend/workspace/genAI/index.d.ts.map +1 -1
- package/esm/backend/workspace/genAI/index.js +13 -5
- package/esm/convertors/fromBackend/AutomationConverter.d.ts.map +1 -1
- package/esm/convertors/fromBackend/AutomationConverter.js +4 -2
- package/esm/convertors/fromBackend/afm/FilterConverter.d.ts.map +1 -1
- package/esm/convertors/fromBackend/afm/FilterConverter.js +42 -0
- package/esm/convertors/shared/absoluteGranularityLiterals.d.ts +38 -0
- package/esm/convertors/shared/absoluteGranularityLiterals.d.ts.map +1 -0
- package/esm/convertors/shared/absoluteGranularityLiterals.js +82 -0
- package/esm/convertors/shared/storedFilterConverter.d.ts +12 -2
- package/esm/convertors/shared/storedFilterConverter.d.ts.map +1 -1
- package/esm/convertors/shared/storedFilterConverter.js +16 -5
- package/esm/convertors/toBackend/InsightConverter.d.ts.map +1 -1
- package/esm/convertors/toBackend/InsightConverter.js +6 -3
- package/esm/convertors/toBackend/afm/FilterConverter.d.ts.map +1 -1
- package/esm/convertors/toBackend/afm/FilterConverter.js +23 -2
- package/package.json +12 -12
package/esm/__version.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const LIB_VERSION = "11.62.0-alpha.
|
|
1
|
+
export declare const LIB_VERSION = "11.62.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.62.0-alpha.
|
|
3
|
+
export const LIB_VERSION = "11.62.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";
|
|
@@ -42,6 +42,8 @@ const TYPE_TO_KEY_MAP = {
|
|
|
42
42
|
ENABLE_PARTIAL_DATA_RESULTS: "enablePartialDataResults",
|
|
43
43
|
ENABLE_NULL_JOINS: "enableNullJoins",
|
|
44
44
|
ENABLE_TIMEZONE_CHANGE: "enableTimezoneChange",
|
|
45
|
+
DEFAULT_METRIC_VISIBILITY: "defaultMetricVisibility",
|
|
46
|
+
DEFAULT_VISUALIZATION_VISIBILITY: "defaultVisualizationVisibility",
|
|
45
47
|
};
|
|
46
48
|
export function mapTypeToKey(type, fallback = "") {
|
|
47
49
|
// For undefined or unmapped type - return fallback
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependentDateFilters.d.ts","sourceRoot":"","sources":["../../../../../src/backend/workspace/attributes/elements/dependentDateFilters.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dependentDateFilters.d.ts","sourceRoot":"","sources":["../../../../../src/backend/workspace/attributes/elements/dependentDateFilters.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAEH,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EAI3B,MAAM,qBAAqB,CAAC;AAQ7B,wBAAgB,2CAA2C,CACvD,UAAU,EAAE,mBAAmB,GAAG,mBAAmB,uBAOxD"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
// (C) 2024-
|
|
1
|
+
// (C) 2024-2026 GoodData Corporation
|
|
2
2
|
import { invariant } from "ts-invariant";
|
|
3
3
|
import { isRelativeBoundedDateFilter, isRelativeDateFilter, isUriRef, } from "@gooddata/sdk-model";
|
|
4
4
|
import { toTigerGranularity } from "../../../../convertors/fromBackend/dateGranularityConversions.js";
|
|
5
|
+
import { hasPeriodLiteral, toWholePeriodLiterals, } from "../../../../convertors/shared/absoluteGranularityLiterals.js";
|
|
5
6
|
export function mapDashboardDateFilterToDependentDateFilter(dateFilter) {
|
|
6
7
|
if (isRelativeDateFilter(dateFilter)) {
|
|
7
8
|
return newRelativeDependentDateFilter(dateFilter);
|
|
@@ -37,19 +38,34 @@ function newRelativeDependentDateFilter(dateFilter) {
|
|
|
37
38
|
};
|
|
38
39
|
}
|
|
39
40
|
function newAbsoluteDependentDateFilter(dateFilter) {
|
|
40
|
-
const localIdentifier = dateFilter.absoluteDateFilter
|
|
41
|
+
const { dataSet: localIdentifier, from, to, granularity } = dateFilter.absoluteDateFilter;
|
|
41
42
|
invariant(!isUriRef(localIdentifier));
|
|
43
|
+
const dataset = {
|
|
44
|
+
identifier: {
|
|
45
|
+
id: localIdentifier.identifier,
|
|
46
|
+
type: "dataset",
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
if (hasPeriodLiteral(granularity)) {
|
|
50
|
+
const literals = toWholePeriodLiterals(granularity, from, to);
|
|
51
|
+
if (literals) {
|
|
52
|
+
return {
|
|
53
|
+
dateFilter: {
|
|
54
|
+
absoluteGranularityDateFilter: {
|
|
55
|
+
dataset,
|
|
56
|
+
granularity: toTigerGranularity(granularity),
|
|
57
|
+
...literals,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
42
63
|
return {
|
|
43
64
|
dateFilter: {
|
|
44
65
|
absoluteDateFilter: {
|
|
45
|
-
dataset
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
type: "dataset",
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
from: dateFilter.absoluteDateFilter.from,
|
|
52
|
-
to: dateFilter.absoluteDateFilter.to,
|
|
66
|
+
dataset,
|
|
67
|
+
from,
|
|
68
|
+
to,
|
|
53
69
|
},
|
|
54
70
|
},
|
|
55
71
|
};
|
|
@@ -5,6 +5,7 @@ import { type TigerAuthenticatedCallGuard } from "../../../types/index.js";
|
|
|
5
5
|
/** The same for the filter-context GET, which links the objects the filters use. */
|
|
6
6
|
declare const FILTER_CONTEXT_RELATIONSHIP_KEYS: {
|
|
7
7
|
readonly displayForm: "labels";
|
|
8
|
+
readonly attribute: "attributes";
|
|
8
9
|
readonly computedAttribute: "computedAttributes";
|
|
9
10
|
readonly measure: "metrics";
|
|
10
11
|
readonly fact: "facts";
|
|
@@ -23,19 +24,21 @@ export declare function resolveUnavailableReferences(document: JsonApiAnalytical
|
|
|
23
24
|
*/
|
|
24
25
|
export declare function resolveUnavailableDashboardReferences(document: JsonApiAnalyticalDashboardOutDocument, dashboard: IDashboard, types: SupportedDashboardReferenceTypes[]): IUnavailableDashboardReference[];
|
|
25
26
|
/**
|
|
26
|
-
* Resolves which filter display forms, computed attributes, metrics and facts referenced by
|
|
27
|
-
* context are unavailable. Each inspected type must have been requested as an include
|
|
28
|
-
* `computedAttributes`, `metrics`, `facts`) so the response contains both
|
|
29
|
-
* document-level `meta.restricted` for it.
|
|
27
|
+
* Resolves which filter display forms, attributes, computed attributes, metrics and facts referenced by
|
|
28
|
+
* a filter context are unavailable. Each inspected type must have been requested as an include
|
|
29
|
+
* (`labels`, `attributes`, `computedAttributes`, `metrics`, `facts`) so the response contains both
|
|
30
|
+
* relationship linkages and document-level `meta.restricted` for it.
|
|
30
31
|
*/
|
|
31
32
|
export declare function resolveUnavailableFilterContextReferences(context: JsonApiFilterContextOut, restricted: RestrictedObject[] | undefined, inspected: FilterContextInspectedType[]): IUnavailableDashboardReference[];
|
|
32
33
|
/**
|
|
33
|
-
* Filter labels, computed attributes, metrics and facts relate to their filter-context
|
|
34
|
-
* dashboard GET side-loads the filter contexts as bare items (no `relationships`), so the
|
|
35
|
-
* linkage for filter objects is reachable only through a direct filter-context GET with
|
|
36
|
-
* (and `computedAttributes`, `metrics`, `facts`), hence this one batched
|
|
37
|
-
* labels are included only when a filter uses them (metric value
|
|
38
|
-
*
|
|
34
|
+
* Filter labels, attributes, computed attributes, metrics and facts relate to their filter-context
|
|
35
|
+
* entities: the dashboard GET side-loads the filter contexts as bare items (no `relationships`), so the
|
|
36
|
+
* existence linkage for filter objects is reachable only through a direct filter-context GET with
|
|
37
|
+
* `include=labels` (and `attributes`, `computedAttributes`, `metrics`, `facts`), hence this one batched
|
|
38
|
+
* extra request. Types other than labels are included only when a filter uses them (metric value
|
|
39
|
+
* filters and the attributes they are computed for, filters on computed attributes, metrics, facts
|
|
40
|
+
* and "Count of" attributes or computed attributes limiting a filter's values), so other dashboards
|
|
41
|
+
* never request them.
|
|
39
42
|
* It inspects the contexts of the effective dashboard, so a `filterContextRef` override is covered;
|
|
40
43
|
* the synthetic export-override context has no entity behind it and is skipped.
|
|
41
44
|
* It would become redundant if the backend emitted `relationships.labels` on the filter-context items
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"referenceAvailability.d.ts","sourceRoot":"","sources":["../../../../src/backend/workspace/dashboards/referenceAvailability.ts"],"names":[],"mappings":"AAEA,OAAO,EAIH,KAAK,qCAAqC,EAC1C,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EAExB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACR,8BAA8B,EAC9B,gCAAgC,EACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,UAAU,
|
|
1
|
+
{"version":3,"file":"referenceAvailability.d.ts","sourceRoot":"","sources":["../../../../src/backend/workspace/dashboards/referenceAvailability.ts"],"names":[],"mappings":"AAEA,OAAO,EAIH,KAAK,qCAAqC,EAC1C,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EAExB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACR,8BAA8B,EAC9B,gCAAgC,EACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACH,KAAK,UAAU,EASlB,MAAM,qBAAqB,CAAC;AAM7B,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAqD3E,oFAAoF;AACpF,QAAA,MAAM,gCAAgC;0BACrB,QAAQ;wBACV,YAAY;gCACJ,oBAAoB;sBAC9B,SAAS;mBACZ,OAAO;CACwD,CAAC;AAE1E,KAAK,0BAA0B,GAAG,MAAM,OAAO,gCAAgC,CAAC;AAsEhF;;GAEG;AACH,wBAAgB,4BAA4B,CACxC,QAAQ,EAAE,qCAAqC,EAC/C,KAAK,EAAE,gCAAgC,EAAE,GAC1C,8BAA8B,EAAE,CAKlC;AAED;;;;;;GAMG;AACH,wBAAgB,qCAAqC,CACjD,QAAQ,EAAE,qCAAqC,EAC/C,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,gCAAgC,EAAE,GAC1C,8BAA8B,EAAE,CAWlC;AAED;;;;;GAKG;AACH,wBAAgB,yCAAyC,CACrD,OAAO,EAAE,uBAAuB,EAChC,UAAU,EAAE,gBAAgB,EAAE,GAAG,SAAS,EAC1C,SAAS,EAAE,0BAA0B,EAAE,GACxC,8BAA8B,EAAE,CAMlC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,kCAAkC,CACpD,QAAQ,EAAE,2BAA2B,EACrC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,UAAU,EACrB,KAAK,EAAE,gCAAgC,EAAE,GAC1C,OAAO,CAAC,8BAA8B,EAAE,CAAC,CA4B3C;AA8CD;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,UAAU,GAAG,MAAM,EAAE,CAQ3E"}
|
|
@@ -20,6 +20,7 @@ const DASHBOARD_RELATIONSHIP_KEYS = {
|
|
|
20
20
|
/** The same for the filter-context GET, which links the objects the filters use. */
|
|
21
21
|
const FILTER_CONTEXT_RELATIONSHIP_KEYS = {
|
|
22
22
|
displayForm: "labels",
|
|
23
|
+
attribute: "attributes",
|
|
23
24
|
computedAttribute: "computedAttributes",
|
|
24
25
|
measure: "metrics",
|
|
25
26
|
fact: "facts",
|
|
@@ -88,21 +89,23 @@ export function resolveUnavailableDashboardReferences(document, dashboard, types
|
|
|
88
89
|
return unavailable.filter((entry) => entry.type !== "filterContext" || (isIdentifierRef(entry.ref) && inUse.has(entry.ref.identifier)));
|
|
89
90
|
}
|
|
90
91
|
/**
|
|
91
|
-
* Resolves which filter display forms, computed attributes, metrics and facts referenced by
|
|
92
|
-
* context are unavailable. Each inspected type must have been requested as an include
|
|
93
|
-
* `computedAttributes`, `metrics`, `facts`) so the response contains both
|
|
94
|
-
* document-level `meta.restricted` for it.
|
|
92
|
+
* Resolves which filter display forms, attributes, computed attributes, metrics and facts referenced by
|
|
93
|
+
* a filter context are unavailable. Each inspected type must have been requested as an include
|
|
94
|
+
* (`labels`, `attributes`, `computedAttributes`, `metrics`, `facts`) so the response contains both
|
|
95
|
+
* relationship linkages and document-level `meta.restricted` for it.
|
|
95
96
|
*/
|
|
96
97
|
export function resolveUnavailableFilterContextReferences(context, restricted, inspected) {
|
|
97
98
|
return diffInspectedTypes({ data: context, meta: { restricted } }, FILTER_CONTEXT_RELATIONSHIP_KEYS, inspected);
|
|
98
99
|
}
|
|
99
100
|
/**
|
|
100
|
-
* Filter labels, computed attributes, metrics and facts relate to their filter-context
|
|
101
|
-
* dashboard GET side-loads the filter contexts as bare items (no `relationships`), so the
|
|
102
|
-
* linkage for filter objects is reachable only through a direct filter-context GET with
|
|
103
|
-
* (and `computedAttributes`, `metrics`, `facts`), hence this one batched
|
|
104
|
-
* labels are included only when a filter uses them (metric value
|
|
105
|
-
*
|
|
101
|
+
* Filter labels, attributes, computed attributes, metrics and facts relate to their filter-context
|
|
102
|
+
* entities: the dashboard GET side-loads the filter contexts as bare items (no `relationships`), so the
|
|
103
|
+
* existence linkage for filter objects is reachable only through a direct filter-context GET with
|
|
104
|
+
* `include=labels` (and `attributes`, `computedAttributes`, `metrics`, `facts`), hence this one batched
|
|
105
|
+
* extra request. Types other than labels are included only when a filter uses them (metric value
|
|
106
|
+
* filters and the attributes they are computed for, filters on computed attributes, metrics, facts
|
|
107
|
+
* and "Count of" attributes or computed attributes limiting a filter's values), so other dashboards
|
|
108
|
+
* never request them.
|
|
106
109
|
* It inspects the contexts of the effective dashboard, so a `filterContextRef` override is covered;
|
|
107
110
|
* the synthetic export-override context has no entity behind it and is skipped.
|
|
108
111
|
* It would become redundant if the backend emitted `relationships.labels` on the filter-context items
|
|
@@ -134,8 +137,9 @@ export async function fetchUnavailableFilterDisplayForms(authCall, workspaceId,
|
|
|
134
137
|
}
|
|
135
138
|
/**
|
|
136
139
|
* The filter-context object types the dashboard's filters use: labels always; computed attributes of
|
|
137
|
-
* attribute filters built on them; metrics of metric value filters
|
|
138
|
-
* attribute
|
|
140
|
+
* attribute filters built on them; metrics of metric value filters and the attributes or computed
|
|
141
|
+
* attributes they are computed for ("For attribute"); metrics, facts and "Count of" attributes or
|
|
142
|
+
* computed attributes that limit an attribute filter's values.
|
|
139
143
|
*/
|
|
140
144
|
function filterObjectTypes(dashboard) {
|
|
141
145
|
const used = new Set(["displayForm"]);
|
|
@@ -143,6 +147,7 @@ function filterObjectTypes(dashboard) {
|
|
|
143
147
|
for (const filter of contexts.flatMap((context) => context?.filters ?? [])) {
|
|
144
148
|
if (isDashboardMeasureValueFilter(filter)) {
|
|
145
149
|
used.add("measure");
|
|
150
|
+
dimensionalityObjectTypes(filter).forEach((type) => used.add(type));
|
|
146
151
|
}
|
|
147
152
|
if (!isDashboardAttributeFilterItem(filter)) {
|
|
148
153
|
continue;
|
|
@@ -151,13 +156,23 @@ function filterObjectTypes(dashboard) {
|
|
|
151
156
|
used.add("computedAttribute");
|
|
152
157
|
}
|
|
153
158
|
for (const ref of dashboardAttributeFilterItemValidateElementsBy(filter) ?? []) {
|
|
154
|
-
if (isIdentifierRef(ref) &&
|
|
159
|
+
if (isIdentifierRef(ref) &&
|
|
160
|
+
(ref.type === "measure" ||
|
|
161
|
+
ref.type === "fact" ||
|
|
162
|
+
ref.type === "attribute" ||
|
|
163
|
+
ref.type === "computedAttribute")) {
|
|
155
164
|
used.add(ref.type);
|
|
156
165
|
}
|
|
157
166
|
}
|
|
158
167
|
}
|
|
159
168
|
return used;
|
|
160
169
|
}
|
|
170
|
+
/** The attribute and computed-attribute types of the items a metric value filter is computed for. */
|
|
171
|
+
function dimensionalityObjectTypes(filter) {
|
|
172
|
+
return (filter.dashboardMeasureValueFilter.dimensionality ?? []).flatMap((ref) => isIdentifierRef(ref) && (ref.type === "attribute" || ref.type === "computedAttribute")
|
|
173
|
+
? [ref.type]
|
|
174
|
+
: []);
|
|
175
|
+
}
|
|
161
176
|
/**
|
|
162
177
|
* Identifiers of the persisted filter contexts the dashboard actually uses (root and tabs; a
|
|
163
178
|
* `filterContextRef` override replaces them all). Only a ref typed `filterContext` names an entity
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/backend/workspace/genAI/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACR,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,aAAa,EACb,0BAA0B,EAC1B,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,6BAA6B,EAChC,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/backend/workspace/genAI/index.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EACR,wBAAwB,EACxB,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,aAAa,EACb,0BAA0B,EAC1B,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,6BAA6B,EAChC,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,yDAAyD,CAAC;AAE9F,OAAO,EAAE,KAAK,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAS3E,qBAAa,YAAa,YAAW,aAAa;IAE1C,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,cAAc;IAHnC,YACqB,QAAQ,EAAE,2BAA2B,EACrC,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,cAAc,EAC/C;IAEJ,oBAAoB,CAAC,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,kBAAkB,CAE1E;IAED,sBAAsB,IAAI,oBAAoB,CAE7C;IAEK,gBAAgB,IAAI,OAAO,CAAC,OAAO,CAAC,CAOzC;IAED,qBAAqB,IAAI,0BAA0B,CAElD;IAED,cAAc,IAAI,mBAAmB,CAEpC;IAED,mBAAmB,IAAI,wBAAwB,CAE9C;IAED,kBAAkB,IAAI,uBAAuB,CAE5C;IAEK,kBAAkB,CACpB,OAAO,EAAE,wBAAwB,EACjC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACnC,OAAO,CAAC,iBAAiB,CAAC,CAkC5B;IAEK,uBAAuB,CACzB,OAAO,EAAE,6BAA6B,EACtC,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GACnC,OAAO,CAAC,iBAAiB,CAAC,CA6B5B;CACJ"}
|
|
@@ -69,11 +69,13 @@ export class GenAIService {
|
|
|
69
69
|
}
|
|
70
70
|
async summarizeVisualizations(request, options) {
|
|
71
71
|
const aiSummarizeVisualizationsRequest = {
|
|
72
|
-
visualizations: request.visualizations
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
visualizations: request.visualizations.map((visualization) => typeof visualization === "string"
|
|
73
|
+
? visualization
|
|
74
|
+
: {
|
|
75
|
+
visualizationId: visualization.visualizationId,
|
|
76
|
+
filters: convertSummaryFilters(visualization.filters),
|
|
77
|
+
}),
|
|
78
|
+
filterContext: convertSummaryFilters(request.filters),
|
|
77
79
|
};
|
|
78
80
|
if (request.formatHint !== undefined) {
|
|
79
81
|
aiSummarizeVisualizationsRequest.formatHint = request.formatHint;
|
|
@@ -85,6 +87,12 @@ export class GenAIService {
|
|
|
85
87
|
return convertSummaryResponse(response.data);
|
|
86
88
|
}
|
|
87
89
|
}
|
|
90
|
+
// Cast bridges the AFM filter definitions to the generated union type of the AI API.
|
|
91
|
+
function convertSummaryFilters(filters) {
|
|
92
|
+
return filters
|
|
93
|
+
.map((filter) => convertFilter(filter))
|
|
94
|
+
.filter(Boolean);
|
|
95
|
+
}
|
|
88
96
|
function convertSummaryResponse(data) {
|
|
89
97
|
return {
|
|
90
98
|
summary: data.summary,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutomationConverter.d.ts","sourceRoot":"","sources":["../../../src/convertors/fromBackend/AutomationConverter.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,eAAe,EAGpB,KAAK,yBAAyB,EAO9B,KAAK,uCAAuC,EAC5C,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,EAE7B,KAAK,6BAA6B,EAQlC,KAAK,sCAAsC,EAK3C,KAAK,gBAAgB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEH,KAAK,iBAAiB,EAEtB,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAI9B,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"AutomationConverter.d.ts","sourceRoot":"","sources":["../../../src/convertors/fromBackend/AutomationConverter.ts"],"names":[],"mappings":"AAIA,OAAO,EACH,KAAK,eAAe,EAGpB,KAAK,yBAAyB,EAO9B,KAAK,uCAAuC,EAC5C,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,EAE7B,KAAK,6BAA6B,EAQlC,KAAK,sCAAsC,EAK3C,KAAK,gBAAgB,EACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAEH,KAAK,iBAAiB,EAEtB,KAAK,gBAAgB,EACrB,KAAK,yBAAyB,EAI9B,KAAK,OAAO,EA2Bf,MAAM,qBAAqB,CAAC;AA6I7B,wBAAgB,iBAAiB,CAC7B,UAAU,EAAE,6BAA6B,GAAG,sCAAsC,EAClF,QAAQ,EAAE,4BAA4B,EAAE,EACxC,UAAU,CAAC,EAAE,gBAAgB,EAAE,GAChC,yBAAyB,CA6H3B;AAED,eAAO,MAAM,kCAAkC,mBAC3B,wBAAwB,KACzC,yBAAyB,EAI3B,CAAC;AAcF,eAAO,MAAM,YAAY,UACd,yBAAyB,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,SAAS,UAC/D,uCAAuC,KAChD,gBAAgB,GAAG,SAoGrB,CAAC;AA0CF;;;;;;;GAOG;AACH,wBAAgB,yCAAyC,CACrD,MAAM,EAAE,OAAO,EACf,uBAAuB,EAAE,MAAM,GAChC,iBAAiB,GAAG,SAAS,CAmG/B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// (C) 2024-2026 GoodData Corporation
|
|
2
2
|
import { compact } from "lodash-es";
|
|
3
|
-
import { filterAttributeElements, filterLocalIdentifier, filterObjRef, idRef, isAbsoluteDateFilter, isAllTimeDateFilter, isArbitraryAttributeFilter, isAttributeFilterWithSelection, isAutomationUserRecipient, isExportDefinitionVisualizationObjectRequestPayload, isFilter, isFilterContextItem, isMatchAttributeFilter, isMeasureValueFilter, isNegativeAttributeFilter, isObjRef, isRelativeBoundedDateFilter, isRelativeDateFilter, measureValueFilterConditions, measureValueFilterDimensionality, measureValueFilterMeasure, newAbsoluteDashboardDateFilter, newAllTimeDashboardDateFilter, newRelativeDashboardDateFilter, } from "@gooddata/sdk-model";
|
|
3
|
+
import { filterAttributeElements, filterLocalIdentifier, filterObjRef, idRef, isAbsoluteDateFilter, isAllTimeDateFilter, isArbitraryAttributeFilter, isAttributeFilterWithSelection, isAutomationUserRecipient, isDateFilterGranularity, isExportDefinitionVisualizationObjectRequestPayload, isFilter, isFilterContextItem, isMatchAttributeFilter, isMeasureValueFilter, isNegativeAttributeFilter, isObjRef, isRelativeBoundedDateFilter, isRelativeDateFilter, measureValueFilterConditions, measureValueFilterDimensionality, measureValueFilterMeasure, newAbsoluteDashboardDateFilter, newAllTimeDashboardDateFilter, newRelativeDashboardDateFilter, } from "@gooddata/sdk-model";
|
|
4
4
|
import { fixNumber } from "../../utils/fixNumber.js";
|
|
5
5
|
import { convertFilter } from "./afm/FilterConverter.js";
|
|
6
6
|
import { convertMeasure } from "./afm/MeasureConverter.js";
|
|
@@ -338,7 +338,9 @@ export function convertExecutionFilterToFilterContextItem(filter, fallbackLocalI
|
|
|
338
338
|
};
|
|
339
339
|
}
|
|
340
340
|
if (isAbsoluteDateFilter(filter)) {
|
|
341
|
-
return newAbsoluteDashboardDateFilter(filter.absoluteDateFilter.from, filter.absoluteDateFilter.to, filter.absoluteDateFilter.dataSet, filter.absoluteDateFilter.localIdentifier, filter.absoluteDateFilter.emptyValueHandling)
|
|
341
|
+
return newAbsoluteDashboardDateFilter(filter.absoluteDateFilter.from, filter.absoluteDateFilter.to, filter.absoluteDateFilter.dataSet, filter.absoluteDateFilter.localIdentifier, filter.absoluteDateFilter.emptyValueHandling, isDateFilterGranularity(filter.absoluteDateFilter.granularity)
|
|
342
|
+
? filter.absoluteDateFilter.granularity
|
|
343
|
+
: "GDC.time.date");
|
|
342
344
|
}
|
|
343
345
|
if (isAllTimeDateFilter(filter)) {
|
|
344
346
|
return newAllTimeDashboardDateFilter(filter.relativeDateFilter.dataSet, filter.relativeDateFilter.localIdentifier, filter.relativeDateFilter.emptyValueHandling);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterConverter.d.ts","sourceRoot":"","sources":["../../../../src/convertors/fromBackend/afm/FilterConverter.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"FilterConverter.d.ts","sourceRoot":"","sources":["../../../../src/convertors/fromBackend/afm/FilterConverter.ts"],"names":[],"mappings":"AAEA,OAAO,EAOH,KAAK,gBAAgB,EAWxB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAGH,KAAK,OAAO,EAQf,MAAM,qBAAqB,CAAC;AA8H7B,eAAO,MAAM,aAAa,WAAY,gBAAgB,KAAG,OAyQxD,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { isAfmObjectIdentifier, isAfmObjectLocalIdentifier, } from "@gooddata/api-client-tiger";
|
|
3
3
|
import { NotSupported } from "@gooddata/sdk-backend-spi";
|
|
4
4
|
import { newArbitraryAttributeFilter, } from "@gooddata/sdk-model";
|
|
5
|
+
import { fromPeriodLiteral, isWireAbsoluteGranularity, toPeriodLiteral, } from "../../shared/absoluteGranularityLiterals.js";
|
|
5
6
|
import { toSdkGranularity } from "../dateGranularityConversions.js";
|
|
6
7
|
import { toLocalRef, toObjRef } from "../ObjRefConverter.js";
|
|
7
8
|
const isPositiveAttributeFilter = (filter) => {
|
|
@@ -13,6 +14,9 @@ const isNegativeAttributeFilter = (filter) => {
|
|
|
13
14
|
const isAbsoluteDateFilter = (filter) => {
|
|
14
15
|
return filter.absoluteDateFilter !== undefined;
|
|
15
16
|
};
|
|
17
|
+
const isAbsoluteGranularityDateFilter = (filter) => {
|
|
18
|
+
return filter.absoluteGranularityDateFilter !== undefined;
|
|
19
|
+
};
|
|
16
20
|
const isAllTimeDateFilter = (filter) => {
|
|
17
21
|
return filter.allTimeDateFilter !== undefined;
|
|
18
22
|
};
|
|
@@ -147,6 +151,44 @@ export const convertFilter = (filter) => {
|
|
|
147
151
|
},
|
|
148
152
|
};
|
|
149
153
|
}
|
|
154
|
+
else if (isAbsoluteGranularityDateFilter(filter)) {
|
|
155
|
+
const { dataset, granularity, from, to, localIdentifier } = filter.absoluteGranularityDateFilter;
|
|
156
|
+
const sdkGranularity = toSdkGranularity(granularity);
|
|
157
|
+
if (from === undefined || from === null || to === undefined || to === null) {
|
|
158
|
+
throw new NotSupported("Open-ended absolute date filters are not supported.");
|
|
159
|
+
}
|
|
160
|
+
if (!isWireAbsoluteGranularity(sdkGranularity)) {
|
|
161
|
+
throw new NotSupported(`Absolute date filters at the ${granularity} granularity are not supported.`);
|
|
162
|
+
}
|
|
163
|
+
const emptyValueHandling = toSdkEmptyValues(filter.absoluteGranularityDateFilter.emptyValueHandling);
|
|
164
|
+
// The range covers whole periods, so it ends on the last day of the period 'to' names,
|
|
165
|
+
// not on its first day.
|
|
166
|
+
let range;
|
|
167
|
+
try {
|
|
168
|
+
range = {
|
|
169
|
+
from: fromPeriodLiteral(sdkGranularity, from).first,
|
|
170
|
+
to: fromPeriodLiteral(sdkGranularity, to).last,
|
|
171
|
+
};
|
|
172
|
+
// Parsing accepts a literal that is not zero-padded or has a short year, so the literal must
|
|
173
|
+
// also come back unchanged when its period is converted to a literal again.
|
|
174
|
+
if (toPeriodLiteral(sdkGranularity, range.from) !== from ||
|
|
175
|
+
toPeriodLiteral(sdkGranularity, range.to) !== to) {
|
|
176
|
+
throw new Error(`Not ${granularity} literals: ${from} - ${to}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
throw new NotSupported(`The absolute date filter range ${from} - ${to} is not in the format of the ${granularity} granularity.`);
|
|
181
|
+
}
|
|
182
|
+
return {
|
|
183
|
+
absoluteDateFilter: {
|
|
184
|
+
dataSet: toObjRef(dataset),
|
|
185
|
+
localIdentifier,
|
|
186
|
+
...range,
|
|
187
|
+
...(sdkGranularity === "GDC.time.date" ? {} : { granularity: sdkGranularity }),
|
|
188
|
+
...(emptyValueHandling === undefined ? {} : { emptyValueHandling }),
|
|
189
|
+
},
|
|
190
|
+
};
|
|
191
|
+
}
|
|
150
192
|
else if (isAllTimeDateFilter(filter)) {
|
|
151
193
|
const emptyValueHandling = toSdkEmptyValues(filter.allTimeDateFilter.emptyValueHandling);
|
|
152
194
|
return {
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type DateAttributeGranularity } from "@gooddata/sdk-model";
|
|
2
|
+
declare const WIRE_ABSOLUTE_GRANULARITIES: readonly ["GDC.time.date", "GDC.time.month", "GDC.time.quarter", "GDC.time.year"];
|
|
3
|
+
/**
|
|
4
|
+
* Granularities an absolute date filter can express on the wire as a period literal.
|
|
5
|
+
*/
|
|
6
|
+
export type WireAbsoluteGranularity = (typeof WIRE_ABSOLUTE_GRANULARITIES)[number];
|
|
7
|
+
/**
|
|
8
|
+
* Granularities whose ranges can be sent as period literals rather than as days.
|
|
9
|
+
*/
|
|
10
|
+
export type PeriodLiteralGranularity = Exclude<WireAbsoluteGranularity, "GDC.time.date">;
|
|
11
|
+
export declare function isWireAbsoluteGranularity(granularity: DateAttributeGranularity | undefined): granularity is WireAbsoluteGranularity;
|
|
12
|
+
/**
|
|
13
|
+
* Tells whether an absolute date filter at the granularity can be sent as period literals rather than
|
|
14
|
+
* as its days.
|
|
15
|
+
*/
|
|
16
|
+
export declare function hasPeriodLiteral(granularity: DateAttributeGranularity | undefined): granularity is PeriodLiteralGranularity;
|
|
17
|
+
/**
|
|
18
|
+
* Converts a day into the literal of the period of the given granularity that contains it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function toPeriodLiteral(granularity: WireAbsoluteGranularity, day: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Converts a period literal into the first and the last day of that period.
|
|
23
|
+
*/
|
|
24
|
+
export declare function fromPeriodLiteral(granularity: WireAbsoluteGranularity, literal: string): {
|
|
25
|
+
first: string;
|
|
26
|
+
last: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Converts a range of days into the literals of its first and last period of the given granularity.
|
|
30
|
+
*
|
|
31
|
+
* @returns undefined when a day is not in the YYYY-MM-DD format or the range is not whole periods
|
|
32
|
+
*/
|
|
33
|
+
export declare function toWholePeriodLiterals(granularity: PeriodLiteralGranularity, from: string, to: string): {
|
|
34
|
+
from: string;
|
|
35
|
+
to: string;
|
|
36
|
+
} | undefined;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=absoluteGranularityLiterals.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"absoluteGranularityLiterals.d.ts","sourceRoot":"","sources":["../../../src/convertors/shared/absoluteGranularityLiterals.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAMpE,QAAA,MAAM,2BAA2B,mFAKuB,CAAC;AAEzD;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnF;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,OAAO,CAAC,uBAAuB,EAAE,eAAe,CAAC,CAAC;AAEzF,wBAAgB,yBAAyB,CACrC,WAAW,EAAE,wBAAwB,GAAG,SAAS,GAClD,WAAW,IAAI,uBAAuB,CAExC;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC5B,WAAW,EAAE,wBAAwB,GAAG,SAAS,GAClD,WAAW,IAAI,wBAAwB,CAEzC;AAkBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,uBAAuB,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEzF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC7B,WAAW,EAAE,uBAAuB,EACpC,OAAO,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAuBjC;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACjC,WAAW,EAAE,wBAAwB,EACrC,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACX;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAe1C"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// (C) 2026 GoodData Corporation
|
|
2
|
+
import { endOfMonth, endOfQuarter, endOfYear, isValid } from "date-fns";
|
|
3
|
+
import { parseDateValue, serializeDateValue } from "../fromBackend/dateFormatting/dateValueParser.js";
|
|
4
|
+
// TODO: a week has no literal yet, because the backend numbers weeks by ISO-8601 and shifts them by the
|
|
5
|
+
// week start; support will be added later in a different PR.
|
|
6
|
+
const WIRE_ABSOLUTE_GRANULARITIES = [
|
|
7
|
+
"GDC.time.date",
|
|
8
|
+
"GDC.time.month",
|
|
9
|
+
"GDC.time.quarter",
|
|
10
|
+
"GDC.time.year",
|
|
11
|
+
];
|
|
12
|
+
export function isWireAbsoluteGranularity(granularity) {
|
|
13
|
+
return WIRE_ABSOLUTE_GRANULARITIES.some((wireGranularity) => wireGranularity === granularity);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Tells whether an absolute date filter at the granularity can be sent as period literals rather than
|
|
17
|
+
* as its days.
|
|
18
|
+
*/
|
|
19
|
+
export function hasPeriodLiteral(granularity) {
|
|
20
|
+
return isWireAbsoluteGranularity(granularity) && granularity !== "GDC.time.date";
|
|
21
|
+
}
|
|
22
|
+
function isDay(value) {
|
|
23
|
+
return /^\d{4}-\d{2}-\d{2}$/.test(value) && isValid(parseDateValue(value, "GDC.time.date"));
|
|
24
|
+
}
|
|
25
|
+
function parseDay(day) {
|
|
26
|
+
if (!isDay(day)) {
|
|
27
|
+
throw new Error(`Not a day in the YYYY-MM-DD format: ${day}`);
|
|
28
|
+
}
|
|
29
|
+
return parseDateValue(day, "GDC.time.date");
|
|
30
|
+
}
|
|
31
|
+
function serializeDay(date) {
|
|
32
|
+
return serializeDateValue(date, "GDC.time.date");
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Converts a day into the literal of the period of the given granularity that contains it.
|
|
36
|
+
*/
|
|
37
|
+
export function toPeriodLiteral(granularity, day) {
|
|
38
|
+
return serializeDateValue(parseDay(day), granularity);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Converts a period literal into the first and the last day of that period.
|
|
42
|
+
*/
|
|
43
|
+
export function fromPeriodLiteral(granularity, literal) {
|
|
44
|
+
const first = parseDateValue(literal, granularity);
|
|
45
|
+
if (!isValid(first)) {
|
|
46
|
+
throw new Error(`Not a ${granularity} literal: ${literal}`);
|
|
47
|
+
}
|
|
48
|
+
let last = first;
|
|
49
|
+
switch (granularity) {
|
|
50
|
+
case "GDC.time.month":
|
|
51
|
+
last = endOfMonth(first);
|
|
52
|
+
break;
|
|
53
|
+
case "GDC.time.quarter":
|
|
54
|
+
last = endOfQuarter(first);
|
|
55
|
+
break;
|
|
56
|
+
case "GDC.time.year":
|
|
57
|
+
last = endOfYear(first);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
first: serializeDay(first),
|
|
62
|
+
last: serializeDay(last),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Converts a range of days into the literals of its first and last period of the given granularity.
|
|
67
|
+
*
|
|
68
|
+
* @returns undefined when a day is not in the YYYY-MM-DD format or the range is not whole periods
|
|
69
|
+
*/
|
|
70
|
+
export function toWholePeriodLiterals(granularity, from, to) {
|
|
71
|
+
if (!isDay(from) || !isDay(to)) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
const literals = {
|
|
75
|
+
from: toPeriodLiteral(granularity, from),
|
|
76
|
+
to: toPeriodLiteral(granularity, to),
|
|
77
|
+
};
|
|
78
|
+
const isWhole = from <= to &&
|
|
79
|
+
fromPeriodLiteral(granularity, literals.from).first === from &&
|
|
80
|
+
fromPeriodLiteral(granularity, literals.to).last === to;
|
|
81
|
+
return isWhole ? literals : undefined;
|
|
82
|
+
}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import { type ITigerFilter, type ITigerFilterContextItem } from "@gooddata/api-client-tiger";
|
|
2
2
|
import { type FilterContextItem, type IFilter } from "@gooddata/sdk-model";
|
|
3
|
+
/**
|
|
4
|
+
* Options of the conversion of SDK filters to Tiger stored filters.
|
|
5
|
+
*/
|
|
6
|
+
export interface IStoredFilterConversionOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Removes the granularity from absolute date filters. It is kept by default.
|
|
9
|
+
*/
|
|
10
|
+
dropAbsoluteDateGranularity?: boolean;
|
|
11
|
+
}
|
|
3
12
|
/**
|
|
4
13
|
* Converts SDK filter to Tiger stored filter format.
|
|
5
14
|
*
|
|
@@ -8,10 +17,11 @@ import { type FilterContextItem, type IFilter } from "@gooddata/sdk-model";
|
|
|
8
17
|
* For AFM/execution filters, use the AFM filter converter instead.
|
|
9
18
|
*
|
|
10
19
|
* @param filter - SDK filter to convert
|
|
20
|
+
* @param options - conversion options
|
|
11
21
|
* @returns Tiger stored filter with sanitized IDs and converted formats
|
|
12
22
|
* @public
|
|
13
23
|
*/
|
|
14
|
-
export declare function convertSdkFilterToTigerStored(filter: IFilter): ITigerFilter;
|
|
24
|
+
export declare function convertSdkFilterToTigerStored(filter: IFilter, options?: IStoredFilterConversionOptions): ITigerFilter;
|
|
15
25
|
/**
|
|
16
26
|
* Converts SDK FilterContextItem to Tiger FilterContextItem.
|
|
17
27
|
*
|
|
@@ -31,7 +41,7 @@ export declare function convertSdkFilterContextItemToTiger(item: FilterContextIt
|
|
|
31
41
|
export declare function convertTigerStoredToSdkFilter(filter: ITigerFilter): IFilter;
|
|
32
42
|
type SdkFiltersToTigerInput = IFilter[] | FilterContextItem[] | undefined;
|
|
33
43
|
type SdkFiltersToTigerOutput<T extends SdkFiltersToTigerInput> = T extends IFilter[] ? ITigerFilter[] : T extends FilterContextItem[] ? ITigerFilterContextItem[] : undefined;
|
|
34
|
-
export declare function convertSdkFiltersToTiger<T extends SdkFiltersToTigerInput>(filters: T): SdkFiltersToTigerOutput<T>;
|
|
44
|
+
export declare function convertSdkFiltersToTiger<T extends SdkFiltersToTigerInput>(filters: T, options?: IStoredFilterConversionOptions): SdkFiltersToTigerOutput<T>;
|
|
35
45
|
type TigerToSdkFiltersInput = ITigerFilter[] | ITigerFilterContextItem[] | undefined;
|
|
36
46
|
type TigerToSdkFiltersOutput<T extends TigerToSdkFiltersInput> = T extends ITigerFilter[] ? IFilter[] : T extends ITigerFilterContextItem[] ? FilterContextItem[] : undefined;
|
|
37
47
|
export declare function convertTigerToSdkFilters<T extends TigerToSdkFiltersInput>(filters: T): TigerToSdkFiltersOutput<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storedFilterConverter.d.ts","sourceRoot":"","sources":["../../../src/convertors/shared/storedFilterConverter.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAG/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACH,KAAK,iBAAiB,EAEtB,KAAK,OAAO,
|
|
1
|
+
{"version":3,"file":"storedFilterConverter.d.ts","sourceRoot":"","sources":["../../../src/convertors/shared/storedFilterConverter.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAG/B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACH,KAAK,iBAAiB,EAEtB,KAAK,OAAO,EAMf,MAAM,qBAAqB,CAAC;AAW7B;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC3C;;OAEG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACzC;AAKD;;;;;;;;;;;GAWG;AACH,wBAAgB,6BAA6B,CACzC,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,8BAAmC,GAC7C,YAAY,CAId;AAaD;;;;;;GAMG;AACH,wBAAgB,kCAAkC,CAAC,IAAI,EAAE,iBAAiB,GAAG,uBAAuB,CAgBnG;AA4CD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAG3E;AAmBD,KAAK,sBAAsB,GAAG,OAAO,EAAE,GAAG,iBAAiB,EAAE,GAAG,SAAS,CAAC;AAC1E,KAAK,uBAAuB,CAAC,CAAC,SAAS,sBAAsB,IAAI,CAAC,SAAS,OAAO,EAAE,GAC9E,YAAY,EAAE,GACd,CAAC,SAAS,iBAAiB,EAAE,GAC3B,uBAAuB,EAAE,GACzB,SAAS,CAAC;AAElB,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,sBAAsB,EACrE,OAAO,EAAE,CAAC,EACV,OAAO,GAAE,8BAAmC,GAC7C,uBAAuB,CAAC,CAAC,CAAC,CAoB5B;AAID,KAAK,sBAAsB,GAAG,YAAY,EAAE,GAAG,uBAAuB,EAAE,GAAG,SAAS,CAAC;AACrF,KAAK,uBAAuB,CAAC,CAAC,SAAS,sBAAsB,IAAI,CAAC,SAAS,YAAY,EAAE,GACnF,OAAO,EAAE,GACT,CAAC,SAAS,uBAAuB,EAAE,GACjC,iBAAiB,EAAE,GACnB,SAAS,CAAC;AAElB,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,sBAAsB,EACrE,OAAO,EAAE,CAAC,GACX,uBAAuB,CAAC,CAAC,CAAC,CAiC5B"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// (C) 2026 GoodData Corporation
|
|
2
2
|
import { isTigerFilterContextItems, isTigerFilters, } from "@gooddata/api-client-tiger";
|
|
3
|
-
import { isComparisonCondition, isDashboardMatchAttributeFilter, isDashboardMeasureValueFilter, } from "@gooddata/sdk-model";
|
|
3
|
+
import { isAbsoluteDateFilter, isComparisonCondition, isDashboardMatchAttributeFilter, isDashboardMeasureValueFilter, } from "@gooddata/sdk-model";
|
|
4
4
|
import { cloneWithSanitizedIdsTyped as cloneWithSanitizedIdsTypedFromBackend } from "../fromBackend/IdSanitization.js";
|
|
5
5
|
import { cloneWithSanitizedIdsTyped as cloneWithSanitizedIdsTypedToBackend } from "../toBackend/IdSanitization.js";
|
|
6
6
|
import { convertMeasureValueFilterSdkToTiger, convertMeasureValueFilterTigerToSdk, } from "./measureValueFilterConverter.js";
|
|
@@ -15,13 +15,24 @@ import { isFilterContextItems, isFilters } from "./sdkFilterTypeGuards.js";
|
|
|
15
15
|
* For AFM/execution filters, use the AFM filter converter instead.
|
|
16
16
|
*
|
|
17
17
|
* @param filter - SDK filter to convert
|
|
18
|
+
* @param options - conversion options
|
|
18
19
|
* @returns Tiger stored filter with sanitized IDs and converted formats
|
|
19
20
|
* @public
|
|
20
21
|
*/
|
|
21
|
-
export function convertSdkFilterToTigerStored(filter) {
|
|
22
|
-
const
|
|
22
|
+
export function convertSdkFilterToTigerStored(filter, options = {}) {
|
|
23
|
+
const stored = options.dropAbsoluteDateGranularity ? dropAbsoluteDateFilterGranularity(filter) : filter;
|
|
24
|
+
const sanitized = cloneWithSanitizedIdsTypedToBackend(stored);
|
|
23
25
|
return convertMeasureValueFilterSdkToTiger(sanitized);
|
|
24
26
|
}
|
|
27
|
+
// Insights store absolute date filters without the granularity. Dropping it cannot change what the
|
|
28
|
+
// filter selects, because from/to already are the first and the last day of the selected periods.
|
|
29
|
+
function dropAbsoluteDateFilterGranularity(filter) {
|
|
30
|
+
if (!isAbsoluteDateFilter(filter) || filter.absoluteDateFilter.granularity === undefined) {
|
|
31
|
+
return filter;
|
|
32
|
+
}
|
|
33
|
+
const { granularity: _granularity, ...absoluteDateFilter } = filter.absoluteDateFilter;
|
|
34
|
+
return { absoluteDateFilter };
|
|
35
|
+
}
|
|
25
36
|
/**
|
|
26
37
|
* Converts SDK FilterContextItem to Tiger FilterContextItem.
|
|
27
38
|
*
|
|
@@ -106,7 +117,7 @@ function convertDashboardFilterToSdk(item) {
|
|
|
106
117
|
}
|
|
107
118
|
return cloneWithSanitizedIdsTypedFromBackend(item);
|
|
108
119
|
}
|
|
109
|
-
export function convertSdkFiltersToTiger(filters) {
|
|
120
|
+
export function convertSdkFiltersToTiger(filters, options = {}) {
|
|
110
121
|
if (!filters) {
|
|
111
122
|
return undefined;
|
|
112
123
|
}
|
|
@@ -117,7 +128,7 @@ export function convertSdkFiltersToTiger(filters) {
|
|
|
117
128
|
return filters.map(convertSdkFilterContextItemToTiger);
|
|
118
129
|
}
|
|
119
130
|
if (isFilters(filters)) {
|
|
120
|
-
return filters.map(convertSdkFilterToTigerStored);
|
|
131
|
+
return filters.map((filter) => convertSdkFilterToTigerStored(filter, options));
|
|
121
132
|
}
|
|
122
133
|
throw new Error("Unsupported filters type");
|
|
123
134
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InsightConverter.d.ts","sourceRoot":"","sources":["../../../src/convertors/toBackend/InsightConverter.ts"],"names":[],"mappings":"AAIA,OAAO,EAOH,KAAK,0BAA0B,EAClC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAIH,KAAK,kBAAkB,EAO1B,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"InsightConverter.d.ts","sourceRoot":"","sources":["../../../src/convertors/toBackend/InsightConverter.ts"],"names":[],"mappings":"AAIA,OAAO,EAOH,KAAK,0BAA0B,EAClC,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAIH,KAAK,kBAAkB,EAO1B,MAAM,qBAAqB,CAAC;AAgC7B;;;;;GAKG;AACH,eAAO,MAAM,cAAc,YACd,kBAAkB,KAC5B,0BAA0B,CAAC,oBA2D7B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,oCAAoC,YAAa,kBAAkB,KAAG,MACxD,CAAC"}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
// (C) 2019-2026 GoodData Corporation
|
|
2
2
|
import { omit } from "lodash-es";
|
|
3
3
|
import { insightLayers, insightParameters, } from "@gooddata/sdk-model";
|
|
4
|
-
import { convertSdkFiltersToTiger } from "../shared/storedFilterConverter.js";
|
|
4
|
+
import { convertSdkFiltersToTiger, } from "../shared/storedFilterConverter.js";
|
|
5
5
|
import { cloneWithSanitizedIdsTyped } from "./IdSanitization.js";
|
|
6
|
+
// TODO: Analytical Designer does not support the granularity of an absolute date filter yet,
|
|
7
|
+
// so the insight and layer filters store only its days; measure filters in buckets keep it.
|
|
8
|
+
const insightFilterConversionOptions = { dropAbsoluteDateGranularity: true };
|
|
6
9
|
function removeIdentifiers(insight) {
|
|
7
10
|
const insightData = omit(insight.insight, ["ref", "uri", "identifier"]);
|
|
8
11
|
return {
|
|
@@ -32,7 +35,7 @@ export const convertInsight = (insight) => {
|
|
|
32
35
|
? {
|
|
33
36
|
layers: layers.map((layer) => {
|
|
34
37
|
const tigerLayer = cloneWithSanitizedIdsTyped(layer);
|
|
35
|
-
const convertedFilters = convertSdkFiltersToTiger(layer.filters);
|
|
38
|
+
const convertedFilters = convertSdkFiltersToTiger(layer.filters, insightFilterConversionOptions);
|
|
36
39
|
return {
|
|
37
40
|
...tigerLayer,
|
|
38
41
|
...(convertedFilters ? { filters: convertedFilters } : {}),
|
|
@@ -48,7 +51,7 @@ export const convertInsight = (insight) => {
|
|
|
48
51
|
: {};
|
|
49
52
|
return {
|
|
50
53
|
buckets: cloneWithSanitizedIdsTyped(sanitizedInsight.insight.buckets),
|
|
51
|
-
filters: convertSdkFiltersToTiger(sanitizedInsight.insight.filters),
|
|
54
|
+
filters: convertSdkFiltersToTiger(sanitizedInsight.insight.filters, insightFilterConversionOptions),
|
|
52
55
|
...(sanitizedInsight.insight.attributeFilterConfigs
|
|
53
56
|
? {
|
|
54
57
|
attributeFilterConfigs: cloneWithSanitizedIdsTyped(sanitizedInsight.insight.attributeFilterConfigs),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilterConverter.d.ts","sourceRoot":"","sources":["../../../../src/convertors/toBackend/afm/FilterConverter.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"FilterConverter.d.ts","sourceRoot":"","sources":["../../../../src/convertors/toBackend/afm/FilterConverter.ts"],"names":[],"mappings":"AAEA,OAAO,EAQH,KAAK,gBAAgB,EASxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAMH,KAAK,OAAO,EA2Bf,MAAM,qBAAqB,CAAC;AA+B7B;;;;;;GAMG;AACH,MAAM,WAAW,wBAAwB;IACrC,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,OAAO,GAAG,SAAS,CAAC;CACtC;AAED,wBAAgB,0BAA0B,CACtC,MAAM,EAAE,OAAO,EACf,aAAa,EAAE,OAAO,GAAG,SAAS,GACnC,wBAAwB,CAE1B;AA8XD,wBAAgB,aAAa,CACzB,OAAO,EAAE,OAAO,GAAG,wBAAwB,EAC3C,yBAAyB,GAAE,OAAe,GAC3C,gBAAgB,GAAG,IAAI,CAyBzB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// (C) 2007-2026 GoodData Corporation
|
|
2
2
|
import { filterIsEmpty, isAbsoluteDateFilter, isAllTimeDateFilter, isArbitraryAttributeFilter, isAttributeElementsByValue, isAttributeFilter, isComparisonCondition, isFilter, isLowerBound, isMatchAttributeFilter, isMeasureValueFilter, isNegativeAttributeFilter, isObjRef, isPositiveAttributeFilter, isRangeCondition, isRankingFilter, isRelativeBoundedDateFilterBody, isRelativeDateFilter, isUpperBound, } from "@gooddata/sdk-model";
|
|
3
3
|
import { toTigerGranularity } from "../../fromBackend/dateGranularityConversions.js";
|
|
4
|
+
import { hasPeriodLiteral, toWholePeriodLiterals } from "../../shared/absoluteGranularityLiterals.js";
|
|
4
5
|
import { toAfmIdentifier, toDateDataSetQualifier, toLabelQualifier, toLocalIdentifier, } from "../ObjRefConverter.js";
|
|
5
6
|
function toTigerEmptyValueHandling(emptyValues) {
|
|
6
7
|
if (emptyValues === "include") {
|
|
@@ -132,11 +133,31 @@ function convertAbsoluteDateFilter(filter, applyOnResultProp) {
|
|
|
132
133
|
const datasetRef = absoluteDateFilter.dataSet;
|
|
133
134
|
const localIdentifier = absoluteDateFilter.localIdentifier;
|
|
134
135
|
const emptyValueHandling = toTigerEmptyValueHandling(absoluteDateFilter.emptyValueHandling);
|
|
136
|
+
const from = String(absoluteDateFilter.from);
|
|
137
|
+
const to = String(absoluteDateFilter.to);
|
|
138
|
+
const granularity = absoluteDateFilter.granularity;
|
|
139
|
+
// A range of whole periods goes as period literals; any other range, which an older or an as-code
|
|
140
|
+
// dashboard can store, goes as its days, as stored.
|
|
141
|
+
if (hasPeriodLiteral(granularity)) {
|
|
142
|
+
const literals = toWholePeriodLiterals(granularity, from, to);
|
|
143
|
+
if (literals) {
|
|
144
|
+
return {
|
|
145
|
+
absoluteGranularityDateFilter: {
|
|
146
|
+
dataset: toDateDataSetQualifier(datasetRef),
|
|
147
|
+
granularity: toTigerGranularity(granularity),
|
|
148
|
+
...literals,
|
|
149
|
+
localIdentifier,
|
|
150
|
+
...(emptyValueHandling === undefined ? {} : { emptyValueHandling }),
|
|
151
|
+
...applyOnResultProp,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
}
|
|
135
156
|
return {
|
|
136
157
|
absoluteDateFilter: {
|
|
137
158
|
dataset: toDateDataSetQualifier(datasetRef),
|
|
138
|
-
from
|
|
139
|
-
to
|
|
159
|
+
from,
|
|
160
|
+
to,
|
|
140
161
|
localIdentifier,
|
|
141
162
|
...(emptyValueHandling === undefined ? {} : { emptyValueHandling }),
|
|
142
163
|
...applyOnResultProp,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gooddata/sdk-backend-tiger",
|
|
3
|
-
"version": "11.62.0-alpha.
|
|
3
|
+
"version": "11.62.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.62.0-alpha.
|
|
38
|
-
"@gooddata/sdk-backend-base": "11.62.0-alpha.
|
|
39
|
-
"@gooddata/sdk-backend-spi": "11.62.0-alpha.
|
|
40
|
-
"@gooddata/sdk-
|
|
41
|
-
"@gooddata/sdk-
|
|
42
|
-
"@gooddata/util": "11.62.0-alpha.
|
|
37
|
+
"@gooddata/api-client-tiger": "11.62.0-alpha.3",
|
|
38
|
+
"@gooddata/sdk-backend-base": "11.62.0-alpha.3",
|
|
39
|
+
"@gooddata/sdk-backend-spi": "11.62.0-alpha.3",
|
|
40
|
+
"@gooddata/sdk-code-convertors": "11.62.0-alpha.3",
|
|
41
|
+
"@gooddata/sdk-model": "11.62.0-alpha.3",
|
|
42
|
+
"@gooddata/util": "11.62.0-alpha.3"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@gooddata/fixtures": "3.7.0",
|
|
@@ -63,11 +63,11 @@
|
|
|
63
63
|
"oxlint-plugin-eslint": "1.82.0",
|
|
64
64
|
"oxlint-tsgolint": "7.0.2001",
|
|
65
65
|
"typescript": "7.0.2",
|
|
66
|
-
"vitest": "
|
|
67
|
-
"@gooddata/catalog-export": "11.62.0-alpha.
|
|
68
|
-
"@gooddata/
|
|
69
|
-
"@gooddata/oxlint-config": "11.62.0-alpha.
|
|
70
|
-
"@gooddata/
|
|
66
|
+
"vitest": "5.0.4",
|
|
67
|
+
"@gooddata/catalog-export": "11.62.0-alpha.3",
|
|
68
|
+
"@gooddata/eslint-config": "11.62.0-alpha.3",
|
|
69
|
+
"@gooddata/oxlint-config": "11.62.0-alpha.3",
|
|
70
|
+
"@gooddata/reference-workspace": "11.62.0-alpha.3"
|
|
71
71
|
},
|
|
72
72
|
"scripts": {
|
|
73
73
|
"_phase:build": "npm run build",
|