@platforma-sdk/workflow-tengo 1.2.6

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 (51) hide show
  1. package/README.md +6 -0
  2. package/dist/tengo/lib/assets.lib.tengo +64 -0
  3. package/dist/tengo/lib/constants.lib.tengo +75 -0
  4. package/dist/tengo/lib/exec.internal.lib.tengo +211 -0
  5. package/dist/tengo/lib/exec.lib.tengo +516 -0
  6. package/dist/tengo/lib/exec.package.lib.tengo +296 -0
  7. package/dist/tengo/lib/exec.runcmd.lib.tengo +275 -0
  8. package/dist/tengo/lib/exec.runenv.lib.tengo +221 -0
  9. package/dist/tengo/lib/exec.stream.lib.tengo +64 -0
  10. package/dist/tengo/lib/file.lib.tengo +112 -0
  11. package/dist/tengo/lib/ll.lib.tengo +233 -0
  12. package/dist/tengo/lib/maps.lib.tengo +102 -0
  13. package/dist/tengo/lib/objects.lib.tengo +22 -0
  14. package/dist/tengo/lib/oop.lib.tengo +29 -0
  15. package/dist/tengo/lib/path.lib.tengo +165 -0
  16. package/dist/tengo/lib/pframes.constants.lib.tengo +53 -0
  17. package/dist/tengo/lib/pframes.export-pcolumn.lib.tengo +47 -0
  18. package/dist/tengo/lib/pframes.lib.tengo +84 -0
  19. package/dist/tengo/lib/pframes.ll.lib.tengo +86 -0
  20. package/dist/tengo/lib/pframes.util.lib.tengo +244 -0
  21. package/dist/tengo/lib/pframes.xsv.lib.tengo +178 -0
  22. package/dist/tengo/lib/render.lib.tengo +100 -0
  23. package/dist/tengo/lib/sets.lib.tengo +93 -0
  24. package/dist/tengo/lib/slices.lib.tengo +202 -0
  25. package/dist/tengo/lib/smart.lib.tengo +1005 -0
  26. package/dist/tengo/lib/tpl.lib.tengo +535 -0
  27. package/dist/tengo/lib/tpl.state-await.lib.tengo +255 -0
  28. package/dist/tengo/lib/tpl.util.lib.tengo +19 -0
  29. package/dist/tengo/lib/validation.lib.tengo +428 -0
  30. package/dist/tengo/lib/workdir.lib.tengo +300 -0
  31. package/dist/tengo/lib/workdir.proc.lib.tengo +158 -0
  32. package/dist/tengo/lib/workdir.save.lib.tengo +158 -0
  33. package/dist/tengo/lib/workflow.bobject.lib.tengo +51 -0
  34. package/dist/tengo/lib/workflow.bquery.lib.tengo +208 -0
  35. package/dist/tengo/lib/workflow.constants.lib.tengo +8 -0
  36. package/dist/tengo/lib/workflow.context.lib.tengo +56 -0
  37. package/dist/tengo/lib/workflow.lib.tengo +298 -0
  38. package/dist/tengo/tpl/exec.create-python-venv.plj.gz +0 -0
  39. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  40. package/dist/tengo/tpl/pframes.aggregate.plj.gz +0 -0
  41. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  42. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  43. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  44. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  45. package/dist/tengo/tpl/pframes.import-xsv-map.plj.gz +0 -0
  46. package/dist/tengo/tpl/pframes.map-pframe.plj.gz +0 -0
  47. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  48. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  49. package/index.d.ts +4 -0
  50. package/index.js +13 -0
  51. package/package.json +25 -0
