@platforma-sdk/workflow-tengo 2.9.5 → 2.9.7

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 (64) hide show
  1. package/dist/tengo/lib/assets.lib.tengo +52 -52
  2. package/dist/tengo/lib/assets.swinfo.lib.tengo +45 -45
  3. package/dist/tengo/lib/constants.lib.tengo +32 -32
  4. package/dist/tengo/lib/exec.R.internal.lib.tengo +29 -29
  5. package/dist/tengo/lib/exec.R.lib.tengo +166 -166
  6. package/dist/tengo/lib/exec.constants.lib.tengo +4 -4
  7. package/dist/tengo/lib/exec.descriptor.lib.tengo +31 -31
  8. package/dist/tengo/lib/exec.internal.lib.tengo +297 -297
  9. package/dist/tengo/lib/exec.lib.tengo +815 -815
  10. package/dist/tengo/lib/exec.monetization.lib.tengo +130 -130
  11. package/dist/tengo/lib/exec.package.lib.tengo +212 -212
  12. package/dist/tengo/lib/exec.python.internal.lib.tengo +6 -6
  13. package/dist/tengo/lib/exec.python.lib.tengo +146 -146
  14. package/dist/tengo/lib/exec.runcmd.lib.tengo +371 -371
  15. package/dist/tengo/lib/exec.runenv.lib.tengo +92 -92
  16. package/dist/tengo/lib/exec.stream.lib.tengo +40 -40
  17. package/dist/tengo/lib/file.internal.lib.tengo +77 -77
  18. package/dist/tengo/lib/file.lib.tengo +57 -57
  19. package/dist/tengo/lib/ll.lib.tengo +244 -244
  20. package/dist/tengo/lib/maps.lib.tengo +152 -152
  21. package/dist/tengo/lib/objects.lib.tengo +13 -13
  22. package/dist/tengo/lib/oop.lib.tengo +19 -19
  23. package/dist/tengo/lib/path.lib.tengo +125 -125
  24. package/dist/tengo/lib/pframes.constants.lib.tengo +28 -28
  25. package/dist/tengo/lib/pframes.export-pcolumn.lib.tengo +33 -33
  26. package/dist/tengo/lib/pframes.lib.tengo +43 -43
  27. package/dist/tengo/lib/pframes.ll.lib.tengo +72 -72
  28. package/dist/tengo/lib/pframes.pcolumn.lib.tengo +49 -49
  29. package/dist/tengo/lib/pframes.spec.lib.tengo +96 -96
  30. package/dist/tengo/lib/pframes.util.lib.tengo +288 -288
  31. package/dist/tengo/lib/pframes.xsv.lib.tengo +272 -272
  32. package/dist/tengo/lib/render.lib.tengo +75 -75
  33. package/dist/tengo/lib/sets.lib.tengo +68 -68
  34. package/dist/tengo/lib/slices.lib.tengo +258 -155
  35. package/dist/tengo/lib/smart.lib.tengo +1069 -1069
  36. package/dist/tengo/lib/test.lib.tengo +161 -161
  37. package/dist/tengo/lib/tpl.lib.tengo +515 -515
  38. package/dist/tengo/lib/tpl.state-await.lib.tengo +240 -240
  39. package/dist/tengo/lib/tpl.util.lib.tengo +9 -9
  40. package/dist/tengo/lib/validation.lib.tengo +378 -378
  41. package/dist/tengo/lib/workdir.lib.tengo +331 -331
  42. package/dist/tengo/lib/workdir.proc.lib.tengo +144 -144
  43. package/dist/tengo/lib/workdir.save.lib.tengo +130 -130
  44. package/dist/tengo/lib/workflow.bobject.lib.tengo +26 -26
  45. package/dist/tengo/lib/workflow.bquery.lib.tengo +165 -165
  46. package/dist/tengo/lib/workflow.constants.lib.tengo +2 -2
  47. package/dist/tengo/lib/workflow.context.lib.tengo +32 -32
  48. package/dist/tengo/lib/workflow.lib.tengo +206 -206
  49. package/dist/tengo/tpl/exec.R.create-renv.plj.gz +0 -0
  50. package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
  51. package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
  52. package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
  53. package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
  54. package/dist/tengo/tpl/pframes.aggregate.plj.gz +0 -0
  55. package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
  56. package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
  57. package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
  58. package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
  59. package/dist/tengo/tpl/pframes.map-pframe.plj.gz +0 -0
  60. package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
  61. package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
  62. package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
  63. package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
  64. package/package.json +2 -2
