@voxgig/sdkgen 4.6.0 → 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/cmp/Feature.js +5 -0
- package/dist/cmp/Feature.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/featureSource.d.ts +3 -1
- package/dist/helpers/featureSource.js +105 -0
- package/dist/helpers/featureSource.js.map +1 -1
- package/dist/sdkgen.d.ts +3 -2
- package/dist/sdkgen.js +9 -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 +52 -0
- package/dist/utility.js.map +1 -1
- package/model/sdkgen.aon +58 -0
- package/package.json +1 -1
- package/project/.sdk/model/feature/secrets.aon +82 -0
- 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/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/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/go/Main_go.ts +2 -1
- package/project/.sdk/src/cmp/go/Test_go.ts +5 -1
- package/project/.sdk/src/cmp/java/Main_java.ts +2 -1
- package/project/.sdk/src/cmp/java/Test_java.ts +5 -1
- package/project/.sdk/src/cmp/js/Main_js.ts +2 -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/Main_kotlin.ts +2 -1
- package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +5 -1
- package/project/.sdk/src/cmp/lua/Main_lua.ts +2 -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/Gitignore_ocaml.ts +1 -0
- package/project/.sdk/src/cmp/perl/Main_perl.ts +2 -1
- 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/Main_php.ts +2 -1
- 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/Main_py.ts +2 -1
- package/project/.sdk/src/cmp/py/Test_py.ts +5 -1
- package/project/.sdk/src/cmp/rb/Main_rb.ts +2 -1
- 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/Main_rust.ts +2 -1
- 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/Main_scala.ts +2 -1
- package/project/.sdk/src/cmp/scala/Test_scala.ts +5 -1
- package/project/.sdk/src/cmp/ts/Config_ts.ts +50 -8
- package/project/.sdk/src/cmp/ts/Main_ts.ts +10 -2
- package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +10 -3
- package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +11 -3
- package/project/.sdk/src/cmp/ts/Test_ts.ts +5 -1
- package/project/.sdk/tm/csharp/test/Runner.cs +45 -0
- package/project/.sdk/tm/dart/test/utility.dart +39 -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/lua/test/runner.lua +40 -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/php/test/Runner.php +36 -0
- package/project/.sdk/tm/rb/test/runner.rb +25 -0
- package/project/.sdk/tm/rust/tests/common/mod.rs +32 -0
- package/project/.sdk/tm/rust/utility/make_options.rs +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +8 -2
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sigv4.ts +29 -5
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +30 -21
- 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/test/vendor/omni/Runner.ts +15 -13
- package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +25 -19
- package/project/.sdk/tm/ts/test/vendor/omni/compat.ts +1 -1
- package/project/.sdk/tm/ts/test/vendor/omni/index.ts +1 -1
- package/project/.sdk/tm/zig/core/utility.zig +1 -1
- package/project/sdkgen-package.json +1 -1
- package/src/cmp/Feature.ts +5 -0
- package/src/cmp/TestControl.ts +64 -0
- package/src/helpers/featureSource.ts +130 -0
- package/src/sdkgen.ts +7 -0
- package/src/utility.ts +61 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Providers.ts +0 -1221
|
@@ -7,7 +7,8 @@ import type {
|
|
|
7
7
|
ModelEntity
|
|
8
8
|
} from '@voxgig/apidef'
|
|
9
9
|
|
|
10
|
-
import { cmp, each, snakify, Folder, File, Content, entityCollection
|
|
10
|
+
import { cmp, each, snakify, Folder, File, Content, entityCollection,
|
|
11
|
+
TestControl } from '@voxgig/sdkgen'
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
import { TestDirect } from './TestDirect_dart'
|
|
@@ -24,6 +25,9 @@ const Test = cmp(function Test(props: any) {
|
|
|
24
25
|
|
|
25
26
|
Folder({ name: 'test' }, () => {
|
|
26
27
|
|
|
28
|
+
// Write-once: a project's edited control file survives regeneration.
|
|
29
|
+
TestControl({ target, dir: 'test' })
|
|
30
|
+
|
|
27
31
|
// Suite entry: registers every static suite plus the generated
|
|
28
32
|
// per-entity suites, then runs them (Makefile: dart run test/main.dart).
|
|
29
33
|
File({ name: 'main.' + target.ext }, () => {
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
List, File, Content, Copy, Folder, Fragment, Line, FeatureHook,
|
|
7
7
|
entityClassName, entityCollection, goModule, goPackageIdent,
|
|
8
8
|
targetFeatures,
|
|
9
|
+
TEST_CONTROL_EXCLUDE
|
|
9
10
|
} from '@voxgig/sdkgen'
|
|
10
11
|
|
|
11
12
|
|
|
@@ -59,7 +60,7 @@ const Main = cmp(async function Main(props: any) {
|
|
|
59
60
|
// downstream consumers.
|
|
60
61
|
Copy({
|
|
61
62
|
from: 'tm/' + target.name,
|
|
62
|
-
exclude: [/src\//, /utility\/struct\/go\.mod
|
|
63
|
+
exclude: [/src\//, /utility\/struct\/go\.mod$/, TEST_CONTROL_EXCLUDE],
|
|
63
64
|
replace: {
|
|
64
65
|
...props.ctx$.stdrep,
|
|
65
66
|
GOMODULE: gomodule,
|
|
@@ -3,7 +3,8 @@ import type {
|
|
|
3
3
|
ModelEntity
|
|
4
4
|
} from '@voxgig/apidef'
|
|
5
5
|
|
|
6
|
-
import { cmp, each, Folder, File, Content, goModule, entityCollection
|
|
6
|
+
import { cmp, each, Folder, File, Content, goModule, entityCollection,
|
|
7
|
+
TestControl } from '@voxgig/sdkgen'
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
import { TestEntity } from './TestEntity_go'
|
|
@@ -21,6 +22,9 @@ const Test = cmp(function Test(props: any) {
|
|
|
21
22
|
|
|
22
23
|
Folder({ name: 'test' }, () => {
|
|
23
24
|
|
|
25
|
+
// Write-once: a project's edited control file survives regeneration.
|
|
26
|
+
TestControl({ target, dir: 'test' })
|
|
27
|
+
|
|
24
28
|
// Generate exists_test.go programmatically to avoid duplication
|
|
25
29
|
// with any scaffolded test file (e.g. projectname_sdk_test.go).
|
|
26
30
|
File({ name: 'exists_test.' + target.ext }, () => {
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
cmp, each,
|
|
6
6
|
File, Content, Copy, Folder, Fragment,
|
|
7
7
|
targetFeatures,
|
|
8
|
+
TEST_CONTROL_EXCLUDE
|
|
8
9
|
} from '@voxgig/sdkgen'
|
|
9
10
|
|
|
10
11
|
|
|
@@ -52,7 +53,7 @@ const Main = cmp(async function Main(props: any) {
|
|
|
52
53
|
// token used throughout the templates (package/import statements).
|
|
53
54
|
Copy({
|
|
54
55
|
from: 'tm/' + target.name,
|
|
55
|
-
exclude: [/src
|
|
56
|
+
exclude: [/src\//, TEST_CONTROL_EXCLUDE],
|
|
56
57
|
replace: {
|
|
57
58
|
...props.ctx$.stdrep,
|
|
58
59
|
JAVAPACKAGE: javapackage,
|
|
@@ -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_java'
|
|
@@ -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
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
List, File, Content, Copy, Folder, Fragment, Line, FeatureHook,
|
|
7
7
|
entityClassName, entityCollection, srcFeatureExcludes, stationLibrary,
|
|
8
8
|
targetFeatures,
|
|
9
|
+
TEST_CONTROL_EXCLUDE
|
|
9
10
|
} from '@voxgig/sdkgen'
|
|
10
11
|
|
|
11
12
|
|
|
@@ -49,7 +50,7 @@ const Main = cmp(async function Main(props: any) {
|
|
|
49
50
|
from: 'tm/' + target.name,
|
|
50
51
|
// Root copies src/feature/<name>/ per ACTIVE feature; keep this blanket
|
|
51
52
|
// copy from restoring one that was switched off after `target add`.
|
|
52
|
-
exclude: srcFeatureExcludes(model),
|
|
53
|
+
exclude: [...srcFeatureExcludes(model), TEST_CONTROL_EXCLUDE],
|
|
53
54
|
replace: {
|
|
54
55
|
...props.ctx$.stdrep,
|
|
55
56
|
}
|
|
@@ -17,7 +17,10 @@ import {
|
|
|
17
17
|
cmp,
|
|
18
18
|
snakify,
|
|
19
19
|
isAuthActive,
|
|
20
|
-
|
|
20
|
+
serverVarEnv,
|
|
21
|
+
serverVariables,
|
|
22
|
+
jsProp, envName, envToken,
|
|
23
|
+
jsKey
|
|
21
24
|
} from '@voxgig/sdkgen'
|
|
22
25
|
|
|
23
26
|
|
|
@@ -41,13 +44,32 @@ const TestDirect = cmp(function TestDirect(props: any) {
|
|
|
41
44
|
|
|
42
45
|
const authActive = isAuthActive(model)
|
|
43
46
|
const apikeyEnvEntry = authActive
|
|
44
|
-
? `\n '${PROJECTNAME}_APIKEY': '
|
|
47
|
+
? `\n '${PROJECTNAME}_APIKEY': '',`
|
|
45
48
|
: ''
|
|
46
49
|
const apikeyLiveField = authActive
|
|
47
50
|
? `
|
|
48
51
|
apikey: env.${PROJECTNAME}_APIKEY,`
|
|
49
52
|
: ''
|
|
50
53
|
|
|
54
|
+
// A templated server URL (OpenAPI server variables) makes a LIVE client
|
|
55
|
+
// impossible to construct without values: makeOptions raises rather than
|
|
56
|
+
// request a URL with a literal `{account_id}` in it. Taken from the
|
|
57
|
+
// environment, the same way the apikey is.
|
|
58
|
+
//
|
|
59
|
+
// Keys are quoted and the env read is bracketed via jsKey/jsProp: a server
|
|
60
|
+
// variable name is spec-derived and need not be a JS identifier — the URL
|
|
61
|
+
// grammar admits a leading digit ({2fa}), and a declared-but-unreferenced
|
|
62
|
+
// variable ({edge-zone}) is not constrained at all. Bare `name:` and
|
|
63
|
+
// `env.PROJ_SERVER_EDGE-ZONE` are both syntax errors.
|
|
64
|
+
const svars = serverVariables(model)
|
|
65
|
+
const serverEnvEntry = svars
|
|
66
|
+
.map((v: any) => `\n '${serverVarEnv(PROJECTNAME, v.name)}': ${JSON.stringify(v.dflt)},`).join('')
|
|
67
|
+
const serverLiveField = 0 === svars.length ? '' : `
|
|
68
|
+
server: {${svars
|
|
69
|
+
.map((v: any) => `
|
|
70
|
+
${jsKey(v.name)}: ${jsProp('env', serverVarEnv(PROJECTNAME, v.name))},`).join('')}
|
|
71
|
+
},`
|
|
72
|
+
|
|
51
73
|
const opnames = Object.keys(entity.op || {})
|
|
52
74
|
const hasLoad = opnames.includes('load')
|
|
53
75
|
const hasList = opnames.includes('list')
|
|
@@ -78,14 +100,17 @@ function directSetup(mockres) {
|
|
|
78
100
|
|
|
79
101
|
const env = envOverride({
|
|
80
102
|
'${entidEnvVar}': {},
|
|
81
|
-
'${PROJECTNAME}_TEST_LIVE': 'FALSE',${apikeyEnvEntry}
|
|
103
|
+
'${PROJECTNAME}_TEST_LIVE': 'FALSE',${apikeyEnvEntry}${serverEnvEntry}
|
|
82
104
|
})
|
|
83
105
|
|
|
84
106
|
const live = 'TRUE' === env.${PROJECTNAME}_TEST_LIVE
|
|
85
107
|
|
|
86
108
|
if (live) {
|
|
87
|
-
|
|
88
|
-
|
|
109
|
+
// Merged so the generated fields win: sdk-test-control.json's
|
|
110
|
+
// test.client.options adds to the live client, it does not redirect it.
|
|
111
|
+
const client = new ${nom(model.const, 'Name')}SDK(
|
|
112
|
+
Object.assign({}, liveClientOptions(), {${apikeyLiveField}${serverLiveField}
|
|
113
|
+
}))
|
|
89
114
|
|
|
90
115
|
let idmap = env['${entidEnvVar}']
|
|
91
116
|
if ('string' === typeof idmap && idmap.startsWith('{')) {
|
|
@@ -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()
|
|
@@ -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
|
cmp, each, names, cmap,
|
|
6
6
|
List, File, Content, Copy, Folder, Fragment, Line, FeatureHook,
|
|
7
7
|
targetFeatures,
|
|
8
|
+
TEST_CONTROL_EXCLUDE
|
|
8
9
|
} from '@voxgig/sdkgen'
|
|
9
10
|
|
|
10
11
|
|
|
@@ -44,7 +45,7 @@ const Main = cmp(async function Main(props: any) {
|
|
|
44
45
|
// Copy tm/lua files with replacements
|
|
45
46
|
Copy({
|
|
46
47
|
from: 'tm/' + target.name,
|
|
47
|
-
exclude: [/src
|
|
48
|
+
exclude: [/src\//, TEST_CONTROL_EXCLUDE],
|
|
48
49
|
replace: {
|
|
49
50
|
...props.ctx$.stdrep,
|
|
50
51
|
}
|
|
@@ -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
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
cmp, each, names,
|
|
6
6
|
File, Content, Copy, Folder, Fragment,
|
|
7
7
|
targetFeatures,
|
|
8
|
+
TEST_CONTROL_EXCLUDE
|
|
8
9
|
} from '@voxgig/sdkgen'
|
|
9
10
|
|
|
10
11
|
|
|
@@ -49,7 +50,7 @@ const Main = cmp(async function Main(props: any) {
|
|
|
49
50
|
// Copy tm/perl files with replacements
|
|
50
51
|
Copy({
|
|
51
52
|
from: 'tm/' + target.name,
|
|
52
|
-
exclude: [/src
|
|
53
|
+
exclude: [/src\//, TEST_CONTROL_EXCLUDE],
|
|
53
54
|
replace: {
|
|
54
55
|
...props.ctx$.stdrep,
|
|
55
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,
|