@voxgig/sdkgen 4.22.0 → 4.24.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 +18 -2
- package/dist/action/doctor.d.ts +1 -1
- package/dist/action/doctor.js +12 -10
- package/dist/action/doctor.js.map +1 -1
- package/dist/action/edition.js +4 -0
- package/dist/action/edition.js.map +1 -1
- package/dist/action/feature.js +5 -1
- package/dist/action/feature.js.map +1 -1
- package/dist/action/remove.d.ts +16 -0
- package/dist/action/remove.js +345 -0
- package/dist/action/remove.js.map +1 -0
- package/dist/action/target.js +6 -1
- package/dist/action/target.js.map +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/core/context.c +3 -1
- package/project/.sdk/tm/c/feature/paging.c +37 -3
- package/project/.sdk/tm/c/feature/test.c +71 -31
- package/project/.sdk/tm/c/utility/prepare_query.c +2 -1
- package/project/.sdk/tm/c/utility/transform_request.c +25 -3
- package/project/.sdk/tm/clojure/src/sdk/core.clj +21 -7
- package/project/.sdk/tm/clojure/src/sdk/features.clj +74 -22
- package/project/.sdk/tm/cpp/core/types.hpp +1 -1
- package/project/.sdk/tm/cpp/feature/paging.hpp +36 -3
- package/project/.sdk/tm/cpp/feature/test.hpp +58 -19
- package/project/.sdk/tm/cpp/utility/pipeline.hpp +16 -4
- package/project/.sdk/tm/csharp/core/Context.cs +1 -1
- package/project/.sdk/tm/csharp/feature/PagingFeature.cs +58 -4
- package/project/.sdk/tm/csharp/feature/TestFeature.cs +23 -25
- package/project/.sdk/tm/csharp/utility/Fetcher.cs +19 -12
- package/project/.sdk/tm/csharp/utility/PrepareQuery.cs +1 -1
- package/project/.sdk/tm/csharp/utility/TransformRequest.cs +23 -3
- package/project/.sdk/tm/elixir/lib/projectname/context.ex +1 -1
- package/project/.sdk/tm/elixir/lib/projectname/feature/paging.ex +52 -10
- package/project/.sdk/tm/elixir/lib/projectname/feature/test.ex +58 -22
- package/project/.sdk/tm/elixir/lib/projectname/utility.ex +30 -9
- package/project/.sdk/tm/go/core/context.go +13 -13
- package/project/.sdk/tm/go/feature/paging_feature.go +40 -2
- package/project/.sdk/tm/go/feature/test_feature.go +3 -15
- package/project/.sdk/tm/go/test/feature_corpus_test.go +1 -0
- package/project/.sdk/tm/go/test/feature_test.go +54 -0
- package/project/.sdk/tm/go/utility/fetcher.go +41 -20
- package/project/.sdk/tm/go/utility/prepare_query.go +1 -1
- package/project/.sdk/tm/go/utility/transform_request.go +22 -3
- package/project/.sdk/tm/java/core/Context.java +2 -1
- package/project/.sdk/tm/java/feature/PagingFeature.java +46 -4
- package/project/.sdk/tm/java/feature/TestFeature.java +21 -19
- package/project/.sdk/tm/java/test/FeatureCorpusTest.java +3 -0
- package/project/.sdk/tm/java/test/FeatureTest.java +42 -0
- package/project/.sdk/tm/java/utility/Fetcher.java +36 -28
- package/project/.sdk/tm/java/utility/PrepareQuery.java +1 -1
- package/project/.sdk/tm/java/utility/TransformRequest.java +18 -3
- package/project/.sdk/tm/js/src/Context.js +7 -2
- package/project/.sdk/tm/js/src/feature/paging/PagingFeature.js +24 -6
- package/project/.sdk/tm/js/src/feature/test/TestFeature.js +7 -5
- package/project/.sdk/tm/js/src/utility/PrepareQueryUtility.js +1 -1
- package/project/.sdk/tm/js/test/feature/Corpus.test.js +4 -0
- 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/core/Context.kt +1 -1
- package/project/.sdk/tm/kotlin/feature/PagingFeature.kt +36 -4
- package/project/.sdk/tm/kotlin/feature/TestFeature.kt +19 -18
- package/project/.sdk/tm/kotlin/utility/Fetcher.kt +33 -24
- package/project/.sdk/tm/kotlin/utility/Prepare.kt +1 -1
- package/project/.sdk/tm/kotlin/utility/ResultTransform.kt +18 -3
- package/project/.sdk/tm/lua/core/context.lua +8 -1
- package/project/.sdk/tm/lua/core/control.lua +3 -0
- package/project/.sdk/tm/lua/feature/paging_feature.lua +44 -5
- package/project/.sdk/tm/lua/feature/test_feature.lua +32 -14
- package/project/.sdk/tm/lua/utility/prepare_query.lua +2 -1
- package/project/.sdk/tm/lua/utility/transform_request.lua +19 -3
- package/project/.sdk/tm/ocaml/sdk_features.ml +78 -25
- package/project/.sdk/tm/ocaml/sdk_runtime.ml +23 -8
- package/project/.sdk/tm/perl/core/context.pm +2 -1
- package/project/.sdk/tm/perl/feature/paging_feature.pm +31 -5
- package/project/.sdk/tm/perl/feature/test_feature.pm +52 -20
- package/project/.sdk/tm/perl/feature/timeout_feature.pm +17 -13
- package/project/.sdk/tm/perl/t/feature_corpus.t +14 -1
- package/project/.sdk/tm/perl/utility/fetcher.pm +15 -1
- package/project/.sdk/tm/perl/utility/prepare_query.pm +1 -0
- package/project/.sdk/tm/perl/utility/transform_request.pm +13 -3
- package/project/.sdk/tm/php/core/Context.php +5 -1
- package/project/.sdk/tm/php/core/Control.php +5 -0
- package/project/.sdk/tm/php/feature/PagingFeature.php +26 -5
- package/project/.sdk/tm/php/feature/TestFeature.php +27 -42
- package/project/.sdk/tm/php/test/FeatureCorpusTest.php +17 -1
- package/project/.sdk/tm/php/test/FeatureTest.php +44 -0
- package/project/.sdk/tm/php/utility/Fetcher.php +17 -3
- package/project/.sdk/tm/php/utility/PrepareQuery.php +1 -1
- package/project/.sdk/tm/php/utility/TransformRequest.php +15 -3
- package/project/.sdk/tm/py/pkg/core/context.py +2 -1
- package/project/.sdk/tm/py/pkg/feature/paging_feature.py +29 -4
- package/project/.sdk/tm/py/pkg/feature/test_feature.py +29 -12
- package/project/.sdk/tm/py/pkg/utility/fetcher.py +63 -65
- package/project/.sdk/tm/py/pkg/utility/prepare_query.py +2 -1
- package/project/.sdk/tm/py/pkg/utility/transform_request.py +11 -3
- package/project/.sdk/tm/py/test/test_feature.py +27 -0
- package/project/.sdk/tm/py/test/test_feature_corpus.py +11 -1
- package/project/.sdk/tm/rb/core/context.rb +1 -1
- package/project/.sdk/tm/rb/feature/paging_feature.rb +27 -5
- package/project/.sdk/tm/rb/feature/test_feature.rb +39 -11
- package/project/.sdk/tm/rb/test/feature_corpus_test.rb +12 -1
- package/project/.sdk/tm/rb/test/feature_test.rb +38 -0
- package/project/.sdk/tm/rb/utility/fetcher.rb +49 -3
- package/project/.sdk/tm/rb/utility/prepare_query.rb +1 -1
- package/project/.sdk/tm/rb/utility/transform_request.rb +10 -3
- package/project/.sdk/tm/rust/core/context.rs +2 -6
- package/project/.sdk/tm/rust/feature/paging.rs +44 -3
- package/project/.sdk/tm/rust/feature/secrets.rs +1 -1
- package/project/.sdk/tm/rust/feature/test.rs +74 -37
- package/project/.sdk/tm/rust/utility/fetcher.rs +41 -14
- package/project/.sdk/tm/rust/utility/prepare_query.rs +1 -1
- package/project/.sdk/tm/rust/utility/transform_request.rs +31 -5
- package/project/.sdk/tm/scala/core/Context.scala +2 -1
- package/project/.sdk/tm/scala/feature/PagingFeature.scala +41 -4
- package/project/.sdk/tm/scala/feature/TestFeature.scala +21 -18
- package/project/.sdk/tm/scala/utility/Fetcher.scala +34 -13
- package/project/.sdk/tm/scala/utility/Prepare.scala +1 -1
- package/project/.sdk/tm/scala/utility/Transform.scala +19 -3
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/core/Context.swift +1 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/PagingFeature.swift +31 -4
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/TestFeature.swift +22 -15
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Fetcher.swift +22 -3
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Prepare.swift +1 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/ResultUtil.swift +14 -3
- package/project/.sdk/tm/ts/src/Context.ts +7 -2
- package/project/.sdk/tm/ts/src/feature/paging/PagingFeature.ts +19 -3
- package/project/.sdk/tm/ts/src/feature/test/TestFeature.ts +3 -0
- package/project/.sdk/tm/ts/src/utility/PrepareQueryUtility.ts +1 -1
- package/project/.sdk/tm/ts/test/feature/Corpus.test.ts +1 -0
- 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/core/context.zig +1 -1
- package/project/.sdk/tm/zig/core/utility.zig +19 -5
- package/project/.sdk/tm/zig/feature/paging.zig +34 -4
- package/project/.sdk/tm/zig/feature/test.zig +65 -30
- package/project/sdkgen-package.json +1 -1
- package/src/action/doctor.ts +12 -9
- package/src/action/edition.ts +8 -0
- package/src/action/feature.ts +7 -1
- package/src/action/remove.ts +492 -0
- package/src/action/target.ts +8 -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
|
@@ -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?> {
|
|
@@ -156,20 +160,13 @@ class TestFeature : BaseFeature("test", "0.0.1", true) {
|
|
|
156
160
|
}
|
|
157
161
|
val args = buildArgs(ctx, op, updateMatch)
|
|
158
162
|
val found = Struct.select(entmap, args)
|
|
159
|
-
|
|
160
|
-
if (ent == null) {
|
|
161
|
-
for (e in entmap.values) {
|
|
162
|
-
if (e is MutableMap<*, *>) {
|
|
163
|
-
ent = e
|
|
164
|
-
break
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
163
|
+
val ent = Struct.getelem(found, 0, null)
|
|
168
164
|
if (ent == null) {
|
|
165
|
+
// update miss: 404, never another record
|
|
169
166
|
return respond(ctx, 404, null, extra("statusText", "Not found"))
|
|
170
167
|
}
|
|
171
168
|
if (ent is MutableMap<*, *>) {
|
|
172
|
-
(ent
|
|
169
|
+
Struct.merge(Struct.jt(ent, reqdata))
|
|
173
170
|
}
|
|
174
171
|
Struct.delprop(ent, "\$KEY")
|
|
175
172
|
val out = Struct.clone(ent)
|
|
@@ -316,10 +313,14 @@ class TestFeature : BaseFeature("test", "0.0.1", true) {
|
|
|
316
313
|
}
|
|
317
314
|
}
|
|
318
315
|
|
|
319
|
-
//
|
|
320
|
-
|
|
321
|
-
val
|
|
322
|
-
|
|
316
|
+
// Path AND query: a path-only read misses a query-addressed record
|
|
317
|
+
// (e.g. GET /result?trace_id=), which has no path param at all.
|
|
318
|
+
val reqdArgs = Struct.jt()
|
|
319
|
+
for (kind in listOf("params", "query")) {
|
|
320
|
+
val argsPath = Struct.getpath(point, listOf("args", kind))
|
|
321
|
+
reqdArgs.addAll(Struct.select(argsPath, Struct.jm("reqd", true)))
|
|
322
|
+
}
|
|
323
|
+
val reqd = Struct.transform(reqdArgs, Struct.jt("`\$EACH`", "", "`\$KEY.name`"))
|
|
323
324
|
|
|
324
325
|
val qand = Struct.jt()
|
|
325
326
|
val q = Struct.jm("`\$AND`", qand)
|
|
@@ -6,12 +6,44 @@ import java.net.URI
|
|
|
6
6
|
import java.net.http.HttpClient
|
|
7
7
|
import java.net.http.HttpRequest
|
|
8
8
|
import java.net.http.HttpResponse
|
|
9
|
+
import java.util.concurrent.ConcurrentHashMap
|
|
9
10
|
import java.util.function.BiFunction
|
|
10
11
|
import java.util.function.Supplier
|
|
11
12
|
|
|
12
13
|
import KOTLINPACKAGE.core.Context
|
|
13
14
|
import KOTLINPACKAGE.utility.struct.Struct
|
|
14
15
|
|
|
16
|
+
// Clients keyed by redirect policy and proxy. Each HttpClient owns a
|
|
17
|
+
// connection pool and a selector thread, so one per request reused
|
|
18
|
+
// nothing; one per key pools across calls.
|
|
19
|
+
private val clients = ConcurrentHashMap<String, HttpClient>()
|
|
20
|
+
|
|
21
|
+
private fun clientFor(fetchdef: MutableMap<String, Any?>): HttpClient {
|
|
22
|
+
// "manual" (set by the station feature's middleware under a hosts
|
|
23
|
+
// policy) returns a 3xx like any other response: an automatic follow
|
|
24
|
+
// would carry injected credentials to a host no policy approved.
|
|
25
|
+
val redirectPolicy =
|
|
26
|
+
if ("manual" == fetchdef["redirect"]) HttpClient.Redirect.NEVER
|
|
27
|
+
else HttpClient.Redirect.NORMAL
|
|
28
|
+
|
|
29
|
+
val praw = fetchdef["proxy"]
|
|
30
|
+
val proxy = if (praw is String) praw else ""
|
|
31
|
+
|
|
32
|
+
return clients.computeIfAbsent("$redirectPolicy|$proxy") {
|
|
33
|
+
val clientb = HttpClient.newBuilder().followRedirects(redirectPolicy)
|
|
34
|
+
if ("" != proxy) {
|
|
35
|
+
try {
|
|
36
|
+
val proxyUri = URI.create(proxy)
|
|
37
|
+
val port = if (proxyUri.port < 0) 80 else proxyUri.port
|
|
38
|
+
clientb.proxy(ProxySelector.of(InetSocketAddress(proxyUri.host, port)))
|
|
39
|
+
} catch (e: RuntimeException) {
|
|
40
|
+
// Unparseable proxy target: direct connection, as the go transport.
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
clientb.build()
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
15
47
|
@Suppress("UNCHECKED_CAST")
|
|
16
48
|
fun defaultHttpFetch(fullurl: String, fetchdef: MutableMap<String, Any?>): MutableMap<String, Any?> {
|
|
17
49
|
var method = if (fetchdef["method"] is String) fetchdef["method"] as String else ""
|
|
@@ -50,32 +82,9 @@ fun defaultHttpFetch(fullurl: String, fetchdef: MutableMap<String, Any?>): Mutab
|
|
|
50
82
|
reqb.setHeader("User-Agent", "Mozilla/5.0 (compatible; ProjectNameSDK/1.0)")
|
|
51
83
|
}
|
|
52
84
|
|
|
53
|
-
// Honour a redirect annotation on the fetch definition (set by the
|
|
54
|
-
// station feature's middleware under a hosts policy): "manual" returns
|
|
55
|
-
// a 3xx like any other response instead of following it — the ts
|
|
56
|
-
// donor's fetch honours the same key natively, and an automatic follow
|
|
57
|
-
// would carry injected credentials to a host no policy approved.
|
|
58
|
-
val redirectPolicy =
|
|
59
|
-
if ("manual" == fetchdef["redirect"]) HttpClient.Redirect.NEVER
|
|
60
|
-
else HttpClient.Redirect.NORMAL
|
|
61
|
-
|
|
62
|
-
// Honour a proxy annotation on the fetch definition (set by the proxy
|
|
63
|
-
// feature): route the request through a proxied HttpClient.
|
|
64
|
-
val clientb = HttpClient.newBuilder().followRedirects(redirectPolicy)
|
|
65
|
-
val proxy = fetchdef["proxy"]
|
|
66
|
-
if (proxy is String && "" != proxy) {
|
|
67
|
-
try {
|
|
68
|
-
val proxyUri = URI.create(proxy)
|
|
69
|
-
val port = if (proxyUri.port < 0) 80 else proxyUri.port
|
|
70
|
-
clientb.proxy(ProxySelector.of(InetSocketAddress(proxyUri.host, port)))
|
|
71
|
-
} catch (e: RuntimeException) {
|
|
72
|
-
// Unparseable proxy target: fall through to a direct connection.
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
85
|
val resp: HttpResponse<String>
|
|
77
86
|
try {
|
|
78
|
-
resp =
|
|
87
|
+
resp = clientFor(fetchdef).send(reqb.build(), HttpResponse.BodyHandlers.ofString())
|
|
79
88
|
} catch (e: Exception) {
|
|
80
89
|
throw RuntimeException("fetch: " + e.message, e)
|
|
81
90
|
}
|
|
@@ -194,7 +194,7 @@ fun prepareQuery(ctx: Context): MutableMap<String, Any?> {
|
|
|
194
194
|
for (item in Struct.items(reqmatch)) {
|
|
195
195
|
val key = if (item[0] is String) item[0] as String else ""
|
|
196
196
|
val v = item[1]
|
|
197
|
-
if (v != null && !containsStr(params, key)) {
|
|
197
|
+
if (v != null && "\$action" != key && !containsStr(params, key)) {
|
|
198
198
|
out[key] = v
|
|
199
199
|
}
|
|
200
200
|
}
|
|
@@ -58,21 +58,36 @@ fun resultHeaders(ctx: Context): KOTLINPACKAGE.core.Result {
|
|
|
58
58
|
return result!!
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
// `$action` selects the point (see makePoint); it is never an API field, so
|
|
62
|
+
// the body is a copy without it. The caller's map is left untouched.
|
|
63
|
+
private fun stripAction(reqdata: Any?): Any? {
|
|
64
|
+
if (reqdata !is Map<*, *> || !reqdata.containsKey("\$action")) {
|
|
65
|
+
return reqdata
|
|
66
|
+
}
|
|
67
|
+
val body = linkedMapOf<String, Any?>()
|
|
68
|
+
for ((k, v) in reqdata) {
|
|
69
|
+
if ("\$action" != k) {
|
|
70
|
+
body[k.toString()] = v
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return body
|
|
74
|
+
}
|
|
75
|
+
|
|
61
76
|
fun transformRequest(ctx: Context): Any? {
|
|
62
77
|
if (ctx.spec != null) {
|
|
63
78
|
ctx.spec!!.step = "reqform"
|
|
64
79
|
}
|
|
65
80
|
|
|
66
81
|
val transform = Helpers.toMapAny(Struct.getprop(ctx.point, "transform"))
|
|
67
|
-
?: return ctx.reqdata
|
|
82
|
+
?: return stripAction(ctx.reqdata)
|
|
68
83
|
|
|
69
84
|
val reqform = Struct.getprop(transform, "req", null)
|
|
70
|
-
?: return ctx.reqdata
|
|
85
|
+
?: return stripAction(ctx.reqdata)
|
|
71
86
|
|
|
72
87
|
val data = linkedMapOf<String, Any?>()
|
|
73
88
|
data["reqdata"] = ctx.reqdata
|
|
74
89
|
|
|
75
|
-
return Struct.transform(data, reqform)
|
|
90
|
+
return stripAction(Struct.transform(data, reqform))
|
|
76
91
|
}
|
|
77
92
|
|
|
78
93
|
fun transformResponse(ctx: Context): Any? {
|
|
@@ -49,7 +49,14 @@ function Context.new(ctxmap, basectx)
|
|
|
49
49
|
if type(ctrl_raw.explain) == "table" then
|
|
50
50
|
self.ctrl.explain = ctrl_raw.explain
|
|
51
51
|
end
|
|
52
|
-
|
|
52
|
+
if ctrl_raw.actor ~= nil then
|
|
53
|
+
self.ctrl.actor = ctrl_raw.actor
|
|
54
|
+
end
|
|
55
|
+
if type(ctrl_raw.paging) == "table" then
|
|
56
|
+
self.ctrl.paging = ctrl_raw.paging
|
|
57
|
+
end
|
|
58
|
+
elseif basectx ~= nil and basectx.ctrl ~= nil
|
|
59
|
+
and helpers.get_ctx_prop(ctxmap, "opname") == nil then
|
|
53
60
|
self.ctrl = basectx.ctrl
|
|
54
61
|
end
|
|
55
62
|
|
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
-- (PreResult) it reads the server's pagination signals — a
|
|
6
6
|
-- `Link: <...>; rel="next"` header, `X-Page`/`X-Next-Page`/
|
|
7
7
|
-- `X-Total-Count` headers, or `next`/`cursor`/`nextCursor`/`hasMore`
|
|
8
|
-
-- fields in the body — and records them on
|
|
9
|
-
--
|
|
8
|
+
-- fields in the body (snake_case forms too) — and records them on
|
|
9
|
+
-- `ctx.result.paging` and the caller's `ctrl.paging`. A per-call
|
|
10
|
+
-- `ctrl.paging` (cursor or page) wins over the option defaults,
|
|
10
11
|
-- so auto-iteration can advance the cursor/page and re-issue the list
|
|
11
12
|
-- call until `hasMore` is false. Parameter names (`pageParam`,
|
|
12
13
|
-- `limitParam`, `cursorParam`), `startPage` (default 1) and `limit` are
|
|
@@ -95,8 +96,14 @@ function PagingFeature:PreRequest(ctx)
|
|
|
95
96
|
if paging["cursor"] ~= nil then
|
|
96
97
|
spec.query[cursor_param] = paging["cursor"]
|
|
97
98
|
elseif spec.query[page_param] == nil then
|
|
98
|
-
|
|
99
|
-
|
|
99
|
+
-- A record written back by PreResult holds the page just fetched as
|
|
100
|
+
-- "page" and the one to fetch as "nextPage", so nextPage wins.
|
|
101
|
+
local page = paging["nextPage"]
|
|
102
|
+
if page == nil then
|
|
103
|
+
page = paging["page"]
|
|
104
|
+
end
|
|
105
|
+
if page ~= nil then
|
|
106
|
+
spec.query[page_param] = page
|
|
100
107
|
else
|
|
101
108
|
spec.query[page_param] = self.options["startPage"] or 1
|
|
102
109
|
end
|
|
@@ -218,17 +225,33 @@ function PagingFeature:PreResult(ctx)
|
|
|
218
225
|
end
|
|
219
226
|
end
|
|
220
227
|
|
|
221
|
-
-- Body-level
|
|
228
|
+
-- Body-level signals; snake_case forms are read first so camelCase wins.
|
|
222
229
|
if type(body) == "table" then
|
|
223
230
|
if body["next"] ~= nil and paging.next == nil then
|
|
224
231
|
paging.next = body["next"]
|
|
225
232
|
end
|
|
233
|
+
if body["next_cursor"] ~= nil then
|
|
234
|
+
paging.cursor = body["next_cursor"]
|
|
235
|
+
end
|
|
226
236
|
if body["cursor"] ~= nil then
|
|
227
237
|
paging.cursor = body["cursor"]
|
|
228
238
|
end
|
|
229
239
|
if body["nextCursor"] ~= nil then
|
|
230
240
|
paging.cursor = body["nextCursor"]
|
|
231
241
|
end
|
|
242
|
+
if paging.nextPage == nil then
|
|
243
|
+
local np = body["nextPage"]
|
|
244
|
+
if np == nil then
|
|
245
|
+
np = body["next_page"]
|
|
246
|
+
end
|
|
247
|
+
if type(np) == "number" or type(np) == "string" then
|
|
248
|
+
paging.nextPage = np
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
if type(body["has_more"]) == "boolean" then
|
|
252
|
+
paging.hasMore = body["has_more"]
|
|
253
|
+
explicit_more = true
|
|
254
|
+
end
|
|
232
255
|
if type(body["hasMore"]) == "boolean" then
|
|
233
256
|
paging.hasMore = body["hasMore"]
|
|
234
257
|
explicit_more = true
|
|
@@ -247,6 +270,22 @@ function PagingFeature:PreResult(ctx)
|
|
|
247
270
|
|
|
248
271
|
result.paging = paging
|
|
249
272
|
|
|
273
|
+
if ctx.ctrl ~= nil then
|
|
274
|
+
-- The Context shares the caller's paging table by reference, so refill
|
|
275
|
+
-- it in place; a fresh table on ctrl never reaches the caller.
|
|
276
|
+
if type(ctx.ctrl.paging) == "table" then
|
|
277
|
+
local shared = ctx.ctrl.paging
|
|
278
|
+
for k in pairs(shared) do
|
|
279
|
+
shared[k] = nil
|
|
280
|
+
end
|
|
281
|
+
for k, v in pairs(paging) do
|
|
282
|
+
shared[k] = v
|
|
283
|
+
end
|
|
284
|
+
else
|
|
285
|
+
ctx.ctrl.paging = paging
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
250
289
|
local client = self.client
|
|
251
290
|
client._paging = { last = paging }
|
|
252
291
|
end
|
|
@@ -167,21 +167,12 @@ function TestFeature:init(ctx, options)
|
|
|
167
167
|
local args = test_self:build_args(fctx, op, update_match)
|
|
168
168
|
local found = vs.select(entmap, args)
|
|
169
169
|
local ent = vs.getelem(found, 0)
|
|
170
|
-
if ent == nil and type(entmap) == "table" then
|
|
171
|
-
for _, e in pairs(entmap) do
|
|
172
|
-
if type(e) == "table" then ent = e; break end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
170
|
if ent == nil then
|
|
171
|
+
-- update miss: 404, never another record
|
|
176
172
|
return respond(404, nil, { statusText = "Not found" })
|
|
177
173
|
end
|
|
178
|
-
if type(ent) == "table" then
|
|
179
|
-
|
|
180
|
-
if reqdata ~= nil then
|
|
181
|
-
for k, v in pairs(reqdata) do
|
|
182
|
-
ent[k] = v
|
|
183
|
-
end
|
|
184
|
-
end
|
|
174
|
+
if type(ent) == "table" and type(fctx.reqdata) == "table" then
|
|
175
|
+
vs.merge({ ent, fctx.reqdata })
|
|
185
176
|
end
|
|
186
177
|
vs.delprop(ent, "$KEY")
|
|
187
178
|
local out = vs.clone(ent)
|
|
@@ -312,12 +303,39 @@ function TestFeature:make_netsim(net, inner)
|
|
|
312
303
|
end
|
|
313
304
|
|
|
314
305
|
|
|
306
|
+
local function point_terminal(p)
|
|
307
|
+
local parts = vs.getprop(p, "parts")
|
|
308
|
+
if type(parts) ~= "table" or #parts == 0 then return false end
|
|
309
|
+
local last = parts[#parts]
|
|
310
|
+
return type(last) == "string" and last:sub(1, 1) == "{"
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
local function point_depth(p)
|
|
314
|
+
local parts = vs.getprop(p, "parts")
|
|
315
|
+
return type(parts) == "table" and #parts or 0
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
-- The entity's own endpoint: a terminal `{param}` marks a record route, and
|
|
319
|
+
-- among equals the shallower path wins (the same rule as make_point).
|
|
320
|
+
local function pick_point(points)
|
|
321
|
+
if type(points) ~= "table" or #points == 0 then return nil end
|
|
322
|
+
local point = points[1]
|
|
323
|
+
for i = 2, #points do
|
|
324
|
+
local cand = points[i]
|
|
325
|
+
if point_terminal(cand) ~= point_terminal(point) then
|
|
326
|
+
if point_terminal(cand) then point = cand end
|
|
327
|
+
elseif point_depth(cand) < point_depth(point) then
|
|
328
|
+
point = cand
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
return point
|
|
332
|
+
end
|
|
333
|
+
|
|
315
334
|
function TestFeature:build_args(ctx, op, args)
|
|
316
335
|
local opname = op.name
|
|
317
336
|
|
|
318
|
-
-- Get last point from config.
|
|
319
337
|
local points = vs.getpath(ctx.config, "entity." .. ctx.entity:get_name() .. ".op." .. opname .. ".points")
|
|
320
|
-
local point =
|
|
338
|
+
local point = pick_point(points)
|
|
321
339
|
|
|
322
340
|
-- Path AND query: a path-only read misses a query-addressed record
|
|
323
341
|
-- (e.g. GET /result?trace_id=), which has no path param at all.
|
|
@@ -29,7 +29,8 @@ local function prepare_query_util(ctx)
|
|
|
29
29
|
for _, item in ipairs(reqmatch_items) do
|
|
30
30
|
local key = item[1]
|
|
31
31
|
local val = item[2]
|
|
32
|
-
if val ~= nil and type(key) == "string" and
|
|
32
|
+
if val ~= nil and type(key) == "string" and key ~= "$action"
|
|
33
|
+
and not contains_param(params, key) then
|
|
33
34
|
out[key] = val
|
|
34
35
|
end
|
|
35
36
|
end
|
|
@@ -3,6 +3,22 @@
|
|
|
3
3
|
local vs = require("utility.struct.struct")
|
|
4
4
|
local helpers = require("core.helpers")
|
|
5
5
|
|
|
6
|
+
-- `$action` selects the point (see make_point_util); it is never an API
|
|
7
|
+
-- field, so the body is a copy without it. The caller's table is left
|
|
8
|
+
-- untouched.
|
|
9
|
+
local function strip_action(reqdata)
|
|
10
|
+
if not vs.ismap(reqdata) or reqdata["$action"] == nil then
|
|
11
|
+
return reqdata
|
|
12
|
+
end
|
|
13
|
+
local body = {}
|
|
14
|
+
for k, v in pairs(reqdata) do
|
|
15
|
+
if k ~= "$action" then
|
|
16
|
+
body[k] = v
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
return body
|
|
20
|
+
end
|
|
21
|
+
|
|
6
22
|
local function transform_request_util(ctx)
|
|
7
23
|
local spec = ctx.spec
|
|
8
24
|
local point = ctx.point
|
|
@@ -13,19 +29,19 @@ local function transform_request_util(ctx)
|
|
|
13
29
|
|
|
14
30
|
local transform = helpers.to_map(vs.getprop(point, "transform"))
|
|
15
31
|
if transform == nil then
|
|
16
|
-
return ctx.reqdata
|
|
32
|
+
return strip_action(ctx.reqdata)
|
|
17
33
|
end
|
|
18
34
|
|
|
19
35
|
local reqform = vs.getprop(transform, "req")
|
|
20
36
|
if reqform == nil then
|
|
21
|
-
return ctx.reqdata
|
|
37
|
+
return strip_action(ctx.reqdata)
|
|
22
38
|
end
|
|
23
39
|
|
|
24
40
|
local reqdata = vs.transform({
|
|
25
41
|
reqdata = ctx.reqdata,
|
|
26
42
|
}, reqform)
|
|
27
43
|
|
|
28
|
-
return reqdata
|
|
44
|
+
return strip_action(reqdata)
|
|
29
45
|
end
|
|
30
46
|
|
|
31
47
|
return transform_request_util
|
|
@@ -1121,9 +1121,15 @@ let paging_feature () : feature =
|
|
|
1121
1121
|
| Noval | Null ->
|
|
1122
1122
|
(match getp q page_param with
|
|
1123
1123
|
| Noval ->
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1124
|
+
(* A record written back by PreResult holds the page just
|
|
1125
|
+
* fetched as `page` and the one to fetch as `nextPage`,
|
|
1126
|
+
* so nextPage wins. *)
|
|
1127
|
+
let page = (match getp paging "nextPage" with
|
|
1128
|
+
| Noval | Null ->
|
|
1129
|
+
(match getp paging "page" with
|
|
1130
|
+
| Noval | Null -> (match getp !options "startPage" with Num n -> Num n | _ -> Num 1.)
|
|
1131
|
+
| p -> p)
|
|
1132
|
+
| np -> np) in
|
|
1127
1133
|
setp q page_param page
|
|
1128
1134
|
| _ -> ())
|
|
1129
1135
|
| c -> setp q cursor_param c);
|
|
@@ -1176,11 +1182,20 @@ let paging_feature () : feature =
|
|
|
1176
1182
|
(match body with
|
|
1177
1183
|
| Map _ ->
|
|
1178
1184
|
(match getp body "next" with Noval | Null -> () | n -> if is_nullish (getp paging "next") then setp paging "next" n);
|
|
1185
|
+
(* Both spellings, camelCase last so it wins when a body
|
|
1186
|
+
* carries the two. *)
|
|
1187
|
+
(match getp body "next_cursor" with Noval | Null -> () | c -> setp paging "cursor" c);
|
|
1179
1188
|
(match getp body "cursor" with Noval | Null -> () | c -> setp paging "cursor" c);
|
|
1180
1189
|
(match getp body "nextCursor" with Noval | Null -> () | c -> setp paging "cursor" c);
|
|
1181
|
-
(
|
|
1182
|
-
|
|
1183
|
-
|
|
1190
|
+
if is_nullish (getp paging "nextPage") then begin
|
|
1191
|
+
let np = (match getp body "nextPage" with
|
|
1192
|
+
| Noval | Null -> getp body "next_page"
|
|
1193
|
+
| v -> v) in
|
|
1194
|
+
(match np with Num _ | Str _ -> setp paging "nextPage" np | _ -> ())
|
|
1195
|
+
end;
|
|
1196
|
+
List.iter (fun k -> match getp body k with
|
|
1197
|
+
| Bool b -> setp paging "hasMore" (Bool b); explicit_more := true
|
|
1198
|
+
| _ -> ()) ["has_more"; "hasMore"]
|
|
1184
1199
|
| _ -> ());
|
|
1185
1200
|
(* Cursor presence only INFERS another page. When the server
|
|
1186
1201
|
* stated the answer outright — relay's `hasNextPage: false`, or
|
|
@@ -1196,6 +1211,16 @@ let paging_feature () : feature =
|
|
|
1196
1211
|
setp paging "hasMore" (Bool hm)
|
|
1197
1212
|
end;
|
|
1198
1213
|
result.rt_paging <- paging;
|
|
1214
|
+
(* The record reached the caller through ctrl in every other typed
|
|
1215
|
+
* port and through nothing here, so a caller who asked for paging
|
|
1216
|
+
* got the pages and never the signals to continue. *)
|
|
1217
|
+
(match ctx.c_ctrl.ctrl_paging with
|
|
1218
|
+
| Map _ as held ->
|
|
1219
|
+
(* The caller holds this map: refill it in place. Every key of
|
|
1220
|
+
* the record is written, so no key of an earlier page lives on. *)
|
|
1221
|
+
List.iter (fun k -> setp held k (getp paging k))
|
|
1222
|
+
["page"; "totalCount"; "nextPage"; "next"; "cursor"; "hasMore"]
|
|
1223
|
+
| _ -> ctx.c_ctrl.ctrl_paging <- paging);
|
|
1199
1224
|
track_set (cc ctx) "paging" (jo [("last", paging)]))
|
|
1200
1225
|
| _ -> ());
|
|
1201
1226
|
f
|
|
@@ -1394,33 +1419,57 @@ let test_feature () : feature =
|
|
|
1394
1419
|
match getp (getp ctx.c_point "transform") "res" with
|
|
1395
1420
|
| Str spec ->
|
|
1396
1421
|
let n = String.length spec in
|
|
1397
|
-
(*
|
|
1398
|
-
|
|
1422
|
+
(* Rebuild whatever nesting the transform unwraps. Multi-segment on
|
|
1423
|
+
purpose: GraphQL ops unwrap `body.data.<field>`. *)
|
|
1399
1424
|
if n > 7 && String.sub spec 0 6 = "`body." && spec.[n - 1] = '`' then
|
|
1400
1425
|
let inner = String.sub spec 6 (n - 7) in
|
|
1401
|
-
if String.length inner = 0
|
|
1402
|
-
else
|
|
1426
|
+
if String.length inner = 0 then data
|
|
1427
|
+
else
|
|
1428
|
+
List.fold_left (fun out seg -> jo [(seg, out)]) data
|
|
1429
|
+
(List.rev (String.split_on_char '.' inner))
|
|
1403
1430
|
else data
|
|
1404
1431
|
| _ -> data in
|
|
1405
1432
|
let respond ctx status data extra =
|
|
1406
1433
|
let out = jo [("status", vint_of status); ("statusText", Str "OK"); ("json", json_thunk (envelope ctx data)); ("body", Str "not-used")] in
|
|
1407
1434
|
(match extra with Some (Map _ as e) -> List.iter (fun k -> setp out k (getp e k)) (keysof e) | _ -> ());
|
|
1408
1435
|
(out, None) in
|
|
1436
|
+
let point_terminal p =
|
|
1437
|
+
match getp p "parts" with
|
|
1438
|
+
| List r -> (match List.rev !r with Str s :: _ -> String.length s > 0 && s.[0] = '{' | _ -> false)
|
|
1439
|
+
| _ -> false in
|
|
1440
|
+
let point_depth p = match getp p "parts" with List r -> List.length !r | _ -> 0 in
|
|
1441
|
+
(* The entity's own endpoint: a terminal `{param}` marks a record route, and
|
|
1442
|
+
among equals the shallower path wins (the same rule as make_point). *)
|
|
1443
|
+
let pick_point points =
|
|
1444
|
+
match points with
|
|
1445
|
+
| List r ->
|
|
1446
|
+
(match !r with
|
|
1447
|
+
| [] -> Noval
|
|
1448
|
+
| first :: rest ->
|
|
1449
|
+
List.fold_left (fun point cand ->
|
|
1450
|
+
if point_terminal cand <> point_terminal point then (if point_terminal cand then cand else point)
|
|
1451
|
+
else if point_depth cand < point_depth point then cand
|
|
1452
|
+
else point) first rest)
|
|
1453
|
+
| _ -> Noval in
|
|
1454
|
+
let reqd_names point kind =
|
|
1455
|
+
let reqd_args = select (getpath_s point ("args." ^ kind)) (jo [("reqd", Bool true)]) in
|
|
1456
|
+
transform reqd_args (ja [Str "`$EACH`"; Str ""; Str "`$KEY.name`"]) in
|
|
1409
1457
|
let build_args ctx (op : operation) args =
|
|
1410
1458
|
let opname = op.op_name in
|
|
1411
1459
|
let entname = match ctx.c_entity with Some e -> e.e_name | None -> "_" in
|
|
1412
1460
|
let points = getpath_s ctx.c_config ("entity." ^ entname ^ ".op." ^ opname ^ ".points") in
|
|
1413
|
-
let point =
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
let
|
|
1461
|
+
let point = pick_point points in
|
|
1462
|
+
(* Path AND query: a path-only read misses a query-addressed record
|
|
1463
|
+
(e.g. GET /result?trace_id=), which has no path param at all. *)
|
|
1464
|
+
let reqd_params = reqd_names point "params" in
|
|
1465
|
+
let reqd_query = reqd_names point "query" in
|
|
1417
1466
|
let qand = ref [] in
|
|
1418
1467
|
(match args with
|
|
1419
1468
|
| Map _ ->
|
|
1420
1469
|
List.iter (fun key ->
|
|
1421
1470
|
let is_id = key = "id" in
|
|
1422
|
-
let
|
|
1423
|
-
|
|
1471
|
+
let is_reqd = not (isempty (select reqd_params (Str key)))
|
|
1472
|
+
|| not (isempty (select reqd_query (Str key))) in
|
|
1424
1473
|
if is_id || is_reqd then begin
|
|
1425
1474
|
let v = (cu ctx).u_param ctx (Str key) in
|
|
1426
1475
|
let ka = (match op.op_alias with Map _ -> (match getp op.op_alias key with Str s -> Some s | _ -> None) | _ -> None) in
|
|
@@ -1461,18 +1510,22 @@ let test_feature () : feature =
|
|
|
1461
1510
|
end
|
|
1462
1511
|
| "update" ->
|
|
1463
1512
|
let update_match = empty_map () in
|
|
1464
|
-
(match fctx.c_reqdata with
|
|
1513
|
+
(match fctx.c_reqdata with
|
|
1514
|
+
| Map _ ->
|
|
1515
|
+
(match getp fctx.c_reqdata "id" with Noval -> () | v -> setp update_match "id" v);
|
|
1516
|
+
(match getp op.op_alias "id" with
|
|
1517
|
+
| Str alias_id -> (match getp fctx.c_reqdata alias_id with Noval -> () | v -> setp update_match alias_id v)
|
|
1518
|
+
| _ -> ())
|
|
1519
|
+
| _ -> ());
|
|
1465
1520
|
let update_match = if size update_match > 0 then update_match else resolve_match fctx (empty_map ()) in
|
|
1466
1521
|
let args = build_args fctx op update_match in
|
|
1467
|
-
let ent =
|
|
1468
|
-
(
|
|
1469
|
-
|
|
1470
|
-
| _ -> ());
|
|
1471
|
-
if is_nullish !ent then respond fctx 404 Noval (Some (jo [("statusText", Str "Not found")]))
|
|
1522
|
+
let ent = getelem (select entmap args) (Num 0.0) in
|
|
1523
|
+
(* update miss: 404, never another record *)
|
|
1524
|
+
if is_nullish ent then respond fctx 404 Noval (Some (jo [("statusText", Str "Not found")]))
|
|
1472
1525
|
else begin
|
|
1473
|
-
(match
|
|
1474
|
-
ignore (delprop
|
|
1475
|
-
respond fctx 200 (clone
|
|
1526
|
+
(match ent, fctx.c_reqdata with Map _, Map _ -> ignore (merge (ja [ent; fctx.c_reqdata])) | _ -> ());
|
|
1527
|
+
ignore (delprop ent (Str "$KEY"));
|
|
1528
|
+
respond fctx 200 (clone ent) None
|
|
1476
1529
|
end
|
|
1477
1530
|
| "remove" ->
|
|
1478
1531
|
let args = build_args fctx op (resolve_match fctx fctx.c_reqmatch) in
|
|
@@ -189,7 +189,9 @@ let make_context_impl (cs : ctxspec) (basectx : ctx option) : ctx =
|
|
|
189
189
|
(match getp cr "actor" with Noval -> () | a -> c.ctrl_actor <- a);
|
|
190
190
|
(match getp cr "paging" with Map _ as m -> c.ctrl_paging <- m | _ -> ());
|
|
191
191
|
c
|
|
192
|
-
| _ -> (match basectx with
|
|
192
|
+
| _ -> (match basectx with
|
|
193
|
+
| Some b when cs.cs_opname = None -> b.c_ctrl
|
|
194
|
+
| _ -> new_control ())
|
|
193
195
|
in
|
|
194
196
|
let meta =
|
|
195
197
|
match cs.cs_meta with Some (Map _ as m) -> m
|
|
@@ -413,7 +415,7 @@ let prepare_query_util (ctx : ctx) : value =
|
|
|
413
415
|
let out = empty_map () in
|
|
414
416
|
List.iter (fun k ->
|
|
415
417
|
let v = getp reqmatch k in
|
|
416
|
-
if not (is_noval v) && not (contains_param k) then setp out k v)
|
|
418
|
+
if not (is_noval v) && k <> "$action" && not (contains_param k) then setp out k v)
|
|
417
419
|
(keysof reqmatch);
|
|
418
420
|
out
|
|
419
421
|
|
|
@@ -555,14 +557,27 @@ let prepare_auth_util = Sdk_prepare_auth.prepare_auth_util
|
|
|
555
557
|
|
|
556
558
|
(* ----- transforms / result helpers ----- *)
|
|
557
559
|
|
|
560
|
+
(* `$action` selects the point (see make_point_util); it is never an API
|
|
561
|
+
field, so the body is a copy without it. The caller's map is left
|
|
562
|
+
untouched. *)
|
|
563
|
+
let strip_action (reqdata : value) : value =
|
|
564
|
+
match reqdata with
|
|
565
|
+
| Map _ when List.mem "$action" (keysof reqdata) ->
|
|
566
|
+
let body = empty_map () in
|
|
567
|
+
List.iter (fun k -> if k <> "$action" then setp body k (getp reqdata k))
|
|
568
|
+
(keysof reqdata);
|
|
569
|
+
body
|
|
570
|
+
| _ -> reqdata
|
|
571
|
+
|
|
558
572
|
let transform_request_util (ctx : ctx) : value =
|
|
559
573
|
(match ctx.c_spec with Some s -> s.sp_step <- "reqform" | None -> ());
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
574
|
+
strip_action
|
|
575
|
+
(match to_map (getp ctx.c_point "transform") with
|
|
576
|
+
| Map _ as tr ->
|
|
577
|
+
(match getp tr "req" with
|
|
578
|
+
| Noval -> ctx.c_reqdata
|
|
579
|
+
| reqform -> transform (jo [("reqdata", ctx.c_reqdata)]) reqform)
|
|
580
|
+
| _ -> ctx.c_reqdata)
|
|
566
581
|
|
|
567
582
|
let transform_response_util (ctx : ctx) : value =
|
|
568
583
|
(match ctx.c_spec with Some s -> s.sp_step <- "resform" | None -> ());
|
|
@@ -45,7 +45,8 @@ sub new {
|
|
|
45
45
|
$self->{ctrl}{actor} = $ctrl_raw->{actor} if exists $ctrl_raw->{actor};
|
|
46
46
|
$self->{ctrl}{paging} = $ctrl_raw->{paging} if Voxgig::Struct::ismap($ctrl_raw->{paging});
|
|
47
47
|
}
|
|
48
|
-
elsif ($basectx && $basectx->{ctrl}
|
|
48
|
+
elsif ($basectx && $basectx->{ctrl}
|
|
49
|
+
&& !defined ProjectNameHelpers::get_ctx_prop($ctxmap, 'opname')) {
|
|
49
50
|
$self->{ctrl} = $basectx->{ctrl};
|
|
50
51
|
}
|
|
51
52
|
|