@@ -7,443 +7,443 @@ smart := import("@platforma-sdk/workflow-tengo:smart")
7
7
 
8
8
  json := import("json")
9
9
 
10
-
11
-
12
-
10
+ //
11
+ // Tools for implementing your own checks:
12
+ //
13
13
 
14
14
  _formatKeyPath := func(current, format, key) {
15
- if current == "" {
16
- if !is_string(key) {
17
- return fmt.sprintf("[%d]", key)
18
- }
15
+ if current == "" {
16
+ if !is_string(key) {
17
+ return fmt.sprintf("[%d]", key)
18
+ }
19
19
 
20
- return key
21
- }
20
+ return key
21
+ }
22
22
 
23
- return fmt.sprintf(format, current, key)
23
+ return fmt.sprintf(format, current, key)
24
24
  }
25
25
 
26
-
27
-
28
-
26
+ /**
27
+ * Validation success result.
28
+ */
29
29
  success := { result: true }
30
30
 
31
-
32
-
33
-
34
-
35
-
36
-
37
-
31
+ /**
32
+ * Validation failure result with a message.
33
+ *
34
+ * @param keyPath: string - the current stack state.
35
+ * @param msg: string - the failure message.
36
+ * @param args: ...any - additional arguments for the message.
37
+ */
38
38
  fail := func(keyPath, msg, ...args) {
39
- return {
40
- result: false,
41
- message: keyPath + ": " + fmt.sprintf(msg, args...)
42
- }
39
+ return {
40
+ result: false,
41
+ message: keyPath + ": " + fmt.sprintf(msg, args...)
42
+ }
43
43
  }
44
44
 
45
45
  isSuccess := func(r) {
46
- return r.result == true
46
+ return r.result == true
47
47
  }
48
48
 
49
-
50
-
51
-
52
-
53
-
49
+ /**
50
+ * Returns true if the validation failed.
51
+ *
52
+ * @param r: either fail or success.
53
+ */
54
54
  isFail := func(r) {
55
- return r.result == false
55
+ return r.result == false
56
56
  }
57
57
 
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
58
+ /**
59
+ * Checks a condition and returns success or failure.
60
+ *
61
+ * @param condition: bool - the condition to check.
62
+ * @param stack: any - the current stack state.
63
+ * @param msg: string - the failure message if the condition is false.
64
+ * @param args: variadic any - additional arguments for the message.
65
+ */
66
66
  check := func(condition, keyPath, msg, ...args) {
67
- if condition {
68
- return success
69
- }
67
+ if condition {
68
+ return success
69
+ }
70
70
 
71
- return fail(keyPath, msg, args...)
71
+ return fail(keyPath, msg, args...)
72
72
  }
73
73
 
