@platforma-sdk/workflow-tengo 4.5.2 → 4.6.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 (40) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +6 -6
  3. package/dist/index.mjs +6 -6
  4. package/dist/tengo/lib/pframes.bundle.lib.tengo +37 -300
  5. package/dist/tengo/lib/pframes.lib.tengo +4 -1
  6. package/dist/tengo/lib/pframes.spec.lib.tengo +21 -1
  7. package/dist/tengo/lib/pframes.xsv-builder.lib.tengo +625 -0
  8. package/dist/tengo/lib/pt.expression.lib.tengo +905 -0
  9. package/dist/tengo/lib/pt.lib.tengo +980 -0
  10. package/dist/tengo/lib/tpl.base.lib.tengo +6 -1
  11. package/dist/tengo/tpl/check_network.create_workdir_from_storage.plj.gz +0 -0
  12. package/dist/tengo/tpl/check_network.download_blob.plj.gz +0 -0
  13. package/dist/tengo/tpl/check_network.run_hello_world.plj.gz +0 -0
  14. package/dist/tengo/tpl/check_network.run_hello_world_py.plj.gz +0 -0
  15. package/dist/tengo/tpl/check_network.upload_blob.plj.gz +0 -0
  16. package/dist/tengo/tpl/check_network.upload_template.plj.gz +0 -0
  17. package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
  18. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  19. package/dist/tengo/tpl/exec.monetization_info.plj.gz +0 -0
  20. package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
  21. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  22. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  23. package/dist/tengo/tpl/exec.python.venv-bin-path.plj.gz +0 -0
  24. package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
  25. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  26. package/dist/tengo/tpl/pframes.export-pframe-for-ui.plj.gz +0 -0
  27. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  28. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  29. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  30. package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
  31. package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
  32. package/dist/tengo/tpl/pframes.slice-data.plj.gz +0 -0
  33. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  34. package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
  35. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  36. package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
  37. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  38. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  39. package/dist/tengo/tpl/workflow.query-anchored.plj.gz +0 -0
  40. package/package.json +4 -3
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" | "exec.R.create-renv" | "exec.python.install-deps" | "exec.python.venv-bin-path" | "pframes.export-multiple-pcolumns" | "exec.python.create-venv" | "exec.monetization_to_json" | "exec.exec" | "exec.monetization_info" | "pframes.xsv-export-pframe" | "pframes.xsv-import-if-not-null" | "pframes.xsv-import-map" | "pframes.process-pcolumn-data" | "pframes.slice-data" | "check_network.create_workdir_from_storage" | "check_network.download_blob" | "check_network.run_hello_world" | "check_network.run_hello_world_py" | "check_network.upload_blob" | "check_network.upload_template" | "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" | "exec.R.create-renv" | "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.python.create-venv" | "exec.monetization_to_json" | "exec.exec" | "exec.monetization_info" | "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
@@ -11,6 +11,11 @@ module.exports = { Templates: {
11
11
  'exec.python.install-deps': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.python.install-deps.plj.gz') },
12
12
  'exec.python.venv-bin-path': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.python.venv-bin-path.plj.gz') },
13
13
  'pframes.export-multiple-pcolumns': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.export-multiple-pcolumns.plj.gz') },
14
+ 'pframes.slice-data': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.slice-data.plj.gz') },
15
+ 'check_network.create_workdir_from_storage': { type: 'from-file', path: require.resolve('./tengo/tpl/check_network.create_workdir_from_storage.plj.gz') },
16
+ 'check_network.download_blob': { type: 'from-file', path: require.resolve('./tengo/tpl/check_network.download_blob.plj.gz') },
17
+ 'check_network.upload_blob': { type: 'from-file', path: require.resolve('./tengo/tpl/check_network.upload_blob.plj.gz') },
18
+ 'check_network.upload_template': { type: 'from-file', path: require.resolve('./tengo/tpl/check_network.upload_template.plj.gz') },
14
19
  'exec.python.create-venv': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.python.create-venv.plj.gz') },
15
20
  'exec.monetization_to_json': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.monetization_to_json.plj.gz') },
16
21
  'exec.exec': { type: 'from-file', path: require.resolve('./tengo/tpl/exec.exec.plj.gz') },
@@ -18,14 +23,9 @@ module.exports = { Templates: {
18
23
  'pframes.xsv-export-pframe': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.xsv-export-pframe.plj.gz') },
19
24
  'pframes.xsv-import-if-not-null': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.xsv-import-if-not-null.plj.gz') },
20
25
  'pframes.xsv-import-map': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.xsv-import-map.plj.gz') },
21
- 'pframes.process-pcolumn-data': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.process-pcolumn-data.plj.gz') },
22
- 'pframes.slice-data': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.slice-data.plj.gz') },
23
- 'check_network.create_workdir_from_storage': { type: 'from-file', path: require.resolve('./tengo/tpl/check_network.create_workdir_from_storage.plj.gz') },
24
- 'check_network.download_blob': { type: 'from-file', path: require.resolve('./tengo/tpl/check_network.download_blob.plj.gz') },
25
26
  'check_network.run_hello_world': { type: 'from-file', path: require.resolve('./tengo/tpl/check_network.run_hello_world.plj.gz') },
26
27
  'check_network.run_hello_world_py': { type: 'from-file', path: require.resolve('./tengo/tpl/check_network.run_hello_world_py.plj.gz') },
27
- 'check_network.upload_blob': { type: 'from-file', path: require.resolve('./tengo/tpl/check_network.upload_blob.plj.gz') },
28
- 'check_network.upload_template': { type: 'from-file', path: require.resolve('./tengo/tpl/check_network.upload_template.plj.gz') },
28
+ 'pframes.process-pcolumn-data': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.process-pcolumn-data.plj.gz') },
29
29
  'pframes.export-pframe': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.export-pframe.plj.gz') },
30
30
  'pframes.export-pframe-for-ui': { type: 'from-file', path: require.resolve('./tengo/tpl/pframes.export-pframe-for-ui.plj.gz') }
31
31
  }};
package/dist/index.mjs CHANGED
@@ -12,6 +12,11 @@ export const Templates = {
12
12
  'exec.python.install-deps': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.python.install-deps.plj.gz') },
13
13
  'exec.python.venv-bin-path': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.python.venv-bin-path.plj.gz') },
14
14
  'pframes.export-multiple-pcolumns': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.export-multiple-pcolumns.plj.gz') },
15
+ 'pframes.slice-data': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.slice-data.plj.gz') },
16
+ 'check_network.create_workdir_from_storage': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/check_network.create_workdir_from_storage.plj.gz') },
17
+ 'check_network.download_blob': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/check_network.download_blob.plj.gz') },
18
+ 'check_network.upload_blob': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/check_network.upload_blob.plj.gz') },
19
+ 'check_network.upload_template': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/check_network.upload_template.plj.gz') },
15
20
  'exec.python.create-venv': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.python.create-venv.plj.gz') },
16
21
  'exec.monetization_to_json': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.monetization_to_json.plj.gz') },
17
22
  'exec.exec': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/exec.exec.plj.gz') },
@@ -19,14 +24,9 @@ export const Templates = {
19
24
  'pframes.xsv-export-pframe': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.xsv-export-pframe.plj.gz') },
20
25
  'pframes.xsv-import-if-not-null': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.xsv-import-if-not-null.plj.gz') },
21
26
  'pframes.xsv-import-map': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.xsv-import-map.plj.gz') },
22
- 'pframes.process-pcolumn-data': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.process-pcolumn-data.plj.gz') },
23
- 'pframes.slice-data': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.slice-data.plj.gz') },
24
- 'check_network.create_workdir_from_storage': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/check_network.create_workdir_from_storage.plj.gz') },
25
- 'check_network.download_blob': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/check_network.download_blob.plj.gz') },
26
27
  'check_network.run_hello_world': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/check_network.run_hello_world.plj.gz') },
27
28
  'check_network.run_hello_world_py': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/check_network.run_hello_world_py.plj.gz') },
28
- 'check_network.upload_blob': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/check_network.upload_blob.plj.gz') },
29
- 'check_network.upload_template': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/check_network.upload_template.plj.gz') },
29
+ 'pframes.process-pcolumn-data': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.process-pcolumn-data.plj.gz') },
30
30
  'pframes.export-pframe': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.export-pframe.plj.gz') },
31
31
  'pframes.export-pframe-for-ui': { type: 'from-file', path: resolve(import.meta.dirname, './tengo/tpl/pframes.export-pframe-for-ui.plj.gz') }
32
32
  };
@@ -1,17 +1,13 @@
1
1
  smart := import("@platforma-sdk/workflow-tengo:smart")
2
2
  json := import("json")
3
- text := import("text")
4
3
  pConstants := import("@platforma-sdk/workflow-tengo:pframes.constants")
5
4
  bquery := import("@platforma-sdk/workflow-tengo:workflow.bquery")
6
5
  canonical := import("@platforma-sdk/workflow-tengo:canonical")
7
6
  pSpec := import("@platforma-sdk/workflow-tengo:pframes.spec")
8
- pBuilder := import("@platforma-sdk/workflow-tengo:pframes.builder")
9
7
  maps := import("@platforma-sdk/workflow-tengo:maps")
10
8
  ll := import("@platforma-sdk/workflow-tengo:ll")
11
- xsv := import("@platforma-sdk/workflow-tengo:pframes.xsv")
12
9
  assets := import("@platforma-sdk/workflow-tengo:assets")
13
10
  render := import("@platforma-sdk/workflow-tengo:render")
14
- strings := import("@platforma-sdk/workflow-tengo:strings")
15
11
 
16
12
 
17
13
 
@@ -167,7 +163,6 @@ createBuilder := func(ctx) {
167
163
  ll.panic("Invalid options type. Expected map got ", ops[1])
168
164
  }
169
165
  if !is_undefined(ops[1].overrides) {
170
-
171
166
 
172
167
  decodedQuery = maps.deepMerge(decodedQuery, ops[1].overrides)
173
168
  }
@@ -175,7 +170,7 @@ createBuilder := func(ctx) {
175
170
 
176
171
 
177
172
  decodedQuery.matchStrategy = "expectMultiple"
178
-
173
+
179
174
  keyToUse := undefined
180
175
  if !is_undefined(queryKey) {
181
176
  keyToUse = queryKey
@@ -379,18 +374,20 @@ pColumnBundleUnmarshaller := func() {
379
374
  if is_array(result) {
380
375
  arr := []
381
376
  for i, r in result {
382
- k := resultKey + string(i)
377
+ ll.assert(!is_undefined(r.ref), "Expected ref in result: %v", r)
378
+ k := resultKey + "." + canonical.encode(r.ref)
383
379
  el := {
384
380
  key: k,
385
381
  spec: r.spec,
386
382
  data: r.data
387
383
  }
388
- pool[k] = el
384
+ pool[k] = el
389
385
  arr = append(arr, el)
390
386
  }
391
387
  pool[resultKey] = arr
392
388
  } else {
393
389
  pool[resultKey] = {
390
+ key: resultKey,
394
391
  spec: result.spec,
395
392
  data: result.data
396
393
  }
@@ -423,6 +420,7 @@ pColumnBundleUnmarshaller := func() {
423
420
 
424
421
 
425
422
 
423
+
426
424
  getColumns: func(resultKey) {
427
425
  result := get(resultKey)
428
426
  if !is_array(result) {
@@ -436,12 +434,39 @@ pColumnBundleUnmarshaller := func() {
436
434
 
437
435
 
438
436
 
437
+
439
438
  getColumn: func(resultKey) {
440
- result := get(resultKey)
439
+ processedId := processColumnId(resultKey)
440
+ columnKeyForPool := processedId.columnKey // Key to fetch from the pool (source for filtered)
441
+ columnAxisFilters := processedId.axisFilters // Filters from FilteredPColumnId
442
+ outputKey := processedId.canonicalId // Key for the output, canonical of original input or filtered ID
443
+
444
+ result := pool[columnKeyForPool]
445
+ if is_undefined(result) {
446
+ ll.panic("Column not found: %v. Pool: %v", columnKeyForPool, maps.getKeys(pool))
447
+ }
448
+
441
449
  if is_array(result) {
442
- ll.panic("Cannot get a single column from a multi-column result: %v. Use getColumns() instead.", resultKey)
450
+ ll.panic("Cannot get a single column from a multi-column result: %v. Use getColumns() instead.", columnKeyForPool)
451
+ }
452
+
453
+ currentSpec := bundle.getSpec(resultKey) // getSpec already handles filtering for the spec
454
+ currentData := result.data
455
+
456
+
457
+ if !is_undefined(columnAxisFilters) && len(columnAxisFilters) > 0 {
458
+ sliceDataTemplate := assets.importTemplate("@platforma-sdk/workflow-tengo:pframes.slice-data")
459
+ currentData = render.createEphemeral(sliceDataTemplate, {
460
+ data: currentData,
461
+ slicingParams: smart.createJsonResource(columnAxisFilters)
462
+ }).output("result")
463
+ }
464
+
465
+ return {
466
+ key: outputKey,
467
+ spec: currentSpec,
468
+ data: currentData
443
469
  }
444
- return result
445
470
  },
446
471
 
447
472
 
@@ -463,7 +488,7 @@ pColumnBundleUnmarshaller := func() {
463
488
  if is_array(result) {
464
489
  ll.panic("Cannot get a single column from a multi-column result: " + columnKey + ". Use get() instead.")
465
490
  }
466
-
491
+
467
492
  baseSpec := result.spec
468
493
 
469
494
 
@@ -489,294 +514,6 @@ pColumnBundleUnmarshaller := func() {
489
514
 
490
515
  axisHeaderOverrides = [[matcher, header]] + axisHeaderOverrides
491
516
  return bundle
492
- },
493
-
494
-
495
-
496
-
497
- xsvTableBuilder: func() {
498
- localAxisHeaderOverrides := copy(axisHeaderOverrides)
499
-
500
- requests := []
501
- addedColumns := {}
502
-
503
- distiller := undefined
504
-
505
- getSpecDistiller := func() {
506
- if is_undefined(distiller) {
507
- columnsToDistill := []
508
- for request in requests {
509
- col := pool[request.key]
510
- columnsToDistill = append(columnsToDistill, col.spec)
511
- }
512
- distiller = pSpec.createSpecDistiller(columnsToDistill)
513
- }
514
- return distiller
515
- }
516
-
517
- findAxisHeaderOverride := func(spec) {
518
- for _, override in localAxisHeaderOverrides {
519
- matcher := override[0]
520
-
521
- if matcher.name == spec.name {
522
- specDistiller := getSpecDistiller()
523
- discriminativeDomains := specDistiller.getDiscriminativeDomainsSet(spec.name)
524
-
525
- domainsMatch := true
526
-
527
- for domainKey, domainValue in matcher.domain {
528
- if is_undefined(discriminativeDomains[domainKey]) {
529
- continue
530
- }
531
-
532
- if is_undefined(spec.domain) ||
533
- is_undefined(spec.domain[domainKey]) ||
534
- spec.domain[domainKey] != domainValue {
535
- domainsMatch = false
536
- break
537
- }
538
- }
539
-
540
- if domainsMatch {
541
- return override[1]
542
- }
543
- }
544
- }
545
- return undefined
546
- }
547
-
548
- generateLabelForAxis := func(spec) {
549
- name := spec.name
550
- label := undefined
551
-
552
- label = findAxisHeaderOverride(spec)
553
-
554
- if is_undefined(label) {
555
- specDistiller := getSpecDistiller()
556
- discriminativeDomains := specDistiller.getDiscriminativeDomains(name)
557
-
558
- if len(discriminativeDomains) == 0 {
559
- label = strings.substituteSpecialCharacters(name)
560
- } else {
561
- ll.panic("Cannot deduce header for %s in axis. Discriminative domains: %s. Please provide a header override.",
562
- name, discriminativeDomains)
563
- }
564
- }
565
-
566
- if is_undefined(label) {
567
- ll.panic("Cannot deduce header for %s in axis. Please provide a header override.",
568
- name)
569
- }
570
-
571
- return label
572
- }
573
-
574
-
575
- findRequestByItem := func(item) {
576
- serializedId := processColumnId(item).canonicalId
577
- for _, request in requests {
578
- if request.canonicalId == serializedId {
579
- return request
580
- }
581
- }
582
-
583
- ll.panic("Column not found in the table: %s. Make sure to call add() first.",
584
- serializedId)
585
- }
586
-
587
- tableBuilder := undefined
588
- tableBuilder = {
589
-
590
-
591
-
592
-
593
-
594
-
595
-
596
- add: func(key, ...ops) {
597
-
598
- distiller = undefined
599
-
600
- processedId := processColumnId(key)
601
- columnKey := processedId.columnKey
602
- columnAxisFilters := processedId.axisFilters
603
- serializedId := processedId.canonicalId
604
-
605
- if is_undefined(pool[columnKey]) {
606
- ll.panic("Column not found: " + columnKey)
607
- }
608
-
609
- request := {
610
- key: columnKey,
611
- canonicalId: serializedId
612
- }
613
-
614
- if !is_undefined(columnAxisFilters) {
615
- request.axisFilters = columnAxisFilters
616
- }
617
-
618
- if len(ops) > 0 {
619
- if !is_undefined(ops[0].header) {
620
- request.headerOverride = ops[0].header
621
- }
622
-
623
- if !is_undefined(ops[0].axisFilters) {
624
- if !is_undefined(request.axisFilters) {
625
- ll.panic("Cannot provide axis filters in both FilteredPColumnId and options. Use either one, not both.")
626
- } else {
627
- request.axisFilters = ops[0].axisFilters
628
-
629
- request.canonicalId = canonical.encode({
630
- source: json.decode(columnKey),
631
- axisFilters: ops[0].axisFilters
632
- })
633
- }
634
- }
635
- }
636
-
637
- if !is_undefined(request.axisFilters) && len(request.axisFilters) > 0 {
638
- colSpec := pool[columnKey].spec
639
- prepared := pSpec.prepareAxisFilters(request.axisFilters, colSpec)
640
-
641
- request.axisFilters = prepared.axisFilters
642
- request.columnSpec = prepared.columnSpec
643
- } else {
644
- request.columnSpec = pool[columnKey].spec
645
- }
646
-
647
- if !is_undefined(addedColumns[request.canonicalId]) {
648
- ll.panic("Duplicate column detected: %s. This column has already been added to the table.",
649
- request.canonicalId)
650
- }
651
-
652
- addedColumns[request.canonicalId] = true
653
-
654
- request.safeId = strings.substituteSpecialCharacters(request.canonicalId)
655
-
656
- if !is_undefined(request.headerOverride) {
657
- request.header = request.headerOverride
658
- } else {
659
-
660
- request.header = request.safeId
661
- }
662
-
663
- requests = append(requests, request)
664
- return tableBuilder
665
- },
666
-
667
-
668
-
669
-
670
-
671
-
672
-
673
- setAxisHeader: func(matcher, header) {
674
- if is_string(matcher) {
675
- matcher = { name: matcher, domain: {} }
676
- }
677
-
678
- localAxisHeaderOverrides = [[matcher, header]] + localAxisHeaderOverrides
679
- return tableBuilder
680
- },
681
-
682
-
683
-
684
-
685
-
686
-
687
-
688
-
689
-
690
-
691
- build: func(format, ...params) {
692
- if format != "csv" && format != "tsv" {
693
- ll.panic("Invalid format: '%s'. Expected 'csv' or 'tsv'.", format)
694
- }
695
-
696
- exportParams := {
697
- naStr: "",
698
- nullStr: ""
699
- }
700
- if len(params) > 0 {
701
- exportParams = maps.deepMerge(exportParams, params[0])
702
- }
703
-
704
- sliceDataTemplate := assets.importTemplate("@platforma-sdk/workflow-tengo:pframes.slice-data")
705
-
706
- columnDistiller := getSpecDistiller()
707
-
708
- pFrame := pBuilder.pFrameBuilder()
709
-
710
- idx := 0
711
- for request in requests {
712
- col := pool[request.key]
713
- colData := col.data
714
-
715
- if !is_undefined(request.axisFilters) {
716
- colData = render.createEphemeral(sliceDataTemplate, {
717
- data: colData,
718
- slicingParams: smart.createJsonResource(request.axisFilters)
719
- }).output("result")
720
- }
721
-
722
- preparedSpec := columnDistiller.distill(request.columnSpec)
723
-
724
- preparedSpec = maps.deepMerge(preparedSpec, {
725
- annotations: { "pl7.app/label": request.header }
726
- })
727
-
728
- for i, axis in preparedSpec.axesSpec {
729
- preparedSpec.axesSpec[i] = maps.deepMerge(axis, {
730
- annotations: { "pl7.app/label": generateLabelForAxis(axis) }
731
- })
732
- }
733
-
734
-
735
-
736
-
737
-
738
-
739
-
740
- pFrame.add(string(idx), preparedSpec, colData)
741
- idx += 1
742
- }
743
-
744
- return xsv.exportFrame(pFrame.build(), format, exportParams)
745
- },
746
-
747
-
748
-
749
-
750
-
751
-
752
-
753
-
754
- getHeader: func(item) {
755
-
756
- if is_map(item) && !is_undefined(item.type) {
757
- return generateLabelForAxis(item)
758
- }
759
-
760
-
761
- request := findRequestByItem(item)
762
- return request.header
763
- },
764
-
765
-
766
-
767
-
768
-
769
-
770
-
771
-
772
- getSpec: func(item) {
773
-
774
- request := findRequestByItem(item)
775
- return request.columnSpec
776
- }
777
- }
778
-
779
- return tableBuilder
780
517
  }
781
518
  })
782
519
 
@@ -13,6 +13,7 @@ pUtil := import("@platforma-sdk/workflow-tengo:pframes.util")
13
13
  pSpec := import("@platforma-sdk/workflow-tengo:pframes.spec")
14
14
  validation := import("@platforma-sdk/workflow-tengo:validation")
15
15
  constants := import("@platforma-sdk/workflow-tengo:pframes.constants")
16
+ xsvBuilder := import("@platforma-sdk/workflow-tengo:pframes.xsv-builder")
16
17
 
17
18
  llProcessTpl := assets.importTemplate("@platforma-sdk/workflow-tengo:pframes.process-pcolumn-data")
18
19
 
@@ -610,5 +611,7 @@ export ll.toStrict({
610
611
  exportFrame: exportFrame,
611
612
  pFrameBuilder: builder.pFrameBuilder,
612
613
  exportColumnData: exportColumnData,
613
- pColumnResourceMapDataBuilder: pColumnResourceMapDataBuilder
614
+ pColumnResourceMapDataBuilder: pColumnResourceMapDataBuilder,
615
+ tsvFileBuilder: func() { return xsvBuilder.xsvFileBuilder("tsv") },
616
+ csvFileBuilder: func() { return xsvBuilder.xsvFileBuilder("csv") }
614
617
  })
@@ -477,6 +477,25 @@ prepareAxisFilters := func(rules, spec) {
477
477
  }
478
478
  }
479
479
 
480
+
481
+
482
+
483
+
484
+
485
+
486
+
487
+ axisSpecToMatcher := func(axisSpec) {
488
+ validation.assertType(axisSpec, P_AXIS_SPEC_SCHEMA)
489
+ matcher := {
490
+ name: axisSpec.name,
491
+ type: axisSpec.type
492
+ }
493
+ if !is_undefined(axisSpec.domain) {
494
+ matcher.domain = maps.clone(axisSpec.domain) // Clone to avoid modifying original spec's domain
495
+ }
496
+ return matcher
497
+ }
498
+
480
499
  export ll.toStrict({
481
500
  P_AXIS_SPEC_SCHEMA: P_AXIS_SPEC_SCHEMA,
482
501
  P_COLUMN_SPEC_SCHEMA: P_COLUMN_SPEC_SCHEMA,
@@ -500,6 +519,7 @@ export ll.toStrict({
500
519
 
501
520
  createSpecDistiller: createSpecDistiller,
502
521
 
503
- prepareAxisFilters: prepareAxisFilters
522
+ prepareAxisFilters: prepareAxisFilters,
523
+ axisSpecToMatcher: axisSpecToMatcher
504
524
  })
505
525