@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
|
@@ -30,7 +30,11 @@ import {
|
|
|
30
30
|
cmp,
|
|
31
31
|
each,
|
|
32
32
|
isAuthActive,
|
|
33
|
-
|
|
33
|
+
serverVarEnv,
|
|
34
|
+
serverVariables,
|
|
35
|
+
entityDataIdField, envName, envToken,
|
|
36
|
+
jsKey,
|
|
37
|
+
jsProp
|
|
34
38
|
} from '@voxgig/sdkgen'
|
|
35
39
|
|
|
36
40
|
|
|
@@ -63,13 +67,32 @@ const TestEntity = cmp(function TestEntity(props: any) {
|
|
|
63
67
|
const ENTENVNAME = envToken(entity.name)
|
|
64
68
|
const authActive = isAuthActive(model)
|
|
65
69
|
const apikeyEnvEntry = authActive
|
|
66
|
-
? `\n '${PROJENVNAME}_APIKEY': '
|
|
70
|
+
? `\n '${PROJENVNAME}_APIKEY': '',`
|
|
67
71
|
: ''
|
|
68
72
|
const apikeyLiveField = authActive
|
|
69
73
|
? `
|
|
70
74
|
apikey: env.${PROJENVNAME}_APIKEY,`
|
|
71
75
|
: ''
|
|
72
76
|
|
|
77
|
+
// A templated server URL (OpenAPI server variables) makes a LIVE client
|
|
78
|
+
// impossible to construct without values: makeOptions raises rather than
|
|
79
|
+
// request a URL with a literal `{account_id}` in it. So the live suite
|
|
80
|
+
// takes them from the environment the same way it takes the apikey.
|
|
81
|
+
//
|
|
82
|
+
// Keys are quoted and the env read is bracketed via jsKey/jsProp: a server
|
|
83
|
+
// variable name is spec-derived and need not be a JS identifier — the URL
|
|
84
|
+
// grammar admits a leading digit ({2fa}), and a declared-but-unreferenced
|
|
85
|
+
// variable ({edge-zone}) is not constrained at all. Bare `name:` and
|
|
86
|
+
// `env.PROJ_SERVER_EDGE-ZONE` are both syntax errors.
|
|
87
|
+
const svars = serverVariables(model)
|
|
88
|
+
const serverEnvEntry = svars
|
|
89
|
+
.map((v: any) => `\n '${serverVarEnv(PROJENVNAME, v.name)}': ${JSON.stringify(v.dflt)},`).join('')
|
|
90
|
+
const serverLiveField = 0 === svars.length ? '' : `
|
|
91
|
+
server: {${svars
|
|
92
|
+
.map((v: any) => `
|
|
93
|
+
${jsKey(v.name)}: ${jsProp('env', serverVarEnv(PROJENVNAME, v.name))},`).join('')}
|
|
94
|
+
},`
|
|
95
|
+
|
|
73
96
|
// TODO: should be a utility function
|
|
74
97
|
const ff = projectPath('src/cmp/js/fragment/')
|
|
75
98
|
|
|
@@ -143,16 +166,23 @@ function basicSetup(extra) {
|
|
|
143
166
|
const env = envOverride({
|
|
144
167
|
'${PROJENVNAME}_TEST_${ENTENVNAME}_ENTID': idmap,
|
|
145
168
|
'${PROJENVNAME}_TEST_LIVE': 'FALSE',
|
|
146
|
-
'${PROJENVNAME}_TEST_EXPLAIN': 'FALSE',${apikeyEnvEntry}
|
|
169
|
+
'${PROJENVNAME}_TEST_EXPLAIN': 'FALSE',${apikeyEnvEntry}${serverEnvEntry}
|
|
147
170
|
})
|
|
148
171
|
|
|
149
172
|
idmap = env['${PROJENVNAME}_TEST_${ENTENVNAME}_ENTID']
|
|
150
173
|
|
|
151
174
|
if ('TRUE' === env.${PROJENVNAME}_TEST_LIVE) {
|
|
152
175
|
client = new ${model.Name}SDK(merge([
|
|
153
|
-
|
|
176
|
+
// FIRST, so the generated fields below win: sdk-test-control.json's
|
|
177
|
+
// test.client.options adds to the live client, it does not redirect it.
|
|
178
|
+
liveClientOptions(),
|
|
179
|
+
{${apikeyLiveField}${serverLiveField}
|
|
154
180
|
},
|
|
155
|
-
extra
|
|
181
|
+
// 'extra || {}', not a bare 'extra': struct.merge returns UNDEFINED when
|
|
182
|
+
// the last entry is undefined, and basicSetup is normally called with no
|
|
183
|
+
// argument at all - so a bare 'extra' silently discarded the apikey and
|
|
184
|
+
// server values above and handed the SDK undefined.
|
|
185
|
+
extra || {}
|
|
156
186
|
]))
|
|
157
187
|
}
|
|
158
188
|
|
|
@@ -3,7 +3,8 @@ import type {
|
|
|
3
3
|
ModelEntity
|
|
4
4
|
} from '@voxgig/apidef'
|
|
5
5
|
|
|
6
|
-
import { cmp, each, Folder, entityCollection
|
|
6
|
+
import { cmp, each, Folder, entityCollection,
|
|
7
|
+
TestControl } from '@voxgig/sdkgen'
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
import { TestDirect } from './TestDirect_js'
|
|
@@ -16,6 +17,9 @@ const Test = cmp(function Test(props: any) {
|
|
|
16
17
|
|
|
17
18
|
Folder({ name: 'test' }, () => {
|
|
18
19
|
|
|
20
|
+
// Write-once: a project's edited control file survives regeneration.
|
|
21
|
+
TestControl({ target, dir: 'test' })
|
|
22
|
+
|
|
19
23
|
Folder({ name: 'entity' }, () => {
|
|
20
24
|
const entity = each(entityCollection(model))
|
|
21
25
|
.filter((e: any) => false !== e.active)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const envlocal = __dirname + '/../../../.env.local'
|
|
3
3
|
require('dotenv').config({ quiet: true, path: [envlocal] })
|
|
4
4
|
|
|
5
|
-
const { test, describe } = require('node:test')
|
|
5
|
+
const { test, describe, afterEach } = require('node:test')
|
|
6
6
|
const assert = require('node:assert')
|
|
7
7
|
|
|
8
8
|
|
|
@@ -10,11 +10,17 @@ const { ProjectNameSDK } = require('../../..')
|
|
|
10
10
|
|
|
11
11
|
const {
|
|
12
12
|
envOverride,
|
|
13
|
+
liveClientOptions,
|
|
14
|
+
liveDelay,
|
|
13
15
|
} = require('../../utility')
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
describe('EntityNameDirect', async () => {
|
|
17
19
|
|
|
20
|
+
// Per-test live pacing. Delay is read from sdk-test-control.json's
|
|
21
|
+
// `test.live.delayMs`; only sleeps when PROJECTENV_TEST_LIVE=TRUE.
|
|
22
|
+
afterEach(liveDelay('PROJECTENV_TEST_LIVE'))
|
|
23
|
+
|
|
18
24
|
test('direct-exists', async () => {
|
|
19
25
|
const sdk = new ProjectNameSDK({
|
|
20
26
|
// Concrete base: a live construction must satisfy any server
|
|
@@ -5,7 +5,7 @@ require('dotenv').config({ quiet: true, path: [envlocal] })
|
|
|
5
5
|
const Path = require('node:path')
|
|
6
6
|
const Fs = require('node:fs')
|
|
7
7
|
|
|
8
|
-
const { test, describe } = require('node:test')
|
|
8
|
+
const { test, describe, afterEach } = require('node:test')
|
|
9
9
|
const assert = require('node:assert')
|
|
10
10
|
|
|
11
11
|
|
|
@@ -13,6 +13,8 @@ const { ProjectNameSDK, BaseFeature, stdutil, config } = require('../../..')
|
|
|
13
13
|
|
|
14
14
|
const {
|
|
15
15
|
envOverride,
|
|
16
|
+
liveClientOptions,
|
|
17
|
+
liveDelay,
|
|
16
18
|
makeCtrl,
|
|
17
19
|
makeMatch,
|
|
18
20
|
makeReqdata,
|
|
@@ -23,6 +25,10 @@ const {
|
|
|
23
25
|
|
|
24
26
|
describe('EntityNameEntity', async () => {
|
|
25
27
|
|
|
28
|
+
// Per-test live pacing. Delay is read from sdk-test-control.json's
|
|
29
|
+
// `test.live.delayMs`; only sleeps when PROJECTENV_TEST_LIVE=TRUE.
|
|
30
|
+
afterEach(liveDelay('PROJECTENV_TEST_LIVE'))
|
|
31
|
+
|
|
26
32
|
test('instance', async () => {
|
|
27
33
|
const testsdk = ProjectNameSDK.test()
|
|
28
34
|
const ent = testsdk.EntityName()
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
each,
|
|
8
8
|
isAuthActive,
|
|
9
9
|
resolveAuthPrefix,
|
|
10
|
+
targetFeatures,
|
|
10
11
|
} from '@voxgig/sdkgen'
|
|
11
12
|
|
|
12
13
|
|
|
@@ -36,7 +37,10 @@ const Config = cmp(async function Config(props: any) {
|
|
|
36
37
|
const kotlinpackage = kotlinPackage(model)
|
|
37
38
|
|
|
38
39
|
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
39
|
-
|
|
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)
|
|
40
44
|
|
|
41
45
|
const headers = getModelPath(model, `main.${KIT}.config.headers`) || {}
|
|
42
46
|
|
|
@@ -4,6 +4,7 @@ import * as Path from 'node:path'
|
|
|
4
4
|
import {
|
|
5
5
|
cmp, each,
|
|
6
6
|
File, Copy, Folder, Fragment,
|
|
7
|
+
TEST_CONTROL_EXCLUDE
|
|
7
8
|
} from '@voxgig/sdkgen'
|
|
8
9
|
|
|
9
10
|
|
|
@@ -47,7 +48,7 @@ const Main = cmp(async function Main(props: any) {
|
|
|
47
48
|
// token used throughout the templates (package/import statements).
|
|
48
49
|
Copy({
|
|
49
50
|
from: 'tm/' + target.name,
|
|
50
|
-
exclude: [/src
|
|
51
|
+
exclude: [/src\//, TEST_CONTROL_EXCLUDE],
|
|
51
52
|
replace: {
|
|
52
53
|
...props.ctx$.stdrep,
|
|
53
54
|
KOTLINPACKAGE: kotlinpackage,
|
|
@@ -3,7 +3,8 @@ import type {
|
|
|
3
3
|
ModelEntity
|
|
4
4
|
} from '@voxgig/apidef'
|
|
5
5
|
|
|
6
|
-
import { cmp, each, Folder, entityCollection
|
|
6
|
+
import { cmp, each, Folder, entityCollection,
|
|
7
|
+
TestControl } from '@voxgig/sdkgen'
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
import { TestEntity } from './TestEntity_kotlin'
|
|
@@ -20,6 +21,9 @@ const Test = cmp(function Test(props: any) {
|
|
|
20
21
|
|
|
21
22
|
Folder({ name: 'test' }, () => {
|
|
22
23
|
|
|
24
|
+
// Write-once: a project's edited control file survives regeneration.
|
|
25
|
+
TestControl({ target, dir: 'test' })
|
|
26
|
+
|
|
23
27
|
// The shared test infrastructure (RunnerSupport, FeatureHarness,
|
|
24
28
|
// PipelineTest, FeatureTest, NetsimTest, PrimaryUtilityTest,
|
|
25
29
|
// CustomUtilityTest, StructRunner/StructCorpusTest, ExistsTest and
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
each,
|
|
6
6
|
isAuthActive,
|
|
7
7
|
resolveAuthPrefix,
|
|
8
|
+
targetFeatures,
|
|
8
9
|
} from '@voxgig/sdkgen'
|
|
9
10
|
|
|
10
11
|
import {
|
|
@@ -29,7 +30,10 @@ const Config = cmp(async function Config(props: any) {
|
|
|
29
30
|
const model: Model = ctx$.model
|
|
30
31
|
|
|
31
32
|
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
32
|
-
|
|
33
|
+
// Gated by the applicability tags, so this target never imports or
|
|
34
|
+
// registers a feature it has no source for. One rule, one place:
|
|
35
|
+
// helpers/applicability.
|
|
36
|
+
const feature = targetFeatures(model, target)
|
|
33
37
|
const headers = getModelPath(model, `main.${KIT}.config.headers`) || {}
|
|
34
38
|
|
|
35
39
|
const authActive = isAuthActive(model)
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
isConfigData,
|
|
16
16
|
resolveAuthPrefix,
|
|
17
17
|
serverVariables,
|
|
18
|
+
targetFeatures,
|
|
18
19
|
} from '@voxgig/sdkgen'
|
|
19
20
|
|
|
20
21
|
|
|
@@ -40,7 +41,10 @@ const Config = cmp(async function Config(props: any) {
|
|
|
40
41
|
const model: Model = ctx$.model
|
|
41
42
|
|
|
42
43
|
const entity = getModelPath(model, `main.${KIT}.entity`)
|
|
43
|
-
|
|
44
|
+
// Gated by the applicability tags, so this target never imports or
|
|
45
|
+
// registers a feature it has no source for. One rule, one place:
|
|
46
|
+
// helpers/applicability.
|
|
47
|
+
const feature = targetFeatures(model, target)
|
|
44
48
|
|
|
45
49
|
const headers = getModelPath(model, `main.${KIT}.config.headers`) || {}
|
|
46
50
|
|
|
@@ -4,6 +4,8 @@ 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
|
+
targetFeatures,
|
|
8
|
+
TEST_CONTROL_EXCLUDE
|
|
7
9
|
} from '@voxgig/sdkgen'
|
|
8
10
|
|
|
9
11
|
|
|
@@ -31,7 +33,10 @@ const Main = cmp(async function Main(props: any) {
|
|
|
31
33
|
const { model } = props.ctx$
|
|
32
34
|
|
|
33
35
|
const entity: ModelEntity = getModelPath(model, `main.${KIT}.entity`)
|
|
34
|
-
|
|
36
|
+
// Gated by the applicability tags, so this target never imports or
|
|
37
|
+
// registers a feature it has no source for. One rule, one place:
|
|
38
|
+
// helpers/applicability.
|
|
39
|
+
const feature = targetFeatures(model, target)
|
|
35
40
|
|
|
36
41
|
Package({ target })
|
|
37
42
|
|
|
@@ -40,7 +45,7 @@ const Main = cmp(async function Main(props: any) {
|
|
|
40
45
|
// Copy tm/lua files with replacements
|
|
41
46
|
Copy({
|
|
42
47
|
from: 'tm/' + target.name,
|
|
43
|
-
exclude: [/src
|
|
48
|
+
exclude: [/src\//, TEST_CONTROL_EXCLUDE],
|
|
44
49
|
replace: {
|
|
45
50
|
...props.ctx$.stdrep,
|
|
46
51
|
}
|
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
keywords,
|
|
10
10
|
repoInfo, packageName,
|
|
11
11
|
packageVersion,
|
|
12
|
+
targetFeatures,
|
|
12
13
|
} from '@voxgig/sdkgen'
|
|
13
14
|
|
|
14
15
|
|
|
@@ -78,7 +79,9 @@ dependencies = {
|
|
|
78
79
|
// factory falls back to. The station feature additionally carries the
|
|
79
80
|
// VENDORED voxgig_station library beside its adapter (no voxgig-station
|
|
80
81
|
// rock exists to depend on - station design 9.2's registry-less tier).
|
|
81
|
-
|
|
82
|
+
// Gated: a feature that does not apply to lua must not be listed
|
|
83
|
+
// as a rockspec module — the require would not resolve.
|
|
84
|
+
const feature = targetFeatures(model, target)
|
|
82
85
|
let featureModules = ` ["feature.base_feature"] = "feature/base_feature.lua",\n`
|
|
83
86
|
each(feature, (f: any) => {
|
|
84
87
|
featureModules +=
|
|
@@ -11,9 +11,13 @@ 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
|
|
|
19
|
+
import { formatLuaValue } from './utility_lua'
|
|
20
|
+
|
|
17
21
|
|
|
18
22
|
function normalizePathParams(
|
|
19
23
|
parts: string[],
|
|
@@ -64,12 +68,25 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
64
68
|
|
|
65
69
|
const authActive = isAuthActive(model)
|
|
66
70
|
const apikeyEnvEntry = authActive
|
|
67
|
-
? `\n ["${PROJECTNAME}_APIKEY"] = "
|
|
71
|
+
? `\n ["${PROJECTNAME}_APIKEY"] = "",`
|
|
68
72
|
: ''
|
|
69
73
|
const apikeyLiveField = authActive
|
|
70
74
|
? `\n apikey = env["${PROJECTNAME}_APIKEY"],`
|
|
71
75
|
: ''
|
|
72
76
|
|
|
77
|
+
// A templated server URL (OpenAPI server variables) makes a LIVE client
|
|
78
|
+
// impossible to construct without values: makeOptions raises rather than
|
|
79
|
+
// request a URL with a literal `{account_id}` in it. So the live suite
|
|
80
|
+
// takes them from the environment the same way it takes the apikey.
|
|
81
|
+
const svars = serverVariables(model)
|
|
82
|
+
const serverEnvEntry = svars
|
|
83
|
+
.map((v: any) => `\n ["${serverVarEnv(PROJECTNAME, v.name)}"] = ${formatLuaValue(v.dflt)},`).join('')
|
|
84
|
+
const serverLiveField = 0 === svars.length ? '' : `
|
|
85
|
+
server = {${svars
|
|
86
|
+
.map((v: any) => `
|
|
87
|
+
["${v.name}"] = env["${serverVarEnv(PROJECTNAME, v.name)}"],`).join('')}
|
|
88
|
+
},`
|
|
89
|
+
|
|
73
90
|
const opnames = Object.keys(entity.op || {})
|
|
74
91
|
const hasLoad = opnames.includes('load')
|
|
75
92
|
const hasList = opnames.includes('list')
|
|
@@ -350,14 +367,21 @@ function ${entity.name}_direct_setup(mockres)
|
|
|
350
367
|
|
|
351
368
|
local env = runner.env_override({
|
|
352
369
|
["${entidEnvVar}"] = {},
|
|
353
|
-
["${PROJECTNAME}_TEST_LIVE"] = "FALSE",${apikeyEnvEntry}
|
|
370
|
+
["${PROJECTNAME}_TEST_LIVE"] = "FALSE",${apikeyEnvEntry}${serverEnvEntry}
|
|
354
371
|
})
|
|
355
372
|
|
|
356
373
|
local live = env["${PROJECTNAME}_TEST_LIVE"] == "TRUE"
|
|
357
374
|
|
|
358
375
|
if live then
|
|
359
|
-
local merged_opts = {${apikeyLiveField}
|
|
376
|
+
local merged_opts = {${apikeyLiveField}${serverLiveField}
|
|
360
377
|
}
|
|
378
|
+
-- sdk-test-control.json's test.client.options goes UNDER the generated
|
|
379
|
+
-- fields: it adds to the live client, it does not redirect it.
|
|
380
|
+
for _k, _v in pairs(runner.live_client_options()) do
|
|
381
|
+
if merged_opts[_k] == nil then
|
|
382
|
+
merged_opts[_k] = _v
|
|
383
|
+
end
|
|
384
|
+
end
|
|
361
385
|
local client = sdk.new(merged_opts)
|
|
362
386
|
return {
|
|
363
387
|
client = client,
|
|
@@ -24,9 +24,13 @@ import {
|
|
|
24
24
|
buildIdNames,
|
|
25
25
|
getMatchEntries,
|
|
26
26
|
isAuthActive,
|
|
27
|
-
entityDataIdField, envName, envToken
|
|
27
|
+
entityDataIdField, envName, envToken,
|
|
28
|
+
serverVarEnv,
|
|
29
|
+
serverVariables
|
|
28
30
|
} from '@voxgig/sdkgen'
|
|
29
31
|
|
|
32
|
+
import { formatLuaValue } from './utility_lua'
|
|
33
|
+
|
|
30
34
|
|
|
31
35
|
// See TestEntity_ts.ts for the GenCtx/OpGen contract.
|
|
32
36
|
type GenCtx = {
|
|
@@ -62,12 +66,25 @@ const TestEntity = cmp(function TestEntity(props: any) {
|
|
|
62
66
|
|
|
63
67
|
const authActive = isAuthActive(model)
|
|
64
68
|
const apikeyEnvEntry = authActive
|
|
65
|
-
? `\n ["${PROJUPPER}_APIKEY"] = "
|
|
69
|
+
? `\n ["${PROJUPPER}_APIKEY"] = "",`
|
|
66
70
|
: ''
|
|
67
71
|
const apikeyLiveField = authActive
|
|
68
72
|
? `\n apikey = env["${PROJUPPER}_APIKEY"],`
|
|
69
73
|
: ''
|
|
70
74
|
|
|
75
|
+
// A templated server URL (OpenAPI server variables) makes a LIVE client
|
|
76
|
+
// impossible to construct without values: makeOptions raises rather than
|
|
77
|
+
// request a URL with a literal `{account_id}` in it. So the live suite
|
|
78
|
+
// takes them from the environment the same way it takes the apikey.
|
|
79
|
+
const svars = serverVariables(model)
|
|
80
|
+
const serverEnvEntry = svars
|
|
81
|
+
.map((v: any) => `\n ["${serverVarEnv(PROJUPPER, v.name)}"] = ${formatLuaValue(v.dflt)},`).join('')
|
|
82
|
+
const serverLiveField = 0 === svars.length ? '' : `
|
|
83
|
+
server = {${svars
|
|
84
|
+
.map((v: any) => `
|
|
85
|
+
["${v.name}"] = env["${serverVarEnv(PROJUPPER, v.name)}"],`).join('')}
|
|
86
|
+
},`
|
|
87
|
+
|
|
71
88
|
const idnames = buildIdNames(entity, basicflow)
|
|
72
89
|
const idnamesStr = idnames.map(n => `"${n}"`).join(', ')
|
|
73
90
|
|
|
@@ -241,7 +258,7 @@ end)
|
|
|
241
258
|
local env = runner.env_override({
|
|
242
259
|
["${PROJUPPER}_TEST_${envToken(entity.name)}_ENTID"] = idmap,
|
|
243
260
|
["${PROJUPPER}_TEST_LIVE"] = "FALSE",
|
|
244
|
-
["${PROJUPPER}_TEST_EXPLAIN"] = "FALSE",${apikeyEnvEntry}
|
|
261
|
+
["${PROJUPPER}_TEST_EXPLAIN"] = "FALSE",${apikeyEnvEntry}${serverEnvEntry}
|
|
245
262
|
})
|
|
246
263
|
|
|
247
264
|
local idmap_resolved = helpers.to_map(
|
|
@@ -262,7 +279,10 @@ end)
|
|
|
262
279
|
Content(`
|
|
263
280
|
if env["${PROJUPPER}_TEST_LIVE"] == "TRUE" then
|
|
264
281
|
local merged_opts = vs.merge({
|
|
265
|
-
|
|
282
|
+
-- FIRST, so the generated fields below win: sdk-test-control.json's
|
|
283
|
+
-- test.client.options adds to the live client, it does not redirect it.
|
|
284
|
+
runner.live_client_options(),
|
|
285
|
+
{${apikeyLiveField}${serverLiveField}
|
|
266
286
|
},
|
|
267
287
|
extra or {},
|
|
268
288
|
})
|
|
@@ -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_lua'
|
|
@@ -17,6 +18,9 @@ const Test = cmp(function Test(props: any) {
|
|
|
17
18
|
|
|
18
19
|
Folder({ name: 'test' }, () => {
|
|
19
20
|
|
|
21
|
+
// Write-once: a project's edited control file survives regeneration.
|
|
22
|
+
TestControl({ target, dir: 'test' })
|
|
23
|
+
|
|
20
24
|
// Generate exists test
|
|
21
25
|
File({ name: 'exists_test.' + target.ext }, () => {
|
|
22
26
|
Content(`-- ${model.const.Name} SDK exists test
|
|
@@ -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
|
|
|
@@ -34,7 +35,10 @@ const Config = cmp(async function Config(props: any) {
|
|
|
34
35
|
|
|
35
36
|
const model: Model = ctx$.model
|
|
36
37
|
|
|
37
|
-
|
|
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)
|
|
38
42
|
|
|
39
43
|
// The canonical config OBJECT and its JSON, from the shared helper. Both
|
|
40
44
|
// representations render from the same `def`, so they cannot describe
|
|
@@ -4,6 +4,8 @@ import * as Path from 'node:path'
|
|
|
4
4
|
import {
|
|
5
5
|
cmp, each, names,
|
|
6
6
|
File, Content, Copy, Folder, Fragment,
|
|
7
|
+
targetFeatures,
|
|
8
|
+
TEST_CONTROL_EXCLUDE
|
|
7
9
|
} from '@voxgig/sdkgen'
|
|
8
10
|
|
|
9
11
|
|
|
@@ -36,7 +38,10 @@ const Main = cmp(async function Main(props: any) {
|
|
|
36
38
|
const { model } = props.ctx$
|
|
37
39
|
|
|
38
40
|
const entity: ModelEntity = getModelPath(model, `main.${KIT}.entity`)
|
|
39
|
-
|
|
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)
|
|
40
45
|
|
|
41
46
|
Package({ target })
|
|
42
47
|
|
|
@@ -45,7 +50,7 @@ const Main = cmp(async function Main(props: any) {
|
|
|
45
50
|
// Copy tm/perl files with replacements
|
|
46
51
|
Copy({
|
|
47
52
|
from: 'tm/' + target.name,
|
|
48
|
-
exclude: [/src
|
|
53
|
+
exclude: [/src\//, TEST_CONTROL_EXCLUDE],
|
|
49
54
|
replace: {
|
|
50
55
|
...props.ctx$.stdrep,
|
|
51
56
|
}
|
|
@@ -11,9 +11,13 @@ 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
|
|
|
19
|
+
import { perlStringLiteral } from './utility_perl'
|
|
20
|
+
|
|
17
21
|
|
|
18
22
|
function normalizePathParams(
|
|
19
23
|
parts: string[],
|
|
@@ -74,12 +78,25 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
74
78
|
|
|
75
79
|
const authActive = isAuthActive(model)
|
|
76
80
|
const apikeyEnvEntry = authActive
|
|
77
|
-
? `\n '${PROJECTNAME}_APIKEY' => '
|
|
81
|
+
? `\n '${PROJECTNAME}_APIKEY' => '',`
|
|
78
82
|
: ''
|
|
79
83
|
const apikeyLiveField = authActive
|
|
80
84
|
? `\n 'apikey' => $env->{'${PROJECTNAME}_APIKEY'},`
|
|
81
85
|
: ''
|
|
82
86
|
|
|
87
|
+
// A templated server URL (OpenAPI server variables) makes a LIVE client
|
|
88
|
+
// impossible to construct without values: makeOptions raises rather than
|
|
89
|
+
// request a URL with a literal `{account_id}` in it. So the live suite
|
|
90
|
+
// takes them from the environment the same way it takes the apikey.
|
|
91
|
+
const svars = serverVariables(model)
|
|
92
|
+
const serverEnvEntry = svars
|
|
93
|
+
.map((v: any) => `\n '${serverVarEnv(PROJECTNAME, v.name)}' => ${perlStringLiteral(v.dflt)},`).join('')
|
|
94
|
+
const serverLiveField = 0 === svars.length ? '' : `
|
|
95
|
+
'server' => {${svars
|
|
96
|
+
.map((v: any) => `
|
|
97
|
+
'${v.name}' => $env->{'${serverVarEnv(PROJECTNAME, v.name)}'},`).join('')}
|
|
98
|
+
},`
|
|
99
|
+
|
|
83
100
|
const opnames = Object.keys(entity.op || {})
|
|
84
101
|
const hasLoad = opnames.includes('load')
|
|
85
102
|
const hasList = opnames.includes('list')
|
|
@@ -377,13 +394,17 @@ sub ${entity.name}_direct_setup {
|
|
|
377
394
|
|
|
378
395
|
my $env = ${N}TestRunner::env_override({
|
|
379
396
|
'${entidEnvVar}' => {},
|
|
380
|
-
'${PROJECTNAME}_TEST_LIVE' => 'FALSE',${apikeyEnvEntry}
|
|
397
|
+
'${PROJECTNAME}_TEST_LIVE' => 'FALSE',${apikeyEnvEntry}${serverEnvEntry}
|
|
381
398
|
});
|
|
382
399
|
|
|
383
400
|
my $live = ((($env->{'${PROJECTNAME}_TEST_LIVE'}) || '') eq 'TRUE') ? 1 : 0;
|
|
384
401
|
|
|
385
402
|
if ($live) {
|
|
386
|
-
|
|
403
|
+
# live_client_options() FIRST so the generated fields below win:
|
|
404
|
+
# sdk-test-control.json's test.client.options adds to the live client,
|
|
405
|
+
# it does not redirect it (a later key wins in a Perl hash literal).
|
|
406
|
+
my $client = ${N}SDK->new({
|
|
407
|
+
%{ ${N}TestRunner::live_client_options() },${apikeyLiveField}${serverLiveField}
|
|
387
408
|
});
|
|
388
409
|
return {
|
|
389
410
|
'client' => $client,
|
|
@@ -17,9 +17,13 @@ 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
|
|
|
25
|
+
import { perlStringLiteral } from './utility_perl'
|
|
26
|
+
|
|
23
27
|
|
|
24
28
|
// See TestEntity_ts.ts for the GenCtx/OpGen contract. Flow-step variables
|
|
25
29
|
// are held in a single declared perl hash (%V) so generated steps never
|
|
@@ -54,12 +58,25 @@ const TestEntity = cmp(function TestEntity(props: any) {
|
|
|
54
58
|
|
|
55
59
|
const authActive = isAuthActive(model)
|
|
56
60
|
const apikeyEnvEntry = authActive
|
|
57
|
-
? `\n '${PROJUPPER}_APIKEY' => '
|
|
61
|
+
? `\n '${PROJUPPER}_APIKEY' => '',`
|
|
58
62
|
: ''
|
|
59
63
|
const apikeyLiveField = authActive
|
|
60
64
|
? `\n 'apikey' => $env->{'${PROJUPPER}_APIKEY'},`
|
|
61
65
|
: ''
|
|
62
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
|
+
const svars = serverVariables(model)
|
|
72
|
+
const serverEnvEntry = svars
|
|
73
|
+
.map((v: any) => `\n '${serverVarEnv(PROJUPPER, v.name)}' => ${perlStringLiteral(v.dflt)},`).join('')
|
|
74
|
+
const serverLiveField = 0 === svars.length ? '' : `
|
|
75
|
+
'server' => {${svars
|
|
76
|
+
.map((v: any) => `
|
|
77
|
+
'${v.name}' => $env->{'${serverVarEnv(PROJUPPER, v.name)}'},`).join('')}
|
|
78
|
+
},`
|
|
79
|
+
|
|
63
80
|
const idnames = buildIdNames(entity, basicflow)
|
|
64
81
|
const idnamesStr = idnames.map(n => `'${n}'`).join(', ')
|
|
65
82
|
|
|
@@ -193,7 +210,7 @@ BASIC_FLOW: {
|
|
|
193
210
|
my $env = ${N}TestRunner::env_override({
|
|
194
211
|
'${ENTIDVAR}' => $idmap,
|
|
195
212
|
'${PROJUPPER}_TEST_LIVE' => 'FALSE',
|
|
196
|
-
'${PROJUPPER}_TEST_EXPLAIN' => 'FALSE',${apikeyEnvEntry}
|
|
213
|
+
'${PROJUPPER}_TEST_EXPLAIN' => 'FALSE',${apikeyEnvEntry}${serverEnvEntry}
|
|
197
214
|
});
|
|
198
215
|
|
|
199
216
|
my $idmap_resolved = ${N}Helpers::to_map($env->{'${ENTIDVAR}'});
|
|
@@ -213,7 +230,10 @@ BASIC_FLOW: {
|
|
|
213
230
|
Content(`
|
|
214
231
|
if ((($env->{'${PROJUPPER}_TEST_LIVE'}) || '') eq 'TRUE') {
|
|
215
232
|
my $merged_opts = Voxgig::Struct::merge([
|
|
216
|
-
|
|
233
|
+
# FIRST, so the generated fields below win: sdk-test-control.json's
|
|
234
|
+
# test.client.options adds to the live client, it does not redirect it.
|
|
235
|
+
${N}TestRunner::live_client_options(),
|
|
236
|
+
{${apikeyLiveField}${serverLiveField}
|
|
217
237
|
},
|
|
218
238
|
(Voxgig::Struct::ismap($extra) ? $extra : {}),
|
|
219
239
|
]);
|
|
@@ -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_perl'
|
|
@@ -17,6 +18,9 @@ const Test = cmp(function Test(props: any) {
|
|
|
17
18
|
|
|
18
19
|
Folder({ name: 't' }, () => {
|
|
19
20
|
|
|
21
|
+
// Write-once: a project's edited control file survives regeneration.
|
|
22
|
+
TestControl({ target, dir: 't' })
|
|
23
|
+
|
|
20
24
|
// Generate exists test
|
|
21
25
|
File({ name: 'exists.t' }, () => {
|
|
22
26
|
Content(`#!perl
|
|
@@ -75,7 +75,17 @@ function clean(o: any, dropDefaults?: boolean): any {
|
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
|
|
78
|
+
// A Perl SINGLE-quoted string literal. Single quotes do not interpolate, so a
|
|
79
|
+
// spec-derived value containing $foo or @foo survives verbatim; only the
|
|
80
|
+
// backslash and the quote itself need escaping. A double-quoted literal (what
|
|
81
|
+
// JSON.stringify emits) would interpolate them.
|
|
82
|
+
function perlStringLiteral(val: string): string {
|
|
83
|
+
return "'" + String(val).replace(/\\/g, '\\\\').replace(/'/g, "\\'") + "'"
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
|
|
78
87
|
export {
|
|
88
|
+
perlStringLiteral,
|
|
79
89
|
clean,
|
|
80
90
|
projectPath,
|
|
81
91
|
}
|