74
+ //
75
+ // Validation:
76
+ //
74
77
 
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
78
+ /**
79
+ * Validates JSON types based on tags when the schema is a string.
80
+ *
81
+ * @param js: any - the JSON to validate.
82
+ * @param tags: { key: string, tags: []tag } - the tags to validate against.
83
+ * @param stack: ...any - the current stack state.
84
+ */
85
85
  _validateTypes := func(js, tags, keyPath, ...stack) {
86
- k := tags.key
86
+ k := tags.key
87
87
 
88
- if k == "any" {
89
- return success
90
- }
88
+ if k == "any" {
89
+ return success
90
+ }
91
91
 
92
- if k == "alphanumeric" && ((is_string(js) && text.re_match("^[[:alnum:]]*$", js)) || is_int(js)) {
93
- return success
94
- }
92
+ if k == "alphanumeric" && ((is_string(js) && text.re_match("^[[:alnum:]]*$", js)) || is_int(js)) {
93
+ return success
94
+ }
95
95
 
96
- if k == "string" && is_string(js) {
97
- regex := tags.tags["regex"]
98
- if !is_undefined(regex) && !text.re_match(regex, js) {
99
- return fail(keyPath, "value %q does not conform regex %q", js, regex)
100
- }
96
+ if k == "string" && is_string(js) {
97
+ regex := tags.tags["regex"]
98
+ if !is_undefined(regex) && !text.re_match(regex, js) {
99
+ return fail(keyPath, "value %q does not conform regex %q", js, regex)
100
+ }
101
101
 
102
- return success
103
- }
102
+ return success
103
+ }
104
104
 
105
- if k == "char" && is_char(js) {
106
- return success
107
- }
105
+ if k == "char" && is_char(js) {
106
+ return success
107
+ }
108
108
 
109
- if k == "bytes" && is_bytes(js) {
110
- return success
111
- }
109
+ if k == "bytes" && is_bytes(js) {
110
+ return success
111
+ }
112
112
 
113
- if k == "null" && is_undefined(js) {
114
- return success
115
- }
113
+ if k == "null" && is_undefined(js) {
114
+ return success
115
+ }
116
116
 
117
- if k == "number" && (is_int(js) || is_float(js)) {
118
- return success
119
- }
117
+ if k == "number" && (is_int(js) || is_float(js)) {
118
+ return success
119
+ }
120
120
 
121
- if k == "bool" && is_bool(js) {
122
- return success
123
- }
121
+ if k == "bool" && is_bool(js) {
122
+ return success
123
+ }
124
124
 
125
- return fail(keyPath, "js %q is not one of a type: %s", js, tags.key)
125
+ return fail(keyPath, "js %q is not one of a type: %s", js, tags.key)
126
126
  }
127
127
 
