@platforma-sdk/workflow-tengo 2.8.0 → 2.8.2

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 (59) hide show
  1. package/dist/tengo/lib/assets.lib.tengo +76 -82
  2. package/dist/tengo/lib/constants.lib.tengo +28 -31
  3. package/dist/tengo/lib/exec.R.internal.lib.tengo +14 -14
  4. package/dist/tengo/lib/exec.R.lib.tengo +158 -167
  5. package/dist/tengo/lib/exec.internal.lib.tengo +222 -234
  6. package/dist/tengo/lib/exec.lib.tengo +647 -714
  7. package/dist/tengo/lib/exec.package.lib.tengo +229 -238
  8. package/dist/tengo/lib/exec.python.internal.lib.tengo +5 -6
  9. package/dist/tengo/lib/exec.python.lib.tengo +138 -146
  10. package/dist/tengo/lib/exec.runcmd.lib.tengo +234 -253
  11. package/dist/tengo/lib/exec.runenv.lib.tengo +88 -92
  12. package/dist/tengo/lib/exec.stream.lib.tengo +36 -40
  13. package/dist/tengo/lib/file.internal.lib.tengo +70 -77
  14. package/dist/tengo/lib/file.lib.tengo +54 -57
  15. package/dist/tengo/lib/ll.lib.tengo +217 -241
  16. package/dist/tengo/lib/maps.lib.tengo +98 -106
  17. package/dist/tengo/lib/objects.lib.tengo +11 -13
  18. package/dist/tengo/lib/oop.lib.tengo +16 -19
  19. package/dist/tengo/lib/path.lib.tengo +116 -125
  20. package/dist/tengo/lib/pframes.constants.lib.tengo +25 -28
  21. package/dist/tengo/lib/pframes.export-pcolumn.lib.tengo +28 -33
  22. package/dist/tengo/lib/pframes.lib.tengo +38 -43
  23. package/dist/tengo/lib/pframes.ll.lib.tengo +70 -73
  24. package/dist/tengo/lib/pframes.pcolumn.lib.tengo +45 -51
  25. package/dist/tengo/lib/pframes.spec.lib.tengo +70 -96
  26. package/dist/tengo/lib/pframes.util.lib.tengo +154 -289
  27. package/dist/tengo/lib/pframes.xsv.lib.tengo +260 -273
  28. package/dist/tengo/lib/render.lib.tengo +65 -76
  29. package/dist/tengo/lib/sets.lib.tengo +61 -68
  30. package/dist/tengo/lib/slices.lib.tengo +169 -180
  31. package/dist/tengo/lib/smart.lib.tengo +956 -1069
  32. package/dist/tengo/lib/test.lib.tengo +129 -161
  33. package/dist/tengo/lib/tpl.lib.tengo +448 -516
  34. package/dist/tengo/lib/tpl.state-await.lib.tengo +226 -241
  35. package/dist/tengo/lib/tpl.util.lib.tengo +4 -9
  36. package/dist/tengo/lib/validation.lib.tengo +334 -379
  37. package/dist/tengo/lib/workdir.lib.tengo +309 -332
  38. package/dist/tengo/lib/workdir.proc.lib.tengo +126 -144
  39. package/dist/tengo/lib/workdir.save.lib.tengo +113 -130
  40. package/dist/tengo/lib/workflow.bobject.lib.tengo +21 -26
  41. package/dist/tengo/lib/workflow.bquery.lib.tengo +140 -166
  42. package/dist/tengo/lib/workflow.constants.lib.tengo +1 -2
  43. package/dist/tengo/lib/workflow.context.lib.tengo +27 -32
  44. package/dist/tengo/lib/workflow.lib.tengo +167 -207
  45. package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
  46. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  47. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  48. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  49. package/dist/tengo/tpl/pframes.aggregate.plj.gz +0 -0
  50. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  51. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  52. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  53. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  54. package/dist/tengo/tpl/pframes.map-pframe.plj.gz +0 -0
  55. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  56. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  57. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  58. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  59. package/package.json +5 -5
