@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
|
@@ -5,26 +5,26 @@ import { isControlSkipped, liveDelayMs } from './utility'
|
|
|
5
5
|
|
|
6
6
|
// The offline flow keeps its deterministic fixture assertions. Live flows
|
|
7
7
|
// resolve real prerequisites per operation and collect failures until done.
|
|
8
|
-
async function runLiveEntity(setup: any, entity: any, flow: any, accessor: string) {
|
|
8
|
+
async function runLiveEntity(setup: any, entity: any, flow: any, accessor: string, facts: any = {}) {
|
|
9
9
|
const { client, transport } = setup
|
|
10
|
-
const steps: any[] = flow.step || []
|
|
10
|
+
const steps: any[] = (flow.step || []).filter((step: any) => false !== step.a)
|
|
11
11
|
const created = new Map<string, any>()
|
|
12
12
|
const listed: any[] = []
|
|
13
13
|
const marks = new Map<string, { name: string, value: any }>()
|
|
14
14
|
const idField = entity.id?.field || 'id'
|
|
15
15
|
const copy = (value: any) => JSON.parse(JSON.stringify(value ?? {}))
|
|
16
|
-
const hasCreate = steps.some(step => step.
|
|
16
|
+
const hasCreate = steps.some(step => step.o === 'create')
|
|
17
17
|
const report = await runLiveSteps(steps.map((step, index) => {
|
|
18
|
-
const ref = step.
|
|
19
|
-
const op = step.
|
|
18
|
+
const ref = step.i?.ref || entity.name + '_ref01'
|
|
19
|
+
const op = step.o
|
|
20
20
|
const excluded = isControlSkipped('entityOp', entity.name + '.' + op, 'live')
|
|
21
21
|
return {
|
|
22
22
|
id: entity.name + '.' + op + '.' + index,
|
|
23
|
-
cleanup: op === 'remove' || (step.
|
|
23
|
+
cleanup: op === 'remove' || (step.v || []).some((v: any) => v.apply === 'ItemNotExists'),
|
|
24
24
|
excluded: excluded.skip ? excluded.reason || 'Excluded by test control' : undefined,
|
|
25
25
|
run: async (context: any) => {
|
|
26
26
|
transport.enter(context)
|
|
27
|
-
const points = entity.op?.[op]?.points || []
|
|
27
|
+
const points = (entity.op?.[op]?.points || []).filter((point: any) => false !== point.a)
|
|
28
28
|
if (!points.length) throw new LiveBlocked('No modelled operation point')
|
|
29
29
|
const record = created.get(ref)
|
|
30
30
|
// A failed create must not turn a later update/remove into a write
|
|
@@ -41,7 +41,7 @@ async function runLiveEntity(setup: any, entity: any, flow: any, accessor: strin
|
|
|
41
41
|
|
|
42
42
|
let input: any = op === 'create'
|
|
43
43
|
? copy(setup.data.new?.[entity.name]?.[ref]) : {}
|
|
44
|
-
for (const [name, binding] of Object.entries({ ...step.
|
|
44
|
+
for (const [name, binding] of Object.entries({ ...step.m, ...step.d })) {
|
|
45
45
|
const value = setup.idmap[binding as string] ?? setup.idmap[name]
|
|
46
46
|
if (undefined !== value) input[name] = value
|
|
47
47
|
}
|
|
@@ -57,34 +57,34 @@ async function runLiveEntity(setup: any, entity: any, flow: any, accessor: strin
|
|
|
57
57
|
let selected: any
|
|
58
58
|
const missing = new Set<string>()
|
|
59
59
|
for (const point of points) {
|
|
60
|
-
if (point.
|
|
60
|
+
if (point.q?.$action !== input.$action) continue
|
|
61
61
|
const candidate = { ...input }
|
|
62
62
|
let viable = true
|
|
63
|
-
const params = point.
|
|
64
|
-
const query = (point.
|
|
63
|
+
const params = point.g?.params || []
|
|
64
|
+
const query = (point.g?.query || []).filter((arg: any) => arg.r)
|
|
65
65
|
for (const arg of [...params, ...query]) {
|
|
66
|
-
if (undefined !== candidate[arg.
|
|
67
|
-
const key = arg.
|
|
68
|
-
const value = setup.idmap[key] ?? setup.idmap[arg.
|
|
69
|
-
if (undefined !== value && null !== value) candidate[arg.
|
|
70
|
-
else if (arg.
|
|
66
|
+
if (undefined !== candidate[arg.n] && null !== candidate[arg.n]) continue
|
|
67
|
+
const key = arg.n === 'id' ? entity.name + '01' : arg.n.replace(/_id$/, '') + '01'
|
|
68
|
+
const value = setup.idmap[key] ?? setup.idmap[arg.n] ?? loaded?.[arg.n] ?? arg.ex
|
|
69
|
+
if (undefined !== value && null !== value) candidate[arg.n] = value
|
|
70
|
+
else if (arg.r !== false) { viable = false; missing.add(arg.n) }
|
|
71
71
|
}
|
|
72
72
|
if (viable) { resolved = candidate; selected = point; break }
|
|
73
73
|
}
|
|
74
74
|
if (!resolved) throw new LiveBlocked('No usable route; missing arguments: ' + [...missing].join(', '))
|
|
75
75
|
input = resolved
|
|
76
|
-
if (op === 'create' && selected.
|
|
77
|
-
const
|
|
78
|
-
const request = requestContract(
|
|
79
|
-
if (request.schema) input = { ...synthesizeInput(request.schema,
|
|
80
|
-
else if (
|
|
81
|
-
for (const arg of selected.
|
|
76
|
+
if (op === 'create' && facts[selected.m + ' ' + selected.o]) {
|
|
77
|
+
const selectedFacts = facts[selected.m + ' ' + selected.o]
|
|
78
|
+
const request = requestContract(selectedFacts)
|
|
79
|
+
if (request.schema) input = { ...synthesizeInput(request.schema, selected.li?.input ?? request.example) }
|
|
80
|
+
else if (selectedFacts.protocol === 'http') input = {}
|
|
81
|
+
for (const arg of selected.g?.params || []) if (resolved[arg.n] !== undefined) input[arg.n] = resolved[arg.n]
|
|
82
82
|
}
|
|
83
83
|
let intendedMark: { name: string, value: any } | undefined
|
|
84
84
|
if (op === 'update') {
|
|
85
|
-
for (const spec of step.
|
|
86
|
-
if (spec.apply === 'TextFieldMark' && step.
|
|
87
|
-
const mark = { name: step.
|
|
85
|
+
for (const spec of step.s || []) {
|
|
86
|
+
if (spec.apply === 'TextFieldMark' && step.i?.textfield) {
|
|
87
|
+
const mark = { name: step.i.textfield, value: spec.def.mark + '_' + setup.now }
|
|
88
88
|
input[mark.name] = mark.value
|
|
89
89
|
intendedMark = mark
|
|
90
90
|
}
|
|
@@ -103,7 +103,7 @@ async function runLiveEntity(setup: any, entity: any, flow: any, accessor: strin
|
|
|
103
103
|
})
|
|
104
104
|
listed.splice(0, listed.length, ...data)
|
|
105
105
|
context.publish(data)
|
|
106
|
-
for (const validation of step.
|
|
106
|
+
for (const validation of step.v || []) {
|
|
107
107
|
const previous = created.get(validation.def?.ref)
|
|
108
108
|
const id = previous?.[idField] ?? previous?.id
|
|
109
109
|
if (undefined === id) continue
|
|
@@ -52,9 +52,9 @@ export async function runLiveScenarios(SDK: any, plan: any[], envPrefix: string,
|
|
|
52
52
|
const explicit = hint.input === undefined ? request.example : resolveRecipe(hint.input, ctx.values)
|
|
53
53
|
let input = request.schema ? synthesizeInput(request.schema, explicit) : explicit ?? {}
|
|
54
54
|
for (const kind of ['params', 'query', 'header', 'cookie']) for (const arg of point.args?.[kind] || []) {
|
|
55
|
-
if (arg.
|
|
56
|
-
if (arg.
|
|
57
|
-
input[arg.
|
|
55
|
+
if (arg.r && input[arg.n] === undefined) {
|
|
56
|
+
if (arg.ex === undefined) throw new LiveBlocked('Missing required argument: ' + arg.n)
|
|
57
|
+
input[arg.n] = arg.ex
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
const role = hint.auth || (point.facts.security?.length === 0 || point.facts.securitySource === 'unspecified' ? 'public' : 'account')
|
|
@@ -100,7 +100,7 @@ pub const Context = struct {
|
|
|
100
100
|
ctrl = c;
|
|
101
101
|
} else if (ctxspec.ctrl_obj) |co| {
|
|
102
102
|
ctrl = co;
|
|
103
|
-
} else if (basectx) |b| {
|
|
103
|
+
} else if (if (ctxspec.opname == null) basectx else null) |b| {
|
|
104
104
|
ctrl = b.ctrl;
|
|
105
105
|
} else {
|
|
106
106
|
ctrl = Control.make();
|
|
@@ -1120,7 +1120,7 @@ pub fn prepare_query_util(ctx: *Context) Value {
|
|
|
1120
1120
|
}
|
|
1121
1121
|
}
|
|
1122
1122
|
}
|
|
1123
|
-
if (!h.is_noval(val) and !contained) h.setp(out, key, val);
|
|
1123
|
+
if (!h.is_noval(val) and !std.mem.eql(u8, key, "$action") and !contained) h.setp(out, key, val);
|
|
1124
1124
|
}
|
|
1125
1125
|
}
|
|
1126
1126
|
return out;
|
|
@@ -1375,6 +1375,20 @@ pub fn result_body_util(ctx: *Context) ?*SdkResult {
|
|
|
1375
1375
|
return result;
|
|
1376
1376
|
}
|
|
1377
1377
|
|
|
1378
|
+
// `$action` selects the point (see make_point_util); it is never an API
|
|
1379
|
+
// field, so the body is a copy without it. The caller's map is left untouched.
|
|
1380
|
+
fn strip_action(reqdata: Value) Value {
|
|
1381
|
+
if (reqdata != .object) return reqdata;
|
|
1382
|
+
if (reqdata.object.get("$action") == null) return reqdata;
|
|
1383
|
+
const body = h.omap();
|
|
1384
|
+
var it = reqdata.object.iterator();
|
|
1385
|
+
while (it.next()) |kv| {
|
|
1386
|
+
const key = kv.key_ptr.*;
|
|
1387
|
+
if (!std.mem.eql(u8, key, "$action")) h.setp(body, key, kv.value_ptr.*);
|
|
1388
|
+
}
|
|
1389
|
+
return body;
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1378
1392
|
pub fn transform_request_util(ctx: *Context) Value {
|
|
1379
1393
|
const spec = ctx.spec;
|
|
1380
1394
|
const point = ctx.point;
|
|
@@ -1382,16 +1396,16 @@ pub fn transform_request_util(ctx: *Context) Value {
|
|
|
1382
1396
|
if (spec) |sp| sp.step = "reqform";
|
|
1383
1397
|
|
|
1384
1398
|
const transform = h.to_map(h.getp(point, "transform"));
|
|
1385
|
-
if (h.is_noval(transform)) return ctx.reqdata;
|
|
1399
|
+
if (h.is_noval(transform)) return strip_action(ctx.reqdata);
|
|
1386
1400
|
|
|
1387
1401
|
const reqform = h.getp(transform, "req");
|
|
1388
|
-
if (h.is_noval(reqform)) return ctx.reqdata;
|
|
1402
|
+
if (h.is_noval(reqform)) return strip_action(ctx.reqdata);
|
|
1389
1403
|
|
|
1390
1404
|
const store = h.jo(&.{.{ "reqdata", ctx.reqdata }});
|
|
1391
1405
|
// transform now reports collected injection errors beside the value; .out
|
|
1392
1406
|
// is what it used to return on its own, errors or not.
|
|
1393
|
-
const tres = vs.transform(h.A(), store, reqform) catch return ctx.reqdata;
|
|
1394
|
-
return tres.out;
|
|
1407
|
+
const tres = vs.transform(h.A(), store, reqform) catch return strip_action(ctx.reqdata);
|
|
1408
|
+
return strip_action(tres.out);
|
|
1395
1409
|
}
|
|
1396
1410
|
|
|
1397
1411
|
pub fn transform_response_util(ctx: *Context) Value {
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
// (or a cursor) into the request query; on the way back (PreResult) it reads
|
|
4
4
|
// the server's pagination signals — a `Link: rel="next"` header,
|
|
5
5
|
// `X-Page`/`X-Next-Page`/`X-Total-Count` headers, or
|
|
6
|
-
// `next`/`cursor`/`nextCursor`/`hasMore` fields in the body
|
|
7
|
-
// on `result.paging
|
|
6
|
+
// `next`/`cursor`/`nextCursor`/`hasMore` fields in the body (snake_case forms
|
|
7
|
+
// too) — and records them on `result.paging` and the caller's ctrl paging. A per-call cursor/page from ctrl takes priority (used by
|
|
8
8
|
// auto-iteration). Parameter names (`pageParam`, `limitParam`, `cursorParam`),
|
|
9
9
|
// the page size (`limit`) and the start page (`startPage`, default 1) are
|
|
10
10
|
// configurable.
|
|
@@ -114,7 +114,10 @@ pub const PagingFeature = struct {
|
|
|
114
114
|
if (!h.is_noval(cursor)) {
|
|
115
115
|
h.setp(query, cursor_param, cursor);
|
|
116
116
|
} else if (h.is_noval(h.getp(query, page_param))) {
|
|
117
|
-
|
|
117
|
+
// A record written back by pre_result holds the page just fetched
|
|
118
|
+
// as "page" and the one to fetch as "nextPage", so nextPage wins.
|
|
119
|
+
var page = h.getp(paging, "nextPage");
|
|
120
|
+
if (h.is_noval(page)) page = h.getp(paging, "page");
|
|
118
121
|
if (!h.is_noval(page)) {
|
|
119
122
|
h.setp(query, page_param, page);
|
|
120
123
|
} else {
|
|
@@ -257,12 +260,16 @@ pub const PagingFeature = struct {
|
|
|
257
260
|
}
|
|
258
261
|
}
|
|
259
262
|
|
|
260
|
-
// Body-level
|
|
263
|
+
// Body-level signals; snake_case forms are read first so camelCase wins.
|
|
261
264
|
if (body == .object) {
|
|
262
265
|
const next = h.getp(body, "next");
|
|
263
266
|
if (!h.is_noval(next) and h.is_noval(h.getp(paging, "next"))) {
|
|
264
267
|
h.setp(paging, "next", next);
|
|
265
268
|
}
|
|
269
|
+
const snake_cursor = h.getp(body, "next_cursor");
|
|
270
|
+
if (!h.is_noval(snake_cursor)) {
|
|
271
|
+
h.setp(paging, "cursor", snake_cursor);
|
|
272
|
+
}
|
|
266
273
|
const cursor = h.getp(body, "cursor");
|
|
267
274
|
if (!h.is_noval(cursor)) {
|
|
268
275
|
h.setp(paging, "cursor", cursor);
|
|
@@ -271,6 +278,18 @@ pub const PagingFeature = struct {
|
|
|
271
278
|
if (!h.is_noval(next_cursor)) {
|
|
272
279
|
h.setp(paging, "cursor", next_cursor);
|
|
273
280
|
}
|
|
281
|
+
if (h.is_noval(h.getp(paging, "nextPage"))) {
|
|
282
|
+
var np = h.getp(body, "nextPage");
|
|
283
|
+
if (h.is_noval(np)) np = h.getp(body, "next_page");
|
|
284
|
+
switch (np) {
|
|
285
|
+
.integer, .float, .string => h.setp(paging, "nextPage", np),
|
|
286
|
+
else => {},
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
if (h.get_bool(body, "has_more")) |has_more| {
|
|
290
|
+
h.setp(paging, "hasMore", h.vbool(has_more));
|
|
291
|
+
explicit_more = true;
|
|
292
|
+
}
|
|
274
293
|
if (h.get_bool(body, "hasMore")) |has_more| {
|
|
275
294
|
h.setp(paging, "hasMore", h.vbool(has_more));
|
|
276
295
|
explicit_more = true;
|
|
@@ -292,6 +311,17 @@ pub const PagingFeature = struct {
|
|
|
292
311
|
|
|
293
312
|
result.paging = paging;
|
|
294
313
|
self.last = paging;
|
|
314
|
+
|
|
315
|
+
// `.object` is a *MapRef, so the caller's map is refilled in place; a
|
|
316
|
+
// fresh map on ctrl never reaches the caller.
|
|
317
|
+
if (ctx.ctrl.paging == .object) {
|
|
318
|
+
const shared = ctx.ctrl.paging.object;
|
|
319
|
+
shared.data.clearRetainingCapacity();
|
|
320
|
+
var it = paging.object.iterator();
|
|
321
|
+
while (it.next()) |kv| h.setp(ctx.ctrl.paging, kv.key_ptr.*, kv.value_ptr.*);
|
|
322
|
+
} else {
|
|
323
|
+
ctx.ctrl.paging = paging;
|
|
324
|
+
}
|
|
295
325
|
}
|
|
296
326
|
|
|
297
327
|
fn vname(p: *anyopaque) []const u8 {
|
|
@@ -109,15 +109,22 @@ fn envelope(ctx: *Context, data: Value) Value {
|
|
|
109
109
|
const restf = h.getpath(&.{ "transform", "res" }, ctx.point);
|
|
110
110
|
if (restf != .string) return data;
|
|
111
111
|
const spec = restf.string;
|
|
112
|
-
//
|
|
113
|
-
//
|
|
112
|
+
// Rebuild whatever nesting the transform unwraps. Multi-segment on purpose:
|
|
113
|
+
// GraphQL ops unwrap `body.data.<field>`, not just one envelope property.
|
|
114
114
|
if (spec.len < 8) return data;
|
|
115
115
|
if (!std.mem.startsWith(u8, spec, "`body.")) return data;
|
|
116
116
|
if (!std.mem.endsWith(u8, spec, "`")) return data;
|
|
117
117
|
const inner = spec[6 .. spec.len - 1];
|
|
118
118
|
if (inner.len == 0) return data;
|
|
119
|
-
|
|
120
|
-
|
|
119
|
+
var out = data;
|
|
120
|
+
var end: usize = inner.len;
|
|
121
|
+
while (true) {
|
|
122
|
+
const cut = std.mem.lastIndexOfScalar(u8, inner[0..end], '.');
|
|
123
|
+
const start = if (cut) |c| c + 1 else 0;
|
|
124
|
+
out = h.jo(&.{.{ inner[start..end], out }});
|
|
125
|
+
if (cut) |c| end = c else break;
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
121
128
|
}
|
|
122
129
|
|
|
123
130
|
fn respond(ctx: *Context, status: i64, data: Value, extra: []const h.Pair) Value {
|
|
@@ -143,26 +150,62 @@ fn resolve_match(ctx: *Context, explicit: Value) Value {
|
|
|
143
150
|
return h.omap();
|
|
144
151
|
}
|
|
145
152
|
|
|
153
|
+
fn point_terminal(p: Value) bool {
|
|
154
|
+
const parts = h.getp(p, "parts");
|
|
155
|
+
if (parts != .array) return false;
|
|
156
|
+
const items = parts.array.data.items;
|
|
157
|
+
if (items.len == 0) return false;
|
|
158
|
+
const last = items[items.len - 1];
|
|
159
|
+
return last == .string and std.mem.startsWith(u8, last.string, "{");
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
fn point_depth(p: Value) usize {
|
|
163
|
+
const parts = h.getp(p, "parts");
|
|
164
|
+
return if (parts == .array) parts.array.data.items.len else 0;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// The entity's own endpoint: a terminal `{param}` marks a record route, and
|
|
168
|
+
// among equals the shallower path wins (the same rule as make_point).
|
|
169
|
+
fn pick_point(points: Value) Value {
|
|
170
|
+
if (points != .array) return h.vnull();
|
|
171
|
+
const items = points.array.data.items;
|
|
172
|
+
if (items.len == 0) return h.vnull();
|
|
173
|
+
var point = items[0];
|
|
174
|
+
for (items[1..]) |cand| {
|
|
175
|
+
if (point_terminal(cand) != point_terminal(point)) {
|
|
176
|
+
if (point_terminal(cand)) point = cand;
|
|
177
|
+
} else if (point_depth(cand) < point_depth(point)) {
|
|
178
|
+
point = cand;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return point;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
fn reqd_names(point: Value, kind: []const u8) Value {
|
|
185
|
+
const args_path = h.getpath(&.{ "args", kind }, point);
|
|
186
|
+
const reqd_args = vs.select(h.A(), args_path, h.jo(&.{.{ "reqd", h.vbool(true) }})) catch return h.olist();
|
|
187
|
+
// transform reports collected injection errors beside the value; .out is
|
|
188
|
+
// the value itself, errors or not.
|
|
189
|
+
const tres = vs.transform(h.A(), reqd_args, h.ja(&.{
|
|
190
|
+
h.vstr("`$EACH`"),
|
|
191
|
+
h.vstr(""),
|
|
192
|
+
h.vstr("`$KEY.name`"),
|
|
193
|
+
})) catch return h.olist();
|
|
194
|
+
return tres.out;
|
|
195
|
+
}
|
|
196
|
+
|
|
146
197
|
fn build_args(ctx: *Context, args: Value) Value {
|
|
147
198
|
const op = ctx.op;
|
|
148
199
|
const opname = op.name;
|
|
149
200
|
const entname: []const u8 = if (ctx.entity) |e| e.get_name() else op.entity;
|
|
150
201
|
|
|
151
202
|
const points = h.getpath(&.{ "entity", entname, "op", opname, "points" }, ctx.config);
|
|
152
|
-
const point =
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
// .out is what it used to return on its own, errors or not.
|
|
159
|
-
const tres = vs.transform(h.A(), reqd_params, h.ja(&.{
|
|
160
|
-
h.vstr("`$EACH`"),
|
|
161
|
-
h.vstr(""),
|
|
162
|
-
h.vstr("`$KEY.name`"),
|
|
163
|
-
})) catch break :blk h.olist();
|
|
164
|
-
break :blk tres.out;
|
|
165
|
-
};
|
|
203
|
+
const point = pick_point(points);
|
|
204
|
+
|
|
205
|
+
// Path AND query: a path-only read misses a query-addressed record
|
|
206
|
+
// (e.g. GET /result?trace_id=), which has no path param at all.
|
|
207
|
+
const reqd_params = reqd_names(point, "params");
|
|
208
|
+
const reqd_query = reqd_names(point, "query");
|
|
166
209
|
|
|
167
210
|
const qand = h.olist();
|
|
168
211
|
const q = h.jo(&.{.{ "`$AND`", qand }});
|
|
@@ -171,8 +214,8 @@ fn build_args(ctx: *Context, args: Value) Value {
|
|
|
171
214
|
const keys = h.keysof_vec(args);
|
|
172
215
|
for (keys) |key| {
|
|
173
216
|
const is_id = std.mem.eql(u8, key, "id");
|
|
174
|
-
const
|
|
175
|
-
|
|
217
|
+
const is_reqd = !h.is_empty(vs.select(h.A(), reqd_params, h.vstr(key)) catch h.olist()) or
|
|
218
|
+
!h.is_empty(vs.select(h.A(), reqd_query, h.vstr(key)) catch h.olist());
|
|
176
219
|
|
|
177
220
|
if (is_id or is_reqd) {
|
|
178
221
|
const v = ctx.util().param(ctx, h.vstr(key));
|
|
@@ -244,20 +287,12 @@ fn test_fetch(entity: Value, ctx: *Context, _: []const u8, _: Value) err.E!Value
|
|
|
244
287
|
const args = build_args(ctx, update_match);
|
|
245
288
|
const found = vs.select(h.A(), entmap, args) catch h.olist();
|
|
246
289
|
var ent = h.get_elem(found, h.vnum(0), h.vnull());
|
|
247
|
-
if (h.is_noval(ent) and h.sizeOf(entmap) > 0) {
|
|
248
|
-
for (h.items_vec(entmap)) |kv| {
|
|
249
|
-
if (kv.v == .object) {
|
|
250
|
-
ent = kv.v;
|
|
251
|
-
break;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
290
|
if (h.is_noval(ent)) {
|
|
291
|
+
// update miss: 404, never another record
|
|
256
292
|
return respond(ctx, 404, h.vnull(), &.{.{ "statusText", h.vstr("Not found") }});
|
|
257
293
|
}
|
|
258
294
|
if (ent == .object and reqdata == .object) {
|
|
259
|
-
|
|
260
|
-
while (it.next()) |kv| h.setp(ent, kv.key_ptr.*, kv.value_ptr.*);
|
|
295
|
+
ent = h.merge(h.ja(&.{ ent, reqdata }));
|
|
261
296
|
}
|
|
262
297
|
h.del_prop(ent, h.vstr("$KEY"));
|
|
263
298
|
return respond(ctx, 200, h.clone(ent), &.{});
|
package/src/action/doctor.ts
CHANGED
|
@@ -230,7 +230,7 @@ function orphanModelFiles(actx: ActionContext): string[] {
|
|
|
230
230
|
|
|
231
231
|
|
|
232
232
|
async function doctor(
|
|
233
|
-
actx: ActionContext, scope?: DoctorScope,
|
|
233
|
+
actx: ActionContext, scope?: DoctorScope, selected?: string[],
|
|
234
234
|
): Promise<ActionResult> {
|
|
235
235
|
const log = actx.log
|
|
236
236
|
const fs = actx.fs()
|
|
@@ -283,17 +283,18 @@ async function doctor(
|
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
if ('target' === kind) {
|
|
286
|
-
checkTarget(actx, source, report)
|
|
286
|
+
checkTarget(actx, source, report, selected)
|
|
287
287
|
}
|
|
288
288
|
|
|
289
289
|
if ('edition' === kind) {
|
|
290
290
|
checkEdition(actx, source, report)
|
|
291
291
|
}
|
|
292
292
|
|
|
293
|
-
// Only an ACTIVE feature has source copied out;
|
|
294
|
-
//
|
|
293
|
+
// Only an ACTIVE feature has source copied out; an inactive one's
|
|
294
|
+
// leftovers are stale. `selected` overrides that for the caller's own.
|
|
295
295
|
if ('feature' === kind &&
|
|
296
|
-
false !== (model as any)?.main?.[KIT]?.feature?.[name]?.active
|
|
296
|
+
(false !== (model as any)?.main?.[KIT]?.feature?.[name]?.active ||
|
|
297
|
+
true === selected?.includes(name))) {
|
|
297
298
|
checkFeatureSource(actx, source, targets, report)
|
|
298
299
|
}
|
|
299
300
|
|
|
@@ -409,6 +410,7 @@ function resolveDeclared(
|
|
|
409
410
|
|
|
410
411
|
function checkTarget(
|
|
411
412
|
actx: ActionContext, resolved: Source, report: DoctorReport,
|
|
413
|
+
selected?: string[],
|
|
412
414
|
) {
|
|
413
415
|
const tname = resolved.name
|
|
414
416
|
const tfolder = resolved.folder
|
|
@@ -442,14 +444,15 @@ function checkTarget(
|
|
|
442
444
|
},
|
|
443
445
|
]
|
|
444
446
|
|
|
445
|
-
// The feature set `target add` would select right now
|
|
446
|
-
//
|
|
447
|
-
//
|
|
448
|
-
//
|
|
447
|
+
// The feature set `target add` would select right now, plus any the CALLER
|
|
448
|
+
// is acting on (`selected`, see COMMENT-NOTES.md). A project that added its
|
|
449
|
+
// targets before feature trimming existed carries source for features its
|
|
450
|
+
// model never declared — expected here as STALE, which is what it is.
|
|
449
451
|
const featuremodel: any = model?.main?.[KIT]?.feature ?? {}
|
|
450
452
|
const features = Array.from(new Set([
|
|
451
453
|
'test',
|
|
452
454
|
...Object.keys(featuremodel).filter((n: string) => false !== featuremodel[n]?.active),
|
|
455
|
+
...(selected ?? []),
|
|
453
456
|
]))
|
|
454
457
|
|
|
455
458
|
// `folder` and `model` matter: the trim catalogue is resolved consumer-side
|
package/src/action/edition.ts
CHANGED
|
@@ -39,6 +39,7 @@ function cmpBase(): string {
|
|
|
39
39
|
|
|
40
40
|
const CMD_MAP: any = Object.assign(Object.create(null), {
|
|
41
41
|
add: cmd_edition_add,
|
|
42
|
+
remove: cmd_edition_remove,
|
|
42
43
|
})
|
|
43
44
|
|
|
44
45
|
|
|
@@ -65,6 +66,13 @@ async function cmd_edition_add(
|
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
|
|
69
|
+
async function cmd_edition_remove(
|
|
70
|
+
args: string[], actx: ActionContext,
|
|
71
|
+
): Promise<ActionResult> {
|
|
72
|
+
return require('./remove').kind_remove('edition', parseAddNames(args), actx)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
|
|
68
76
|
async function edition_add(
|
|
69
77
|
edition: string[], actx: ActionContext,
|
|
70
78
|
): Promise<ActionResult> {
|
package/src/action/feature.ts
CHANGED
|
@@ -42,7 +42,8 @@ import {
|
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
const CMD_MAP: any = {
|
|
45
|
-
add: cmd_feature_add
|
|
45
|
+
add: cmd_feature_add,
|
|
46
|
+
remove: cmd_feature_remove,
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
const BASE = 'node_modules/@voxgig/sdkgen'
|
|
@@ -74,6 +75,11 @@ async function cmd_feature_add(args: string[], actx: ActionContext): Promise<Act
|
|
|
74
75
|
}
|
|
75
76
|
|
|
76
77
|
|
|
78
|
+
async function cmd_feature_remove(args: string[], actx: ActionContext): Promise<ActionResult> {
|
|
79
|
+
return require('./remove').kind_remove('feature', parseAddNames(args), actx)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
77
83
|
async function feature_add(features: string[], actx: ActionContext): Promise<ActionResult> {
|
|
78
84
|
|
|
79
85
|
// Reuse the caller's Jostraca instance so feature generation honours the
|