@finos/legend-application-repl 0.0.2

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.
Files changed (116) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +3 -0
  3. package/lib/Const.d.ts +25 -0
  4. package/lib/Const.d.ts.map +1 -0
  5. package/lib/Const.js +26 -0
  6. package/lib/Const.js.map +1 -0
  7. package/lib/application/LegendREPLGridClient.d.ts +27 -0
  8. package/lib/application/LegendREPLGridClient.d.ts.map +1 -0
  9. package/lib/application/LegendREPLGridClient.js +40 -0
  10. package/lib/application/LegendREPLGridClient.js.map +1 -0
  11. package/lib/application/LegendREPLGridClientApplicationConfig.d.ts +29 -0
  12. package/lib/application/LegendREPLGridClientApplicationConfig.d.ts.map +1 -0
  13. package/lib/application/LegendREPLGridClientApplicationConfig.js +33 -0
  14. package/lib/application/LegendREPLGridClientApplicationConfig.js.map +1 -0
  15. package/lib/application/LegendREPLGridClientPluginManager.d.ts +32 -0
  16. package/lib/application/LegendREPLGridClientPluginManager.d.ts.map +1 -0
  17. package/lib/application/LegendREPLGridClientPluginManager.js +46 -0
  18. package/lib/application/LegendREPLGridClientPluginManager.js.map +1 -0
  19. package/lib/components/AgGrid.d.ts +22 -0
  20. package/lib/components/AgGrid.d.ts.map +1 -0
  21. package/lib/components/AgGrid.js +43 -0
  22. package/lib/components/AgGrid.js.map +1 -0
  23. package/lib/components/Core_LegendREPLGridClientApplicationPlugin.d.ts +23 -0
  24. package/lib/components/Core_LegendREPLGridClientApplicationPlugin.d.ts.map +1 -0
  25. package/lib/components/Core_LegendREPLGridClientApplicationPlugin.js +35 -0
  26. package/lib/components/Core_LegendREPLGridClientApplicationPlugin.js.map +1 -0
  27. package/lib/components/LegendREPLGridClientApplication.d.ts +24 -0
  28. package/lib/components/LegendREPLGridClientApplication.d.ts.map +1 -0
  29. package/lib/components/LegendREPLGridClientApplication.js +32 -0
  30. package/lib/components/LegendREPLGridClientApplication.js.map +1 -0
  31. package/lib/components/LegendREPLGridClientFrameworkProvider.d.ts +22 -0
  32. package/lib/components/LegendREPLGridClientFrameworkProvider.d.ts.map +1 -0
  33. package/lib/components/LegendREPLGridClientFrameworkProvider.js +29 -0
  34. package/lib/components/LegendREPLGridClientFrameworkProvider.js.map +1 -0
  35. package/lib/components/REPLGridClient.d.ts +18 -0
  36. package/lib/components/REPLGridClient.d.ts.map +1 -0
  37. package/lib/components/REPLGridClient.js +56 -0
  38. package/lib/components/REPLGridClient.js.map +1 -0
  39. package/lib/components/REPLGridClientStoreProvider.d.ts +22 -0
  40. package/lib/components/REPLGridClientStoreProvider.d.ts.map +1 -0
  41. package/lib/components/REPLGridClientStoreProvider.js +32 -0
  42. package/lib/components/REPLGridClientStoreProvider.js.map +1 -0
  43. package/lib/components/grid/GridUtils.d.ts +29 -0
  44. package/lib/components/grid/GridUtils.d.ts.map +1 -0
  45. package/lib/components/grid/GridUtils.js +152 -0
  46. package/lib/components/grid/GridUtils.js.map +1 -0
  47. package/lib/components/grid/REPLGridServerResult.d.ts +22 -0
  48. package/lib/components/grid/REPLGridServerResult.d.ts.map +1 -0
  49. package/lib/components/grid/REPLGridServerResult.js +26 -0
  50. package/lib/components/grid/REPLGridServerResult.js.map +1 -0
  51. package/lib/components/grid/ServerSideDataSource.d.ts +32 -0
  52. package/lib/components/grid/ServerSideDataSource.d.ts.map +1 -0
  53. package/lib/components/grid/ServerSideDataSource.js +107 -0
  54. package/lib/components/grid/ServerSideDataSource.js.map +1 -0
  55. package/lib/components/grid/TDSLambdaBuilder.d.ts +19 -0
  56. package/lib/components/grid/TDSLambdaBuilder.d.ts.map +1 -0
  57. package/lib/components/grid/TDSLambdaBuilder.js +277 -0
  58. package/lib/components/grid/TDSLambdaBuilder.js.map +1 -0
  59. package/lib/components/grid/TDSRequest.d.ts +90 -0
  60. package/lib/components/grid/TDSRequest.d.ts.map +1 -0
  61. package/lib/components/grid/TDSRequest.js +120 -0
  62. package/lib/components/grid/TDSRequest.js.map +1 -0
  63. package/lib/grid.css +17 -0
  64. package/lib/grid.css.map +1 -0
  65. package/lib/index.css +17 -0
  66. package/lib/index.css.map +1 -0
  67. package/lib/index.d.ts +22 -0
  68. package/lib/index.d.ts.map +1 -0
  69. package/lib/index.js +37 -0
  70. package/lib/index.js.map +1 -0
  71. package/lib/package.json +88 -0
  72. package/lib/repl.css +17 -0
  73. package/lib/repl.css.map +1 -0
  74. package/lib/server/REPLServerClient.d.ts +28 -0
  75. package/lib/server/REPLServerClient.d.ts.map +1 -0
  76. package/lib/server/REPLServerClient.js +30 -0
  77. package/lib/server/REPLServerClient.js.map +1 -0
  78. package/lib/stores/LegendREPLGridClientApplicationPlugin.d.ts +26 -0
  79. package/lib/stores/LegendREPLGridClientApplicationPlugin.d.ts.map +1 -0
  80. package/lib/stores/LegendREPLGridClientApplicationPlugin.js +27 -0
  81. package/lib/stores/LegendREPLGridClientApplicationPlugin.js.map +1 -0
  82. package/lib/stores/LegendREPLGridClientBaseStore.d.ts +25 -0
  83. package/lib/stores/LegendREPLGridClientBaseStore.d.ts.map +1 -0
  84. package/lib/stores/LegendREPLGridClientBaseStore.js +24 -0
  85. package/lib/stores/LegendREPLGridClientBaseStore.js.map +1 -0
  86. package/lib/stores/REPLGridClientStore.d.ts +31 -0
  87. package/lib/stores/REPLGridClientStore.d.ts.map +1 -0
  88. package/lib/stores/REPLGridClientStore.js +101 -0
  89. package/lib/stores/REPLGridClientStore.js.map +1 -0
  90. package/lib/stores/REPLGridState.d.ts +38 -0
  91. package/lib/stores/REPLGridState.d.ts.map +1 -0
  92. package/lib/stores/REPLGridState.js +81 -0
  93. package/lib/stores/REPLGridState.js.map +1 -0
  94. package/package.json +88 -0
  95. package/src/Const.ts +27 -0
  96. package/src/application/LegendREPLGridClient.tsx +66 -0
  97. package/src/application/LegendREPLGridClientApplicationConfig.ts +64 -0
  98. package/src/application/LegendREPLGridClientPluginManager.ts +67 -0
  99. package/src/components/AgGrid.tsx +65 -0
  100. package/src/components/Core_LegendREPLGridClientApplicationPlugin.tsx +42 -0
  101. package/src/components/LegendREPLGridClientApplication.tsx +61 -0
  102. package/src/components/LegendREPLGridClientFrameworkProvider.tsx +63 -0
  103. package/src/components/REPLGridClient.tsx +157 -0
  104. package/src/components/REPLGridClientStoreProvider.tsx +61 -0
  105. package/src/components/grid/GridUtils.ts +190 -0
  106. package/src/components/grid/REPLGridServerResult.ts +30 -0
  107. package/src/components/grid/ServerSideDataSource.ts +184 -0
  108. package/src/components/grid/TDSLambdaBuilder.ts +413 -0
  109. package/src/components/grid/TDSRequest.ts +153 -0
  110. package/src/index.tsx +40 -0
  111. package/src/server/REPLServerClient.ts +74 -0
  112. package/src/stores/LegendREPLGridClientApplicationPlugin.ts +30 -0
  113. package/src/stores/LegendREPLGridClientBaseStore.ts +34 -0
  114. package/src/stores/REPLGridClientStore.ts +153 -0
  115. package/src/stores/REPLGridState.ts +102 -0
  116. package/tsconfig.json +66 -0