128
-
129
-
130
-
131
-
132
-
133
-
128
+ /**
129
+ * Parses JSON tags from a string rule.
130
+ *
131
+ * @param rule: string - a key with tags, e.g. "any,type=string,regex=abc.*"
132
+ * @return parsedRule: { key: string, tags: map } - the key and tags parsed from the rule.
133
+ */
134
134
  _parseTags := func(rule) {
135
- tagsKV := text.split(rule, ",")
136
- key := tagsKV[0]
137
- tagsKV = tagsKV[1:]
138
-
139
- tags := {}
140
- for _, kv in tagsKV {
141
- kAndV := text.split(kv, "=")
142
- k := kAndV[0]
143
- if len(kAndV) == 1 {
144
- tags[k] = true
145
- } else {
146
- tags[k] = kAndV[1]
147
- }
148
- }
149
-
150
- return ll.toStrict({
151
- key: key,
152
- tags: tags
153
- })
154
- }
155
-
156
-
157
-
158
-
159
-
160
-
161
-
162
-
163
-
135
+ tagsKV := text.split(rule, ",")
136
+ key := tagsKV[0]
137
+ tagsKV = tagsKV[1:]
138
+
139
+ tags := {}
140
+ for _, kv in tagsKV {
141
+ kAndV := text.split(kv, "=")
142
+ k := kAndV[0]
143
+ if len(kAndV) == 1 {
144
+ tags[k] = true
145
+ } else {
146
+ tags[k] = kAndV[1]
147
+ }
148
+ }
149
+
150
+ return ll.toStrict({
151
+ key: key,
152
+ tags: tags
153
+ })
154
+ }
155
+
156
+ /**
157
+ * Validates JSON against a schema.
158
+ *
159
+ * @param js: any - the JSON to validate.
160
+ * @param schema: any - the schema to validate against.
161
+ * @param stack: ...any - the current stack state.
162
+ * @return either fail or success
163
+ */
164
164
  _validateJson := func(js, schema, keyPath, ...stack) {
165
- if is_undefined(schema) {
166
- if len(stack) == 0 {
167
- return fail(keyPath, "key is not defined by schema, but exists in the JSON")
168
- }
169
-
170
- return fail(keyPath, "key is not defined by schema, but exists in the JSON. Validated item: %#v", stack[0])
171
- }
172
-
173
-
174
-
175
- if is_string(schema) {
176
- if schema == "any" {
177
- return success
178
- }
179
- tags := _parseTags(schema)
180
-
181
- return _validateTypes(js, tags, keyPath, stack...)
182
- }
183
-
184
-
185
-
186
-
187
- if is_callable(schema) {
188
- return schema(js, keyPath, stack)
189
- }
190
-
191
-
192
-
193
-
194
- if is_array(schema) && len(schema) > 0 && schema[0] == "or" {
195
- for i, elem in schema[1:] {
196
- r := _validateJson(js, elem, keyPath, stack...)
197
- if isSuccess(r) {
198
- return r
199
- }
200
- }
201
-
202
- return fail(keyPath, "js %q does not fit any of the following rules: %q", js, schema)
203
- }
204
-
205
-
206
-
207
-
208
- if is_array(schema) {
209
- if !is_array(js) {
210
- return fail(keyPath, "js %q must be array", js)
211
- }
212
-
213
- schema = schema[0]
214
- for i, elem in js {
215
- r := _validateJson(elem, schema, _formatKeyPath(keyPath, "%s[%d]", i), js, stack...)
216
- if isFail(r) {
217
- return r
218
- }
219
- }
220
-
221
- return success
222
- }
223
-
224
-
225
-
226
-
227
-
228
- if !ll.isMap(js) {
229
- return fail(keyPath, "js %#v must be map", js)
230
- }
231
-
232
-
233
- schemaTags := {}
234
-
235
- schemaRules := {}
236
-
237
- jsFull := {}
238
-
239
- for k, v in schema {
240
- p := _parseTags(k)
241
- schemaTags[p.key] = p
242
- schemaRules[p.key] = v
243
- jsFull[p.key] = undefined
244
- }
245
-
246
-
247
- any := schemaTags["any"]
248
- if !is_undefined(any) {
249
- if is_undefined(jsFull["any"]) { // in case actual object has field named "any"
250
- delete(jsFull, "any")
251
- }
252
- }
253
-
254
- options := schemaTags["__options__"]
255
- if is_undefined(options) {
256
- options = {}
257
- } else {
258
- delete(schemaTags, "__options__")
259
- delete(schemaRules, "__options__")
260
- if is_undefined(jsFull["__options__"]) { // in case actual object has field named "__options__"
261
- delete(jsFull, "__options__")
262
- }
263
- }
264
-
265
-
266
- for k, v in js {
267
- jsFull[k] = v
268
- }
269
-
270
- for _key, elem in jsFull {
271
- if any {
272
- r := _validateJson(elem, schemaRules["any"], _formatKeyPath(keyPath, "%s.%s", _key), js, stack...)
273
- if isFail(r) {
274
- return r
275
- }
276
-
277
- if !is_undefined(any.tags["type"]) {
278
- r := _validateJson(_key, any.tags["type"], keyPath, stack...)
279
- if isFail(r) {
280
- return r
281
- }
282
- }
283
-
284
- continue
285
- }
286
-
287
-
288
- key := schemaTags[_key]
289
-
290
- if is_undefined(key) {
291
- if options.tags["closed"] == true {
292
- return fail(keyPath, "only keys %v from the schema must be set, found %q", maps.getKeys(schema), _key)
293
- }
294
-
295
- continue
296
- }
297
-
298
- if key.tags["type"] {
299
- r := _validateJson(_key, key.tags["type"], keyPath, stack...)
300
- if isFail(r) {
301
- return r
302
- }
303
- }
304
-
305
- if is_undefined(elem) {
306
- if key.tags["omitempty"] || key.tags["optional"] || key.tags["?"] {
307
- continue
308
- }
309
- return fail(keyPath, "value %q does not contain key %q", js, _key)
310
- }
311
-
312
- r := _validateJson(elem, schemaRules[_key], _formatKeyPath(keyPath, "%s.%s", _key), js, stack...)
313
- if isFail(r) {
314
- return r
315
- }
316
- }
317
-
318
- return success
319
- }
320
-
321
-
322
-
323
-
324
-
325
-
326
-
327
-
165
+ if is_undefined(schema) {
166
+ if len(stack) == 0 {
167
+ return fail(keyPath, "key is not defined by schema, but exists in the JSON")
168
+ }
169
+
170
+ return fail(keyPath, "key is not defined by schema, but exists in the JSON. Validated item: %#v", stack[0])
171
+ }
172
+
173
+ // if the schema is a string, then
174
+ // we check the predefined type.
175
+ if is_string(schema) {
176
+ if schema == "any" {
177
+ return success
178
+ }
179
+ tags := _parseTags(schema)
180
+
181
+ return _validateTypes(js, tags, keyPath, stack...)
182
+ }
183
+
184
+ // if the schema is a function, call it
185
+ // with the element and the path of how we
186
+ // got this element, i.e. recursion history.
187
+ if is_callable(schema) {
188
+ return schema(js, keyPath, stack)
189
+ }
190
+
191
+ // if the schema is an array with "or" at the beginning,
192
+ // we should check if the element is succeed with
193
+ // any of the following elements.
194
+ if is_array(schema) && len(schema) > 0 && schema[0] == "or" {
195
+ for i, elem in schema[1:] {
196
+ r := _validateJson(js, elem, keyPath, stack...)
197
+ if isSuccess(r) {
198
+ return r
199
+ }
200
+ }
201
+
202
+ return fail(keyPath, "js %q does not fit any of the following rules: %q", js, schema)
203
+ }
204
+
205
+ // if the schema is an array, then check that every
206
+ // element of the json has the schema that is the first element
207
+ // of the schema.
208
+ if is_array(schema) {
209
+ if !is_array(js) {
210
+ return fail(keyPath, "js %q must be array", js)
211
+ }
212
+
213
+ schema = schema[0]
214
+ for i, elem in js {
215
+ r := _validateJson(elem, schema, _formatKeyPath(keyPath, "%s[%d]", i), js, stack...)
216
+ if isFail(r) {
217
+ return r
218
+ }
219
+ }
220
+
221
+ return success
222
+ }
223
+
224
+ // only map left, since schema can't be undefined
225
+ // if the schema is a map, check that every key
226
+ // in json-object is in the schema and vice-versa,
227
+ // unless there are tags "any" or "omitempty".
228
+ if !ll.isMap(js) {
229
+ return fail(keyPath, "js %#v must be map", js)
230
+ }
231
+
232
+ // schema.key -> tags
233
+ schemaTags := {}
234
+ // schema.key -> rule
235
+ schemaRules := {}
236
+ // js padded with all keys from schema
237
+ jsFull := {}
238
+
239
+ for k, v in schema {
240
+ p := _parseTags(k)
241
+ schemaTags[p.key] = p
242
+ schemaRules[p.key] = v
243
+ jsFull[p.key] = undefined
244
+ }
245
+
246
+ // tags that should be applied to all elements
247
+ any := schemaTags["any"]
248
+ if !is_undefined(any) {
249
+ if is_undefined(jsFull["any"]) { // in case actual object has field named "any"
250
+ delete(jsFull, "any")
251
+ }
252
+ }
253
+
254
+ options := schemaTags["__options__"]
255
+ if is_undefined(options) {
256
+ options = {}
257
+ } else {
258
+ delete(schemaTags, "__options__")
259
+ delete(schemaRules, "__options__")
260
+ if is_undefined(jsFull["__options__"]) { // in case actual object has field named "__options__"
261
+ delete(jsFull, "__options__")
262
+ }
263
+ }
264
+
265
+ // transferring fields from input map into padded map
266
+ for k, v in js {
267
+ jsFull[k] = v
268
+ }
269
+
270
+ for _key, elem in jsFull {
271
+ if any {
272
+ r := _validateJson(elem, schemaRules["any"], _formatKeyPath(keyPath, "%s.%s", _key), js, stack...)
273
+ if isFail(r) {
274
+ return r
275
+ }
276
+
277
+ if !is_undefined(any.tags["type"]) {
278
+ r := _validateJson(_key, any.tags["type"], keyPath, stack...)
279
+ if isFail(r) {
280
+ return r
281
+ }
282
+ }
283
+
284
+ continue
285
+ }
286
+
287
+ // tags for the key
288
+ key := schemaTags[_key]
289
+
290
+ if is_undefined(key) {
291
+ if options.tags["closed"] == true {
292
+ return fail(keyPath, "only keys %v from the schema must be set, found %q", maps.getKeys(schema), _key)
293
+ }
294
+
295
+ continue
296
+ }
297
+
298
+ if key.tags["type"] {
299
+ r := _validateJson(_key, key.tags["type"], keyPath, stack...)
300
+ if isFail(r) {
301
+ return r
302
+ }
303
+ }
304
+
305
+ if is_undefined(elem) {
306
+ if key.tags["omitempty"] || key.tags["optional"] || key.tags["?"] {
307
+ continue
308
+ }
309
+ return fail(keyPath, "value %q does not contain key %q", js, _key)
310
+ }
311
+
312
+ r := _validateJson(elem, schemaRules[_key], _formatKeyPath(keyPath, "%s.%s", _key), js, stack...)
313
+ if isFail(r) {
314
+ return r
315
+ }
316
+ }
317
+
318
+ return success
319
+ }
320
+
321
+ /**
322
+ * Checks if the given JSON conforms to the given schema.
323
+ *
324
+ * @param js: any - the JSON to check.
325
+ * @param schema: any - the schema to check against.
326
+ * @return either fail or success
327
+ */
328
328
  checkJson := func(js, schema) {
329
- return _validateJson(js, schema, "")
329
+ return _validateJson(js, schema, "")
330
330
  }
