@platforma-sdk/workflow-tengo 4.12.0 → 4.14.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.
Files changed (44) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +1 -0
  3. package/dist/index.mjs +1 -0
  4. package/dist/tengo/lib/maps.lib.tengo +8 -2
  5. package/dist/tengo/lib/pframes.lib.tengo +446 -31
  6. package/dist/tengo/lib/pframes.spec.lib.tengo +37 -3
  7. package/dist/tengo/lib/slices.lib.tengo +1 -1
  8. package/dist/tengo/tpl/anonymize.deanonymize.plj.gz +0 -0
  9. package/dist/tengo/tpl/anonymize.impl.plj.gz +0 -0
  10. package/dist/tengo/tpl/check_network.create_workdir_from_storage.plj.gz +0 -0
  11. package/dist/tengo/tpl/check_network.download_blob.plj.gz +0 -0
  12. package/dist/tengo/tpl/check_network.run_hello_world.plj.gz +0 -0
  13. package/dist/tengo/tpl/check_network.run_hello_world_py.plj.gz +0 -0
  14. package/dist/tengo/tpl/check_network.upload_blob.plj.gz +0 -0
  15. package/dist/tengo/tpl/check_network.upload_template.plj.gz +0 -0
  16. package/dist/tengo/tpl/check_network.workdir_type_name_extractor.plj.gz +0 -0
  17. package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
  18. package/dist/tengo/tpl/exec.delayed-compute-allocation.impl.plj.gz +0 -0
  19. package/dist/tengo/tpl/exec.exec-impl.plj.gz +0 -0
  20. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  21. package/dist/tengo/tpl/exec.load-software.impl.plj.gz +0 -0
  22. package/dist/tengo/tpl/exec.monetization_info.plj.gz +0 -0
  23. package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
  24. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  25. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  26. package/dist/tengo/tpl/exec.python.venv-bin-path.plj.gz +0 -0
  27. package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
  28. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  29. package/dist/tengo/tpl/pframes.export-pframe-for-ui.plj.gz +0 -0
  30. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  31. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  32. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  33. package/dist/tengo/tpl/pframes.parse-to-json.plj.gz +0 -0
  34. package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
  35. package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
  36. package/dist/tengo/tpl/pframes.slice-data.plj.gz +0 -0
  37. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  38. package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
  39. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  40. package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
  41. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  42. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  43. package/dist/tengo/tpl/workflow.query-anchored.plj.gz +0 -0
  44. 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(res[k]) && is_map(v) {
217
- res[k] = deepTransform(res[k], v)
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,147 @@ 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
+ BASIC_TSV_COLUMN_SPEC_SCHEMA := {
24
+ "valueType": "string,regex=Int|Long|Float|Double|String",
25
+ "name,?": "string",
26
+ "domain,?": { "any": "string" },
27
+ "annotations,?": { "any": "string" }
28
+ }
29
+
30
+
31
+ BASIC_TSV_COLUMN_SPEC_SCHEMA_STRING := {
32
+ "valueType": "string,regex=String",
33
+ "name,?": "string",
34
+ "domain,?": { "any": "string" },
35
+ "annotations,?": { "any": "string" }
36
+ }
37
+
38
+
39
+ BASIC_COLUMN_INFO_SCHEMA := {
40
+ "__options__,closed": "",
41
+ "column": "string",
42
+ "id,?": "string",
43
+ "type": "string,regex=Int|Long|Float|Double|String"
44
+ }
45
+
46
+
47
+ TSV_CONTENT_SETTINGS_SCHEMA := {
48
+ "__options__,closed": "",
49
+ "axes": [{
50
+ "__options__,closed": "",
51
+ "column": "string",
52
+ "spec": {
53
+ "__options__,closed": "",
54
+ "type": "string,regex=Int|Long|Float|Double|String",
55
+ "name,?": "string",
56
+ "domain,?": { "any": "string" },
57
+ "annotations,?": { "any": "string" }
58
+ }
59
+ }],
60
+ "columns": [["or",
61
+ {
62
+ "__options__,closed": "",
63
+ "kind": "string,regex=column",
64
+ "column": "string",
65
+ "id,?": "string",
66
+ "spec": BASIC_TSV_COLUMN_SPEC_SCHEMA
67
+ },
68
+ {
69
+ "__options__,closed": "",
70
+ "kind": "string,regex=line",
71
+ "id": "string",
72
+ "spec": BASIC_TSV_COLUMN_SPEC_SCHEMA_STRING
73
+ },
74
+ {
75
+ "__options__,closed": "",
76
+ "kind": "string,regex=json-line",
77
+ "id": "string",
78
+ "spec": BASIC_TSV_COLUMN_SPEC_SCHEMA_STRING,
79
+ "columns": [BASIC_COLUMN_INFO_SCHEMA]
80
+ },
81
+ {
82
+ "__options__,closed": "",
83
+ "column": "string",
84
+ "id,?": "string",
85
+ "spec": BASIC_TSV_COLUMN_SPEC_SCHEMA
86
+ }
87
+ ]]
88
+ }
89
+
90
+
91
+ getTsvColumnId := func(column) {
92
+ kind := column.kind
93
+ if is_undefined(kind) {
94
+ kind = "column"
95
+ }
96
+
97
+ if kind == "column" {
98
+ columnId := column.id
99
+ if is_undefined(columnId) {
100
+ columnId = column.column
101
+ }
102
+ return columnId
103
+ } else if kind == "line" || kind == "json-line" {
104
+ return column.id
105
+ } else {
106
+ ll.panic("Unknown column kind: %s", kind)
107
+ }
108
+ }
109
+
110
+
111
+ transformTsvSettings := func(settings) {
112
+ return {
113
+ axes: slices.map(settings.axes, func(axis) {
114
+ return {
115
+ name: axis.column,
116
+ type: axis.spec.type
117
+ }
118
+ }),
119
+ columns: slices.map(settings.columns, func(column) {
120
+
121
+ kind := column.kind
122
+ if is_undefined(kind) {
123
+ kind = "column"
124
+ }
125
+
126
+ if kind == "column" {
127
+ transformedColumn := {
128
+ kind: "column",
129
+ name: column.column,
130
+ type: column.spec.valueType
131
+ }
132
+ if !is_undefined(column.id) {
133
+ transformedColumn.id = column.id
134
+ }
135
+ return transformedColumn
136
+ } else if kind == "line" {
137
+ return {
138
+ kind: "line",
139
+ id: column.id
140
+ }
141
+ } else if kind == "json-line" {
142
+ return {
143
+ kind: "json-line",
144
+ id: column.id,
145
+ columns: slices.map(column.columns, func(jsonCol) {
146
+ transformedCol := {
147
+ name: jsonCol.column,
148
+ type: jsonCol.type
149
+ }
150
+ if !is_undefined(jsonCol.id) {
151
+ transformedCol.id = jsonCol.id
152
+ }
153
+ return transformedCol
154
+ })
155
+ }
156
+ } else {
157
+ ll.panic("Unknown column kind: %s", kind)
158
+ }
159
+ })
160
+ }
161
+ }
162
+
163
+
23
164
 
24
165
 
25
166
 
@@ -38,6 +179,181 @@ exportColumnData := func(data) {
38
179
 
39
180
 
40
181
 
182
+
183
+
184
+
185
+
186
+
187
+
188
+
189
+
190
+
191
+
192
+
193
+
194
+
195
+
196
+
197
+
198
+
199
+
200
+
201
+
202
+
203
+
204
+
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+
215
+
216
+
217
+
218
+
219
+
220
+
221
+
222
+
223
+
224
+
225
+
226
+
227
+
228
+
229
+
230
+
231
+ parseToJson := func(targetContent, params) {
232
+ validation.assertType(params, TSV_CONTENT_SETTINGS_SCHEMA, "Invalid TsvContent settings")
233
+
234
+
235
+ transformedSettings := transformTsvSettings(params)
236
+
237
+
238
+ input := undefined
239
+ baseAxesSpec := []
240
+
241
+ if is_string(targetContent) || smart.isReference(targetContent) {
242
+
243
+ input = targetContent
244
+ } else if is_map(targetContent) && !is_undefined(targetContent.data) && !is_undefined(targetContent.spec) {
245
+
246
+ input = targetContent.data
247
+ validation.assertType(targetContent.spec, pSpec.P_COLUMN_SPEC_SCHEMA)
248
+ baseAxesSpec = slices.normalize(targetContent.spec.axesSpec)
249
+ } else {
250
+ ll.panic("targetContent must be a string, resource reference, or {data: resource, spec: PColumnSpec}")
251
+ }
252
+
253
+
254
+ axesSpec := copy(baseAxesSpec)
255
+ for axis in params.axes {
256
+ axesSpec = append(axesSpec, axis.spec)
257
+ }
258
+
259
+
260
+ outputSpecs := {}
261
+ for column in params.columns {
262
+ columnId := getTsvColumnId(column)
263
+ spec := maps.merge(column.spec, { axesSpec: axesSpec, kind: "PColumn" })
264
+ outputSpecs[columnId] = spec
265
+ }
266
+
267
+
268
+ parseToJsonTpl := assets.importTemplate("@platforma-sdk/workflow-tengo:pframes.parse-to-json")
269
+ renderResult := render.create(parseToJsonTpl, {
270
+ params: smart.createJsonResource(transformedSettings),
271
+ input: input
272
+ })
273
+
274
+
275
+ self := undefined
276
+ self = ll.toStrict({
277
+
278
+
279
+
280
+
281
+
282
+
283
+ output: func(columnId) {
284
+ spec := outputSpecs[columnId]
285
+ if is_undefined(spec) {
286
+ ll.panic("unknown column: " + columnId)
287
+ }
288
+ return {
289
+ data: renderResult.resolveOutput(["result", columnId]),
290
+ spec: spec
291
+ }
292
+ },
293
+
294
+
295
+
296
+
297
+
298
+
299
+
300
+ outputData: func(columnId) {
301
+ if is_undefined(outputSpecs[columnId]) {
302
+ ll.panic("unknown column: " + columnId)
303
+ }
304
+ return renderResult.resolveOutput(["result", columnId])
305
+ },
306
+
307
+
308
+
309
+
310
+
311
+
312
+
313
+ outputSpec: func(columnId) {
314
+ spec := outputSpecs[columnId]
315
+ if is_undefined(spec) {
316
+ ll.panic("unknown column: " + columnId)
317
+ }
318
+ return spec
319
+ },
320
+
321
+
322
+
323
+
324
+
325
+
326
+ listOutputs: func() {
327
+ return maps.getKeys(outputSpecs)
328
+ },
329
+
330
+
331
+
332
+
333
+
334
+
335
+
336
+
337
+ addAllOutputsToBuilder: func(builder, ...separator) {
338
+ maps.forEach(outputSpecs, func(columnId, spec) {
339
+ builder.add(
340
+ columnId,
341
+ spec,
342
+ renderResult.resolveOutput(["result", columnId])
343
+ )
344
+ })
345
+
346
+ return builder
347
+ }
348
+ })
349
+
350
+ return self
351
+ }
352
+
353
+
354
+
355
+
356
+
41
357
  pColumnResourceMapDataBuilder := func(keyLength) {
42
358
  ll.panic("pframes.pColumnResourceMapDataBuilder is not supported any more; use pcolumn.resourceMapBuilder")
43
359
  }
@@ -185,6 +501,57 @@ __primitiveValueTypes := { "Int": true, "Long": true, "Float": true, "Double": t
185
501
 
186
502
 
187
503
 
504
+
505
+
506
+
507
+
508
+
509
+
510
+
511
+
512
+
513
+
514
+
515
+
516
+
517
+
518
+
519
+
520
+
521
+
522
+
523
+
524
+
525
+
526
+
527
+
528
+
529
+
530
+
531
+
532
+
533
+
534
+
535
+
536
+
537
+
538
+
539
+
540
+
541
+
542
+
543
+
544
+
545
+
546
+
547
+
548
+
549
+
550
+
551
+
552
+
553
+
554
+
188
555
 
189
556
 
190
557
 
@@ -249,12 +616,25 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
249
616
  ll.panic("can't use passAggregationAxesSpec, passAggregationAxesNames or passDistilledAggregationSpec without aggregate")
250
617
  }
251
618
 
619
+ createOutputTrace := func(output) {
620
+ hasOutputTrace := !is_undefined(output.traceSteps)
621
+ hasGlobalTrace := !is_undefined(opts.traceSteps)
622
+ hasInputTrace := !is_undefined(input.spec.annotations[pSpec.A_TRACE])
252
623
 
253
- trace := undefined
254
- if !is_undefined(opts.traceSteps) || !is_undefined(input.spec.annotations[pSpec.A_TRACE]) {
255
- trace = pSpec.makeTrace(input.spec, (opts.traceSteps ? opts.traceSteps : [])...)
256
- }
624
+ outputTraceSteps := slices.normalize(opts.traceSteps) + slices.normalize(output.traceSteps)
625
+
626
+ trace := undefined
627
+ if len(outputTraceSteps) > 0 || hasInputTrace {
628
+ trace = pSpec.makeTrace(input.spec, outputTraceSteps...)
629
+ }
257
630
 
631
+ outputOverrideTrace := output.overrideTrace
632
+ if is_undefined(outputOverrideTrace) {
633
+ outputOverrideTrace = hasOutputTrace || hasGlobalTrace
634
+ }
635
+
636
+ return { trace: trace, overrideTrace: outputOverrideTrace }
637
+ }
258
638
 
259
639
  processTemplateParams := {
260
640
  eph: opts.isEphemeral,
@@ -289,7 +669,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
289
669
  metaExtra = {}
290
670
  }
291
671
 
292
- iterationAxesSpec := input.spec.axesSpec
672
+ iterationAxesSpec := copy(input.spec.axesSpec)
293
673
 
294
674
 
295
675
  if !isPotentiallyPartitioned {
@@ -376,19 +756,20 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
376
756
  for output in outputs {
377
757
 
378
758
  outputsMap[output.name] = output
759
+ traceInfo := createOutputTrace(output)
379
760
  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)
761
+ spec := maps.merge(output.spec, { axesSpec: copy(iterationAxesSpec) + slices.normalize(output.spec.axesSpec) })
762
+ if !is_undefined(traceInfo.trace) {
763
+ spec = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
383
764
  }
384
765
  outputSpecs[output.name] = spec
385
- processedOutputs = append(processedOutputs, maps.merge(output, {spec: undefined })) // removing spec field
766
+ processedOutputs = append(processedOutputs, maps.merge(output, {spec: undefined, traceSteps: undefined, overrideTrace: undefined }))
386
767
  } else if output.type == "ResourceMap" {
387
768
  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)
769
+ { keyLength: len(output.spec.axesSpec), spec: undefined, traceSteps: undefined, overrideTrace: undefined }))
770
+ spec := maps.merge(output.spec, { axesSpec: copy(iterationAxesSpec) + slices.normalize(output.spec.axesSpec) })
771
+ if !is_undefined(traceInfo.trace) {
772
+ spec = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
392
773
  }