@@ -0,0 +1,413 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import {
18
+ V1_AppliedFunction,
19
+ V1_AppliedProperty,
20
+ V1_CBoolean,
21
+ V1_CDateTime,
22
+ V1_CDecimal,
23
+ V1_CFloat,
24
+ V1_CInteger,
25
+ V1_CStrictDate,
26
+ V1_CStrictTime,
27
+ V1_CString,
28
+ V1_ClassInstance,
29
+ V1_ColSpec,
30
+ V1_ColSpecArray,
31
+ V1_Collection,
32
+ V1_Lambda,
33
+ type V1_PrimitiveValueSpecification,
34
+ type V1_ValueSpecification,
35
+ V1_Variable,
36
+ PRIMITIVE_TYPE,
37
+ V1_ClassInstanceType,
38
+ } from '@finos/legend-graph';
39
+ import {
40
+ TDSFilter,
41
+ TDSFilterCondition,
42
+ type TDSGroupby,
43
+ type TDSRequest,
44
+ type TDSSort,
45
+ TDS_FILTER_GROUP,
46
+ TDS_FILTER_OPERATION,
47
+ TDS_AGGREGATION_FUNCTION,
48
+ } from './TDSRequest.js';
49
+ import {
50
+ UnsupportedOperationError,
51
+ guaranteeIsBoolean,
52
+ guaranteeIsNumber,
53
+ guaranteeIsString,
54
+ guaranteeNonNullable,
55
+ } from '@finos/legend-shared';
56
+ import {
57
+ DEFAULT_VARIABLE_NAME,
58
+ FILTER_FUNCTION_NAME,
59
+ GROUPBY_FUNCTION_NAME,
60
+ NOT_FUNCTION_NAME,
61
+ SORT_FUNCTION_NAME,
62
+ } from '../../Const.js';
63
+
64
+ const getPrimitiveValueSpecification = (
65
+ type: PRIMITIVE_TYPE,
66
+ column: unknown,
67
+ ): V1_PrimitiveValueSpecification => {
68
+ switch (type) {
69
+ case PRIMITIVE_TYPE.STRING: {
70
+ const stringValue = new V1_CString();
71
+ stringValue.value = guaranteeIsString(column);
72
+ return stringValue;
73
+ }
74
+ case PRIMITIVE_TYPE.BOOLEAN: {
75
+ const booleanValue = new V1_CBoolean();
76
+ booleanValue.value = guaranteeIsBoolean(column);
77
+ return booleanValue;
78
+ }
79
+ case PRIMITIVE_TYPE.NUMBER:
80
+ case PRIMITIVE_TYPE.DECIMAL: {
81
+ const cDecimal = new V1_CDecimal();
82
+ cDecimal.value = guaranteeIsNumber(column);
83
+ return cDecimal;
84
+ }
85
+ case PRIMITIVE_TYPE.INTEGER: {
86
+ const cInteger = new V1_CInteger();
87
+ cInteger.value = guaranteeIsNumber(column);
88
+ return cInteger;
89
+ }
90
+ case PRIMITIVE_TYPE.FLOAT: {
91
+ const cFloat = new V1_CFloat();
92
+ cFloat.value = guaranteeIsNumber(column);
93
+ return cFloat;
94
+ }
95
+ case PRIMITIVE_TYPE.DATE:
96
+ case PRIMITIVE_TYPE.DATETIME: {
97
+ const cDateTime = new V1_CDateTime();
98
+ cDateTime.value = guaranteeIsString(column);
99
+ return cDateTime;
100
+ }
101
+ case PRIMITIVE_TYPE.STRICTDATE: {
102
+ const cStrictDate = new V1_CStrictDate();
103
+ cStrictDate.value = guaranteeIsString(column);
104
+ return cStrictDate;
105
+ }
106
+ case PRIMITIVE_TYPE.STRICTTIME: {
107
+ const cStrictTime = new V1_CStrictTime();
108
+ cStrictTime.value = guaranteeIsString(column);
109
+ return cStrictTime;
110
+ }
111
+ default:
112
+ throw new UnsupportedOperationError(
113
+ `Unsupported tds column type ${type}`,
114
+ );
115
+ }
116
+ };
117
+
118
+ const updateParentFunction = (
119
+ expressions: V1_ValueSpecification[],
120
+ functionName: string,
121
+ child: V1_ValueSpecification[],
122
+ ): void => {
123
+ let newExpressions: V1_ValueSpecification[] = [
124
+ guaranteeNonNullable(expressions[0]),
125
+ ];
126
+ newExpressions = newExpressions.concat(child);
127
+ const childFunc = new V1_AppliedFunction();
128
+ childFunc.function = functionName;
129
+ childFunc.parameters = newExpressions;
130
+ expressions[0] = childFunc;
131
+ };
132
+
133
+ const processFilterOperations = (
134
+ expressions: V1_ValueSpecification[],
135
+ filters: TDSFilter[],
136
+ ): void => {
137
+ if (filters.length === 0) {
138
+ return;
139
+ }
140
+ const filterLambda = new V1_Lambda();
141
+ filters.forEach((filterValue) => {
142
+ const conditions = filterValue.conditions;
143
+ const groupCondition = filterValue.groupOperation;
144
+ const defaultVariable = new V1_Variable();
145
+ defaultVariable.name = DEFAULT_VARIABLE_NAME;
146
+ const conditionExpressions: V1_ValueSpecification[] = [];
147
+ conditions.forEach((condition) => {
148
+ const filterCondition = new V1_AppliedFunction();
149
+ const property = new V1_AppliedProperty();
150
+ property.property = filterValue.column;
151
+ property.class = filterValue.columnType;
152
+ property.parameters = [defaultVariable];
153
+
154
+ switch (condition.operation) {
155
+ case TDS_FILTER_OPERATION.EQUALS:
156
+ case TDS_FILTER_OPERATION.GREATER_THAN:
157
+ case TDS_FILTER_OPERATION.GREATER_THAN_OR_EQUAL:
158
+ case TDS_FILTER_OPERATION.LESS_THAN:
159
+ case TDS_FILTER_OPERATION.LESS_THAN_OR_EQUAL:
160
+ case TDS_FILTER_OPERATION.CONTAINS:
161
+ case TDS_FILTER_OPERATION.ENDS_WITH:
162
+ case TDS_FILTER_OPERATION.STARTS_WITH: {
163
+ filterCondition.function = condition.operation;
164
+ filterCondition.parameters.push(property);
165
+ filterCondition.parameters.push(
166
+ getPrimitiveValueSpecification(
167
+ filterValue.columnType,
168
+ condition.value,
169
+ ),
170
+ );
171
+ break;
172
+ }
173
+ case TDS_FILTER_OPERATION.BLANK: {
174
+ filterCondition.function = condition.operation;
175
+ filterCondition.parameters.push(property);
176
+ break;
177
+ }
178
+ case TDS_FILTER_OPERATION.NOT_EQUAL: {
179
+ filterCondition.function = NOT_FUNCTION_NAME;
180
+
181
+ const filterConditionFunc = new V1_AppliedFunction();
182
+ filterConditionFunc.function = TDS_FILTER_OPERATION.EQUALS;
183
+ filterConditionFunc.parameters.push(property);
184
+ filterConditionFunc.parameters.push(
185
+ getPrimitiveValueSpecification(
186
+ filterValue.columnType,
187
+ condition.value,
188
+ ),
189
+ );
190
+
191
+ filterCondition.parameters.push(filterConditionFunc);
192
+ break;
193
+ }
194
+ case TDS_FILTER_OPERATION.NOT_BLANK: {
195
+ filterCondition.function = NOT_FUNCTION_NAME;
196
+
197
+ const filterConditionFunc = new V1_AppliedFunction();
198
+ filterConditionFunc.function = TDS_FILTER_OPERATION.BLANK;
199
+ filterConditionFunc.parameters.push(property);
200
+ filterConditionFunc.parameters.push(
201
+ getPrimitiveValueSpecification(
202
+ filterValue.columnType,
203
+ condition.value,
204
+ ),
205
+ );
206
+
207
+ filterCondition.parameters.push(filterConditionFunc);
208
+ break;
209
+ }
210
+ case TDS_FILTER_OPERATION.NOT_CONTAINS: {
211
+ filterCondition.function = NOT_FUNCTION_NAME;
212
+
213
+ const filterConditionFunc = new V1_AppliedFunction();
214
+ filterConditionFunc.function = TDS_FILTER_OPERATION.CONTAINS;
215
+ filterConditionFunc.parameters.push(property);
216
+ filterConditionFunc.parameters.push(
217
+ getPrimitiveValueSpecification(
218
+ filterValue.columnType,
219
+ condition.value,
220
+ ),
221
+ );
222
+
223
+ filterCondition.parameters.push(filterConditionFunc);
224
+ break;
225
+ }
226
+ default:
227
+ throw new UnsupportedOperationError(
228
+ `Unsupported filter operation ${condition.operation}`,
229
+ );
230
+ }
231
+ conditionExpressions.push(filterCondition);
232
+ });
233
+ if (conditionExpressions.length > 1) {
234
+ const groupFunc = new V1_AppliedFunction();
235
+ groupFunc.function = groupCondition;
236
+ groupFunc.parameters = conditionExpressions;
237
+ filterLambda.body.push(groupFunc);
238
+ } else {
239
+ filterLambda.body = filterLambda.body.concat(conditionExpressions);
240
+ }
241
+
242
+ if (filterLambda.body.length > 1) {
243
+ const andFunc = new V1_AppliedFunction();
244
+ andFunc.function = TDS_FILTER_GROUP.AND;
245
+ andFunc.parameters = filterLambda.body;
246
+ filterLambda.body = [andFunc];
247
+ }
248
+ filterLambda.parameters = [defaultVariable];
249
+ });
250
+ updateParentFunction(expressions, FILTER_FUNCTION_NAME, [filterLambda]);
251
+ };
252
+
253
+ const getAggregationColSpec = (
254
+ column: string,
255
+ functionName: TDS_AGGREGATION_FUNCTION,
256
+ columnType: PRIMITIVE_TYPE,
257
+ // Temporary. Remove it when we support groupBy with empty aggregations
258
+ columnName?: string,
259
+ ): V1_ColSpec => {
260
+ const colSpec = new V1_ColSpec();
261
+ const aggLambda = new V1_Lambda();
262
+ const property = new V1_AppliedProperty();
263
+ property.property = column;
264
+ property.class = columnType;
265
+ const defaultVariable = new V1_Variable();
266
+ defaultVariable.name = DEFAULT_VARIABLE_NAME;
267
+ property.parameters = [defaultVariable];
268
+ aggLambda.body.push(property);
269
+ aggLambda.parameters.push(defaultVariable);
270
+ colSpec.function1 = aggLambda;
271
+
272
+ const funcLambda = new V1_Lambda();
273
+ const aggFunc = new V1_AppliedFunction();
274
+ aggFunc.function = functionName;
275
+ const aggVariable = new V1_Variable();
276
+ aggVariable.name = 'agg';
277
+ funcLambda.body.push(aggFunc);
278
+ aggFunc.parameters.push(aggVariable);
279
+ funcLambda.parameters.push(aggVariable);
280
+ colSpec.function2 = funcLambda;
281
+
282
+ colSpec.name = columnName ?? column;
283
+ return colSpec;
284
+ };
285
+
286
+ const processGroupByOperations = (
287
+ expressions: V1_ValueSpecification[],
288
+ groupByOperation: TDSGroupby,
289
+ columns: string[],
290
+ ): void => {
291
+ if (!groupByOperation.columns.length) {
292
+ return;
293
+ }
294
+ const groupByInstance = new V1_ClassInstance();
295
+ groupByInstance.type = V1_ClassInstanceType.COL_SPEC_ARRAY;
296
+ const groupByColSpecArray = new V1_ColSpecArray();
297
+ const aggregationColSpecArray = new V1_ColSpecArray();
298
+ const aggregationInstance = new V1_ClassInstance();
299
+ aggregationInstance.type = V1_ClassInstanceType.COL_SPEC_ARRAY;
300
+
301
+ if (groupByOperation.groupKeys.length !== groupByOperation.columns.length) {
302
+ const groupKeys = groupByOperation.groupKeys;
303
+ const currentGroupByColumn = groupByOperation.columns[groupKeys.length];
304
+ const columnSpec = new V1_ColSpec();
305
+ columnSpec.name = guaranteeNonNullable(currentGroupByColumn);
306
+ groupByColSpecArray.colSpecs.push(columnSpec);
307
+
308
+ // Temporary. Remove it later when we support empty aggregations
309
+ if (groupByOperation.aggregations.length === 0) {
310
+ const column = guaranteeNonNullable(groupByOperation.columns[0]);
311
+ const colSpec = getAggregationColSpec(
312
+ column,
313
+ TDS_AGGREGATION_FUNCTION.COUNT,
314
+ PRIMITIVE_TYPE.STRING,
315
+ TDS_AGGREGATION_FUNCTION.COUNT,
316
+ );
317
+ aggregationColSpecArray.colSpecs.push(colSpec);
318
+ }
319
+ }
320
+
321
+ // Projecting the columns when there is an aggregation because that would end up projecting just the aggregation column
322
+ if (
323
+ groupByOperation.groupKeys.length === groupByOperation.columns.length &&
324
+ groupByOperation.aggregations.length > 0
325
+ ) {
326
+ const aggColumns = groupByOperation.aggregations.map((agg) => agg.column);
327
+ columns.forEach((column) => {
328
+ if (!aggColumns.includes(column)) {
329
+ const colSpec = new V1_ColSpec();
330
+ colSpec.name = column;
331
+ groupByColSpecArray.colSpecs.push(colSpec);
332
+ }
333
+ });
334
+ }
335
+
336
+ groupByOperation.aggregations.forEach((agg) => {
337
+ const colSpec = getAggregationColSpec(
338
+ agg.column,
339
+ agg.function,
340
+ agg.columnType,
341
+ );
342
+ aggregationColSpecArray.colSpecs.push(colSpec);
343
+ });
344
+
345
+ groupByInstance.value = groupByColSpecArray;
346
+ aggregationInstance.value = aggregationColSpecArray;
347
+
348
+ if (
349
+ groupByColSpecArray.colSpecs.length !== 0 ||
350
+ aggregationColSpecArray.colSpecs.length !== 0
351
+ ) {
352
+ updateParentFunction(expressions, GROUPBY_FUNCTION_NAME, [
353
+ groupByInstance,
354
+ aggregationInstance,
355
+ ]);
356
+ }
357
+ };
358
+
359
+ const processSortOperations = (
360
+ expressions: V1_ValueSpecification[],
361
+ sortOperations: TDSSort[],
362
+ groupBy: TDSGroupby,
363
+ ): void => {
364
+ if (sortOperations.length === 0) {
365
+ return;
366
+ }
367
+ const sortCollection = new V1_Collection();
368
+ sortOperations.forEach((sortValue) => {
369
+ if (
370
+ groupBy.columns.length === groupBy.groupKeys.length ||
371
+ groupBy.columns.indexOf(sortValue.column) === groupBy.groupKeys.length
372
+ ) {
373
+ const sortFunc = new V1_AppliedFunction();
374
+ sortFunc.function = sortValue.order;
375
+ const instance = new V1_ClassInstance();
376
+ instance.type = V1_ClassInstanceType.COL_SPEC;
377
+ const value = new V1_ColSpec();
378
+ value.name = sortValue.column;
379
+ instance.value = value;
380
+ sortFunc.parameters.push(instance);
381
+ sortCollection.values.push(sortFunc);
382
+ }
383
+ });
384
+ updateParentFunction(expressions, SORT_FUNCTION_NAME, [sortCollection]);
385
+ };
386
+
387
+ export const buildLambdaExpressions = (
388
+ funcBody: V1_ValueSpecification,
389
+ request: TDSRequest,
390
+ ): V1_Lambda => {
391
+ const groupBy = request.groupBy;
392
+ for (let index = 0; index < groupBy.groupKeys.length; index++) {
393
+ const groupFilter = new TDSFilter(
394
+ guaranteeNonNullable(groupBy.columns.at(index)),
395
+ PRIMITIVE_TYPE.STRING,
396
+ [
397
+ new TDSFilterCondition(
398
+ TDS_FILTER_OPERATION.EQUALS,
399
+ groupBy.groupKeys.at(index),
400
+ ),
401
+ ],
402
+ TDS_FILTER_GROUP.AND,
403
+ );
404
+ request.filter.push(groupFilter);
405
+ }
406
+ const expressions = [funcBody];
407
+ processFilterOperations(expressions, request.filter);
408
+ processGroupByOperations(expressions, request.groupBy, request.columns);
409
+ processSortOperations(expressions, request.sort, request.groupBy);
410
+ const lambda = new V1_Lambda();
411
+ lambda.body = expressions;
412
+ return lambda;
413
+ };
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import type { PRIMITIVE_TYPE } from '@finos/legend-graph';
18
+
19
+ export enum TDS_FILTER_OPERATION {
20
+ EQUALS = 'equal',
21
+ NOT_EQUAL = 'notEqual',
22
+ GREATER_THAN = 'greaterThan',
23
+ GREATER_THAN_OR_EQUAL = 'greaterThanOrEqual',
24
+ LESS_THAN = 'lessThan',
25
+ LESS_THAN_OR_EQUAL = 'lessThanOrEqual',
26
+ BLANK = 'isEmpty',
27
+ NOT_BLANK = 'isNotEmpty',
28
+ CONTAINS = 'contains',
29
+ NOT_CONTAINS = 'notContains',
30
+ STARTS_WITH = 'startsWith',
31
+ ENDS_WITH = 'endsWith',
32
+ }
33
+
34
+ export enum TDS_FILTER_GROUP {
35
+ AND = 'and',
36
+ OR = 'or',
37
+ }
38
+
39
+ export enum TDS_AGGREGATION_FUNCTION {
40
+ SUM = 'sum',
41
+ MIN = 'min',
42
+ MAX = 'max',
43
+ COUNT = 'count',
44
+ AVG = 'avg',
45
+ FIRST = 'first',
46
+ LAST = 'last',
47
+ }
48
+
49
+ export enum TDS_SORT_ORDER {
50
+ ASCENDING = 'ascending',
51
+ DESCENDING = 'descending',
52
+ }
53
+
54
+ export enum FILTER_TYPE {
55
+ TEXT = 'text',
56
+ NUMBER = 'number',
57
+ }
58
+
59
+ export class TDSFilterCondition {
60
+ operation!: TDS_FILTER_OPERATION;
61
+ value!: unknown;
62
+
63
+ constructor(operation: TDS_FILTER_OPERATION, value: unknown) {
64
+ this.operation = operation;
65
+ this.value = value;
66
+ }
67
+ }
68
+
69
+ export class TDSFilter {
70
+ column!: string;
71
+ columnType!: PRIMITIVE_TYPE;
72
+ conditions!: TDSFilterCondition[];
73
+ groupOperation!: TDS_FILTER_GROUP;
74
+
75
+ constructor(
76
+ column: string,
77
+ columnType: PRIMITIVE_TYPE,
78
+ conditions: TDSFilterCondition[],
79
+ groupOperation: TDS_FILTER_GROUP,
80
+ ) {
81
+ this.column = column;
82
+ this.columnType = columnType;
83
+ this.conditions = conditions;
84
+ this.groupOperation = groupOperation;
85
+ }
86
+ }
87
+
88
+ export class TDSSort {
89
+ column!: string;
90
+ order!: TDS_SORT_ORDER;
91
+
92
+ constructor(column: string, order: TDS_SORT_ORDER) {
93
+ this.column = column;
94
+ this.order = order;
95
+ }
96
+ }
97
+
98
+ export class TDSAggregation {
99
+ column!: string;
100
+ columnType!: PRIMITIVE_TYPE;
101
+ function!: TDS_AGGREGATION_FUNCTION;
102
+
103
+ constructor(
104
+ column: string,
105
+ columnType: PRIMITIVE_TYPE,
106
+ _function: TDS_AGGREGATION_FUNCTION,
107
+ ) {
108
+ this.column = column;
109
+ this.columnType = columnType;
110
+ this.function = _function;
111
+ }
112
+ }
113
+
114
+ export class TDSGroupby {
115
+ columns!: string[];
116
+ groupKeys!: string[];
117
+ aggregations!: TDSAggregation[];
118
+
119
+ constructor(
120
+ columns: string[],
121
+ groupKeys: string[],
122
+ aggregations: TDSAggregation[],
123
+ ) {
124
+ this.columns = columns;
125
+ this.groupKeys = groupKeys;
126
+ this.aggregations = aggregations;
127
+ }
128
+ }
129
+
130
+ export class TDSRequest {
131
+ startRow?: number | undefined;
132
+ endRow?: number | undefined;
133
+ columns!: string[];
134
+ filter!: TDSFilter[];
135
+ sort!: TDSSort[];
136
+ groupBy!: TDSGroupby;
137
+
138
+ constructor(
139
+ columns: string[],
140
+ filter: TDSFilter[],
141
+ sort: TDSSort[],
142
+ groupBy: TDSGroupby,
143
+ startRow?: number | undefined,
144
+ endRow?: number | undefined,
145
+ ) {
146
+ this.startRow = startRow;
147
+ this.endRow = endRow;
148
+ this.columns = columns;
149
+ this.filter = filter;
150
+ this.sort = sort;
151
+ this.groupBy = groupBy;
152
+ }
153
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { type AbstractPlugin, type AbstractPreset } from '@finos/legend-shared';
18
+ import { LegendREPLGridClient } from './application/LegendREPLGridClient.js';
19
+ import { Core_LegendREPLGridClientApplicationPlugin } from './components/Core_LegendREPLGridClientApplicationPlugin.js';
20
+
21
+ export class LegendREPLGridClientWebApplication {
22
+ static getPresetCollection(): AbstractPreset[] {
23
+ return [];
24
+ }
25
+
26
+ static getPluginCollection(): AbstractPlugin[] {
27
+ return [new Core_LegendREPLGridClientApplicationPlugin()];
28
+ }
29
+
30
+ static run(baseUrl: string): void {
31
+ LegendREPLGridClient.create()
32
+ .setup({ baseAddress: baseUrl })
33
+ .withPresets(LegendREPLGridClientWebApplication.getPresetCollection())
34
+ .withPlugins(LegendREPLGridClientWebApplication.getPluginCollection())
35
+ .start()
36
+ .catch((e: unknown) => {
37
+ throw e;
38
+ });
39
+ }
40
+ }
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import {
18
+ guaranteeNonNullable,
19
+ type NetworkClient,
20
+ type PlainObject,
21
+ } from '@finos/legend-shared';
22
+ import type { REPLGridServerResult } from '../components/grid/REPLGridServerResult.js';
23
+ import type { V1_Lambda } from '@finos/legend-graph';
24
+
25
+ export class REPLServerClient {
26
+ private readonly networkClient: NetworkClient;
27
+
28
+ constructor(networkClient: NetworkClient) {
29
+ this.networkClient = networkClient;
30
+ }
31
+
32
+ get baseUrl(): string {
33
+ return guaranteeNonNullable(
34
+ this.networkClient.baseUrl,
35
+ `REPL client has not been configured properly`,
36
+ );
37
+ }
38
+
39
+ getREPLGridServerResult = (
40
+ request: PlainObject<V1_Lambda>,
41
+ ): Promise<PlainObject<REPLGridServerResult>> =>
42
+ this.networkClient.post(
43
+ `${this.baseUrl}/gridResult`,
44
+ request,
45
+ undefined,
46
+ undefined,
47
+ );
48
+
49
+ getIntialQueryLambda = (): Promise<PlainObject<V1_Lambda>> =>
50
+ this.networkClient.get(
51
+ `${this.baseUrl}/initialLambda`,
52
+ undefined,
53
+ undefined,
54
+ undefined,
55
+ );
56
+
57
+ getInitialREPLGridServerResult = (): Promise<
58
+ PlainObject<REPLGridServerResult>
59
+ > =>
60
+ this.networkClient.get(
61
+ `${this.baseUrl}/gridResult`,
62
+ undefined,
63
+ undefined,
64
+ undefined,
65
+ );
66
+
67
+ getLicenseKey = (): Promise<string> =>
68
+ this.networkClient.get(
69
+ `${this.baseUrl}/licenseKey`,
70
+ undefined,
71
+ undefined,
72
+ undefined,
73
+ );
74
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import { LegendApplicationPlugin } from '@finos/legend-application';
18
+ import type { LegendREPLGridClientPluginManager } from '../application/LegendREPLGridClientPluginManager.js';
19
+
20
+ export abstract class LegendREPLGridClientApplicationPlugin extends LegendApplicationPlugin {
21
+ /**
22
+ * This helps to better type-check for this empty abtract type
23
+ * See https://github.com/finos/legend-studio/blob/master/docs/technical/typescript-usage.md#understand-typescript-structual-type-system
24
+ */
25
+ private readonly _$nominalTypeBrand!: 'LegendREPLGridClientApplicationPlugin';
26
+
27
+ install(pluginManager: LegendREPLGridClientPluginManager): void {
28
+ pluginManager.registerApplicationPlugin(this);
29
+ }
30
+ }