@hpcc-js/marshaller 2.28.7 → 2.28.8
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/LICENSE +43 -43
- package/dist/index.es6.js +25 -13
- package/dist/index.es6.js.map +1 -1
- package/dist/index.js +25 -13
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/package.json +12 -12
- package/src/__package__.ts +3 -3
- package/src/dashy.css +239 -239
- package/src/dashy.ts +521 -521
- package/src/ddl1/DDLApi.ts +229 -229
- package/src/ddl1/FlyoutButton.ts +120 -120
- package/src/ddl1/Graph.ts +93 -93
- package/src/ddl1/HTML.ts +77 -77
- package/src/ddl1/HipieDDL.ts +2437 -2437
- package/src/ddl1/HipieDDLMixin.ts +380 -380
- package/src/ddl1/Tabbed.ts +91 -91
- package/src/ddl1/TargetMarshaller.ts +57 -57
- package/src/ddl2/PopupManager.ts +89 -89
- package/src/ddl2/activities/activity.ts +431 -431
- package/src/ddl2/activities/databomb.ts +237 -237
- package/src/ddl2/activities/datasource.ts +52 -52
- package/src/ddl2/activities/dspicker.ts +106 -106
- package/src/ddl2/activities/filter.ts +542 -542
- package/src/ddl2/activities/form.ts +153 -153
- package/src/ddl2/activities/groupby.ts +439 -439
- package/src/ddl2/activities/hipiepipeline.ts +114 -114
- package/src/ddl2/activities/limit.ts +49 -49
- package/src/ddl2/activities/logicalfile.ts +62 -62
- package/src/ddl2/activities/nullview.ts +12 -12
- package/src/ddl2/activities/project.ts +764 -764
- package/src/ddl2/activities/rest.ts +568 -568
- package/src/ddl2/activities/roxie.ts +490 -490
- package/src/ddl2/activities/sampledata.json +16264 -16264
- package/src/ddl2/activities/sort.ts +176 -176
- package/src/ddl2/activities/wuresult.ts +395 -395
- package/src/ddl2/dashboard.css +13 -13
- package/src/ddl2/dashboard.ts +330 -330
- package/src/ddl2/dashboardDockPanel.ts +123 -123
- package/src/ddl2/dashboardGrid.ts +202 -202
- package/src/ddl2/ddl.ts +410 -410
- package/src/ddl2/ddleditor.ts +60 -60
- package/src/ddl2/dsTable.ts +238 -238
- package/src/ddl2/dvTable.ts +31 -31
- package/src/ddl2/graphadapter.ts +297 -297
- package/src/ddl2/javascriptadapter.ts +354 -354
- package/src/ddl2/model/element.ts +398 -398
- package/src/ddl2/model/visualization.ts +351 -351
- package/src/ddl2/model/vizChartPanel.ts +149 -149
- package/src/ddl2/pipelinePanel.css +4 -4
- package/src/ddl2/pipelinePanel.ts +465 -465
- package/src/index.ts +26 -26
- package/types/__package__.d.ts +2 -2
- package/types-3.4/__package__.d.ts +2 -2
|
@@ -1,568 +1,568 @@
|
|
|
1
|
-
import { PropertyExt, publish } from "@hpcc-js/common";
|
|
2
|
-
import { createConnection } from "@hpcc-js/comms";
|
|
3
|
-
import { DDL2 } from "@hpcc-js/ddl-shim";
|
|
4
|
-
import { AsyncOrderedQueue, compare, hashSum } from "@hpcc-js/util";
|
|
5
|
-
import { Element, ElementContainer } from "../model/element";
|
|
6
|
-
import { IActivityError, ReferencedFields } from "./activity";
|
|
7
|
-
import { rowToFields } from "./databomb";
|
|
8
|
-
import { Datasource, DatasourceRef } from "./datasource";
|
|
9
|
-
|
|
10
|
-
export class RestField extends PropertyExt {
|
|
11
|
-
protected _owner: RestService;
|
|
12
|
-
|
|
13
|
-
@publish("", "string", "RestField Label")
|
|
14
|
-
fieldID: publish<this, string>;
|
|
15
|
-
|
|
16
|
-
constructor() {
|
|
17
|
-
super();
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
toDDL(): DDL2.IFieldString {
|
|
21
|
-
return {
|
|
22
|
-
type: "string",
|
|
23
|
-
id: this.fieldID()
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
fromDDL(ddl: DDL2.IFieldString): this {
|
|
28
|
-
return this
|
|
29
|
-
.fieldID(ddl.id)
|
|
30
|
-
;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
static fromDDL(ddl: DDL2.IFieldString): RestField {
|
|
34
|
-
return new RestField().fromDDL(ddl);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
owner(): RestService;
|
|
38
|
-
owner(_: RestService): this;
|
|
39
|
-
owner(_?: RestService): RestService | this {
|
|
40
|
-
if (!arguments.length) return this._owner;
|
|
41
|
-
this._owner = _;
|
|
42
|
-
return this;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
valid(): boolean {
|
|
46
|
-
return !!this.fieldID();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export class RestService extends Datasource {
|
|
51
|
-
|
|
52
|
-
private _responseFields: { [outputID: string]: DDL2.IField[] } = {};
|
|
53
|
-
|
|
54
|
-
@publish("", "string", "REST Url")
|
|
55
|
-
url: publish<this, string>;
|
|
56
|
-
@publish("", "string", "Query Set")
|
|
57
|
-
action: publish<this, string>;
|
|
58
|
-
@publish("get", "set", "Request mode", ["get", "post"])
|
|
59
|
-
mode: publish<this, "get" | "post">;
|
|
60
|
-
@publish([], "propertyArray", "Multi Fields", null, { autoExpand: RestField })
|
|
61
|
-
requestFields: publish<this, RestField[]>;
|
|
62
|
-
|
|
63
|
-
constructor(readonly _ec: ElementContainer) {
|
|
64
|
-
super();
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
toDDL(): DDL2.IRestService {
|
|
68
|
-
return {
|
|
69
|
-
type: "rest",
|
|
70
|
-
id: this.id(),
|
|
71
|
-
url: this.url(),
|
|
72
|
-
action: this.action(),
|
|
73
|
-
mode: this.mode(),
|
|
74
|
-
inputs: this.validRequestFields().map(rf => rf.toDDL()),
|
|
75
|
-
outputs: this.outputDDL()
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
fromDDL(ddl: DDL2.IRestService, skipID = false): this {
|
|
80
|
-
(skipID ? this : this.id(ddl.id))
|
|
81
|
-
.url(ddl.url)
|
|
82
|
-
.action(ddl.action)
|
|
83
|
-
.mode(ddl.mode || "get")
|
|
84
|
-
.requestFields(ddl.inputs.map(RestField.fromDDL))
|
|
85
|
-
;
|
|
86
|
-
for (const key in ddl.outputs) {
|
|
87
|
-
this.responseFields(key, ddl.outputs[key].fields);
|
|
88
|
-
}
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
static fromDDL(ec: ElementContainer, ddl: DDL2.IRestService, skipID = false): RestService {
|
|
93
|
-
return new RestService(ec).fromDDL(ddl, skipID);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
hash(more: object = {}): string {
|
|
97
|
-
return hashSum({
|
|
98
|
-
url: this.url(),
|
|
99
|
-
action: this.action(),
|
|
100
|
-
mode: this.mode(),
|
|
101
|
-
...more
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
label(): string {
|
|
106
|
-
return this.action();
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
responseFields(resultName: string): DDL2.IField[];
|
|
110
|
-
responseFields(resultName: string, _: DDL2.IField[]): this;
|
|
111
|
-
responseFields(resultName: string, _?: DDL2.IField[]): DDL2.IField[] | this {
|
|
112
|
-
if (arguments.length === 1) return this._responseFields[resultName] || [];
|
|
113
|
-
this._responseFields[resultName] = _;
|
|
114
|
-
return this;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
validRequestFields(): RestField[] {
|
|
118
|
-
return this.requestFields().filter(f => f.valid());
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
private _prevRequestHash;
|
|
122
|
-
private _prevPromise;
|
|
123
|
-
private _submitQ = new AsyncOrderedQueue();
|
|
124
|
-
submit(request: { [key: string]: any }): Promise<{ [key: string]: any }> {
|
|
125
|
-
const requestHash = hashSum(request);
|
|
126
|
-
if (!this._prevPromise || this._prevRequestHash !== requestHash) {
|
|
127
|
-
this._prevRequestHash = requestHash;
|
|
128
|
-
const conn = createConnection({ baseUrl: this.url(), type: this.mode() });
|
|
129
|
-
this._prevPromise = this._submitQ.push(conn.send(this.action(), request));
|
|
130
|
-
}
|
|
131
|
-
return this._prevPromise;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
resultNames(): string[] {
|
|
135
|
-
const retVal: string[] = [];
|
|
136
|
-
for (const key in this._responseFields) {
|
|
137
|
-
retVal.push(key);
|
|
138
|
-
}
|
|
139
|
-
return retVal;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
outputDDL(): DDL2.OutputDict {
|
|
143
|
-
const retVal: DDL2.OutputDict = {};
|
|
144
|
-
this.resultNames().forEach(resultName => {
|
|
145
|
-
retVal[resultName] = {
|
|
146
|
-
fields: this._responseFields[resultName]
|
|
147
|
-
};
|
|
148
|
-
});
|
|
149
|
-
return retVal;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
RestService.prototype._class += " RestService";
|
|
153
|
-
|
|
154
|
-
export class RestResult extends Datasource {
|
|
155
|
-
|
|
156
|
-
@publish(null, "widget", "Rest service")
|
|
157
|
-
_service: RestService = new RestService(this._ec);
|
|
158
|
-
service(): RestService;
|
|
159
|
-
service(_: RestService): this;
|
|
160
|
-
service(_?: RestService): this | RestService {
|
|
161
|
-
if (!arguments.length) return this._service;
|
|
162
|
-
this._service = _;
|
|
163
|
-
this._service.refreshMeta();
|
|
164
|
-
return this;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
@publish("", "string", "Result Name")
|
|
168
|
-
resultName: publish<this, string>;
|
|
169
|
-
|
|
170
|
-
constructor(private _ec: ElementContainer) {
|
|
171
|
-
super();
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
validRequestFields(): RestField[] {
|
|
175
|
-
return this.service().validRequestFields();
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
toDDL(): DDL2.IRestService {
|
|
179
|
-
return this.service().toDDL();
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
fromDDL(ddl: DDL2.IRestService): this {
|
|
183
|
-
this.service().fromDDL(ddl);
|
|
184
|
-
return this;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
static fromDDL(ec: ElementContainer, rs: RestService, resultName: string): RestResult {
|
|
188
|
-
return new RestResult(ec)
|
|
189
|
-
.id(`${rs.id()}_${resultName}`)
|
|
190
|
-
.service(rs)
|
|
191
|
-
.resultName(resultName)
|
|
192
|
-
;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
serviceID(): string {
|
|
196
|
-
return `${this.service().url()}/${this.service().action()}}`;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
sourceHash(): string {
|
|
200
|
-
return this.service().hash();
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
requestFields(): DDL2.IField[] {
|
|
204
|
-
return this.service().requestFields().map(rf => rf.toDDL());
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
responseFields(): DDL2.IField[];
|
|
208
|
-
responseFields(_: DDL2.IField[]): this;
|
|
209
|
-
responseFields(_?: DDL2.IField[]): this | DDL2.IField[] {
|
|
210
|
-
if (!arguments.length) return this.service().responseFields(this.resultName());
|
|
211
|
-
this.service().responseFields(this.resultName(), _);
|
|
212
|
-
return this;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
hash(more: object = {}): string {
|
|
216
|
-
return hashSum({
|
|
217
|
-
source: this.sourceHash(),
|
|
218
|
-
resultName: this.resultName(),
|
|
219
|
-
...more
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
label(): string {
|
|
224
|
-
return `${this.service().label()}\n${this.resultName()}`;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
private _jsonData: object[] = [];
|
|
228
|
-
private jsonDataFields(): DDL2.IField[] {
|
|
229
|
-
if (!this._jsonData || !this._jsonData.length) return [];
|
|
230
|
-
const retVal = rowToFields(this._jsonData[0], this._jsonData);
|
|
231
|
-
this.responseFields(retVal);
|
|
232
|
-
return retVal;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
computeFields(inFields: ReadonlyArray<DDL2.IField>): () => ReadonlyArray<DDL2.IField> {
|
|
236
|
-
return () => this.jsonDataFields();
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
computeData(): ReadonlyArray<object> {
|
|
240
|
-
return this._jsonData;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
submit(request: { [key: string]: any }): Promise<{ [key: string]: any }> {
|
|
244
|
-
return this.service().submit(request).then(response => {
|
|
245
|
-
const resultName = this.resultName();
|
|
246
|
-
const resultFields = resultName ? resultName.split(".") : [];
|
|
247
|
-
for (const field of resultFields) {
|
|
248
|
-
response = (response || {})[field];
|
|
249
|
-
}
|
|
250
|
-
this._jsonData = response as object[];
|
|
251
|
-
return response;
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
formatRequest() {
|
|
256
|
-
const request = {};
|
|
257
|
-
this.service().validRequestFields().forEach(f => {
|
|
258
|
-
request[f.fieldID()] = "";
|
|
259
|
-
});
|
|
260
|
-
return request;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
exec(): Promise<void> {
|
|
264
|
-
return this.submit(this.formatRequest()).then(response => { });
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
RestResult.prototype._class += " RestResult";
|
|
268
|
-
|
|
269
|
-
export class Param extends PropertyExt {
|
|
270
|
-
|
|
271
|
-
@publish(null, "string", "Label") // TODO Add ReadOnly
|
|
272
|
-
localField: publish<this, string>;
|
|
273
|
-
localField_exists: () => boolean;
|
|
274
|
-
@publish(null, "set", "Activity", function (this: Param) { return this.visualizationIDs(); }, {
|
|
275
|
-
optional: true,
|
|
276
|
-
disable: (w: Param): boolean => w.value_exists(),
|
|
277
|
-
validate: (w: Param): boolean => w.source_disabled() || w.visualizationIDs().indexOf(w.source()) >= 0
|
|
278
|
-
})
|
|
279
|
-
source: publish<this, string>;
|
|
280
|
-
source_exists: () => boolean;
|
|
281
|
-
source_valid: () => boolean;
|
|
282
|
-
source_disabled: () => boolean;
|
|
283
|
-
@publish(null, "set", "Source Field", function (this: Param) { return this.sourceFields(); }, {
|
|
284
|
-
optional: true,
|
|
285
|
-
disable: (w: Param): boolean => !w.source_exists() || w.value_exists(),
|
|
286
|
-
validate: (w: Param): boolean => w.remoteField_disabled() || w.sourceFields().indexOf(w.remoteField()) >= 0
|
|
287
|
-
})
|
|
288
|
-
remoteField: publish<this, string>;
|
|
289
|
-
remoteField_exists: () => boolean;
|
|
290
|
-
remoteField_valid: () => boolean;
|
|
291
|
-
remoteField_disabled: () => boolean;
|
|
292
|
-
@publish(null, "string", "Static Value", null, {
|
|
293
|
-
optional: true,
|
|
294
|
-
disable: (w: Param): boolean => w.source_exists(),
|
|
295
|
-
validate: (w: Param): boolean => w.value_disabled() || w.value_exists()
|
|
296
|
-
})
|
|
297
|
-
value: publish<this, string>;
|
|
298
|
-
value_exists: () => boolean;
|
|
299
|
-
value_valid: () => boolean;
|
|
300
|
-
value_disabled: () => boolean;
|
|
301
|
-
|
|
302
|
-
validate(prefix: string): IActivityError[] {
|
|
303
|
-
const retVal: IActivityError[] = [];
|
|
304
|
-
if (!this.source_valid()) {
|
|
305
|
-
retVal.push({
|
|
306
|
-
source: `${prefix}.source.${this.source()}`,
|
|
307
|
-
msg: `Invalid source: "${this.source()}"`,
|
|
308
|
-
hint: `expected: ${JSON.stringify(this.visualizationIDs())}`
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
if (!this.remoteField_valid()) {
|
|
312
|
-
retVal.push({
|
|
313
|
-
source: `${prefix}.remoteField`,
|
|
314
|
-
msg: `Invalid remoteField: "${this.remoteField()}"`,
|
|
315
|
-
hint: `expected: ${JSON.stringify(this.sourceOutFields())}`
|
|
316
|
-
});
|
|
317
|
-
}
|
|
318
|
-
if (!this.value_valid()) {
|
|
319
|
-
retVal.push({
|
|
320
|
-
source: `${prefix}.value`,
|
|
321
|
-
msg: `Invalid value: "${this.value()}"`,
|
|
322
|
-
hint: "expected: any value."
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
return retVal;
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
constructor(private _ec: ElementContainer) {
|
|
329
|
-
super();
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
toDDL(): DDL2.IRequestField {
|
|
333
|
-
return {
|
|
334
|
-
source: this.source(),
|
|
335
|
-
remoteFieldID: this.remoteField(),
|
|
336
|
-
localFieldID: this.localField(),
|
|
337
|
-
value: this.value()
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
fromDDL(ddl: DDL2.IRequestField): this {
|
|
342
|
-
return this
|
|
343
|
-
.source(ddl.source)
|
|
344
|
-
.remoteField(ddl.remoteFieldID)
|
|
345
|
-
.localField(ddl.localFieldID)
|
|
346
|
-
.value(ddl.value)
|
|
347
|
-
;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
static fromDDL(ec: ElementContainer, ddl: DDL2.IRequestField): Param {
|
|
351
|
-
return new Param(ec).fromDDL(ddl);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
hash() {
|
|
355
|
-
return hashSum({
|
|
356
|
-
label: this.localField(),
|
|
357
|
-
source: this.source(),
|
|
358
|
-
sourceField: this.remoteField()
|
|
359
|
-
});
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
visualizationIDs() {
|
|
363
|
-
return this._ec.elementIDs();
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
sourceFields() {
|
|
367
|
-
return this.sourceOutFields().map(field => field.id);
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
sourceViz(): Element {
|
|
371
|
-
return this._ec.element(this.source());
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
sourceOutFields(): ReadonlyArray<DDL2.IField> {
|
|
375
|
-
return this.sourceViz().hipiePipeline().selectionFields();
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
sourceSelection(): any[] {
|
|
379
|
-
return this.sourceViz().selection();
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
calcValue(): Array<string | number | boolean> {
|
|
383
|
-
if (this.source_exists() && this.remoteField_exists()) {
|
|
384
|
-
const sourceSelection = this.sourceSelection();
|
|
385
|
-
return sourceSelection.map(row => row[this.remoteField()]);
|
|
386
|
-
} else if (this.value_exists()) {
|
|
387
|
-
return [this.value()];
|
|
388
|
-
}
|
|
389
|
-
return [""];
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
exists(): boolean {
|
|
393
|
-
return this.localField_exists() && ((this.source_exists() && this.remoteField_exists()) || this.value_exists());
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
Param.prototype._class += " Param";
|
|
397
|
-
|
|
398
|
-
export class RestResultRef extends DatasourceRef {
|
|
399
|
-
|
|
400
|
-
serviceID(): string {
|
|
401
|
-
return this.datasource().serviceID();
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
private _data: ReadonlyArray<object> = [];
|
|
405
|
-
|
|
406
|
-
datasource(): RestResult;
|
|
407
|
-
datasource(_: RestResult): this;
|
|
408
|
-
datasource(_?: RestResult): this | RestResult {
|
|
409
|
-
return super.datasource.apply(this, arguments);
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
url(): string {
|
|
413
|
-
return this.datasource().service().url();
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
action(): string {
|
|
417
|
-
return this.datasource().service().action();
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
resultName(): string {
|
|
421
|
-
return this.datasource().resultName();
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
@publish([], "propertyArray", "Request Fields")
|
|
425
|
-
_request: Param[];
|
|
426
|
-
request(): Param[];
|
|
427
|
-
request(_: Param[]): this;
|
|
428
|
-
request(_?: Param[]): Param[] | this {
|
|
429
|
-
if (!arguments.length) return this._request;
|
|
430
|
-
this._request = _;
|
|
431
|
-
return this;
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
validate(): IActivityError[] {
|
|
435
|
-
let retVal: IActivityError[] = [];
|
|
436
|
-
for (const filter of this.validParams()) {
|
|
437
|
-
retVal = retVal.concat(filter.validate("request"));
|
|
438
|
-
}
|
|
439
|
-
return retVal;
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
constructor(private _ec: ElementContainer) {
|
|
443
|
-
super();
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
toDDL(): DDL2.IRoxieServiceRef {
|
|
447
|
-
return {
|
|
448
|
-
id: this.datasource().service().id(),
|
|
449
|
-
output: this.resultName(),
|
|
450
|
-
request: this.validParams().map((vp): DDL2.IRequestField => {
|
|
451
|
-
return {
|
|
452
|
-
source: vp.source(),
|
|
453
|
-
remoteFieldID: vp.remoteField(),
|
|
454
|
-
localFieldID: vp.localField(),
|
|
455
|
-
value: vp.value()
|
|
456
|
-
};
|
|
457
|
-
})
|
|
458
|
-
};
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
sourceHash(): string {
|
|
462
|
-
return this.datasource().hash();
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
requestFieldRefs(): DDL2.IRequestField[];
|
|
466
|
-
requestFieldRefs(_: DDL2.IRequestField[]): this;
|
|
467
|
-
requestFieldRefs(_?: DDL2.IRequestField[]): DDL2.IRequestField[] | this {
|
|
468
|
-
if (!arguments.length) return this.validParams().map(param => param.toDDL());
|
|
469
|
-
this.request(_.map(fc => Param.fromDDL(this._ec, fc)));
|
|
470
|
-
return this;
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
requestFields(): DDL2.IField[] {
|
|
474
|
-
return this.datasource().requestFields();
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
responseFields(): DDL2.IField[] {
|
|
478
|
-
return this.datasource().responseFields();
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
hash(): string {
|
|
482
|
-
return this.datasource().hash({
|
|
483
|
-
resultName: this.resultName(),
|
|
484
|
-
request: this.formatRequest()
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
|
|
488
|
-
label(): string {
|
|
489
|
-
return `${this.datasource().label()}\n${this.datasource().resultName()}`;
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
elementIDs() {
|
|
493
|
-
return this._ec.elementIDs();
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
element(source) {
|
|
497
|
-
return this._ec.element(source);
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
referencedFields(refs: ReferencedFields): void {
|
|
501
|
-
super.referencedFields(refs);
|
|
502
|
-
const localFieldIDs: string[] = [];
|
|
503
|
-
for (const param of this.validParams()) {
|
|
504
|
-
const filterSource = param.sourceViz().hipiePipeline();
|
|
505
|
-
if (!refs.inputs[this.id()]) {
|
|
506
|
-
refs.inputs[this.id()] = [];
|
|
507
|
-
}
|
|
508
|
-
refs.inputs[this.id()].push(param.localField());
|
|
509
|
-
filterSource.resolveFields(refs, [param.remoteField()]);
|
|
510
|
-
}
|
|
511
|
-
super.resolveFields(refs, localFieldIDs);
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
validParams() {
|
|
515
|
-
return this.request().filter(param => param.exists());
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
refreshMeta(): Promise<void> {
|
|
519
|
-
return this.datasource().refreshMeta().then(() => {
|
|
520
|
-
const oldParams = this.request();
|
|
521
|
-
const diffs = compare(oldParams.map(p => p.localField()), this.datasource().validRequestFields().map(ff => ff.fieldID()));
|
|
522
|
-
const newParams = oldParams.filter(op => diffs.update.indexOf(op.localField()) >= 0);
|
|
523
|
-
this.request(newParams.concat(diffs.enter.map(label => new Param(this._ec).localField(label))));
|
|
524
|
-
});
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
updatedBy(): string[] {
|
|
528
|
-
return this.validParams().map(param => param.source());
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
computeFields(inFields: ReadonlyArray<DDL2.IField>): () => ReadonlyArray<DDL2.IField> {
|
|
532
|
-
return this.datasource().computeFields(inFields);
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
formatRequest(): { [key: string]: any } {
|
|
536
|
-
const request = this.datasource().formatRequest();
|
|
537
|
-
this.request().forEach(f => {
|
|
538
|
-
if (request[f.localField()] !== undefined) {
|
|
539
|
-
request[f.localField()] = f.calcValue() || request[f.localField()];
|
|
540
|
-
}
|
|
541
|
-
});
|
|
542
|
-
return request;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
private _prevRequestHash;
|
|
546
|
-
private _prevRequestPromise;
|
|
547
|
-
exec(): Promise<void> {
|
|
548
|
-
const request = this.formatRequest();
|
|
549
|
-
const requestHash = hashSum({ hash: this.hash(), request });
|
|
550
|
-
if (this._prevRequestHash !== requestHash) {
|
|
551
|
-
this._prevRequestHash = requestHash;
|
|
552
|
-
this._prevRequestPromise = this.datasource().submit(request).then((response: { [key: string]: any }) => {
|
|
553
|
-
this._data = this.fixInt64(response);
|
|
554
|
-
return this._data;
|
|
555
|
-
});
|
|
556
|
-
}
|
|
557
|
-
return this._prevRequestPromise;
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
inData(): ReadonlyArray<object> {
|
|
561
|
-
return this._data;
|
|
562
|
-
}
|
|
563
|
-
|
|
564
|
-
computeData(): ReadonlyArray<object> {
|
|
565
|
-
return this._data;
|
|
566
|
-
}
|
|
567
|
-
}
|
|
568
|
-
RestResultRef.prototype._class += " RestResultRef";
|
|
1
|
+
import { PropertyExt, publish } from "@hpcc-js/common";
|
|
2
|
+
import { createConnection } from "@hpcc-js/comms";
|
|
3
|
+
import { DDL2 } from "@hpcc-js/ddl-shim";
|
|
4
|
+
import { AsyncOrderedQueue, compare, hashSum } from "@hpcc-js/util";
|
|
5
|
+
import { Element, ElementContainer } from "../model/element";
|
|
6
|
+
import { IActivityError, ReferencedFields } from "./activity";
|
|
7
|
+
import { rowToFields } from "./databomb";
|
|
8
|
+
import { Datasource, DatasourceRef } from "./datasource";
|
|
9
|
+
|
|
10
|
+
export class RestField extends PropertyExt {
|
|
11
|
+
protected _owner: RestService;
|
|
12
|
+
|
|
13
|
+
@publish("", "string", "RestField Label")
|
|
14
|
+
fieldID: publish<this, string>;
|
|
15
|
+
|
|
16
|
+
constructor() {
|
|
17
|
+
super();
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
toDDL(): DDL2.IFieldString {
|
|
21
|
+
return {
|
|
22
|
+
type: "string",
|
|
23
|
+
id: this.fieldID()
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
fromDDL(ddl: DDL2.IFieldString): this {
|
|
28
|
+
return this
|
|
29
|
+
.fieldID(ddl.id)
|
|
30
|
+
;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
static fromDDL(ddl: DDL2.IFieldString): RestField {
|
|
34
|
+
return new RestField().fromDDL(ddl);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
owner(): RestService;
|
|
38
|
+
owner(_: RestService): this;
|
|
39
|
+
owner(_?: RestService): RestService | this {
|
|
40
|
+
if (!arguments.length) return this._owner;
|
|
41
|
+
this._owner = _;
|
|
42
|
+
return this;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
valid(): boolean {
|
|
46
|
+
return !!this.fieldID();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class RestService extends Datasource {
|
|
51
|
+
|
|
52
|
+
private _responseFields: { [outputID: string]: DDL2.IField[] } = {};
|
|
53
|
+
|
|
54
|
+
@publish("", "string", "REST Url")
|
|
55
|
+
url: publish<this, string>;
|
|
56
|
+
@publish("", "string", "Query Set")
|
|
57
|
+
action: publish<this, string>;
|
|
58
|
+
@publish("get", "set", "Request mode", ["get", "post"])
|
|
59
|
+
mode: publish<this, "get" | "post">;
|
|
60
|
+
@publish([], "propertyArray", "Multi Fields", null, { autoExpand: RestField })
|
|
61
|
+
requestFields: publish<this, RestField[]>;
|
|
62
|
+
|
|
63
|
+
constructor(readonly _ec: ElementContainer) {
|
|
64
|
+
super();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
toDDL(): DDL2.IRestService {
|
|
68
|
+
return {
|
|
69
|
+
type: "rest",
|
|
70
|
+
id: this.id(),
|
|
71
|
+
url: this.url(),
|
|
72
|
+
action: this.action(),
|
|
73
|
+
mode: this.mode(),
|
|
74
|
+
inputs: this.validRequestFields().map(rf => rf.toDDL()),
|
|
75
|
+
outputs: this.outputDDL()
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
fromDDL(ddl: DDL2.IRestService, skipID = false): this {
|
|
80
|
+
(skipID ? this : this.id(ddl.id))
|
|
81
|
+
.url(ddl.url)
|
|
82
|
+
.action(ddl.action)
|
|
83
|
+
.mode(ddl.mode || "get")
|
|
84
|
+
.requestFields(ddl.inputs.map(RestField.fromDDL))
|
|
85
|
+
;
|
|
86
|
+
for (const key in ddl.outputs) {
|
|
87
|
+
this.responseFields(key, ddl.outputs[key].fields);
|
|
88
|
+
}
|
|
89
|
+
return this;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
static fromDDL(ec: ElementContainer, ddl: DDL2.IRestService, skipID = false): RestService {
|
|
93
|
+
return new RestService(ec).fromDDL(ddl, skipID);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
hash(more: object = {}): string {
|
|
97
|
+
return hashSum({
|
|
98
|
+
url: this.url(),
|
|
99
|
+
action: this.action(),
|
|
100
|
+
mode: this.mode(),
|
|
101
|
+
...more
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
label(): string {
|
|
106
|
+
return this.action();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
responseFields(resultName: string): DDL2.IField[];
|
|
110
|
+
responseFields(resultName: string, _: DDL2.IField[]): this;
|
|
111
|
+
responseFields(resultName: string, _?: DDL2.IField[]): DDL2.IField[] | this {
|
|
112
|
+
if (arguments.length === 1) return this._responseFields[resultName] || [];
|
|
113
|
+
this._responseFields[resultName] = _;
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
validRequestFields(): RestField[] {
|
|
118
|
+
return this.requestFields().filter(f => f.valid());
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
private _prevRequestHash;
|
|
122
|
+
private _prevPromise;
|
|
123
|
+
private _submitQ = new AsyncOrderedQueue();
|
|
124
|
+
submit(request: { [key: string]: any }): Promise<{ [key: string]: any }> {
|
|
125
|
+
const requestHash = hashSum(request);
|
|
126
|
+
if (!this._prevPromise || this._prevRequestHash !== requestHash) {
|
|
127
|
+
this._prevRequestHash = requestHash;
|
|
128
|
+
const conn = createConnection({ baseUrl: this.url(), type: this.mode() });
|
|
129
|
+
this._prevPromise = this._submitQ.push(conn.send(this.action(), request));
|
|
130
|
+
}
|
|
131
|
+
return this._prevPromise;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
resultNames(): string[] {
|
|
135
|
+
const retVal: string[] = [];
|
|
136
|
+
for (const key in this._responseFields) {
|
|
137
|
+
retVal.push(key);
|
|
138
|
+
}
|
|
139
|
+
return retVal;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
outputDDL(): DDL2.OutputDict {
|
|
143
|
+
const retVal: DDL2.OutputDict = {};
|
|
144
|
+
this.resultNames().forEach(resultName => {
|
|
145
|
+
retVal[resultName] = {
|
|
146
|
+
fields: this._responseFields[resultName]
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
return retVal;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
RestService.prototype._class += " RestService";
|
|
153
|
+
|
|
154
|
+
export class RestResult extends Datasource {
|
|
155
|
+
|
|
156
|
+
@publish(null, "widget", "Rest service")
|
|
157
|
+
_service: RestService = new RestService(this._ec);
|
|
158
|
+
service(): RestService;
|
|
159
|
+
service(_: RestService): this;
|
|
160
|
+
service(_?: RestService): this | RestService {
|
|
161
|
+
if (!arguments.length) return this._service;
|
|
162
|
+
this._service = _;
|
|
163
|
+
this._service.refreshMeta();
|
|
164
|
+
return this;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@publish("", "string", "Result Name")
|
|
168
|
+
resultName: publish<this, string>;
|
|
169
|
+
|
|
170
|
+
constructor(private _ec: ElementContainer) {
|
|
171
|
+
super();
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
validRequestFields(): RestField[] {
|
|
175
|
+
return this.service().validRequestFields();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
toDDL(): DDL2.IRestService {
|
|
179
|
+
return this.service().toDDL();
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
fromDDL(ddl: DDL2.IRestService): this {
|
|
183
|
+
this.service().fromDDL(ddl);
|
|
184
|
+
return this;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
static fromDDL(ec: ElementContainer, rs: RestService, resultName: string): RestResult {
|
|
188
|
+
return new RestResult(ec)
|
|
189
|
+
.id(`${rs.id()}_${resultName}`)
|
|
190
|
+
.service(rs)
|
|
191
|
+
.resultName(resultName)
|
|
192
|
+
;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
serviceID(): string {
|
|
196
|
+
return `${this.service().url()}/${this.service().action()}}`;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
sourceHash(): string {
|
|
200
|
+
return this.service().hash();
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
requestFields(): DDL2.IField[] {
|
|
204
|
+
return this.service().requestFields().map(rf => rf.toDDL());
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
responseFields(): DDL2.IField[];
|
|
208
|
+
responseFields(_: DDL2.IField[]): this;
|
|
209
|
+
responseFields(_?: DDL2.IField[]): this | DDL2.IField[] {
|
|
210
|
+
if (!arguments.length) return this.service().responseFields(this.resultName());
|
|
211
|
+
this.service().responseFields(this.resultName(), _);
|
|
212
|
+
return this;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
hash(more: object = {}): string {
|
|
216
|
+
return hashSum({
|
|
217
|
+
source: this.sourceHash(),
|
|
218
|
+
resultName: this.resultName(),
|
|
219
|
+
...more
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
label(): string {
|
|
224
|
+
return `${this.service().label()}\n${this.resultName()}`;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
private _jsonData: object[] = [];
|
|
228
|
+
private jsonDataFields(): DDL2.IField[] {
|
|
229
|
+
if (!this._jsonData || !this._jsonData.length) return [];
|
|
230
|
+
const retVal = rowToFields(this._jsonData[0], this._jsonData);
|
|
231
|
+
this.responseFields(retVal);
|
|
232
|
+
return retVal;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
computeFields(inFields: ReadonlyArray<DDL2.IField>): () => ReadonlyArray<DDL2.IField> {
|
|
236
|
+
return () => this.jsonDataFields();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
computeData(): ReadonlyArray<object> {
|
|
240
|
+
return this._jsonData;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
submit(request: { [key: string]: any }): Promise<{ [key: string]: any }> {
|
|
244
|
+
return this.service().submit(request).then(response => {
|
|
245
|
+
const resultName = this.resultName();
|
|
246
|
+
const resultFields = resultName ? resultName.split(".") : [];
|
|
247
|
+
for (const field of resultFields) {
|
|
248
|
+
response = (response || {})[field];
|
|
249
|
+
}
|
|
250
|
+
this._jsonData = response as object[];
|
|
251
|
+
return response;
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
formatRequest() {
|
|
256
|
+
const request = {};
|
|
257
|
+
this.service().validRequestFields().forEach(f => {
|
|
258
|
+
request[f.fieldID()] = "";
|
|
259
|
+
});
|
|
260
|
+
return request;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
exec(): Promise<void> {
|
|
264
|
+
return this.submit(this.formatRequest()).then(response => { });
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
RestResult.prototype._class += " RestResult";
|
|
268
|
+
|
|
269
|
+
export class Param extends PropertyExt {
|
|
270
|
+
|
|
271
|
+
@publish(null, "string", "Label") // TODO Add ReadOnly
|
|
272
|
+
localField: publish<this, string>;
|
|
273
|
+
localField_exists: () => boolean;
|
|
274
|
+
@publish(null, "set", "Activity", function (this: Param) { return this.visualizationIDs(); }, {
|
|
275
|
+
optional: true,
|
|
276
|
+
disable: (w: Param): boolean => w.value_exists(),
|
|
277
|
+
validate: (w: Param): boolean => w.source_disabled() || w.visualizationIDs().indexOf(w.source()) >= 0
|
|
278
|
+
})
|
|
279
|
+
source: publish<this, string>;
|
|
280
|
+
source_exists: () => boolean;
|
|
281
|
+
source_valid: () => boolean;
|
|
282
|
+
source_disabled: () => boolean;
|
|
283
|
+
@publish(null, "set", "Source Field", function (this: Param) { return this.sourceFields(); }, {
|
|
284
|
+
optional: true,
|
|
285
|
+
disable: (w: Param): boolean => !w.source_exists() || w.value_exists(),
|
|
286
|
+
validate: (w: Param): boolean => w.remoteField_disabled() || w.sourceFields().indexOf(w.remoteField()) >= 0
|
|
287
|
+
})
|
|
288
|
+
remoteField: publish<this, string>;
|
|
289
|
+
remoteField_exists: () => boolean;
|
|
290
|
+
remoteField_valid: () => boolean;
|
|
291
|
+
remoteField_disabled: () => boolean;
|
|
292
|
+
@publish(null, "string", "Static Value", null, {
|
|
293
|
+
optional: true,
|
|
294
|
+
disable: (w: Param): boolean => w.source_exists(),
|
|
295
|
+
validate: (w: Param): boolean => w.value_disabled() || w.value_exists()
|
|
296
|
+
})
|
|
297
|
+
value: publish<this, string>;
|
|
298
|
+
value_exists: () => boolean;
|
|
299
|
+
value_valid: () => boolean;
|
|
300
|
+
value_disabled: () => boolean;
|
|
301
|
+
|
|
302
|
+
validate(prefix: string): IActivityError[] {
|
|
303
|
+
const retVal: IActivityError[] = [];
|
|
304
|
+
if (!this.source_valid()) {
|
|
305
|
+
retVal.push({
|
|
306
|
+
source: `${prefix}.source.${this.source()}`,
|
|
307
|
+
msg: `Invalid source: "${this.source()}"`,
|
|
308
|
+
hint: `expected: ${JSON.stringify(this.visualizationIDs())}`
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
if (!this.remoteField_valid()) {
|
|
312
|
+
retVal.push({
|
|
313
|
+
source: `${prefix}.remoteField`,
|
|
314
|
+
msg: `Invalid remoteField: "${this.remoteField()}"`,
|
|
315
|
+
hint: `expected: ${JSON.stringify(this.sourceOutFields())}`
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
if (!this.value_valid()) {
|
|
319
|
+
retVal.push({
|
|
320
|
+
source: `${prefix}.value`,
|
|
321
|
+
msg: `Invalid value: "${this.value()}"`,
|
|
322
|
+
hint: "expected: any value."
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
return retVal;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
constructor(private _ec: ElementContainer) {
|
|
329
|
+
super();
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
toDDL(): DDL2.IRequestField {
|
|
333
|
+
return {
|
|
334
|
+
source: this.source(),
|
|
335
|
+
remoteFieldID: this.remoteField(),
|
|
336
|
+
localFieldID: this.localField(),
|
|
337
|
+
value: this.value()
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
fromDDL(ddl: DDL2.IRequestField): this {
|
|
342
|
+
return this
|
|
343
|
+
.source(ddl.source)
|
|
344
|
+
.remoteField(ddl.remoteFieldID)
|
|
345
|
+
.localField(ddl.localFieldID)
|
|
346
|
+
.value(ddl.value)
|
|
347
|
+
;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
static fromDDL(ec: ElementContainer, ddl: DDL2.IRequestField): Param {
|
|
351
|
+
return new Param(ec).fromDDL(ddl);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
hash() {
|
|
355
|
+
return hashSum({
|
|
356
|
+
label: this.localField(),
|
|
357
|
+
source: this.source(),
|
|
358
|
+
sourceField: this.remoteField()
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
visualizationIDs() {
|
|
363
|
+
return this._ec.elementIDs();
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
sourceFields() {
|
|
367
|
+
return this.sourceOutFields().map(field => field.id);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
sourceViz(): Element {
|
|
371
|
+
return this._ec.element(this.source());
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
sourceOutFields(): ReadonlyArray<DDL2.IField> {
|
|
375
|
+
return this.sourceViz().hipiePipeline().selectionFields();
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
sourceSelection(): any[] {
|
|
379
|
+
return this.sourceViz().selection();
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
calcValue(): Array<string | number | boolean> {
|
|
383
|
+
if (this.source_exists() && this.remoteField_exists()) {
|
|
384
|
+
const sourceSelection = this.sourceSelection();
|
|
385
|
+
return sourceSelection.map(row => row[this.remoteField()]);
|
|
386
|
+
} else if (this.value_exists()) {
|
|
387
|
+
return [this.value()];
|
|
388
|
+
}
|
|
389
|
+
return [""];
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
exists(): boolean {
|
|
393
|
+
return this.localField_exists() && ((this.source_exists() && this.remoteField_exists()) || this.value_exists());
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
Param.prototype._class += " Param";
|
|
397
|
+
|
|
398
|
+
export class RestResultRef extends DatasourceRef {
|
|
399
|
+
|
|
400
|
+
serviceID(): string {
|
|
401
|
+
return this.datasource().serviceID();
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
private _data: ReadonlyArray<object> = [];
|
|
405
|
+
|
|
406
|
+
datasource(): RestResult;
|
|
407
|
+
datasource(_: RestResult): this;
|
|
408
|
+
datasource(_?: RestResult): this | RestResult {
|
|
409
|
+
return super.datasource.apply(this, arguments);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
url(): string {
|
|
413
|
+
return this.datasource().service().url();
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
action(): string {
|
|
417
|
+
return this.datasource().service().action();
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
resultName(): string {
|
|
421
|
+
return this.datasource().resultName();
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
@publish([], "propertyArray", "Request Fields")
|
|
425
|
+
_request: Param[];
|
|
426
|
+
request(): Param[];
|
|
427
|
+
request(_: Param[]): this;
|
|
428
|
+
request(_?: Param[]): Param[] | this {
|
|
429
|
+
if (!arguments.length) return this._request;
|
|
430
|
+
this._request = _;
|
|
431
|
+
return this;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
validate(): IActivityError[] {
|
|
435
|
+
let retVal: IActivityError[] = [];
|
|
436
|
+
for (const filter of this.validParams()) {
|
|
437
|
+
retVal = retVal.concat(filter.validate("request"));
|
|
438
|
+
}
|
|
439
|
+
return retVal;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
constructor(private _ec: ElementContainer) {
|
|
443
|
+
super();
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
toDDL(): DDL2.IRoxieServiceRef {
|
|
447
|
+
return {
|
|
448
|
+
id: this.datasource().service().id(),
|
|
449
|
+
output: this.resultName(),
|
|
450
|
+
request: this.validParams().map((vp): DDL2.IRequestField => {
|
|
451
|
+
return {
|
|
452
|
+
source: vp.source(),
|
|
453
|
+
remoteFieldID: vp.remoteField(),
|
|
454
|
+
localFieldID: vp.localField(),
|
|
455
|
+
value: vp.value()
|
|
456
|
+
};
|
|
457
|
+
})
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
sourceHash(): string {
|
|
462
|
+
return this.datasource().hash();
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
requestFieldRefs(): DDL2.IRequestField[];
|
|
466
|
+
requestFieldRefs(_: DDL2.IRequestField[]): this;
|
|
467
|
+
requestFieldRefs(_?: DDL2.IRequestField[]): DDL2.IRequestField[] | this {
|
|
468
|
+
if (!arguments.length) return this.validParams().map(param => param.toDDL());
|
|
469
|
+
this.request(_.map(fc => Param.fromDDL(this._ec, fc)));
|
|
470
|
+
return this;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
requestFields(): DDL2.IField[] {
|
|
474
|
+
return this.datasource().requestFields();
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
responseFields(): DDL2.IField[] {
|
|
478
|
+
return this.datasource().responseFields();
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
hash(): string {
|
|
482
|
+
return this.datasource().hash({
|
|
483
|
+
resultName: this.resultName(),
|
|
484
|
+
request: this.formatRequest()
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
label(): string {
|
|
489
|
+
return `${this.datasource().label()}\n${this.datasource().resultName()}`;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
elementIDs() {
|
|
493
|
+
return this._ec.elementIDs();
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
element(source) {
|
|
497
|
+
return this._ec.element(source);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
referencedFields(refs: ReferencedFields): void {
|
|
501
|
+
super.referencedFields(refs);
|
|
502
|
+
const localFieldIDs: string[] = [];
|
|
503
|
+
for (const param of this.validParams()) {
|
|
504
|
+
const filterSource = param.sourceViz().hipiePipeline();
|
|
505
|
+
if (!refs.inputs[this.id()]) {
|
|
506
|
+
refs.inputs[this.id()] = [];
|
|
507
|
+
}
|
|
508
|
+
refs.inputs[this.id()].push(param.localField());
|
|
509
|
+
filterSource.resolveFields(refs, [param.remoteField()]);
|
|
510
|
+
}
|
|
511
|
+
super.resolveFields(refs, localFieldIDs);
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
validParams() {
|
|
515
|
+
return this.request().filter(param => param.exists());
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
refreshMeta(): Promise<void> {
|
|
519
|
+
return this.datasource().refreshMeta().then(() => {
|
|
520
|
+
const oldParams = this.request();
|
|
521
|
+
const diffs = compare(oldParams.map(p => p.localField()), this.datasource().validRequestFields().map(ff => ff.fieldID()));
|
|
522
|
+
const newParams = oldParams.filter(op => diffs.update.indexOf(op.localField()) >= 0);
|
|
523
|
+
this.request(newParams.concat(diffs.enter.map(label => new Param(this._ec).localField(label))));
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
updatedBy(): string[] {
|
|
528
|
+
return this.validParams().map(param => param.source());
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
computeFields(inFields: ReadonlyArray<DDL2.IField>): () => ReadonlyArray<DDL2.IField> {
|
|
532
|
+
return this.datasource().computeFields(inFields);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
formatRequest(): { [key: string]: any } {
|
|
536
|
+
const request = this.datasource().formatRequest();
|
|
537
|
+
this.request().forEach(f => {
|
|
538
|
+
if (request[f.localField()] !== undefined) {
|
|
539
|
+
request[f.localField()] = f.calcValue() || request[f.localField()];
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
return request;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
private _prevRequestHash;
|
|
546
|
+
private _prevRequestPromise;
|
|
547
|
+
exec(): Promise<void> {
|
|
548
|
+
const request = this.formatRequest();
|
|
549
|
+
const requestHash = hashSum({ hash: this.hash(), request });
|
|
550
|
+
if (this._prevRequestHash !== requestHash) {
|
|
551
|
+
this._prevRequestHash = requestHash;
|
|
552
|
+
this._prevRequestPromise = this.datasource().submit(request).then((response: { [key: string]: any }) => {
|
|
553
|
+
this._data = this.fixInt64(response);
|
|
554
|
+
return this._data;
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
return this._prevRequestPromise;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
inData(): ReadonlyArray<object> {
|
|
561
|
+
return this._data;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
computeData(): ReadonlyArray<object> {
|
|
565
|
+
return this._data;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
RestResultRef.prototype._class += " RestResultRef";
|