393
774
  outputSpecs[output.name] = spec
394
775
  } else if output.type == "Xsv" {
@@ -400,17 +781,50 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
400
781
  })
401
782
  purifiedPfconvCfg := decomposition.purifiedCfg
402
783
  columnsSpec := decomposition.columnsSpec
403
- if !is_undefined(trace) {
784
+ if !is_undefined(traceInfo.trace) {
404
785
  for columnName, spec in columnsSpec {
405
- columnsSpec[columnName] = trace.inject(spec)
786
+ columnsSpec[columnName] = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
406
787
  }
407
788
  }
408
789
  outputSpecs[output.name] = columnsSpec
409
790
  processedOutputs = append(processedOutputs, maps.merge(output,
410
791
  {
411
792
  settings: purifiedPfconvCfg,
412
- flattenWithDelimiter: "/"
793
+ flattenWithDelimiter: "/",
794
+ traceSteps: undefined,
795
+ overrideTrace: undefined
413
796
  }))
797
+ } else if output.type == "TsvContent" {
798
+ validation.assertType(output.settings, TSV_CONTENT_SETTINGS_SCHEMA, "Invalid TsvContent settings")
799
+
800
+
801
+ transformedSettings := transformTsvSettings(output.settings)
802
+
803
+
804
+ columnsSpec := {}
805
+ axesSpec := copy(iterationAxesSpec)
806
+ for axis in output.settings.axes {
807
+ axesSpec = append(axesSpec, axis.spec)
808
+ }
809
+
810
+ for column in output.settings.columns {
811
+ columnId := getTsvColumnId(column)
812
+
813
+
814
+ spec := maps.merge(column.spec, { axesSpec: axesSpec, kind: "PColumn" })
815
+ if !is_undefined(traceInfo.trace) {
816
+ spec = traceInfo.trace.inject(spec, {override: traceInfo.overrideTrace})
817
+ }
818
+ columnsSpec[columnId] = spec
819
+ }
820
+
821
+ outputSpecs[output.name] = columnsSpec
822
+ processedOutputs = append(processedOutputs, maps.merge(output, {
823
+ settings: transformedSettings,
824
+ flattenWithDelimiter: "/",
825
+ traceSteps: undefined,
826
+ overrideTrace: undefined
827
+ }))
414
828
  } else {
415
829
  ll.panic("unknown output type: " + output.type)
416
830
  }