package/README.md ADDED
@@ -0,0 +1,6 @@
1
+ # Resources
2
+
3
+ - [Tengo syntax](https://github.com/d5/tengo/blob/master/docs/tutorial.md)
4
+ - [Tengo builtin functions](https://github.com/d5/tengo/blob/master/docs/builtins.md)
5
+ - [Modules provided by the pl (`tx` and `plapi`)](https://github.com/milaboratory/pl/blob/main/controllers/templates/pkg/lang/interpreter_api_v1.go)
6
+
@@ -0,0 +1,64 @@
1
+ /** API to retrieve assets packed with template code (like other templates). */
2
+
3
+ plapi := import("plapi")
4
+ json := import("json")
5
+ ll := import("@platforma-sdk/workflow-tengo:ll")
6
+ smart := import("@platforma-sdk/workflow-tengo:smart")
7
+
8
+ /**
9
+ * Returns internal template identifier for loaded templates
10
+ *
11
+ * @param tplName: string - full name of a template, including namespace (package name).
12
+ * Local templates (within the same package) can omit namespace part and start the name with colon:
13
+ * - "@company/package:someTemplateName"
14
+ * - ":myLocalTemplate"
15
+ *
16
+ * @return template: smart.resource - resource of tengo template with given name.
17
+ */
18
+ importTemplate := func(tplName) {
19
+ return smart.resource(plapi.getTemplateId(tplName))
20
+ }
21
+
22
+ /**
23
+ * Returns software description suitable for 'exec' operations.
24
+ *
25
+ * @param swName: string - full name of the software description, including namespace (package name).
26
+ * Local software definitions (within the same package) can omit namespace part and start the name with colon:
27
+ * - "@company/package:some-oftware"
28
+ * - ":my-local-software"
29
+ *
30
+ * @return softwareInfo: softwareInfo - structure with software info
31
+ */
32
+ importSoftware := func(swName) {
33
+ sw := plapi.getSoftwareInfo(swName)
34
+ return ll.toStrict({
35
+ _type: "softwareDescriptor",
36
+
37
+ resource: smart.resource(sw.id),
38
+ name: sw.name,
39
+ version: sw.version,
40
+ blobRef: sw.blobRef,
41
+ descriptor: ll.toStrict(json.decode(sw.descriptor)) // raw sw.json data with software entrypoint descriptor
42
+ })
43
+ }
44
+
45
+ /**
46
+ * Checks if given item is a software info
47
+ *
48
+ * @param toCheck: any - item to check
49
+ *
50
+ * @return isSoftware: boolean - true for software info, loaded with importSoftware()
51
+ */
52
+ isSoftwareInfo := func(toCheck) {
53
+ if !ll.isMap(toCheck) {
54
+ return false
55
+ }
56
+
57
+ return (ll.fromStrict(toCheck)._type) == "softwareDescriptor"
58
+ }
59
+
60
+ export ll.toStrict({
61
+ importTemplate: importTemplate,
62
+ importSoftware: importSoftware,
63
+ isSoftwareInfo: isSoftwareInfo
64
+ })
@@ -0,0 +1,75 @@
1
+ // constants
2
+
3
+ ll := import("@platforma-sdk/workflow-tengo:ll")
4
+
5
+ RTYPE_JSON := { Name: "json/object", Version: "1" }
6
+
7
+ RTYPE_MAP := { Name: "std/map", Version: "1" }
8
+ // @TODO this should be deleted once we align on map type name
9
+ RTYPE_MAP_ALT := { Name: "StdMap", Version: "1" }
10
+ RTYPE_MAP_EPH := { Name: "EphStdMap", Version: "1" }
11
+
12
+ RTYPE_BINARY_MAP := { Name: "BinaryMap", Version: "1" }
13
+ RTYPE_BINARY_VALUE := { Name: "BinaryValue", Version: "1" }
14
+ RTYPE_BLOB_MAP := { Name: "BlobMap", Version: "1" }
15
+
16
+ RTYPE_CONTEXT := { Name: "BContext", Version: "1" }
17
+ RTYPE_CONTEXT_END := { Name: "BContextEnd", Version: "1" }
18
+ RTYPE_RENDER_TEMPLATE := { Name: "RenderTemplate", Version: "1" }
19
+ RTYPE_RENDER_EPH_TEMPLATE := { Name: "EphRenderTemplate", Version: "1" }
20
+
21
+ RTYPE_BOBJECT_SPEC := { Name: "BObjectSpec", Version: "1" }
22
+ RTYPE_BRESOLVE_CHOICE := { Name: "BResolveChoice", Version: "1" }
23
+ RTYPE_BRESOLVE_FIRST := { Name: "BResolveSingle", Version: "1" }
24
+ RTYPE_BRESOLVE_NO_RESULT := { Name: "BResolveSingleNoResult", Version: "1" }
25
+
26
+ RTYPE_QUERY_RESULT := { Name: "BQueryResult", Version: "1" }
27
+
28
+ RTYPE_OBJECT_SPEC := { Name: "BObjectSpec", Version: "1" }
29
+
30
+ RTYPE_WORKDIR_CREATE := { Name: "WorkdirCreate", Version: "1" }
31
+ RTYPE_WORKDIR_FILL := { Name: "WorkdirFill", Version: "1" }
32
+ RTYPE_WORKDIR_FILL_RULES := { Name: "WorkdirFill/rules", Version: "1" }
33
+ RTYPE_WORKDIR_SAVE := { Name: "WorkdirSave", Version: "1" }
34
+ RTYPE_WORKDIR_SAVE_RULES := { Name: "WorkdirSave/rules", Version: "1" }
35
+
36
+ /** Main resource type of representing a PL error */
37
+ RTYPE_JSON_ERROR := { Name: "json/resourceError", Version: "1"}
38
+
39
+ FTYPE_OTW := "OTW" // Generic one-time writable field. The value of this field can be set only once.
40
+ FTYPE_SERVICE := "service"
41
+ FTYPE_INPUT := "input"
42
+ FTYPE_OUTPUT := "output"
43
+ FTYPE_DYNAMIC := "dynamic"
44
+
45
+ export ll.toStrict({
46
+ FTYPE_OTW : FTYPE_OTW,
47
+ FTYPE_SERVICE : FTYPE_SERVICE,
48
+ FTYPE_INPUT : FTYPE_INPUT,
49
+ FTYPE_OUTPUT : FTYPE_OUTPUT,
50
+ FTYPE_DYNAMIC : FTYPE_DYNAMIC,
51
+
52
+ RTYPE_BINARY_MAP : RTYPE_BINARY_MAP,
53
+ RTYPE_BINARY_VALUE : RTYPE_BINARY_VALUE,
54
+ RTYPE_BLOB_MAP : RTYPE_BLOB_MAP,
55
+ RTYPE_BOBJECT_SPEC : RTYPE_BOBJECT_SPEC,
56
+ RTYPE_BRESOLVE_CHOICE : RTYPE_BRESOLVE_CHOICE,
57
+ RTYPE_BRESOLVE_FIRST : RTYPE_BRESOLVE_FIRST,
58
+ RTYPE_BRESOLVE_NO_RESULT : RTYPE_BRESOLVE_NO_RESULT,
59
+ RTYPE_CONTEXT : RTYPE_CONTEXT,
60
+ RTYPE_CONTEXT_END : RTYPE_CONTEXT_END,
61
+ RTYPE_JSON : RTYPE_JSON,
62
+ RTYPE_MAP : RTYPE_MAP,
63
+ RTYPE_MAP_ALT : RTYPE_MAP_ALT,
64
+ RTYPE_MAP_EPH : RTYPE_MAP_EPH,
65
+ RTYPE_QUERY_RESULT : RTYPE_QUERY_RESULT,
66
+ RTYPE_OBJECT_SPEC : RTYPE_OBJECT_SPEC,
67
+ RTYPE_RENDER_EPH_TEMPLATE : RTYPE_RENDER_EPH_TEMPLATE,
68
+ RTYPE_RENDER_TEMPLATE : RTYPE_RENDER_TEMPLATE,
69
+ RTYPE_WORKDIR_CREATE : RTYPE_WORKDIR_CREATE,
70
+ RTYPE_WORKDIR_FILL : RTYPE_WORKDIR_FILL,
71
+ RTYPE_WORKDIR_FILL_RULES : RTYPE_WORKDIR_FILL_RULES,
72
+ RTYPE_WORKDIR_SAVE : RTYPE_WORKDIR_SAVE,
73
+ RTYPE_WORKDIR_SAVE_RULES : RTYPE_WORKDIR_SAVE_RULES,
74
+ RTYPE_JSON_ERROR : RTYPE_JSON_ERROR
75
+ })
@@ -0,0 +1,211 @@
1
+ ll := import("@platforma-sdk/workflow-tengo:ll")
2
+ json := import("json")
3
+ text := import("text")
4
+ oop := import("@platforma-sdk/workflow-tengo:oop")
5
+ maps := import("@platforma-sdk/workflow-tengo:maps")
6
+ path := import("@platforma-sdk/workflow-tengo:path")
7
+ pkg := import("@platforma-sdk/workflow-tengo:exec.package")
8
+ runenv := import("@platforma-sdk/workflow-tengo:exec.runenv")
9
+
10
+ // Variables, substituted in command arguments and environment variable values
11
+ _ARG_VAR_PKG := "{pkg}" // abs path to software package
12
+ _ARG_VAR_JAVA := "{java}" // abs path to 'java' run environment
13
+ _ARG_VAR_PYTHON := "{python}" // abs path to 'python' run environment
14
+
15
+ /**
16
+ * Create new argument marking it as 'with' or 'without' variables inside.
17
+ * The outcome of 'hasVariables' flag value is wether the value will be treated
18
+ * by Platforma Backend on server side before being given to the actual command.
19
+ */
20
+ _newArg := func(hasVariables, value) {
21
+ return ll.toStrict({
22
+ hasVars: hasVariables,
23
+ value: value
24
+ })
25
+ }
26
+
27
+ _newRefVar := func(varName, refName, reference) {
28
+ return ll.toStrict({
29
+ varName: varName,
30
+ refName: refName,
31
+ reference: reference
32
+ })
33
+ }
34
+
35
+ _installSoftware := func(registry, pkgName) {
36
+ archive := pkg.get(registry, pkgName).archive()
37
+ return pkg.install(archive).package()
38
+ }
39
+
40
+ _directCallOptions := func(runOptions) {
41
+ cmd := _newArg(false, runOptions.cmd)
42
+ args := []
43
+ envs := {}
44
+
45
+ for name, arg in runOptions.args {
46
+ args = append(args, _newArg(false, arg))
47
+ }
48
+
49
+ for name, val in runOptions.envs {
50
+ envs[name] = _newArg(false, val)
51
+ }
52
+
53
+ return oop.inherit(runOptions, {
54
+ variables: [],
55
+ customPaths: [],
56
+ cmd: cmd,
57
+ args: args,
58
+ envs: envs
59
+ })
60
+ }
61
+
62
+ _loadJavaRunEnvironment := func(descriptor) {
63
+ javaPkg := _installSoftware(descriptor.runEnv.registry, descriptor.runEnv.package)
64
+ javaRefVar := _newRefVar(_ARG_VAR_JAVA, descriptor.runEnv.name, javaPkg)
65
+
66
+ return ll.toStrict({
67
+ variables: [ javaRefVar ],
68
+ customPaths: [ _newArg(true, path.join(_ARG_VAR_JAVA, descriptor.runEnv.binDir)) ],
69
+ envs: {}
70
+ })
71
+ }
72
+
73
+ _loadPythonRunEnvironment := func(descriptor, softName, softPkg) {
74
+ venvBuilder := runenv.pythonVenv().
75
+ software(softPkg).
76
+ runEnvDescriptor(descriptor.runEnv).
77
+ dependencies(descriptor.dependencies)
78
+
79
+ if !is_undefined(descriptor.toolset) && descriptor.toolset != "" {
80
+ venvBuilder.useToolset(descriptor.toolset)
81
+ }
82
+
83
+ venv := venvBuilder.build().venv()
84
+
85
+ venvRoot := path.join(_ARG_VAR_PYTHON, "venv")
86
+ venvRefKey := softName + "/venv"
87
+
88
+ pythonRefVar := _newRefVar(_ARG_VAR_PYTHON, venvRefKey, venv)
89
+
90
+ return ll.toStrict({
91
+ variables: [ pythonRefVar ],
92
+ customPaths: [ _newArg(true, path.join(venvRoot, "bin")) ],
93
+ envs: {
94
+ "VIRTUAL_ENV": _newArg(true, venvRoot)
95
+ }
96
+ })
97
+ }
98
+
99
+ _loadRunEnvironment := func(descriptor, softName, softPackage) {
100
+ if descriptor.runEnv.type == "java" {
101
+ return _loadJavaRunEnvironment(descriptor)
102
+ }
103
+ if descriptor.runEnv.type == "python" {
104
+ return _loadPythonRunEnvironment(descriptor, softName, softPackage)
105
+ }
106
+
107
+ ll.panic("run environment type %q is not currently supported by tengo-sdk", descriptor.runEnv.type)
108
+ }
109
+
110
+ _binPackageCallOptions := func(runOptions, variables, descriptor, softPackage) {
111
+ customPaths := []
112
+ envs := ll.toStrict({})
113
+ args := []
114
+
115
+ // Real command shoule be:
116
+ // [<runEnv bin>] [<runEnv options>] [<entrypoint bin>] [<entrypoint options>] <cmd> <args>
117
+ if (maps.containsKey(descriptor, "runEnv")) {
118
+ runEnvInfo := _loadRunEnvironment(descriptor, runOptions.software.name, softPackage)
119
+
120
+ if len(runEnvInfo.variables) > 0 {
121
+ variables = append(variables, runEnvInfo.variables...)
122
+ }
123
+ if len(runEnvInfo.customPaths) > 0 {
124
+ customPaths = append(customPaths, runEnvInfo.customPaths...)
125
+ }
126
+ if len(runEnvInfo.envs) > 0 {
127
+ for n, v in runEnvInfo.envs {
128
+ envs[n] = v
129
+ }
130
+ }
131
+ }
132
+
133
+ ll.assert(len(descriptor.cmd) != 0, "cannot render final command for software: empty 'cmd' in software descritor")
134
+
135
+ cmd := _newArg(true, descriptor.cmd[0])
136
+
137
+ for arg in splice(descriptor.cmd, 1) {
138
+ args = append(args, _newArg(true, arg))
139
+ }
140
+ for arg in runOptions.args {
141
+ args = append(args, _newArg(false, arg))
142
+ }
143
+
144
+ for name, val in runOptions.envs {
145
+ envs[name] = _newArg(false, val)
146
+ }
147
+
148
+ return oop.inherit(runOptions, {
149
+ variables: variables,
150
+ customPaths: customPaths,
151
+ cmd: cmd,
152
+ args: args,
153
+ envs: envs
154
+ })
155
+ }
156
+
157
+ _devLocalPackageCallOptions := func(runOptions) {
158
+ software := runOptions.software
159
+ localDescriptor := software.descriptor.local
160
+
161
+ softPackage := pkg.use({
162
+ hash: localDescriptor.hash,
163
+ path: localDescriptor.path,
164
+ descriptor: json.encode(ll.fromStrict(software.descriptor)),
165
+ origin: {
166
+ registry: "dev-local",
167
+ url: "file://" + localDescriptor.path,
168
+ packageName: software.descriptor.name
169
+ }
170
+ }).package()
171
+
172
+ variables := [ _newRefVar(_ARG_VAR_PKG, software.name, softPackage) ]
173
+
174
+ return _binPackageCallOptions(runOptions, variables, localDescriptor, softPackage)
175
+ }
176
+
177
+ _remotePackageCallOptions := func(runOptions) {
178
+ software := runOptions.software
179
+ binaryDescriptor := software.descriptor.binary
180
+ softPackage := _installSoftware(binaryDescriptor.registry, binaryDescriptor.package)
181
+
182
+ variables := [ _newRefVar(_ARG_VAR_PKG, software.name, softPackage) ]
183
+
184
+ return _binPackageCallOptions(runOptions, variables, binaryDescriptor, softPackage)
185
+ }
186
+
187
+ binaryRunOptions := func(runOptions) {
188
+ if (is_undefined(runOptions.software)) {
189
+ //
190
+ // Simple local command run, no software pacakges involved (backward compatibility)
191
+ //
192
+ return _directCallOptions(runOptions)
193
+ }
194
+
195
+ software := runOptions.software
196
+ descriptor := software.descriptor
197
+
198
+ if (maps.containsKey(descriptor, "local")) {
199
+ return _devLocalPackageCallOptions(runOptions)
200
+ }
201
+
202
+ if (maps.containsKey(descriptor, "binary")) {
203
+ return _remotePackageCallOptions(runOptions)
204
+ }
205
+
206
+ ll.panic("Unable to run software %s v%s: 'binary' execution mode is not enabled in software descriptor", software.name, software.version)
207
+ }
208
+
209
+ export {
210
+ binaryRunOptions : binaryRunOptions
211
+ }