@@ -1,325 +1,190 @@
1
1
  ll := import("@platforma-sdk/workflow-tengo:ll")
2
2
  validation := import("@platforma-sdk/workflow-tengo:validation")
3
- constants := import("@platforma-sdk/workflow-tengo:pframes.constants")
4
3
  objects := import("@platforma-sdk/workflow-tengo:objects")
5
4
 
6
5
  _PRE_PROCESS_STEP_SCHEMA := [`or`,
7
- {
8
- // Perform JS String.prototype.replace() operation
9
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace
10
- `type`: `string,regex=regexpReplace`,
11
- // String representing ECMAScript RegEx with at least one capturing group.
12
- // If you need to reorder capturing groups - use RegExp matching the whole string
13
- // (must start with string begin anchor ^, end with string end anchor $).
14
- // Use regex playground https://regexr.com/ to test your ideas.
15
- `pattern`: `string`,
16
- // Replacement pattern used to construct result string from captured groups
17
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement
18
- // Empty string as result would become NA.
19
- `replacement`: `string`
20
- },
21
- {
22
- // Simplified 'regexpReplace' with replacement set to $1.
23
- // This means that string is replaced with first capture group value.
24
- // Example 1:
25
- // - input: 123___abc.xlsx
26
- // - pattern: \d+___([a-z]+).xlsx
27
- // - result: abc
28
- // Example 2:
29
- // - input: 123___abc.xlsx
30
- // - pattern: (\d+)___([a-z]+).xlsx
31
- // - result: 123
32
- // Example 3:
33
- // - input: 123___abc.xlsx
34
- // - pattern: ((\d+)___([a-z]+)).xlsx
35
- // - result: 123___abc
36
- `type`: `string,regex=regexpExtract`,
37
- // String representing ECMAScript RegEx with at least one capturing group.
38
- // RegEx must match the entire string, this would be enforced even when ^ and $ are skipped.
39
- // If there are no matches - value would be replaced with empty string.
40
- // Wrong example:
41
- // - input: 123___abc.xlsx
42
- // - pattern: (\d+___[a-z]+)
43
- // - result: empty string, as .xlsx part is missing in pattern, so pattern was not matched
44
- // Correct example:
45
- // - input: 123___abc.xlsx
46
- // - pattern: (\d+___[a-z]+).xlsx
47
- // - result: 123___abc
48
- `pattern`: `string`
49
- }]
6
+ {
7
+ `type`: `string,regex=regexpReplace`,
8
+ `pattern`: `string`,
9
+ `replacement`: `string`
10
+ },
11
+ {
12
+ `type`: `string,regex=regexpExtract`,
13
+ `pattern`: `string`
14
+ }]
50
15
 
51
16
  _SPEC_AXES_SCHEMA := {
52
- // Column label from XSV
53
- `column`: `string`,
54
- // Regular expression, if matched - whole row would be skipped;
55
- // Performed just after reading XSV before any other operations;
56
- // default: no filter
57
- `filterOutRegex,?`: `string`,
58
- // Pre-processing operations to be performed just after filtering out rows
59
- `preProcess,?`: [_PRE_PROCESS_STEP_SCHEMA],
60
- // Regular expression, if matched - value is considered to be N/A;
61
- // default: Int, Long - check that the value is a valid integer number;
62
- // Float, Double - check that the value is a valid float number, not a NaN;
63
- // String - accept anything;
64
- `naRegex,?`: `string`,
65
- // Should the N/A values (or empty rows) be allowed;
66
- // default: false
67
- `allowNA,?`: `bool`,
68
- // Specification of the axis
69
- `spec`: {
70
- // Type of axis values
71
- `type`: `string,regex=Int|Long|Float|Double|String`,
72
- // Name of the axis to be used in spec;
73
- // default: column label
74
- `name,?`: `string`,
75
- // Auxiliary information to the axis name, type and parents to form a unique identifier;
76
- // default: empty
77
- `domain,?`: { any: `string` },
78
- // Any additional information attached to the axis that does not affect its identifier;
79
- // default: "pl7.app/label": Column label from XSV
80
- `annotations,?`: { any: `string` },
81
- // A list of zero-based indices of parent axes in the overall axes specification;
82
- // default: empty
83
- `parentAxes,?`: [`number`]
84
- }
17
+ `column`: `string`,
18
+ `filterOutRegex,?`: `string`,
19
+ `preProcess,?`: [_PRE_PROCESS_STEP_SCHEMA],
20
+ `naRegex,?`: `string`,
21
+ `allowNA,?`: `bool`,
22
+ `spec`: {
23
+ `type`: `string,regex=Int|Long|Float|Double|String`,
24
+ `name,?`: `string`,
25
+ `domain,?`: { any: `string` },
26
+ `annotations,?`: { any: `string` },
27
+ `parentAxes,?`: [`number`]
28
+ }
85
29
  }
