@platforma-sdk/workflow-tengo 6.17.2 → 6.18.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.
- package/dist/index.cjs +2 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -0
- package/dist/tengo/lib/feats.lib.tengo +3 -0
- package/dist/tengo/lib/pframes.bundle.lib.tengo +30 -5
- package/dist/tengo/lib/pframes.table-builder.lib.tengo +58 -17
- package/dist/tengo/lib/pt.lib.tengo +20 -1
- package/dist/tengo/lib/pt.sizing.lib.tengo +27 -0
- package/dist/tengo/lib/tpl.base.lib.tengo +1 -0
- package/dist/tengo/lib/v2.bquery.lib.tengo +9 -0
- package/dist/tengo/lib/v2.exports.lib.tengo +141 -0
- package/dist/tengo/lib/v2.node-rules.lib.tengo +102 -0
- package/dist/tengo/lib/v2.workflow.lib.tengo +281 -0
- package/dist/tengo/lib/workflow.bquery.lib.tengo +218 -26
- package/dist/tengo/tpl/annotations.compute.plj.gz +0 -0
- package/dist/tengo/tpl/anonymize.deanonymize.plj.gz +0 -0
- package/dist/tengo/tpl/anonymize.impl.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.create_workdir_from_storage.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.download_blob.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.run_hello_world.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.run_hello_world_py.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.upload_blob.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.upload_template.plj.gz +0 -0
- package/dist/tengo/tpl/check_network.workdir_type_name_extractor.plj.gz +0 -0
- package/dist/tengo/tpl/exec.conda.create-env.plj.gz +0 -0
- package/dist/tengo/tpl/exec.delayed-compute-allocation.impl.plj.gz +0 -0
- package/dist/tengo/tpl/exec.exec-impl.plj.gz +0 -0
- package/dist/tengo/tpl/exec.exec.plj.gz +0 -0
- package/dist/tengo/tpl/exec.load-software.impl.plj.gz +0 -0
- package/dist/tengo/tpl/exec.monetization_info.plj.gz +0 -0
- package/dist/tengo/tpl/exec.monetization_to_json.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.create-venv.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.install-deps.plj.gz +0 -0
- package/dist/tengo/tpl/exec.python.venv-bin-path.plj.gz +0 -0
- package/dist/tengo/tpl/ll.get-field.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.build-table.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-multiple-pcolumns.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-parquet-pcolumn-chunk.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-pframe-for-ui.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.export-single-pcolumn.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.import-dir.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.merge-resource-maps.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.parse-to-json.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.process-pcolumn-batch-split.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.process-pcolumn-batch.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.process-pcolumn-data.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.remove-nulls.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.slice-data.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-export-pframe.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-import-if-not-null.plj.gz +0 -0
- package/dist/tengo/tpl/pframes.xsv-import-map.plj.gz +0 -0
- package/dist/tengo/tpl/pt.import-dir.plj.gz +0 -0
- package/dist/tengo/tpl/pt.workflow-run.plj.gz +0 -0
- package/dist/tengo/tpl/v2.export-collection-for-ui.plj.gz +0 -0
- package/dist/tengo/tpl/v2.export-for-ui.plj.gz +0 -0
- package/dist/tengo/tpl/waiter.waiter.plj.gz +0 -0
- package/dist/tengo/tpl/workdir.save.plj.gz +0 -0
- package/dist/tengo/tpl/workflow.build-ctx.plj.gz +0 -0
- package/dist/tengo/tpl/workflow.query-anchored.plj.gz +0 -0
- package/dist/tengo/tpl/workflow.query-context-filter.plj.gz +0 -0
- package/package.json +3 -3
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
ll := import("@platforma-sdk/workflow-tengo:ll")
|
|
40
|
+
text := import("text")
|
|
41
|
+
smart := import("@platforma-sdk/workflow-tengo:smart")
|
|
42
|
+
sets := import("@platforma-sdk/workflow-tengo:sets")
|
|
43
|
+
oop := import("@platforma-sdk/workflow-tengo:oop")
|
|
44
|
+
bquery := import("@platforma-sdk/workflow-tengo:v2.bquery")
|
|
45
|
+
exports := import("@platforma-sdk/workflow-tengo:v2.exports")
|
|
46
|
+
pBundle := import("@platforma-sdk/workflow-tengo:pframes.bundle")
|
|
47
|
+
pTableBuilder := import("@platforma-sdk/workflow-tengo:pframes.table-builder")
|
|
48
|
+
|
|
49
|
+
self := import("@platforma-sdk/workflow-tengo:tpl")
|
|
50
|
+
|
|
51
|
+
_RESULT_OUTPUT := "result"
|
|
52
|
+
_EXPORTS_OUTPUT := "exports"
|
|
53
|
+
_INPUT_CONTEXT := "context"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
_PREPARED_INPUTS_PREFIX := "prepared/"
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
self.defineOutputs([_RESULT_OUTPUT, _EXPORTS_OUTPUT])
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
isProduction := func() {
|
|
66
|
+
return self.rawInputs().isProduction.getValueAsJson() == true
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
_args := undefined
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
args := func() {
|
|
75
|
+
if is_undefined(_args) {
|
|
76
|
+
inputs := self.inputs()
|
|
77
|
+
|
|
78
|
+
_args = inputs.args
|
|
79
|
+
if is_undefined(_args) || smart.isReference(_args) {
|
|
80
|
+
ll.panic("Unexpected args type: %v", _args)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
for k, v in inputs {
|
|
84
|
+
if text.has_prefix(k, _PREPARED_INPUTS_PREFIX) {
|
|
85
|
+
name := text.trim_prefix(k, _PREPARED_INPUTS_PREFIX)
|
|
86
|
+
ll.assert(is_undefined(_args[name]), "prepare name is already in use in inputs: %s", name)
|
|
87
|
+
_args[name] = v
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return _args
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
_blockId := undefined
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
blockId := func() {
|
|
100
|
+
if is_undefined(_blockId) {
|
|
101
|
+
_blockId = self.inputs().blockId
|
|
102
|
+
ll.assert(!is_undefined(_blockId), "block id is not set in workflow inputs")
|
|
103
|
+
}
|
|
104
|
+
return _blockId
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
getBlockId := func() {
|
|
111
|
+
ret := blockId().getDataAsJson()
|
|
112
|
+
ll.assert(is_string(ret), "block id is not a string")
|
|
113
|
+
return ret
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
_parentContext := undefined
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
getParentBCtx := func() {
|
|
123
|
+
if is_undefined(_parentContext) {
|
|
124
|
+
_parentContext = self.inputs()[_INPUT_CONTEXT]
|
|
125
|
+
if is_undefined(_parentContext) {
|
|
126
|
+
ll.panic("parent context is not set in inputs")
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return _parentContext
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
query := func(spec, ...options) {
|
|
142
|
+
return bquery.create(spec, getParentBCtx(), options...)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
_resolveOne := func(r, ...options) {
|
|
146
|
+
res := bquery.resolve(r, getParentBCtx(), options...)
|
|
147
|
+
return ll.toStrict(oop.inherit(res, {
|
|
148
|
+
spec: res.getFutureInputField("spec"),
|
|
149
|
+
data: res.getFutureInputField("data")
|
|
150
|
+
}))
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
resolve := func(ref, ...options) {
|
|
161
|
+
return _resolveOne(ref, options...)
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
anchoredQuery := func(anchors, queryMap, ...opts) {
|
|
169
|
+
return bquery.anchoredQuery(getParentBCtx(), anchors, queryMap, opts...)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
prepare := func(cb) {
|
|
179
|
+
self.prepare(func(_) {
|
|
180
|
+
raw := cb(args())
|
|
181
|
+
prefixed := {}
|
|
182
|
+
for k, v in raw {
|
|
183
|
+
prefixed[_PREPARED_INPUTS_PREFIX + k] = v
|
|
184
|
+
}
|
|
185
|
+
return prefixed
|
|
186
|
+
})
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
validateArgs := func(argsSchema) {
|
|
193
|
+
self.validateInputs({
|
|
194
|
+
args: argsSchema
|
|
195
|
+
})
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
createPBundleBuilder := func() {
|
|
203
|
+
return pBundle.createBuilderWith(bquery, getParentBCtx())
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
tableBuilder := func(format) {
|
|
216
|
+
return pTableBuilder.tableBuilderWith(bquery, format, getParentBCtx())
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
_assertOwnOutputs := func() {
|
|
223
|
+
defined := sets.fromSlice(self.definedOutputs())
|
|
224
|
+
if defined != sets.fromSlice([_RESULT_OUTPUT, _EXPORTS_OUTPUT]) {
|
|
225
|
+
ll.panic("a v2 workflow's outputs are exactly result and exports, but this template defines %v; " +
|
|
226
|
+
"is something it imports using @platforma-sdk/workflow-tengo:workflow?", sets.toSlice(defined))
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
_buildOutputs := func(results) {
|
|
231
|
+
ll.assert(ll.isMap(results) && !smart.isReference(results), "expected to see map result from body function")
|
|
232
|
+
ll.assert(
|
|
233
|
+
sets.fromSlice(["outputs", "exports"]) == sets.fromMapKeys(results),
|
|
234
|
+
"expected only outputs and exports in the returned map, found %v", sets.toSlice(sets.fromMapKeys(results))
|
|
235
|
+
)
|
|
236
|
+
ll.assert(ll.isMap(results.outputs) && !smart.isReference(results.outputs),
|
|
237
|
+
"expected a map in outputs returned from workflow.body")
|
|
238
|
+
|
|
239
|
+
exports.assertNode(results.exports, "exports")
|
|
240
|
+
|
|
241
|
+
resBuilder := smart.mapBuilder()
|
|
242
|
+
for name, value in results.outputs {
|
|
243
|
+
ll.assert(!is_undefined(value), "value is undefined for output %s", name)
|
|
244
|
+
resBuilder.add(name, value)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
tplOutputs := {}
|
|
248
|
+
tplOutputs[_RESULT_OUTPUT] = resBuilder.build()
|
|
249
|
+
tplOutputs[_EXPORTS_OUTPUT] = results.exports
|
|
250
|
+
return tplOutputs
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
body := func(fn) {
|
|
260
|
+
_assertOwnOutputs()
|
|
261
|
+
self.body(func(_) {
|
|
262
|
+
return _buildOutputs(fn(args()))
|
|
263
|
+
})
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
export ll.toStrict({
|
|
267
|
+
getParentBCtx: getParentBCtx,
|
|
268
|
+
query: query,
|
|
269
|
+
resolve: resolve,
|
|
270
|
+
anchoredQuery: anchoredQuery,
|
|
271
|
+
prepare: prepare,
|
|
272
|
+
args: args,
|
|
273
|
+
rawInputs: self.rawInputs,
|
|
274
|
+
body: body,
|
|
275
|
+
isProduction: isProduction,
|
|
276
|
+
blockId: blockId,
|
|
277
|
+
getBlockId: getBlockId,
|
|
278
|
+
validateArgs: validateArgs,
|
|
279
|
+
createPBundleBuilder: createPBundleBuilder,
|
|
280
|
+
tableBuilder: tableBuilder
|
|
281
|
+
})
|
|
@@ -3,6 +3,7 @@ smart := import("@platforma-sdk/workflow-tengo:smart")
|
|
|
3
3
|
maps := import("@platforma-sdk/workflow-tengo:maps")
|
|
4
4
|
constants := import("@platforma-sdk/workflow-tengo:constants")
|
|
5
5
|
json := import("json")
|
|
6
|
+
text := import("text")
|
|
6
7
|
assets := import("@platforma-sdk/workflow-tengo:assets")
|
|
7
8
|
render := import("@platforma-sdk/workflow-tengo:render")
|
|
8
9
|
validation := import("@platforma-sdk/workflow-tengo:validation")
|
|
@@ -13,6 +14,19 @@ queryAnchoredTpl := assets.importTemplate("@platforma-sdk/workflow-tengo:workflo
|
|
|
13
14
|
_CONTEXT_FIELD_NAME := "ctx"
|
|
14
15
|
|
|
15
16
|
|
|
17
|
+
|
|
18
|
+
_FAMILIES := {
|
|
19
|
+
"1": {
|
|
20
|
+
single: constants.RTYPE_BRESOLVE_FIRST,
|
|
21
|
+
choice: constants.RTYPE_BRESOLVE_CHOICE
|
|
22
|
+
},
|
|
23
|
+
"2": {
|
|
24
|
+
single: { Name: "BResolveSingle", Version: "2" },
|
|
25
|
+
choice: { Name: "BResolveChoice", Version: "2" }
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
|
|
16
30
|
_OPTIONS_SCHEME := {
|
|
17
31
|
"spec,?": `bool`,
|
|
18
32
|
"data,?": `bool`,
|
|
@@ -113,9 +127,11 @@ _QUERY_MAP_SCHEMA := {
|
|
|
113
127
|
|
|
114
128
|
|
|
115
129
|
|
|
116
|
-
|
|
130
|
+
_create := func(family, spec, ctx, options) {
|
|
131
|
+
|
|
117
132
|
|
|
118
133
|
|
|
134
|
+
types := _FAMILIES[string(family)]
|
|
119
135
|
|
|
120
136
|
ops := copy(_DEFAULT_OPTIONS)
|
|
121
137
|
if len(options) > 0 {
|
|
@@ -136,10 +152,10 @@ create := func(spec, ctx, ...options) {
|
|
|
136
152
|
|
|
137
153
|
builder := undefined
|
|
138
154
|
if ops.first {
|
|
139
|
-
builder = smart.ephemeralBuilder(
|
|
155
|
+
builder = smart.ephemeralBuilder(types.single, query)
|
|
140
156
|
} else {
|
|
141
157
|
|
|
142
|
-
builder = smart.ephemeralBuilder(
|
|
158
|
+
builder = smart.ephemeralBuilder(types.choice, query)
|
|
143
159
|
}
|
|
144
160
|
|
|
145
161
|
builder.createInputField(_CONTEXT_FIELD_NAME).set(ctx)
|
|
@@ -151,6 +167,9 @@ create := func(spec, ctx, ...options) {
|
|
|
151
167
|
rb := smart.structBuilder(constants.RTYPE_QUERY_RESULT)
|
|
152
168
|
|
|
153
169
|
|
|
170
|
+
if family != 1 {
|
|
171
|
+
ops.family = family
|
|
172
|
+
}
|
|
154
173
|
rb.createInputField("ops").setJson(ops)
|
|
155
174
|
|
|
156
175
|
if ops.spec {
|
|
@@ -171,6 +190,19 @@ create := func(spec, ctx, ...options) {
|
|
|
171
190
|
return rb.lockAndBuild()
|
|
172
191
|
}
|
|
173
192
|
|
|
193
|
+
create := func(spec, ctx, ...options) {
|
|
194
|
+
return _create(1, spec, ctx, options)
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
|
|
174
206
|
|
|
175
207
|
|
|
176
208
|
|
|
@@ -183,6 +215,28 @@ resultUnmarshaller := func() {
|
|
|
183
215
|
parse: func(resource, parser) {
|
|
184
216
|
|
|
185
217
|
ops := resource.get("ops").getDataAsJson()
|
|
218
|
+
isFamily2 := ops.family == 2
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
isNR := func(r) {
|
|
222
|
+
return r.info().Type.Name == constants.RTYPE_BRESOLVE_NO_RESULT.Name
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
isNoResultField := func(field) {
|
|
227
|
+
return field.isSet() && !field.isErrorSet() &&
|
|
228
|
+
field.getValue().checkResourceType(constants.RTYPE_BRESOLVE_NO_RESULT)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
decodeRef := func(address) {
|
|
233
|
+
if !isFamily2 {
|
|
234
|
+
return address
|
|
235
|
+
}
|
|
236
|
+
parts := text.split_n(address.blockId, "/", 2)
|
|
237
|
+
ll.assert(len(parts) == 2, "unexpected address of a family-2 value: %v", address)
|
|
238
|
+
return { block: parts[0], workflow: parts[1], name: address.name }
|
|
239
|
+
}
|
|
186
240
|
|
|
187
241
|
|
|
188
242
|
|
|
@@ -200,22 +254,19 @@ resultUnmarshaller := func() {
|
|
|
200
254
|
if ops.first {
|
|
201
255
|
|
|
202
256
|
|
|
203
|
-
|
|
204
|
-
isNR := func(r) {
|
|
205
|
-
return r.info().Type.Name == constants.RTYPE_BRESOLVE_NO_RESULT.Name
|
|
206
|
-
}
|
|
207
|
-
|
|
208
257
|
if isNR(resource.get("ref")) {
|
|
209
258
|
return undefined
|
|
210
259
|
}
|
|
211
260
|
|
|
212
261
|
result := {
|
|
213
|
-
ref: resource.get("ref").getDataAsJson(),
|
|
262
|
+
ref: decodeRef(resource.get("ref").getDataAsJson()),
|
|
214
263
|
spec: resource.get("spec").getDataAsJson()
|
|
215
264
|
}
|
|
216
265
|
|
|
217
266
|
if resource.hasInputField("data") {
|
|
218
|
-
|
|
267
|
+
if !isFamily2 || !isNoResultField(resource.getField("data")) {
|
|
268
|
+
result.data = getData(resource, "data")
|
|
269
|
+
}
|
|
219
270
|
}
|
|
220
271
|
|
|
221
272
|
return ll.toStrict(result)
|
|
@@ -231,13 +282,18 @@ resultUnmarshaller := func() {
|
|
|
231
282
|
result := []
|
|
232
283
|
maps.forEach(specs, func(ref, s) {
|
|
233
284
|
r := {
|
|
234
|
-
ref: json.decode(ref),
|
|
285
|
+
ref: decodeRef(json.decode(ref)),
|
|
235
286
|
spec: s.getValueAsJson()
|
|
236
287
|
}
|
|
237
288
|
|
|
238
289
|
|
|
290
|
+
|
|
239
291
|
if !is_undefined(datas) {
|
|
240
|
-
|
|
292
|
+
if !isFamily2 {
|
|
293
|
+
r.data = getData(datas, ref)
|
|
294
|
+
} else if datas.hasInputField(ref) && !isNoResultField(datas.getField(ref)) {
|
|
295
|
+
r.data = getData(datas, ref)
|
|
296
|
+
}
|
|
241
297
|
}
|
|
242
298
|
|
|
243
299
|
result = append(result, ll.toStrict(r))
|
|
@@ -262,23 +318,86 @@ resultUnmarshaller := func() {
|
|
|
262
318
|
|
|
263
319
|
|
|
264
320
|
|
|
265
|
-
|
|
321
|
+
_FAMILY2_REF_FIELDS := ["block", "workflow", "name"]
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
_isFamily2Ref := func(value) {
|
|
326
|
+
if !ll.isMap(value) || smart.isReference(value) || len(value) != len(_FAMILY2_REF_FIELDS) {
|
|
327
|
+
return false
|
|
328
|
+
}
|
|
329
|
+
for f in _FAMILY2_REF_FIELDS {
|
|
330
|
+
if !maps.containsKey(value, f) || !is_string(value[f]) || value[f] == "" {
|
|
331
|
+
return false
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return !text.contains(value.block, "/") && !text.contains(value.workflow, "/")
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
_assertFamily2Ref := func(ref) {
|
|
338
|
+
if !_isFamily2Ref(ref) {
|
|
339
|
+
ll.panic("a ref is {block, workflow, name}: three non-empty strings, block and workflow without \"/\"; got %v", ref)
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
_family2Options := func(options, allowed) {
|
|
346
|
+
ll.assert(len(options) <= 1, "expected at most one options map, got %v", options)
|
|
347
|
+
if len(options) == 0 {
|
|
348
|
+
return {}
|
|
349
|
+
}
|
|
350
|
+
o := options[0]
|
|
351
|
+
ll.assert(ll.isMap(o) && !smart.isReference(o), "expected a map of options, got %v", o)
|
|
352
|
+
for k, v in o {
|
|
353
|
+
ok := false
|
|
354
|
+
for a in allowed {
|
|
355
|
+
if a == k {
|
|
356
|
+
ok = true
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
if !ok {
|
|
360
|
+
ll.panic("query option %q is not allowed in the v2 query API; allowed: %v", k, allowed)
|
|
361
|
+
}
|
|
362
|
+
ll.assert(is_bool(v), "query option %q must be a boolean, got %v", k, v)
|
|
363
|
+
}
|
|
364
|
+
return copy(o)
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
_resolve := func(family, ref, ctx, options) {
|
|
266
368
|
|
|
267
|
-
spec :=
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
369
|
+
spec := undefined
|
|
370
|
+
if family == 2 {
|
|
371
|
+
_assertFamily2Ref(ref)
|
|
372
|
+
spec = {
|
|
373
|
+
type: "Direct",
|
|
374
|
+
block_id: ref.block + "/" + ref.workflow,
|
|
375
|
+
output_name: ref.name
|
|
376
|
+
}
|
|
377
|
+
} else {
|
|
378
|
+
spec = {
|
|
379
|
+
type: "Direct",
|
|
380
|
+
block_id: ref.blockId, // @TODO use consistent naming in pl
|
|
381
|
+
output_name: ref.name // @TODO use consistent naming in pl
|
|
382
|
+
}
|
|
271
383
|
}
|
|
272
384
|
|
|
273
385
|
ops := {}
|
|
274
386
|
|
|
275
387
|
if len(options) > 0 {
|
|
276
|
-
ops = options[0]
|
|
388
|
+
ops = copy(options[0])
|
|
277
389
|
}
|
|
278
390
|
|
|
279
391
|
ops.first = true
|
|
392
|
+
if family == 2 {
|
|
393
|
+
ops.errIfMissing = true
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return _create(family, spec, ctx, [ops])
|
|
397
|
+
}
|
|
280
398
|
|
|
281
|
-
|
|
399
|
+
resolve := func(ref, ctx, ...options) {
|
|
400
|
+
return _resolve(1, ref, ctx, options)
|
|
282
401
|
}
|
|
283
402
|
|
|
284
403
|
|
|
@@ -310,7 +429,7 @@ _ANCHORED_QUERY_DEFAULT_OPTIONS := {
|
|
|
310
429
|
|
|
311
430
|
|
|
312
431
|
|
|
313
|
-
|
|
432
|
+
_anchoredQuery := func(family, ctx, anchors, queryMap, opts) {
|
|
314
433
|
|
|
315
434
|
validation.assertType(queryMap, _QUERY_MAP_SCHEMA, "invalid query map schema")
|
|
316
435
|
|
|
@@ -334,7 +453,7 @@ anchoredQuery := func(ctx, anchors, queryMap, ...opts) {
|
|
|
334
453
|
}
|
|
335
454
|
}
|
|
336
455
|
|
|
337
|
-
resolvedAnchors[anchorId] =
|
|
456
|
+
resolvedAnchors[anchorId] = _resolve(family, ref, ctx, [opts])
|
|
338
457
|
}
|
|
339
458
|
|
|
340
459
|
|
|
@@ -356,14 +475,19 @@ anchoredQuery := func(ctx, anchors, queryMap, ...opts) {
|
|
|
356
475
|
}
|
|
357
476
|
}
|
|
358
477
|
|
|
478
|
+
request := {
|
|
479
|
+
queryMap: processedQueryMap,
|
|
480
|
+
opts: normalizedOpts
|
|
481
|
+
}
|
|
482
|
+
if family != 1 {
|
|
483
|
+
request.family = family
|
|
484
|
+
}
|
|
485
|
+
|
|
359
486
|
|
|
360
487
|
queryResult := render.createEphemeral(queryAnchoredTpl, {
|
|
361
488
|
ctx: ctx,
|
|
362
489
|
anchorSpecs: smart.createMapResource(maps.mapValues(resolvedAnchors, func(v) { return v.inputs().spec })),
|
|
363
|
-
request:
|
|
364
|
-
queryMap: processedQueryMap,
|
|
365
|
-
opts: normalizedOpts
|
|
366
|
-
}
|
|
490
|
+
request: request
|
|
367
491
|
})
|
|
368
492
|
|
|
369
493
|
|
|
@@ -422,9 +546,77 @@ anchoredQuery := func(ctx, anchors, queryMap, ...opts) {
|
|
|
422
546
|
return self
|
|
423
547
|
}
|
|
424
548
|
|
|
549
|
+
anchoredQuery := func(ctx, anchors, queryMap, ...opts) {
|
|
550
|
+
return _anchoredQuery(1, ctx, anchors, queryMap, opts)
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
forFamily := func(family) {
|
|
582
|
+
ll.assert(family == 1 || family == 2, "unknown resolver family: %v, expected 1 or 2", family)
|
|
583
|
+
if family == 1 {
|
|
584
|
+
return ll.toStrict({
|
|
585
|
+
create: func(spec, ctx, ...options) {
|
|
586
|
+
return _create(1, spec, ctx, options)
|
|
587
|
+
},
|
|
588
|
+
resolve: func(ref, ctx, ...options) {
|
|
589
|
+
return _resolve(1, ref, ctx, options)
|
|
590
|
+
},
|
|
591
|
+
anchoredQuery: func(ctx, anchors, queryMap, ...opts) {
|
|
592
|
+
return _anchoredQuery(1, ctx, anchors, queryMap, opts)
|
|
593
|
+
}
|
|
594
|
+
})
|
|
595
|
+
}
|
|
596
|
+
return ll.toStrict({
|
|
597
|
+
create: func(spec, ctx, ...options) {
|
|
598
|
+
ops := _family2Options(options, ["spec", "data", "single"])
|
|
599
|
+
if ops.single == true {
|
|
600
|
+
ops.first = true
|
|
601
|
+
ops.errIfMissing = true
|
|
602
|
+
}
|
|
603
|
+
delete(ops, "single")
|
|
604
|
+
return _create(2, spec, ctx, [ops])
|
|
605
|
+
},
|
|
606
|
+
resolve: func(ref, ctx, ...options) {
|
|
607
|
+
return _resolve(2, ref, ctx, [_family2Options(options, ["spec", "data"])])
|
|
608
|
+
},
|
|
609
|
+
anchoredQuery: func(ctx, anchors, queryMap, ...opts) {
|
|
610
|
+
return _anchoredQuery(2, ctx, anchors, queryMap, opts)
|
|
611
|
+
},
|
|
612
|
+
isRef: _isFamily2Ref
|
|
613
|
+
})
|
|
614
|
+
}
|
|
615
|
+
|
|
425
616
|
export ll.toStrict({
|
|
426
617
|
create: create,
|
|
427
618
|
resolve: resolve,
|
|
428
619
|
resultUnmarshaller: resultUnmarshaller,
|
|
429
|
-
anchoredQuery: anchoredQuery
|
|
620
|
+
anchoredQuery: anchoredQuery,
|
|
621
|
+
forFamily: forFamily
|
|
430
622
|
})
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|