331
331
 
332
-
333
-
334
-
335
-
336
-
337
-
338
-
332
+ /**
333
+ * Checks if the given JSON is valid according to the given schema.
334
+ *
335
+ * @param js: any - the JSON to check.
336
+ * @param schema: any - the schema to check against.
337
+ * @return result: bool - the result of the validation (true/false).
338
+ */
339
339
  isValid := func(js, schema) {
340
- return _validateJson(js, schema, "").result
340
+ return _validateJson(js, schema, "").result
341
341
  }
342
342
 
343
-
344
-
345
-
346
-
347
-
348
-
349
-
343
+ /**
344
+ * Asserts that a given JSON conforms to a given schema.
345
+ *
346
+ * @param js: any - the JSON to assert.
347
+ * @param schema: any - the schema to assert against.
348
+ * @param failMsg: string - optional parameter with custom message to be printed on validation error
349
+ */
350
350
  assertJsonSchema := func(js, schema, ...failMsg) {
351
- r := _validateJson(js, schema, "")
351
+ r := _validateJson(js, schema, "")
352
352
 
353
- msg := "JSON validation error"
354
- if len(failMsg) > 0 {
355
- msg = failMsg[0]
356
- }
353
+ msg := "JSON validation error"
354
+ if len(failMsg) > 0 {
355
+ msg = failMsg[0]
356
+ }
357
357
 
358
- if isFail(r) {
359
- ll.panic("%s: %s", msg, r.message)
358
+ if isFail(r) {
359
+ ll.panic("%s: %s", msg, r.message)
360
+ }
360
361
  }
361
- }
362
-
363
-
364
-
365
-
366
-
367
-
368
-
369
-
370
362
 
