@voxgig/sdkgen 4.22.0 → 4.23.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/bin/voxgig-sdkgen +1 -1
- package/dist/cmp/ReadmeTop.js +1 -1
- package/dist/cmp/ReadmeTop.js.map +1 -1
- package/dist/cmp/ReadmeUnions.js +1 -1
- package/dist/cmp/ReadmeUnions.js.map +1 -1
- package/dist/cmp/Test.js +1 -1
- package/dist/cmp/Test.js.map +1 -1
- package/dist/helpers/buildIdNames.d.ts +3 -1
- package/dist/helpers/buildIdNames.js +15 -7
- package/dist/helpers/buildIdNames.js.map +1 -1
- package/dist/helpers/canonSpec.js +2 -2
- package/dist/helpers/canonSpec.js.map +1 -1
- package/dist/helpers/getMatchEntries.js +2 -2
- package/dist/helpers/getMatchEntries.js.map +1 -1
- package/dist/helpers/modelNames.js +5 -1
- package/dist/helpers/modelNames.js.map +1 -1
- package/dist/helpers/opShape.js +33 -33
- package/dist/helpers/opShape.js.map +1 -1
- package/dist/helpers/pointPath.js +5 -10
- package/dist/helpers/pointPath.js.map +1 -1
- package/dist/helpers/resolved.js +2 -29
- package/dist/helpers/resolved.js.map +1 -1
- package/dist/sdkgen.d.ts +2 -2
- package/dist/sdkgen.js +5 -3
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utility.js +15 -7
- package/dist/utility.js.map +1 -1
- package/package.json +3 -3
- package/project/.sdk/src/cmp/c/EntityTypes_c.ts +4 -4
- package/project/.sdk/src/cmp/c/ReadmeEntity_c.ts +3 -3
- package/project/.sdk/src/cmp/c/ReadmeModel_c.ts +3 -3
- package/project/.sdk/src/cmp/c/ReadmeRef_c.ts +5 -5
- package/project/.sdk/src/cmp/c/Schema_c.ts +1 -1
- package/project/.sdk/src/cmp/c/TestDirect_c.ts +12 -12
- package/project/.sdk/src/cmp/clojure/ReadmeEntity_clojure.ts +3 -3
- package/project/.sdk/src/cmp/clojure/ReadmeModel_clojure.ts +3 -3
- package/project/.sdk/src/cmp/clojure/ReadmeRef_clojure.ts +5 -5
- package/project/.sdk/src/cmp/clojure/Schema_clojure.ts +1 -1
- package/project/.sdk/src/cmp/cpp/EntityTypes_cpp.ts +3 -3
- package/project/.sdk/src/cmp/cpp/ReadmeEntity_cpp.ts +3 -3
- package/project/.sdk/src/cmp/cpp/ReadmeModel_cpp.ts +3 -3
- package/project/.sdk/src/cmp/cpp/ReadmeRef_cpp.ts +5 -5
- package/project/.sdk/src/cmp/cpp/Schema_cpp.ts +1 -1
- package/project/.sdk/src/cmp/cpp/TestDirect_cpp.ts +14 -14
- package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +51 -50
- package/project/.sdk/src/cmp/csharp/EntityTypes_csharp.ts +4 -4
- package/project/.sdk/src/cmp/csharp/ReadmeEntity_csharp.ts +3 -3
- package/project/.sdk/src/cmp/csharp/ReadmeModel_csharp.ts +3 -3
- package/project/.sdk/src/cmp/csharp/ReadmeRef_csharp.ts +5 -5
- package/project/.sdk/src/cmp/csharp/Schema_csharp.ts +1 -1
- package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +30 -30
- package/project/.sdk/src/cmp/csharp/TestEntity_csharp.ts +66 -65
- package/project/.sdk/src/cmp/elixir/EntityTypes_elixir.ts +4 -4
- package/project/.sdk/src/cmp/elixir/ReadmeEntity_elixir.ts +3 -3
- package/project/.sdk/src/cmp/elixir/ReadmeModel_elixir.ts +3 -3
- package/project/.sdk/src/cmp/elixir/ReadmeRef_elixir.ts +4 -4
- package/project/.sdk/src/cmp/elixir/Schema_elixir.ts +1 -1
- package/project/.sdk/src/cmp/go/EntityTypes_go.ts +4 -4
- package/project/.sdk/src/cmp/go/ReadmeEntity_go.ts +3 -3
- package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +3 -3
- package/project/.sdk/src/cmp/go/ReadmeRef_go.ts +5 -5
- package/project/.sdk/src/cmp/go/Schema_go.ts +1 -1
- package/project/.sdk/src/cmp/go/TestDirect_go.ts +38 -38
- package/project/.sdk/src/cmp/go/TestEntity_go.ts +75 -74
- package/project/.sdk/src/cmp/go/utility_go.ts +5 -5
- package/project/.sdk/src/cmp/java/EntityTypes_java.ts +4 -4
- package/project/.sdk/src/cmp/java/ReadmeEntity_java.ts +3 -3
- package/project/.sdk/src/cmp/java/ReadmeModel_java.ts +3 -3
- package/project/.sdk/src/cmp/java/ReadmeRef_java.ts +5 -5
- package/project/.sdk/src/cmp/java/Schema_java.ts +1 -1
- package/project/.sdk/src/cmp/java/TestDirect_java.ts +30 -30
- package/project/.sdk/src/cmp/java/TestEntity_java.ts +69 -68
- package/project/.sdk/src/cmp/js/EntityTypes_js.ts +5 -5
- package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +3 -3
- package/project/.sdk/src/cmp/js/ReadmeModel_js.ts +3 -3
- package/project/.sdk/src/cmp/js/ReadmeRef_js.ts +5 -5
- package/project/.sdk/src/cmp/js/Schema_js.ts +1 -1
- package/project/.sdk/src/cmp/js/TestDirect_js.ts +27 -27
- package/project/.sdk/src/cmp/js/TestEntity_js.ts +66 -69
- package/project/.sdk/src/cmp/js/TestLive_js.ts +3 -3
- package/project/.sdk/src/cmp/js/utility_js.ts +5 -5
- package/project/.sdk/src/cmp/kotlin/EntityTypes_kotlin.ts +4 -4
- package/project/.sdk/src/cmp/kotlin/ReadmeEntity_kotlin.ts +3 -3
- package/project/.sdk/src/cmp/kotlin/ReadmeModel_kotlin.ts +3 -3
- package/project/.sdk/src/cmp/kotlin/ReadmeRef_kotlin.ts +5 -5
- package/project/.sdk/src/cmp/kotlin/Schema_kotlin.ts +1 -1
- package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +30 -30
- package/project/.sdk/src/cmp/kotlin/TestEntity_kotlin.ts +67 -66
- package/project/.sdk/src/cmp/lua/EntityTypes_lua.ts +5 -5
- package/project/.sdk/src/cmp/lua/ReadmeEntity_lua.ts +3 -3
- package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +3 -3
- package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +4 -4
- package/project/.sdk/src/cmp/lua/ReadmeRef_lua.ts +5 -5
- package/project/.sdk/src/cmp/lua/Schema_lua.ts +1 -1
- package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +25 -25
- package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +66 -65
- package/project/.sdk/src/cmp/ocaml/ReadmeEntity_ocaml.ts +3 -3
- package/project/.sdk/src/cmp/ocaml/ReadmeModel_ocaml.ts +3 -3
- package/project/.sdk/src/cmp/ocaml/ReadmeRef_ocaml.ts +5 -5
- package/project/.sdk/src/cmp/ocaml/Schema_ocaml.ts +1 -1
- package/project/.sdk/src/cmp/perl/ReadmeEntity_perl.ts +3 -3
- package/project/.sdk/src/cmp/perl/ReadmeModel_perl.ts +3 -3
- package/project/.sdk/src/cmp/perl/ReadmeRef_perl.ts +5 -5
- package/project/.sdk/src/cmp/perl/Schema_perl.ts +1 -1
- package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +25 -25
- package/project/.sdk/src/cmp/perl/TestEntity_perl.ts +60 -59
- package/project/.sdk/src/cmp/php/EntityTypes_php.ts +4 -4
- package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +3 -3
- package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +3 -3
- package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +4 -4
- package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +5 -5
- package/project/.sdk/src/cmp/php/Schema_php.ts +1 -1
- package/project/.sdk/src/cmp/php/TestDirect_php.ts +25 -25
- package/project/.sdk/src/cmp/php/TestEntity_php.ts +66 -65
- package/project/.sdk/src/cmp/py/EntityTypes_py.ts +4 -4
- package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +3 -3
- package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +3 -3
- package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +5 -5
- package/project/.sdk/src/cmp/py/Schema_py.ts +1 -1
- package/project/.sdk/src/cmp/py/TestDirect_py.ts +25 -25
- package/project/.sdk/src/cmp/py/TestEntity_py.ts +66 -65
- package/project/.sdk/src/cmp/py-data/Main_py-data.ts +4 -4
- package/project/.sdk/src/cmp/rb/EntityTypes_rb.ts +4 -4
- package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +3 -3
- package/project/.sdk/src/cmp/rb/ReadmeModel_rb.ts +3 -3
- package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +4 -4
- package/project/.sdk/src/cmp/rb/ReadmeRef_rb.ts +5 -5
- package/project/.sdk/src/cmp/rb/Schema_rb.ts +1 -1
- package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +25 -25
- package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +66 -65
- package/project/.sdk/src/cmp/rust/EntityTypes_rust.ts +4 -4
- package/project/.sdk/src/cmp/rust/ReadmeEntity_rust.ts +3 -3
- package/project/.sdk/src/cmp/rust/ReadmeModel_rust.ts +3 -3
- package/project/.sdk/src/cmp/rust/ReadmeRef_rust.ts +5 -5
- package/project/.sdk/src/cmp/rust/Schema_rust.ts +1 -1
- package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +18 -18
- package/project/.sdk/src/cmp/rust/TestEntity_rust.ts +63 -62
- package/project/.sdk/src/cmp/scala/EntityTypes_scala.ts +4 -4
- package/project/.sdk/src/cmp/scala/ReadmeEntity_scala.ts +3 -3
- package/project/.sdk/src/cmp/scala/ReadmeModel_scala.ts +3 -3
- package/project/.sdk/src/cmp/scala/ReadmeRef_scala.ts +5 -5
- package/project/.sdk/src/cmp/scala/Schema_scala.ts +1 -1
- package/project/.sdk/src/cmp/scala/TestDirect_scala.ts +14 -14
- package/project/.sdk/src/cmp/scala/TestEntity_scala.ts +60 -59
- package/project/.sdk/src/cmp/swift/EntityTypes_swift.ts +4 -4
- package/project/.sdk/src/cmp/swift/ReadmeEntity_swift.ts +3 -3
- package/project/.sdk/src/cmp/swift/ReadmeModel_swift.ts +3 -3
- package/project/.sdk/src/cmp/swift/ReadmeRef_swift.ts +5 -5
- package/project/.sdk/src/cmp/swift/Schema_swift.ts +1 -1
- package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +5 -5
- package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +3 -3
- package/project/.sdk/src/cmp/ts/ReadmeModel_ts.ts +3 -3
- package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +1 -1
- package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +5 -5
- package/project/.sdk/src/cmp/ts/Schema_ts.ts +1 -1
- package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +40 -40
- package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +72 -75
- package/project/.sdk/src/cmp/ts/TestLive_ts.ts +3 -3
- package/project/.sdk/src/cmp/ts/utility_ts.ts +5 -5
- package/project/.sdk/src/cmp/zig/ReadmeEntity_zig.ts +3 -3
- package/project/.sdk/src/cmp/zig/ReadmeModel_zig.ts +3 -3
- package/project/.sdk/src/cmp/zig/ReadmeRef_zig.ts +5 -5
- package/project/.sdk/src/cmp/zig/Schema_zig.ts +1 -1
- package/project/.sdk/tm/c/feature/test.c +20 -4
- package/project/.sdk/tm/clojure/src/sdk/features.clj +6 -4
- package/project/.sdk/tm/cpp/feature/test.hpp +17 -6
- package/project/.sdk/tm/csharp/feature/TestFeature.cs +10 -4
- package/project/.sdk/tm/elixir/lib/projectname/feature/test.ex +11 -5
- package/project/.sdk/tm/java/feature/TestFeature.java +11 -6
- package/project/.sdk/tm/js/test/live-entity.js +29 -29
- package/project/.sdk/tm/js/test/live-scenarios.js +4 -4
- package/project/.sdk/tm/kotlin/feature/TestFeature.kt +8 -4
- package/project/.sdk/tm/ocaml/sdk_features.ml +6 -4
- package/project/.sdk/tm/perl/feature/test_feature.pm +6 -4
- package/project/.sdk/tm/rb/feature/test_feature.rb +6 -4
- package/project/.sdk/tm/rust/feature/test.rs +8 -4
- package/project/.sdk/tm/scala/feature/TestFeature.scala +10 -6
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/TestFeature.swift +10 -6
- package/project/.sdk/tm/ts/test/live-entity.ts +26 -26
- package/project/.sdk/tm/ts/test/live-scenarios.ts +3 -3
- package/project/.sdk/tm/zig/feature/test.zig +11 -4
- package/project/sdkgen-package.json +1 -1
- package/src/cmp/ReadmeTop.ts +1 -1
- package/src/cmp/ReadmeUnions.ts +1 -1
- package/src/cmp/Test.ts +1 -1
- package/src/helpers/buildIdNames.ts +17 -7
- package/src/helpers/canonSpec.ts +2 -2
- package/src/helpers/getMatchEntries.ts +2 -2
- package/src/helpers/modelNames.ts +6 -1
- package/src/helpers/opShape.ts +33 -33
- package/src/helpers/pointPath.ts +5 -10
- package/src/helpers/resolved.ts +3 -14
- package/src/sdkgen.ts +3 -1
- package/src/utility.ts +16 -7
|
@@ -30,20 +30,36 @@ static voxgig_value* envelope(Context* ctx, voxgig_value* data) {
|
|
|
30
30
|
if (NULL == spec) {
|
|
31
31
|
return data;
|
|
32
32
|
}
|
|
33
|
-
//
|
|
34
|
-
//
|
|
33
|
+
// Rebuild whatever nesting the transform unwraps. Multi-segment on purpose:
|
|
34
|
+
// GraphQL ops unwrap `body.data.<field>` (and `body.data.<field>.<entity>`
|
|
35
|
+
// for mutation payloads), not just a single envelope property.
|
|
35
36
|
size_t n = strlen(spec);
|
|
36
37
|
if (n < 8 || 0 != strncmp(spec, "`body.", 6) || '`' != spec[n - 1]) {
|
|
37
38
|
return data;
|
|
38
39
|
}
|
|
39
40
|
size_t inner_len = n - 7;
|
|
40
|
-
if (0 == inner_len
|
|
41
|
+
if (0 == inner_len) {
|
|
41
42
|
return data;
|
|
42
43
|
}
|
|
43
44
|
char* inner = (char*)malloc(inner_len + 1);
|
|
44
45
|
memcpy(inner, spec + 6, inner_len);
|
|
45
46
|
inner[inner_len] = '\0';
|
|
46
|
-
|
|
47
|
+
// Innermost segment first, so walk back from the end, terminating each
|
|
48
|
+
// segment in place as it is consumed. cmap copies the key.
|
|
49
|
+
voxgig_value* out = data;
|
|
50
|
+
size_t pos = inner_len;
|
|
51
|
+
while (1) {
|
|
52
|
+
size_t start = pos;
|
|
53
|
+
while (start > 0 && '.' != inner[start - 1]) {
|
|
54
|
+
start--;
|
|
55
|
+
}
|
|
56
|
+
inner[pos] = '\0';
|
|
57
|
+
out = cmap(1, inner + start, out);
|
|
58
|
+
if (0 == start) {
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
pos = start - 1;
|
|
62
|
+
}
|
|
47
63
|
free(inner);
|
|
48
64
|
return out;
|
|
49
65
|
}
|
|
@@ -124,11 +124,13 @@
|
|
|
124
124
|
(let [envelope (fn [data]
|
|
125
125
|
(let [tm (vs/getprop (core/oget fctx :point) "transform")
|
|
126
126
|
spec (vs/getprop tm "res")]
|
|
127
|
-
;;
|
|
128
|
-
;;
|
|
127
|
+
;; Rebuild whatever nesting the transform unwraps;
|
|
128
|
+
;; GraphQL ops unwrap `body.data.<field>`.
|
|
129
129
|
(if (and (some? data) (string? spec))
|
|
130
|
-
(if-let [m (re-matches #"`body\.(
|
|
131
|
-
(vs/jm
|
|
130
|
+
(if-let [m (re-matches #"`body\.(.+)`" spec)]
|
|
131
|
+
(reduce (fn [out seg] (vs/jm seg out))
|
|
132
|
+
data
|
|
133
|
+
(reverse (str/split (second m) #"\." -1)))
|
|
132
134
|
data)
|
|
133
135
|
data)))
|
|
134
136
|
respond (fn [status data extra]
|
|
@@ -68,16 +68,27 @@ private:
|
|
|
68
68
|
Value restf = getp(tm, "res");
|
|
69
69
|
if (!restf.is_string()) return data;
|
|
70
70
|
std::string spec = restf.as_string();
|
|
71
|
-
//
|
|
72
|
-
//
|
|
71
|
+
// Rebuild whatever nesting the transform unwraps. Multi-segment on purpose:
|
|
72
|
+
// GraphQL ops unwrap `body.data.<field>`, not just one envelope property.
|
|
73
73
|
if (spec.size() < 8) return data;
|
|
74
74
|
if (0 != spec.compare(0, 6, "`body.")) return data;
|
|
75
75
|
if ('`' != spec[spec.size() - 1]) return data;
|
|
76
76
|
std::string inner = spec.substr(6, spec.size() - 7);
|
|
77
|
-
if (inner.empty()
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
if (inner.empty()) return data;
|
|
78
|
+
std::vector<std::string> segs;
|
|
79
|
+
for (size_t at = 0;;) {
|
|
80
|
+
size_t dot = inner.find('.', at);
|
|
81
|
+
if (std::string::npos == dot) { segs.push_back(inner.substr(at)); break; }
|
|
82
|
+
segs.push_back(inner.substr(at, dot - at));
|
|
83
|
+
at = dot + 1;
|
|
84
|
+
}
|
|
85
|
+
Value out = data;
|
|
86
|
+
for (size_t i = segs.size(); i > 0; i--) {
|
|
87
|
+
Value wrapped = vmap();
|
|
88
|
+
map_put(wrapped, segs[i - 1], out);
|
|
89
|
+
out = wrapped;
|
|
90
|
+
}
|
|
91
|
+
return out;
|
|
81
92
|
}
|
|
82
93
|
|
|
83
94
|
Value respond(CtxPtr ctx, int status, const Value& data, const Value& extra) {
|
|
@@ -59,15 +59,21 @@ public class TestFeature : BaseFeature
|
|
|
59
59
|
if (data == null || ctx2.Point == null) { return data; }
|
|
60
60
|
var tm = StructUtils.GetProp(ctx2.Point, "transform");
|
|
61
61
|
if (StructUtils.GetProp(tm, "res") is not string spec) { return data; }
|
|
62
|
-
//
|
|
63
|
-
//
|
|
62
|
+
// Rebuild whatever nesting the transform unwraps. Multi-segment on purpose:
|
|
63
|
+
// GraphQL ops unwrap `body.data.<field>`, not just one envelope property.
|
|
64
64
|
if (!spec.StartsWith("`body.") || !spec.EndsWith("`") || spec.Length < 8)
|
|
65
65
|
{
|
|
66
66
|
return data;
|
|
67
67
|
}
|
|
68
68
|
var inner = spec.Substring(6, spec.Length - 7);
|
|
69
|
-
if (inner.Length == 0
|
|
70
|
-
|
|
69
|
+
if (inner.Length == 0) { return data; }
|
|
70
|
+
var segs = inner.Split('.');
|
|
71
|
+
object? built = data;
|
|
72
|
+
for (var i = segs.Length - 1; 0 <= i; i--)
|
|
73
|
+
{
|
|
74
|
+
built = new Dictionary<string, object?> { [segs[i]] = built };
|
|
75
|
+
}
|
|
76
|
+
return built;
|
|
71
77
|
}
|
|
72
78
|
|
|
73
79
|
Dictionary<string, object?> Respond(int status, object? data,
|
|
@@ -55,16 +55,22 @@ defmodule ProjectName.Feature.Test do
|
|
|
55
55
|
defp envelope(fctx, data) do
|
|
56
56
|
spec = S.getprop(S.getprop(S.getprop(fctx, "point"), "transform"), "res")
|
|
57
57
|
|
|
58
|
-
#
|
|
59
|
-
#
|
|
58
|
+
# Rebuild whatever nesting the transform unwraps. Multi-segment on purpose:
|
|
59
|
+
# GraphQL ops unwrap `body.data.<field>`, not just one envelope property.
|
|
60
60
|
case {data, spec} do
|
|
61
61
|
{nil, _} ->
|
|
62
62
|
data
|
|
63
63
|
|
|
64
64
|
{_, s} when is_binary(s) ->
|
|
65
|
-
case Regex.run(~r/^`body\.(
|
|
66
|
-
[_, inner] ->
|
|
67
|
-
|
|
65
|
+
case Regex.run(~r/^`body\.(.+)`$/, s) do
|
|
66
|
+
[_, inner] ->
|
|
67
|
+
inner
|
|
68
|
+
|> String.split(".")
|
|
69
|
+
|> Enum.reverse()
|
|
70
|
+
|> Enum.reduce(data, fn seg, out -> S.jm([seg, out]) end)
|
|
71
|
+
|
|
72
|
+
_ ->
|
|
73
|
+
data
|
|
68
74
|
end
|
|
69
75
|
|
|
70
76
|
_ ->
|
|
@@ -109,18 +109,23 @@ public class TestFeature extends BaseFeature {
|
|
|
109
109
|
return data;
|
|
110
110
|
}
|
|
111
111
|
String spec = (String) restf;
|
|
112
|
-
//
|
|
113
|
-
//
|
|
112
|
+
// Rebuild whatever nesting the transform unwraps. Multi-segment on purpose:
|
|
113
|
+
// GraphQL ops unwrap `body.data.<field>`, not just one envelope property.
|
|
114
114
|
if (!spec.startsWith("`body.") || !spec.endsWith("`") || spec.length() < 8) {
|
|
115
115
|
return data;
|
|
116
116
|
}
|
|
117
117
|
String inner = spec.substring(6, spec.length() - 1);
|
|
118
|
-
if (inner.isEmpty()
|
|
118
|
+
if (inner.isEmpty()) {
|
|
119
119
|
return data;
|
|
120
120
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
String[] segs = inner.split("\\.", -1);
|
|
122
|
+
Object out = data;
|
|
123
|
+
for (int i = segs.length - 1; 0 <= i; i--) {
|
|
124
|
+
Map<String, Object> wrapped = new LinkedHashMap<>();
|
|
125
|
+
wrapped.put(segs[i], out);
|
|
126
|
+
out = wrapped;
|
|
127
|
+
}
|
|
128
|
+
return out;
|
|
124
129
|
}
|
|
125
130
|
|
|
126
131
|
private Map<String, Object> respond(Context ctx, int status, Object data, Map<String, Object> extra) {
|
|
@@ -10,26 +10,26 @@ const live_runner_1 = require("./live-runner");
|
|
|
10
10
|
const utility_1 = require("./utility");
|
|
11
11
|
// The offline flow keeps its deterministic fixture assertions. Live flows
|
|
12
12
|
// resolve real prerequisites per operation and collect failures until done.
|
|
13
|
-
async function runLiveEntity(setup, entity, flow, accessor) {
|
|
13
|
+
async function runLiveEntity(setup, entity, flow, accessor, facts = {}) {
|
|
14
14
|
const { client, transport } = setup;
|
|
15
|
-
const steps = flow.step || [];
|
|
15
|
+
const steps = (flow.step || []).filter((step) => false !== step.a);
|
|
16
16
|
const created = new Map();
|
|
17
17
|
const listed = [];
|
|
18
18
|
const marks = new Map();
|
|
19
19
|
const idField = entity.id?.field || 'id';
|
|
20
20
|
const copy = (value) => JSON.parse(JSON.stringify(value ?? {}));
|
|
21
|
-
const hasCreate = steps.some(step => step.
|
|
21
|
+
const hasCreate = steps.some(step => step.o === 'create');
|
|
22
22
|
const report = await (0, live_runner_1.runLiveSteps)(steps.map((step, index) => {
|
|
23
|
-
const ref = step.
|
|
24
|
-
const op = step.
|
|
23
|
+
const ref = step.i?.ref || entity.name + '_ref01';
|
|
24
|
+
const op = step.o;
|
|
25
25
|
const excluded = (0, utility_1.isControlSkipped)('entityOp', entity.name + '.' + op, 'live');
|
|
26
26
|
return {
|
|
27
27
|
id: entity.name + '.' + op + '.' + index,
|
|
28
|
-
cleanup: op === 'remove' || (step.
|
|
28
|
+
cleanup: op === 'remove' || (step.v || []).some((v) => v.apply === 'ItemNotExists'),
|
|
29
29
|
excluded: excluded.skip ? excluded.reason || 'Excluded by test control' : undefined,
|
|
30
30
|
run: async (context) => {
|
|
31
31
|
transport.enter(context);
|
|
32
|
-
const points = entity.op?.[op]?.points || [];
|
|
32
|
+
const points = (entity.op?.[op]?.points || []).filter((point) => false !== point.a);
|
|
33
33
|
if (!points.length)
|
|
34
34
|
throw new live_runner_1.LiveBlocked('No modelled operation point');
|
|
35
35
|
const record = created.get(ref);
|
|
@@ -48,7 +48,7 @@ async function runLiveEntity(setup, entity, flow, accessor) {
|
|
|
48
48
|
}
|
|
49
49
|
let input = op === 'create'
|
|
50
50
|
? copy(setup.data.new?.[entity.name]?.[ref]) : {};
|
|
51
|
-
for (const [name, binding] of Object.entries({ ...step.
|
|
51
|
+
for (const [name, binding] of Object.entries({ ...step.m, ...step.d })) {
|
|
52
52
|
const value = setup.idmap[binding] ?? setup.idmap[name];
|
|
53
53
|
if (undefined !== value)
|
|
54
54
|
input[name] = value;
|
|
@@ -66,22 +66,22 @@ async function runLiveEntity(setup, entity, flow, accessor) {
|
|
|
66
66
|
let selected;
|
|
67
67
|
const missing = new Set();
|
|
68
68
|
for (const point of points) {
|
|
69
|
-
if (point.
|
|
69
|
+
if (point.q?.$action !== input.$action)
|
|
70
70
|
continue;
|
|
71
71
|
const candidate = { ...input };
|
|
72
72
|
let viable = true;
|
|
73
|
-
const params = point.
|
|
74
|
-
const query = (point.
|
|
73
|
+
const params = point.g?.params || [];
|
|
74
|
+
const query = (point.g?.query || []).filter((arg) => arg.r);
|
|
75
75
|
for (const arg of [...params, ...query]) {
|
|
76
|
-
if (undefined !== candidate[arg.
|
|
76
|
+
if (undefined !== candidate[arg.n] && null !== candidate[arg.n])
|
|
77
77
|
continue;
|
|
78
|
-
const key = arg.
|
|
79
|
-
const value = setup.idmap[key] ?? setup.idmap[arg.
|
|
78
|
+
const key = arg.n === 'id' ? entity.name + '01' : arg.n.replace(/_id$/, '') + '01';
|
|
79
|
+
const value = setup.idmap[key] ?? setup.idmap[arg.n] ?? loaded?.[arg.n] ?? arg.ex;
|
|
80
80
|
if (undefined !== value && null !== value)
|
|
81
|
-
candidate[arg.
|
|
82
|
-
else if (arg.
|
|
81
|
+
candidate[arg.n] = value;
|
|
82
|
+
else if (arg.r !== false) {
|
|
83
83
|
viable = false;
|
|
84
|
-
missing.add(arg.
|
|
84
|
+
missing.add(arg.n);
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
if (viable) {
|
|
@@ -93,22 +93,22 @@ async function runLiveEntity(setup, entity, flow, accessor) {
|
|
|
93
93
|
if (!resolved)
|
|
94
94
|
throw new live_runner_1.LiveBlocked('No usable route; missing arguments: ' + [...missing].join(', '));
|
|
95
95
|
input = resolved;
|
|
96
|
-
if (op === 'create' && selected.
|
|
97
|
-
const
|
|
98
|
-
const request = (0, live_contract_1.requestContract)(
|
|
96
|
+
if (op === 'create' && facts[selected.m + ' ' + selected.o]) {
|
|
97
|
+
const selectedFacts = facts[selected.m + ' ' + selected.o];
|
|
98
|
+
const request = (0, live_contract_1.requestContract)(selectedFacts);
|
|
99
99
|
if (request.schema)
|
|
100
|
-
input = { ...(0, live_contract_1.synthesizeInput)(request.schema,
|
|
101
|
-
else if (
|
|
100
|
+
input = { ...(0, live_contract_1.synthesizeInput)(request.schema, selected.li?.input ?? request.example) };
|
|
101
|
+
else if (selectedFacts.protocol === 'http')
|
|
102
102
|
input = {};
|
|
103
|
-
for (const arg of selected.
|
|
104
|
-
if (resolved[arg.
|
|
105
|
-
input[arg.
|
|
103
|
+
for (const arg of selected.g?.params || [])
|
|
104
|
+
if (resolved[arg.n] !== undefined)
|
|
105
|
+
input[arg.n] = resolved[arg.n];
|
|
106
106
|
}
|
|
107
107
|
let intendedMark;
|
|
108
108
|
if (op === 'update') {
|
|
109
|
-
for (const spec of step.
|
|
110
|
-
if (spec.apply === 'TextFieldMark' && step.
|
|
111
|
-
const mark = { name: step.
|
|
109
|
+
for (const spec of step.s || []) {
|
|
110
|
+
if (spec.apply === 'TextFieldMark' && step.i?.textfield) {
|
|
111
|
+
const mark = { name: step.i.textfield, value: spec.def.mark + '_' + setup.now };
|
|
112
112
|
input[mark.name] = mark.value;
|
|
113
113
|
intendedMark = mark;
|
|
114
114
|
}
|
|
@@ -127,7 +127,7 @@ async function runLiveEntity(setup, entity, flow, accessor) {
|
|
|
127
127
|
});
|
|
128
128
|
listed.splice(0, listed.length, ...data);
|
|
129
129
|
context.publish(data);
|
|
130
|
-
for (const validation of step.
|
|
130
|
+
for (const validation of step.v || []) {
|
|
131
131
|
const previous = created.get(validation.def?.ref);
|
|
132
132
|
const id = previous?.[idField] ?? previous?.id;
|
|
133
133
|
if (undefined === id)
|
|
@@ -64,10 +64,10 @@ async function runLiveScenarios(SDK, plan, envPrefix, liveDefaults = {}) {
|
|
|
64
64
|
let input = request.schema ? (0, live_contract_1.synthesizeInput)(request.schema, explicit) : explicit ?? {};
|
|
65
65
|
for (const kind of ['params', 'query', 'header', 'cookie'])
|
|
66
66
|
for (const arg of point.args?.[kind] || []) {
|
|
67
|
-
if (arg.
|
|
68
|
-
if (arg.
|
|
69
|
-
throw new live_runner_1.LiveBlocked('Missing required argument: ' + arg.
|
|
70
|
-
input[arg.
|
|
67
|
+
if (arg.r && input[arg.n] === undefined) {
|
|
68
|
+
if (arg.ex === undefined)
|
|
69
|
+
throw new live_runner_1.LiveBlocked('Missing required argument: ' + arg.n);
|
|
70
|
+
input[arg.n] = arg.ex;
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
const role = hint.auth || (point.facts.security?.length === 0 || point.facts.securitySource === 'unspecified' ? 'public' : 'account');
|
|
@@ -63,12 +63,16 @@ class TestFeature : BaseFeature("test", "0.0.1", true) {
|
|
|
63
63
|
if (null == data || null == ctx) return data
|
|
64
64
|
val tm = Struct.getprop(ctx.point, "transform")
|
|
65
65
|
val restf = Struct.getprop(tm, "res") as? String ?: return data
|
|
66
|
-
//
|
|
67
|
-
//
|
|
66
|
+
// Rebuild whatever nesting the transform unwraps. Multi-segment on purpose:
|
|
67
|
+
// GraphQL ops unwrap `body.data.<field>`, not just one envelope property.
|
|
68
68
|
if (!restf.startsWith("`body.") || !restf.endsWith("`") || restf.length < 8) return data
|
|
69
69
|
val inner = restf.substring(6, restf.length - 1)
|
|
70
|
-
if (inner.isEmpty()
|
|
71
|
-
|
|
70
|
+
if (inner.isEmpty()) return data
|
|
71
|
+
var out: Any? = data
|
|
72
|
+
for (seg in inner.split(".").reversed()) {
|
|
73
|
+
out = linkedMapOf<String, Any?>(seg to out)
|
|
74
|
+
}
|
|
75
|
+
return out
|
|
72
76
|
}
|
|
73
77
|
|
|
74
78
|
private fun respond(ctx: Context?, status: Int, data: Any?, extra: MutableMap<String, Any?>?): MutableMap<String, Any?> {
|
|
@@ -1394,12 +1394,14 @@ let test_feature () : feature =
|
|
|
1394
1394
|
match getp (getp ctx.c_point "transform") "res" with
|
|
1395
1395
|
| Str spec ->
|
|
1396
1396
|
let n = String.length spec in
|
|
1397
|
-
(*
|
|
1398
|
-
|
|
1397
|
+
(* Rebuild whatever nesting the transform unwraps. Multi-segment on
|
|
1398
|
+
purpose: GraphQL ops unwrap `body.data.<field>`. *)
|
|
1399
1399
|
if n > 7 && String.sub spec 0 6 = "`body." && spec.[n - 1] = '`' then
|
|
1400
1400
|
let inner = String.sub spec 6 (n - 7) in
|
|
1401
|
-
if String.length inner = 0
|
|
1402
|
-
else
|
|
1401
|
+
if String.length inner = 0 then data
|
|
1402
|
+
else
|
|
1403
|
+
List.fold_left (fun out seg -> jo [(seg, out)]) data
|
|
1404
|
+
(List.rev (String.split_on_char '.' inner))
|
|
1403
1405
|
else data
|
|
1404
1406
|
| _ -> data in
|
|
1405
1407
|
let respond ctx status data extra =
|
|
@@ -66,10 +66,12 @@ sub init {
|
|
|
66
66
|
my $tm = ProjectNameHelpers::gp($fctx->{point}, 'transform');
|
|
67
67
|
my $spec = ProjectNameHelpers::gp($tm, 'res');
|
|
68
68
|
return $data unless defined $spec && !ref($spec);
|
|
69
|
-
#
|
|
70
|
-
#
|
|
71
|
-
return $data unless $spec =~ /^`body\.(
|
|
72
|
-
|
|
69
|
+
# Rebuild whatever nesting the transform unwraps. Multi-segment on purpose:
|
|
70
|
+
# GraphQL ops unwrap `body.data.<field>`, not just one envelope property.
|
|
71
|
+
return $data unless $spec =~ /^`body\.(.+)`$/;
|
|
72
|
+
my $out = $data;
|
|
73
|
+
$out = { $_ => $out } for reverse split /\./, $1, -1;
|
|
74
|
+
return $out;
|
|
73
75
|
};
|
|
74
76
|
|
|
75
77
|
my $respond = sub {
|
|
@@ -4,9 +4,10 @@ require_relative '../utility/struct/voxgig_struct'
|
|
|
4
4
|
require_relative 'base_feature'
|
|
5
5
|
|
|
6
6
|
class ProjectNameTestFeature < ProjectNameBaseFeature
|
|
7
|
-
# The `body.<
|
|
8
|
-
#
|
|
9
|
-
|
|
7
|
+
# The `body.<path>` form of an op's response transform: the mock rebuilds
|
|
8
|
+
# whatever nesting the transform unwraps. Multi-segment on purpose: GraphQL
|
|
9
|
+
# ops unwrap body.data.<field>, not just one level.
|
|
10
|
+
ENVELOPE_RES_RE = /\A`body\.(.+)`\z/
|
|
10
11
|
|
|
11
12
|
def initialize
|
|
12
13
|
super
|
|
@@ -52,7 +53,8 @@ class ProjectNameTestFeature < ProjectNameBaseFeature
|
|
|
52
53
|
restf = transform["res"]
|
|
53
54
|
next data unless restf.is_a?(String)
|
|
54
55
|
m = ENVELOPE_RES_RE.match(restf)
|
|
55
|
-
|
|
56
|
+
next data if m.nil?
|
|
57
|
+
m[1].split('.', -1).reverse.reduce(data) { |out, seg| { seg => out } }
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
respond = ->(status, data, extra) {
|
|
@@ -34,11 +34,15 @@ fn envelope(ctx: &Rc<Context>, data: Value) -> Value {
|
|
|
34
34
|
}
|
|
35
35
|
let restf = crate::core::helpers::getpath(&["transform", "res"], &ctx.point.borrow());
|
|
36
36
|
if let Value::Str(spec) = restf {
|
|
37
|
-
//
|
|
38
|
-
//
|
|
37
|
+
// Rebuild whatever nesting the transform unwraps: a GraphQL op unwraps
|
|
38
|
+
// `body.data.<field>`, not just one envelope property.
|
|
39
39
|
if let Some(inner) = spec.strip_prefix("`body.").and_then(|r| r.strip_suffix('`')) {
|
|
40
|
-
if !inner.is_empty()
|
|
41
|
-
|
|
40
|
+
if !inner.is_empty() {
|
|
41
|
+
let mut out = data;
|
|
42
|
+
for seg in inner.split('.').rev() {
|
|
43
|
+
out = jo(vec![(seg, out)]);
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
42
46
|
}
|
|
43
47
|
}
|
|
44
48
|
}
|
|
@@ -50,14 +50,18 @@ class TestFeature extends BaseFeature("test", "0.0.1", true) {
|
|
|
50
50
|
val tm = Struct.getprop(ctx.point, "transform")
|
|
51
51
|
Struct.getprop(tm, "res") match {
|
|
52
52
|
case spec: String =>
|
|
53
|
-
//
|
|
54
|
-
//
|
|
53
|
+
// Rebuild whatever nesting the transform unwraps. Multi-segment on purpose:
|
|
54
|
+
// GraphQL ops unwrap `body.data.<field>`, not just one envelope property.
|
|
55
55
|
if (!spec.startsWith("`body.") || !spec.endsWith("`") || spec.length < 8) return data
|
|
56
56
|
val inner = spec.substring(6, spec.length - 1)
|
|
57
|
-
if (inner.isEmpty
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
if (inner.isEmpty) return data
|
|
58
|
+
var out: Object = data
|
|
59
|
+
for (seg <- inner.split("\\.", -1).reverse) {
|
|
60
|
+
val wrapped = new java.util.LinkedHashMap[String, Object]()
|
|
61
|
+
wrapped.put(seg, out)
|
|
62
|
+
out = wrapped
|
|
63
|
+
}
|
|
64
|
+
out
|
|
61
65
|
case _ => data
|
|
62
66
|
}
|
|
63
67
|
}
|
|
@@ -16,14 +16,18 @@ private func testEnvelope(_ ctx: Context, _ data: Value) -> Value {
|
|
|
16
16
|
guard let point = ctx.point else { return data }
|
|
17
17
|
guard case .map(let tm)? = point.entries["transform"] else { return data }
|
|
18
18
|
guard case .string(let spec)? = tm.entries["res"] else { return data }
|
|
19
|
-
//
|
|
20
|
-
//
|
|
19
|
+
// Rebuild whatever nesting the transform unwraps. Multi-segment on purpose:
|
|
20
|
+
// GraphQL ops unwrap `body.data.<field>`, not just one envelope property.
|
|
21
21
|
guard spec.hasPrefix("`body."), spec.hasSuffix("`"), spec.count >= 8 else { return data }
|
|
22
22
|
let inner = String(spec.dropFirst(6).dropLast(1))
|
|
23
|
-
guard !inner.isEmpty
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
guard !inner.isEmpty else { return data }
|
|
24
|
+
var out = data
|
|
25
|
+
for seg in inner.split(separator: ".", omittingEmptySubsequences: false).reversed() {
|
|
26
|
+
let wrapped = VMap()
|
|
27
|
+
wrapped.entries[String(seg)] = out
|
|
28
|
+
out = .map(wrapped)
|
|
29
|
+
}
|
|
30
|
+
return out
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
private func testRespond(_ ctx: Context, _ status: Int, _ data: Value, _ extra: VMap?) -> Value {
|
|
@@ -5,26 +5,26 @@ import { isControlSkipped, liveDelayMs } from './utility'
|
|
|
5
5
|
|
|
6
6
|
// The offline flow keeps its deterministic fixture assertions. Live flows
|
|
7
7
|
// resolve real prerequisites per operation and collect failures until done.
|
|
8
|
-
async function runLiveEntity(setup: any, entity: any, flow: any, accessor: string) {
|
|
8
|
+
async function runLiveEntity(setup: any, entity: any, flow: any, accessor: string, facts: any = {}) {
|
|
9
9
|
const { client, transport } = setup
|
|
10
|
-
const steps: any[] = flow.step || []
|
|
10
|
+
const steps: any[] = (flow.step || []).filter((step: any) => false !== step.a)
|
|
11
11
|
const created = new Map<string, any>()
|
|
12
12
|
const listed: any[] = []
|
|
13
13
|
const marks = new Map<string, { name: string, value: any }>()
|
|
14
14
|
const idField = entity.id?.field || 'id'
|
|
15
15
|
const copy = (value: any) => JSON.parse(JSON.stringify(value ?? {}))
|
|
16
|
-
const hasCreate = steps.some(step => step.
|
|
16
|
+
const hasCreate = steps.some(step => step.o === 'create')
|
|
17
17
|
const report = await runLiveSteps(steps.map((step, index) => {
|
|
18
|
-
const ref = step.
|
|
19
|
-
const op = step.
|
|
18
|
+
const ref = step.i?.ref || entity.name + '_ref01'
|
|
19
|
+
const op = step.o
|
|
20
20
|
const excluded = isControlSkipped('entityOp', entity.name + '.' + op, 'live')
|
|
21
21
|
return {
|
|
22
22
|
id: entity.name + '.' + op + '.' + index,
|
|
23
|
-
cleanup: op === 'remove' || (step.
|
|
23
|
+
cleanup: op === 'remove' || (step.v || []).some((v: any) => v.apply === 'ItemNotExists'),
|
|
24
24
|
excluded: excluded.skip ? excluded.reason || 'Excluded by test control' : undefined,
|
|
25
25
|
run: async (context: any) => {
|
|
26
26
|
transport.enter(context)
|
|
27
|
-
const points = entity.op?.[op]?.points || []
|
|
27
|
+
const points = (entity.op?.[op]?.points || []).filter((point: any) => false !== point.a)
|
|
28
28
|
if (!points.length) throw new LiveBlocked('No modelled operation point')
|
|
29
29
|
const record = created.get(ref)
|
|
30
30
|
// A failed create must not turn a later update/remove into a write
|
|
@@ -41,7 +41,7 @@ async function runLiveEntity(setup: any, entity: any, flow: any, accessor: strin
|
|
|
41
41
|
|
|
42
42
|
let input: any = op === 'create'
|
|
43
43
|
? copy(setup.data.new?.[entity.name]?.[ref]) : {}
|
|
44
|
-
for (const [name, binding] of Object.entries({ ...step.
|
|
44
|
+
for (const [name, binding] of Object.entries({ ...step.m, ...step.d })) {
|
|
45
45
|
const value = setup.idmap[binding as string] ?? setup.idmap[name]
|
|
46
46
|
if (undefined !== value) input[name] = value
|
|
47
47
|
}
|
|
@@ -57,34 +57,34 @@ async function runLiveEntity(setup: any, entity: any, flow: any, accessor: strin
|
|
|
57
57
|
let selected: any
|
|
58
58
|
const missing = new Set<string>()
|
|
59
59
|
for (const point of points) {
|
|
60
|
-
if (point.
|
|
60
|
+
if (point.q?.$action !== input.$action) continue
|
|
61
61
|
const candidate = { ...input }
|
|
62
62
|
let viable = true
|
|
63
|
-
const params = point.
|
|
64
|
-
const query = (point.
|
|
63
|
+
const params = point.g?.params || []
|
|
64
|
+
const query = (point.g?.query || []).filter((arg: any) => arg.r)
|
|
65
65
|
for (const arg of [...params, ...query]) {
|
|
66
|
-
if (undefined !== candidate[arg.
|
|
67
|
-
const key = arg.
|
|
68
|
-
const value = setup.idmap[key] ?? setup.idmap[arg.
|
|
69
|
-
if (undefined !== value && null !== value) candidate[arg.
|
|
70
|
-
else if (arg.
|
|
66
|
+
if (undefined !== candidate[arg.n] && null !== candidate[arg.n]) continue
|
|
67
|
+
const key = arg.n === 'id' ? entity.name + '01' : arg.n.replace(/_id$/, '') + '01'
|
|
68
|
+
const value = setup.idmap[key] ?? setup.idmap[arg.n] ?? loaded?.[arg.n] ?? arg.ex
|
|
69
|
+
if (undefined !== value && null !== value) candidate[arg.n] = value
|
|
70
|
+
else if (arg.r !== false) { viable = false; missing.add(arg.n) }
|
|
71
71
|
}
|
|
72
72
|
if (viable) { resolved = candidate; selected = point; break }
|
|
73
73
|
}
|
|
74
74
|
if (!resolved) throw new LiveBlocked('No usable route; missing arguments: ' + [...missing].join(', '))
|
|
75
75
|
input = resolved
|
|
76
|
-
if (op === 'create' && selected.
|
|
77
|
-
const
|
|
78
|
-
const request = requestContract(
|
|
79
|
-
if (request.schema) input = { ...synthesizeInput(request.schema,
|
|
80
|
-
else if (
|
|
81
|
-
for (const arg of selected.
|
|
76
|
+
if (op === 'create' && facts[selected.m + ' ' + selected.o]) {
|
|
77
|
+
const selectedFacts = facts[selected.m + ' ' + selected.o]
|
|
78
|
+
const request = requestContract(selectedFacts)
|
|
79
|
+
if (request.schema) input = { ...synthesizeInput(request.schema, selected.li?.input ?? request.example) }
|
|
80
|
+
else if (selectedFacts.protocol === 'http') input = {}
|
|
81
|
+
for (const arg of selected.g?.params || []) if (resolved[arg.n] !== undefined) input[arg.n] = resolved[arg.n]
|
|
82
82
|
}
|
|
83
83
|
let intendedMark: { name: string, value: any } | undefined
|
|
84
84
|
if (op === 'update') {
|
|
85
|
-
for (const spec of step.
|
|
86
|
-
if (spec.apply === 'TextFieldMark' && step.
|
|
87
|
-
const mark = { name: step.
|
|
85
|
+
for (const spec of step.s || []) {
|
|
86
|
+
if (spec.apply === 'TextFieldMark' && step.i?.textfield) {
|
|
87
|
+
const mark = { name: step.i.textfield, value: spec.def.mark + '_' + setup.now }
|
|
88
88
|
input[mark.name] = mark.value
|
|
89
89
|
intendedMark = mark
|
|
90
90
|
}
|
|
@@ -103,7 +103,7 @@ async function runLiveEntity(setup: any, entity: any, flow: any, accessor: strin
|
|
|
103
103
|
})
|
|
104
104
|
listed.splice(0, listed.length, ...data)
|
|
105
105
|
context.publish(data)
|
|
106
|
-
for (const validation of step.
|
|
106
|
+
for (const validation of step.v || []) {
|
|
107
107
|
const previous = created.get(validation.def?.ref)
|
|
108
108
|
const id = previous?.[idField] ?? previous?.id
|
|
109
109
|
if (undefined === id) continue
|
|
@@ -52,9 +52,9 @@ export async function runLiveScenarios(SDK: any, plan: any[], envPrefix: string,
|
|
|
52
52
|
const explicit = hint.input === undefined ? request.example : resolveRecipe(hint.input, ctx.values)
|
|
53
53
|
let input = request.schema ? synthesizeInput(request.schema, explicit) : explicit ?? {}
|
|
54
54
|
for (const kind of ['params', 'query', 'header', 'cookie']) for (const arg of point.args?.[kind] || []) {
|
|
55
|
-
if (arg.
|
|
56
|
-
if (arg.
|
|
57
|
-
input[arg.
|
|
55
|
+
if (arg.r && input[arg.n] === undefined) {
|
|
56
|
+
if (arg.ex === undefined) throw new LiveBlocked('Missing required argument: ' + arg.n)
|
|
57
|
+
input[arg.n] = arg.ex
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
const role = hint.auth || (point.facts.security?.length === 0 || point.facts.securitySource === 'unspecified' ? 'public' : 'account')
|