@gooddata/code-cli 0.50.0-alpha.5 → 0.50.0-alpha.7

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/dist/index.js CHANGED
@@ -37370,7 +37370,7 @@ function isPromise(value) {
37370
37370
  //#endregion
37371
37371
  //#region package.json
37372
37372
  var name$1 = "@gooddata/code-cli";
37373
- var version$1 = "0.50.0-alpha.5";
37373
+ var version$1 = "0.50.0-alpha.7";
37374
37374
  //#endregion
37375
37375
  //#region ../../../common/temp/aac/node_modules/.pnpm/vscode-languageserver@8.1.0/node_modules/vscode-languageserver/lib/common/utils/is.js
37376
37376
  var require_is$2 = /* @__PURE__ */ __commonJSMin(((exports) => {
@@ -80599,6 +80599,7 @@ var require_follow_redirects$1 = /* @__PURE__ */ __commonJSMin(((exports, module
80599
80599
  */
80600
80600
  const tigerIdTypeToObjectType = {
80601
80601
  attribute: "attribute",
80602
+ computedAttribute: "computedAttribute",
80602
80603
  metric: "measure",
80603
80604
  label: "displayForm",
80604
80605
  dataset: "dataSet",
@@ -87717,8 +87718,26 @@ var ErrorCodes;
87717
87718
  ErrorCodes[ErrorCodes["ParameterValueUncovered"] = 14] = "ParameterValueUncovered";
87718
87719
  })(ErrorCodes || (ErrorCodes = {}));
87719
87720
  //#endregion
87720
- //#region ../../../common/temp/aac/node_modules/.pnpm/gdc-maql-language-server@file+..+..+..+libs+gdc-maql-language-server/node_modules/gdc-maql-language-server/esm/findObjects.js
87721
+ //#region ../../../common/temp/aac/node_modules/.pnpm/gdc-maql-language-server@file+..+..+..+libs+gdc-maql-language-server/node_modules/gdc-maql-language-server/esm/maqlObjectTypes.js
87721
87722
  var import_tree = require_tree();
87723
+ /**
87724
+ * MAQL spells the computed-attribute object type with an underscore (`{computed_attribute/id}`),
87725
+ * while the Tiger entity type it maps onto is camelCase (`computedAttribute`). Every other MAQL
87726
+ * object type is spelled the same on both sides, so this is the only bridge the two need.
87727
+ */
87728
+ const MAQL_OBJECT_TYPE_TO_TIGER_TYPE = { computed_attribute: "computedAttribute" };
87729
+ /**
87730
+ * Translates an object type as written in MAQL into the Tiger entity type it denotes. Types that
87731
+ * are spelled identically on both sides are returned unchanged, so this is safe to apply to any
87732
+ * `{type/id}` token before looking the type up.
87733
+ *
87734
+ * Keep the MAQL spelling for anything user-facing (diagnostics quote what the author wrote).
87735
+ */
87736
+ function normalizeMaqlObjectType(maqlObjectType) {
87737
+ return MAQL_OBJECT_TYPE_TO_TIGER_TYPE[maqlObjectType] ?? maqlObjectType;
87738
+ }
87739
+ //#endregion
87740
+ //#region ../../../common/temp/aac/node_modules/.pnpm/gdc-maql-language-server@file+..+..+..+libs+gdc-maql-language-server/node_modules/gdc-maql-language-server/esm/findObjects.js
87722
87741
  const { AttributeTypeContext: AttributeTypeContext$1, MaqlParser: MaqlParser$4, NumericTypeContext: NumericTypeContext$1 } = import_dist$7.default;
87723
87742
  function findAllObjects(metric) {
87724
87743
  const finder = new ObjectFinder();
@@ -87738,12 +87757,13 @@ var ObjectFinder = class {
87738
87757
  const rbrace = ctx.tryGetToken(MaqlParser$4.RBRACE, 0);
87739
87758
  if (lbrace === void 0 || lbrace.symbol.tokenIndex === -1 || sep === void 0 || sep.symbol.tokenIndex === -1 || id === void 0 || id.symbol.tokenIndex === -1 || rbrace === void 0 || rbrace.symbol.tokenIndex === -1 || type === void 0) return;
87740
87759
  const range = antlrContextRange(ctx.start, ctx.stop);
87760
+ const tigerType = normalizeMaqlObjectType(type);
87741
87761
  this.objects.push({
87742
- tigerType: isTigerType(type) ? type : void 0,
87762
+ tigerType: isTigerType(tigerType) ? tigerType : void 0,
87743
87763
  actualType: type,
87744
87764
  id: ctx.ID().text,
87745
87765
  ref: {
87746
- type: tigerIdTypeToObjectType[type],
87766
+ type: tigerIdTypeToObjectType[tigerType],
87747
87767
  identifier: ctx.ID().text
87748
87768
  },
87749
87769
  range
@@ -89294,10 +89314,11 @@ var LdmObjects = class LdmObjects {
89294
89314
  labels;
89295
89315
  facts;
89296
89316
  metrics;
89317
+ computedAttributes;
89297
89318
  parameters;
89298
89319
  datasets;
89299
89320
  size;
89300
- constructor(attributes, facts, metrics, parameters, dates, datasets) {
89321
+ constructor(attributes, facts, metrics, parameters, dates, datasets, computedAttributes = []) {
89301
89322
  const processedAttributes = this.processAttributes(attributes);
89302
89323
  const processedDates = this.processDates(dates);
89303
89324
  const regularAttributes = processedAttributes.flatMap((item) => item.attributes);
@@ -89316,15 +89337,17 @@ var LdmObjects = class LdmObjects {
89316
89337
  };
89317
89338
  this.facts = facts.map((fact) => LdmObjects.toTigerMetadataObject(fact.fact));
89318
89339
  this.metrics = metrics.map((metric) => LdmObjects.toTigerMetadataObject(metric.measure));
89340
+ this.computedAttributes = computedAttributes.map((computedAttribute) => LdmObjects.toTigerMetadataObject(computedAttribute));
89319
89341
  this.parameters = parameters.map((parameter) => LdmObjects.toTigerMetadataObject(parameter));
89320
89342
  this.datasets = datasets.map((dataset) => LdmObjects.toTigerDataset(dataset));
89321
- this.size = this.attributes.all.length + this.labels.all.length + this.facts.length + this.metrics.length + this.parameters.length;
89343
+ this.size = this.attributes.all.length + this.labels.all.length + this.facts.length + this.metrics.length + this.computedAttributes.length + this.parameters.length;
89322
89344
  }
89323
89345
  get(type, typeModifier = "all") {
89324
89346
  switch (type) {
89325
89347
  case "attribute": return this.attributes[typeModifier];
89326
89348
  case "fact": return this.facts;
89327
89349
  case "metric": return this.metrics;
89350
+ case "computedAttribute": return this.computedAttributes;
89328
89351
  case "parameter": return this.parameters;
89329
89352
  case "dataset": return this.datasets;
89330
89353
  case "label": return this.labels[typeModifier];
@@ -102867,6 +102890,7 @@ var SpecificCoreErrorCode;
102867
102890
  SpecificCoreErrorCode["UniquenessDatasetsId"] = "core.uniqueness.datasets.id";
102868
102891
  SpecificCoreErrorCode["UniquenessMetricsId"] = "core.uniqueness.metrics.id";
102869
102892
  SpecificCoreErrorCode["UniquenessParametersId"] = "core.uniqueness.parameters.id";
102893
+ SpecificCoreErrorCode["UniquenessComputedAttributesId"] = "core.uniqueness.computedAttributes.id";
102870
102894
  SpecificCoreErrorCode["UniquenessVisualisationsId"] = "core.uniqueness.visualisations.id";
102871
102895
  SpecificCoreErrorCode["UniquenessDashboardsId"] = "core.uniqueness.dashboards.id";
102872
102896
  SpecificCoreErrorCode["UniquenessPluginId"] = "core.uniqueness.plugins.id";
@@ -103013,6 +103037,7 @@ const CoreErrorMessages$1 = {
103013
103037
  [SpecificCoreErrorCode.UniquenessDatasetsId]: `There are more datasets with id "{0}". Use unique names for datasets.`,
103014
103038
  [SpecificCoreErrorCode.UniquenessMetricsId]: `There are more metrics with id "{0}". Use unique names for metrics.`,
103015
103039
  [SpecificCoreErrorCode.UniquenessParametersId]: `There are more parameters with id "{0}". Use unique names for parameters.`,
103040
+ [SpecificCoreErrorCode.UniquenessComputedAttributesId]: `There are more computed attributes with id "{0}". Use unique names for computed attributes.`,
103016
103041
  [SpecificCoreErrorCode.UniquenessVisualisationsId]: `There are more visualisations with id "{0}". Use unique names for visualisations.`,
103017
103042
  [SpecificCoreErrorCode.UniquenessDashboardsId]: `There are more dashboards with id "{0}". Use unique names for dashboards.`,
103018
103043
  [SpecificCoreErrorCode.UniquenessPluginId]: `There are more plugins with id "{0}". Use unique names for plugins.`,
@@ -103091,6 +103116,7 @@ const CoreErrorTypes$1 = {
103091
103116
  [SpecificCoreErrorCode.UniquenessDatasetsId]: "UniquenessDatasetsId",
103092
103117
  [SpecificCoreErrorCode.UniquenessMetricsId]: "UniquenessMetricsId",
103093
103118
  [SpecificCoreErrorCode.UniquenessParametersId]: "UniquenessParametersId",
103119
+ [SpecificCoreErrorCode.UniquenessComputedAttributesId]: "UniquenessComputedAttributesId",
103094
103120
  [SpecificCoreErrorCode.UniquenessPluginId]: "UniquenessPluginId",
103095
103121
  [SpecificCoreErrorCode.UniquenessAttributeHierarchyId]: "UniquenessAttributeHierarchyId",
103096
103122
  [SpecificCoreErrorCode.UniquenessDashboardWidgetLocalId]: "UniquenessDashboardWidgetLocalId",
@@ -106500,8 +106526,16 @@ const SupportedReferenceTypes$1 = [
106500
106526
  "dataset",
106501
106527
  "attribute"
106502
106528
  ];
106503
- /** MAQL can additionally name a parameter; custom URLs and shorthand fields cannot. */
106504
- const SupportedMaqlReferenceTypes = [...SupportedReferenceTypes$1, "parameter"];
106529
+ /**
106530
+ * MAQL can additionally name a parameter and a computed attribute; custom URLs and shorthand fields
106531
+ * cannot. The computed attribute token precedes "attribute" in the alternation the patterns build
106532
+ * from this list, so the longer token wins.
106533
+ */
106534
+ const SupportedMaqlReferenceTypes = [
106535
+ "computed_attribute",
106536
+ ...SupportedReferenceTypes$1,
106537
+ "parameter"
106538
+ ];
106505
106539
  /** The id fragment of a `type/id` reference, shared by every pattern that matches one. */
106506
106540
  const REFERENCE_ID_PATTERN = "(?!\\.)[.A-Za-z0-9_-]{1,255}";
106507
106541
  function parseReferenceObject$1(obj, supported = SupportedReferenceTypes$1) {
@@ -106583,6 +106617,7 @@ const DatasetTypes$2 = ["dataset"];
106583
106617
  const DateDatasetTypes$2 = ["date"];
106584
106618
  const MetricTypes$1 = ["metric"];
106585
106619
  const ParameterTypes$1 = ["parameter"];
106620
+ const ComputedAttributeTypes$1 = ["computed_attribute"];
106586
106621
  const AttrTypes$1 = ["attribute"];
106587
106622
  const FactTypes$1 = ["fact"];
106588
106623
  const AggregatedFactTypes = ["aggregated_fact"];
@@ -106623,6 +106658,7 @@ const TypesAll = allReferenceTypes([
106623
106658
  "dataset",
106624
106659
  "metric",
106625
106660
  "parameter",
106661
+ "computed_attribute",
106626
106662
  "area_chart",
106627
106663
  "bubble_chart",
106628
106664
  "bar_chart",
@@ -106684,6 +106720,10 @@ function isParameter(obj) {
106684
106720
  if (typeof obj === "object" && obj && "id" in obj && "type" in obj) return ParameterTypes$1.includes(obj.type);
106685
106721
  return false;
106686
106722
  }
106723
+ function isComputedAttribute(obj) {
106724
+ if (typeof obj === "object" && obj && "id" in obj && "type" in obj) return ComputedAttributeTypes$1.includes(obj.type);
106725
+ return false;
106726
+ }
106687
106727
  function isManifest(obj) {
106688
106728
  return !!(typeof obj === "object" && obj && "profiles" in obj && "source_dir" in obj);
106689
106729
  }
@@ -134859,18 +134899,31 @@ function isBrowserDetectedTimezone$1(timezoneId) {
134859
134899
  return timezoneId === BROWSER_DETECTED$1;
134860
134900
  }
134861
134901
  /**
134902
+ * Signed offset-style identifiers (`±HH`, `±HHMM`, `±HH:MM`, optionally with seconds).
134903
+ * Some `Intl` implementations accept these as `timeZone` values, but they are not named
134904
+ * IANA timezone IDs. Named IDs such as `"Etc/GMT+1"` do not match this pattern.
134905
+ */
134906
+ const OFFSET_STYLE_TIMEZONE_ID$1 = /^[+-]\d{2}(?:\d{2}|:\d{2}(?::\d{2}(?:\.\d+)?)?)?$/;
134907
+ /**
134862
134908
  * Tests whether `timezoneId` is a valid IANA timezone identifier according to
134863
134909
  * the runtime ICU data (via `Intl.DateTimeFormat`). The {@link BROWSER_DETECTED}
134864
134910
  * sentinel is not a valid IANA ID — use {@link isValidDashboardTimezoneId} for
134865
134911
  * values stored on the dashboard.
134866
134912
  *
134913
+ * Identifiers are case-sensitive. `Intl` accepts timezones case-insensitively, so
134914
+ * a value that only differs in case from the canonical form (e.g. `"america/new_york"`)
134915
+ * is rejected. Aliases that resolve to a different identifier (e.g. `"Etc/UTC"` → `"UTC"`)
134916
+ * are still accepted as ICU-known IDs. Offset-style identifiers (e.g. `"+01"`, `"+0100"`,
134917
+ * `"+01:00"`) are rejected.
134918
+ *
134867
134919
  * @param timezoneId - timezone identifier to test
134868
134920
  * @alpha
134869
134921
  */
134870
134922
  function isValidIanaTimezoneId$1(timezoneId) {
134923
+ if (OFFSET_STYLE_TIMEZONE_ID$1.test(timezoneId)) return false;
134871
134924
  try {
134872
- new Intl.DateTimeFormat(void 0, { timeZone: timezoneId });
134873
- return true;
134925
+ const canonical = new Intl.DateTimeFormat(void 0, { timeZone: timezoneId }).resolvedOptions().timeZone;
134926
+ return canonical === timezoneId || canonical.toLowerCase() !== timezoneId.toLowerCase();
134874
134927
  } catch {
134875
134928
  return false;
134876
134929
  }
@@ -135386,6 +135439,29 @@ function yamlParameterDefinitionToDeclarative(definition) {
135386
135439
  };
135387
135440
  }
135388
135441
  //#endregion
135442
+ //#region ../../../sdk/libs/sdk-code-convertors/src/to/yamlComputedAttributeToDeclarative.ts
135443
+ /**
135444
+ * A computed attribute is textual for now: the backend does not transfer the value type from
135445
+ * metadata yet, so every computed attribute is interpreted as a STRING/TEXT one. The YAML shape
135446
+ * therefore does not expose dataType/valueType and the defaults are filled in here.
135447
+ */
135448
+ const DEFAULT_DATA_TYPE = "STRING";
135449
+ const DEFAULT_VALUE_TYPE = "TEXT";
135450
+ /** @public */
135451
+ function yamlComputedAttributeToDeclarative(input) {
135452
+ const output = {
135453
+ id: input.id,
135454
+ title: input.title ?? convertIdToTitle$1(input.id),
135455
+ description: input.description ?? "",
135456
+ tags: input.tags ?? [],
135457
+ content: { maql: input.maql },
135458
+ dataType: DEFAULT_DATA_TYPE,
135459
+ valueType: DEFAULT_VALUE_TYPE
135460
+ };
135461
+ if (input.locale !== void 0) output.locale = input.locale;
135462
+ return output;
135463
+ }
135464
+ //#endregion
135389
135465
  //#region ../../../sdk/libs/sdk-code-convertors/src/configs/utils.ts
135390
135466
  /** @public */
135391
135467
  function getValueOrDefault(value, defaultValue, type = "string", undefinedAsDefault = false) {
@@ -140294,6 +140370,8 @@ const MetricTypes = ["metric"];
140294
140370
  /** @internal */
140295
140371
  const ParameterTypes = ["parameter"];
140296
140372
  /** @internal */
140373
+ const ComputedAttributeTypes = ["computed_attribute"];
140374
+ /** @internal */
140297
140375
  const DashboardTypes = ["dashboard"];
140298
140376
  /** @internal */
140299
140377
  const PluginTypes = ["plugin"];
@@ -140331,6 +140409,7 @@ const AllTypes = [
140331
140409
  ...DateDatasetTypes,
140332
140410
  ...MetricTypes,
140333
140411
  ...ParameterTypes,
140412
+ ...ComputedAttributeTypes,
140334
140413
  ...DashboardTypes,
140335
140414
  ...PluginTypes,
140336
140415
  ...VisualisationsTypes,
@@ -141139,6 +141218,12 @@ const DATE_INSTANCE_COMMENT = [
141139
141218
  " Read more about date instances:",
141140
141219
  " https://www.gooddata.com/developers/cloud-native/doc/cloud/model-data/concepts/dataset/#date-datasets"
141141
141220
  ].join("\n");
141221
+ const COMPUTED_ATTRIBUTE_COMMENT = [
141222
+ " A computed attribute turns numbers into named groups, for example \"Small\", \"Medium\", \"Large\".",
141223
+ " Write the break points in MAQL - the first matching branch wins - and use it like any attribute.",
141224
+ " Read more about MAQL:",
141225
+ " https://www.gooddata.com/developers/cloud-native/doc/cloud/create-metrics/maql/"
141226
+ ].join("\n");
141142
141227
  const METRIC_COMMENT = [
141143
141228
  " A metric is a computational expression of numerical data (facts or other metrics).",
141144
141229
  " Use MAQL to create reusable multidimensional queries that combine multiple facts and attributes.",
@@ -141393,6 +141478,23 @@ function declarativeParameterDefinitionToYaml(definition) {
141393
141478
  };
141394
141479
  }
141395
141480
  //#endregion
141481
+ //#region ../../../sdk/libs/sdk-code-convertors/src/from/declarativeComputedAttributeToYaml.ts
141482
+ /** @public */
141483
+ function declarativeComputedAttributeToYaml(computedAttribute) {
141484
+ const doc = new import_dist.Document({
141485
+ type: "computed_attribute",
141486
+ id: computedAttribute.id
141487
+ });
141488
+ doc.commentBefore = COMPUTED_ATTRIBUTE_COMMENT;
141489
+ fillOptionalMetaFields(doc, computedAttribute);
141490
+ doc.add(entryWithSpace("maql", computedAttribute.content.maql ?? ""));
141491
+ if (computedAttribute.locale) doc.add(doc.createPair("locale", computedAttribute.locale));
141492
+ return {
141493
+ content: doc.toString({ lineWidth: 0 }),
141494
+ json: doc.toJSON()
141495
+ };
141496
+ }
141497
+ //#endregion
141396
141498
  //#region ../../../sdk/libs/sdk-code-convertors/src/from/filtersToYaml.ts
141397
141499
  function detectEmptyValuesFilterType(filter) {
141398
141500
  const attributeElements = filterAttributeElements(filter);
@@ -143764,6 +143866,9 @@ const ID_PATTERN = new RegExp(`(${SupportedMaqlReferenceTypes.join("|")})\\/(${R
143764
143866
  function resolveMetricReferences(item) {
143765
143867
  return resolveMaqlReferences(item.maql ?? "");
143766
143868
  }
143869
+ function resolveComputedAttributeReferences(item) {
143870
+ return resolveMaqlReferences(item.maql ?? "");
143871
+ }
143767
143872
  function resolveMaqlReferences(maql) {
143768
143873
  const reg = new RegExp(ID_PATTERN.source, ID_PATTERN.flags);
143769
143874
  const all = [];
@@ -144019,6 +144124,7 @@ function containsReference(item, ref) {
144019
144124
  ...isDashboard(item) ? [createReferenceObject(item.id, "dashboard")] : [],
144020
144125
  ...isPlugin(item) ? [createReferenceObject(item.id, "plugin")] : [],
144021
144126
  ...isMetric(item) ? [createReferenceObject(item.id, "metric")] : [],
144127
+ ...isComputedAttribute(item) ? [createReferenceObject(item.id, "computed_attribute")] : [],
144022
144128
  ...isParameter(item) ? [createReferenceObject(item.id, "parameter")] : [],
144023
144129
  ...isAttributeHierarchy(item) ? [createReferenceObject(item.id, "attribute_hierarchy")] : []
144024
144130
  ].some((item) => item.type === ref.type && item.identifier === ref.identifier);
@@ -144028,6 +144134,7 @@ function collectItemReferences(item) {
144028
144134
  case "dataset":
144029
144135
  case "date": return resolveDatasetReferences$1(item);
144030
144136
  case "metric": return resolveMetricReferences(item);
144137
+ case "computed_attribute": return resolveComputedAttributeReferences(item);
144031
144138
  case "dashboard": return resolveDashboardReferences(item);
144032
144139
  case "plugin":
144033
144140
  case "parameter": return [];
@@ -144309,20 +144416,22 @@ function convertDateTitle(item, gran) {
144309
144416
  //#endregion
144310
144417
  //#region ../code/esm/features/references/resolve/objects.js
144311
144418
  function resolveLdmObjects(files) {
144312
- const { metrics, parameters, datasets, dates } = files.reduce((prev, item) => {
144419
+ const { metrics, computedAttributes, parameters, datasets, dates } = files.reduce((prev, item) => {
144313
144420
  if (isDataset$1(item)) prev.datasets.push(buildDataset(item));
144314
144421
  if (isDateDataset$1(item)) prev.dates.push(buildDate(item));
144315
144422
  if (isMetric(item)) prev.metrics.push(buildMetric(item));
144423
+ if (isComputedAttribute(item)) prev.computedAttributes.push(buildComputedAttribute(item));
144316
144424
  if (isParameter(item)) prev.parameters.push(buildParameter(item));
144317
144425
  return prev;
144318
144426
  }, {
144319
144427
  metrics: [],
144428
+ computedAttributes: [],
144320
144429
  parameters: [],
144321
144430
  dates: [],
144322
144431
  datasets: []
144323
144432
  });
144324
144433
  const { attributes, facts } = extractFromDatasets(datasets);
144325
- return new LdmObjects(attributes, facts, metrics, parameters, dates, datasets);
144434
+ return new LdmObjects(attributes, facts, metrics, parameters, dates, datasets, computedAttributes);
144326
144435
  }
144327
144436
  function extractFromDatasets(datasets) {
144328
144437
  const attributes = [];
@@ -144447,6 +144556,24 @@ function buildMetric(item) {
144447
144556
  groups: []
144448
144557
  };
144449
144558
  }
144559
+ /**
144560
+ * A computed attribute has no real labels, so unlike a normal attribute it contributes only itself
144561
+ * to the catalog - MAQL references it directly as `{computed_attribute/id}`, never through a label.
144562
+ */
144563
+ function buildComputedAttribute(item) {
144564
+ return {
144565
+ type: "computedAttribute",
144566
+ ...buildUriRef("computedAttribute", item.id),
144567
+ id: item.id,
144568
+ description: item.description ?? "",
144569
+ title: item.title ?? convertIdToTitle(item.id),
144570
+ expression: item.maql,
144571
+ production: true,
144572
+ deprecated: false,
144573
+ unlisted: false,
144574
+ displayForms: []
144575
+ };
144576
+ }
144450
144577
  function buildParameter(item) {
144451
144578
  return {
144452
144579
  type: "parameter",
@@ -145836,6 +145963,15 @@ function resolveReferencesByObjectSource(references, source, opts) {
145836
145963
  remote: false
145837
145964
  };
145838
145965
  }
145966
+ case "computedAttribute.id": {
145967
+ const [available, diagnostics] = resolveReferencesIds(references, ["computed_attribute"]);
145968
+ return {
145969
+ available: withPrefix(isComputedAttribute(references.self) ? available.filter(filterBySelf(references.self?.id)) : available, "computed_attribute", opts.typePrefix),
145970
+ ambiguous: getAmbiguous(available),
145971
+ diagnostics,
145972
+ remote: false
145973
+ };
145974
+ }
145839
145975
  case "dataset.field": {
145840
145976
  const [available, diagnostics] = resolveFieldsIds(references, ["dataset"]);
145841
145977
  return {
@@ -146717,6 +146853,13 @@ const metadata_v1 = {
146717
146853
  },
146718
146854
  "then": { "$ref": "#/$global/gaac/metric" }
146719
146855
  },
146856
+ {
146857
+ "if": {
146858
+ "properties": { "type": { "const": "computed_attribute" } },
146859
+ "required": ["type"]
146860
+ },
146861
+ "then": { "$ref": "#/$global/gaac/computed_attribute" }
146862
+ },
146720
146863
  {
146721
146864
  "if": {
146722
146865
  "properties": { "type": { "const": "dashboard" } },
@@ -146786,6 +146929,7 @@ const metadata_v1 = {
146786
146929
  "snippets": [
146787
146930
  "dataset",
146788
146931
  "metric",
146932
+ "computed_attribute",
146789
146933
  "date",
146790
146934
  "dashboard",
146791
146935
  "plugin",
@@ -146824,6 +146968,7 @@ const metadata_v1 = {
146824
146968
  "dataset",
146825
146969
  "date",
146826
146970
  "metric",
146971
+ "computed_attribute",
146827
146972
  "dashboard",
146828
146973
  "plugin",
146829
146974
  "table",
@@ -147161,6 +147306,59 @@ const metadata_v1 = {
147161
147306
  "maql"
147162
147307
  ]
147163
147308
  },
147309
+ "computed_attribute": {
147310
+ "title": "ComputedAttribute",
147311
+ "type": "object",
147312
+ "additionalProperties": false,
147313
+ "properties": {
147314
+ "id": {
147315
+ "$ref": "#/$global/gaac/identifier",
147316
+ "description": "A unique identifier of the computed attribute. Must not collide with the identifier of an attribute or a label.",
147317
+ "$semantic": [{
147318
+ "type": "uniqueness",
147319
+ "source": "computedAttribute.id",
147320
+ "code": "core.uniqueness.computedAttributes.id"
147321
+ }, {
147322
+ "type": "definition",
147323
+ "source": "computedAttribute.id"
147324
+ }]
147325
+ },
147326
+ "type": {
147327
+ "type": "string",
147328
+ "enum": ["computed_attribute"]
147329
+ },
147330
+ "title": {
147331
+ "$ref": "#/$global/gaac/title",
147332
+ "description": "An optional human readable title for the computed attribute. Will be derived from id if not provided explicitly."
147333
+ },
147334
+ "description": {
147335
+ "$ref": "#/$global/gaac/description",
147336
+ "description": "An optional description of the computed attribute."
147337
+ },
147338
+ "tags": {
147339
+ "$ref": "#/$global/gaac/tags",
147340
+ "description": "A list of strings - metadata tags of this computed attribute."
147341
+ },
147342
+ "maql": {
147343
+ "type": "string",
147344
+ "description": "Define MAQL syntax for the computed attribute. Values are assigned with break points written as CASE WHEN branches over a metric, and the first matching branch wins.",
147345
+ "$semantic": { "type": "maql" }
147346
+ },
147347
+ "locale": {
147348
+ "type": "string",
147349
+ "description": "An optional locale whose collation order the computed values are sorted by."
147350
+ }
147351
+ },
147352
+ "$semantic": {
147353
+ "type": "snippet",
147354
+ "snippets": ["computed_attribute"]
147355
+ },
147356
+ "required": [
147357
+ "id",
147358
+ "type",
147359
+ "maql"
147360
+ ]
147361
+ },
147164
147362
  "dashboard": {
147165
147363
  "title": "Dashboard",
147166
147364
  "type": "object",
@@ -152002,6 +152200,59 @@ const metadata_v1 = {
152002
152200
  "mode": "property"
152003
152201
  }
152004
152202
  },
152203
+ "computed_attribute": {
152204
+ "title": "ComputedAttribute",
152205
+ "type": "object",
152206
+ "additionalProperties": false,
152207
+ "properties": {
152208
+ "id": {
152209
+ "$ref": "#/$global/gaac/identifier",
152210
+ "description": "A unique identifier of the computed attribute. Must not collide with the identifier of an attribute or a label.",
152211
+ "$semantic": [{
152212
+ "type": "uniqueness",
152213
+ "source": "computedAttribute.id",
152214
+ "code": "core.uniqueness.computedAttributes.id"
152215
+ }, {
152216
+ "type": "definition",
152217
+ "source": "computedAttribute.id"
152218
+ }]
152219
+ },
152220
+ "type": {
152221
+ "type": "string",
152222
+ "enum": ["computed_attribute"]
152223
+ },
152224
+ "title": {
152225
+ "$ref": "#/$global/gaac/title",
152226
+ "description": "An optional human readable title for the computed attribute. Will be derived from id if not provided explicitly."
152227
+ },
152228
+ "description": {
152229
+ "$ref": "#/$global/gaac/description",
152230
+ "description": "An optional description of the computed attribute."
152231
+ },
152232
+ "tags": {
152233
+ "$ref": "#/$global/gaac/tags",
152234
+ "description": "A list of strings - metadata tags of this computed attribute."
152235
+ },
152236
+ "maql": {
152237
+ "type": "string",
152238
+ "description": "Define MAQL syntax for the computed attribute. Values are assigned with break points written as CASE WHEN branches over a metric, and the first matching branch wins.",
152239
+ "$semantic": { "type": "maql" }
152240
+ },
152241
+ "locale": {
152242
+ "type": "string",
152243
+ "description": "An optional locale whose collation order the computed values are sorted by."
152244
+ }
152245
+ },
152246
+ "$semantic": {
152247
+ "type": "snippet",
152248
+ "snippets": ["computed_attribute"]
152249
+ },
152250
+ "required": [
152251
+ "id",
152252
+ "type",
152253
+ "maql"
152254
+ ]
152255
+ },
152005
152256
  "widthItem": {
152006
152257
  "title": "Width",
152007
152258
  "type": "object",
@@ -156727,18 +156978,31 @@ function isBrowserDetectedTimezone(timezoneId) {
156727
156978
  return timezoneId === BROWSER_DETECTED;
156728
156979
  }
156729
156980
  /**
156981
+ * Signed offset-style identifiers (`±HH`, `±HHMM`, `±HH:MM`, optionally with seconds).
156982
+ * Some `Intl` implementations accept these as `timeZone` values, but they are not named
156983
+ * IANA timezone IDs. Named IDs such as `"Etc/GMT+1"` do not match this pattern.
156984
+ */
156985
+ const OFFSET_STYLE_TIMEZONE_ID = /^[+-]\d{2}(?:\d{2}|:\d{2}(?::\d{2}(?:\.\d+)?)?)?$/;
156986
+ /**
156730
156987
  * Tests whether `timezoneId` is a valid IANA timezone identifier according to
156731
156988
  * the runtime ICU data (via `Intl.DateTimeFormat`). The {@link BROWSER_DETECTED}
156732
156989
  * sentinel is not a valid IANA ID — use {@link isValidDashboardTimezoneId} for
156733
156990
  * values stored on the dashboard.
156734
156991
  *
156992
+ * Identifiers are case-sensitive. `Intl` accepts timezones case-insensitively, so
156993
+ * a value that only differs in case from the canonical form (e.g. `"america/new_york"`)
156994
+ * is rejected. Aliases that resolve to a different identifier (e.g. `"Etc/UTC"` → `"UTC"`)
156995
+ * are still accepted as ICU-known IDs. Offset-style identifiers (e.g. `"+01"`, `"+0100"`,
156996
+ * `"+01:00"`) are rejected.
156997
+ *
156735
156998
  * @param timezoneId - timezone identifier to test
156736
156999
  * @alpha
156737
157000
  */
156738
157001
  function isValidIanaTimezoneId(timezoneId) {
157002
+ if (OFFSET_STYLE_TIMEZONE_ID.test(timezoneId)) return false;
156739
157003
  try {
156740
- new Intl.DateTimeFormat(void 0, { timeZone: timezoneId });
156741
- return true;
157004
+ const canonical = new Intl.DateTimeFormat(void 0, { timeZone: timezoneId }).resolvedOptions().timeZone;
157005
+ return canonical === timezoneId || canonical.toLowerCase() !== timezoneId.toLowerCase();
156742
157006
  } catch {
156743
157007
  return false;
156744
157008
  }
@@ -158375,6 +158639,7 @@ function buildSnippet(definition, type) {
158375
158639
  case "date": return buildSnippetForDateDataset(definition);
158376
158640
  case "metric": return buildSnippetForMetric(definition);
158377
158641
  case "parameter": return buildSnippetForParameter(definition);
158642
+ case "computed_attribute": return buildSnippetForComputedAttribute(definition);
158378
158643
  case "attribute": return buildSnippetForAttribute(definition);
158379
158644
  case "fact": return buildSnippetForFact(definition);
158380
158645
  case "color": return buildSnippetForColor();
@@ -158435,6 +158700,15 @@ function buildSnippetForParameter(definition) {
158435
158700
  lines.push(``);
158436
158701
  return lines.join("\n");
158437
158702
  }
158703
+ function buildSnippetForComputedAttribute(definition) {
158704
+ const lines = [];
158705
+ const tb = tabStopBuilder();
158706
+ if (!definition.id) lines.push(`id: ${tb()}`);
158707
+ if (!definition.type) lines.push(`type: computed_attribute`);
158708
+ if (!definition.maql) lines.push(`maql: SELECT CASE WHEN {metric/${tb()}} > ${tb("0")} THEN "${tb("High")}" ELSE "${tb("Low")}" END`);
158709
+ lines.push(``);
158710
+ return lines.join("\n");
158711
+ }
158438
158712
  function buildSnippetForAttribute(definition) {
158439
158713
  const lines = [];
158440
158714
  const tb = tabStopBuilder();
@@ -159691,6 +159965,7 @@ const REFERENCED_OBJECT_TYPES = {
159691
159965
  "dataSource.id": "dataSource",
159692
159966
  "metric.id": "metric",
159693
159967
  "parameter.id": "parameter",
159968
+ "computedAttribute.id": "computed_attribute",
159694
159969
  "table.id": "table",
159695
159970
  "fact.id": "fact",
159696
159971
  "aggregated_fact.id": "aggregated_fact",
@@ -159714,6 +159989,7 @@ function referencesFindYamlForReferences(references, nodeItem, semanticItem, typ
159714
159989
  case "dataSource.id":
159715
159990
  case "metric.id":
159716
159991
  case "parameter.id":
159992
+ case "computedAttribute.id":
159717
159993
  case "table.id":
159718
159994
  case "fact.id":
159719
159995
  case "aggregated_fact.id":
@@ -159818,6 +160094,9 @@ function referencesFindYamlForDefinition(references, parents, nodeItem, semantic
159818
160094
  case "dashboard.id":
159819
160095
  prev.push(...createDefinitionForMainType(references, isDashboard, value, "dashboard"));
159820
160096
  break;
160097
+ case "computedAttribute.id":
160098
+ prev.push(...createDefinitionForMainType(references, isComputedAttribute, value, "computed_attribute"));
160099
+ break;
159821
160100
  case "metric.id":
159822
160101
  prev.push(...createDefinitionForMainType(references, isMetric, value, "metric"));
159823
160102
  break;
@@ -160344,6 +160623,7 @@ function createTextEdit(item, name) {
160344
160623
  case "dataSource":
160345
160624
  case "metric":
160346
160625
  case "parameter":
160626
+ case "computed_attribute":
160347
160627
  case "attribute_hierarchy":
160348
160628
  case "label": {
160349
160629
  const prefix = `${item.type}/`;
@@ -160799,7 +161079,7 @@ async function open(state, emitter, file) {
160799
161079
  //#endregion
160800
161080
  //#region ../code/package.json
160801
161081
  var name = "@gooddata/code";
160802
- var version = "0.50.0-alpha.5";
161082
+ var version = "0.50.0-alpha.7";
160803
161083
  //#endregion
160804
161084
  //#region ../../../sdk/libs/api-client-tiger/src/axios.ts
160805
161085
  /**
@@ -160821,7 +161101,7 @@ const _CONFIG = {
160821
161101
  common: {
160822
161102
  "X-Requested-With": "XMLHttpRequest",
160823
161103
  "X-GDC-JS-PACKAGE": "@gooddata/api-client-tiger",
160824
- "X-GDC-JS-PACKAGE-VERSION": "11.54.0-alpha.5"
161104
+ "X-GDC-JS-PACKAGE-VERSION": "11.54.0-alpha.7"
160825
161105
  },
160826
161106
  post: { "Content-Type": "application/json;charset=utf8" },
160827
161107
  put: { "Content-Type": "application/json;charset=utf8" }
@@ -199341,6 +199621,7 @@ function updateDeclarativeLayout(currentWs, newWs) {
199341
199621
  analytics: {
199342
199622
  ...currentWs.analytics ?? {},
199343
199623
  metrics: newWs.analytics?.metrics,
199624
+ ...newWs.analytics?.computedAttributes ? { computedAttributes: newWs.analytics?.computedAttributes } : {},
199344
199625
  ...newWs.analytics?.visualizationObjects ? { visualizationObjects: newWs.analytics?.visualizationObjects } : {},
199345
199626
  ...newWs.analytics?.analyticalDashboards ? { analyticalDashboards: newWs.analytics?.analyticalDashboards } : {},
199346
199627
  ...newWs.analytics?.filterContexts ? { filterContexts: newWs.analytics?.filterContexts } : {},
@@ -199522,6 +199803,11 @@ function createDeclarativeWorkspaceModel(entities, profile) {
199522
199803
  return data;
199523
199804
  });
199524
199805
  ws.analytics.parameters = parameterEntities.map((d) => d.declarative);
199806
+ const computedAttributesEntities = entities.filter((e) => ComputedAttributeTypes.includes(e.type)).map((data) => {
199807
+ data.declarative = yamlComputedAttributeToDeclarative(data.data);
199808
+ return data;
199809
+ });
199810
+ ws.analytics.computedAttributes = computedAttributesEntities.map((d) => d.declarative);
199525
199811
  const visualisationsEntities = entities.filter((e) => VisualisationsTypes.includes(e.type)).map((data) => {
199526
199812
  data.declarative = yamlVisualisationToDeclarative(entities, data.data);
199527
199813
  return data;
@@ -199795,6 +200081,10 @@ function buildEntities(ws) {
199795
200081
  type: "metric",
199796
200082
  id: metric.id
199797
200083
  })),
200084
+ ...(ws.analytics?.computedAttributes ?? []).map((computedAttribute) => ({
200085
+ type: "computed_attribute",
200086
+ id: computedAttribute.id
200087
+ })),
199798
200088
  ...(ws.analytics?.visualizationObjects ?? []).map((visualisation) => ({
199799
200089
  type: declarativeVisTypeToYaml(visualisation.content),
199800
200090
  id: visualisation.id
@@ -199831,6 +200121,7 @@ async function fromDeclarative(workspace, basePath, profile, { tables = {}, stor
199831
200121
  const datasetsPath = [...basePath, "datasets"];
199832
200122
  const metricsPath = [...basePath, "metrics"];
199833
200123
  const parametersPath = [...basePath, "parameters"];
200124
+ const computedAttributesPath = [...basePath, "computedAttributes"];
199834
200125
  const visualisationsPath = [...basePath, "visualisations"];
199835
200126
  const dashboardsPath = [...basePath, "dashboards"];
199836
200127
  const pluginPath = [...basePath, "plugins"];
@@ -199888,6 +200179,17 @@ async function fromDeclarative(workspace, basePath, profile, { tables = {}, stor
199888
200179
  });
199889
200180
  return createNewFile(store, filePath, createFileContent({ content: Buffer.from(content, "utf8") }), { mode: "remote" });
199890
200181
  }) ?? []);
200182
+ if (workspace?.analytics?.computedAttributes) mergeResults(update, workspace.analytics.computedAttributes.map((computedAttribute) => {
200183
+ const { content, json } = declarativeComputedAttributeToYaml(computedAttribute);
200184
+ const filePath = generateFileName(files, computedAttributesPath, computedAttribute.id, computedAttribute.title);
200185
+ if (json && content) entitiesLoaded.push({
200186
+ type: "computed_attribute",
200187
+ id: computedAttribute.id,
200188
+ data: json,
200189
+ path: filePath
200190
+ });
200191
+ return createNewFile(store, filePath, createFileContent({ content: Buffer.from(content, "utf8") }), { mode: "remote" });
200192
+ }) ?? []);
199891
200193
  if (workspace?.analytics?.visualizationObjects) mergeResults(update, workspace.analytics.visualizationObjects.map((visualisation) => {
199892
200194
  const { content, json } = declarativeVisualisationToYaml(entitiesLoaded, visualisation);
199893
200195
  const filePath = generateFileName(files, visualisationsPath, visualisation.id, visualisation.title);
@@ -202285,6 +202587,7 @@ async function fileExists$2(path) {
202285
202587
  //#endregion
202286
202588
  //#region src/commands/init/file.cursorRules.ts
202287
202589
  const ruleFiles = [
202590
+ "computedAttributes.mdc",
202288
202591
  "dashboards.mdc",
202289
202592
  "datasets.mdc",
202290
202593
  "gooddata.mdc",