@finos/legend-query-builder 4.14.30 → 4.14.31

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. package/lib/components/QueryBuilder.d.ts +1 -1
  2. package/lib/components/QueryBuilder.d.ts.map +1 -1
  3. package/lib/components/QueryBuilder.js +36 -3
  4. package/lib/components/QueryBuilder.js.map +1 -1
  5. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js +1 -1
  6. package/lib/components/__test-utils__/QueryBuilderComponentTestUtils.js.map +1 -1
  7. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.d.ts.map +1 -1
  8. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.js +5 -10
  9. package/lib/components/fetch-structure/QueryBuilderFetchStructurePanel.js.map +1 -1
  10. package/lib/graph/QueryBuilderMetaModelConst.d.ts +3 -0
  11. package/lib/graph/QueryBuilderMetaModelConst.d.ts.map +1 -1
  12. package/lib/graph/QueryBuilderMetaModelConst.js +5 -0
  13. package/lib/graph/QueryBuilderMetaModelConst.js.map +1 -1
  14. package/lib/graph-manager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.js +4 -1
  15. package/lib/graph-manager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.js.map +1 -1
  16. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.d.ts +1 -0
  17. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.d.ts.map +1 -1
  18. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.js +51 -3
  19. package/lib/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.js.map +1 -1
  20. package/lib/index.css +17 -1
  21. package/lib/index.css.map +1 -1
  22. package/lib/index.d.ts +1 -1
  23. package/lib/index.d.ts.map +1 -1
  24. package/lib/index.js +1 -1
  25. package/lib/index.js.map +1 -1
  26. package/lib/package.json +1 -1
  27. package/lib/stores/QueryBuilderResultState.d.ts.map +1 -1
  28. package/lib/stores/QueryBuilderResultState.js +1 -0
  29. package/lib/stores/QueryBuilderResultState.js.map +1 -1
  30. package/lib/stores/QueryBuilderState.d.ts +4 -1
  31. package/lib/stores/QueryBuilderState.d.ts.map +1 -1
  32. package/lib/stores/QueryBuilderState.js +12 -1
  33. package/lib/stores/QueryBuilderState.js.map +1 -1
  34. package/lib/stores/QueryBuilderStateBuilder.d.ts +2 -1
  35. package/lib/stores/QueryBuilderStateBuilder.d.ts.map +1 -1
  36. package/lib/stores/QueryBuilderStateBuilder.js +33 -4
  37. package/lib/stores/QueryBuilderStateBuilder.js.map +1 -1
  38. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts +5 -0
  39. package/lib/stores/QueryBuilderValueSpecificationBuilderHelper.d.ts.map +1 -1
  40. package/lib/stores/__test-utils__/QueryBuilderStateTestUtils.js +1 -1
  41. package/lib/stores/__test-utils__/QueryBuilderStateTestUtils.js.map +1 -1
  42. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.d.ts +1 -0
  43. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.d.ts.map +1 -1
  44. package/lib/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js.map +1 -1
  45. package/lib/stores/fetch-structure/QueryBuilderFetchStructureState.d.ts +2 -1
  46. package/lib/stores/fetch-structure/QueryBuilderFetchStructureState.d.ts.map +1 -1
  47. package/lib/stores/fetch-structure/QueryBuilderFetchStructureState.js +7 -0
  48. package/lib/stores/fetch-structure/QueryBuilderFetchStructureState.js.map +1 -1
  49. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts +1 -0
  50. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.d.ts.map +1 -1
  51. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js +4 -0
  52. package/lib/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.js.map +1 -1
  53. package/lib/stores/fetch-structure/tds/QueryBuilderAdvancedWorkflowState.d.ts +2 -0
  54. package/lib/stores/fetch-structure/tds/QueryBuilderAdvancedWorkflowState.d.ts.map +1 -0
  55. package/lib/stores/fetch-structure/tds/QueryBuilderAdvancedWorkflowState.js +2 -0
  56. package/lib/stores/fetch-structure/tds/QueryBuilderAdvancedWorkflowState.js.map +1 -0
  57. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts +1 -0
  58. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.d.ts.map +1 -1
  59. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js +4 -0
  60. package/lib/stores/fetch-structure/tds/QueryBuilderTDSState.js.map +1 -1
  61. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.d.ts +4 -3
  62. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.d.ts.map +1 -1
  63. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js +35 -3
  64. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.js.map +1 -1
  65. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.d.ts +2 -9
  66. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.d.ts.map +1 -1
  67. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js +45 -36
  68. package/lib/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.js.map +1 -1
  69. package/{src/stores/workflow/QueryBuilderWorkFlowState.ts → lib/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.d.ts} +5 -12
  70. package/lib/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.d.ts.map +1 -0
  71. package/lib/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.js +55 -0
  72. package/lib/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.js.map +1 -0
  73. package/lib/stores/{workflow → query-workflow}/QueryBuilderWorkFlowState.d.ts +12 -0
  74. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.d.ts.map +1 -0
  75. package/lib/stores/{workflow → query-workflow}/QueryBuilderWorkFlowState.js +18 -0
  76. package/lib/stores/query-workflow/QueryBuilderWorkFlowState.js.map +1 -0
  77. package/lib/stores/workflows/FunctionQueryBuilderState.d.ts +1 -1
  78. package/lib/stores/workflows/FunctionQueryBuilderState.d.ts.map +1 -1
  79. package/lib/stores/workflows/MappingQueryBuilderState.d.ts +1 -1
  80. package/lib/stores/workflows/MappingQueryBuilderState.d.ts.map +1 -1
  81. package/lib/stores/workflows/ServiceQueryBuilderState.d.ts +1 -1
  82. package/lib/stores/workflows/ServiceQueryBuilderState.d.ts.map +1 -1
  83. package/package.json +3 -3
  84. package/src/components/QueryBuilder.tsx +77 -2
  85. package/src/components/__test-utils__/QueryBuilderComponentTestUtils.tsx +1 -1
  86. package/src/components/fetch-structure/QueryBuilderFetchStructurePanel.tsx +29 -29
  87. package/src/graph/QueryBuilderMetaModelConst.ts +7 -0
  88. package/src/graph-manager/protocol/pure/QueryBuilder_PureProtocolProcessorPlugin.ts +3 -3
  89. package/src/graph-manager/protocol/pure/v1/V1_QueryValueSpecificationBuilderHelper.ts +122 -1
  90. package/src/index.ts +1 -1
  91. package/src/stores/QueryBuilderResultState.ts +1 -0
  92. package/src/stores/QueryBuilderState.ts +17 -1
  93. package/src/stores/QueryBuilderStateBuilder.ts +65 -5
  94. package/src/stores/QueryBuilderValueSpecificationBuilderHelper.ts +5 -0
  95. package/src/stores/__test-utils__/QueryBuilderStateTestUtils.ts +1 -1
  96. package/src/stores/fetch-structure/QueryBuilderFetchStructureImplementationState.ts +1 -0
  97. package/src/stores/fetch-structure/QueryBuilderFetchStructureState.ts +15 -0
  98. package/src/stores/fetch-structure/graph-fetch/QueryBuilderGraphFetchTreeState.ts +5 -0
  99. package/src/stores/fetch-structure/tds/QueryBuilderAdvancedWorkflowState.ts +0 -0
  100. package/src/stores/fetch-structure/tds/QueryBuilderTDSState.ts +5 -0
  101. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionStateBuilder.ts +76 -2
  102. package/src/stores/fetch-structure/tds/projection/QueryBuilderProjectionValueSpecificationBuilder.ts +90 -81
  103. package/src/stores/fetch-structure/tds/projection/QueryBuilderRelationProjectValueSpecBuidler.ts +108 -0
  104. package/src/stores/query-workflow/QueryBuilderWorkFlowState.ts +64 -0
  105. package/src/stores/workflows/FunctionQueryBuilderState.ts +1 -1
  106. package/src/stores/workflows/MappingQueryBuilderState.ts +1 -1
  107. package/src/stores/workflows/ServiceQueryBuilderState.ts +1 -1
  108. package/tsconfig.json +3 -1
  109. package/lib/stores/workflow/QueryBuilderWorkFlowState.d.ts.map +0 -1
  110. package/lib/stores/workflow/QueryBuilderWorkFlowState.js.map +0 -1
