@voxgig/sdkgen 2.0.1 → 3.0.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 +22 -2
- package/dist/action/doctor.d.ts +14 -0
- package/dist/action/doctor.js +296 -0
- package/dist/action/doctor.js.map +1 -0
- package/dist/action/feature.js +48 -9
- package/dist/action/feature.js.map +1 -1
- package/dist/action/target.d.ts +6 -1
- package/dist/action/target.js +134 -22
- package/dist/action/target.js.map +1 -1
- package/dist/cmp/Entity.js +5 -0
- package/dist/cmp/Entity.js.map +1 -1
- package/dist/cmp/Feature.js +2 -1
- package/dist/cmp/Feature.js.map +1 -1
- package/dist/cmp/Main.js +5 -1
- package/dist/cmp/Main.js.map +1 -1
- package/dist/cmp/ReadmeExplanation.js +1 -1
- package/dist/cmp/ReadmeExplanation.js.map +1 -1
- package/dist/cmp/ReadmeTop.js +16 -6
- package/dist/cmp/ReadmeTop.js.map +1 -1
- package/dist/cmp/Registered.d.ts +7 -0
- package/dist/cmp/Registered.js +70 -0
- package/dist/cmp/Registered.js.map +1 -0
- package/dist/cmp/Test.js +3 -1
- package/dist/cmp/Test.js.map +1 -1
- package/dist/helpers/dryrun.d.ts +10 -0
- package/dist/helpers/dryrun.js +35 -0
- package/dist/helpers/dryrun.js.map +1 -0
- package/dist/helpers/featureSource.d.ts +13 -0
- package/dist/helpers/featureSource.js +156 -0
- package/dist/helpers/featureSource.js.map +1 -0
- package/dist/helpers/naming.d.ts +9 -1
- package/dist/helpers/naming.js +66 -2
- package/dist/helpers/naming.js.map +1 -1
- package/dist/helpers/opExample.js +23 -3
- package/dist/helpers/opExample.js.map +1 -1
- package/dist/helpers/opShape.d.ts +11 -1
- package/dist/helpers/opShape.js +51 -0
- package/dist/helpers/opShape.js.map +1 -1
- package/dist/helpers/packageMeta.d.ts +8 -1
- package/dist/helpers/packageMeta.js +141 -10
- package/dist/helpers/packageMeta.js.map +1 -1
- package/dist/helpers/stdrep.d.ts +3 -0
- package/dist/helpers/stdrep.js +47 -0
- package/dist/helpers/stdrep.js.map +1 -0
- package/dist/helpers/testPolicy.d.ts +2 -0
- package/dist/helpers/testPolicy.js +46 -0
- package/dist/helpers/testPolicy.js.map +1 -0
- package/dist/sdkgen.d.ts +15 -6
- package/dist/sdkgen.js +45 -4
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/model/sdkgen.aontu +125 -0
- package/package.json +8 -5
- package/project/.sdk/model/target/c.aontu +28 -3
- package/project/.sdk/model/target/clojure.aontu +24 -3
- package/project/.sdk/model/target/cpp.aontu +25 -3
- package/project/.sdk/model/target/csharp.aontu +25 -3
- package/project/.sdk/model/target/dart.aontu +15 -3
- package/project/.sdk/model/target/elixir.aontu +15 -3
- package/project/.sdk/model/target/go-cli.aontu +17 -1
- package/project/.sdk/model/target/go-mcp.aontu +17 -1
- package/project/.sdk/model/target/go.aontu +14 -4
- package/project/.sdk/model/target/haskell.aontu +24 -3
- package/project/.sdk/model/target/java.aontu +26 -3
- package/project/.sdk/model/target/js.aontu +15 -3
- package/project/.sdk/model/target/kotlin.aontu +26 -3
- package/project/.sdk/model/target/lean.aontu +25 -3
- package/project/.sdk/model/target/lua.aontu +15 -3
- package/project/.sdk/model/target/ocaml.aontu +24 -3
- package/project/.sdk/model/target/perl.aontu +15 -3
- package/project/.sdk/model/target/php.aontu +15 -3
- package/project/.sdk/model/target/py-data.aontu +16 -3
- package/project/.sdk/model/target/py.aontu +15 -3
- package/project/.sdk/model/target/rb.aontu +15 -3
- package/project/.sdk/model/target/rust.aontu +25 -3
- package/project/.sdk/model/target/scala.aontu +25 -3
- package/project/.sdk/model/target/swift.aontu +25 -3
- package/project/.sdk/model/target/ts.aontu +15 -3
- package/project/.sdk/model/target/zig.aontu +26 -3
- package/project/.sdk/src/cmp/c/Config_c.ts +10 -11
- package/project/.sdk/src/cmp/c/Entity_c.ts +5 -1
- package/project/.sdk/src/cmp/c/fragment/Entity.fragment.c +23 -5
- package/project/.sdk/src/cmp/c/fragment/EntityCreateOp.fragment.c +9 -2
- package/project/.sdk/src/cmp/c/fragment/EntityListOp.fragment.c +19 -2
- package/project/.sdk/src/cmp/c/fragment/EntityLoadOp.fragment.c +9 -2
- package/project/.sdk/src/cmp/c/fragment/EntityRemoveOp.fragment.c +12 -2
- package/project/.sdk/src/cmp/c/fragment/EntityUpdateOp.fragment.c +9 -2
- package/project/.sdk/src/cmp/c/fragment/Main.fragment.c +1 -0
- package/project/.sdk/src/cmp/clojure/TestEntity_clojure.ts +6 -3
- package/project/.sdk/src/cmp/clojure/fragment/Entity.fragment.clj +18 -1
- package/project/.sdk/src/cmp/clojure/fragment/EntityCreateOp.fragment.clj +2 -2
- package/project/.sdk/src/cmp/clojure/fragment/EntityLoadOp.fragment.clj +2 -2
- package/project/.sdk/src/cmp/clojure/fragment/EntityRemoveOp.fragment.clj +12 -8
- package/project/.sdk/src/cmp/clojure/fragment/EntityUpdateOp.fragment.clj +2 -2
- package/project/.sdk/src/cmp/cpp/Entity_cpp.ts +5 -1
- package/project/.sdk/src/cmp/cpp/TestEntity_cpp.ts +24 -11
- package/project/.sdk/src/cmp/cpp/fragment/EntityCreateOp.fragment.cpp +8 -2
- package/project/.sdk/src/cmp/cpp/fragment/EntityListOp.fragment.cpp +18 -2
- package/project/.sdk/src/cmp/cpp/fragment/EntityLoadOp.fragment.cpp +8 -2
- package/project/.sdk/src/cmp/cpp/fragment/EntityRemoveOp.fragment.cpp +11 -2
- package/project/.sdk/src/cmp/cpp/fragment/EntityUpdateOp.fragment.cpp +8 -2
- package/project/.sdk/src/cmp/csharp/Package_csharp.ts +2 -1
- package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +3 -3
- package/project/.sdk/src/cmp/csharp/TestEntity_csharp.ts +6 -6
- package/project/.sdk/src/cmp/csharp/fragment/EntityBase.fragment.cs +38 -1
- package/project/.sdk/src/cmp/csharp/fragment/Main.fragment.cs +42 -33
- package/project/.sdk/src/cmp/dart/Config_dart.ts +6 -0
- package/project/.sdk/src/cmp/dart/Package_dart.ts +2 -1
- package/project/.sdk/src/cmp/dart/ReadmeEntity_dart.ts +13 -2
- package/project/.sdk/src/cmp/dart/ReadmeHowto_dart.ts +2 -1
- package/project/.sdk/src/cmp/dart/ReadmeInstall_dart.ts +3 -3
- package/project/.sdk/src/cmp/dart/ReadmeModel_dart.ts +1 -1
- package/project/.sdk/src/cmp/dart/ReadmeQuick_dart.ts +17 -6
- package/project/.sdk/src/cmp/dart/ReadmeRef_dart.ts +13 -2
- package/project/.sdk/src/cmp/dart/ReadmeTopQuick_dart.ts +13 -2
- package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +3 -3
- package/project/.sdk/src/cmp/dart/TestEntity_dart.ts +8 -8
- package/project/.sdk/src/cmp/dart/fragment/EntityBase.fragment.dart +18 -1
- package/project/.sdk/src/cmp/dart/fragment/EntityCreateOp.fragment.dart +9 -1
- package/project/.sdk/src/cmp/dart/fragment/EntityLoadOp.fragment.dart +9 -1
- package/project/.sdk/src/cmp/dart/fragment/EntityRemoveOp.fragment.dart +15 -1
- package/project/.sdk/src/cmp/dart/fragment/EntityUpdateOp.fragment.dart +9 -1
- package/project/.sdk/src/cmp/dart/fragment/SdkError.fragment.dart +8 -0
- package/project/.sdk/src/cmp/elixir/Package_elixir.ts +3 -1
- package/project/.sdk/src/cmp/elixir/ReadmeInstall_elixir.ts +2 -2
- package/project/.sdk/src/cmp/elixir/ReadmeTopQuick_elixir.ts +7 -4
- package/project/.sdk/src/cmp/elixir/TestEntity_elixir.ts +11 -2
- package/project/.sdk/src/cmp/elixir/fragment/EntityCreateOp.fragment.ex +2 -1
- package/project/.sdk/src/cmp/elixir/fragment/EntityListOp.fragment.ex +1 -0
- package/project/.sdk/src/cmp/elixir/fragment/EntityLoadOp.fragment.ex +2 -1
- package/project/.sdk/src/cmp/elixir/fragment/EntityRemoveOp.fragment.ex +4 -1
- package/project/.sdk/src/cmp/elixir/fragment/EntityUpdateOp.fragment.ex +2 -1
- package/project/.sdk/src/cmp/go/EntityTypes_go.ts +38 -8
- package/project/.sdk/src/cmp/go/Entity_go.ts +2 -2
- package/project/.sdk/src/cmp/go/Main_go.ts +4 -5
- package/project/.sdk/src/cmp/go/Package_go.ts +8 -5
- package/project/.sdk/src/cmp/go/ReadmeExplanation_go.ts +2 -2
- package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +2 -2
- package/project/.sdk/src/cmp/go/ReadmeInstall_go.ts +4 -2
- package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +2 -2
- package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +2 -2
- package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +2 -2
- package/project/.sdk/src/cmp/go/ReadmeTopTest_go.ts +2 -2
- package/project/.sdk/src/cmp/go/TestDirect_go.ts +21 -15
- package/project/.sdk/src/cmp/go/TestEntity_go.ts +9 -9
- package/project/.sdk/src/cmp/go/Test_go.ts +2 -2
- package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +42 -1
- package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +4 -4
- package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +4 -4
- package/project/.sdk/src/cmp/haskell/Package_haskell.ts +2 -1
- package/project/.sdk/src/cmp/haskell/ReadmeEntity_haskell.ts +10 -5
- package/project/.sdk/src/cmp/haskell/ReadmeModel_haskell.ts +10 -8
- package/project/.sdk/src/cmp/haskell/ReadmeQuick_haskell.ts +14 -10
- package/project/.sdk/src/cmp/haskell/ReadmeRef_haskell.ts +21 -18
- package/project/.sdk/src/cmp/haskell/ReadmeTopQuick_haskell.ts +4 -4
- package/project/.sdk/src/cmp/haskell/Test_haskell.ts +23 -11
- package/project/.sdk/src/cmp/java/Package_java.ts +2 -1
- package/project/.sdk/src/cmp/java/ReadmeHowto_java.ts +2 -1
- package/project/.sdk/src/cmp/java/ReadmeInstall_java.ts +2 -2
- package/project/.sdk/src/cmp/java/ReadmeModel_java.ts +1 -1
- package/project/.sdk/src/cmp/java/ReadmeQuick_java.ts +3 -3
- package/project/.sdk/src/cmp/java/TestDirect_java.ts +3 -3
- package/project/.sdk/src/cmp/java/TestEntity_java.ts +6 -6
- package/project/.sdk/src/cmp/java/fragment/EntityBase.fragment.java +34 -1
- package/project/.sdk/src/cmp/java/fragment/SdkError.fragment.java +12 -0
- package/project/.sdk/src/cmp/js/Main_js.ts +4 -1
- package/project/.sdk/src/cmp/js/Package_js.ts +7 -1
- package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +13 -2
- package/project/.sdk/src/cmp/js/ReadmeHowto_js.ts +2 -1
- package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +13 -2
- package/project/.sdk/src/cmp/js/ReadmeTopQuick_js.ts +13 -2
- package/project/.sdk/src/cmp/js/ReadmeTopTest_js.ts +2 -1
- package/project/.sdk/src/cmp/js/TestDirect_js.ts +3 -3
- package/project/.sdk/src/cmp/js/TestEntity_js.ts +8 -8
- package/project/.sdk/src/cmp/js/fragment/EntityBase.fragment.js +22 -1
- package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +9 -1
- package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +9 -1
- package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +15 -1
- package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +9 -1
- package/project/.sdk/src/cmp/js/fragment/SdkError.fragment.js +13 -0
- package/project/.sdk/src/cmp/kotlin/Package_kotlin.ts +2 -1
- package/project/.sdk/src/cmp/kotlin/ReadmeHowto_kotlin.ts +2 -1
- package/project/.sdk/src/cmp/kotlin/ReadmeInstall_kotlin.ts +2 -2
- package/project/.sdk/src/cmp/kotlin/ReadmeModel_kotlin.ts +1 -1
- package/project/.sdk/src/cmp/kotlin/ReadmeQuick_kotlin.ts +3 -3
- package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +3 -3
- package/project/.sdk/src/cmp/kotlin/TestEntity_kotlin.ts +6 -6
- package/project/.sdk/src/cmp/kotlin/fragment/EntityBase.fragment.kt +32 -1
- package/project/.sdk/src/cmp/lean/Package_lean.ts +3 -1
- package/project/.sdk/src/cmp/lean/Test_lean.ts +75 -21
- package/project/.sdk/src/cmp/lua/MainEntity_lua.ts +9 -4
- package/project/.sdk/src/cmp/lua/Package_lua.ts +4 -3
- package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +11 -3
- package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +1 -1
- package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +3 -3
- package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +9 -9
- package/project/.sdk/src/cmp/lua/fragment/Entity.fragment.lua +37 -1
- package/project/.sdk/src/cmp/lua/fragment/SdkError.fragment.lua +12 -0
- package/project/.sdk/src/cmp/ocaml/EntityOperation_ocaml.ts +30 -3
- package/project/.sdk/src/cmp/ocaml/Entity_ocaml.ts +11 -5
- package/project/.sdk/src/cmp/ocaml/Package_ocaml.ts +3 -1
- package/project/.sdk/src/cmp/ocaml/ReadmeEntity_ocaml.ts +10 -5
- package/project/.sdk/src/cmp/ocaml/ReadmeHowto_ocaml.ts +6 -2
- package/project/.sdk/src/cmp/ocaml/ReadmeModel_ocaml.ts +10 -8
- package/project/.sdk/src/cmp/ocaml/ReadmeQuick_ocaml.ts +14 -13
- package/project/.sdk/src/cmp/ocaml/ReadmeRef_ocaml.ts +20 -18
- package/project/.sdk/src/cmp/ocaml/ReadmeTopQuick_ocaml.ts +4 -4
- package/project/.sdk/src/cmp/ocaml/ReadmeTopTest_ocaml.ts +8 -2
- package/project/.sdk/src/cmp/ocaml/TestEntity_ocaml.ts +8 -5
- package/project/.sdk/src/cmp/perl/ReadmeHowto_perl.ts +2 -1
- package/project/.sdk/src/cmp/perl/ReadmeModel_perl.ts +1 -1
- package/project/.sdk/src/cmp/perl/ReadmeQuick_perl.ts +3 -3
- package/project/.sdk/src/cmp/perl/ReadmeTopQuick_perl.ts +1 -1
- package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +3 -3
- package/project/.sdk/src/cmp/perl/TestEntity_perl.ts +6 -6
- package/project/.sdk/src/cmp/perl/fragment/Entity.fragment.pm +36 -1
- package/project/.sdk/src/cmp/php/MainEntity_php.ts +21 -16
- package/project/.sdk/src/cmp/php/Package_php.ts +2 -2
- package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +6 -6
- package/project/.sdk/src/cmp/php/ReadmeHowto_php.ts +4 -3
- package/project/.sdk/src/cmp/php/ReadmeIntro_php.ts +2 -2
- package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +1 -1
- package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +12 -12
- package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +6 -6
- package/project/.sdk/src/cmp/php/ReadmeTopQuick_php.ts +4 -4
- package/project/.sdk/src/cmp/php/ReadmeTopTest_php.ts +2 -2
- package/project/.sdk/src/cmp/php/TestDirect_php.ts +3 -3
- package/project/.sdk/src/cmp/php/TestEntity_php.ts +17 -15
- package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +20 -1
- package/project/.sdk/src/cmp/php/fragment/SdkError.fragment.php +11 -0
- package/project/.sdk/src/cmp/py/Package_py.ts +4 -3
- package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +13 -2
- package/project/.sdk/src/cmp/py/ReadmeHowto_py.ts +2 -1
- package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +1 -1
- package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +17 -6
- package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +14 -3
- package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +13 -2
- package/project/.sdk/src/cmp/py/TestDirect_py.ts +3 -3
- package/project/.sdk/src/cmp/py/TestEntity_py.ts +9 -9
- package/project/.sdk/src/cmp/py/Test_py.ts +4 -1
- package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +29 -1
- package/project/.sdk/src/cmp/py/fragment/SdkError.fragment.py +11 -0
- package/project/.sdk/src/cmp/py-data/Main_py-data.ts +2 -1
- package/project/.sdk/src/cmp/rb/Package_rb.ts +4 -3
- package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +1 -1
- package/project/.sdk/src/cmp/rb/ReadmeHowto_rb.ts +2 -1
- package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +5 -5
- package/project/.sdk/src/cmp/rb/ReadmeTopQuick_rb.ts +1 -1
- package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +3 -3
- package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +9 -9
- package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +31 -1
- package/project/.sdk/src/cmp/rb/fragment/SdkError.fragment.rb +10 -1
- package/project/.sdk/src/cmp/rust/Entity_rust.ts +5 -1
- package/project/.sdk/src/cmp/rust/Main_rust.ts +21 -0
- package/project/.sdk/src/cmp/rust/Package_rust.ts +2 -1
- package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +3 -3
- package/project/.sdk/src/cmp/rust/TestEntity_rust.ts +12 -12
- package/project/.sdk/src/cmp/rust/fragment/Entity.fragment.rs +18 -0
- package/project/.sdk/src/cmp/rust/fragment/EntityCreateOp.fragment.rs +8 -2
- package/project/.sdk/src/cmp/rust/fragment/EntityListOp.fragment.rs +20 -3
- package/project/.sdk/src/cmp/rust/fragment/EntityLoadOp.fragment.rs +8 -2
- package/project/.sdk/src/cmp/rust/fragment/EntityRemoveOp.fragment.rs +10 -2
- package/project/.sdk/src/cmp/rust/fragment/EntityUpdateOp.fragment.rs +8 -2
- package/project/.sdk/src/cmp/rust/fragment/SdkError.fragment.rs +10 -0
- package/project/.sdk/src/cmp/scala/ReadmeHowto_scala.ts +2 -1
- package/project/.sdk/src/cmp/scala/ReadmeInstall_scala.ts +3 -3
- package/project/.sdk/src/cmp/scala/ReadmeModel_scala.ts +1 -1
- package/project/.sdk/src/cmp/scala/ReadmeQuick_scala.ts +3 -3
- package/project/.sdk/src/cmp/scala/TestEntity_scala.ts +3 -3
- package/project/.sdk/src/cmp/scala/fragment/EntityBase.fragment.scala +27 -1
- package/project/.sdk/src/cmp/swift/ReadmeHowto_swift.ts +2 -1
- package/project/.sdk/src/cmp/swift/ReadmeInstall_swift.ts +3 -3
- package/project/.sdk/src/cmp/swift/ReadmeModel_swift.ts +1 -1
- package/project/.sdk/src/cmp/swift/ReadmeQuick_swift.ts +3 -3
- package/project/.sdk/src/cmp/swift/fragment/EntityBase.fragment.swift +34 -1
- package/project/.sdk/src/cmp/ts/EntityOperation_ts.ts +9 -1
- package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +18 -1
- package/project/.sdk/src/cmp/ts/Gitignore_ts.ts +5 -2
- package/project/.sdk/src/cmp/ts/Main_ts.ts +4 -1
- package/project/.sdk/src/cmp/ts/Package_ts.ts +10 -1
- package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +13 -2
- package/project/.sdk/src/cmp/ts/ReadmeHowto_ts.ts +2 -1
- package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +21 -6
- package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +52 -2
- package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +14 -3
- package/project/.sdk/src/cmp/ts/ReadmeTopTest_ts.ts +34 -2
- package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +64 -43
- package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +8 -8
- package/project/.sdk/src/cmp/ts/fragment/Direct.test.fragment.ts +2 -2
- package/project/.sdk/src/cmp/ts/fragment/Entity.test.fragment.ts +2 -2
- package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +25 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +10 -2
- package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +1 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +10 -2
- package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +27 -3
- package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +10 -2
- package/project/.sdk/src/cmp/ts/fragment/SdkError.fragment.ts +15 -0
- package/project/.sdk/src/cmp/zig/Entity_zig.ts +5 -1
- package/project/.sdk/src/cmp/zig/Package_zig.ts +3 -1
- package/project/.sdk/src/cmp/zig/fragment/Entity.fragment.zig +39 -0
- package/project/.sdk/src/cmp/zig/fragment/EntityCreateOp.fragment.zig +2 -2
- package/project/.sdk/src/cmp/zig/fragment/EntityListOp.fragment.zig +21 -2
- package/project/.sdk/src/cmp/zig/fragment/EntityLoadOp.fragment.zig +2 -2
- package/project/.sdk/src/cmp/zig/fragment/EntityRemoveOp.fragment.zig +5 -2
- package/project/.sdk/src/cmp/zig/fragment/EntityUpdateOp.fragment.zig +2 -2
- package/project/.sdk/tm/c/VERSION +1 -1
- package/project/.sdk/tm/c/core/helpers.c +1 -0
- package/project/.sdk/tm/c/core/sdk.h +22 -6
- package/project/.sdk/tm/c/tests/feature_harness.h +1 -0
- package/project/.sdk/tm/c/tests/primary_utility_test.c +4 -1
- package/project/.sdk/tm/c/utility/graphql.c +1 -1
- package/project/.sdk/tm/c/utility/make_url.c +1 -0
- package/project/.sdk/tm/c/utility/param.c +1 -0
- package/project/.sdk/tm/clojure/VERSION +1 -1
- package/project/.sdk/tm/cpp/VERSION +1 -1
- package/project/.sdk/tm/cpp/core/types.hpp +33 -8
- package/project/.sdk/tm/cpp/test/pipeline_test.cpp +5 -0
- package/project/.sdk/tm/cpp/test/runner_support.hpp +4 -4
- package/project/.sdk/tm/csharp/VERSION +1 -1
- package/project/.sdk/tm/csharp/core/Types.cs +6 -0
- package/project/.sdk/tm/csharp/test/FeatureHarness.cs +396 -0
- package/project/.sdk/tm/csharp/test/FeatureTest.cs +7 -385
- package/project/.sdk/tm/csharp/test/Runner.cs +4 -4
- package/project/.sdk/tm/dart/lib/utility/MakeErrorUtility.dart +4 -0
- package/project/.sdk/tm/dart/test/utility.dart +4 -4
- package/project/.sdk/tm/elixir/VERSION +1 -1
- package/project/.sdk/tm/elixir/lib/projectname/entity_base.ex +26 -0
- package/project/.sdk/tm/go/VERSION +1 -1
- package/project/.sdk/tm/go/core/types.go +6 -0
- package/project/.sdk/tm/go/test/feature_harness_test.go +361 -0
- package/project/.sdk/tm/go/test/feature_test.go +7 -350
- package/project/.sdk/tm/go/test/pipeline_test.go +6 -0
- package/project/.sdk/tm/go/test/runner_test.go +16 -4
- package/project/.sdk/tm/haskell/VERSION +1 -1
- package/project/.sdk/tm/haskell/src/SdkFeatures.hs +28 -5
- package/project/.sdk/tm/haskell/src/SdkTypes.hs +14 -5
- package/project/.sdk/tm/java/VERSION +1 -1
- package/project/.sdk/tm/java/test/RunnerSupport.java +4 -4
- package/project/.sdk/tm/java/utility/MakeError.java +4 -0
- package/project/.sdk/tm/js/src/utility/MakeErrorUtility.js +4 -0
- package/project/.sdk/tm/js/test/utility.js +3 -3
- package/project/.sdk/tm/kotlin/VERSION +1 -1
- package/project/.sdk/tm/kotlin/core/Utility.kt +2 -0
- package/project/.sdk/tm/kotlin/test/RunnerSupport.kt +3 -3
- package/project/.sdk/tm/lean/Makefile +25 -0
- package/project/.sdk/tm/lean/VERSION +1 -1
- package/project/.sdk/tm/lean/src/SdkUtility.lean +11 -9
- package/project/.sdk/tm/lean/test/TFeature.lean +27 -14
- package/project/.sdk/tm/lean/test/TPrimaryUtility.lean +5 -2
- package/project/.sdk/tm/lua/test/runner.lua +4 -4
- package/project/.sdk/tm/lua/utility/make_error.lua +4 -0
- package/project/.sdk/tm/ocaml/VERSION +1 -1
- package/project/.sdk/tm/ocaml/sdk_types.ml +14 -5
- package/project/.sdk/tm/ocaml/test/t_pipeline.ml +5 -2
- package/project/.sdk/tm/perl/t/runner.pm +4 -4
- package/project/.sdk/tm/php/VERSION +1 -1
- package/project/.sdk/tm/php/test/Runner.php +4 -4
- package/project/.sdk/tm/php/utility/MakeError.php +5 -0
- package/project/.sdk/tm/py/pkg/utility/make_error.py +4 -0
- package/project/.sdk/tm/py/test/runner.py +19 -4
- package/project/.sdk/tm/rb/test/runner.rb +4 -4
- package/project/.sdk/tm/rb/utility/make_error.rb +4 -0
- package/project/.sdk/tm/rust/VERSION +1 -1
- package/project/.sdk/tm/rust/core/types.rs +22 -6
- package/project/.sdk/tm/rust/tests/common/mod.rs +6 -6
- package/project/.sdk/tm/rust/tests/pipeline_test.rs +6 -0
- package/project/.sdk/tm/rust/utility/make_error.rs +4 -0
- package/project/.sdk/tm/scala/VERSION +1 -1
- package/project/.sdk/tm/swift/VERSION +1 -1
- package/project/.sdk/tm/ts/src/tsconfig.json +1 -0
- package/project/.sdk/tm/ts/src/utility/MakeErrorUtility.ts +4 -0
- package/project/.sdk/tm/ts/test/tsconfig.json +1 -0
- package/project/.sdk/tm/ts/test/utility.ts +3 -3
- package/project/.sdk/tm/zig/VERSION +1 -1
- package/src/action/doctor.ts +410 -0
- package/src/action/feature.ts +54 -16
- package/src/action/target.ts +174 -25
- package/src/cmp/Entity.ts +7 -0
- package/src/cmp/Feature.ts +3 -1
- package/src/cmp/Main.ts +7 -1
- package/src/cmp/ReadmeExplanation.ts +2 -2
- package/src/cmp/ReadmeTop.ts +22 -9
- package/src/cmp/Registered.ts +100 -0
- package/src/cmp/Test.ts +4 -1
- package/src/helpers/dryrun.ts +57 -0
- package/src/helpers/featureSource.ts +208 -0
- package/src/helpers/naming.ts +73 -2
- package/src/helpers/opExample.ts +19 -2
- package/src/helpers/opShape.ts +65 -0
- package/src/helpers/packageMeta.ts +163 -10
- package/src/helpers/stdrep.ts +56 -0
- package/src/helpers/testPolicy.ts +52 -0
- package/src/sdkgen.ts +70 -4
- package/project/.sdk/tm/rust/feature/mod.rs +0 -24
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// EJECT-START
|
|
2
2
|
|
|
3
|
-
pub fn update(self: *EntyClass, reqdata: Value, ctrl: Value)
|
|
3
|
+
pub fn update(self: *EntyClass, reqdata: Value, ctrl: Value) EntResult {
|
|
4
4
|
const ctx = self.utility.make_context(CtxSpec{
|
|
5
5
|
.opname = "update",
|
|
6
6
|
.ctrl = ctrl,
|
|
@@ -8,7 +8,7 @@ pub fn update(self: *EntyClass, reqdata: Value, ctrl: Value) OpResult {
|
|
|
8
8
|
.data = self.data,
|
|
9
9
|
.reqdata = reqdata,
|
|
10
10
|
}, self.ent_ctx());
|
|
11
|
-
return self.
|
|
11
|
+
return self.run_op_ent(ctx, update_post_done);
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
fn update_post_done(self: *EntyClass, ctx: *Context) void {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
PROJECTVERSION
|
|
@@ -303,17 +303,33 @@ voxgig_value* utility_fetch(Utility* u, Context* ctx, const char* url,
|
|
|
303
303
|
// Entity (vtable; mirrors core/types.rs Entity + ProjectNameEntity)
|
|
304
304
|
// ===========================================================================
|
|
305
305
|
|
|
306
|
+
// Every operation resolves to the ENTITY, not the raw data. `list` resolves
|
|
307
|
+
// to a NULL-terminated array of them, one per record; the record is reached
|
|
308
|
+
// through `data`. See AGENTS.md "Entity operations return ENTITIES".
|
|
309
|
+
//
|
|
310
|
+
// `voxgig_value` cannot carry an entity - it is a closed data union
|
|
311
|
+
// (UNDEF|NULL|BOOL|INT|DOUBLE|STRING|LIST|MAP|FUNC|SENTINEL), and adding a
|
|
312
|
+
// variant to a general-purpose struct library to hold SDK objects would be
|
|
313
|
+
// wrong - so the CONTRACT lives in these signatures instead.
|
|
306
314
|
typedef struct EntityVT {
|
|
307
315
|
const char* (*get_name)(Entity*);
|
|
308
316
|
Entity* (*make)(Entity*);
|
|
309
317
|
voxgig_value* (*data)(Entity*, voxgig_value* args); // args NULL => none
|
|
310
318
|
voxgig_value* (*matchv)(Entity*, voxgig_value* args); // args NULL => none
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
319
|
+
|
|
320
|
+
// `remove` resolves to the entity, marked. The instance KEEPS the data it
|
|
321
|
+
// held - a caller can still read what was deleted - but it is no longer a
|
|
322
|
+
// live record.
|
|
323
|
+
void (*mark_deleted)(Entity*);
|
|
324
|
+
bool (*deleted)(Entity*);
|
|
325
|
+
|
|
326
|
+
// CRUD ops (ProjectNameEntity). On error set *err and return NULL.
|
|
327
|
+
Entity* (*load)(Entity*, voxgig_value* reqmatch, voxgig_value* ctrl, PNError** err);
|
|
328
|
+
// Returns a NULL-terminated Entity* array (never NULL on success).
|
|
329
|
+
Entity** (*list)(Entity*, voxgig_value* reqmatch, voxgig_value* ctrl, PNError** err);
|
|
330
|
+
Entity* (*create)(Entity*, voxgig_value* reqdata, voxgig_value* ctrl, PNError** err);
|
|
331
|
+
Entity* (*update)(Entity*, voxgig_value* reqdata, voxgig_value* ctrl, PNError** err);
|
|
332
|
+
Entity* (*remove)(Entity*, voxgig_value* reqmatch, voxgig_value* ctrl, PNError** err);
|
|
317
333
|
} EntityVT;
|
|
318
334
|
|
|
319
335
|
struct Entity {
|
|
@@ -241,7 +241,10 @@ static void test_primary_make_fetch_def_basic(void) {
|
|
|
241
241
|
static void test_primary_make_fetch_def_with_body(void) {
|
|
242
242
|
base_client();
|
|
243
243
|
Context* ctx = full_ctx();
|
|
244
|
-
|
|
244
|
+
// 8 pairs, not 9 - cmap is variadic and reads exactly npairs, so an
|
|
245
|
+
// overcount walks off the argument list and the trailing entry (method) is
|
|
246
|
+
// whatever the read finds.
|
|
247
|
+
ctx->spec = spec_new(cmap(8, "base", v_str("http://localhost:8080"), "prefix", v_str(""),
|
|
245
248
|
"path", v_str("items"), "suffix", v_str(""), "params", v_map(),
|
|
246
249
|
"query", v_map(), "headers", v_map(), "method", v_str("POST")));
|
|
247
250
|
ctx->spec->body = cmap(1, "name", v_str("test"));
|
|
@@ -72,7 +72,7 @@ const char* graphql_error_code(voxgig_value* gqlerr) {
|
|
|
72
72
|
// generated create/update call look exactly like its REST equivalent.
|
|
73
73
|
voxgig_value* graphql_body_util(Context* ctx) {
|
|
74
74
|
voxgig_value* gql = getp(ctx->point, "graphql");
|
|
75
|
-
if (!voxgig_is_map(gql)) return
|
|
75
|
+
if (!voxgig_is_map(gql)) return voxgig_new_undef();
|
|
76
76
|
|
|
77
77
|
// reqmatch/reqdata hold the caller's arguments for THIS call; data/match
|
|
78
78
|
// hold the entity's current state. Which pair depends on whether the op
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
PROJECTVERSION
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
PROJECTVERSION
|
|
@@ -347,6 +347,12 @@ public:
|
|
|
347
347
|
virtual EntityPtr make() = 0;
|
|
348
348
|
virtual Value data(const Value& arg = Value::undef()) = 0;
|
|
349
349
|
virtual Value match(const Value& arg = Value::undef()) = 0;
|
|
350
|
+
|
|
351
|
+
// `remove` resolves to the entity, marked. The instance KEEPS the data it
|
|
352
|
+
// held - a caller can still read what was deleted - but it is no longer a
|
|
353
|
+
// live record.
|
|
354
|
+
virtual void markDeleted() = 0;
|
|
355
|
+
virtual bool deleted() = 0;
|
|
350
356
|
};
|
|
351
357
|
|
|
352
358
|
// ---- Feature contract -------------------------------------------------
|
|
@@ -575,22 +581,33 @@ public:
|
|
|
575
581
|
|
|
576
582
|
// ---- SdkEntity contract -----------------------------------------------
|
|
577
583
|
|
|
584
|
+
class SdkEntity;
|
|
585
|
+
using SdkEntityPtr = std::shared_ptr<SdkEntity>;
|
|
586
|
+
|
|
587
|
+
// Every operation resolves to the ENTITY, not the raw data - `list` to a
|
|
588
|
+
// vector of them, one per record. The record is reached through `data()`.
|
|
589
|
+
// See AGENTS.md "Entity operations return ENTITIES".
|
|
590
|
+
//
|
|
591
|
+
// `Value` cannot carry an entity: it is a closed data union, and adding a
|
|
592
|
+
// variant to a general-purpose struct library to hold SDK objects would be
|
|
593
|
+
// wrong. So the CONTRACT lives in these signatures instead.
|
|
578
594
|
class SdkEntity : public Entity {
|
|
579
595
|
public:
|
|
580
|
-
virtual
|
|
581
|
-
virtual
|
|
582
|
-
virtual
|
|
583
|
-
virtual
|
|
584
|
-
virtual
|
|
596
|
+
virtual SdkEntityPtr load(const Value& reqmatch, const Value& ctrl) = 0;
|
|
597
|
+
virtual std::vector<SdkEntityPtr> list(const Value& reqmatch, const Value& ctrl) = 0;
|
|
598
|
+
virtual SdkEntityPtr create(const Value& reqdata, const Value& ctrl) = 0;
|
|
599
|
+
virtual SdkEntityPtr update(const Value& reqdata, const Value& ctrl) = 0;
|
|
600
|
+
virtual SdkEntityPtr remove(const Value& reqmatch, const Value& ctrl) = 0;
|
|
585
601
|
};
|
|
586
602
|
|
|
587
|
-
using SdkEntityPtr = std::shared_ptr<SdkEntity>;
|
|
588
|
-
|
|
589
603
|
// ---- EntityBase (shared entity runtime + runOp) -----------------------
|
|
590
604
|
|
|
591
|
-
class EntityBase : public SdkEntity
|
|
605
|
+
class EntityBase : public SdkEntity,
|
|
606
|
+
public std::enable_shared_from_this<EntityBase> {
|
|
592
607
|
public:
|
|
593
608
|
std::string name_ = "";
|
|
609
|
+
// Set once a successful `remove` resolves on this instance.
|
|
610
|
+
bool deleted_ = false;
|
|
594
611
|
SdkClient* client = nullptr;
|
|
595
612
|
UtilityPtr utility;
|
|
596
613
|
Value entopts = Value::undef();
|
|
@@ -602,6 +619,14 @@ public:
|
|
|
602
619
|
|
|
603
620
|
std::string getName() override { return name_; }
|
|
604
621
|
|
|
622
|
+
void markDeleted() override { deleted_ = true; }
|
|
623
|
+
bool deleted() override { return deleted_; }
|
|
624
|
+
|
|
625
|
+
// The handle for this instance, as the ops return it.
|
|
626
|
+
SdkEntityPtr self() {
|
|
627
|
+
return std::static_pointer_cast<SdkEntity>(shared_from_this());
|
|
628
|
+
}
|
|
629
|
+
|
|
605
630
|
Value data(const Value& arg = Value::undef()) override;
|
|
606
631
|
Value match(const Value& arg = Value::undef()) override;
|
|
607
632
|
|
|
@@ -43,6 +43,11 @@ struct PlEntity : public Entity {
|
|
|
43
43
|
return Value::undef();
|
|
44
44
|
}
|
|
45
45
|
Value match(const Value& arg = Value::undef()) override { return Value::undef(); }
|
|
46
|
+
|
|
47
|
+
// Every operation resolves to the entity; `remove` marks it. The fake has
|
|
48
|
+
// to satisfy the same interface the real entities do.
|
|
49
|
+
void markDeleted() override {}
|
|
50
|
+
bool deleted() override { return false; }
|
|
46
51
|
};
|
|
47
52
|
|
|
48
53
|
static std::string errCodeOf(const std::function<void()>& fn) {
|
|
@@ -74,8 +74,8 @@ inline std::string getenv_local(const std::string& key) {
|
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
inline Value env_override(Value m) {
|
|
77
|
-
std::string live = getenv_local("
|
|
78
|
-
std::string over = getenv_local("
|
|
77
|
+
std::string live = getenv_local("PROJECTENV_TEST_LIVE");
|
|
78
|
+
std::string over = getenv_local("PROJECTENV_TEST_OVERRIDE");
|
|
79
79
|
if (live == "TRUE" || over == "TRUE") {
|
|
80
80
|
if (m.is_map()) {
|
|
81
81
|
for (const auto& k : Struct::keysof(m)) {
|
|
@@ -92,8 +92,8 @@ inline Value env_override(Value m) {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
|
-
std::string explain = getenv_local("
|
|
96
|
-
if (!explain.empty()) map_put(m, "
|
|
95
|
+
std::string explain = getenv_local("PROJECTENV_TEST_EXPLAIN");
|
|
96
|
+
if (!explain.empty()) map_put(m, "PROJECTENV_TEST_EXPLAIN", Value(explain));
|
|
97
97
|
return m;
|
|
98
98
|
}
|
|
99
99
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
PROJECTVERSION
|
|
@@ -11,6 +11,12 @@ public interface IEntity
|
|
|
11
11
|
IEntity Make();
|
|
12
12
|
object? Data(object? data = null);
|
|
13
13
|
object? Match(object? match = null);
|
|
14
|
+
|
|
15
|
+
// Every operation resolves to the entity; Remove additionally marks it.
|
|
16
|
+
// The instance keeps the data it held - a caller can still read what was
|
|
17
|
+
// deleted - but it is no longer a live record.
|
|
18
|
+
void MarkDeleted();
|
|
19
|
+
bool Deleted();
|
|
14
20
|
}
|
|
15
21
|
|
|
16
22
|
// Transport function: performs the HTTP (or mock) request. Returns a
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
// Offline feature-test harness: a faithful miniature of the real operation
|
|
2
|
+
// pipeline (same hook order and short-circuit rules as the generated entity
|
|
3
|
+
// op code) driven against a configurable mock transport, with no live server
|
|
4
|
+
// and no API-specific fixtures. C# twin of tm/go/test/feature_harness_test.go.
|
|
5
|
+
//
|
|
6
|
+
// SEPARATE FROM FeatureTest.cs ON PURPOSE. `target add` drops the
|
|
7
|
+
// cross-feature suite when a project trims its feature set (it constructs
|
|
8
|
+
// every shipped feature by name), but PipelineTest.cs uses these Fh* helpers
|
|
9
|
+
// too - leaving them in FeatureTest.cs took the whole test assembly down
|
|
10
|
+
// with it.
|
|
11
|
+
|
|
12
|
+
using System.Text.RegularExpressions;
|
|
13
|
+
|
|
14
|
+
using Voxgig.Struct;
|
|
15
|
+
using Xunit;
|
|
16
|
+
|
|
17
|
+
using ProjectNameSdk;
|
|
18
|
+
using ProjectNameSdk.Feature;
|
|
19
|
+
|
|
20
|
+
namespace ProjectNameSdk.Test;
|
|
21
|
+
|
|
22
|
+
// --- harness ----------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
// FhClock is a deterministic virtual clock: Now() advances only when
|
|
25
|
+
// Sleep(ms) is called, so timing-based features can be asserted without
|
|
26
|
+
// real delays.
|
|
27
|
+
internal class FhClock
|
|
28
|
+
{
|
|
29
|
+
public long T;
|
|
30
|
+
public long Now() => T;
|
|
31
|
+
public void Sleep(int ms) => T += ms;
|
|
32
|
+
public void Advance(int ms) => T += ms;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// FhRecorder is a mock transport recording every call, replying via an
|
|
36
|
+
// optional Reply func (default: 200 with a call counter).
|
|
37
|
+
internal class FhRecorder
|
|
38
|
+
{
|
|
39
|
+
public List<Dictionary<string, object?>> Calls = new();
|
|
40
|
+
public Func<int, Dictionary<string, object?>, object?>? Reply;
|
|
41
|
+
|
|
42
|
+
public object? Fetch(Context ctx, string url, Dictionary<string, object?> fetchdef)
|
|
43
|
+
{
|
|
44
|
+
Calls.Add(new Dictionary<string, object?>
|
|
45
|
+
{
|
|
46
|
+
["url"] = url,
|
|
47
|
+
["fetchdef"] = fetchdef,
|
|
48
|
+
});
|
|
49
|
+
if (Reply != null)
|
|
50
|
+
{
|
|
51
|
+
return Reply(Calls.Count, fetchdef);
|
|
52
|
+
}
|
|
53
|
+
return Fh.Response(200, new Dictionary<string, object?>
|
|
54
|
+
{
|
|
55
|
+
["ok"] = true,
|
|
56
|
+
["n"] = Calls.Count,
|
|
57
|
+
}, null);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public Dictionary<string, object?> Headers(int i)
|
|
61
|
+
{
|
|
62
|
+
var fetchdef = Calls[i]["fetchdef"] as Dictionary<string, object?>;
|
|
63
|
+
return fetchdef?["headers"] as Dictionary<string, object?>
|
|
64
|
+
?? new Dictionary<string, object?>();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
public Dictionary<string, object?> Fetchdef(int i)
|
|
68
|
+
{
|
|
69
|
+
return Calls[i]["fetchdef"] as Dictionary<string, object?>
|
|
70
|
+
?? new Dictionary<string, object?>();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
public string Url(int i)
|
|
74
|
+
{
|
|
75
|
+
return Calls[i]["url"] as string ?? "";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
internal class FhOpSpec
|
|
80
|
+
{
|
|
81
|
+
public string Entity = "";
|
|
82
|
+
public string Op = "";
|
|
83
|
+
public string Method = "";
|
|
84
|
+
public string Path = "";
|
|
85
|
+
public Dictionary<string, object?>? Query;
|
|
86
|
+
public Dictionary<string, object?>? Headers;
|
|
87
|
+
public object? Body;
|
|
88
|
+
public Dictionary<string, object?>? Ctrl;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
internal class FhOpResult
|
|
92
|
+
{
|
|
93
|
+
public bool Ok;
|
|
94
|
+
public object? Data;
|
|
95
|
+
public Exception? Err;
|
|
96
|
+
public Result? Result;
|
|
97
|
+
public Context? Ctx;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// FhHarness wires features (in init order) to a mock transport and a mini
|
|
101
|
+
// operation pipeline.
|
|
102
|
+
internal class FhHarness
|
|
103
|
+
{
|
|
104
|
+
public ProjectNameSDK Client = null!;
|
|
105
|
+
public Utility Utility = null!;
|
|
106
|
+
public Context Rootctx = null!;
|
|
107
|
+
public string Base = "http://api.test";
|
|
108
|
+
|
|
109
|
+
private static string FhDefaultMethod(string op)
|
|
110
|
+
{
|
|
111
|
+
return op switch
|
|
112
|
+
{
|
|
113
|
+
"create" => "POST",
|
|
114
|
+
"update" => "PATCH",
|
|
115
|
+
"remove" => "DELETE",
|
|
116
|
+
_ => "GET",
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private static string FhBuildUrl(Spec spec)
|
|
121
|
+
{
|
|
122
|
+
var keys = spec.Query.Where(kv => kv.Value != null)
|
|
123
|
+
.Select(kv => kv.Key).OrderBy(k => k, StringComparer.Ordinal).ToList();
|
|
124
|
+
var qs = string.Join("&", keys.Select(k =>
|
|
125
|
+
Uri.EscapeDataString(k) + "=" +
|
|
126
|
+
Uri.EscapeDataString(StructUtils.Stringify(spec.Query[k]))));
|
|
127
|
+
var url = spec.Base + spec.Path;
|
|
128
|
+
if (qs != "")
|
|
129
|
+
{
|
|
130
|
+
url += "?" + qs;
|
|
131
|
+
}
|
|
132
|
+
return url;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Op runs one operation through the mini pipeline (mirrors the generated
|
|
136
|
+
// entity op code: hook, short-circuit, make*, hook, ...).
|
|
137
|
+
public FhOpResult Op(FhOpSpec o)
|
|
138
|
+
{
|
|
139
|
+
var entity = o.Entity == "" ? "widget" : o.Entity;
|
|
140
|
+
var opname = o.Op == "" ? "load" : o.Op;
|
|
141
|
+
var method = o.Method == "" ? FhDefaultMethod(opname) : o.Method;
|
|
142
|
+
var ctrl = o.Ctrl ?? new Dictionary<string, object?>();
|
|
143
|
+
|
|
144
|
+
var ctx = Utility.MakeContext(new Dictionary<string, object?>
|
|
145
|
+
{
|
|
146
|
+
["opname"] = opname,
|
|
147
|
+
["ctrl"] = ctrl,
|
|
148
|
+
}, Rootctx);
|
|
149
|
+
ctx.Op = new Operation(new Dictionary<string, object?>
|
|
150
|
+
{
|
|
151
|
+
["entity"] = entity,
|
|
152
|
+
["name"] = opname,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
Utility.FeatureHook(ctx, "PostConstructEntity");
|
|
156
|
+
|
|
157
|
+
Utility.FeatureHook(ctx, "PrePoint");
|
|
158
|
+
if (ctx.Out.TryGetValue("point", out var pointOut) && pointOut is Exception perr)
|
|
159
|
+
{
|
|
160
|
+
return Fail(ctx, perr);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
Utility.FeatureHook(ctx, "PreSpec");
|
|
164
|
+
var path = o.Path == "" ? "/" + entity : o.Path;
|
|
165
|
+
var headers = new Dictionary<string, object?>(o.Headers
|
|
166
|
+
?? new Dictionary<string, object?>());
|
|
167
|
+
var query = new Dictionary<string, object?>(o.Query
|
|
168
|
+
?? new Dictionary<string, object?>());
|
|
169
|
+
ctx.Spec = new Spec(new Dictionary<string, object?>
|
|
170
|
+
{
|
|
171
|
+
["method"] = method,
|
|
172
|
+
["base"] = Base,
|
|
173
|
+
["path"] = path,
|
|
174
|
+
["headers"] = headers,
|
|
175
|
+
["query"] = query,
|
|
176
|
+
["step"] = "start",
|
|
177
|
+
});
|
|
178
|
+
if (o.Body != null)
|
|
179
|
+
{
|
|
180
|
+
ctx.Spec.Body = o.Body;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
Utility.FeatureHook(ctx, "PreRequest");
|
|
184
|
+
ctx.Spec.Url = FhBuildUrl(ctx.Spec);
|
|
185
|
+
|
|
186
|
+
var fetchdef = new Dictionary<string, object?>
|
|
187
|
+
{
|
|
188
|
+
["url"] = ctx.Spec.Url,
|
|
189
|
+
["method"] = ctx.Spec.Method,
|
|
190
|
+
["headers"] = ctx.Spec.Headers,
|
|
191
|
+
};
|
|
192
|
+
if (ctx.Spec.Body != null)
|
|
193
|
+
{
|
|
194
|
+
fetchdef["body"] = ctx.Spec.Body;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
object? response = null;
|
|
198
|
+
Exception? fetchErr = null;
|
|
199
|
+
if (ctx.Out.TryGetValue("request", out var reqOut) && reqOut != null)
|
|
200
|
+
{
|
|
201
|
+
response = reqOut;
|
|
202
|
+
}
|
|
203
|
+
else
|
|
204
|
+
{
|
|
205
|
+
try
|
|
206
|
+
{
|
|
207
|
+
response = Utility.Fetcher(ctx, ctx.Spec.Url, fetchdef);
|
|
208
|
+
}
|
|
209
|
+
catch (Exception ex)
|
|
210
|
+
{
|
|
211
|
+
fetchErr = ex;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (response is Dictionary<string, object?> rm)
|
|
215
|
+
{
|
|
216
|
+
ctx.Response = new Response(rm);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
Utility.FeatureHook(ctx, "PreResponse");
|
|
220
|
+
FhPopulateResult(ctx, response, fetchErr);
|
|
221
|
+
Utility.FeatureHook(ctx, "PreResult");
|
|
222
|
+
Utility.FeatureHook(ctx, "PreDone");
|
|
223
|
+
|
|
224
|
+
if (ctx.Result != null && ctx.Result.Ok)
|
|
225
|
+
{
|
|
226
|
+
return new FhOpResult
|
|
227
|
+
{
|
|
228
|
+
Ok = true,
|
|
229
|
+
Data = ctx.Result.Resdata,
|
|
230
|
+
Result = ctx.Result,
|
|
231
|
+
Ctx = ctx,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
Exception err;
|
|
236
|
+
if (ctx.Result?.Err != null)
|
|
237
|
+
{
|
|
238
|
+
err = ctx.Result.Err;
|
|
239
|
+
}
|
|
240
|
+
else
|
|
241
|
+
{
|
|
242
|
+
err = ctx.MakeError("op_failed", "operation failed");
|
|
243
|
+
}
|
|
244
|
+
return Fail(ctx, err);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
private FhOpResult Fail(Context ctx, Exception err)
|
|
248
|
+
{
|
|
249
|
+
ctx.Ctrl.Err = err;
|
|
250
|
+
Utility.FeatureHook(ctx, "PreUnexpected");
|
|
251
|
+
return new FhOpResult
|
|
252
|
+
{
|
|
253
|
+
Ok = false,
|
|
254
|
+
Err = err,
|
|
255
|
+
Result = ctx.Result,
|
|
256
|
+
Ctx = ctx,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
private static void FhPopulateResult(Context ctx, object? response, Exception? fetchErr)
|
|
261
|
+
{
|
|
262
|
+
var result = new Result(new Dictionary<string, object?>());
|
|
263
|
+
ctx.Result = result;
|
|
264
|
+
|
|
265
|
+
if (fetchErr != null)
|
|
266
|
+
{
|
|
267
|
+
result.Err = fetchErr;
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (response is not Dictionary<string, object?> rm)
|
|
272
|
+
{
|
|
273
|
+
result.Err = ctx.MakeError("request_no_response", "response: undefined");
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
var resp = new Response(rm);
|
|
278
|
+
result.Status = resp.Status;
|
|
279
|
+
result.StatusText = resp.StatusText;
|
|
280
|
+
if (resp.Headers is Dictionary<string, object?> hm)
|
|
281
|
+
{
|
|
282
|
+
result.Headers = hm;
|
|
283
|
+
}
|
|
284
|
+
if (resp.JsonFunc != null)
|
|
285
|
+
{
|
|
286
|
+
result.Body = resp.JsonFunc();
|
|
287
|
+
}
|
|
288
|
+
result.Resdata = result.Body;
|
|
289
|
+
|
|
290
|
+
if (result.Status >= 400)
|
|
291
|
+
{
|
|
292
|
+
result.Err = ctx.MakeError("request_status",
|
|
293
|
+
$"request: {result.Status}: {result.StatusText}");
|
|
294
|
+
}
|
|
295
|
+
else if (resp.Err != null)
|
|
296
|
+
{
|
|
297
|
+
result.Err = resp.Err;
|
|
298
|
+
}
|
|
299
|
+
if (result.Err == null)
|
|
300
|
+
{
|
|
301
|
+
result.Ok = true;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
internal static class Fh
|
|
307
|
+
{
|
|
308
|
+
// HasFeature is true when this SDK was generated with the named feature.
|
|
309
|
+
public static bool HasFeature(string name)
|
|
310
|
+
{
|
|
311
|
+
var config = SdkConfig.MakeConfig();
|
|
312
|
+
return config.TryGetValue("feature", out var fraw) &&
|
|
313
|
+
fraw is Dictionary<string, object?> fm &&
|
|
314
|
+
fm.TryGetValue(name, out var f) && f != null;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
public static bool SkipWithout(params string[] names)
|
|
318
|
+
{
|
|
319
|
+
return names.Any(name => !HasFeature(name));
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Response builds a transport-shaped response the pipeline understands.
|
|
323
|
+
public static Dictionary<string, object?> Response(int status, object? data,
|
|
324
|
+
Dictionary<string, object?>? headers)
|
|
325
|
+
{
|
|
326
|
+
var h = new Dictionary<string, object?>();
|
|
327
|
+
if (headers != null)
|
|
328
|
+
{
|
|
329
|
+
foreach (var kv in headers)
|
|
330
|
+
{
|
|
331
|
+
h[kv.Key.ToLowerInvariant()] = kv.Value;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return new Dictionary<string, object?>
|
|
335
|
+
{
|
|
336
|
+
["status"] = status,
|
|
337
|
+
["statusText"] = status >= 400 ? "ERR" : "OK",
|
|
338
|
+
["body"] = "not-used",
|
|
339
|
+
["json"] = (Func<object?>)(() => data),
|
|
340
|
+
["headers"] = h,
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// Make constructs the harness: a real (test-mode) client, an isolated
|
|
345
|
+
// utility whose fetcher is the mock server, and the requested features
|
|
346
|
+
// initialised against it. Fires PostConstruct once wiring is complete.
|
|
347
|
+
public static FhHarness Make(FetcherFunc? server,
|
|
348
|
+
params (BaseFeature f, Dictionary<string, object?>? options)[] features)
|
|
349
|
+
{
|
|
350
|
+
var client = ProjectNameSDK.TestSDK(null, null);
|
|
351
|
+
client.Features = new List<BaseFeature>();
|
|
352
|
+
|
|
353
|
+
var utility = client.GetUtility();
|
|
354
|
+
if (server == null)
|
|
355
|
+
{
|
|
356
|
+
var rec = new FhRecorder();
|
|
357
|
+
server = rec.Fetch;
|
|
358
|
+
}
|
|
359
|
+
utility.Fetcher = server;
|
|
360
|
+
|
|
361
|
+
var rootctx = utility.MakeContext(new Dictionary<string, object?>
|
|
362
|
+
{
|
|
363
|
+
["client"] = client,
|
|
364
|
+
["utility"] = utility,
|
|
365
|
+
}, client.GetRootCtx());
|
|
366
|
+
|
|
367
|
+
foreach (var (f, options) in features)
|
|
368
|
+
{
|
|
369
|
+
var fopts = new Dictionary<string, object?> { ["active"] = true };
|
|
370
|
+
if (options != null)
|
|
371
|
+
{
|
|
372
|
+
foreach (var kv in options)
|
|
373
|
+
{
|
|
374
|
+
fopts[kv.Key] = kv.Value;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
f.Init(rootctx, fopts);
|
|
378
|
+
client.Features.Add(f);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
utility.FeatureHook(rootctx, "PostConstruct");
|
|
382
|
+
|
|
383
|
+
return new FhHarness
|
|
384
|
+
{
|
|
385
|
+
Client = client,
|
|
386
|
+
Utility = utility,
|
|
387
|
+
Rootctx = rootctx,
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// ErrCode extracts the SDK error code, "" otherwise.
|
|
392
|
+
public static string ErrCode(Exception? err)
|
|
393
|
+
{
|
|
394
|
+
return err is ProjectNameError se ? se.Code : "";
|
|
395
|
+
}
|
|
396
|
+
}
|