@platforma-sdk/workflow-tengo 4.11.0 → 4.13.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.d.ts +1 -1
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/dist/tengo/lib/maps.lib.tengo +8 -2
- package/dist/tengo/lib/pframes.lib.tengo +148 -30
- package/dist/tengo/lib/pframes.spec.lib.tengo +37 -3
- package/dist/tengo/lib/pt.expression.lib.tengo +206 -45
- package/dist/tengo/lib/slices.lib.tengo +1 -1
- 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.R.create-renv.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.export-multiple-pcolumns.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.parse-to-json.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/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/package.json +2 -2
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-single-pcolumn" | "pframes.import-dir" | "pframes.remove-nulls" | "waiter.waiter" | "workdir.save" | "workflow.build-ctx" | "workflow.query-anchored" | "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" | "pframes.slice-data" | "check_network.create_workdir_from_storage" | "check_network.download_blob" | "check_network.upload_blob" | "check_network.upload_template" | "exec.R.create-renv" | "exec.exec-impl" | "exec.monetization_info" | "exec.python.create-venv" | "exec.load-software.impl" | "exec.exec" | "pframes.xsv-export-pframe" | "pframes.xsv-import-if-not-null" | "pframes.xsv-import-map" | "check_network.run_hello_world" | "check_network.run_hello_world_py" | "pframes.process-pcolumn-data" | "pframes.export-pframe" | "pframes.export-pframe-for-ui";
|
|
2
|
+
declare type TplName = "ll.get-field" | "pframes.export-single-pcolumn" | "pframes.import-dir" | "pframes.remove-nulls" | "waiter.waiter" | "workdir.save" | "workflow.build-ctx" | "workflow.query-anchored" | "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" | "pframes.slice-data" | "check_network.create_workdir_from_storage" | "check_network.download_blob" | "check_network.upload_blob" | "check_network.upload_template" | "exec.R.create-renv" | "exec.exec-impl" | "exec.monetization_info" | "exec.python.create-venv" | "pframes.parse-to-json" | "exec.load-software.impl" | "exec.exec" | "pframes.xsv-export-pframe" | "pframes.xsv-import-if-not-null" | "pframes.xsv-import-map" | "check_network.run_hello_world" | "check_network.run_hello_world_py" | "pframes.process-pcolumn-data" | "pframes.export-pframe" | "pframes.export-pframe-for-ui";
|
|
3
3
|
declare const Templates: Record<TplName, TemplateFromFile>;
|
|
4
4
|
export { Templates };
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ module.exports = { Templates: {
|
|
|
24
24
|
'exec.exec-impl': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.exec-impl.plj.gz') },
|
|
25
25
|
'exec.monetization_info': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.monetization_info.plj.gz') },
|
|
26
26
|
'exec.python.create-venv': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.python.create-venv.plj.gz') },
|
|
27
|
+
'pframes.parse-to-json': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.parse-to-json.plj.gz') },
|
|
27
28
|
'exec.load-software.impl': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.load-software.impl.plj.gz') },
|
|
28
29
|
'exec.exec': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.exec.plj.gz') },
|
|
29
30
|
'pframes.xsv-export-pframe': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.xsv-export-pframe.plj.gz') },
|
package/dist/index.mjs
CHANGED
|
@@ -25,6 +25,7 @@ export const Templates = {
|
|
|
25
25
|
'exec.exec-impl': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.exec-impl.plj.gz') },
|
|
26
26
|
'exec.monetization_info': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.monetization_info.plj.gz') },
|
|
27
27
|
'exec.python.create-venv': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.python.create-venv.plj.gz') },
|
|
28
|
+
'pframes.parse-to-json': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.parse-to-json.plj.gz') },
|
|
28
29
|
'exec.load-software.impl': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.load-software.impl.plj.gz') },
|
|
29
30
|
'exec.exec': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.exec.plj.gz') },
|
|
30
31
|
'pframes.xsv-export-pframe': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.xsv-export-pframe.plj.gz') },
|
|
@@ -213,8 +213,14 @@ deepTransform = func(...maps) {
|
|
|
213
213
|
} else {
|
|
214
214
|
res[k] = result
|
|
215
215
|
}
|
|
216
|
-
} else if is_map(
|
|
217
|
-
|
|
216
|
+
} else if is_map(v) {
|
|
217
|
+
if is_map(res[k]) {
|
|
218
|
+
res[k] = deepTransform(res[k], v)
|
|
219
|
+
} else {
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
res[k] = deepTransform({}, v)
|
|
223
|
+
}
|
|
218
224
|
} else {
|
|
219
225
|
res[k] = v
|
|
220
226
|
}
|
|
@@ -20,6 +20,29 @@ pColumnData := import("@platforma-sdk/workflow-tengo:pframes.data")
|
|
|
20
20
|
llProcessTpl := assets.importTemplate("@platforma-sdk/workflow-tengo:pframes.process-pcolumn-data")
|
|
21
21
|
|
|
22
22
|
|
|
23
|
+
TSV_CONTENT_SETTINGS_SCHEMA := {
|
|
24
|
+
"axes": [{
|
|
25
|
+
"column": "string",
|
|
26
|
+
"spec": {
|
|
27
|
+
"type": "string,regex=Int|Long|Float|Double|String",
|
|
28
|
+
"name,?": "string",
|
|
29
|
+
"domain,?": { "any": "string" },
|
|
30
|
+
"annotations,?": { "any": "string" }
|
|
31
|
+
}
|
|
32
|
+
}],
|
|
33
|
+
"columns": [{
|
|
34
|
+
"column": "string",
|
|
35
|
+
"id,?": "string",
|
|
36
|
+
"spec": {
|
|
37
|
+
"valueType": "string,regex=Int|Long|Float|Double|String",
|
|
38
|
+
"name,?": "string",
|
|
39
|
+
"domain,?": { "any": "string" },
|
|
40
|
+
"annotations,?": { "any": "string" }
|
|
41
|
+
}
|
|
42
|
+
}]
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
|
|
23
46
|
|
|
24
47
|
|
|
25
48
|
|
|
@@ -185,6 +208,36 @@ __primitiveValueTypes := { "Int": true, "Long": true, "Float": true, "Double": t
|
|
|
185
208
|
|
|
186
209
|
|
|
187
210
|
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
|
|
188
241
|
|
|
189
242
|
|
|
190
243
|
|
|
@@ -249,12 +302,25 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
249
302
|
ll.panic("can't use passAggregationAxesSpec, passAggregationAxesNames or passDistilledAggregationSpec without aggregate")
|
|
250
303
|
}
|
|
251
304
|
|
|
305
|
+
createOutputTrace := func(output) {
|
|
306
|
+
hasOutputTrace := !is_undefined(output.traceSteps)
|
|
307
|
+
hasGlobalTrace := !is_undefined(opts.traceSteps)
|
|
308
|
+
hasInputTrace := !is_undefined(input.spec.annotations[pSpec.A_TRACE])
|
|
252
309
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
trace
|
|
256
|
-
|
|
310
|
+
outputTraceSteps := slices.normalize(opts.traceSteps) + slices.normalize(output.traceSteps)
|
|
311
|
+
|
|
312
|
+
trace := undefined
|
|
313
|
+
if len(outputTraceSteps) > 0 || hasInputTrace {
|
|
314
|
+
trace = pSpec.makeTrace(input.spec, outputTraceSteps...)
|
|
315
|
+
}
|
|
257
316
|
|
|
317
|
+
outputOverrideTrace := output.overrideTrace
|
|
318
|
+
if is_undefined(outputOverrideTrace) {
|
|
319
|
+
outputOverrideTrace = hasOutputTrace || hasGlobalTrace
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
return { trace: trace, overrideTrace: outputOverrideTrace }
|
|
323
|
+
}
|
|
258
324
|
|
|
259
325
|
processTemplateParams := {
|
|
260
326
|
eph: opts.isEphemeral,
|
|
@@ -289,7 +355,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
289
355
|
metaExtra = {}
|
|
290
356
|
}
|
|
291
357
|
|
|
292
|
-
iterationAxesSpec := input.spec.axesSpec
|
|
358
|
+
iterationAxesSpec := copy(input.spec.axesSpec)
|
|
293
359
|
|
|
294
360
|
|
|
295
361
|
if !isPotentiallyPartitioned {
|
|
@@ -376,19 +442,20 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
376
442
|
for output in outputs {
|
|
377
443
|
|
|
378
444
|
outputsMap[output.name] = output
|
|
445
|
+
traceInfo := createOutputTrace(output)
|
|
379
446
|
if output.type == "Resource" || output.type == "BinaryPartitioned" || output.type == "JsonPartitioned" {
|
|
380
|
-
spec := maps.merge(output.spec, { axesSpec: iterationAxesSpec + slices.normalize(output.spec.axesSpec) })
|
|
381
|
-
if !is_undefined(trace) {
|
|
382
|
-
spec = trace.inject(spec)
|
|
447
|
+
spec := maps.merge(output.spec, { axesSpec: copy(iterationAxesSpec) + slices.normalize(output.spec.axesSpec) })
|
|
448
|
+
if !is_undefined(traceInfo.trace) {
|
|
449
|
+
spec = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
|
|
383
450
|
}
|
|
384
451
|
outputSpecs[output.name] = spec
|
|
385
|
-
processedOutputs = append(processedOutputs, maps.merge(output, {spec: undefined
|
|
452
|
+
processedOutputs = append(processedOutputs, maps.merge(output, {spec: undefined, traceSteps: undefined, overrideTrace: undefined }))
|
|
386
453
|
} else if output.type == "ResourceMap" {
|
|
387
454
|
processedOutputs = append(processedOutputs, maps.merge(output,
|
|
388
|
-
{ keyLength: len(output.spec.axesSpec), spec: undefined }))
|
|
389
|
-
spec := maps.merge(output.spec, { axesSpec: iterationAxesSpec + slices.normalize(output.spec.axesSpec) })
|
|
390
|
-
if !is_undefined(trace) {
|
|
391
|
-
spec = trace.inject(spec)
|
|
455
|
+
{ keyLength: len(output.spec.axesSpec), spec: undefined, traceSteps: undefined, overrideTrace: undefined }))
|
|
456
|
+
spec := maps.merge(output.spec, { axesSpec: copy(iterationAxesSpec) + slices.normalize(output.spec.axesSpec) })
|
|
457
|
+
if !is_undefined(traceInfo.trace) {
|
|
458
|
+
spec = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
|
|
392
459
|
}
|
|
393
460
|
outputSpecs[output.name] = spec
|
|
394
461
|
} else if output.type == "Xsv" {
|
|
@@ -400,17 +467,68 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
400
467
|
})
|
|
401
468
|
purifiedPfconvCfg := decomposition.purifiedCfg
|
|
402
469
|
columnsSpec := decomposition.columnsSpec
|
|
403
|
-
if !is_undefined(trace) {
|
|
470
|
+
if !is_undefined(traceInfo.trace) {
|
|
404
471
|
for columnName, spec in columnsSpec {
|
|
405
|
-
columnsSpec[columnName] = trace.inject(spec)
|
|
472
|
+
columnsSpec[columnName] = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
|
|
406
473
|
}
|
|
407
474
|
}
|
|
408
475
|
outputSpecs[output.name] = columnsSpec
|
|
409
476
|
processedOutputs = append(processedOutputs, maps.merge(output,
|
|
410
477
|
{
|
|
411
478
|
settings: purifiedPfconvCfg,
|
|
412
|
-
flattenWithDelimiter: "/"
|
|
479
|
+
flattenWithDelimiter: "/",
|
|
480
|
+
traceSteps: undefined,
|
|
481
|
+
overrideTrace: undefined
|
|
413
482
|
}))
|
|
483
|
+
} else if output.type == "TsvContent" {
|
|
484
|
+
validation.assertType(output.settings, TSV_CONTENT_SETTINGS_SCHEMA, "Invalid TsvContent settings")
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
transformedSettings := {
|
|
488
|
+
axes: slices.map(output.settings.axes, func(axis) {
|
|
489
|
+
return {
|
|
490
|
+
name: axis.column,
|
|
491
|
+
type: axis.spec.type
|
|
492
|
+
}
|
|
493
|
+
}),
|
|
494
|
+
columns: slices.map(output.settings.columns, func(column) {
|
|
495
|
+
transformedColumn := {
|
|
496
|
+
name: column.column,
|
|
497
|
+
type: column.spec.valueType
|
|
498
|
+
}
|
|
499
|
+
if !is_undefined(column.id) {
|
|
500
|
+
transformedColumn.id = column.id
|
|
501
|
+
}
|
|
502
|
+
return transformedColumn
|
|
503
|
+
})
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
columnsSpec := {}
|
|
508
|
+
axesSpec := copy(iterationAxesSpec)
|
|
509
|
+
for axis in output.settings.axes {
|
|
510
|
+
axesSpec = append(axesSpec, axis.spec)
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
for column in output.settings.columns {
|
|
514
|
+
columnId := column.id
|
|
515
|
+
if is_undefined(columnId) {
|
|
516
|
+
columnId = column.column
|
|
517
|
+
}
|
|
518
|
+
spec := maps.merge(column.spec, { axesSpec: axesSpec, kind: "PColumn" })
|
|
519
|
+
if !is_undefined(traceInfo.trace) {
|
|
520
|
+
spec = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
|
|
521
|
+
}
|
|
522
|
+
columnsSpec[columnId] = spec
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
outputSpecs[output.name] = columnsSpec
|
|
526
|
+
processedOutputs = append(processedOutputs, maps.merge(output, {
|
|
527
|
+
settings: transformedSettings,
|
|
528
|
+
flattenWithDelimiter: "/",
|
|
529
|
+
traceSteps: undefined,
|
|
530
|
+
overrideTrace: undefined
|
|
531
|
+
}))
|
|
414
532
|
} else {
|
|
415
533
|
ll.panic("unknown output type: " + output.type)
|
|
416
534
|
}
|
|
@@ -455,9 +573,9 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
455
573
|
}
|
|
456
574
|
|
|
457
575
|
spec := outputSpecs[name]
|
|
458
|
-
if output.type == "Xsv" {
|
|
576
|
+
if output.type == "Xsv" || output.type == "TsvContent" {
|
|
459
577
|
if len(column) != 1 {
|
|
460
|
-
ll.panic("column name must be provided for
|
|
578
|
+
ll.panic("column name must be provided for " + output.type + " output")
|
|
461
579
|
}
|
|
462
580
|
columnName := column[0]
|
|
463
581
|
spec = spec[columnName]
|
|
@@ -467,7 +585,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
467
585
|
return spec
|
|
468
586
|
} else {
|
|
469
587
|
if len(column) > 0 {
|
|
470
|
-
ll.panic("column name should not be provided for non-Xsv output")
|
|
588
|
+
ll.panic("column name should not be provided for non-Xsv/TsvContent output")
|
|
471
589
|
}
|
|
472
590
|
return spec
|
|
473
591
|
}
|
|
@@ -490,14 +608,14 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
490
608
|
ll.panic("unknown output: " + name)
|
|
491
609
|
}
|
|
492
610
|
|
|
493
|
-
if output.type == "Xsv" {
|
|
611
|
+
if output.type == "Xsv" || output.type == "TsvContent" {
|
|
494
612
|
if len(column) != 1 {
|
|
495
|
-
ll.panic("column name must be provided for
|
|
613
|
+
ll.panic("column name must be provided for " + output.type + " output")
|
|
496
614
|
}
|
|
497
615
|
return renderResult.output(name + "/" + column[0])
|
|
498
616
|
} else {
|
|
499
617
|
if len(column) > 0 {
|
|
500
|
-
ll.panic("column name should not be provided for non-Xsv output")
|
|
618
|
+
ll.panic("column name should not be provided for non-Xsv/TsvContent output")
|
|
501
619
|
}
|
|
502
620
|
return renderResult.output(name)
|
|
503
621
|
}
|
|
@@ -520,9 +638,9 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
520
638
|
ll.panic("unknown output: " + name)
|
|
521
639
|
}
|
|
522
640
|
|
|
523
|
-
if output.type == "Xsv" {
|
|
641
|
+
if output.type == "Xsv" || output.type == "TsvContent" {
|
|
524
642
|
if len(column) != 1 {
|
|
525
|
-
ll.panic("column name must be provided for
|
|
643
|
+
ll.panic("column name must be provided for " + output.type + " output")
|
|
526
644
|
}
|
|
527
645
|
columnName := column[0]
|
|
528
646
|
spec := outputSpecs[name][columnName]
|
|
@@ -535,7 +653,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
535
653
|
}
|
|
536
654
|
} else {
|
|
537
655
|
if len(column) > 0 {
|
|
538
|
-
ll.panic("column name should not be provided for non-Xsv output")
|
|
656
|
+
ll.panic("column name should not be provided for non-Xsv/TsvContent output")
|
|
539
657
|
}
|
|
540
658
|
return {
|
|
541
659
|
data: renderResult.output(name),
|
|
@@ -556,8 +674,8 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
556
674
|
ll.panic("unknown output: " + name)
|
|
557
675
|
}
|
|
558
676
|
|
|
559
|
-
if output.type != "Xsv" {
|
|
560
|
-
ll.panic("outputFrame can only be used with Xsv outputs")
|
|
677
|
+
if output.type != "Xsv" && output.type != "TsvContent" {
|
|
678
|
+
ll.panic("outputFrame can only be used with Xsv or TsvContent outputs")
|
|
561
679
|
}
|
|
562
680
|
|
|
563
681
|
builder := builder.pFrameBuilder()
|
|
@@ -581,7 +699,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
581
699
|
}
|
|
582
700
|
|
|
583
701
|
maps.forEach(outputsMap, func(name, output) {
|
|
584
|
-
if output.type == "Xsv" {
|
|
702
|
+
if output.type == "Xsv" || output.type == "TsvContent" {
|
|
585
703
|
|
|
586
704
|
for columnName, spec in outputSpecs[name] {
|
|
587
705
|
builder.add(
|
|
@@ -649,8 +767,8 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
|
|
|
649
767
|
if is_undefined(output) {
|
|
650
768
|
ll.panic("unknown output: " + name)
|
|
651
769
|
}
|
|
652
|
-
if output.type != "Xsv" {
|
|
653
|
-
ll.panic("output is not Xsv: " + name)
|
|
770
|
+
if output.type != "Xsv" && output.type != "TsvContent" {
|
|
771
|
+
ll.panic("output is not Xsv or TsvContent: " + name)
|
|
654
772
|
}
|
|
655
773
|
|
|
656
774
|
return maps.getKeys(outputSpecs[name])
|
|
@@ -258,10 +258,44 @@ makeTrace := func(input, ...steps) {
|
|
|
258
258
|
return ll.toStrict({
|
|
259
259
|
value: currentTrace,
|
|
260
260
|
valueStr: currentTraceStr,
|
|
261
|
-
|
|
262
|
-
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
inject: func(spec, ...opts) {
|
|
263
274
|
validation.assertType(spec, P_COLUMN_SPEC_SCHEMA)
|
|
264
|
-
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
options := {}
|
|
278
|
+
if len(opts) > 0 {
|
|
279
|
+
if len(opts) == 1 && is_map(opts[0]) {
|
|
280
|
+
options = opts[0]
|
|
281
|
+
} else {
|
|
282
|
+
ll.panic("inject: optional parameters must be a single map argument, got: %v", opts)
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
override := options.override
|
|
288
|
+
if is_undefined(override) {
|
|
289
|
+
override = true
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return maps.deepTransform(spec, {annotations: {"pl7.app/trace": func(oldValue) {
|
|
293
|
+
|
|
294
|
+
if override || is_undefined(oldValue) {
|
|
295
|
+
return currentTraceStr
|
|
296
|
+
}
|
|
297
|
+
return oldValue
|
|
298
|
+
}}})
|
|
265
299
|
}
|
|
266
300
|
})
|
|
267
301
|
}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
2
2
|
maps := import("@platforma-sdk/workflow-tengo:maps")
|
|
3
3
|
slices := import("@platforma-sdk/workflow-tengo:slices")
|
|
4
|
+
validation := import("@platforma-sdk/workflow-tengo:validation")
|
|
5
|
+
fmt := import("fmt")
|
|
4
6
|
|
|
5
7
|
|
|
6
8
|
|
|
@@ -16,6 +18,24 @@ when := undefined
|
|
|
16
18
|
rank := undefined
|
|
17
19
|
|
|
18
20
|
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
_validateOptions := func(options, schema, functionName) {
|
|
24
|
+
if len(options) > 1 {
|
|
25
|
+
ll.panic("%s accepts at most one options map argument.", functionName)
|
|
26
|
+
}
|
|
27
|
+
if len(options) == 0 {
|
|
28
|
+
return {}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
opsMap := options[0]
|
|
32
|
+
ll.assert(is_map(opsMap), "Options argument to %s(), if provided, must be an options map.", functionName)
|
|
33
|
+
|
|
34
|
+
validation.assertType(opsMap, schema, fmt.sprintf("%s options validation error", functionName))
|
|
35
|
+
return opsMap
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
19
39
|
_isExpression := func(item) {
|
|
20
40
|
return ll.isMap(item) && ll.methodExists(item, "getExpression")
|
|
21
41
|
}
|
|
@@ -266,15 +286,13 @@ _newExpression = func(expression, currentAlias) {
|
|
|
266
286
|
|
|
267
287
|
|
|
268
288
|
cast: func(dtype, ...options) {
|
|
289
|
+
ops := _validateOptions(options, {
|
|
290
|
+
"__options__,closed": "",
|
|
291
|
+
"strict,?": "bool"
|
|
292
|
+
}, "cast")
|
|
269
293
|
strictVal := false
|
|
270
|
-
if
|
|
271
|
-
|
|
272
|
-
opsMap := options[0]
|
|
273
|
-
ll.assert(is_map(opsMap), "Second argument to cast(), if provided, must be an options map.")
|
|
274
|
-
if !is_undefined(opsMap.strict) {
|
|
275
|
-
ll.assert(is_bool(opsMap.strict), "strict in options map must be a boolean")
|
|
276
|
-
strictVal = opsMap.strict
|
|
277
|
-
}
|
|
294
|
+
if !is_undefined(ops.strict) {
|
|
295
|
+
strictVal = ops.strict
|
|
278
296
|
}
|
|
279
297
|
return _newExpression(
|
|
280
298
|
{type: "cast", value: expression, dtype: dtype, strict: strictVal},
|
|
@@ -334,14 +352,19 @@ _newExpression = func(expression, currentAlias) {
|
|
|
334
352
|
if len(args) > 0 {
|
|
335
353
|
arg := args[0]
|
|
336
354
|
if is_map(arg) {
|
|
337
|
-
|
|
355
|
+
ops := _validateOptions([arg], {
|
|
356
|
+
"__options__,closed": "",
|
|
357
|
+
"length,?": "any",
|
|
358
|
+
"end,?": "any"
|
|
359
|
+
}, "strSlice")
|
|
360
|
+
if ops.length != undefined && ops.end != undefined {
|
|
338
361
|
ll.panic("strSlice cannot have both 'length' and 'end' options.")
|
|
339
362
|
}
|
|
340
|
-
if !is_undefined(
|
|
341
|
-
expr.length = _mapToSingleExpressionStruct(
|
|
363
|
+
if !is_undefined(ops.length) {
|
|
364
|
+
expr.length = _mapToSingleExpressionStruct(ops.length, "col")
|
|
342
365
|
}
|
|
343
|
-
if !is_undefined(
|
|
344
|
-
expr.end = _mapToSingleExpressionStruct(
|
|
366
|
+
if !is_undefined(ops.end) {
|
|
367
|
+
expr.end = _mapToSingleExpressionStruct(ops.end, "col")
|
|
345
368
|
}
|
|
346
369
|
} else {
|
|
347
370
|
expr.length = _mapToSingleExpressionStruct(arg, "col")
|
|
@@ -361,21 +384,19 @@ _newExpression = func(expression, currentAlias) {
|
|
|
361
384
|
|
|
362
385
|
|
|
363
386
|
strReplace: func(pattern, replacement, ...options) {
|
|
387
|
+
ops := _validateOptions(options, {
|
|
388
|
+
"__options__,closed": "",
|
|
389
|
+
"replaceAll,?": "bool",
|
|
390
|
+
"literal,?": "bool"
|
|
391
|
+
}, "strReplace")
|
|
364
392
|
replaceAllVal := false
|
|
365
393
|
literalVal := false
|
|
366
394
|
|
|
367
|
-
if
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
ll.assert(is_bool(opsMap.replaceAll), "replaceAll in options map must be a boolean")
|
|
373
|
-
replaceAllVal = opsMap.replaceAll
|
|
374
|
-
}
|
|
375
|
-
if !is_undefined(opsMap.literal) {
|
|
376
|
-
ll.assert(is_bool(opsMap.literal), "literal in options map must be a boolean")
|
|
377
|
-
literalVal = opsMap.literal
|
|
378
|
-
}
|
|
395
|
+
if !is_undefined(ops.replaceAll) {
|
|
396
|
+
replaceAllVal = ops.replaceAll
|
|
397
|
+
}
|
|
398
|
+
if !is_undefined(ops.literal) {
|
|
399
|
+
literalVal = ops.literal
|
|
379
400
|
}
|
|
380
401
|
|
|
381
402
|
return _newExpression({
|
|
@@ -413,6 +434,147 @@ _newExpression = func(expression, currentAlias) {
|
|
|
413
434
|
|
|
414
435
|
|
|
415
436
|
|
|
437
|
+
strContains: func(pattern, ...options) {
|
|
438
|
+
ops := _validateOptions(options, {
|
|
439
|
+
"__options__,closed": "",
|
|
440
|
+
"literal,?": "bool",
|
|
441
|
+
"strict,?": "bool"
|
|
442
|
+
}, "strContains")
|
|
443
|
+
literalVal := false
|
|
444
|
+
strictVal := true
|
|
445
|
+
|
|
446
|
+
if !is_undefined(ops.literal) {
|
|
447
|
+
literalVal = ops.literal
|
|
448
|
+
}
|
|
449
|
+
if !is_undefined(ops.strict) {
|
|
450
|
+
strictVal = ops.strict
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return _newExpression({
|
|
454
|
+
type: "str_contains",
|
|
455
|
+
value: expression,
|
|
456
|
+
pattern: _mapToSingleExpressionStruct(pattern, "lit"),
|
|
457
|
+
literal: literalVal,
|
|
458
|
+
strict: strictVal
|
|
459
|
+
}, undefined)
|
|
460
|
+
},
|
|
461
|
+
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
|
|
469
|
+
strContainsAny: func(patterns, ...options) {
|
|
470
|
+
ll.assert(is_array(patterns), "patterns must be an array of strings")
|
|
471
|
+
for pattern in patterns {
|
|
472
|
+
ll.assert(is_string(pattern), "all patterns must be strings")
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
ops := _validateOptions(options, {
|
|
476
|
+
"__options__,closed": "",
|
|
477
|
+
"asciiCaseInsensitive,?": "bool"
|
|
478
|
+
}, "strContainsAny")
|
|
479
|
+
asciiCaseInsensitiveVal := false
|
|
480
|
+
if !is_undefined(ops.asciiCaseInsensitive) {
|
|
481
|
+
asciiCaseInsensitiveVal = ops.asciiCaseInsensitive
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
return _newExpression({
|
|
485
|
+
type: "str_contains_any",
|
|
486
|
+
value: expression,
|
|
487
|
+
patterns: patterns,
|
|
488
|
+
asciiCaseInsensitive: asciiCaseInsensitiveVal
|
|
489
|
+
}, undefined)
|
|
490
|
+
},
|
|
491
|
+
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
|
|
499
|
+
strCountMatches: func(pattern, ...options) {
|
|
500
|
+
ops := _validateOptions(options, {
|
|
501
|
+
"__options__,closed": "",
|
|
502
|
+
"literal,?": "bool"
|
|
503
|
+
}, "strCountMatches")
|
|
504
|
+
literalVal := false
|
|
505
|
+
|
|
506
|
+
if !is_undefined(ops.literal) {
|
|
507
|
+
literalVal = ops.literal
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
return _newExpression({
|
|
511
|
+
type: "str_count_matches",
|
|
512
|
+
value: expression,
|
|
513
|
+
pattern: _mapToSingleExpressionStruct(pattern, "lit"),
|
|
514
|
+
literal: literalVal
|
|
515
|
+
}, undefined)
|
|
516
|
+
},
|
|
517
|
+
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
|
|
522
|
+
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
strExtract: func(pattern, ...options) {
|
|
526
|
+
ops := _validateOptions(options, {
|
|
527
|
+
"__options__,closed": "",
|
|
528
|
+
"groupIndex,?": "number"
|
|
529
|
+
}, "strExtract")
|
|
530
|
+
groupIndexVal := 0
|
|
531
|
+
|
|
532
|
+
if !is_undefined(ops.groupIndex) {
|
|
533
|
+
groupIndexVal = ops.groupIndex
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
return _newExpression({
|
|
537
|
+
type: "str_extract",
|
|
538
|
+
value: expression,
|
|
539
|
+
pattern: _mapToSingleExpressionStruct(pattern, "lit"),
|
|
540
|
+
groupIndex: groupIndexVal
|
|
541
|
+
}, undefined)
|
|
542
|
+
},
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
|
|
549
|
+
strStartsWith: func(prefix) {
|
|
550
|
+
return _newExpression({
|
|
551
|
+
type: "str_starts_with",
|
|
552
|
+
value: expression,
|
|
553
|
+
prefix: _mapToSingleExpressionStruct(prefix, "lit")
|
|
554
|
+
}, undefined)
|
|
555
|
+
},
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
strEndsWith: func(suffix) {
|
|
563
|
+
return _newExpression({
|
|
564
|
+
type: "str_ends_with",
|
|
565
|
+
value: expression,
|
|
566
|
+
suffix: _mapToSingleExpressionStruct(suffix, "lit")
|
|
567
|
+
}, undefined)
|
|
568
|
+
},
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
416
578
|
strDistance: func(string2, metric, returnSimilarity) {
|
|
417
579
|
ll.assert(_isExpression(string2), "string2 must be an expression object")
|
|
418
580
|
ll.assert(is_string(metric), "metric must be a string")
|
|
@@ -561,13 +723,16 @@ _newExpression = func(expression, currentAlias) {
|
|
|
561
723
|
actualArgs := args
|
|
562
724
|
|
|
563
725
|
if len(args) > 0 && is_map(args[len(args)-1]) && !(_isExpression(args[len(args)-1])) {
|
|
564
|
-
ops := args[len(args)-1]
|
|
726
|
+
ops := _validateOptions([args[len(args)-1]], {
|
|
727
|
+
"__options__,closed": "",
|
|
728
|
+
"orderBy,?": "any",
|
|
729
|
+
"descending,?": "bool"
|
|
730
|
+
}, "cumsum")
|
|
565
731
|
actualArgs = args[0:len(args)-1]
|
|
566
|
-
if
|
|
732
|
+
if !is_undefined(ops.orderBy) {
|
|
567
733
|
additionalOrderByVal = _mapToExpressionStructList(ops.orderBy, "col")
|
|
568
734
|
}
|
|
569
|
-
if
|
|
570
|
-
ll.assert(is_bool(ops.descending), "descending in options map must be a boolean")
|
|
735
|
+
if !is_undefined(ops.descending) {
|
|
571
736
|
descendingVal = ops.descending
|
|
572
737
|
}
|
|
573
738
|
}
|
|
@@ -645,15 +810,13 @@ concatStr := func(expressions, ...options) {
|
|
|
645
810
|
ll.assert(is_array(expressions), "First argument to concatStr must be an array of expressions")
|
|
646
811
|
ll.assert(len(expressions) > 0, "Expression array for concatStr cannot be empty")
|
|
647
812
|
|
|
813
|
+
ops := _validateOptions(options, {
|
|
814
|
+
"__options__,closed": "",
|
|
815
|
+
"delimiter,?": "string"
|
|
816
|
+
}, "concatStr")
|
|
648
817
|
delimiterVal := "" // Default to empty string
|
|
649
|
-
if
|
|
650
|
-
|
|
651
|
-
opsMap := options[0]
|
|
652
|
-
ll.assert(is_map(opsMap), "Second argument to concatStr(), if provided, must be an options map.")
|
|
653
|
-
if !is_undefined(opsMap.delimiter) {
|
|
654
|
-
ll.assert(is_string(opsMap.delimiter), "delimiter in options map must be a string")
|
|
655
|
-
delimiterVal = opsMap.delimiter
|
|
656
|
-
}
|
|
818
|
+
if !is_undefined(ops.delimiter) {
|
|
819
|
+
delimiterVal = ops.delimiter
|
|
657
820
|
}
|
|
658
821
|
|
|
659
822
|
return _newExpression({
|
|
@@ -800,14 +963,12 @@ rank = func(orderByExpressions, ...options) {
|
|
|
800
963
|
orderByVal = _mapToExpressionStructList(orderByExpressions, "col")
|
|
801
964
|
ll.assert(len(orderByVal) > 0, "rank() 'orderBy' list cannot be empty after processing arguments.")
|
|
802
965
|
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
descendingVal = opsMap.descending
|
|
810
|
-
}
|
|
966
|
+
ops := _validateOptions(options, {
|
|
967
|
+
"__options__,closed": "",
|
|
968
|
+
"descending,?": "bool"
|
|
969
|
+
}, "rank")
|
|
970
|
+
if !is_undefined(ops.descending) {
|
|
971
|
+
descendingVal = ops.descending
|
|
811
972
|
}
|
|
812
973
|
|
|
813
974
|
return _newWindowExpression({
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@platforma-sdk/workflow-tengo",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.13.0",
|
|
4
4
|
"description": "Tengo SDK library",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@milaboratories/software-pframes-conv": "2.2.2",
|
|
20
20
|
"@platforma-open/milaboratories.software-small-binaries": "^1.15.21",
|
|
21
|
-
"@platforma-open/milaboratories.software-ptabler": "1.
|
|
21
|
+
"@platforma-open/milaboratories.software-ptabler": "1.8.0"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@platforma-sdk/tengo-builder": "^2.1.12"
|