86
30
 
87
31
  _SPEC_COLUMN_SCHEMA := {
88
- // Column label from XSV
89
- `column`: `string`,
90
- // Regular expression, if matched - whole row would be skipped;
91
- // Performed just after reading XSV before any other operations;
92
- // default: no filter
93
- `filterOutRegex,?`: `string`,
94
- // Pre-processing operations to be performed just after filtering out rows
95
- `preProcess,?`: [_PRE_PROCESS_STEP_SCHEMA],
96
- // Regular expression, if matched - value is considered to be N/A;
97
- // default: Int, Long - check that the value is a valid integer number;
98
- // Float, Double - check that the value is a valid float number, not a NaN;
99
- // String - accept anything;
100
- `naRegex,?`: `string`,
101
- // Should the N/A values (or empty rows) be allowed;
102
- // default: true
103
- `allowNA,?`: `bool`,
104
- // ID of the column to be used in spec and as a saved filename;
105
- // default: column label with all special characters replaced with '_'
106
- `id,?`: `string`,
107
- // Specification of the column
108
- `spec`: {
109
- // Type of column values
110
- `valueType`: `string,regex=Int|Long|Float|Double|String`,
111
- // Name of the column to be used in spec;
112
- // default: column label
113
- `name,?`: `string`,
114
- // Auxiliary information to the column name, type and parents to form a unique identifier;
115
- // default: empty
116
- `domain,?`: { any: `string` },
117
- // Any additional information attached to the axis that does not affect its identifier;
118
- // default: "pl7.app/label": Column label from XSV
119
- `annotations,?`: { any: `string` },
120
- // A list of zero-based indices of parent axes in the overall axes specification;
121
- // default: empty
122
- `parentAxes,?`: [ `number` ]
123
- }
32
+ `column`: `string`,
33
+ `filterOutRegex,?`: `string`,
34
+ `preProcess,?`: [_PRE_PROCESS_STEP_SCHEMA],
35
+ `naRegex,?`: `string`,
36
+ `allowNA,?`: `bool`,
37
+ `id,?`: `string`,
38
+ `spec`: {
39
+ `valueType`: `string,regex=Int|Long|Float|Double|String`,
40
+ `name,?`: `string`,
41
+ `domain,?`: { any: `string` },
42
+ `annotations,?`: { any: `string` },
43
+ `parentAxes,?`: [ `number` ]
44
+ }
124
45
  }
125
46
 
126
47
  _SPEC_INDEX_SCHEMA := {
127
- // Name of the axis
128
- `name`: `string`,
129
- // Auxiliary information to the column name, type and parents to form a unique identifier;
130
- // default: empty
131
- `domain,?`: { any: `string` },
132
- // Any additional information attached to the axis that does not affect its identifier;
133
- // default: "pl7.app/label": name
134
- `annotations,?`: { any: `string` },
135
- // A list of zero-based indices of parent axes in the overall axes specification;
136
- // default: empty
137
- `parentAxes,?`: [`number`]
48
+ `name`: `string`,
49
+ `domain,?`: { any: `string` },
50
+ `annotations,?`: { any: `string` },
51
+ `parentAxes,?`: [`number`]
138
52
  }