363
+ //
364
+ // Domain-specific schemas and checks:
365
+ //
371
366
 
367
+ /**
368
+ * Checks if the given element is a resource.
369
+ *
370
+ * @param options: object - resource validation options
371
+ */
372
372
  resource := func(...args) {
373
373
 
374
- ops := {}
375
- if len(args) > 0 {
376
- ops = args[0]
377
- }
378
-
379
- assertJsonSchema(ops, {
380
- `type,?`: {
381
- Name: `string`,
382
- Version: `string`
383
- }
384
- })
385
-
386
- checker := func(elem, keyPath, stack) {
387
- c := undefined
388
-
389
- c = check(smart.isResource(elem), keyPath, "the element " + elem + " must be a resource")
390
- if isFail(c) {
391
- return c
392
- }
393
-
394
- if !is_undefined(ops.type) {
395
- c = check(elem.info().Type.Name == ops.type.Name && elem.info().Type.Version == ops.type.Version, keyPath,
396
- "the element " + elem + " must have the following type: ", ops.type, " found: ", elem.info().Type)
397
- if isFail(c) {
398
- return c
399
- }
400
- }
401
-
402
- return c
403
- }
404
-
405
- return checker
406
- }
407
-
408
-
409
-
410
-
411
-
412
-
374
+ ops := {}
375
+ if len(args) > 0 {
376
+ ops = args[0]
377
+ }
378
+
379
+ assertJsonSchema(ops, {
380
+ `type,?`: {
381
+ Name: `string`,
382
+ Version: `string`
383
+ }
384
+ })
385
+
386
+ checker := func(elem, keyPath, stack) {
387
+ c := undefined
388
+
389
+ c = check(smart.isResource(elem), keyPath, "the element " + elem + " must be a resource")
390
+ if isFail(c) {
391
+ return c
392
+ }
393
+
394
+ if !is_undefined(ops.type) {
395
+ c = check(elem.info().Type.Name == ops.type.Name && elem.info().Type.Version == ops.type.Version, keyPath,
396
+ "the element " + elem + " must have the following type: ", ops.type, " found: ", elem.info().Type)
397
+ if isFail(c) {
398
+ return c
399
+ }
400
+ }
401
+
402
+ return c
403
+ }
404
+
405
+ return checker
406
+ }
407
+
408
+ /**
409
+ * Checks if the given element is a resource with specified type.
410
+ *
411
+ * @param rt: ResourceType - desired resource type
412
+ */
413
413
  resourceType := func(rt) {
414
- return func(elem, keyPath, stack) {
415
- return check(smart.isResource(elem) && elem.info().Type.Name == rt.Name, keyPath, "the element " + elem + " must be a resource")
416
- }
414
+ return func(elem, keyPath, stack) {
415
+ return check(smart.isResource(elem) && elem.info().Type.Name == rt.Name, keyPath, "the element " + elem + " must be a resource")
416
+ }
417
417
  }