@@ -32,6 +32,7 @@ import { QueryBuilderGraphFetchTreeState } from '../../stores/fetch-structure/gr
32
32
  import { QueryBuilderPanelIssueCountBadge } from '../shared/QueryBuilderPanelIssueCountBadge.js';
33
33
  import { FETCH_STRUCTURE_IMPLEMENTATION } from '../../stores/fetch-structure/QueryBuilderFetchStructureImplementationState.js';
34
34
  import { QUERY_BUILDER_TEST_ID } from '../../__lib__/QueryBuilderTesting.js';
35
+ import { onChangeFetchStructureImplementation } from '../../stores/fetch-structure/QueryBuilderFetchStructureState.js';
35
36
 
36
37
  const QueryBuilderFetchStructureEditor = observer(
37
38
  (props: { queryBuilderState: QueryBuilderState }) => {
@@ -68,24 +69,18 @@ export const QueryBuilderFetchStructurePanel = observer(
68
69
  (props: { queryBuilderState: QueryBuilderState }) => {
69
70
  const { queryBuilderState } = props;
70
71
  const fetchStructureState = queryBuilderState.fetchStructureState;
71
-
72
- const onChangeFetchStructureImplementation =
73
- (implementationType: FETCH_STRUCTURE_IMPLEMENTATION): (() => void) =>
74
- (): void => {
75
- if (fetchStructureState.implementation.type !== implementationType) {
76
- fetchStructureState.implementation.checkBeforeChangingImplementation(
77
- () => {
78
- fetchStructureState.changeImplementation(implementationType);
79
- },
80
- );
81
- }
82
- };
72
+ const fetchConfig =
73
+ queryBuilderState.workflowState.getFetchStructureLayoutConfig(
74
+ queryBuilderState,
75
+ );
83
76
 
84
77
  return (
85
78
  <Panel data-testid={QUERY_BUILDER_TEST_ID.QUERY_BUILDER_FETCH_STRUCTURE}>
86
79
  <PanelHeader>
87
80
  <div className="panel__header__title">
88
- <div className="panel__header__title__label">fetch structure</div>
81
+ <div className="panel__header__title__label">
82
+ {fetchConfig.label}
83
+ </div>
89
84
  {fetchStructureState.implementation.fetchStructureValidationIssues
90
85
  .length !== 0 && (
91
86
  <QueryBuilderPanelIssueCountBadge
@@ -96,22 +91,27 @@ export const QueryBuilderFetchStructurePanel = observer(
96
91
  />
97
92
  )}
98
93
  </div>
99
- <PanelHeaderActions>
100
- <div className="query-builder__fetch__structure__modes">
101
- {Object.values(FETCH_STRUCTURE_IMPLEMENTATION).map((type) => (
102
- <button
103
- onClick={onChangeFetchStructureImplementation(type)}
104
- className={clsx('query-builder__fetch__structure__mode', {
105
- 'query-builder__fetch__structure__mode--selected':
106
- type === fetchStructureState.implementation.type,
107
- })}
108
- key={type}
109
- >
110
- {prettyCONSTName(type)}
111
- </button>
112
- ))}
113
- </div>
114
- </PanelHeaderActions>
94
+ {fetchConfig.showInFetchPanel ? (
95
+ <PanelHeaderActions>
96
+ <div className="query-builder__fetch__structure__modes">
97
+ {Object.values(FETCH_STRUCTURE_IMPLEMENTATION).map((type) => (
98
+ <button
99
+ onClick={onChangeFetchStructureImplementation(
100
+ type,
101
+ fetchStructureState,
102
+ )}
103
+ className={clsx('query-builder__fetch__structure__mode', {
104
+ 'query-builder__fetch__structure__mode--selected':
105
+ type === fetchStructureState.implementation.type,
106
+ })}
107
+ key={type}
108
+ >
109
+ {prettyCONSTName(type)}
110
+ </button>
111
+ ))}
112
+ </div>
113
+ </PanelHeaderActions>
114
+ ) : null}
115
115
  </PanelHeader>
116
116
  <QueryBuilderFetchStructureEditor
117
117
  queryBuilderState={queryBuilderState}
@@ -24,6 +24,8 @@ export enum QUERY_BUILDER_PURE_PATH {
24
24
  DURATION_UNIT = 'meta::pure::functions::date::DurationUnit',
25
25
  DAY_OF_WEEK = 'meta::pure::functions::date::DayOfWeek',
26
26
 
27
+ // RELATION
28
+ RELATION = 'meta::pure::metamodel::relation::Relation',
27
29
  // serialization
28
30
  SERIALIZE_CONFIG = 'meta::pure::graphFetch::execution::AlloySerializationConfig',
29
31
  }
@@ -31,6 +33,7 @@ export enum QUERY_BUILDER_PURE_PATH {
31
33
  export enum QUERY_BUILDER_SUPPORTED_CALENDAR_AGGREGATION_FUNCTIONS {
32
34
  CALENDAR_ANNUALIZED = 'meta::pure::functions::date::calendar::annualized',
33
35
  CALENDAR_CME = ' meta::pure::functions::date::calendar::cme',
36
+
34
37
  CALENDAR_CW = 'meta::pure::functions::date::calendar::cw',
35
38
  CALENDAR_CW_FM = 'meta::pure::functions::date::calendar::cw_fm',
36
39
  CALENDAR_CY_MINUS2 = 'meta::pure::functions::date::calendar::CYMinus2',
@@ -114,6 +117,10 @@ export enum QUERY_BUILDER_SUPPORTED_FUNCTIONS {
114
117
  TDS_RESTRICT = 'meta::pure::tds::restrict',
115
118
  TDS_FUNC = 'meta::pure::tds::func',
116
119
 
120
+ // Relation
121
+ RELATION_PROJECT = 'meta::pure::functions::relation::project',
122
+ RELATION_LIMIT = 'meta::pure::functions::relation::limit',
123
+
117
124
  // filter
118
125
  CONTAINS = 'meta::pure::functions::string::contains',
119
126
  ENDS_WITH = 'meta::pure::functions::string::endsWith',
@@ -146,10 +146,10 @@ export class QueryBuilder_PureProtocolProcessorPlugin extends PureProtocolProces
146
146
  processingContext,
147
147
  );
148
148
  } else if (
149
- matchFunctionName(
150
- functionName,
149
+ matchFunctionName(functionName, [
151
150
  QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_PROJECT,
152
- )
151
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.RELATION_PROJECT,
152
+ ])
153
153
  ) {
154
154
  return V1_buildProjectFunctionExpression(
155
155
  functionName,
@@ -21,6 +21,7 @@ import {
21
21
  filterByType,
22
22
  guaranteeNonNullable,
23
23
  guaranteeType,
24
+ isNonNullable,
24
25
  returnUndefOnError,
25
26
  } from '@finos/legend-shared';
26
27
  import {
@@ -56,6 +57,11 @@ import {
56
57
  LambdaFunction,
57
58
  LambdaFunctionInstanceValue,
58
59
  PackageableElementExplicitReference,
60
+ V1_ClassInstance,
61
+ V1_ColSpecArray,
62
+ ColSpecArrayInstance,
63
+ ColSpecArray,
64
+ ColSpec,
59
65
  } from '@finos/legend-graph';
60
66
  import {
61
67
  QUERY_BUILDER_PURE_PATH,
@@ -574,6 +580,110 @@ export const V1_buildFilterFunctionExpression = (
574
580
  return expression;
575
581
  };
576
582
 
583
+ export const V1_buildTypedProjectFunctionExpression = (
584
+ functionName: string,
585
+ parameters: V1_ValueSpecification[],
586
+ openVariables: string[],
587
+ compileContext: V1_GraphBuilderContext,
588
+ processingContext: V1_ProcessingContext,
589
+ ): SimpleFunctionExpression => {
590
+ assertTrue(
591
+ parameters.length === 2,
592
+ `Can't build relation project() expression: project() expects 2 arguments`,
593
+ );
594
+
595
+ let topLevelLambdaParameters: V1_Variable[] = [];
596
+ const precedingExperession = (
597
+ parameters[0] as V1_ValueSpecification
598
+ ).accept_ValueSpecificationVisitor(
599
+ new V1_ValueSpecificationBuilder(
600
+ compileContext,
601
+ processingContext,
602
+ openVariables,
603
+ ),
604
+ );
605
+ assertNonNullable(
606
+ precedingExperession.genericType,
607
+ `Can't build relation project() expression: preceding expression return type is missing`,
608
+ );
609
+
610
+ const classInstance = parameters[1];
611
+ assertType(
612
+ classInstance,
613
+ V1_ClassInstance,
614
+ `Can't build relation project() expression: project() expects argument #1 to be a ClassInstance`,
615
+ );
616
+ const specArray = guaranteeType(
617
+ classInstance.value,
618
+ V1_ColSpecArray,
619
+ `Can't build relation project() expression: project() expects argument #1 to hold spec array instances value`,
620
+ );
621
+
622
+ topLevelLambdaParameters = specArray.colSpecs
623
+ .map((e) => e.function1)
624
+ .filter(isNonNullable)
625
+ .filter(filterByType(V1_Lambda))
626
+ .map((lambda) => lambda.parameters)
627
+ .flat();
628
+
629
+ const variables = new Set<string>();
630
+ // Make sure top-level lambdas have their lambda parameter types set properly
631
+ topLevelLambdaParameters.forEach((variable) => {
632
+ if (!variables.has(variable.name) && !variable.class) {
633
+ const variableExpression = new VariableExpression(
634
+ variable.name,
635
+ precedingExperession.multiplicity,
636
+ );
637
+ variableExpression.genericType = precedingExperession.genericType;
638
+ processingContext.addInferredVariables(variable.name, variableExpression);
639
+ }
640
+ });
641
+ const processedExpression = new ColSpecArrayInstance(Multiplicity.ONE);
642
+ const processedColSpecArray = new ColSpecArray();
643
+ processedExpression.values = [processedColSpecArray];
644
+
645
+ processedColSpecArray.colSpecs = specArray.colSpecs.map((colSpec) => {
646
+ const pColSpec = new ColSpec();
647
+ let lambda: ValueSpecification;
648
+ const _funct = guaranteeType(
649
+ colSpec.function1,
650
+ V1_ValueSpecification,
651
+ `Can't build relation col spec() expression: expects function1 to be a lambda`,
652
+ );
653
+ try {
654
+ lambda = buildProjectionColumnLambda(
655
+ _funct,
656
+ openVariables,
657
+ compileContext,
658
+ processingContext,
659
+ );
660
+ } catch {
661
+ lambda = new INTERNAL__UnknownValueSpecification(
662
+ V1_serializeValueSpecification(
663
+ _funct,
664
+ compileContext.extensions.plugins,
665
+ ),
666
+ );
667
+ }
668
+ pColSpec.function1 = lambda;
669
+ pColSpec.name = colSpec.name;
670
+ return pColSpec;
671
+ });
672
+
673
+ const expression = V1_buildBaseSimpleFunctionExpression(
674
+ [precedingExperession, processedExpression],
675
+ functionName,
676
+ compileContext,
677
+ );
678
+ expression.genericType = GenericTypeExplicitReference.create(
679
+ new GenericType(
680
+ compileContext.resolveType(QUERY_BUILDER_PURE_PATH.RELATION).value,
681
+ ),
682
+ );
683
+
684
+ return expression;
685
+ };
686
+
577
687
  export const V1_buildProjectFunctionExpression = (
578
688
  functionName: string,
579
689
  parameters: V1_ValueSpecification[],
@@ -581,8 +691,19 @@ export const V1_buildProjectFunctionExpression = (
581
691
  compileContext: V1_GraphBuilderContext,
582
692
  processingContext: V1_ProcessingContext,
583
693
  ): SimpleFunctionExpression => {
694
+ if (parameters.length === 2) {
695
+ return V1_buildTypedProjectFunctionExpression(
696
+ functionName,
697
+ parameters,
698
+ openVariables,
699
+ compileContext,
700
+ processingContext,
701
+ );
702
+ }
703
+
704
+ const length = parameters.length;
584
705
  assertTrue(
585
- parameters.length === 3,
706
+ length === 3 || length === 2,
586
707
  `Can't build project() expression: project() expects 2 arguments`,
587
708
  );
588
709
 
package/src/index.ts CHANGED
@@ -93,4 +93,4 @@ export * from './stores/QueryBuilder_LegendApplicationPlugin_Extension.js';
93
93
 
94
94
  export * from './stores/data-access/DataAccessState.js';
95
95
  export * from './components/data-access/DataAccessOverview.js';
96
- export * from './stores/workflow/QueryBuilderWorkFlowState.js';
96
+ export * from './stores/query-workflow/QueryBuilderWorkFlowState.js';
@@ -312,6 +312,7 @@ export class QueryBuilderResultState {
312
312
  if (this.queryBuilderState.isQuerySupported) {
313
313
  const lambdaFunction = buildLambdaFunction(this.queryBuilderState, {
314
314
  isBuildingExecutionQuery: true,
315
+ useTypedRelationFunctions: this.queryBuilderState.isFetchStructureTyped,
315
316
  ...executionOptions,
316
317
  });
317
318
  query = buildRawLambdaFromLambdaFunction(
@@ -109,7 +109,7 @@ import {
109
109
  import type { QueryBuilderConfig } from '../graph-manager/QueryBuilderConfig.js';
110
110
  import { QUERY_BUILDER_EVENT } from '../__lib__/QueryBuilderEvent.js';
111
111
  import { QueryBuilderChangeHistoryState } from './QueryBuilderChangeHistoryState.js';
112
- import { type QueryBuilderWorkflowState } from './workflow/QueryBuilderWorkFlowState.js';
112
+ import { type QueryBuilderWorkflowState } from './query-workflow/QueryBuilderWorkFlowState.js';
113
113
 
114
114
  export interface QuerySDLC {}
115
115
 
@@ -157,6 +157,8 @@ export abstract class QueryBuilderState implements CommandRegistrar {
157
157
  isQueryChatOpened = false;
158
158
  isLocalModeEnabled = false;
159
159
 
160
+ lambdaWriteMode = QUERY_BUILDER_LAMBDA_WRITER_MODE.STANDARD;
161
+
160
162
  class?: Class | undefined;
161
163
  getAllFunction: QUERY_BUILDER_SUPPORTED_GET_ALL_FUNCTIONS =
162
164
  QUERY_BUILDER_SUPPORTED_GET_ALL_FUNCTIONS.GET_ALL;
@@ -204,6 +206,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
204
206
  isQueryChatOpened: observable,
205
207
  isLocalModeEnabled: observable,
206
208
  getAllFunction: observable,
209
+ lambdaWriteMode: observable,
207
210
 
208
211
  sideBarClassName: computed,
209
212
  isQuerySupported: computed,
@@ -218,6 +221,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
218
221
  setIsQueryChatOpened: action,
219
222
  setIsLocalModeEnabled: action,
220
223
  setGetAllFunction: action,
224
+ setLambdaWriteMode: action,
221
225
 
222
226
  resetQueryResult: action,
223
227
  resetQueryContent: action,
@@ -300,6 +304,17 @@ export abstract class QueryBuilderState implements CommandRegistrar {
300
304
  return this.allVariables.map((e) => e.name);
301
305
  }
302
306
 
307
+ get isFetchStructureTyped(): boolean {
308
+ return (
309
+ this.lambdaWriteMode ===
310
+ QUERY_BUILDER_LAMBDA_WRITER_MODE.TYPED_FETCH_STRUCTURE
311
+ );
312
+ }
313
+
314
+ setLambdaWriteMode(val: QUERY_BUILDER_LAMBDA_WRITER_MODE): void {
315
+ this.lambdaWriteMode = val;
316
+ }
317
+
303
318
  getQueryExecutionContext(): QueryExecutionContext {
304
319
  const queryExeContext = new QueryExplicitExecutionContext();
305
320
  const runtimeValue = guaranteeType(
@@ -538,6 +553,7 @@ export abstract class QueryBuilderState implements CommandRegistrar {
538
553
  return buildRawLambdaFromLambdaFunction(
539
554
  buildLambdaFunction(this, {
540
555
  keepSourceInformation: Boolean(options?.keepSourceInformation),
556
+ useTypedRelationFunctions: this.isFetchStructureTyped,
541
557
  }),
542
558
  this.graphManagerState,
543
559
  );
@@ -26,7 +26,7 @@ import {
26
26
  } from '@finos/legend-shared';
27
27
  import type { QueryBuilderState } from './QueryBuilderState.js';
28
28
  import {
29
- type AbstractPropertyExpression,
29
+ AbstractPropertyExpression,
30
30
  type EnumValueInstanceValue,
31
31
  type FunctionExpression,
32
32
  type GraphFetchTreeInstanceValue,
@@ -36,7 +36,8 @@ import {
36
36
  type INTERNAL__PropagatedValue,
37
37
  type ValueSpecification,
38
38
  type CollectionInstanceValue,
39
- type LambdaFunctionInstanceValue,
39
+ LambdaFunctionInstanceValue,
40
+ type ColSpecArrayInstance,
40
41
  InstanceValue,
41
42
  INTERNAL__UnknownValueSpecification,
42
43
  matchFunctionName,
@@ -481,6 +482,7 @@ export class QueryBuilderValueSpecificationProcessor
481
482
  ) {
482
483
  processTDSProjectionDerivationExpression(
483
484
  valueSpecification,
485
+ undefined,
484
486
  this.parentExpression,
485
487
  this.queryBuilderState,
486
488
  );
@@ -637,10 +639,10 @@ export class QueryBuilderValueSpecificationProcessor
637
639
  );
638
640
  return;
639
641
  } else if (
640
- matchFunctionName(
641
- functionName,
642
+ matchFunctionName(functionName, [
642
643
  QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_PROJECT,
643
- )
644
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.RELATION_PROJECT,
645
+ ])
644
646
  ) {
645
647
  processTDSProjectExpression(
646
648
  valueSpecification,
@@ -835,6 +837,7 @@ export class QueryBuilderValueSpecificationProcessor
835
837
  if (
836
838
  matchFunctionName(this.parentExpression.functionName, [
837
839
  QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_PROJECT,
840
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.RELATION_PROJECT,
838
841
  QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_GROUP_BY,
839
842
  QUERY_BUILDER_SUPPORTED_FUNCTIONS.TDS_AGG,
840
843
  ...Object.values(
@@ -844,6 +847,7 @@ export class QueryBuilderValueSpecificationProcessor
844
847
  ) {
845
848
  processTDSProjectionColumnPropertyExpression(
846
849
  valueSpecification,
850
+ undefined,
847
851
  this.queryBuilderState,
848
852
  );
849
853
  return;
@@ -903,6 +907,62 @@ export class QueryBuilderValueSpecificationProcessor
903
907
  ): void {
904
908
  throw new UnsupportedOperationError();
905
909
  }
910
+
911
+ visit_ColSpecArrayInstance(valueSpecification: ColSpecArrayInstance): void {
912
+ assertNonNullable(
913
+ this.parentExpression,
914
+ `Can't process col spec aray instance: parent expression cannot be retrieved`,
915
+ );
916
+
917
+ if (
918
+ matchFunctionName(this.parentExpression.functionName, [
919
+ QUERY_BUILDER_SUPPORTED_FUNCTIONS.RELATION_PROJECT,
920
+ ])
921
+ ) {
922
+ const spec = valueSpecification.values;
923
+ assertTrue(
924
+ spec.length === 1,
925
+ `Can't process col spec array instance: value expected to be of size 1`,
926
+ );
927
+ guaranteeNonNullable(spec[0]).colSpecs.forEach((col) => {
928
+ const _function1 = guaranteeType(
929
+ col.function1,
930
+ LambdaFunctionInstanceValue,
931
+ `Can't process col spec: function1 not a lambda function instance value`,
932
+ );
933
+ assertTrue(_function1.values.length === 1);
934
+ const lambdaVal = guaranteeNonNullable(_function1.values[0]);
935
+ assertTrue(lambdaVal.expressionSequence.length === 1);
936
+ const expression = guaranteeNonNullable(
937
+ lambdaVal.expressionSequence[0],
938
+ );
939
+
940
+ if (expression instanceof AbstractPropertyExpression) {
941
+ processTDSProjectionColumnPropertyExpression(
942
+ expression,
943
+ col.name,
944
+ this.queryBuilderState,
945
+ );
946
+ } else if (expression instanceof INTERNAL__UnknownValueSpecification) {
947
+ assertNonNullable(
948
+ this.parentExpression,
949
+ `Can't process unknown value: parent expression cannot be retrieved`,
950
+ );
951
+ processTDSProjectionDerivationExpression(
952
+ expression,
953
+ col.name,
954
+ this.parentExpression,
955
+ this.queryBuilderState,
956
+ );
957
+ }
958
+ });
959
+
960
+ return;
961
+ }
962
+ throw new UnsupportedOperationError(
963
+ `Can't process col spec array expression with parent expression of function ${this.parentExpression.functionName}()`,
964
+ );
965
+ }
906
966
  }
907
967
 
908
968
  export const processParameters = (
@@ -205,4 +205,9 @@ export type LambdaFunctionBuilderOption = {
205
205
  * limit for the query results if it exists so the exported results contain all the data
206
206
  */
207
207
  isExportingResult?: boolean | undefined;
208
+ /**
209
+ * Set this flag to `true` when you want to write to typed TDS function using the `Relation`
210
+ * typed in engine. This is still an experimental feature, hence we should only enable this flag when user wants to enable this directly.
211
+ */
212
+ useTypedRelationFunctions?: boolean | undefined;
208
213
  };
@@ -41,7 +41,7 @@ import {
41
41
  INTERNAL__BasicQueryBuilderState,
42
42
  type QueryBuilderState,
43
43
  } from '../QueryBuilderState.js';
44
- import { QueryBuilderAdvancedWorkflowState } from '../workflow/QueryBuilderWorkFlowState.js';
44
+ import { QueryBuilderAdvancedWorkflowState } from '../query-workflow/QueryBuilderWorkFlowState.js';
45
45
 
46
46
  export class TEST__LegendApplicationPluginManager
47
47
  extends LegendApplicationPluginManager<LegendApplicationPlugin>
@@ -58,6 +58,7 @@ export abstract class QueryBuilderFetchStructureImplementationState
58
58
  abstract get usedExplorerTreePropertyNodeIDs(): string[];
59
59
  abstract get fetchStructureValidationIssues(): string[];
60
60
  abstract get allValidationIssues(): string[];
61
+ abstract get fetchLabel(): string;
61
62
 
62
63
  abstract onClassChange(_class: Class | undefined): void;
63
64
  abstract revealCompilationError(compilationError: CompilationError): boolean;
@@ -29,6 +29,21 @@ import {
29
29
  type QueryBuilderFetchStructureImplementationState,
30
30
  } from './QueryBuilderFetchStructureImplementationState.js';
31
31
 
32
+ export const onChangeFetchStructureImplementation =
33
+ (
34
+ implementationType: FETCH_STRUCTURE_IMPLEMENTATION,
35
+ fetchStructureState: QueryBuilderFetchStructureState,
36
+ ): (() => void) =>
37
+ (): void => {
38
+ if (fetchStructureState.implementation.type !== implementationType) {
39
+ fetchStructureState.implementation.checkBeforeChangingImplementation(
40
+ () => {
41
+ fetchStructureState.changeImplementation(implementationType);
42
+ },
43
+ );
44
+ }
45
+ };
46
+
32
47
  export class QueryBuilderFetchStructureState {
33
48
  readonly queryBuilderState: QueryBuilderState;
34
49
  implementation: QueryBuilderFetchStructureImplementationState;
@@ -292,6 +292,7 @@ export class QueryBuilderGraphFetchTreeState
292
292
  setSerializationState: action,
293
293
  setChecked: action,
294
294
  initialize: action,
295
+ checkBeforeChangingImplementation: action,
295
296
  });
296
297
 
297
298
  // try to initialize the graph-fetch tree data using the setup class
@@ -304,6 +305,10 @@ export class QueryBuilderGraphFetchTreeState
304
305
  return FETCH_STRUCTURE_IMPLEMENTATION.GRAPH_FETCH;
305
306
  }
306
307
 
308
+ override get fetchLabel(): string {
309
+ return 'Class Properties';
310
+ }
311
+
307
312
  get usedExplorerTreePropertyNodeIDs(): string[] {
308
313
  if (!this.treeData) {
309
314
  return [];
@@ -154,6 +154,7 @@ export class QueryBuilderTDSState
154
154
  initializeWithQuery: action,
155
155
  setShowPostFilterPanel: action,
156
156
  setShowWindowFuncPanel: action,
157
+ checkBeforeChangingImplementation: action,
157
158
  convertDerivationProjectionObjects: flow,
158
159
  fetchDerivedReturnTypes: flow,
159
160
  });
@@ -194,6 +195,10 @@ export class QueryBuilderTDSState
194
195
  );
195
196
  }
196
197
 
198
+ override get fetchLabel(): string {
199
+ return 'Columns';
200
+ }
201
+
197
202
  override get TEMPORARY__showPostFetchStructurePanel(): boolean {
198
203
  return (
199
204
  this.queryBuilderState.filterState.showPanel ||