@voxgig/sdkgen 4.5.3 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/action/check.js +15 -0
- package/dist/action/check.js.map +1 -1
- package/dist/cmp/AgentGuide.js +1 -1
- package/dist/cmp/AgentGuide.js.map +1 -1
- package/dist/cmp/AgentGuideContent.d.ts +1 -1
- package/dist/cmp/AgentGuideContent.js +8 -2
- package/dist/cmp/AgentGuideContent.js.map +1 -1
- package/dist/cmp/Feature.js +22 -0
- package/dist/cmp/Feature.js.map +1 -1
- package/dist/cmp/FeatureDocs.d.ts +1 -1
- package/dist/cmp/FeatureDocs.js +6 -1
- package/dist/cmp/FeatureDocs.js.map +1 -1
- package/dist/cmp/ReadmeExplanation.js +3 -1
- package/dist/cmp/ReadmeExplanation.js.map +1 -1
- package/dist/cmp/ReadmeFeatures.js +1 -1
- package/dist/cmp/ReadmeFeatures.js.map +1 -1
- package/dist/cmp/ReadmeRefFeatures.js +1 -1
- package/dist/cmp/ReadmeRefFeatures.js.map +1 -1
- package/dist/cmp/TestControl.d.ts +4 -0
- package/dist/cmp/TestControl.js +51 -0
- package/dist/cmp/TestControl.js.map +1 -0
- package/dist/helpers/applicability.d.ts +6 -0
- package/dist/helpers/applicability.js +103 -0
- package/dist/helpers/applicability.js.map +1 -0
- package/dist/helpers/collectDeps.js +4 -2
- package/dist/helpers/collectDeps.js.map +1 -1
- package/dist/helpers/featureSource.d.ts +3 -1
- package/dist/helpers/featureSource.js +105 -0
- package/dist/helpers/featureSource.js.map +1 -1
- package/dist/helpers/serverVars.d.ts +2 -1
- package/dist/helpers/serverVars.js +17 -0
- package/dist/helpers/serverVars.js.map +1 -1
- package/dist/sdkgen.d.ts +5 -3
- package/dist/sdkgen.js +16 -4
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utility.d.ts +2 -1
- package/dist/utility.js +59 -1
- package/dist/utility.js.map +1 -1
- package/model/sdkgen.aon +97 -0
- package/package.json +1 -1
- package/project/.sdk/model/feature/feature-index.aon +1 -0
- package/project/.sdk/model/feature/secrets.aon +200 -0
- package/project/.sdk/model/target/ts.aon +8 -1
- package/project/.sdk/src/cmp/c/Config_c.ts +5 -1
- package/project/.sdk/src/cmp/cpp/Config_cpp.ts +5 -1
- package/project/.sdk/src/cmp/cpp/Main_cpp.ts +2 -1
- package/project/.sdk/src/cmp/cpp/Test_cpp.ts +5 -1
- package/project/.sdk/src/cmp/csharp/Config_csharp.ts +5 -1
- package/project/.sdk/src/cmp/csharp/Main_csharp.ts +2 -1
- package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +30 -6
- package/project/.sdk/src/cmp/csharp/TestEntity_csharp.ts +29 -5
- package/project/.sdk/src/cmp/csharp/Test_csharp.ts +5 -1
- package/project/.sdk/src/cmp/dart/Config_dart.ts +5 -1
- package/project/.sdk/src/cmp/dart/Main_dart.ts +2 -1
- package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +23 -6
- package/project/.sdk/src/cmp/dart/TestEntity_dart.ts +28 -7
- package/project/.sdk/src/cmp/dart/Test_dart.ts +5 -1
- package/project/.sdk/src/cmp/elixir/Config_elixir.ts +5 -1
- package/project/.sdk/src/cmp/elixir/Main_elixir.ts +5 -1
- package/project/.sdk/src/cmp/go/Config_go.ts +5 -1
- package/project/.sdk/src/cmp/go/Main_go.ts +8 -3
- package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +16 -3
- package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +16 -3
- package/project/.sdk/src/cmp/go/TestDirect_go.ts +28 -4
- package/project/.sdk/src/cmp/go/TestEntity_go.ts +43 -10
- package/project/.sdk/src/cmp/go/Test_go.ts +5 -1
- package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +5 -5
- package/project/.sdk/src/cmp/java/Config_java.ts +22 -1
- package/project/.sdk/src/cmp/java/Main_java.ts +7 -2
- package/project/.sdk/src/cmp/java/ReadmeQuick_java.ts +17 -3
- package/project/.sdk/src/cmp/java/ReadmeTopQuick_java.ts +17 -3
- package/project/.sdk/src/cmp/java/TestDirect_java.ts +23 -4
- package/project/.sdk/src/cmp/java/TestEntity_java.ts +29 -4
- package/project/.sdk/src/cmp/java/Test_java.ts +5 -1
- package/project/.sdk/src/cmp/js/Config_js.ts +5 -1
- package/project/.sdk/src/cmp/js/Main_js.ts +7 -2
- package/project/.sdk/src/cmp/js/Package_js.ts +4 -1
- package/project/.sdk/src/cmp/js/TestDirect_js.ts +30 -5
- package/project/.sdk/src/cmp/js/TestEntity_js.ts +35 -5
- package/project/.sdk/src/cmp/js/Test_js.ts +5 -1
- package/project/.sdk/src/cmp/js/fragment/Direct.test.fragment.js +7 -1
- package/project/.sdk/src/cmp/js/fragment/Entity.test.fragment.js +7 -1
- package/project/.sdk/src/cmp/kotlin/Config_kotlin.ts +5 -1
- package/project/.sdk/src/cmp/kotlin/Main_kotlin.ts +2 -1
- package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +5 -1
- package/project/.sdk/src/cmp/lean/Config_lean.ts +5 -1
- package/project/.sdk/src/cmp/lua/Config_lua.ts +5 -1
- package/project/.sdk/src/cmp/lua/Main_lua.ts +7 -2
- package/project/.sdk/src/cmp/lua/Package_lua.ts +4 -1
- package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +28 -4
- package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +24 -4
- package/project/.sdk/src/cmp/lua/Test_lua.ts +5 -1
- package/project/.sdk/src/cmp/ocaml/Config_ocaml.ts +5 -1
- package/project/.sdk/src/cmp/ocaml/Gitignore_ocaml.ts +1 -0
- package/project/.sdk/src/cmp/perl/Main_perl.ts +7 -2
- package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +25 -4
- package/project/.sdk/src/cmp/perl/TestEntity_perl.ts +24 -4
- package/project/.sdk/src/cmp/perl/Test_perl.ts +5 -1
- package/project/.sdk/src/cmp/perl/utility_perl.ts +10 -0
- package/project/.sdk/src/cmp/php/Config_php.ts +5 -1
- package/project/.sdk/src/cmp/php/Main_php.ts +7 -2
- package/project/.sdk/src/cmp/php/TestDirect_php.ts +24 -5
- package/project/.sdk/src/cmp/php/TestEntity_php.ts +28 -4
- package/project/.sdk/src/cmp/php/Test_php.ts +5 -1
- package/project/.sdk/src/cmp/py/Config_py.ts +5 -1
- package/project/.sdk/src/cmp/py/Main_py.ts +7 -2
- package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +16 -3
- package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +16 -3
- package/project/.sdk/src/cmp/py/TestDirect_py.ts +24 -5
- package/project/.sdk/src/cmp/py/TestEntity_py.ts +23 -3
- package/project/.sdk/src/cmp/py/Test_py.ts +5 -1
- package/project/.sdk/src/cmp/rb/Config_rb.ts +5 -1
- package/project/.sdk/src/cmp/rb/Main_rb.ts +7 -2
- package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +24 -5
- package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +24 -4
- package/project/.sdk/src/cmp/rb/Test_rb.ts +5 -1
- package/project/.sdk/src/cmp/rb/utility_rb.ts +3 -1
- package/project/.sdk/src/cmp/rust/Config_rust.ts +5 -1
- package/project/.sdk/src/cmp/rust/Main_rust.ts +7 -2
- package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +31 -4
- package/project/.sdk/src/cmp/rust/TestEntity_rust.ts +37 -4
- package/project/.sdk/src/cmp/rust/Test_rust.ts +5 -1
- package/project/.sdk/src/cmp/scala/Config_scala.ts +5 -1
- package/project/.sdk/src/cmp/scala/Main_scala.ts +7 -2
- package/project/.sdk/src/cmp/scala/Test_scala.ts +5 -1
- package/project/.sdk/src/cmp/swift/Config_swift.ts +5 -1
- package/project/.sdk/src/cmp/ts/Config_ts.ts +55 -9
- package/project/.sdk/src/cmp/ts/Main_ts.ts +67 -3
- package/project/.sdk/src/cmp/ts/Package_ts.ts +4 -1
- package/project/.sdk/src/cmp/ts/ReadmeModel_ts.ts +15 -3
- package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +18 -5
- package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +19 -5
- package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +75 -8
- package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +36 -5
- package/project/.sdk/src/cmp/ts/Test_ts.ts +5 -1
- package/project/.sdk/src/cmp/ts/fragment/Direct.test.fragment.ts +9 -2
- package/project/.sdk/src/cmp/ts/fragment/Entity.test.fragment.ts +9 -2
- package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +7 -0
- package/project/.sdk/src/cmp/zig/Config_zig.ts +5 -1
- package/project/.sdk/tm/c/utility/make_options.c +22 -0
- package/project/.sdk/tm/clojure/src/sdk/core.clj +18 -1
- package/project/.sdk/tm/cpp/utility/pipeline.hpp +23 -0
- package/project/.sdk/tm/csharp/test/CustomUtilityTest.cs +15 -0
- package/project/.sdk/tm/csharp/test/Runner.cs +45 -0
- package/project/.sdk/tm/csharp/utility/MakeOptions.cs +23 -0
- package/project/.sdk/tm/dart/lib/utility/MakeOptionsUtility.dart +22 -0
- package/project/.sdk/tm/dart/test/utility.dart +39 -0
- package/project/.sdk/tm/elixir/lib/projectname/utility.ex +19 -0
- package/project/.sdk/tm/go/core/context.go +1 -1
- package/project/.sdk/tm/go/feature/cost_feature.go +1 -1
- package/project/.sdk/tm/go/feature/paging_feature.go +5 -5
- package/project/.sdk/tm/go/feature/test_feature.go +12 -5
- package/project/.sdk/tm/go/test/custom_utility_test.go +15 -0
- package/project/.sdk/tm/go/test/feature_corpus_test.go +7 -0
- package/project/.sdk/tm/go/test/runner_test.go +46 -0
- package/project/.sdk/tm/go/test/struct_runner_test.go +7 -7
- package/project/.sdk/tm/go/test/struct_utility_test.go +63 -27
- package/project/.sdk/tm/go/utility/fetcher.go +2 -2
- package/project/.sdk/tm/go/utility/make_options.go +24 -5
- package/project/.sdk/tm/go/utility/make_point.go +1 -1
- package/project/.sdk/tm/go/utility/make_spec.go +17 -1
- package/project/.sdk/tm/go/utility/prepare_auth.go +1 -1
- package/project/.sdk/tm/go/utility/struct/voxgigstruct.go +370 -307
- package/project/.sdk/tm/go/utility/transform_request.go +29 -1
- package/project/.sdk/tm/go/utility/transform_response.go +20 -1
- package/project/.sdk/tm/java/test/CustomUtilityTest.java +10 -0
- package/project/.sdk/tm/java/test/FeatureCorpusTest.java +7 -0
- package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +6 -0
- package/project/.sdk/tm/java/test/RunnerSupport.java +43 -0
- package/project/.sdk/tm/java/utility/MakeOptions.java +84 -1
- package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +24 -0
- package/project/.sdk/tm/js/src/utility/StructUtility.js +2076 -1837
- package/project/.sdk/tm/js/test/feature/Corpus.test.js +9 -0
- package/project/.sdk/tm/js/test/sdk-test-control.json +19 -0
- package/project/.sdk/tm/js/test/utility.js +91 -1
- package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +21 -0
- package/project/.sdk/tm/lean/src/SdkUtility.lean +12 -1
- package/project/.sdk/tm/lua/test/runner.lua +40 -0
- package/project/.sdk/tm/ocaml/sdk_runtime.ml +11 -0
- package/project/.sdk/tm/ocaml/test/harness.ml +14 -4
- package/project/.sdk/tm/perl/t/runner.pm +30 -0
- package/project/.sdk/tm/perl/utility/make_options.pm +18 -0
- package/project/.sdk/tm/php/test/FeatureCorpusTest.php +10 -1
- package/project/.sdk/tm/php/test/Runner.php +36 -0
- package/project/.sdk/tm/php/utility/MakeOptions.php +24 -0
- package/project/.sdk/tm/py/pkg/utility/make_options.py +20 -0
- package/project/.sdk/tm/py/test/runner.py +32 -0
- package/project/.sdk/tm/py/test/test_feature_corpus.py +10 -1
- package/project/.sdk/tm/rb/test/feature_corpus_test.rb +9 -1
- package/project/.sdk/tm/rb/test/runner.rb +25 -0
- package/project/.sdk/tm/rb/utility/make_options.rb +17 -0
- package/project/.sdk/tm/rust/tests/common/mod.rs +32 -0
- package/project/.sdk/tm/rust/utility/make_options.rs +26 -1
- package/project/.sdk/tm/scala/utility/Make.scala +17 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +21 -0
- package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +419 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +387 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sigv4.ts +175 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +51 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/Registry.ts +90 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/addr.ts +48 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/aws.ts +219 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/azuresecrets.ts +144 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/boru.ts +113 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/doppler.ts +77 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/dotenv.ts +51 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/env.ts +31 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/file.ts +54 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/gcpsecrets.ts +118 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/hashicorp.ts +159 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/http.ts +66 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/infisical.ts +107 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/memory.ts +33 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/onepassword.ts +120 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/support.ts +176 -0
- package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +18 -0
- package/project/.sdk/tm/ts/src/utility/StructUtility.ts +1321 -710
- package/project/.sdk/tm/ts/test/feature/Corpus.test.ts +9 -0
- package/project/.sdk/tm/ts/test/feature/secrets/Secrets.test.ts +764 -0
- package/project/.sdk/tm/ts/test/omni.test.ts +84 -0
- package/project/.sdk/tm/ts/test/omni.ts +86 -0
- package/project/.sdk/tm/ts/test/utility/PrimaryUtility.test.ts +6 -2
- package/project/.sdk/tm/ts/test/utility/StructUtility.test.ts +2 -2
- package/project/.sdk/tm/ts/test/utility.ts +122 -0
- package/project/.sdk/tm/ts/test/vendor/omni/Runner.ts +694 -0
- package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +244 -0
- package/project/.sdk/tm/ts/test/vendor/omni/compat.ts +188 -0
- package/project/.sdk/tm/ts/test/vendor/omni/index.ts +38 -0
- package/project/.sdk/tm/zig/core/utility.zig +24 -1
- package/project/sdkgen-package.json +2 -1
- package/src/action/check.ts +18 -0
- package/src/cmp/AgentGuide.ts +1 -1
- package/src/cmp/AgentGuideContent.ts +9 -2
- package/src/cmp/Feature.ts +24 -0
- package/src/cmp/FeatureDocs.ts +7 -1
- package/src/cmp/ReadmeExplanation.ts +4 -1
- package/src/cmp/ReadmeFeatures.ts +1 -1
- package/src/cmp/ReadmeRefFeatures.ts +1 -1
- package/src/cmp/TestControl.ts +64 -0
- package/src/helpers/applicability.ts +123 -0
- package/src/helpers/collectDeps.ts +5 -1
- package/src/helpers/featureSource.ts +130 -0
- package/src/helpers/serverVars.ts +19 -0
- package/src/sdkgen.ts +16 -1
- package/src/utility.ts +71 -1
- package/project/.sdk/tm/ts/test/runner.ts +0 -425
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
isAuthActive,
|
|
10
10
|
isConfigData,
|
|
11
11
|
resolveAuthPrefix,
|
|
12
|
+
targetFeatures,
|
|
12
13
|
} from '@voxgig/sdkgen'
|
|
13
14
|
|
|
14
15
|
|
|
@@ -35,7 +36,10 @@ const Config = cmp(async function Config(props: any) {
|
|
|
35
36
|
const model: Model = ctx$.model
|
|
36
37
|
|
|
37
38
|
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
38
|
-
|
|
39
|
+
// Gated by the applicability tags, so this target never imports or
|
|
40
|
+
// registers a feature it has no source for. One rule, one place:
|
|
41
|
+
// helpers/applicability.
|
|
42
|
+
const feature = targetFeatures(model, target)
|
|
39
43
|
|
|
40
44
|
const headers = getModelPath(model, `main.${KIT}.config.headers`) || {}
|
|
41
45
|
|
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
cmp, each,
|
|
6
6
|
File, Content, Copy, Folder, Fragment,
|
|
7
7
|
entityClassName,
|
|
8
|
+
targetFeatures,
|
|
9
|
+
TEST_CONTROL_EXCLUDE
|
|
8
10
|
} from '@voxgig/sdkgen'
|
|
9
11
|
|
|
10
12
|
|
|
@@ -35,7 +37,10 @@ const Main = cmp(async function Main(props: any) {
|
|
|
35
37
|
const { model } = props.ctx$
|
|
36
38
|
|
|
37
39
|
const entity: ModelEntity = getModelPath(model, `main.${KIT}.entity`)
|
|
38
|
-
|
|
40
|
+
// Gated by the applicability tags, so this target never imports or
|
|
41
|
+
// registers a feature it has no source for. One rule, one place:
|
|
42
|
+
// helpers/applicability.
|
|
43
|
+
const feature = targetFeatures(model, target)
|
|
39
44
|
|
|
40
45
|
// The rust crate identifier (RUSTCRATE placeholder), e.g. solar_sdk —
|
|
41
46
|
// used in every `use <crate>::...` path in the test templates.
|
|
@@ -50,7 +55,7 @@ const Main = cmp(async function Main(props: any) {
|
|
|
50
55
|
// here exactly like the go target.
|
|
51
56
|
Copy({
|
|
52
57
|
from: 'tm/' + target.name,
|
|
53
|
-
exclude: [/src
|
|
58
|
+
exclude: [/src\//, TEST_CONTROL_EXCLUDE],
|
|
54
59
|
replace: {
|
|
55
60
|
...props.ctx$.stdrep,
|
|
56
61
|
RUSTCRATE: rustcrate,
|
|
@@ -11,7 +11,9 @@ import {
|
|
|
11
11
|
File,
|
|
12
12
|
cmp,
|
|
13
13
|
snakify,
|
|
14
|
-
isAuthActive, envName, envToken
|
|
14
|
+
isAuthActive, envName, envToken,
|
|
15
|
+
serverVarEnv,
|
|
16
|
+
serverVariables
|
|
15
17
|
} from '@voxgig/sdkgen'
|
|
16
18
|
|
|
17
19
|
|
|
@@ -67,12 +69,28 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
67
69
|
|
|
68
70
|
const authActive = isAuthActive(model)
|
|
69
71
|
const apikeyEnvEntry = authActive
|
|
70
|
-
? `\n ("${PROJECTNAME}_APIKEY", Value::str("
|
|
72
|
+
? `\n ("${PROJECTNAME}_APIKEY", Value::str("")),`
|
|
71
73
|
: ''
|
|
72
74
|
const apikeyLiveField = authActive
|
|
73
75
|
? `("apikey", getp(&env, "${PROJECTNAME}_APIKEY"))`
|
|
74
76
|
: ''
|
|
75
77
|
|
|
78
|
+
// A templated server URL (OpenAPI server variables) makes a LIVE client
|
|
79
|
+
// impossible to construct without values: makeOptions raises rather than
|
|
80
|
+
// request a URL with a literal `{account_id}` in it. So the live suite
|
|
81
|
+
// takes them from the environment the same way it takes the apikey.
|
|
82
|
+
//
|
|
83
|
+
// Emitted as a jo() tuple entry, so it carries its own leading comma only
|
|
84
|
+
// when an apikey entry precedes it - otherwise `jo(vec![, ...])`.
|
|
85
|
+
const svars = serverVariables(model)
|
|
86
|
+
const serverEnvEntry = svars
|
|
87
|
+
.map((v: any) => `\n ("${serverVarEnv(PROJECTNAME, v.name)}", Value::str(${JSON.stringify(v.dflt)})),`).join('')
|
|
88
|
+
const serverLiveEntry = 0 === svars.length ? '' :
|
|
89
|
+
`("server", jo(vec![${svars
|
|
90
|
+
.map((v: any) => `("${v.name}", getp(&env, "${serverVarEnv(PROJECTNAME, v.name)}"))`).join(', ')}]))`
|
|
91
|
+
const serverLiveField = '' === serverLiveEntry ? '' :
|
|
92
|
+
('' === apikeyLiveField ? serverLiveEntry : ', ' + serverLiveEntry)
|
|
93
|
+
|
|
76
94
|
const opnames = Object.keys(entity.op || {})
|
|
77
95
|
const hasLoad = opnames.includes('load')
|
|
78
96
|
const hasList = opnames.includes('list')
|
|
@@ -148,13 +166,22 @@ fn ${evar}_direct_setup(mockres: Value) -> ${entity.Name}DirectSetup {
|
|
|
148
166
|
|
|
149
167
|
let env = env_override(jo(vec![
|
|
150
168
|
("${entidEnvVar}", Value::empty_map()),
|
|
151
|
-
("${PROJECTNAME}_TEST_LIVE", Value::str("FALSE")),${apikeyEnvEntry}
|
|
169
|
+
("${PROJECTNAME}_TEST_LIVE", Value::str("FALSE")),${apikeyEnvEntry}${serverEnvEntry}
|
|
152
170
|
]));
|
|
153
171
|
|
|
154
172
|
let live = getp(&env, "${PROJECTNAME}_TEST_LIVE") == Value::str("TRUE");
|
|
155
173
|
|
|
156
174
|
if live {
|
|
157
|
-
|
|
175
|
+
// live_client_options() FIRST, so the generated entries below win:
|
|
176
|
+
// sdk-test-control.json's test.client.options adds to the live
|
|
177
|
+
// client, it does not redirect it.
|
|
178
|
+
let client = ${model.const.Name}SDK::new(to_map(&vs::merge(
|
|
179
|
+
&ja(vec![
|
|
180
|
+
live_client_options(),
|
|
181
|
+
jo(vec![${apikeyLiveField}${serverLiveField}]),
|
|
182
|
+
]),
|
|
183
|
+
None,
|
|
184
|
+
)));
|
|
158
185
|
let idmap = match to_map(&getp(&env, "${entidEnvVar}")) {
|
|
159
186
|
Value::Map(m) => Value::Map(m),
|
|
160
187
|
_ => Value::empty_map(),
|
|
@@ -17,7 +17,9 @@ import {
|
|
|
17
17
|
each,
|
|
18
18
|
buildIdNames,
|
|
19
19
|
getMatchEntries,
|
|
20
|
-
isAuthActive, envName, envToken
|
|
20
|
+
isAuthActive, envName, envToken,
|
|
21
|
+
serverVarEnv,
|
|
22
|
+
serverVariables
|
|
21
23
|
} from '@voxgig/sdkgen'
|
|
22
24
|
|
|
23
25
|
|
|
@@ -56,12 +58,28 @@ const TestEntity = cmp(function TestEntity(props: any) {
|
|
|
56
58
|
|
|
57
59
|
const authActive = isAuthActive(model)
|
|
58
60
|
const apikeyEnvEntry = authActive
|
|
59
|
-
? `\n ("${PROJUPPER}_APIKEY", Value::str("
|
|
61
|
+
? `\n ("${PROJUPPER}_APIKEY", Value::str("")),`
|
|
60
62
|
: ''
|
|
61
63
|
const apikeyLiveField = authActive
|
|
62
64
|
? `("apikey", getp(&env, "${PROJUPPER}_APIKEY"))`
|
|
63
65
|
: ''
|
|
64
66
|
|
|
67
|
+
// A templated server URL (OpenAPI server variables) makes a LIVE client
|
|
68
|
+
// impossible to construct without values: makeOptions raises rather than
|
|
69
|
+
// request a URL with a literal `{account_id}` in it. So the live suite
|
|
70
|
+
// takes them from the environment the same way it takes the apikey.
|
|
71
|
+
//
|
|
72
|
+
// Emitted as a jo() tuple entry, so it carries its own leading comma only
|
|
73
|
+
// when an apikey entry precedes it - otherwise `jo(vec![, ...])`.
|
|
74
|
+
const svars = serverVariables(model)
|
|
75
|
+
const serverEnvEntry = svars
|
|
76
|
+
.map((v: any) => `\n ("${serverVarEnv(PROJUPPER, v.name)}", Value::str(${JSON.stringify(v.dflt)})),`).join('')
|
|
77
|
+
const serverLiveEntry = 0 === svars.length ? '' :
|
|
78
|
+
`("server", jo(vec![${svars
|
|
79
|
+
.map((v: any) => `("${v.name}", getp(&env, "${serverVarEnv(PROJUPPER, v.name)}"))`).join(', ')}]))`
|
|
80
|
+
const serverLiveField = '' === serverLiveEntry ? '' :
|
|
81
|
+
('' === apikeyLiveField ? serverLiveEntry : ', ' + serverLiveEntry)
|
|
82
|
+
|
|
65
83
|
const idnames = buildIdNames(entity, basicflow)
|
|
66
84
|
const idnamesStr = idnames.map(n => `Value::str("${n}")`).join(', ')
|
|
67
85
|
|
|
@@ -268,7 +286,7 @@ ${allSteps.length > 0 ? ' let client = setup.client.clone();\n' : ''}`)
|
|
|
268
286
|
let env = env_override(jo(vec![
|
|
269
287
|
("${PROJUPPER}_TEST_${ENTUPPER}_ENTID", idmap.clone()),
|
|
270
288
|
("${PROJUPPER}_TEST_LIVE", Value::str("FALSE")),
|
|
271
|
-
("${PROJUPPER}_TEST_EXPLAIN", Value::str("FALSE")),${apikeyEnvEntry}
|
|
289
|
+
("${PROJUPPER}_TEST_EXPLAIN", Value::str("FALSE")),${apikeyEnvEntry}${serverEnvEntry}
|
|
272
290
|
]));
|
|
273
291
|
|
|
274
292
|
let idmap_resolved = match to_map(&getp(&env, "${PROJUPPER}_TEST_${ENTUPPER}_ENTID")) {
|
|
@@ -293,7 +311,22 @@ ${allSteps.length > 0 ? ' let client = setup.client.clone();\n' : ''}`)
|
|
|
293
311
|
|
|
294
312
|
let client = if live {
|
|
295
313
|
let merged = vs::merge(
|
|
296
|
-
|
|
314
|
+
// live_client_options() FIRST, so the generated entries below win:
|
|
315
|
+
// sdk-test-control.json's test.client.options adds to the live
|
|
316
|
+
// client, it does not redirect it.
|
|
317
|
+
&ja(vec![
|
|
318
|
+
live_client_options(),
|
|
319
|
+
jo(vec![${apikeyLiveField}${serverLiveField}]),
|
|
320
|
+
// A NON-NODE later entry REPLACES the accumulated map in
|
|
321
|
+
// vs::merge, and the normal call passes Value::Noval - so a
|
|
322
|
+
// a bare extra discarded live_client_options() and the
|
|
323
|
+
// apikey/server map above it, and the live client was
|
|
324
|
+
// constructed with nothing.
|
|
325
|
+
match extra {
|
|
326
|
+
Value::Map(m) => Value::Map(m),
|
|
327
|
+
_ => Value::empty_map(),
|
|
328
|
+
},
|
|
329
|
+
]),
|
|
297
330
|
None,
|
|
298
331
|
);
|
|
299
332
|
${model.const.Name}SDK::new(to_map(&merged))
|
|
@@ -3,7 +3,8 @@ import type {
|
|
|
3
3
|
ModelEntity
|
|
4
4
|
} from '@voxgig/apidef'
|
|
5
5
|
|
|
6
|
-
import { cmp, each, Folder, File, Content, entityCollection
|
|
6
|
+
import { cmp, each, Folder, File, Content, entityCollection,
|
|
7
|
+
TestControl } from '@voxgig/sdkgen'
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
import { TestEntity } from './TestEntity_rust'
|
|
@@ -20,6 +21,9 @@ const Test = cmp(function Test(props: any) {
|
|
|
20
21
|
|
|
21
22
|
Folder({ name: 'tests' }, () => {
|
|
22
23
|
|
|
24
|
+
// Write-once: a project's edited control file survives regeneration.
|
|
25
|
+
TestControl({ target, dir: 'tests' })
|
|
26
|
+
|
|
23
27
|
// exists test — the SDK constructs in test mode.
|
|
24
28
|
File({ name: 'exists_test.' + target.ext }, () => {
|
|
25
29
|
Content(`// Generated existence test: the SDK constructs in test mode.
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
each,
|
|
7
7
|
isAuthActive,
|
|
8
8
|
resolveAuthPrefix,
|
|
9
|
+
targetFeatures,
|
|
9
10
|
} from '@voxgig/sdkgen'
|
|
10
11
|
|
|
11
12
|
|
|
@@ -35,7 +36,10 @@ const Config = cmp(async function Config(props: any) {
|
|
|
35
36
|
const scalapackage = scalaPackage(model)
|
|
36
37
|
|
|
37
38
|
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
38
|
-
|
|
39
|
+
// Gated by the applicability tags, so this target never imports or
|
|
40
|
+
// registers a feature it has no source for. One rule, one place:
|
|
41
|
+
// helpers/applicability.
|
|
42
|
+
const feature = targetFeatures(model, target)
|
|
39
43
|
|
|
40
44
|
const headers = getModelPath(model, `main.${KIT}.config.headers`) || {}
|
|
41
45
|
|
|
@@ -4,6 +4,8 @@ import * as Path from 'node:path'
|
|
|
4
4
|
import {
|
|
5
5
|
cmp, each,
|
|
6
6
|
File, Content, Copy, Folder, Fragment,
|
|
7
|
+
targetFeatures,
|
|
8
|
+
TEST_CONTROL_EXCLUDE
|
|
7
9
|
} from '@voxgig/sdkgen'
|
|
8
10
|
|
|
9
11
|
|
|
@@ -33,7 +35,10 @@ const Main = cmp(async function Main(props: any) {
|
|
|
33
35
|
const { model } = props.ctx$
|
|
34
36
|
|
|
35
37
|
const entity: ModelEntity = getModelPath(model, `main.${KIT}.entity`)
|
|
36
|
-
|
|
38
|
+
// Gated by the applicability tags, so this target never imports or
|
|
39
|
+
// registers a feature it has no source for. One rule, one place:
|
|
40
|
+
// helpers/applicability.
|
|
41
|
+
const feature = targetFeatures(model, target)
|
|
37
42
|
|
|
38
43
|
// The Scala package root for every runtime piece (like GOMODULE for go).
|
|
39
44
|
const scalapackage = scalaPackage(model)
|
|
@@ -47,7 +52,7 @@ const Main = cmp(async function Main(props: any) {
|
|
|
47
52
|
// ProjectName carries the SDK name into vendored template strings.
|
|
48
53
|
Copy({
|
|
49
54
|
from: 'tm/' + target.name,
|
|
50
|
-
exclude: [/src
|
|
55
|
+
exclude: [/src\//, TEST_CONTROL_EXCLUDE],
|
|
51
56
|
replace: {
|
|
52
57
|
...props.ctx$.stdrep,
|
|
53
58
|
ProjectName: model.const.Name,
|
|
@@ -9,7 +9,8 @@ import type {
|
|
|
9
9
|
ModelEntity
|
|
10
10
|
} from '@voxgig/apidef'
|
|
11
11
|
|
|
12
|
-
import { cmp, each, Folder, File, Content, entityCollection
|
|
12
|
+
import { cmp, each, Folder, File, Content, entityCollection,
|
|
13
|
+
TestControl } from '@voxgig/sdkgen'
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
import { TestEntity } from './TestEntity_scala'
|
|
@@ -31,6 +32,9 @@ const Test = cmp(function Test(props: any) {
|
|
|
31
32
|
// template, and are driven by the generated SdkEntityTestMain aggregator.
|
|
32
33
|
Folder({ name: 'sdktest' }, () => {
|
|
33
34
|
|
|
35
|
+
// Write-once: a project's edited control file survives regeneration.
|
|
36
|
+
TestControl({ target, dir: 'sdktest' })
|
|
37
|
+
|
|
34
38
|
const entities: { Name: string; entity: boolean; direct: boolean }[] = []
|
|
35
39
|
|
|
36
40
|
const entity = each(entityCollection(model))
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
cmp,
|
|
6
6
|
configDefinition,
|
|
7
7
|
each,
|
|
8
|
+
targetFeatures,
|
|
8
9
|
} from '@voxgig/sdkgen'
|
|
9
10
|
|
|
10
11
|
|
|
@@ -26,7 +27,10 @@ const Config = cmp(async function Config(props: any) {
|
|
|
26
27
|
|
|
27
28
|
const model: Model = ctx$.model
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
// Gated by the applicability tags, so this target never imports or
|
|
31
|
+
// registers a feature it has no source for. One rule, one place:
|
|
32
|
+
// helpers/applicability.
|
|
33
|
+
const feature = targetFeatures(model, target)
|
|
30
34
|
|
|
31
35
|
// The config as data, built by the shared helper so every target embeds
|
|
32
36
|
// the same model by construction. Passing target.name opts this target
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
isHttpBasicAuth,
|
|
19
19
|
resolveAuthPrefix,
|
|
20
20
|
serverVariables,
|
|
21
|
+
targetFeatures,
|
|
21
22
|
} from '@voxgig/sdkgen'
|
|
22
23
|
|
|
23
24
|
|
|
@@ -41,7 +42,10 @@ const Config = cmp(async function Config(props: any) {
|
|
|
41
42
|
const model: Model = ctx$.model
|
|
42
43
|
|
|
43
44
|
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
44
|
-
|
|
45
|
+
// Gated by the applicability tags, so this target never imports or
|
|
46
|
+
// registers a feature it has no source for. One rule, one place:
|
|
47
|
+
// helpers/applicability.
|
|
48
|
+
const feature = targetFeatures(model, target)
|
|
45
49
|
|
|
46
50
|
const ff = Path.normalize(__dirname + '/../../../src/cmp/ts/fragment/')
|
|
47
51
|
|
|
@@ -95,10 +99,13 @@ const Config = cmp(async function Config(props: any) {
|
|
|
95
99
|
|
|
96
100
|
replace: {
|
|
97
101
|
|
|
98
|
-
'// #ImportFeatures': () =>
|
|
99
|
-
|
|
100
|
-
`
|
|
101
|
-
|
|
102
|
+
'// #ImportFeatures': () => {
|
|
103
|
+
each(feature, (f: any) => {
|
|
104
|
+
Line(`import { ${nom(f, 'Name')}Feature } from ` +
|
|
105
|
+
`'./feature/${f.name}/${nom(f, 'Name')}Feature'`)
|
|
106
|
+
})
|
|
107
|
+
pluginImports(feature)
|
|
108
|
+
},
|
|
102
109
|
|
|
103
110
|
'// #FeatureClasses': () => each(feature, (f: any) => {
|
|
104
111
|
Line(` ${f.name}: ${nom(f, 'Name')}Feature,`)
|
|
@@ -126,10 +133,13 @@ const Config = cmp(async function Config(props: any) {
|
|
|
126
133
|
|
|
127
134
|
"'HEADERS'": indent(JSON.stringify(headers, null, 2), 4).trim(),
|
|
128
135
|
|
|
129
|
-
'// #ImportFeatures': () =>
|
|
130
|
-
|
|
131
|
-
`
|
|
132
|
-
|
|
136
|
+
'// #ImportFeatures': () => {
|
|
137
|
+
each(feature, (f: any) => {
|
|
138
|
+
Line(`import { ${nom(f, 'Name')}Feature } from ` +
|
|
139
|
+
`'./feature/${f.name}/${nom(f, 'Name')}Feature'`)
|
|
140
|
+
})
|
|
141
|
+
pluginImports(feature)
|
|
142
|
+
},
|
|
133
143
|
|
|
134
144
|
// Values from configDefinition's def, not re-derived here, so the
|
|
135
145
|
// literal rep and the data rep cannot disagree on identity.
|
|
@@ -173,6 +183,42 @@ const Config = cmp(async function Config(props: any) {
|
|
|
173
183
|
})
|
|
174
184
|
|
|
175
185
|
|
|
186
|
+
|
|
187
|
+
// PLUGIN REGISTRATION IMPORTS.
|
|
188
|
+
//
|
|
189
|
+
// A sekreto provider module registers itself when it is imported, and
|
|
190
|
+
// nothing else imports it: the core surface deliberately does not reach a
|
|
191
|
+
// platform-dependent provider, and the full-set barrel — the file whose
|
|
192
|
+
// job was to reach all of them — is not vendored into an SDK at all.
|
|
193
|
+
//
|
|
194
|
+
// So without these lines an SDK generates `provider/dotenv.ts`, never
|
|
195
|
+
// imports it, and throws `unknown provider kind: dotenv` the first time a
|
|
196
|
+
// chain names it. Emitted here because Config already imports every active
|
|
197
|
+
// feature from the model, and this is the same list one level down.
|
|
198
|
+
//
|
|
199
|
+
// Import for SIDE EFFECT only — `import '...'`, no bindings. The module's
|
|
200
|
+
// top-level `register()` call is the whole point.
|
|
201
|
+
function pluginImports(feature: any) {
|
|
202
|
+
each(feature, (f: any) => {
|
|
203
|
+
each(f.plugin, (plugin: any) => {
|
|
204
|
+
// Filter on `active` HERE rather than trusting the feature object to
|
|
205
|
+
// arrive filtered. Whether a model path was read with `only_active`
|
|
206
|
+
// varies by call site, and getting it wrong in this direction emits
|
|
207
|
+
// an import for a module the trim just deleted — an SDK that does
|
|
208
|
+
// not compile, rather than one that merely carries too much.
|
|
209
|
+
if (false === plugin.active || null == plugin.active) return
|
|
210
|
+
|
|
211
|
+
for (const one of (plugin.path || [])) {
|
|
212
|
+
const path = String(one)
|
|
213
|
+
// Only a provider MODULE registers a kind; a plugin may own other
|
|
214
|
+
// files (Sigv4.ts is signing support, not a provider).
|
|
215
|
+
if (!/\/provider\/[^/]+\.ts$/.test(path)) continue
|
|
216
|
+
Line(`import '${'./' + path.replace(/^src\//, '').replace(/\.ts$/, '')}'`)
|
|
217
|
+
}
|
|
218
|
+
})
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
|
|
176
222
|
export {
|
|
177
223
|
Config
|
|
178
224
|
}
|
|
@@ -4,7 +4,10 @@ import * as Path from 'node:path'
|
|
|
4
4
|
import {
|
|
5
5
|
cmp, each, names, cmap,
|
|
6
6
|
List, File, Content, Copy, Folder, Fragment, Line, FeatureHook,
|
|
7
|
-
entityClassName, entityCollection, srcFeatureExcludes,
|
|
7
|
+
entityClassName, entityCollection, srcFeatureExcludes, pluginExcludes,
|
|
8
|
+
stationLibrary,
|
|
9
|
+
targetFeatures,
|
|
10
|
+
TEST_CONTROL_EXCLUDE
|
|
8
11
|
} from '@voxgig/sdkgen'
|
|
9
12
|
|
|
10
13
|
|
|
@@ -35,7 +38,14 @@ const Main = cmp(async function Main(props: any) {
|
|
|
35
38
|
const { model } = props.ctx$
|
|
36
39
|
|
|
37
40
|
const entity: ModelEntity = getModelPath(model, `main.${KIT}.entity`)
|
|
38
|
-
|
|
41
|
+
// Gated by the applicability tags, so this target never imports or
|
|
42
|
+
// registers a feature it has no source for. One rule, one place:
|
|
43
|
+
// helpers/applicability.
|
|
44
|
+
const feature = targetFeatures(model, target)
|
|
45
|
+
|
|
46
|
+
// Does the secrets feature apply here and is it switched on? Both, since
|
|
47
|
+
// targetFeatures already dropped it for a target with no sekreto port.
|
|
48
|
+
const secrets = null != feature.secrets
|
|
39
49
|
|
|
40
50
|
Package({ target })
|
|
41
51
|
|
|
@@ -45,7 +55,13 @@ const Main = cmp(async function Main(props: any) {
|
|
|
45
55
|
from: 'tm/' + target.name,
|
|
46
56
|
// Root copies src/feature/<name>/ per ACTIVE feature; keep this blanket
|
|
47
57
|
// copy from restoring one that was switched off after `target add`.
|
|
48
|
-
|
|
58
|
+
// A feature's inactive plugins go too - same rule, one level
|
|
59
|
+
// deeper. See helpers/featureSource.pluginExcludes.
|
|
60
|
+
exclude: [
|
|
61
|
+
...srcFeatureExcludes(model),
|
|
62
|
+
...pluginExcludes(model),
|
|
63
|
+
TEST_CONTROL_EXCLUDE,
|
|
64
|
+
],
|
|
49
65
|
replace: {
|
|
50
66
|
...props.ctx$.stdrep,
|
|
51
67
|
}
|
|
@@ -74,6 +90,54 @@ const Main = cmp(async function Main(props: any) {
|
|
|
74
90
|
replace: {
|
|
75
91
|
...props.ctx$.stdrep,
|
|
76
92
|
|
|
93
|
+
// SECRETS. All five slots are emitted only when the secrets
|
|
94
|
+
// feature applies to this target AND the model activates it.
|
|
95
|
+
// An unconditional edit here would land in every generated SDK
|
|
96
|
+
// and break the inactive-output gate: a model without the
|
|
97
|
+
// feature must generate byte-identically to pre-migration.
|
|
98
|
+
//
|
|
99
|
+
// `feature` is already gated by targetFeatures, so a target
|
|
100
|
+
// that does not provide 'sekreto' never reaches these.
|
|
101
|
+
'// #SecretsImport': () => secrets ?
|
|
102
|
+
Line(`import * as sekreto from './feature/secrets/sekreto'`) : undefined,
|
|
103
|
+
|
|
104
|
+
'// #SecretsField': ({ indent }: any) => secrets ?
|
|
105
|
+
Line({ indent }, '_secrets?: any') : undefined,
|
|
106
|
+
|
|
107
|
+
// The LIVE instance, not a clone: sekreto holds provider and
|
|
108
|
+
// cache state, so a clone would resolve into a copy that
|
|
109
|
+
// prepareAuth never sees.
|
|
110
|
+
'// #SecretsAccessor': ({ indent }: any) => secrets ?
|
|
111
|
+
Content({ indent }, `
|
|
112
|
+
secrets() {
|
|
113
|
+
return this._secrets && this._secrets.sekreto()
|
|
114
|
+
}
|
|
115
|
+
`) : undefined,
|
|
116
|
+
|
|
117
|
+
// prepare() bypasses the feature hook pipeline, so the PreSpec
|
|
118
|
+
// hook that resolves the secret for entity ops never runs on
|
|
119
|
+
// this path and the resolve has to be explicit.
|
|
120
|
+
//
|
|
121
|
+
// It RETURNS the Error rather than rejecting: _rawRequest
|
|
122
|
+
// awaits prepare() outside its try, and direct()/graphql() are
|
|
123
|
+
// documented to return a value or an Error, never reject. The
|
|
124
|
+
// prototype rejected here, which would have turned a broken
|
|
125
|
+
// vault into an unhandled rejection on the direct path.
|
|
126
|
+
'// #SecretsResolve': ({ indent }: any) => secrets ?
|
|
127
|
+
Content({ indent }, `
|
|
128
|
+
if (null != this._secrets) {
|
|
129
|
+
try {
|
|
130
|
+
await this._secrets.resolve()
|
|
131
|
+
}
|
|
132
|
+
catch (err: any) {
|
|
133
|
+
return err instanceof Error ? err : new Error(String(err))
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
`) : undefined,
|
|
137
|
+
|
|
138
|
+
'// #SecretsExport': ({ indent }: any) => secrets ?
|
|
139
|
+
Line({ indent }, 'sekreto,') : undefined,
|
|
140
|
+
|
|
77
141
|
'#BuildFeatures': ({ indent }: any) => {
|
|
78
142
|
List({ item: feature, line: false }, ({ item }: any) =>
|
|
79
143
|
Line({ indent },
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
PUBLISHER_URL,
|
|
14
14
|
packageVersion,
|
|
15
15
|
authorInfo,
|
|
16
|
+
targetFeatures,
|
|
16
17
|
} from '@voxgig/sdkgen'
|
|
17
18
|
|
|
18
19
|
|
|
@@ -36,7 +37,9 @@ const Package = cmp(async function Package(props: any) {
|
|
|
36
37
|
// constant here did.
|
|
37
38
|
const author = authorInfo(model, target.name)
|
|
38
39
|
|
|
39
|
-
|
|
40
|
+
// Gated by applicability: a feature that does not apply to this
|
|
41
|
+
// target must not inject its deps into the generated manifest.
|
|
42
|
+
const feature = targetFeatures(model, target)
|
|
40
43
|
|
|
41
44
|
const only = (kind: string, deps: any) =>
|
|
42
45
|
omap(deps, ([k, v]: any) => [v.active && kind === v.kind ? k : undefined, v.version])
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { cmp, each, Content, isAuthActive, isHttpBasicAuth } from '@voxgig/sdkgen'
|
|
2
|
+
import { cmp, each, Content, isAuthActive, isHttpBasicAuth, serverVariables } from '@voxgig/sdkgen'
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
KIT,
|
|
@@ -61,12 +61,24 @@ const ReadmeModel = cmp(function ReadmeModel(props: any) {
|
|
|
61
61
|
? '| `secret` | `string` | API secret for authentication. |\n'
|
|
62
62
|
: ''
|
|
63
63
|
|
|
64
|
+
// Server variables are not one option among many: without them the
|
|
65
|
+
// constructor THROWS, because the base URL is a template. Documented
|
|
66
|
+
// first for that reason, and named individually so a reader knows what
|
|
67
|
+
// to supply without going back to the spec.
|
|
68
|
+
const svars = serverVariables(model)
|
|
69
|
+
const serverOptionType = 0 === svars.length ? '' :
|
|
70
|
+
`\n server?: { ${svars.map((v: any) => `${v.name}: string`).join(', ')} }`
|
|
71
|
+
const serverOptionRow = 0 === svars.length ? '' :
|
|
72
|
+
'| `server` | `object` | **Required.** Values for the server-URL variables: ' +
|
|
73
|
+
svars.map((v: any) => '`' + v.name + '`').join(', ') +
|
|
74
|
+
'. The API base URL is a template over them. |\n'
|
|
75
|
+
|
|
64
76
|
Content(`### ${model.const.Name}SDK
|
|
65
77
|
|
|
66
78
|
#### Constructor
|
|
67
79
|
|
|
68
80
|
\`\`\`ts
|
|
69
|
-
new ${model.const.Name}SDK(options?: {${apikeyOptionType}${secretOptionType}
|
|
81
|
+
new ${model.const.Name}SDK(options?: {${apikeyOptionType}${secretOptionType}${serverOptionType}
|
|
70
82
|
base?: string
|
|
71
83
|
prefix?: string
|
|
72
84
|
suffix?: string
|
|
@@ -77,7 +89,7 @@ new ${model.const.Name}SDK(options?: {${apikeyOptionType}${secretOptionType}
|
|
|
77
89
|
|
|
78
90
|
| Option | Type | Description |
|
|
79
91
|
| --- | --- | --- |
|
|
80
|
-
${apikeyOptionRow}${secretOptionRow}| \`base\` | \`string\` | Base URL of the API server. |
|
|
92
|
+
${serverOptionRow}${apikeyOptionRow}${secretOptionRow}| \`base\` | \`string\` | Base URL of the API server. |
|
|
81
93
|
| \`prefix\` | \`string\` | URL path prefix prepended to all requests. |
|
|
82
94
|
| \`suffix\` | \`string\` | URL path suffix appended to all requests. |
|
|
83
95
|
| \`feature\` | \`object\` | Feature activation flags (e.g. \`{ test: { active: true } }\`). |
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { cmp, each, Content, isAuthActive, isHttpBasicAuth, packageName, envName, opRequestShape, entityIdField, entityDataIdField, entityOps, safeVarName, exampleVarName, jsKey, matchArg, idLiteral } from '@voxgig/sdkgen'
|
|
2
|
+
import { cmp, each, Content, isAuthActive, isHttpBasicAuth, packageName, envName, serverVariables, opRequestShape, entityIdField, entityDataIdField, entityOps, safeVarName, exampleVarName, jsKey, matchArg, idLiteral } from '@voxgig/sdkgen'
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
KIT,
|
|
@@ -40,10 +40,23 @@ const ReadmeQuick = cmp(function ReadmeQuick(props: any) {
|
|
|
40
40
|
!it.optional && it.name !== entityIdField(e))
|
|
41
41
|
) as any
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
// Server variables (a templated server URL) are REQUIRED at construction
|
|
44
|
+
// — makeOptions refuses rather than request a URL with a literal
|
|
45
|
+
// `{account_id}` in it — so a quickstart that omits them is a quickstart
|
|
46
|
+
// that throws on its first line.
|
|
47
|
+
const svarLines = serverVariables(model)
|
|
48
|
+
.map((v: any) => `\n ${v.name}: '<${v.name}>',`).join('')
|
|
49
|
+
const serverField = '' === svarLines ? '' :
|
|
50
|
+
`\n // Required: this API's server URL is templated on these.\n server: {${svarLines}\n },`
|
|
51
|
+
|
|
52
|
+
const ctorFields = (isAuthActive(model)
|
|
53
|
+
? `\n apikey: process.env.${envName(model)}_APIKEY,${
|
|
54
|
+
isHttpBasicAuth(model) ? `\n secret: process.env.${envName(model)}_SECRET,` : ''}`
|
|
55
|
+
: '') + serverField
|
|
56
|
+
|
|
57
|
+
const ctor = '' === ctorFields
|
|
58
|
+
? `new ${model.const.Name}SDK()`
|
|
59
|
+
: `new ${model.const.Name}SDK({${ctorFields}\n})`
|
|
47
60
|
|
|
48
61
|
Content(`### 1. Create a client
|
|
49
62
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { cmp, Content, isAuthActive, isHttpBasicAuth, packageName, envName, entityIdField, entityOps, opRequestShape, safeVarName, exampleVarName, jsKey, matchArg, idLiteral } from '@voxgig/sdkgen'
|
|
2
|
+
import { cmp, Content, isAuthActive, isHttpBasicAuth, packageName, envName, entityIdField, entityOps, opRequestShape, safeVarName, exampleVarName, jsKey, matchArg, idLiteral , serverVariables} from '@voxgig/sdkgen'
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
KIT,
|
|
@@ -28,10 +28,24 @@ const ReadmeTopQuick = cmp(function ReadmeTopQuick(props: any) {
|
|
|
28
28
|
const exampleEntity = Object.values(entity).find((e: any) => e.active !== false) as any
|
|
29
29
|
|
|
30
30
|
const authActive = isAuthActive(model)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
|
|
32
|
+
// Server variables (a templated server URL) are REQUIRED at construction
|
|
33
|
+
// - makeOptions refuses rather than request a URL with a literal
|
|
34
|
+
// {account_id} in it - so a quickstart that omits them is a quickstart
|
|
35
|
+
// that throws on its first line.
|
|
36
|
+
const svarLines = serverVariables(model)
|
|
37
|
+
.map((v: any) => `\n ${v.name}: '<${v.name}>',`).join('')
|
|
38
|
+
const serverField = '' === svarLines ? '' :
|
|
39
|
+
`\n // Required: this API's server URL is templated on these.\n server: {${svarLines}\n },`
|
|
40
|
+
|
|
41
|
+
const ctorFields = (authActive
|
|
42
|
+
? `\n apikey: process.env.${envName(model)}_APIKEY,${
|
|
43
|
+
isHttpBasicAuth(model) ? `\n secret: process.env.${envName(model)}_SECRET,` : ''}`
|
|
44
|
+
: '') + serverField
|
|
45
|
+
|
|
46
|
+
const ctor = '' === ctorFields
|
|
47
|
+
? `new ${model.const.Name}SDK()`
|
|
48
|
+
: `new ${model.const.Name}SDK({${ctorFields}\n})`
|
|
35
49
|
|
|
36
50
|
Content(`\`\`\`ts
|
|
37
51
|
import { ${model.const.Name}SDK } from '${packageName(model, target.name)}'
|