@@ -455,9 +869,9 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
455
869
  }
456
870
 
457
871
  spec := outputSpecs[name]
458
- if output.type == "Xsv" {
872
+ if output.type == "Xsv" || output.type == "TsvContent" {
459
873
  if len(column) != 1 {
460
- ll.panic("column name must be provided for Xsv output")
874
+ ll.panic("column name must be provided for " + output.type + " output")
461
875
  }
462
876
  columnName := column[0]
463
877
  spec = spec[columnName]
@@ -467,7 +881,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
467
881
  return spec
468
882
  } else {
469
883
  if len(column) > 0 {
470
- ll.panic("column name should not be provided for non-Xsv output")
884
+ ll.panic("column name should not be provided for non-Xsv/TsvContent output")
471
885
  }
472
886
  return spec
473
887
  }
@@ -490,14 +904,14 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
490
904
  ll.panic("unknown output: " + name)
491
905
  }
492
906
 
493
- if output.type == "Xsv" {
907
+ if output.type == "Xsv" || output.type == "TsvContent" {
494
908
  if len(column) != 1 {
495
- ll.panic("column name must be provided for Xsv output")
909
+ ll.panic("column name must be provided for " + output.type + " output")
496
910
  }
497
911
  return renderResult.output(name + "/" + column[0])
498
912
  } else {
499
913
  if len(column) > 0 {
500
- ll.panic("column name should not be provided for non-Xsv output")
914
+ ll.panic("column name should not be provided for non-Xsv/TsvContent output")
501
915
  }
502
916
  return renderResult.output(name)
503
917
  }
@@ -520,9 +934,9 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
520
934
  ll.panic("unknown output: " + name)
521
935
  }