139
53
 
140
54
  PFCONV_IMPORT_CFG_SCHEMA := {
141
- // Single ASCII character to be used as separator;
142
- // default: ',' for .csv, '\t' for .tsv
143
- `separator,?`: `string`,
144
- // Single ASCII character, if XSV row begins with this character - the row would be skipped;
145
- // default: error is thrown if comment lines are found in document
146
- `commentLinePrefix,?`: `string`,
147
- // Should empty lines be skipped;
148
- // default: false
149
- `skipEmptyLines,?`: `bool`,
150
- // Resolve duplicates by adding sequential suffixes to column labels;
151
- // default: true
152
- `allowColumnLabelDuplicates,?`: `bool`,
153
- // XSV columns to use as PColumn axes, order of axes in resulting columns
154
- // would match the order of spec entries provided here
155
- `axes`: [_SPEC_AXES_SCHEMA],
156
- // Axis of type Long with XSV row numbers (would be the last one);
157
- // default: do not create additional axis with indexes
158
- `index,?`: _SPEC_INDEX_SCHEMA,
159
- // XSV columns to use as PColumn values, each exported individually
160
- `columns`: [_SPEC_COLUMN_SCHEMA],
161
- // When columns spec is provided but no such column was found in XSV - create such column
162
- // filled with NA values instead of failing;
163
- // default: false
164
- `allowArtificialColumns,?`: `bool`,
165
- // Prefix all column names with given string;
166
- // default: names would be preserved
167
- `columnNamePrefix,?`: `string`,
168
- // Columns would be stored using specified format;
169
- // default: Binary
170
- `storageFormat,?` : `string,regex=Binary|Json`,
171
- // Partitioning key length;
172
- // default: 0
173
- `partitionKeyLength,?` : `number`
55
+ `separator,?`: `string`,
56
+ `commentLinePrefix,?`: `string`,
57
+ `skipEmptyLines,?`: `bool`,
58
+ `allowColumnLabelDuplicates,?`: `bool`,
59
+ `axes`: [_SPEC_AXES_SCHEMA],
60
+ `index,?`: _SPEC_INDEX_SCHEMA,
61
+ `columns`: [_SPEC_COLUMN_SCHEMA],
62
+ `allowArtificialColumns,?`: `bool`,
63
+ `columnNamePrefix,?`: `string`,
64
+ `storageFormat,?` : `string,regex=Binary|Json`,
65
+ `partitionKeyLength,?` : `number`
174
66
  }
175
67
 
176
68
  _COLUMN_FILTER_SCHEMA := {
177
- // Match any of the types listed here;
178
- // default: type is ignored during matching
179
- `type,?`: `string,regex=Int|Long|Float|Double|String|Bytes`,
180
- // Match any of the names listed here;
181
- // default: name is ignored during matching
182
- `name,?`: `string`,
183
- // Match requires all the listed domains to have provided values;
184
- // default: no domain equality checks are performed during matching
185
- `domainValue,?`: { any: `string` },
186
- // Match requires all the listed annotations to have provided values;
187
- // default: no annotation equality checks are performed during matching
188
- `annotationValue,?`: { any: `string` },
189
- // Match requires all the listed annotations to match provided regex patterns;
190
- // default: no annotation pattern matching is performed during matching
191
- `annotationPattern,?`: { any: `string` }
69
+ `type,?`: `string,regex=Int|Long|Float|Double|String|Bytes`,
70
+ `name,?`: `string`,
71
+ `domainValue,?`: { any: `string` },
72
+ `annotationValue,?`: { any: `string` },
73
+ `annotationPattern,?`: { any: `string` }
192
74
  }
193
75
 
