@platforma-sdk/workflow-tengo 6.17.3 → 6.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -0
- package/dist/tengo/lib/pframes.bundle.lib.tengo +30 -5
- package/dist/tengo/lib/pframes.table-builder.lib.tengo +58 -17
- package/dist/tengo/lib/tpl.base.lib.tengo +1 -0
- package/dist/tengo/lib/v2.bquery.lib.tengo +9 -0
- package/dist/tengo/lib/v2.exports.lib.tengo +141 -0
- package/dist/tengo/lib/v2.node-rules.lib.tengo +102 -0
- package/dist/tengo/lib/v2.workflow.lib.tengo +281 -0
- package/dist/tengo/lib/workflow.bquery.lib.tengo +218 -26
- package/dist/tengo/tpl/annotations.compute.plj.gz +0 -0
- package/dist/tengo/tpl/anonymize.deanonymize.plj.gz +0 -0
- package/dist/tengo/tpl/anonymize.impl.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.create_workdir_from_storage.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.download_blob.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.run_hello_world.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.run_hello_world_py.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.upload_blob.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.upload_template.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.workdir_type_name_extractor.plj.gz +0 -0
- package/dist/tengo/tpl/exec.conda.create-env.plj.gz +0 -0
- package/dist/tengo/tpl/exec.delayed-compute-allocation.impl.plj.gz +0 -0
- package/dist/tengo/tpl/exec.exec-impl.plj.gz +0 -0
- package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
- package/dist/tengo/tpl/exec.load-software.impl.plj.gz +0 -0
- package/dist/tengo/tpl/exec.monetization_info.plj.gz +0 -0
- package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.venv-bin-path.plj.gz +0 -0
- package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.build-table.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-parquet-pcolumn-chunk.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-pframe-for-ui.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.merge-resource-maps.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.parse-to-json.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.process-pcolumn-batch-split.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.process-pcolumn-batch.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.slice-data.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
- package/dist/tengo/tpl/pt.import-dir.plj.gz +0 -0
- package/dist/tengo/tpl/pt.workflow-run.plj.gz +0 -0
- package/dist/tengo/tpl/v2.export-collection-for-ui.plj.gz +0 -0
- package/dist/tengo/tpl/v2.export-for-ui.plj.gz +0 -0
- package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
- package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
- package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
- package/dist/tengo/tpl/workflow.query-anchored.plj.gz +0 -0
- package/dist/tengo/tpl/workflow.query-context-filter.plj.gz +0 -0
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -43,5 +43,7 @@ module.exports = { Templates: {
|
|
|
43
43
|
'pframes.process-pcolumn-batch': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.process-pcolumn-batch.plj.gz') },
|
|
44
44
|
'pframes.process-pcolumn-data': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.process-pcolumn-data.plj.gz') },
|
|
45
45
|
'pframes.export-pframe': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.export-pframe.plj.gz') },
|
|
46
|
+
'v2.export-collection-for-ui': { type: 'from-file', path: require.resolve('./tengo/tpl/v2.export-collection-for-ui.plj.gz') },
|
|
47
|
+
'v2.export-for-ui': { type: 'from-file', path: require.resolve('./tengo/tpl/v2.export-for-ui.plj.gz') },
|
|
46
48
|
'pframes.export-pframe-for-ui': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.export-pframe-for-ui.plj.gz') }
|
|
47
49
|
}};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
declare type TemplateFromFile = { readonly type: "from-file"; readonly path: string; };
|
|
2
|
-
declare type TplName = "ll.get-field" | "pframes.export-parquet-pcolumn-chunk" | "pframes.export-single-pcolumn" | "pframes.import-dir" | "pframes.merge-resource-maps" | "pframes.remove-nulls" | "pt.import-dir" | "waiter.waiter" | "workdir.save" | "workflow.build-ctx" | "workflow.query-context-filter" | "anonymize.deanonymize" | "anonymize.impl" | "check_network.workdir_type_name_extractor" | "exec.delayed-compute-allocation.impl" | "exec.monetization_to_json" | "exec.python.install-deps" | "exec.python.venv-bin-path" | "pframes.export-multiple-pcolumns" | "workflow.query-anchored" | "check_network.create_workdir_from_storage" | "exec.conda.create-env" | "exec.exec-impl" | "exec.monetization_info" | "exec.python.create-venv" | "pframes.slice-data" | "check_network.download_blob" | "check_network.upload_blob" | "check_network.upload_template" | "exec.load-software.impl" | "pframes.parse-to-json" | "exec.exec" | "pt.workflow-run" | "check_network.run_hello_world" | "check_network.run_hello_world_py" | "pframes.build-table" | "pframes.xsv-export-pframe" | "pframes.xsv-import-if-not-null" | "pframes.xsv-import-map" | "annotations.compute" | "pframes.process-pcolumn-batch-split" | "pframes.process-pcolumn-batch" | "pframes.process-pcolumn-data" | "pframes.export-pframe" | "pframes.export-pframe-for-ui";
|
|
2
|
+
declare type TplName = "ll.get-field" | "pframes.export-parquet-pcolumn-chunk" | "pframes.export-single-pcolumn" | "pframes.import-dir" | "pframes.merge-resource-maps" | "pframes.remove-nulls" | "pt.import-dir" | "waiter.waiter" | "workdir.save" | "workflow.build-ctx" | "workflow.query-context-filter" | "anonymize.deanonymize" | "anonymize.impl" | "check_network.workdir_type_name_extractor" | "exec.delayed-compute-allocation.impl" | "exec.monetization_to_json" | "exec.python.install-deps" | "exec.python.venv-bin-path" | "pframes.export-multiple-pcolumns" | "workflow.query-anchored" | "check_network.create_workdir_from_storage" | "exec.conda.create-env" | "exec.exec-impl" | "exec.monetization_info" | "exec.python.create-venv" | "pframes.slice-data" | "check_network.download_blob" | "check_network.upload_blob" | "check_network.upload_template" | "exec.load-software.impl" | "pframes.parse-to-json" | "exec.exec" | "pt.workflow-run" | "check_network.run_hello_world" | "check_network.run_hello_world_py" | "pframes.build-table" | "pframes.xsv-export-pframe" | "pframes.xsv-import-if-not-null" | "pframes.xsv-import-map" | "annotations.compute" | "pframes.process-pcolumn-batch-split" | "pframes.process-pcolumn-batch" | "pframes.process-pcolumn-data" | "pframes.export-pframe" | "v2.export-collection-for-ui" | "v2.export-for-ui" | "pframes.export-pframe-for-ui";
|
|
3
3
|
declare const Templates: Record<TplName, TemplateFromFile>;
|
|
4
4
|
export { Templates };
|
package/dist/index.js
CHANGED
|
@@ -44,5 +44,7 @@ export const Templates = {
|
|
|
44
44
|
'pframes.process-pcolumn-batch': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.process-pcolumn-batch.plj.gz') },
|
|
45
45
|
'pframes.process-pcolumn-data': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.process-pcolumn-data.plj.gz') },
|
|
46
46
|
'pframes.export-pframe': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.export-pframe.plj.gz') },
|
|
47
|
+
'v2.export-collection-for-ui': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/v2.export-collection-for-ui.plj.gz') },
|
|
48
|
+
'v2.export-for-ui': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/v2.export-for-ui.plj.gz') },
|
|
47
49
|
'pframes.export-pframe-for-ui': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.export-pframe-for-ui.plj.gz') }
|
|
48
50
|
};
|
|
@@ -65,7 +65,8 @@ render := import("@platforma-sdk/workflow-tengo:render")
|
|
|
65
65
|
|
|
66
66
|
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
|
|
69
|
+
createBuilderWith := func(q, ctx) {
|
|
69
70
|
|
|
70
71
|
|
|
71
72
|
|
|
@@ -117,6 +118,9 @@ createBuilder := func(ctx) {
|
|
|
117
118
|
|
|
118
119
|
|
|
119
120
|
isGlobalRef := is_map(decodedId) && decodedId.__isRef == true
|
|
121
|
+
if isGlobalRef && maps.containsKey(q, "isRef") {
|
|
122
|
+
ll.panic("serialized value ids are not supported by this query API; add a ref {block, workflow, name} with addRef, got %v", id)
|
|
123
|
+
}
|
|
120
124
|
if isGlobalRef {
|
|
121
125
|
refKey := is_string(id) ? id : canonical.encode(decodedId)
|
|
122
126
|
if !is_undefined(queryKey) {
|
|
@@ -305,7 +309,7 @@ createBuilder := func(ctx) {
|
|
|
305
309
|
build: func() {
|
|
306
310
|
|
|
307
311
|
|
|
308
|
-
resolveResult :=
|
|
312
|
+
resolveResult := q.anchoredQuery(ctx, anchors, queries, anchoredQueryOpts)
|
|
309
313
|
|
|
310
314
|
bundle := smart.mapBuilder(pConstants.RTYPE_P_COLUMN_BUNDLE)
|
|
311
315
|
|
|
@@ -314,7 +318,7 @@ createBuilder := func(ctx) {
|
|
|
314
318
|
bundle.addRef(refKey, resolveResult.getAnchor(ref))
|
|
315
319
|
bundle.addRef(ref, resolveResult.getAnchor(ref))
|
|
316
320
|
} else {
|
|
317
|
-
bundle.addRef(refKey,
|
|
321
|
+
bundle.addRef(refKey, q.resolve(ref, ctx))
|
|
318
322
|
}
|
|
319
323
|
}
|
|
320
324
|
|
|
@@ -334,6 +338,15 @@ createBuilder := func(ctx) {
|
|
|
334
338
|
|
|
335
339
|
|
|
336
340
|
|
|
341
|
+
createBuilder := func(ctx) {
|
|
342
|
+
return createBuilderWith(bquery, ctx)
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
|
|
337
350
|
|
|
338
351
|
|
|
339
352
|
|
|
@@ -392,6 +405,17 @@ pColumnBundleUnmarshaller := func() {
|
|
|
392
405
|
|
|
393
406
|
result := bResultUnmarshaller.parse(value.getValue(), parser)
|
|
394
407
|
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
dataOf := func(r) {
|
|
412
|
+
if !ll.isMap(r) || maps.containsKey(r, "data") || !maps.containsKey(r, "ref") ||
|
|
413
|
+
!ll.isMap(r.ref) || !maps.containsKey(r.ref, "block") {
|
|
414
|
+
return r.data
|
|
415
|
+
}
|
|
416
|
+
return undefined
|
|
417
|
+
}
|
|
418
|
+
|
|
395
419
|
if is_array(result) {
|
|
396
420
|
arr := []
|
|
397
421
|
for i, r in result {
|
|
@@ -400,7 +424,7 @@ pColumnBundleUnmarshaller := func() {
|
|
|
400
424
|
el := {
|
|
401
425
|
key: k,
|
|
402
426
|
spec: r.spec,
|
|
403
|
-
data: r
|
|
427
|
+
data: dataOf(r)
|
|
404
428
|
}
|
|
405
429
|
pool[k] = el
|
|
406
430
|
arr = append(arr, el)
|
|
@@ -410,7 +434,7 @@ pColumnBundleUnmarshaller := func() {
|
|
|
410
434
|
pool[resultKey] = {
|
|
411
435
|
key: resultKey,
|
|
412
436
|
spec: result.spec,
|
|
413
|
-
data: result
|
|
437
|
+
data: dataOf(result)
|
|
414
438
|
}
|
|
415
439
|
}
|
|
416
440
|
}
|
|
@@ -611,5 +635,6 @@ pColumnBundleUnmarshaller := func() {
|
|
|
611
635
|
|
|
612
636
|
export ll.toStrict({
|
|
613
637
|
createBuilder: createBuilder,
|
|
638
|
+
createBuilderWith: createBuilderWith,
|
|
614
639
|
pColumnBundleUnmarshaller: pColumnBundleUnmarshaller
|
|
615
640
|
})
|
|
@@ -22,8 +22,6 @@
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
25
|
|
|
28
26
|
|
|
29
27
|
|
|
@@ -148,6 +146,29 @@ isQuerySpec := func(q) {
|
|
|
148
146
|
|
|
149
147
|
|
|
150
148
|
|
|
149
|
+
holdsRef := func(value, isRef) {
|
|
150
|
+
stack := [value]
|
|
151
|
+
si := 0
|
|
152
|
+
for si < len(stack) {
|
|
153
|
+
v := stack[si]
|
|
154
|
+
si += 1
|
|
155
|
+
if isRef(v) { return true }
|
|
156
|
+
if ll.isMap(v) {
|
|
157
|
+
if isResolvedColumn(v) { continue }
|
|
158
|
+
for _, child in v {
|
|
159
|
+
stack = append(stack, child)
|
|
160
|
+
}
|
|
161
|
+
} else if is_array(v) {
|
|
162
|
+
for _, child in v {
|
|
163
|
+
stack = append(stack, child)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return false
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
|
|
151
172
|
|
|
152
173
|
|
|
153
174
|
|
|
@@ -157,7 +178,16 @@ isQuerySpec := func(q) {
|
|
|
157
178
|
|
|
158
179
|
|
|
159
180
|
|
|
160
|
-
|
|
181
|
+
tableBuilderWith := func(q, format, ...ctxArg) {
|
|
182
|
+
|
|
183
|
+
unresolved := isUnresolved
|
|
184
|
+
if maps.containsKey(q, "isRef") {
|
|
185
|
+
unresolved = func(value) { return holdsRef(value, q.isRef) }
|
|
186
|
+
}
|
|
187
|
+
querySpec := func(v) {
|
|
188
|
+
return !unresolved(v) && !isResolvedColumn(v) && !isEnrichmentRef(v)
|
|
189
|
+
}
|
|
190
|
+
|
|
161
191
|
ll.assert(!is_undefined(VALID_FORMATS[format]),
|
|
162
192
|
"format must be one of [tsv, csv, parquet, ndjson], got '%s'", format)
|
|
163
193
|
|
|
@@ -194,7 +224,7 @@ tableBuilder := func(format, ...ctxArg) {
|
|
|
194
224
|
header = opts[0].header
|
|
195
225
|
}
|
|
196
226
|
|
|
197
|
-
unresolved :=
|
|
227
|
+
unresolved := unresolved(value)
|
|
198
228
|
if !unresolved {
|
|
199
229
|
ll.assert(
|
|
200
230
|
isResolvedColumn(value) ||
|
|
@@ -232,7 +262,7 @@ tableBuilder := func(format, ...ctxArg) {
|
|
|
232
262
|
header = opts[0].header
|
|
233
263
|
}
|
|
234
264
|
join := columnJoinOpt(opts)
|
|
235
|
-
if
|
|
265
|
+
if unresolved(query) || isEnrichmentRef(query) {
|
|
236
266
|
_hasUnresolved = true
|
|
237
267
|
}
|
|
238
268
|
_columns = append(_columns, {
|
|
@@ -283,7 +313,7 @@ tableBuilder := func(format, ...ctxArg) {
|
|
|
283
313
|
entrySuffix = undefined
|
|
284
314
|
}
|
|
285
315
|
|
|
286
|
-
if
|
|
316
|
+
if unresolved(entryQuery) || isEnrichmentRef(entryQuery) {
|
|
287
317
|
_hasUnresolved = true
|
|
288
318
|
}
|
|
289
319
|
_columns = append(_columns, {
|
|
@@ -298,7 +328,7 @@ tableBuilder := func(format, ...ctxArg) {
|
|
|
298
328
|
return self
|
|
299
329
|
}
|
|
300
330
|
|
|
301
|
-
if
|
|
331
|
+
if unresolved(query) || isEnrichmentRef(query) {
|
|
302
332
|
_hasUnresolved = true
|
|
303
333
|
}
|
|
304
334
|
_columns = append(_columns, {
|
|
@@ -406,7 +436,7 @@ tableBuilder := func(format, ...ctxArg) {
|
|
|
406
436
|
|
|
407
437
|
hasQuerySpec := false
|
|
408
438
|
for _, c in _columns {
|
|
409
|
-
if
|
|
439
|
+
if querySpec(c.query) {
|
|
410
440
|
hasQuerySpec = true
|
|
411
441
|
break
|
|
412
442
|
}
|
|
@@ -421,15 +451,18 @@ tableBuilder := func(format, ...ctxArg) {
|
|
|
421
451
|
|
|
422
452
|
resolveColumn := func(value) {
|
|
423
453
|
if is_string(value) {
|
|
454
|
+
if maps.containsKey(q, "isRef") {
|
|
455
|
+
ll.panic("serialized value ids are not supported by this query API; pass a ref {block, workflow, name}, got %v", value)
|
|
456
|
+
}
|
|
424
457
|
ref := decodeGlobalPObjectId(value)
|
|
425
|
-
r :=
|
|
458
|
+
r := q.resolve(ref, _ctx)
|
|
426
459
|
return {
|
|
427
460
|
spec: r.getFutureInputField("spec"),
|
|
428
461
|
data: r.getFutureInputField("data")
|
|
429
462
|
}
|
|
430
463
|
}
|
|
431
|
-
if
|
|
432
|
-
r :=
|
|
464
|
+
if unresolved(value) {
|
|
465
|
+
r := q.resolve(value, _ctx)
|
|
433
466
|
return {
|
|
434
467
|
spec: r.getFutureInputField("spec"),
|
|
435
468
|
data: r.getFutureInputField("data")
|
|
@@ -462,7 +495,7 @@ tableBuilder := func(format, ...ctxArg) {
|
|
|
462
495
|
data: resolvedCol.data,
|
|
463
496
|
filters: []
|
|
464
497
|
}
|
|
465
|
-
if
|
|
498
|
+
if unresolved(column) {
|
|
466
499
|
primaryPlRefs[p.name] = column
|
|
467
500
|
}
|
|
468
501
|
|
|
@@ -487,7 +520,7 @@ tableBuilder := func(format, ...ctxArg) {
|
|
|
487
520
|
multiQueryResultByIdx := {}
|
|
488
521
|
qMap := {}
|
|
489
522
|
for idx, c in _columns {
|
|
490
|
-
if
|
|
523
|
+
if querySpec(c.query) {
|
|
491
524
|
strategy := "expectSingle"
|
|
492
525
|
if c.mode == "multi" { strategy = "expectMultiple" }
|
|
493
526
|
qMap["q" + string(idx)] = maps.deepMerge(c.query, {
|
|
@@ -500,9 +533,9 @@ tableBuilder := func(format, ...ctxArg) {
|
|
|
500
533
|
"column query specs require at least one primary added as a PlRef " +
|
|
501
534
|
"or PrimaryRef (pre-resolved primaries cannot anchor column queries)")
|
|
502
535
|
|
|
503
|
-
qResult :=
|
|
536
|
+
qResult := q.anchoredQuery(_ctx, primaryPlRefs, qMap)
|
|
504
537
|
for idx, c in _columns {
|
|
505
|
-
if
|
|
538
|
+
if querySpec(c.query) {
|
|
506
539
|
r := qResult.getResult("q" + string(idx))
|
|
507
540
|
if c.mode == "multi" {
|
|
508
541
|
|
|
@@ -552,7 +585,7 @@ tableBuilder := func(format, ...ctxArg) {
|
|
|
552
585
|
} else if isResolvedColumn(c.query) {
|
|
553
586
|
entry.spec = c.query.spec
|
|
554
587
|
entry.data = c.query.data
|
|
555
|
-
} else if
|
|
588
|
+
} else if unresolved(c.query) {
|
|
556
589
|
resolved := resolveColumn(c.query)
|
|
557
590
|
entry.spec = resolved.spec
|
|
558
591
|
entry.data = resolved.data
|
|
@@ -646,6 +679,14 @@ tableBuilder := func(format, ...ctxArg) {
|
|
|
646
679
|
return ll.toStrict(self)
|
|
647
680
|
}
|
|
648
681
|
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
|
|
685
|
+
tableBuilder := func(format, ...ctxArg) {
|
|
686
|
+
return tableBuilderWith(bquery, format, ctxArg...)
|
|
687
|
+
}
|
|
688
|
+
|
|
649
689
|
export ll.toStrict({
|
|
650
|
-
tableBuilder: tableBuilder
|
|
690
|
+
tableBuilder: tableBuilder,
|
|
691
|
+
tableBuilderWith: tableBuilderWith
|
|
651
692
|
})
|
|
@@ -739,6 +739,7 @@ tpl := func(ops) {
|
|
|
739
739
|
hasInput : self.hasInput,
|
|
740
740
|
inputs : self.inputs,
|
|
741
741
|
defineOutputs : self.defineOutputs,
|
|
742
|
+
definedOutputs : func() { return copy(self.definedOutputs) },
|
|
742
743
|
setOutputCache : self.setOutputCache,
|
|
743
744
|
setOutputCacheMillis : self.setOutputCacheMillis,
|
|
744
745
|
setOutputCacheSeconds : self.setOutputCacheSeconds,
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
13
|
+
smart := import("@platforma-sdk/workflow-tengo:smart")
|
|
14
|
+
maps := import("@platforma-sdk/workflow-tengo:maps")
|
|
15
|
+
constants := import("@platforma-sdk/workflow-tengo:constants")
|
|
16
|
+
bobject := import("@platforma-sdk/workflow-tengo:workflow.bobject")
|
|
17
|
+
rules := import("@platforma-sdk/workflow-tengo:v2.node-rules")
|
|
18
|
+
|
|
19
|
+
_CONSTRUCTORS_HINT := "build it with v2.exports.folder or v2.exports.collection (or pframes.pFrameBuilder)"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
_see := func(value) {
|
|
23
|
+
if smart.isField(value) {
|
|
24
|
+
info := value.info()
|
|
25
|
+
if info.IsSet && info.Value != 0 {
|
|
26
|
+
return { kind: "resource", type: value.getValue().info().Type }
|
|
27
|
+
}
|
|
28
|
+
return { kind: "pending" }
|
|
29
|
+
}
|
|
30
|
+
if smart.isResource(value) {
|
|
31
|
+
return { kind: "resource", type: value.info().Type }
|
|
32
|
+
}
|
|
33
|
+
if ll.isMap(value) {
|
|
34
|
+
return { kind: "map", keys: maps.getKeys(value) }
|
|
35
|
+
}
|
|
36
|
+
return { kind: "other", typeName: type_name(value) }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
assertNode := func(value, what) {
|
|
48
|
+
got := rules.refusal(_see(value))
|
|
49
|
+
if !is_undefined(got) {
|
|
50
|
+
ll.panic("%s must be a typed node — a folder or a collection — or a reference to one; got %s; %s",
|
|
51
|
+
what, got, _CONSTRUCTORS_HINT)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
folder := func(entries) {
|
|
63
|
+
ll.assert(ll.isMap(entries) && !smart.isReference(entries),
|
|
64
|
+
"v2.exports.folder: expected a map of entry name to node, got %v", entries)
|
|
65
|
+
|
|
66
|
+
b := smart.mapBuilder()
|
|
67
|
+
for name in maps.getKeys(entries) {
|
|
68
|
+
rules.assertName(name, "folder entry name")
|
|
69
|
+
node := entries[name]
|
|
70
|
+
if !smart.isReference(node) && ll.isMap(node) && maps.containsKey(node, "spec") {
|
|
71
|
+
ll.panic("folder entry %q is not a node; items belong in a collection (v2.exports.collection)", name)
|
|
72
|
+
}
|
|
73
|
+
assertNode(node, "folder entry \"" + name + "\"")
|
|
74
|
+
b.add(name, node)
|
|
75
|
+
}
|
|
76
|
+
return b.build()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
_isNoResult := func(data) {
|
|
81
|
+
if smart.isField(data) {
|
|
82
|
+
info := data.info()
|
|
83
|
+
if !(info.IsSet && info.Value != 0) {
|
|
84
|
+
return false
|
|
85
|
+
}
|
|
86
|
+
data = data.getValue()
|
|
87
|
+
}
|
|
88
|
+
return smart.isResource(data) && data.checkResourceType(constants.RTYPE_BRESOLVE_NO_RESULT)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
collection := func(items) {
|
|
104
|
+
ll.assert(ll.isMap(items) && !smart.isReference(items),
|
|
105
|
+
"v2.exports.collection: expected a map of item name to {spec, data}, got %v", items)
|
|
106
|
+
|
|
107
|
+
b := smart.structBuilder(rules.COLLECTION_TYPE)
|
|
108
|
+
for name in maps.getKeys(items) {
|
|
109
|
+
rules.assertName(name, "item name")
|
|
110
|
+
item := items[name]
|
|
111
|
+
if smart.isReference(item) || !ll.isMap(item) {
|
|
112
|
+
ll.panic("item %q must be a map {spec, data}, got %v", name, item)
|
|
113
|
+
}
|
|
114
|
+
for key in maps.getKeys(item) {
|
|
115
|
+
if key != "spec" && key != "data" && key != "ref" {
|
|
116
|
+
ll.panic("item %q has key %q; an item has only spec and data", name, key)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if !maps.containsKey(item, "spec") || is_undefined(item.spec) {
|
|
121
|
+
ll.panic("item %q has no spec", name)
|
|
122
|
+
}
|
|
123
|
+
spec := item.spec
|
|
124
|
+
if !smart.isReference(spec) {
|
|
125
|
+
spec = bobject.createSpec(spec)
|
|
126
|
+
}
|
|
127
|
+
b.createInputField(name + ".spec").set(spec)
|
|
128
|
+
|
|
129
|
+
data := maps.containsKey(item, "data") ? item.data : undefined
|
|
130
|
+
if !is_undefined(data) && !_isNoResult(data) {
|
|
131
|
+
b.createInputField(name + ".data").setRefOrJson(data)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return b.lockAndBuild()
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export ll.toStrict({
|
|
138
|
+
folder: folder,
|
|
139
|
+
collection: collection,
|
|
140
|
+
assertNode: assertNode
|
|
141
|
+
})
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
10
|
+
text := import("text")
|
|
11
|
+
|
|
12
|
+
FOLDER_TYPE := { Name: "std/map", Version: "1" }
|
|
13
|
+
COLLECTION_TYPE := { Name: "PFrame", Version: "1" }
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
nameProblem := func(name) {
|
|
27
|
+
if !is_string(name) {
|
|
28
|
+
return "is not a string"
|
|
29
|
+
}
|
|
30
|
+
if name == "" {
|
|
31
|
+
return "is empty"
|
|
32
|
+
}
|
|
33
|
+
if text.contains(name, ".") {
|
|
34
|
+
return "contains \".\", which joins the names of a path"
|
|
35
|
+
}
|
|
36
|
+
if name == "resourceError" {
|
|
37
|
+
return "is reserved by the backend"
|
|
38
|
+
}
|
|
39
|
+
if text.has_prefix(name, "recovery/") {
|
|
40
|
+
return "starts with \"recovery/\", which the backend reserves"
|
|
41
|
+
}
|
|
42
|
+
return undefined
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
assertName := func(name, what) {
|
|
52
|
+
problem := nameProblem(name)
|
|
53
|
+
if !is_undefined(problem) {
|
|
54
|
+
ll.panic("%s %q %s", what, name, problem)
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
isNodeType := func(type) {
|
|
65
|
+
return (type.Name == FOLDER_TYPE.Name && type.Version == FOLDER_TYPE.Version) ||
|
|
66
|
+
(type.Name == COLLECTION_TYPE.Name && type.Version == COLLECTION_TYPE.Version)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
refusal := func(seen) {
|
|
80
|
+
if seen.kind == "pending" {
|
|
81
|
+
return undefined
|
|
82
|
+
}
|
|
83
|
+
if seen.kind == "resource" {
|
|
84
|
+
if isNodeType(seen.type) {
|
|
85
|
+
return undefined
|
|
86
|
+
}
|
|
87
|
+
return "a resource of type " + seen.type.Name + "/" + seen.type.Version
|
|
88
|
+
}
|
|
89
|
+
if seen.kind == "map" {
|
|
90
|
+
return "a map with keys [" + text.join(seen.keys, ", ") + "]"
|
|
91
|
+
}
|
|
92
|
+
return "a value of type " + seen.typeName
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export ll.toStrict({
|
|
96
|
+
FOLDER_TYPE: FOLDER_TYPE,
|
|
97
|
+
COLLECTION_TYPE: COLLECTION_TYPE,
|
|
98
|
+
nameProblem: nameProblem,
|
|
99
|
+
assertName: assertName,
|
|
100
|
+
isNodeType: isNodeType,
|
|
101
|
+
refusal: refusal
|
|
102
|
+
})
|