@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
@@ -0,0 +1,300 @@
1
+ /**
2
+ * Gives an interface for working with workdirs.
3
+ */
4
+
5
+ json := import("json")
6
+
7
+ ll := import("@platforma-sdk/workflow-tengo:ll")
8
+ assets := import("@platforma-sdk/workflow-tengo:assets")
9
+ constants := import("@platforma-sdk/workflow-tengo:constants")
10
+ smart := import("@platforma-sdk/workflow-tengo:smart")
11
+ oop := import("@platforma-sdk/workflow-tengo:oop")
12
+ sets := import("@platforma-sdk/workflow-tengo:sets")
13
+ slices := import("@platforma-sdk/workflow-tengo:slices")
14
+ path := import("@platforma-sdk/workflow-tengo:path")
15
+ enum := import("enum")
16
+ validation := import("@platforma-sdk/workflow-tengo:validation")
17
+ render := import("@platforma-sdk/workflow-tengo:render")
18
+
19
+ create := func() {
20
+ wd := smart.ephemeralBuilder(constants.RTYPE_WORKDIR_CREATE).lockAndBuild()
21
+ return wd.getField("workdir")
22
+ }
23
+
24
+ _getFileFillRule := func(filePath, extension) {
25
+ return {
26
+ path: filePath,
27
+ type: "file",
28
+ permissions: 0o600,
29
+ pathKey: filePath,
30
+ blobKey: filePath,
31
+ copyOptional: true,
32
+ fileExtension: extension
33
+ }
34
+ }
35
+
36
+ /**
37
+ * Generates a value fill rule for a given file path.
38
+ *
39
+ * @param filePath: string - the path of the file.
40
+ * @return rule: map - the value fill rule.
41
+ */
42
+ _getValueFillRule := func(filePath) {
43
+ return {
44
+ path: filePath,
45
+ type: "value",
46
+ permissions: 0o600,
47
+ pathKey: filePath,
48
+ valueKey: filePath
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Generates a directory fill rule for a given directory.
54
+ *
55
+ * @param dir: string - the path of the directory.
56
+ * @return rule: map - the directory fill rule.
57
+ */
58
+ _getDirFillRule := func(dir) {
59
+ return {
60
+ path: dir,
61
+ type: "dir",
62
+ permissions: 0o700,
63
+ pathKey: ""
64
+ }
65
+ }
66
+
67
+ /**
68
+ * Fills a workdir with files, values, and directories.
69
+ *
70
+ * @param workdir: reference - a reference to the workdir to fill.
71
+ * @return self: builder - a builder that adds files and directories to the workdir. */
72
+ _fill := func(workdir) {
73
+ ll.assert(smart.isReference(workdir), "workdir must be a reference to a resource or field")
74
+
75
+ wd := smart.ephemeralBuilder(constants.RTYPE_WORKDIR_FILL)
76
+ wd.getField("workdirIn").set(workdir)
77
+
78
+ files := {}
79
+ values := {}
80
+ dirs := {}
81
+
82
+ self := undefined
83
+ self = ll.toStrict(oop.inherit(wd, {
84
+ _getAllDirs: func(fileName) {
85
+ dirsWithFileName := path.getBasenameDirs(fileName)
86
+ return slices.slice(dirsWithFileName, 0, -1)
87
+ },
88
+
89
+ _addDirs: func(fileName) {
90
+ newDirs := self._getAllDirs(fileName)
91
+ sets.add(dirs, newDirs...)
92
+ },
93
+
94
+ /**
95
+ * Adds a file to the workdir.
96
+ *
97
+ * @param fileName: string - the name of the file.
98
+ * @param fileResource: reference - the file to add.
99
+ */
100
+ addFile: func(fileName, fileResource) {
101
+ validation.assertJsonSchema(fileName, "string")
102
+ validation.assertJsonSchema(fileResource, validation.reference)
103
+
104
+ files[fileName] = fileResource
105
+ self._addDirs(fileName)
106
+
107
+ return self
108
+ },
109
+
110
+ /**
111
+ * Adds multiple files to the workdir.
112
+ *
113
+ * @param fileMap: map[string]reference - a map of files.
114
+ */
115
+ addFiles: func(fileMap) {
116
+ enum.each(fileMap, self.addFile)
117
+ return self
118
+ },
119
+
120
+ /**
121
+ * Adds a file with a content to the workdir.
122
+ *
123
+ * @param fileName: string - the name of the file.
124
+ * @param contentRef: reference|any - the content as a reference to add or the content itself.
125
+ */
126
+ writeFile: func(fileName, contentRef) {
127
+ validation.assertJsonSchema(fileName, "string")
128
+ values[fileName] = contentRef
129
+ self._addDirs(fileName)
130
+
131
+ return self
132
+ },
133
+
134
+ /**
135
+ * Adds multiple files with contents to the workdir.
136
+ *
137
+ * @param contentMap: map[string]any|reference - a map of references to a content or to a content itself.
138
+ */
139
+ writeFiles: func(contentRefMap) {
140
+ enum.each(contentRefMap, self.writeFile)
141
+ return self
142
+ },
143
+
144
+ /**
145
+ * Creates a possibly nested directory in the workdir.
146
+ *
147
+ * @param dir: string - the path of the directory.
148
+ */
149
+ mkDir: func(dir) {
150
+ sets.add(dirs, path.getBasenameDirs(dir))
151
+ return self
152
+ },
153
+
154
+ /**
155
+ * Builds the filled workdir.
156
+ *
157
+ * @return wd: reference - a reference to the filled workdir.
158
+ */
159
+ build: func() {
160
+ rules := []
161
+ for dir, _ in dirs {
162
+ rules = append(rules, _getDirFillRule(dir))
163
+ }
164
+ for fileName, _ in files {
165
+ rules = append(rules, _getFileFillRule(fileName, path.getExtension(fileName)))
166
+ }
167
+ for fileName, _ in values {
168
+ rules = append(rules, _getValueFillRule(fileName))
169
+ }
170
+
171
+ rulesRes := smart.createValueResource(
172
+ constants.RTYPE_WORKDIR_FILL_RULES,
173
+ json.encode(rules)
174
+ )
175
+ self.getField("rules").set(rulesRes)
176
+
177
+ self.getField("dataIn").set(smart.createBinaryMapResource(values))
178
+ self.getField("blobsIn").set(smart.createBlobMapResource(files))
179
+
180
+ return self.lockAndBuild().outputs().workdirOut
181
+ }
182
+ }))
183
+
184
+ return self
185
+ }
186
+
187
+ /**
188
+ * Creates and fills a workdir with files, contents, and directories. See _fill for futher documentation.
189
+ *
190
+ * @return self: builder - a builder that adds files and directories to the workdir.
191
+ */
192
+ builder := func() {
193
+ return _fill(create())
194
+ }
195
+
196
+ /**
197
+ * Saves a workdir.
198
+ *
199
+ * @param workdir: reference - a reference to the workdir to save.
200
+ * @return self: builder - the builder that helps adding save rules to the save workdir.
201
+ */
202
+ save := func(workdir) {
203
+ ll.assert(smart.isReference(workdir), "workdir must be a reference to a resource or field")
204
+
205
+ // files to save
206
+ files := {}
207
+ // files to save their content
208
+ filesContent := {}
209
+ // file sets to save by regex
210
+ fileSets := {}
211
+ // file sets to save their content by regex
212
+ fileSetsContent := {}
213
+
214
+ self := undefined
215
+ self = ll.toStrict({
216
+ /**
217
+ * Saves a file from the workdir.
218
+ *
219
+ * @param fileName: string - the name of the file.
220
+ */
221
+ saveFile: func(fileName) {
222
+ validation.assertJsonSchema(fileName, "string")
223
+ sets.add(files, fileName)
224
+ return self
225
+ },
226
+
227
+ /**
228
+ * Saves a file to a value resource from the workdir.
229
+ *
230
+ * @param fileName: string - the name of the file.
231
+ */
232
+ saveFileContent: func(fileName) {
233
+ validation.assertJsonSchema(fileName, "string")
234
+ sets.add(filesContent, fileName)
235
+ return self
236
+ },
237
+
238
+ /**
239
+ * Save files which names satisfy given regex rule
240
+ *
241
+ * @param name: string - a name to refer this file set in the outputs
242
+ * @param regex: string - regex
243
+ */
244
+ saveFileSet: func(name, regex) {
245
+ validation.assertJsonSchema(regex, "string")
246
+ ll.assert(is_undefined(fileSets[name]), "file set with name '", name, "' is already in added")
247
+ fileSets[name] = regex
248
+ return self
249
+ },
250
+
251
+ /**
252
+ * Save files content which names satisfy given regex rule
253
+ *
254
+ * @param name: string - a name to refer this file set in the outputs
255
+ * @param regex: string - regex
256
+ */
257
+ saveFileSetContent: func(name, regex) {
258
+ validation.assertJsonSchema(regex, "string")
259
+ ll.assert(is_undefined(fileSetsContent[name]), "file set content with name '", name, "' is already in added")
260
+ sets.add(fileSetsContent, regex)
261
+ return self
262
+ },
263
+
264
+ /**
265
+ * Builds the saved workdir.
266
+ *
267
+ * @return wd: reference - the saved workdir with additional fields.
268
+ */
269
+ build: func() {
270
+
271
+ tpl := assets.importTemplate("@platforma-sdk/workflow-tengo:workdir.save")
272
+ inputs := {
273
+ workdir: workdir,
274
+ files: files,
275
+ filesContent: filesContent,
276
+ fileSets: fileSets,
277
+ fileSetsContent: fileSetsContent
278
+ }
279
+
280
+ wds := render.createEphemeral(tpl, inputs)
281
+
282
+ return ll.toStrict({
283
+ files: wds.output("files"),
284
+ filesContent: wds.output("filesContent"),
285
+ fileSets : wds.output("fileSets"),
286
+ fileSetsContent : wds.output("fileSetsContent"),
287
+ workdir: wds.output("workdir"),
288
+ progress: wds.output("progress")
289
+ })
290
+ }
291
+ })
292
+
293
+ return self
294
+ }
295
+
296
+ export ll.toStrict({
297
+ builder: builder,
298
+ create: create,
299
+ save: save
300
+ })
@@ -0,0 +1,158 @@
1
+ /** Library for workdir processor templates */
2
+
3
+ tpl := import("@platforma-sdk/workflow-tengo:tpl")
4
+ ll := import("@platforma-sdk/workflow-tengo:ll")
5
+ wdSave := import("@platforma-sdk/workflow-tengo:workdir.save")
6
+
7
+ // the template has a defined outputs
8
+ tpl.defineOutputs(["result", "workdir"])
9
+
10
+ proc := func() {
11
+ self := undefined
12
+
13
+ self = {
14
+
15
+ _wdBefore: undefined,
16
+ /**
17
+ * @return wd: resource - initial working directory resource
18
+ */
19
+ wdBefore: func() {
20
+ if is_undefined(self._wdBefore) {
21
+ self._wdBefore = tpl.inputs().workdir
22
+ }
23
+ return self._wdBefore
24
+ },
25
+
26
+ _filesInWd: undefined,
27
+ /**
28
+ * @return fileNames: string[] - list of file paths currently existing in the working directory
29
+ */
30
+ filesInWd: func() {
31
+ if is_undefined(self._filesInWd) {
32
+ self._filesInWd = self.wdBefore().getDataAsJson().files
33
+ }
34
+
35
+ return self._filesInWd
36
+ },
37
+
38
+ _wdAfterReadFiles: undefined,
39
+ /**
40
+ * @return wd: resource - working directory resource after "readFiles" is done
41
+ */
42
+ wdAfterReadFiles: func() {
43
+ if is_undefined(self._wdAfterReadFiles) {
44
+
45
+ if !is_undefined(tpl.inputs().wdAfterReadFiles) {
46
+
47
+ //
48
+ // this means readFiles was used and we are actually
49
+ // in the 'prepare' render
50
+ //
51
+ self._wdAfterReadFiles = tpl.inputs().wdAfterReadFiles
52
+ } else {
53
+
54
+ // no readFiles
55
+ self._wdAfterReadFiles = self.wdBefore()
56
+ }
57
+ }
58
+
59
+ return self._wdAfterReadFiles
60
+ },
61
+
62
+ /**
63
+ * Select files to read their content and pass it to the body function
64
+ *
65
+ * @param cb: callback - a callback which takes a list of file names (paths) existing in the working directory and
66
+ * returning a map of key -> file name containing files to get content from; each file content will be available in
67
+ * the body inputs with the corresponding key
68
+ */
69
+ readFiles: func(cb) {
70
+ tpl.prepare(func(inputs){
71
+ inputs.files = self.filesInWd()
72
+ // key -> file name
73
+ files := cb(inputs)
74
+
75
+ wdBuilder := wdSave.builder(self.wdBefore())
76
+ for _, fName in files {
77
+ wdBuilder.saveFileContent(fName)
78
+ }
79
+ wd := wdBuilder.build()
80
+
81
+ // run prepare to get file contents in the inputs
82
+ preps := {}
83
+ for key, fName in files {
84
+ preps[key] = wd.getSavedFileContent(fName)
85
+ }
86
+
87
+ preps.wdAfterReadFiles = wd.getWorkdirAfter()
88
+
89
+ return preps
90
+ })
91
+ },
92
+
93
+ _wdFinalBuilder: undefined,
94
+ /**
95
+ * Final workdir builder, after prepare
96
+ */
97
+ wdFinalBuilder: func() {
98
+ if is_undefined(self._wdFinalBuilder) {
99
+ self._wdFinalBuilder = wdSave.builder(self.wdAfterReadFiles())
100
+ }
101
+ return self._wdFinalBuilder
102
+ },
103
+
104
+ /**
105
+ * Save given file.
106
+ *
107
+ * @return ref: reference - a reference to saved file resource
108
+ */
109
+ saveFile: func(fName) {
110
+ self.wdFinalBuilder().saveFile(fName)
111
+ return self.wdFinalBuilder().getSavedFile(fName)
112
+ },
113
+
114
+ /**
115
+ * Save content of a given file.
116
+ *
117
+ * @return ref: reference - a reference to saved file content value resource
118
+ */
119
+ saveFileContent: func(fName) {
120
+ self.wdFinalBuilder().saveFileContent(fName)
121
+ return self.wdFinalBuilder().getSavedFileContent(fName)
122
+ },
123
+
124
+ /**
125
+ * Template body function
126
+ *
127
+ * @param cb: func - a callback function to run in template body; the inputs passed to the body will have the following fields:
128
+ * files: string[] - list of files in workdir
129
+ * args: map - additional arguments of the template processor
130
+ * ...filesContent: resources - fields with the content of files specified in 'readFiles'
131
+ */
132
+ body: func(cb) {
133
+ tpl.body(func(inputs) {
134
+
135
+ inputs.files = self.filesInWd()
136
+ result := cb(inputs)
137
+ wd := self.wdFinalBuilder().build()
138
+
139
+ return {
140
+ result: result,
141
+ workdir: wd.getWorkdirAfter()
142
+ }
143
+ })
144
+ }
145
+ }
146
+
147
+ return ll.toStrict(self)
148
+ }
149
+
150
+ /** singleton instance */
151
+ instance := proc()
152
+
153
+ export ll.toStrict({
154
+ readFiles: instance.readFiles,
155
+ saveFile: instance.saveFile,
156
+ saveFileContent: instance.saveFileContent,
157
+ body: instance.body
158
+ })
@@ -0,0 +1,158 @@
1
+ /** A library providing workdir save resource builder */
2
+
3
+ ll := import("@platforma-sdk/workflow-tengo:ll")
4
+ oop := import("@platforma-sdk/workflow-tengo:oop")
5
+ json := import("json")
6
+ sets := import("@platforma-sdk/workflow-tengo:sets")
7
+ smart := import("@platforma-sdk/workflow-tengo:smart")
8
+ constants := import("@platforma-sdk/workflow-tengo:constants")
9
+
10
+ _WORKDIR_IN_FIELD := "workdirIn"
11
+ _RULES_FIELD := "rules"
12
+ _SAVED_FILES_FIELD := "blobsOut"
13
+ _SAVED_CONTENT_FIELD := "dataOut"
14
+ _WORKDIR_AFTER_FIELD := "workdirOut"
15
+ _PROGRESS_FIELD := "progress"
16
+
17
+
18
+ /**
19
+ * Generates a file save rule for a given file name.
20
+ *
21
+ * @param fileName: string - the name of the file.
22
+ * @return rule: map - the file save rule.
23
+ */
24
+ getFileSaveRule := func(fileName) {
25
+ return {
26
+ blobKey: fileName,
27
+ type: "file",
28
+ filePath: fileName
29
+ }
30
+ }
31
+
32
+ /**
33
+ * Generates a value save rule for a given file name.
34
+ *
35
+ * @param fileName: string - the name of the file.
36
+ * @return rule: map - the value save rule.
37
+ */
38
+ getContentSaveRule := func(fileName) {
39
+ return {
40
+ blobKey: fileName,
41
+ type: "content",
42
+ contentPath: fileName
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Creates a builder for workdir save resource
48
+ */
49
+ builder := func(wdBefore) {
50
+
51
+ super := smart.ephemeralBuilder(constants.RTYPE_WORKDIR_SAVE)
52
+ // set input wd
53
+ super.getField(_WORKDIR_IN_FIELD).set(wdBefore)
54
+
55
+ // file save rules
56
+ fRules := {}
57
+ // content save rules
58
+ cRules := {}
59
+
60
+ self := undefined
61
+ self = ll.toStrict(oop.inherit(super, {
62
+
63
+ /**
64
+ * Save file.
65
+ *
66
+ * @param fName: string - file name
67
+ *
68
+ */
69
+ saveFile: func(fName) {
70
+ fRules = sets.add(fRules, fName)
71
+ return self
72
+ },
73
+
74
+ /**
75
+ * Save file content.
76
+ *
77
+ * @param fName: string - file name
78
+ *
79
+ */
80
+ saveFileContent: func(fName) {
81
+ cRules = sets.add(cRules, fName)
82
+ return self
83
+ },
84
+
85
+ /**
86
+ * Get field pointing to saved files map resource
87
+ */
88
+ getSavedFiles: func() {
89
+ return self.getField(_SAVED_FILES_FIELD)
90
+ },
91
+
92
+ /**
93
+ * Get field pointing to saved files content map resource
94
+ */
95
+ getSavedFilesContent: func() {
96
+ return self.getField(_SAVED_CONTENT_FIELD)
97
+ },
98
+
99
+ /**
100
+ * Get field pointing to workdir after resource
101
+ */
102
+ getWorkdirAfter: func() {
103
+ return self.getField(_WORKDIR_AFTER_FIELD)
104
+ },
105
+
106
+ /**
107
+ * Get field pointing to progress resource
108
+ */
109
+ getProgress: func() {
110
+ return self.getField(_PROGRESS_FIELD)
111
+ },
112
+
113
+ /**
114
+ * Get future field pointing to saved file resource
115
+ */
116
+ getSavedFile: func(fName) {
117
+ return self.getSavedFiles().getFutureInputField(fName)
118
+ },
119
+
120
+ /**
121
+ * Get future field pointing to saved file content value resource
122
+ */
123
+ getSavedFileContent: func(fName) {
124
+ return self.getSavedFilesContent().getFutureInputField(fName)
125
+ },
126
+
127
+ /**
128
+ * Build resource
129
+ */
130
+ build: func() {
131
+ rules := []
132
+ for fName, _ in fRules {
133
+ rules = append(rules, getFileSaveRule(fName))
134
+ }
135
+ for fName, _ in cRules {
136
+ rules = append(rules, getContentSaveRule(fName))
137
+ }
138
+
139
+ super.getField(_RULES_FIELD).set(
140
+ smart.createValueResource(
141
+ constants.RTYPE_WORKDIR_SAVE_RULES,
142
+ json.encode(rules)
143
+ )
144
+ )
145
+
146
+ resource := super.lockAndBuild()
147
+
148
+ // still return self to have all the methods
149
+ return self
150
+ }
151
+ }))
152
+
153
+ return self
154
+ }
155
+
156
+ export ll.toStrict({
157
+ builder: builder
158
+ })
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Utility functions to work with export objects & p-frames
3
+ */
4
+
5
+ ll := import("@platforma-sdk/workflow-tengo:ll")
6
+ constants := import("@platforma-sdk/workflow-tengo:constants")
7
+ json := import("json")
8
+ smart := import("@platforma-sdk/workflow-tengo:smart")
9
+ validation := import("@platforma-sdk/workflow-tengo:validation")
10
+
11
+
12
+ //
13
+ _pObjectSpecSchema := {
14
+ "__options__,closed": "",
15
+
16
+ "kind": "string",
17
+
18
+ "valueType,omitempty": `string,regex=json|File|DynamicFile|String|Double|Long|Int`,
19
+
20
+ "name,omitempty": {",any": "string"},
21
+
22
+ "domain,omitempty": {",any": "string"},
23
+
24
+ "axesSpec,omitempty": [{
25
+ "type": "string,regex=String",
26
+ "name": "string",
27
+ "domain,omitempty": {",any": "string"},
28
+ "annotations,omitempty": {",any": "string"}
29
+ }],
30
+
31
+ "annotations,omitempty": {",any": "string"}
32
+ }
33
+
34
+
35
+ /**
36
+ * Creates export object spec from a given map
37
+ *
38
+ * @param spec: map
39
+ */
40
+ createSpec := func(spec) {
41
+ ll.assert(ll.isMap(spec), "expected map got %v", spec)
42
+
43
+ // @TODO fix validation
44
+ // validation.assertValidJson(spec, _pObjectSpecSchema)
45
+
46
+ return smart.createValueResource(constants.RTYPE_BOBJECT_SPEC, json.encode(spec))
47
+ }
48
+
49
+ export ll.toStrict({
50
+ createSpec: createSpec
51
+ })