194
76
  PFCONV_EXPORT_CFG_SCHEMA := {
195
- // String representing NA values of types Int, Long, Float, Double;
196
- // default: NaN
197
- `naStr,?`: `string`,
198
- // String representing NA and missing values of types String, Bytes;
199
- // default: null
200
- `nullStr,?`: `string`,
201
- // Toggle to export or skip axes and columns of type Bytes;
202
- // default: false
203
- `exportBytes,?`: `bool`,
204
- // Single ASCII character to be used as separator;
205
- // default: ',' for .csv, '\t' for .tsv
206
- `separator,?`: `string`,
207
- // Only columns matching the selector are exported;
208
- // default: all columns are exported
209
- `columnSelector,?`: [_COLUMN_FILTER_SCHEMA],
210
- // During export, columns with equal axes specifications would be joined into single table
211
- // using the join type specified;
212
- // default: Full
213
- `joinType,?`: `string,regex=Full|Inner`
77
+ `naStr,?`: `string`,
78
+ `nullStr,?`: `string`,
79
+ `exportBytes,?`: `bool`,
80
+ `separator,?`: `string`,
81
+ `columnSelector,?`: [_COLUMN_FILTER_SCHEMA],
82
+ `joinType,?`: `string,regex=Full|Inner`
214
83
  }
215
84
 
216
- /**
217
- * Get column id from the column spec
218
- */
85
+
86
+
219
87
  xsvColumnId := func(c) {
220
- id := c.id
221
- if is_undefined(id) {
222
- id = c.column
223
- }
224
- return id
88
+ id := c.id
89
+ if is_undefined(id) {
90
+ id = c.column
91
+ }
92
+ return id
225
93
  }
226
94
 
227
- /**
228
- * Removes all annotations & domain information from spec, to pass it to pfconv
229
- */
95
+
96
+
230
97
  purifySpec := func(spec) {
231
- newSpec := copy(spec)
232
-
233
- newAxes := []
234
- for ax in spec.axes {
235
- newAxes = append(newAxes, objects.deleteUndefined({
236
- column: ax.column,
237
- filterOutRegex: ax.filterOutRegex,
238
- preProcess: ax.preProcess,
239
- naRegex: ax.naRegex,
240
- allowNA: ax.allowNA,
241
- spec: { type: ax.spec.type }
242
- }))
243
- }
244
- newSpec.axes = newAxes
245
-
246
- newCols := []
247
- for col in spec.columns {
248
- newCols = append(newCols, objects.deleteUndefined({
249
- column: col.column,
250
- filterOutRegex: col.filterOutRegex,
251
- preProcess: col.preProcess,
252
- naRegex: col.naRegex,
253
- allowNA: col.allowNA,
254
- id: col.id,
255
- spec: { valueType: col.spec.valueType }
256
- }))
257
- }
258
- newSpec.columns = newCols
259
-
260
- validation.assertJsonSchema(newSpec, PFCONV_IMPORT_CFG_SCHEMA)
261
-
262
- return newSpec
98
+ newSpec := copy(spec)
99
+
100
+ newAxes := []
101
+ for ax in spec.axes {
102
+ newAxes = append(newAxes, objects.deleteUndefined({
103
+ column: ax.column,
104
+ filterOutRegex: ax.filterOutRegex,
105
+ preProcess: ax.preProcess,
106
+ naRegex: ax.naRegex,
107
+ allowNA: ax.allowNA,
108
+ spec: { type: ax.spec.type }
109
+ }))
110
+ }
111
+ newSpec.axes = newAxes
112
+
113
+ newCols := []
114
+ for col in spec.columns {
115
+ newCols = append(newCols, objects.deleteUndefined({
116
+ column: col.column,
117
+ filterOutRegex: col.filterOutRegex,
118
+ preProcess: col.preProcess,
119
+ naRegex: col.naRegex,
120
+ allowNA: col.allowNA,
121
+ id: col.id,
122
+ spec: { valueType: col.spec.valueType }
123
+ }))
124
+ }
125
+ newSpec.columns = newCols
126
+
127
+ validation.assertJsonSchema(newSpec, PFCONV_IMPORT_CFG_SCHEMA)
128
+
129
+ return newSpec
263
130
  }
264
131
 