418
418
 
419
-
420
-
421
-
422
-
423
-
424
-
419
+ /**
420
+ * Checks if the given element is a reference.
421
+ *
422
+ * @param elem: any - the element to check.
423
+ * @param stack: any - the current stack state.
424
+ */
425
425
  reference := func(elem, keyPath, stack) {
426
- return check(smart.isReference(elem), keyPath, "the element " + elem + " must be a resource or a field")
426
+ return check(smart.isReference(elem), keyPath, "the element " + elem + " must be a resource or a field")
427
427
  }
428
428
 
429
-
430
-
431
-
429
+ /**
430
+ * Schema for reference
431
+ */
432
432
  refSchema := {
433
- blockId: `string`,
434
- name: `string`
433
+ blockId: `string`,
434
+ name: `string`
435
435
  }
436
436
 
437
437
  export ll.toStrict({
438
- success: success,
439
- fail: fail,
440
- isSuccess: isSuccess,
441
- isFail: isFail,
442
- checkJson: checkJson,
443
- isValid: isValid,
444
- assertJsonSchema: assertJsonSchema,
445
- resource: resource,
446
- reference: reference,
447
- resourceType: resourceType,
448
- ref: refSchema
438
+ success: success,
439
+ fail: fail,
440
+ isSuccess: isSuccess,
441
+ isFail: isFail,
442
+ checkJson: checkJson,
443
+ isValid: isValid,
444
+ assertJsonSchema: assertJsonSchema,
445
+ resource: resource,
446
+ reference: reference,
447
+ resourceType: resourceType,
448
+ ref: refSchema
449
449
  })