@voxgig/sdkgen 1.2.1 → 1.3.1
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 +2 -2
- package/dist/action/action.d.ts +2 -1
- package/dist/action/action.js +15 -9
- package/dist/action/action.js.map +1 -1
- package/dist/action/feature.js +6 -3
- package/dist/action/feature.js.map +1 -1
- package/dist/action/target.d.ts +7 -1
- package/dist/action/target.js +13 -6
- package/dist/action/target.js.map +1 -1
- package/dist/cmp/Changelog.d.ts +2 -0
- package/dist/cmp/Changelog.js +30 -0
- package/dist/cmp/Changelog.js.map +1 -0
- package/dist/cmp/Deploy.d.ts +2 -0
- package/dist/cmp/Deploy.js +227 -0
- package/dist/cmp/Deploy.js.map +1 -0
- package/dist/cmp/FeatureHook.js +5 -6
- package/dist/cmp/FeatureHook.js.map +1 -1
- package/dist/cmp/License.d.ts +2 -0
- package/dist/cmp/License.js +44 -0
- package/dist/cmp/License.js.map +1 -0
- package/dist/cmp/Readme.js +2 -0
- package/dist/cmp/Readme.js.map +1 -1
- package/dist/cmp/ReadmeErrors.d.ts +2 -0
- package/dist/cmp/ReadmeErrors.js +210 -0
- package/dist/cmp/ReadmeErrors.js.map +1 -0
- package/dist/cmp/ReadmeExplanation.js +213 -223
- package/dist/cmp/ReadmeExplanation.js.map +1 -1
- package/dist/cmp/ReadmeModel.js +6 -1
- package/dist/cmp/ReadmeModel.js.map +1 -1
- package/dist/cmp/ReadmeTop.js +389 -82
- package/dist/cmp/ReadmeTop.js.map +1 -1
- package/dist/cmp/Security.d.ts +2 -0
- package/dist/cmp/Security.js +36 -0
- package/dist/cmp/Security.js.map +1 -0
- package/dist/helpers/canonType.d.ts +7 -0
- package/dist/helpers/canonType.js +74 -0
- package/dist/helpers/canonType.js.map +1 -0
- package/dist/helpers/collectDeps.d.ts +3 -2
- package/dist/helpers/collectDeps.js.map +1 -1
- package/dist/helpers/naming.d.ts +3 -0
- package/dist/helpers/naming.js +51 -0
- package/dist/helpers/naming.js.map +1 -0
- package/dist/helpers/opExample.d.ts +13 -0
- package/dist/helpers/opExample.js +149 -0
- package/dist/helpers/opExample.js.map +1 -0
- package/dist/helpers/opShape.d.ts +18 -0
- package/dist/helpers/opShape.js +193 -0
- package/dist/helpers/opShape.js.map +1 -0
- package/dist/helpers/packageMeta.d.ts +27 -0
- package/dist/helpers/packageMeta.js +224 -0
- package/dist/helpers/packageMeta.js.map +1 -0
- package/dist/sdkgen.d.ts +11 -1
- package/dist/sdkgen.js +57 -18
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +65 -2
- package/dist/types.js.map +1 -1
- package/dist/utility.js +20 -11
- package/dist/utility.js.map +1 -1
- package/model/sdkgen.aontu +137 -0
- package/package.json +11 -5
- package/project/.sdk/model/target/go-cli.jsonic +47 -0
- package/project/.sdk/model/target/go-mcp.jsonic +41 -0
- package/project/.sdk/model/target/go.jsonic +9 -3
- package/project/.sdk/model/target/js.jsonic +13 -0
- package/project/.sdk/model/target/lua.jsonic +13 -0
- package/project/.sdk/model/target/php.jsonic +13 -0
- package/project/.sdk/model/target/py.jsonic +13 -0
- package/project/.sdk/model/target/rb.jsonic +13 -0
- package/project/.sdk/model/target/ts.jsonic +13 -0
- package/project/.sdk/src/cmp/go/EntityOperation_go.ts +1 -0
- package/project/.sdk/src/cmp/go/EntityTypes_go.ts +197 -0
- package/project/.sdk/src/cmp/go/Entity_go.ts +2 -1
- package/project/.sdk/src/cmp/go/MainEntity_go.ts +6 -0
- package/project/.sdk/src/cmp/go/Main_go.ts +23 -3
- package/project/.sdk/src/cmp/go/Package_go.ts +1 -1
- package/project/.sdk/src/cmp/go/ReadmeEntity_go.ts +18 -6
- package/project/.sdk/src/cmp/go/ReadmeExamplesTest_go.ts +684 -0
- package/project/.sdk/src/cmp/go/ReadmeExplanation_go.ts +1 -1
- package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +48 -8
- package/project/.sdk/src/cmp/go/ReadmeInstall_go.ts +11 -6
- package/project/.sdk/src/cmp/go/ReadmeIntro_go.ts +40 -1
- package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +63 -17
- package/project/.sdk/src/cmp/go/ReadmeOptions_go.ts +4 -3
- package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +124 -115
- package/project/.sdk/src/cmp/go/ReadmeRef_go.ts +28 -15
- package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +33 -9
- package/project/.sdk/src/cmp/go/ReadmeTopTest_go.ts +35 -5
- package/project/.sdk/src/cmp/go/TestEntity_go.ts +1 -1
- package/project/.sdk/src/cmp/go/Test_go.ts +5 -1
- package/project/.sdk/src/cmp/go/fragment/Entity.fragment.go +21 -0
- package/project/.sdk/src/cmp/go/fragment/EntityCreateOp.fragment.go +11 -0
- package/project/.sdk/src/cmp/go/fragment/EntityListOp.fragment.go +11 -0
- package/project/.sdk/src/cmp/go/fragment/EntityLoadOp.fragment.go +11 -0
- package/project/.sdk/src/cmp/go/fragment/EntityRemoveOp.fragment.go +11 -0
- package/project/.sdk/src/cmp/go/fragment/EntityUpdateOp.fragment.go +11 -0
- package/project/.sdk/src/cmp/go-cli/Main_go-cli.ts +195 -0
- package/project/.sdk/src/cmp/go-cli/fragment/main.fragment.go +106 -0
- package/project/.sdk/src/cmp/go-cli/fragment/words.fragment.go +132 -0
- package/project/.sdk/src/cmp/go-mcp/Main_go-mcp.ts +184 -0
- package/project/.sdk/src/cmp/go-mcp/fragment/main.fragment.go +68 -0
- package/project/.sdk/src/cmp/go-mcp/fragment/tools.fragment.go +114 -0
- package/project/.sdk/src/cmp/js/EntityTypes_js.ts +111 -0
- package/project/.sdk/src/cmp/js/MainEntity_js.ts +1 -0
- package/project/.sdk/src/cmp/js/Main_js.ts +3 -0
- package/project/.sdk/src/cmp/js/Package_js.ts +16 -7
- package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +13 -7
- package/project/.sdk/src/cmp/js/ReadmeExplanation_js.ts +2 -2
- package/project/.sdk/src/cmp/js/ReadmeHowto_js.ts +52 -11
- package/project/.sdk/src/cmp/js/ReadmeIntro_js.ts +39 -1
- package/project/.sdk/src/cmp/js/ReadmeModel_js.ts +50 -18
- package/project/.sdk/src/cmp/js/ReadmeOptions_js.ts +4 -3
- package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +45 -19
- package/project/.sdk/src/cmp/js/ReadmeRef_js.ts +24 -13
- package/project/.sdk/src/cmp/js/ReadmeTopHowto_js.ts +3 -0
- package/project/.sdk/src/cmp/js/ReadmeTopQuick_js.ts +28 -12
- package/project/.sdk/src/cmp/js/ReadmeTopTest_js.ts +23 -3
- package/project/.sdk/src/cmp/js/fragment/EntityCreateOp.fragment.js +5 -0
- package/project/.sdk/src/cmp/js/fragment/EntityListOp.fragment.js +5 -0
- package/project/.sdk/src/cmp/js/fragment/EntityLoadOp.fragment.js +5 -0
- package/project/.sdk/src/cmp/js/fragment/EntityRemoveOp.fragment.js +5 -0
- package/project/.sdk/src/cmp/js/fragment/EntityUpdateOp.fragment.js +5 -0
- package/project/.sdk/src/cmp/js/utility_js.ts +57 -0
- package/project/.sdk/src/cmp/lua/EntityTypes_lua.ts +113 -0
- package/project/.sdk/src/cmp/lua/MainEntity_lua.ts +8 -0
- package/project/.sdk/src/cmp/lua/Main_lua.ts +4 -0
- package/project/.sdk/src/cmp/lua/Package_lua.ts +23 -4
- package/project/.sdk/src/cmp/lua/ReadmeEntity_lua.ts +12 -10
- package/project/.sdk/src/cmp/lua/ReadmeExamplesTest_lua.ts +293 -0
- package/project/.sdk/src/cmp/lua/ReadmeHowto_lua.ts +46 -8
- package/project/.sdk/src/cmp/lua/ReadmeInstall_lua.ts +19 -3
- package/project/.sdk/src/cmp/lua/ReadmeIntro_lua.ts +38 -1
- package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +51 -16
- package/project/.sdk/src/cmp/lua/ReadmeOptions_lua.ts +4 -3
- package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +79 -18
- package/project/.sdk/src/cmp/lua/ReadmeRef_lua.ts +25 -20
- package/project/.sdk/src/cmp/lua/ReadmeTopQuick_lua.ts +17 -9
- package/project/.sdk/src/cmp/lua/ReadmeTopTest_lua.ts +32 -5
- package/project/.sdk/src/cmp/lua/Test_lua.ts +4 -0
- package/project/.sdk/src/cmp/lua/fragment/EntityCreateOp.fragment.lua +4 -0
- package/project/.sdk/src/cmp/lua/fragment/EntityListOp.fragment.lua +4 -0
- package/project/.sdk/src/cmp/lua/fragment/EntityLoadOp.fragment.lua +4 -0
- package/project/.sdk/src/cmp/lua/fragment/EntityRemoveOp.fragment.lua +4 -0
- package/project/.sdk/src/cmp/lua/fragment/EntityUpdateOp.fragment.lua +4 -0
- package/project/.sdk/src/cmp/php/EntityTypes_php.ts +142 -0
- package/project/.sdk/src/cmp/php/MainEntity_php.ts +18 -1
- package/project/.sdk/src/cmp/php/Main_php.ts +4 -0
- package/project/.sdk/src/cmp/php/Package_php.ts +18 -7
- package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +15 -11
- package/project/.sdk/src/cmp/php/ReadmeExamplesTest_php.ts +401 -0
- package/project/.sdk/src/cmp/php/ReadmeHowto_php.ts +56 -13
- package/project/.sdk/src/cmp/php/ReadmeInstall_php.ts +15 -3
- package/project/.sdk/src/cmp/php/ReadmeIntro_php.ts +40 -1
- package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +26 -8
- package/project/.sdk/src/cmp/php/ReadmeOptions_php.ts +4 -3
- package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +80 -22
- package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +51 -42
- package/project/.sdk/src/cmp/php/ReadmeTopHowto_php.ts +1 -1
- package/project/.sdk/src/cmp/php/ReadmeTopQuick_php.ts +19 -11
- package/project/.sdk/src/cmp/php/ReadmeTopTest_php.ts +41 -11
- package/project/.sdk/src/cmp/php/TestDirect_php.ts +9 -9
- package/project/.sdk/src/cmp/php/TestEntity_php.ts +6 -12
- package/project/.sdk/src/cmp/php/Test_php.ts +4 -0
- package/project/.sdk/src/cmp/php/fragment/Entity.fragment.php +13 -1
- package/project/.sdk/src/cmp/php/fragment/EntityCreateOp.fragment.php +10 -1
- package/project/.sdk/src/cmp/php/fragment/EntityListOp.fragment.php +10 -1
- package/project/.sdk/src/cmp/php/fragment/EntityLoadOp.fragment.php +10 -1
- package/project/.sdk/src/cmp/php/fragment/EntityRemoveOp.fragment.php +10 -1
- package/project/.sdk/src/cmp/php/fragment/EntityUpdateOp.fragment.php +10 -1
- package/project/.sdk/src/cmp/php/fragment/Main.fragment.php +22 -14
- package/project/.sdk/src/cmp/py/EntityTypes_py.ts +184 -0
- package/project/.sdk/src/cmp/py/Entity_py.ts +27 -0
- package/project/.sdk/src/cmp/py/MainEntity_py.ts +2 -1
- package/project/.sdk/src/cmp/py/Main_py.ts +35 -0
- package/project/.sdk/src/cmp/py/Package_py.ts +24 -3
- package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +27 -11
- package/project/.sdk/src/cmp/py/ReadmeExamplesTest_py.ts +626 -0
- package/project/.sdk/src/cmp/py/ReadmeHowto_py.ts +53 -14
- package/project/.sdk/src/cmp/py/ReadmeInstall_py.ts +19 -3
- package/project/.sdk/src/cmp/py/ReadmeIntro_py.ts +48 -1
- package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +28 -10
- package/project/.sdk/src/cmp/py/ReadmeOptions_py.ts +4 -3
- package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +73 -24
- package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +57 -37
- package/project/.sdk/src/cmp/py/ReadmeTopHowto_py.ts +1 -1
- package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +19 -11
- package/project/.sdk/src/cmp/py/ReadmeTopTest_py.ts +30 -5
- package/project/.sdk/src/cmp/py/TestDirect_py.ts +7 -9
- package/project/.sdk/src/cmp/py/TestEntity_py.ts +6 -14
- package/project/.sdk/src/cmp/py/Test_py.ts +4 -0
- package/project/.sdk/src/cmp/py/fragment/Entity.fragment.py +5 -2
- package/project/.sdk/src/cmp/py/fragment/EntityCreateOp.fragment.py +1 -1
- package/project/.sdk/src/cmp/py/fragment/EntityListOp.fragment.py +5 -1
- package/project/.sdk/src/cmp/py/fragment/EntityLoadOp.fragment.py +6 -1
- package/project/.sdk/src/cmp/py/fragment/EntityRemoveOp.fragment.py +6 -1
- package/project/.sdk/src/cmp/py/fragment/EntityUpdateOp.fragment.py +1 -1
- package/project/.sdk/src/cmp/py/fragment/Main.fragment.py +17 -10
- package/project/.sdk/src/cmp/rb/EntityTypes_rb.ts +136 -0
- package/project/.sdk/src/cmp/rb/MainEntity_rb.ts +1 -0
- package/project/.sdk/src/cmp/rb/Main_rb.ts +4 -0
- package/project/.sdk/src/cmp/rb/Package_rb.ts +34 -7
- package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +26 -10
- package/project/.sdk/src/cmp/rb/ReadmeExamplesTest_rb.ts +289 -0
- package/project/.sdk/src/cmp/rb/ReadmeHowto_rb.ts +72 -21
- package/project/.sdk/src/cmp/rb/ReadmeInstall_rb.ts +16 -4
- package/project/.sdk/src/cmp/rb/ReadmeIntro_rb.ts +40 -1
- package/project/.sdk/src/cmp/rb/ReadmeModel_rb.ts +29 -12
- package/project/.sdk/src/cmp/rb/ReadmeOptions_rb.ts +4 -3
- package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +85 -22
- package/project/.sdk/src/cmp/rb/ReadmeRef_rb.ts +56 -37
- package/project/.sdk/src/cmp/rb/ReadmeTopHowto_rb.ts +1 -1
- package/project/.sdk/src/cmp/rb/ReadmeTopQuick_rb.ts +19 -11
- package/project/.sdk/src/cmp/rb/ReadmeTopTest_rb.ts +43 -11
- package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +9 -9
- package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +6 -12
- package/project/.sdk/src/cmp/rb/Test_rb.ts +4 -0
- package/project/.sdk/src/cmp/rb/fragment/Entity.fragment.rb +2 -0
- package/project/.sdk/src/cmp/rb/fragment/EntityCreateOp.fragment.rb +5 -0
- package/project/.sdk/src/cmp/rb/fragment/EntityListOp.fragment.rb +20 -2
- package/project/.sdk/src/cmp/rb/fragment/EntityLoadOp.fragment.rb +8 -1
- package/project/.sdk/src/cmp/rb/fragment/EntityRemoveOp.fragment.rb +6 -1
- package/project/.sdk/src/cmp/rb/fragment/EntityUpdateOp.fragment.rb +5 -0
- package/project/.sdk/src/cmp/rb/fragment/Main.fragment.rb +24 -8
- package/project/.sdk/src/cmp/ts/EntityTypes_ts.ts +105 -0
- package/project/.sdk/src/cmp/ts/Entity_ts.ts +17 -1
- package/project/.sdk/src/cmp/ts/MainEntity_ts.ts +1 -0
- package/project/.sdk/src/cmp/ts/Main_ts.ts +6 -0
- package/project/.sdk/src/cmp/ts/Package_ts.ts +14 -7
- package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +13 -7
- package/project/.sdk/src/cmp/ts/ReadmeExampleTest_ts.ts +81 -0
- package/project/.sdk/src/cmp/ts/ReadmeExamplesTest_ts.ts +446 -0
- package/project/.sdk/src/cmp/ts/ReadmeExplanation_ts.ts +2 -2
- package/project/.sdk/src/cmp/ts/ReadmeHowto_ts.ts +57 -11
- package/project/.sdk/src/cmp/ts/ReadmeInstall_ts.ts +19 -6
- package/project/.sdk/src/cmp/ts/ReadmeIntro_ts.ts +39 -1
- package/project/.sdk/src/cmp/ts/ReadmeModel_ts.ts +50 -18
- package/project/.sdk/src/cmp/ts/ReadmeOptions_ts.ts +4 -3
- package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +95 -40
- package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +24 -13
- package/project/.sdk/src/cmp/ts/ReadmeTopHowto_ts.ts +3 -0
- package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +44 -12
- package/project/.sdk/src/cmp/ts/ReadmeTopTest_ts.ts +23 -3
- package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +2 -2
- package/project/.sdk/src/cmp/ts/Test_ts.ts +5 -0
- package/project/.sdk/src/cmp/ts/fragment/Entity.fragment.ts +3 -1
- package/project/.sdk/src/cmp/ts/fragment/EntityBase.fragment.ts +10 -5
- package/project/.sdk/src/cmp/ts/fragment/EntityCreateOp.fragment.ts +4 -2
- package/project/.sdk/src/cmp/ts/fragment/EntityListOp.fragment.ts +4 -2
- package/project/.sdk/src/cmp/ts/fragment/EntityLoadOp.fragment.ts +4 -2
- package/project/.sdk/src/cmp/ts/fragment/EntityRemoveOp.fragment.ts +4 -2
- package/project/.sdk/src/cmp/ts/fragment/EntityUpdateOp.fragment.ts +4 -2
- package/project/.sdk/src/cmp/ts/utility_ts.ts +59 -0
- package/project/.sdk/tm/go/LICENSE +1 -1
- package/project/.sdk/tm/go/Makefile +36 -1
- package/project/.sdk/tm/go/VERSION +1 -0
- package/project/.sdk/tm/go/core/context.go +12 -7
- package/project/.sdk/tm/go-cli/src/feature/README.md +6 -0
- package/project/.sdk/tm/go-cli/src/feature/base/.gitkeep +0 -0
- package/project/.sdk/tm/go-cli/src/feature/log/.gitkeep +0 -0
- package/project/.sdk/tm/go-cli/src/feature/test/.gitkeep +0 -0
- package/project/.sdk/tm/go-mcp/src/feature/README.md +6 -0
- package/project/.sdk/tm/go-mcp/src/feature/base/.gitkeep +0 -0
- package/project/.sdk/tm/go-mcp/src/feature/log/.gitkeep +0 -0
- package/project/.sdk/tm/go-mcp/src/feature/test/.gitkeep +0 -0
- package/project/.sdk/tm/js/LICENSE +1 -1
- package/project/.sdk/tm/js/Makefile +41 -0
- package/project/.sdk/tm/lua/LICENSE +1 -1
- package/project/.sdk/tm/lua/Makefile +40 -1
- package/project/.sdk/tm/lua/core/context.lua +13 -8
- package/project/.sdk/tm/php/LICENSE +1 -1
- package/project/.sdk/tm/php/Makefile +31 -1
- package/project/.sdk/tm/php/VERSION +1 -0
- package/project/.sdk/tm/php/core/Context.php +12 -6
- package/project/.sdk/tm/php/test/PrimaryUtilityTest.php +13 -4
- package/project/.sdk/tm/php/utility/Done.php +2 -2
- package/project/.sdk/tm/php/utility/MakeError.php +3 -3
- package/project/.sdk/tm/py/LICENSE +1 -1
- package/project/.sdk/tm/py/Makefile +34 -1
- package/project/.sdk/tm/py/core/context.py +12 -7
- package/project/.sdk/tm/py/test/test_primary_utility.py +15 -4
- package/project/.sdk/tm/py/utility/done.py +3 -1
- package/project/.sdk/tm/py/utility/make_error.py +2 -2
- package/project/.sdk/tm/rb/LICENSE +1 -1
- package/project/.sdk/tm/rb/Makefile +33 -1
- package/project/.sdk/tm/rb/core/context.rb +8 -3
- package/project/.sdk/tm/rb/test/primary_utility_test.rb +2 -2
- package/project/.sdk/tm/rb/utility/done.rb +3 -1
- package/project/.sdk/tm/rb/utility/make_error.rb +5 -2
- package/project/.sdk/tm/ts/LICENSE +1 -1
- package/project/.sdk/tm/ts/Makefile +42 -0
- package/project/.sdk/tm/ts/src/Context.ts +8 -3
- package/src/action/action.ts +17 -10
- package/src/action/feature.ts +8 -6
- package/src/action/target.ts +17 -8
- package/src/cmp/Changelog.ts +34 -0
- package/src/cmp/Deploy.ts +258 -0
- package/src/cmp/FeatureHook.ts +6 -8
- package/src/cmp/License.ts +49 -0
- package/src/cmp/Readme.ts +2 -0
- package/src/cmp/ReadmeErrors.ts +257 -0
- package/src/cmp/ReadmeExplanation.ts +250 -230
- package/src/cmp/ReadmeModel.ts +7 -2
- package/src/cmp/ReadmeTop.ts +411 -95
- package/src/cmp/Security.ts +41 -0
- package/src/helpers/canonType.ts +89 -0
- package/src/helpers/collectDeps.ts +5 -3
- package/src/helpers/naming.ts +59 -0
- package/src/helpers/opExample.ts +170 -0
- package/src/helpers/opShape.ts +236 -0
- package/src/helpers/packageMeta.ts +236 -0
- package/src/sdkgen.ts +87 -20
- package/src/tsconfig.json +1 -0
- package/src/types.ts +85 -2
- package/src/utility.ts +22 -11
- package/README.md +0 -2
- package/dist/action/lang.d.ts +0 -2
- package/dist/action/lang.js +0 -68
- package/dist/action/lang.js.map +0 -1
- package/dist/cmp/Hook.d.ts +0 -2
- package/dist/cmp/Hook.js +0 -10
- package/dist/cmp/Hook.js.map +0 -1
- package/dist/cmp/Top.d.ts +0 -2
- package/dist/cmp/Top.js +0 -23
- package/dist/cmp/Top.js.map +0 -1
- package/dist/prepare-openapi.d.ts +0 -2
- package/dist/prepare-openapi.js +0 -37
- package/dist/prepare-openapi.js.map +0 -1
- package/model/sdkgen.jsonic +0 -74
- package/project/.sdk/tm/go/utility/struct/go.mod +0 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { cmp, each, Content } from '@voxgig/sdkgen'
|
|
2
|
+
import { cmp, each, Content, canonToType, canonKey, entityIdField } from '@voxgig/sdkgen'
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
KIT,
|
|
@@ -7,6 +7,18 @@ import {
|
|
|
7
7
|
} from '@voxgig/apidef'
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
// A type-correct Ruby literal for a field's canonical type — the create body
|
|
11
|
+
// is EXECUTED by the doc test, so it must carry a real value per field.
|
|
12
|
+
function rbLit(type: any): string {
|
|
13
|
+
const k = canonKey(type)
|
|
14
|
+
if ('INTEGER' === k || 'NUMBER' === k) return '1'
|
|
15
|
+
if ('BOOLEAN' === k) return 'true'
|
|
16
|
+
if ('ARRAY' === k) return '[]'
|
|
17
|
+
if ('OBJECT' === k) return '{}'
|
|
18
|
+
return '"example"'
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
10
22
|
// Operation method spelling differs between Go and other languages — Go
|
|
11
23
|
// uses PascalCase methods with explicit ctrl arg, others use lowercase
|
|
12
24
|
// methods with optional ctrl. The op descriptions are language-agnostic.
|
|
@@ -41,6 +53,8 @@ const ReadmeEntity = cmp(function ReadmeEntity(props: any) {
|
|
|
41
53
|
publishedEntities.map((entity: any) => {
|
|
42
54
|
const opnames = Object.keys(entity.op || {})
|
|
43
55
|
const fields = entity.fields || []
|
|
56
|
+
// Model-driven id key: null when this entity has no id-like field.
|
|
57
|
+
const idF = entityIdField(entity)
|
|
44
58
|
|
|
45
59
|
Content(`
|
|
46
60
|
### ${entity.Name}
|
|
@@ -53,7 +67,7 @@ const ReadmeEntity = cmp(function ReadmeEntity(props: any) {
|
|
|
53
67
|
`)
|
|
54
68
|
}
|
|
55
69
|
|
|
56
|
-
Content(`Create an instance:
|
|
70
|
+
Content(`Create an instance: \`${entity.name} = client.${entity.Name}\`
|
|
57
71
|
|
|
58
72
|
`)
|
|
59
73
|
|
|
@@ -84,7 +98,7 @@ const ReadmeEntity = cmp(function ReadmeEntity(props: any) {
|
|
|
84
98
|
|
|
85
99
|
each(fields, (field: any) => {
|
|
86
100
|
const desc = field.short || ''
|
|
87
|
-
Content(`| \`${field.name}\` | \`${field.type
|
|
101
|
+
Content(`| \`${field.name}\` | \`${canonToType(field.type, target.name)}\` | ${desc} |
|
|
88
102
|
`)
|
|
89
103
|
})
|
|
90
104
|
|
|
@@ -95,8 +109,9 @@ const ReadmeEntity = cmp(function ReadmeEntity(props: any) {
|
|
|
95
109
|
if (opnames.includes('load')) {
|
|
96
110
|
Content(`#### Example: Load
|
|
97
111
|
|
|
98
|
-
\`\`\`
|
|
99
|
-
|
|
112
|
+
\`\`\`ruby
|
|
113
|
+
# load returns the bare ${entity.Name} record (raises on error).
|
|
114
|
+
${entity.name} = client.${entity.Name}.load(${idF ? `{ "${idF}" => "${entity.name}_id" }` : ''})
|
|
100
115
|
\`\`\`
|
|
101
116
|
|
|
102
117
|
`)
|
|
@@ -105,8 +120,9 @@ const ${entity.name} = await client.${entity.Name}().load({ id: '${entity.name}_
|
|
|
105
120
|
if (opnames.includes('list')) {
|
|
106
121
|
Content(`#### Example: List
|
|
107
122
|
|
|
108
|
-
\`\`\`
|
|
109
|
-
|
|
123
|
+
\`\`\`ruby
|
|
124
|
+
# list returns an Array of ${entity.Name} records (raises on error).
|
|
125
|
+
${entity.name}s = client.${entity.Name}.list
|
|
110
126
|
\`\`\`
|
|
111
127
|
|
|
112
128
|
`)
|
|
@@ -115,12 +131,12 @@ const ${entity.name}s = await client.${entity.Name}().list()
|
|
|
115
131
|
if (opnames.includes('create')) {
|
|
116
132
|
Content(`#### Example: Create
|
|
117
133
|
|
|
118
|
-
\`\`\`
|
|
119
|
-
|
|
134
|
+
\`\`\`ruby
|
|
135
|
+
${entity.name} = client.${entity.Name}.create({
|
|
120
136
|
`)
|
|
121
137
|
each(fields, (field: any) => {
|
|
122
138
|
if ('id' !== field.name && field.req) {
|
|
123
|
-
Content(` ${field.name}
|
|
139
|
+
Content(` "${field.name}" => ${rbLit(field.type)}, # ${canonToType(field.type, target.name)}
|
|
124
140
|
`)
|
|
125
141
|
}
|
|
126
142
|
})
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
|
|
2
|
+
import { cmp, File, Content } from '@voxgig/sdkgen'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
KIT,
|
|
6
|
+
getModelPath,
|
|
7
|
+
} from '@voxgig/apidef'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
// Emits test/readme_examples_test.rb — a Minitest COMPLETENESS GATE that
|
|
11
|
+
// guarantees every fenced ruby code example in the package docs is unit-tested.
|
|
12
|
+
// It reads ALL THREE docs — the root (multi-language) ../../README.md, the
|
|
13
|
+
// Ruby-specific ../README.md, and ../REFERENCE.md — extracts every fenced ruby
|
|
14
|
+
// block (tagged by source doc + index) and enforces four properties:
|
|
15
|
+
//
|
|
16
|
+
// 1. SYNTAX — `ruby -c` on every block. Every documented example must parse.
|
|
17
|
+
// 2. RUN — every RUNNABLE block (one that constructs the SDK, drives
|
|
18
|
+
// client., or performs an entity op) is EXECUTED offline in seeded test
|
|
19
|
+
// mode against the real SDK. The captured stdout+stderr is scanned for
|
|
20
|
+
// FATAL programming-error markers REGARDLESS of exit code, so a bug that a
|
|
21
|
+
// documented begin/rescue swallows and prints is still caught. Only a
|
|
22
|
+
// not-found / domain error is tolerated.
|
|
23
|
+
// 3. COMPLETENESS — every block is partitioned into exactly one of
|
|
24
|
+
// {executed, syntaxchecked-nonrunnable, illustration} and the counts must
|
|
25
|
+
// sum to the total. "illustration" is a NARROW explicit class (a
|
|
26
|
+
// signature / method-table block that names the SDK class or a documented
|
|
27
|
+
// method but never uses a live client) — never a catch-all. A
|
|
28
|
+
// runnable-looking block that was NOT executed lands in neither bucket and
|
|
29
|
+
// FAILS the gate: no runnable example can be silently skipped.
|
|
30
|
+
// 4. A per-doc summary (total / executed / syntaxchecked / illustration) is
|
|
31
|
+
// printed.
|
|
32
|
+
//
|
|
33
|
+
// A runnable block is rewritten so its client is a test-mode client
|
|
34
|
+
// (<Sdk>SDK.test) seeded with an in-memory fixture for every entity it
|
|
35
|
+
// references; any real .new/.test constructor is rewritten and the doc's own
|
|
36
|
+
// require of the SDK file is stripped (we require it by absolute path). A block
|
|
37
|
+
// that only *uses* `client` (constructed in an earlier fenced block) gets a
|
|
38
|
+
// test client prepended.
|
|
39
|
+
//
|
|
40
|
+
// The emitted Ruby builds the ``` fence via 96.chr and shells out via Open3,
|
|
41
|
+
// so this generator string contains no backticks of its own.
|
|
42
|
+
const ReadmeExamplesTest = cmp(function ReadmeExamplesTest(props: any) {
|
|
43
|
+
const { target } = props
|
|
44
|
+
const { model } = props.ctx$
|
|
45
|
+
|
|
46
|
+
const sdkbase = model.const.Name + '_sdk'
|
|
47
|
+
const sdkfile = sdkbase + '.rb'
|
|
48
|
+
|
|
49
|
+
// Entity accessor (client.<Name>) => fixture storage key (lowercase name),
|
|
50
|
+
// derived from the model so fixtures seed under the key the mock expects.
|
|
51
|
+
const entity = getModelPath(model, `main.${KIT}.entity`) || {}
|
|
52
|
+
const entityLines = Object.values(entity)
|
|
53
|
+
.filter((e: any) => e && e.active !== false)
|
|
54
|
+
.map((e: any) => ` ${JSON.stringify(e.Name)} => ${JSON.stringify(e.name)},`)
|
|
55
|
+
.join('\n')
|
|
56
|
+
|
|
57
|
+
File({ name: 'readme_examples_test.' + target.ext }, () => {
|
|
58
|
+
Content(`# ${model.const.Name} SDK — documentation example COMPLETENESS GATE.
|
|
59
|
+
#
|
|
60
|
+
# Guarantees every fenced ruby code example across ALL THREE package docs is
|
|
61
|
+
# unit-tested. Reads the root ../../README.md, the Ruby ../README.md, and
|
|
62
|
+
# ../REFERENCE.md, extracts every fenced ruby block (tagged by source doc +
|
|
63
|
+
# index) and enforces:
|
|
64
|
+
#
|
|
65
|
+
# 1. SYNTAX — 'ruby -c' on every block. Every documented ruby example must
|
|
66
|
+
# parse.
|
|
67
|
+
# 2. RUN — every RUNNABLE block (one that constructs the SDK, drives client.,
|
|
68
|
+
# or performs an entity op load/list/create/update/remove) is EXECUTED
|
|
69
|
+
# offline in seeded test mode (${model.const.Name}SDK.test) against the real
|
|
70
|
+
# SDK. The captured output is scanned for a real Ruby-level error (undefined
|
|
71
|
+
# method, wrong number of arguments, NameError, ...) REGARDLESS of exit
|
|
72
|
+
# code, so a bug a documented begin/rescue swallows and prints cannot slip
|
|
73
|
+
# through. Expected not-found domain errors are tolerated.
|
|
74
|
+
# 3. COMPLETENESS — every block is partitioned into exactly one of
|
|
75
|
+
# {executed, syntaxchecked-nonrunnable, illustration}; the counts must sum
|
|
76
|
+
# to the total. A runnable-looking block that was not executed belongs to
|
|
77
|
+
# no bucket and FAILS the gate.
|
|
78
|
+
#
|
|
79
|
+
# Ruby is dynamically typed, so syntax + actually running every example is the
|
|
80
|
+
# strongest check available without a live server.
|
|
81
|
+
|
|
82
|
+
require "minitest/autorun"
|
|
83
|
+
require "tempfile"
|
|
84
|
+
require "open3"
|
|
85
|
+
|
|
86
|
+
class ReadmeExamplesTest < Minitest::Test
|
|
87
|
+
# The three documentation sources this gate covers.
|
|
88
|
+
DOCS = {
|
|
89
|
+
"root README" => File.join(__dir__, "..", "..", "README.md"),
|
|
90
|
+
"rb README" => File.join(__dir__, "..", "README.md"),
|
|
91
|
+
"rb REFERENCE" => File.join(__dir__, "..", "REFERENCE.md"),
|
|
92
|
+
}
|
|
93
|
+
SDK = File.join(__dir__, "..", "${sdkfile}")
|
|
94
|
+
SDK_CLASS = "${model.const.Name}SDK"
|
|
95
|
+
|
|
96
|
+
# SDK file basename (no extension) — used to strip the doc's own require of the
|
|
97
|
+
# SDK file from a runnable block (we require it by absolute path).
|
|
98
|
+
SDK_BASE = "${sdkbase}"
|
|
99
|
+
|
|
100
|
+
# Entity accessor (client.<Name>) => fixture storage key (lowercase name).
|
|
101
|
+
ENTITIES = {
|
|
102
|
+
${entityLines}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
# Documented SDK method names — used only to recognise the NARROW
|
|
106
|
+
# signature/method-table "illustration" class.
|
|
107
|
+
METHODS = %w[options_map get_utility prepare direct data_get data_set match_get match_set make get_name]
|
|
108
|
+
|
|
109
|
+
# Ruby-level errors that indicate a real bug in a documented example (as
|
|
110
|
+
# opposed to an expected not-found / domain error, which is tolerated).
|
|
111
|
+
FATAL = /NoMethodError|NameError|ArgumentError|undefined method|undefined local variable|uninitialized constant|wrong number of arguments/
|
|
112
|
+
|
|
113
|
+
# Extract every fenced ruby block from all three docs, each tagged with its
|
|
114
|
+
# source doc label and its index within that doc.
|
|
115
|
+
def ruby_blocks
|
|
116
|
+
fence = (96.chr) * 3
|
|
117
|
+
blocks = []
|
|
118
|
+
DOCS.each do |label, path|
|
|
119
|
+
assert File.exist?(path), "missing documentation source: #{label}"
|
|
120
|
+
File.read(path).scan(/#{fence}ruby\\r?\\n(.*?)#{fence}/m).each_with_index do |a, i|
|
|
121
|
+
blocks << { doc: label, n: i, code: a[0] }
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
blocks
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# --- classification -------------------------------------------------------
|
|
128
|
+
|
|
129
|
+
# A block is RUNNABLE when it constructs the SDK, drives client., or performs
|
|
130
|
+
# an entity operation. Every runnable block MUST be executed.
|
|
131
|
+
def runnable?(b)
|
|
132
|
+
b =~ /#{Regexp.escape(SDK_CLASS)}\\.(?:new|test)\\b/ ||
|
|
133
|
+
b =~ /\\bclient\\./ ||
|
|
134
|
+
b =~ /\\.(?:load|list|create|update|remove)\\b/ ? true : false
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# A block "mentions the SDK" when it references the client variable, the SDK
|
|
138
|
+
# class, an entity accessor, or an entity operation. A non-runnable block that
|
|
139
|
+
# mentions the SDK but is not a signature illustration is an uncovered
|
|
140
|
+
# runnable-looking block and must fail the completeness gate.
|
|
141
|
+
def looks_sdk?(b)
|
|
142
|
+
return true if b =~ /\\bclient\\b/
|
|
143
|
+
return true if b =~ /\\b#{Regexp.escape(SDK_CLASS)}\\b/
|
|
144
|
+
return true if b =~ /\\.(?:load|list|create|update|remove)\\b/
|
|
145
|
+
ENTITIES.each_key { |name| return true if b =~ /\\.#{Regexp.escape(name)}\\b/ }
|
|
146
|
+
false
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# NARROW illustration class: a non-runnable block that references the SDK class
|
|
150
|
+
# or a documented method NAME as a signature / method-table, and never uses a
|
|
151
|
+
# live client variable. This is an explicit, restricted class — not a
|
|
152
|
+
# catch-all — so an unexecuted block that uses a client variable cannot hide here.
|
|
153
|
+
def illustration?(b)
|
|
154
|
+
return false if runnable?(b)
|
|
155
|
+
return false if b =~ /\\bclient\\b/
|
|
156
|
+
return true if b =~ /\\b#{Regexp.escape(SDK_CLASS)}\\b/
|
|
157
|
+
METHODS.each { |m| return true if b =~ /\\b#{Regexp.escape(m)}\\s*\\(/ }
|
|
158
|
+
false
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Partition label for a block: exactly one of the four.
|
|
162
|
+
def classify(b)
|
|
163
|
+
return "executed" if runnable?(b)
|
|
164
|
+
return "illustration" if illustration?(b)
|
|
165
|
+
return "syntaxchecked_nonrunnable" unless looks_sdk?(b)
|
|
166
|
+
"unclassified"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# --- tests ----------------------------------------------------------------
|
|
170
|
+
|
|
171
|
+
def test_docs_have_ruby_examples
|
|
172
|
+
refute_empty ruby_blocks, "docs should contain ruby examples"
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Every ruby block across all three docs must parse (ruby -c).
|
|
176
|
+
def test_ruby_snippets_have_valid_syntax
|
|
177
|
+
failures = []
|
|
178
|
+
ruby_blocks.each do |blk|
|
|
179
|
+
Tempfile.create(["readme_rb_", ".rb"]) do |f|
|
|
180
|
+
f.write(blk[:code])
|
|
181
|
+
f.flush
|
|
182
|
+
out, status = Open3.capture2e("ruby", "-c", f.path)
|
|
183
|
+
failures << "#{blk[:doc]} ##{blk[:n]}:\\n#{out}\\n#{blk[:code]}" unless status.success?
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
assert_equal [], failures, "docs ruby blocks with syntax errors:\\n#{failures.join("\\n\\n")}"
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Build the SDK 'entity' fixture option (as Ruby source) for the entities a
|
|
190
|
+
# block references, falling back to seeding all entities when none are named.
|
|
191
|
+
def fixtures_literal(block)
|
|
192
|
+
refs = ENTITIES.select { |name, _| block =~ /\\bclient\\.#{Regexp.escape(name)}\\b/ }
|
|
193
|
+
refs = ENTITIES if refs.empty?
|
|
194
|
+
entity = {}
|
|
195
|
+
refs.each_value { |storage| entity[storage] = { "test01" => { "id" => "test01" } } }
|
|
196
|
+
{ "entity" => entity }.inspect
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Rewrite a runnable block into an executable offline test-mode program: the
|
|
200
|
+
# doc's own require of the SDK file is stripped (we require it by absolute
|
|
201
|
+
# path); any real client constructor (.new/.test) becomes <Sdk>SDK.test(<fixtures>);
|
|
202
|
+
# a block that only uses a client variable gets such a constructor prepended. (The
|
|
203
|
+
# constructor arg-list match is deliberately shallow — it does not span nested
|
|
204
|
+
# parens — because runnable op blocks never build a client inline with a
|
|
205
|
+
# lambda/closure argument.)
|
|
206
|
+
def to_runner(block)
|
|
207
|
+
fixtures = fixtures_literal(block)
|
|
208
|
+
# Drop the doc's own require of the SDK file; we require it by absolute path.
|
|
209
|
+
block = block.gsub(/^[ \\t]*require(?:_relative|_once)?[^\\n]*#{Regexp.escape(SDK_BASE)}[^\\n]*\\r?\\n?/i, "")
|
|
210
|
+
ctor_re = /#{Regexp.escape(SDK_CLASS)}\\.(?:new|test)(?:\\([^()]*\\))?/
|
|
211
|
+
body =
|
|
212
|
+
if block =~ /#{Regexp.escape(SDK_CLASS)}\\.(?:new|test)\\b/
|
|
213
|
+
block.gsub(ctor_re) { "#{SDK_CLASS}.test(#{fixtures})" }
|
|
214
|
+
else
|
|
215
|
+
"client = #{SDK_CLASS}.test(#{fixtures})\\n" + block
|
|
216
|
+
end
|
|
217
|
+
"require_relative #{SDK.inspect}\\n" + body
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# Every RUNNABLE block is executed offline in test mode and must not raise a
|
|
221
|
+
# real Ruby-level error — even one an error-handling example swallows in a
|
|
222
|
+
# rescue and prints: the captured output is scanned for FATAL either way, so a
|
|
223
|
+
# programming error in a documented begin/rescue cannot slip through. Expected
|
|
224
|
+
# domain errors (e.g. "404: Not found") never match FATAL, so caught not-found
|
|
225
|
+
# cases stay tolerated.
|
|
226
|
+
def test_ruby_examples_run_offline
|
|
227
|
+
ran = 0
|
|
228
|
+
failures = []
|
|
229
|
+
ruby_blocks.each do |blk|
|
|
230
|
+
next unless runnable?(blk[:code])
|
|
231
|
+
ran += 1
|
|
232
|
+
Tempfile.create(["readme_run_", ".rb"]) do |f|
|
|
233
|
+
f.write(to_runner(blk[:code]))
|
|
234
|
+
f.flush
|
|
235
|
+
out, status = Open3.capture2e("ruby", f.path)
|
|
236
|
+
if out =~ FATAL
|
|
237
|
+
failures << "#{blk[:doc]} ##{blk[:n]} (exit #{status.exitstatus}):\\n#{out}\\n#{blk[:code]}"
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
assert_operator ran, :>, 0, "expected at least one runnable example to execute"
|
|
242
|
+
assert_equal [], failures, "docs ruby examples raised a real error when run offline:\\n#{failures.join("\\n\\n")}"
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# COMPLETENESS GATE: every fenced ruby block is partitioned into exactly one of
|
|
246
|
+
# {executed, syntaxchecked-nonrunnable, illustration}. The three counts must
|
|
247
|
+
# sum to the total. A block that references the SDK but is neither runnable (so
|
|
248
|
+
# not executed) nor a narrow signature illustration is "unclassified" — a
|
|
249
|
+
# runnable-looking example that would be silently skipped — and fails the gate.
|
|
250
|
+
def test_ruby_examples_are_completely_classified
|
|
251
|
+
blocks = ruby_blocks
|
|
252
|
+
buckets = { "executed" => [], "syntaxchecked_nonrunnable" => [], "illustration" => [], "unclassified" => [] }
|
|
253
|
+
per_doc = {}
|
|
254
|
+
blocks.each do |blk|
|
|
255
|
+
cls = classify(blk[:code])
|
|
256
|
+
buckets[cls] << blk
|
|
257
|
+
d = (per_doc[blk[:doc]] ||= { "total" => 0, "executed" => 0, "syntaxchecked_nonrunnable" => 0, "illustration" => 0, "unclassified" => 0 })
|
|
258
|
+
d["total"] += 1
|
|
259
|
+
d[cls] += 1
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
summary = "ReadmeExamplesTest — ruby example coverage:\\n"
|
|
263
|
+
per_doc.each do |doc, c|
|
|
264
|
+
extra = c["unclassified"] > 0 ? " UNCLASSIFIED=#{c["unclassified"]}" : ""
|
|
265
|
+
summary += format(" %-14s total=%d executed=%d syntaxchecked=%d illustration=%d%s\\n",
|
|
266
|
+
doc, c["total"], c["executed"], c["syntaxchecked_nonrunnable"], c["illustration"], extra)
|
|
267
|
+
end
|
|
268
|
+
warn "\\n" + summary
|
|
269
|
+
|
|
270
|
+
unclassified = buckets["unclassified"].map { |b| "#{b[:doc]} ##{b[:n]}:\\n#{b[:code]}" }
|
|
271
|
+
assert_equal [], unclassified,
|
|
272
|
+
"runnable-looking ruby blocks that were neither executed nor a signature illustration:\\n#{unclassified.join("\\n\\n")}"
|
|
273
|
+
|
|
274
|
+
total = blocks.length
|
|
275
|
+
sum = buckets["executed"].length + buckets["syntaxchecked_nonrunnable"].length + buckets["illustration"].length
|
|
276
|
+
assert_equal total, sum,
|
|
277
|
+
"every ruby block must be executed, syntaxchecked-nonrunnable, or illustration.\\n#{summary}"
|
|
278
|
+
|
|
279
|
+
assert_operator buckets["executed"].length, :>, 0, "expected at least one executed ruby example"
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
`)
|
|
283
|
+
})
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
export {
|
|
288
|
+
ReadmeExamplesTest
|
|
289
|
+
}
|
|
@@ -1,12 +1,59 @@
|
|
|
1
1
|
|
|
2
|
-
import { cmp, Content, isAuthActive } from '@voxgig/sdkgen'
|
|
2
|
+
import { cmp, Content, isAuthActive, envName, canonKey, entityIdField, entityPrimaryOp, opRequestShape } from '@voxgig/sdkgen'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
KIT,
|
|
6
|
+
getModelPath,
|
|
7
|
+
nom,
|
|
8
|
+
} from '@voxgig/apidef'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
// A type-correct Ruby literal for a field's canonical type.
|
|
12
|
+
function rbLit(type: any): string {
|
|
13
|
+
const k = canonKey(type)
|
|
14
|
+
if ('INTEGER' === k || 'NUMBER' === k) return '1'
|
|
15
|
+
if ('BOOLEAN' === k) return 'true'
|
|
16
|
+
if ('ARRAY' === k) return '[]'
|
|
17
|
+
if ('OBJECT' === k) return '{}'
|
|
18
|
+
return '"example"'
|
|
19
|
+
}
|
|
3
20
|
|
|
4
21
|
|
|
5
22
|
const ReadmeHowto = cmp(function ReadmeHowto(props: any) {
|
|
6
23
|
const { target, ctx$: { model } } = props
|
|
7
24
|
|
|
25
|
+
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
26
|
+
const exampleEntity = Object.values(entity || {}).find((e: any) => e && e.active !== false) as any
|
|
27
|
+
const eName = exampleEntity ? nom(exampleEntity, 'Name') : 'Entity'
|
|
28
|
+
// Model-driven id key: null when the entity has no id-like field (a
|
|
29
|
+
// response-wrapped spec). When null the fixture seeds no id and a match op
|
|
30
|
+
// takes no argument.
|
|
31
|
+
const idF = exampleEntity ? entityIdField(exampleEntity) : null
|
|
32
|
+
// Drive the test-mode example off the entity's PRIMARY op — an op it actually
|
|
33
|
+
// exposes — never a hardcoded `load` a create-only entity lacks.
|
|
34
|
+
const primaryOp = exampleEntity ? (entityPrimaryOp(exampleEntity) || 'load') : 'load'
|
|
35
|
+
const isMatchOp = 'load' === primaryOp || 'remove' === primaryOp
|
|
36
|
+
const seedSentence = idF
|
|
37
|
+
? '. Seed fixture\ndata via the `entity` option so offline calls resolve without a live server'
|
|
38
|
+
: ''
|
|
39
|
+
const testCtor = idF
|
|
40
|
+
? `${model.const.Name}SDK.test({\n "entity" => { "${eName.toLowerCase()}" => { "test01" => { "${idF}" => "test01" } } },\n})`
|
|
41
|
+
: `${model.const.Name}SDK.test`
|
|
42
|
+
// A type-correct argument for the primary-op call: a match hash for load/
|
|
43
|
+
// remove, a required-field body for create/update, nothing for list.
|
|
44
|
+
let testCallArg = ''
|
|
45
|
+
if (exampleEntity && isMatchOp) {
|
|
46
|
+
testCallArg = idF ? `{ "${idF}" => "test01" }` : ''
|
|
47
|
+
} else if (exampleEntity && ('create' === primaryOp || 'update' === primaryOp)) {
|
|
48
|
+
const items = opRequestShape(exampleEntity, primaryOp).items
|
|
49
|
+
.filter((it: any) => it.name !== idF && it.name !== 'id')
|
|
50
|
+
const required = items.filter((it: any) => !it.optional)
|
|
51
|
+
const chosen = required.length ? required : items.slice(0, 3)
|
|
52
|
+
testCallArg = `{ ${chosen.map((it: any) => `"${it.name}" => ${rbLit(it.type)}`).join(', ')} }`
|
|
53
|
+
}
|
|
54
|
+
|
|
8
55
|
const apikeyEnvLine = isAuthActive(model)
|
|
9
|
-
? `\n${model
|
|
56
|
+
? `\n${envName(model)}_APIKEY=<your-key>`
|
|
10
57
|
: ''
|
|
11
58
|
|
|
12
59
|
Content(`### Make a direct HTTP request
|
|
@@ -14,45 +61,49 @@ const ReadmeHowto = cmp(function ReadmeHowto(props: any) {
|
|
|
14
61
|
For endpoints not covered by entity methods:
|
|
15
62
|
|
|
16
63
|
\`\`\`ruby
|
|
17
|
-
result
|
|
64
|
+
result = client.direct({
|
|
18
65
|
"path" => "/api/resource/{id}",
|
|
19
66
|
"method" => "GET",
|
|
20
67
|
"params" => { "id" => "example" },
|
|
21
68
|
})
|
|
22
|
-
raise err if err
|
|
23
69
|
|
|
24
70
|
if result["ok"]
|
|
25
71
|
puts result["status"] # 200
|
|
26
72
|
puts result["data"] # response body
|
|
73
|
+
else
|
|
74
|
+
# On an HTTP error status there is no err (only a transport failure sets
|
|
75
|
+
# it), so fall back to the status code.
|
|
76
|
+
warn(result["err"] || "HTTP #{result["status"]}")
|
|
27
77
|
end
|
|
28
78
|
\`\`\`
|
|
29
79
|
|
|
30
80
|
### Prepare a request without sending it
|
|
31
81
|
|
|
32
82
|
\`\`\`ruby
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
puts fetchdef["
|
|
41
|
-
puts fetchdef["
|
|
42
|
-
|
|
83
|
+
begin
|
|
84
|
+
fetchdef = client.prepare({
|
|
85
|
+
"path" => "/api/resource/{id}",
|
|
86
|
+
"method" => "DELETE",
|
|
87
|
+
"params" => { "id" => "example" },
|
|
88
|
+
})
|
|
89
|
+
puts fetchdef["url"]
|
|
90
|
+
puts fetchdef["method"]
|
|
91
|
+
puts fetchdef["headers"]
|
|
92
|
+
rescue => err
|
|
93
|
+
warn "prepare failed: #{err}"
|
|
94
|
+
end
|
|
43
95
|
\`\`\`
|
|
44
96
|
|
|
45
97
|
### Use test mode
|
|
46
98
|
|
|
47
|
-
Create a mock client for unit testing — no server required:
|
|
99
|
+
Create a mock client for unit testing — no server required${seedSentence}:
|
|
48
100
|
|
|
49
101
|
\`\`\`ruby
|
|
50
|
-
client = ${
|
|
102
|
+
client = ${testCtor}
|
|
51
103
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
)
|
|
55
|
-
# result contains mock response data
|
|
104
|
+
# Entity ops return the bare mock record (raises on error).
|
|
105
|
+
${eName.toLowerCase()} = client.${eName}.${primaryOp}(${testCallArg})
|
|
106
|
+
puts ${eName.toLowerCase()}
|
|
56
107
|
\`\`\`
|
|
57
108
|
|
|
58
109
|
### Use a custom fetch function
|
|
@@ -82,7 +133,7 @@ client = ${model.const.Name}SDK.new({
|
|
|
82
133
|
Create a \`.env.local\` file at the project root:
|
|
83
134
|
|
|
84
135
|
\`\`\`
|
|
85
|
-
${model
|
|
136
|
+
${envName(model)}_TEST_LIVE=TRUE${apikeyEnvLine}
|
|
86
137
|
\`\`\`
|
|
87
138
|
|
|
88
139
|
Then run:
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
|
|
2
|
-
import { cmp, Content } from '@voxgig/sdkgen'
|
|
2
|
+
import { cmp, Content, installCommand, isPublished, packageName, repoInfo } from '@voxgig/sdkgen'
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
const ReadmeInstall = cmp(function ReadmeInstall(props: any) {
|
|
6
6
|
const { target, ctx$ } = props
|
|
7
7
|
const { model } = ctx$
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
if (isPublished(model, target.name)) {
|
|
10
|
+
Content(`\`\`\`bash
|
|
11
|
+
${installCommand(model, target.name)}
|
|
11
12
|
\`\`\`
|
|
12
13
|
|
|
13
14
|
Or add to your \`Gemfile\`:
|
|
14
15
|
|
|
15
16
|
\`\`\`ruby
|
|
16
|
-
gem "${model
|
|
17
|
+
gem "${packageName(model, 'gem')}"
|
|
17
18
|
\`\`\`
|
|
18
19
|
|
|
19
20
|
Then run:
|
|
@@ -22,6 +23,17 @@ Then run:
|
|
|
22
23
|
bundle install
|
|
23
24
|
\`\`\`
|
|
24
25
|
|
|
26
|
+
`)
|
|
27
|
+
return
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Publish pending: not yet on RubyGems. Install from the git release tag.
|
|
31
|
+
const { releasesUrl } = repoInfo(model)
|
|
32
|
+
Content(`This package is not yet published to RubyGems. Install it from the
|
|
33
|
+
GitHub release tag (\`${target.name}/vX.Y.Z\`):
|
|
34
|
+
|
|
35
|
+
- Releases: [${releasesUrl}](${releasesUrl})
|
|
36
|
+
|
|
25
37
|
`)
|
|
26
38
|
})
|
|
27
39
|
|
|
@@ -1,13 +1,52 @@
|
|
|
1
1
|
|
|
2
2
|
import { cmp, Content } from '@voxgig/sdkgen'
|
|
3
3
|
|
|
4
|
+
import {
|
|
5
|
+
KIT,
|
|
6
|
+
getModelPath,
|
|
7
|
+
nom,
|
|
8
|
+
} from '@voxgig/apidef'
|
|
9
|
+
|
|
4
10
|
|
|
5
11
|
const ReadmeIntro = cmp(function ReadmeIntro(props: any) {
|
|
6
12
|
const { target, ctx$: { model } } = props
|
|
13
|
+
const info = (model.main && model.main.kit && model.main.kit.info) || {}
|
|
14
|
+
const tagline = info.tagline || ''
|
|
15
|
+
|
|
16
|
+
// Derive a representative entity (and its operations) from the model so the
|
|
17
|
+
// semantic-entity pitch names something real rather than a placeholder.
|
|
18
|
+
const entity = getModelPath(model, `main.${KIT}.entity`) || {}
|
|
19
|
+
const exampleEntity = Object.values(entity).find((e: any) => e && e.active !== false) as any
|
|
20
|
+
const eName = exampleEntity ? nom(exampleEntity, 'Name') : null
|
|
21
|
+
// Model-driven op list — union of the operations the active entities
|
|
22
|
+
// actually expose (a read-only entity has just list+load), in canonical
|
|
23
|
+
// order; never claim create/update/remove exist when no entity has them.
|
|
24
|
+
const CANON_OPS = ['list', 'load', 'create', 'update', 'remove']
|
|
25
|
+
const opSet = new Set<string>()
|
|
26
|
+
Object.values(entity || {}).forEach((e: any) => {
|
|
27
|
+
if (!e || e.active === false) return
|
|
28
|
+
Object.keys(e.op || {}).forEach((o: string) => {
|
|
29
|
+
if (e.op[o] && e.op[o].active !== false) opSet.add(o)
|
|
30
|
+
})
|
|
31
|
+
})
|
|
32
|
+
const opnames = CANON_OPS.filter((o) => opSet.has(o))
|
|
33
|
+
.concat([...opSet].filter((o) => !CANON_OPS.includes(o)))
|
|
34
|
+
const opList = (opnames.length > 0 ? opnames : ['list', 'load']).join('`/`')
|
|
35
|
+
|
|
36
|
+
const semantic = eName
|
|
37
|
+
? `The SDK exposes the API as capitalised, semantic **Entities** — for example \`client.${eName}\` — with named operations (\`${opList}\`) instead of raw URL paths and query strings. Working with resources and verbs keeps call sites self-describing and reduces cognitive load.
|
|
38
|
+
|
|
39
|
+
`
|
|
40
|
+
: ''
|
|
7
41
|
|
|
8
42
|
Content(`# ${model.Name} ${target.title} SDK
|
|
9
43
|
|
|
10
|
-
|
|
44
|
+
${tagline}
|
|
45
|
+
|
|
46
|
+
The ${target.title} SDK for the ${model.Name} API — an entity-oriented client using idiomatic Ruby conventions.
|
|
47
|
+
|
|
48
|
+
${semantic}> Other languages, the CLI, and MCP server live alongside this one — see
|
|
49
|
+
> the [top-level README](../README.md).
|
|
11
50
|
|
|
12
51
|
`)
|
|
13
52
|
})
|