522
936
 
523
- if output.type == "Xsv" {
937
+ if output.type == "Xsv" || output.type == "TsvContent" {
524
938
  if len(column) != 1 {
525
- ll.panic("column name must be provided for Xsv output")
939
+ ll.panic("column name must be provided for " + output.type + " output")
526
940
  }
527
941
  columnName := column[0]
528
942
  spec := outputSpecs[name][columnName]
@@ -535,7 +949,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
535
949
  }
536
950
  } else {
537
951
  if len(column) > 0 {
538
- ll.panic("column name should not be provided for non-Xsv output")
952
+ ll.panic("column name should not be provided for non-Xsv/TsvContent output")
539
953
  }
540
954
  return {
541
955
  data: renderResult.output(name),
@@ -556,8 +970,8 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
556
970
  ll.panic("unknown output: " + name)
557
971
  }
558
972
 
559
- if output.type != "Xsv" {
560
- ll.panic("outputFrame can only be used with Xsv outputs")
973
+ if output.type != "Xsv" && output.type != "TsvContent" {
974
+ ll.panic("outputFrame can only be used with Xsv or TsvContent outputs")
561
975
  }
562
976
 
563
977
  builder := builder.pFrameBuilder()
@@ -581,7 +995,7 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
581
995
  }
582
996
 
583
997
  maps.forEach(outputsMap, func(name, output) {
584
- if output.type == "Xsv" {
998
+ if output.type == "Xsv" || output.type == "TsvContent" {
585
999
 
586
1000
  for columnName, spec in outputSpecs[name] {
587
1001
  builder.add(
@@ -649,8 +1063,8 @@ processColumn := func(input, bodyTpl, outputs, ...opts) {
649
1063
  if is_undefined(output) {
650
1064
  ll.panic("unknown output: " + name)
651
1065
  }
652
- if output.type != "Xsv" {
653
- ll.panic("output is not Xsv: " + name)
1066
+ if output.type != "Xsv" && output.type != "TsvContent" {
1067
+ ll.panic("output is not Xsv or TsvContent: " + name)
654
1068
  }
655
1069
 
656
1070
  return maps.getKeys(outputSpecs[name])
@@ -690,5 +1104,6 @@ export ll.toStrict({
690
1104
  exportColumnData: exportColumnData,
691
1105
  pColumnResourceMapDataBuilder: pColumnResourceMapDataBuilder,
692
1106
  tsvFileBuilder: func() { return xsvBuilder.xsvFileBuilder("tsv") },
693
- csvFileBuilder: func() { return xsvBuilder.xsvFileBuilder("csv") }
1107
+ csvFileBuilder: func() { return xsvBuilder.xsvFileBuilder("csv") },
1108
+ parseToJson: parseToJson
694
1109
  })
@@ -258,10 +258,44 @@ makeTrace := func(input, ...steps) {
258
258
  return ll.toStrict({
259
259
  value: currentTrace,
260
260
  valueStr: currentTraceStr,
261
-
262
- inject: func(spec) {
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
- return maps.deepMerge(spec, {annotations: {"pl7.app/trace": currentTraceStr}})
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
  }
@@ -310,7 +310,7 @@ normalize := func(s) {
310
310
  if is_undefined(s) {
311
311
  return []
312
312
  }
313
- return s
313
+ return copy(s)
314
314
  }
315
315
 
316
316
  export ll.toStrict({
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.12.0",
3
+ "version": "4.14.0",
4
4
  "description": "Tengo SDK library",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.js",
@@ -21,7 +21,7 @@
21
21
  "@platforma-open/milaboratories.software-ptabler": "1.8.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@platforma-sdk/tengo-builder": "^2.1.12"
24
+ "@platforma-sdk/tengo-builder": "^2.1.13"
25
25
  },
26
26
  "scripts": {
27
27
  "type-check": "pl-tengo check",