265
- /**
266
- * Split given pfconv config into:
267
- *
268
- * (1) purified cfg with minimal required settings to be passed to the pfconv binary,
269
- * to maximize caching retention when domains and annotations changes
270
- * (2) complete columns specs, that can be directly rendered into BObjectSpecs and
271
- * returned as workflow exports
272
- *
273
- * This method comes in handy in situations where actual csv -> pframe export is broadcasted
274
- * onto multiple objects, and then converges, so that each export operation only requires purified
275
- * config, and only data is saved for such operations, and actual specs are added somewhere
276
- * upstream.
277
- *
278
- * @param cfg full pfconv config object
279
- * @param ops additional options
280
- * {
281
- * additionalAxesSpec - array of additional axes spec to prepend to each column spec
282
- * }
283
- *
284
- * @return {
285
- * purifiedCfg - purified pfconv config
286
- * columnsSpec - map of full column specs by ids from the original cfg
287
- * }
288
- */
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+
151
+
152
+
153
+
154
+
289
155
  decomposePfconvImportCfg := func(cfg, ...ops) {
290
- ll.assert(len(ops) <= 1, "too many options for decomposePfconvImportCfg: %v", len(ops))
291
-
292
- axesSpec := []
293
- if len(ops) == 1 && !is_undefined(ops[0].additionalAxesSpec) {
294
- axesSpec = ops[0].additionalAxesSpec
295
- }
296
-
297
- for axis in cfg.axes {
298
- axesSpec = append(axesSpec, axis.spec)
299
- }
300
-
301
- columnsSpec := {}
302
-
303
- for column in cfg.columns {
304
- id := xsvColumnId(column)
305
- ll.assert(is_undefined(columnsSpec[id]), "repeated column spec id in pfconv cfg: %v", id)
306
- columnsSpec[id] = column.spec
307
- columnsSpec[id].axesSpec = axesSpec
308
- // make sure spec contain correct kind value
309
- columnsSpec[id].kind = "PColumn"
310
- }
311
-
312
- return {
313
- purifiedCfg: purifySpec(cfg),
314
- columnsSpec: columnsSpec
315
- }
156
+ ll.assert(len(ops) <= 1, "too many options for decomposePfconvImportCfg: %v", len(ops))
157
+
158
+ axesSpec := []
159
+ if len(ops) == 1 && !is_undefined(ops[0].additionalAxesSpec) {
160
+ axesSpec = ops[0].additionalAxesSpec
161
+ }
162
+
163
+ for axis in cfg.axes {
164
+ axesSpec = append(axesSpec, axis.spec)
165
+ }
166
+
167
+ columnsSpec := {}
168
+
169
+ for column in cfg.columns {
170
+ id := xsvColumnId(column)
171
+ ll.assert(is_undefined(columnsSpec[id]), "repeated column spec id in pfconv cfg: %v", id)
172
+ columnsSpec[id] = column.spec
173
+ columnsSpec[id].axesSpec = axesSpec
174
+ columnsSpec[id].kind = "PColumn"
175
+ }
176
+
177
+ return {
178
+ purifiedCfg: purifySpec(cfg),
179
+ columnsSpec: columnsSpec
180
+ }
316
181
  }
317
182
 
318
183
  export ll.toStrict({
319
- PFCONV_IMPORT_CFG_SCHEMA: PFCONV_IMPORT_CFG_SCHEMA,
320
- PFCONV_EXPORT_CFG_SCHEMA: PFCONV_EXPORT_CFG_SCHEMA,
184
+ PFCONV_IMPORT_CFG_SCHEMA: PFCONV_IMPORT_CFG_SCHEMA,
185
+ PFCONV_EXPORT_CFG_SCHEMA: PFCONV_EXPORT_CFG_SCHEMA,
321
186
 
322
- xsvColumnId: xsvColumnId,
323
- purifySpec: purifySpec,
324
- decomposePfconvImportCfg: decomposePfconvImportCfg
187
+ xsvColumnId: xsvColumnId,
188
+ purifySpec: purifySpec,
189
+ decomposePfconvImportCfg: decomposePfconvImportCfg
325
190
  })