@voxgig/sdkgen 4.6.0 → 4.8.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/helpers/opShape.js +8 -11
- package/dist/helpers/opShape.js.map +1 -1
- package/dist/helpers/pointPath.d.ts +10 -0
- package/dist/helpers/pointPath.js +54 -0
- package/dist/helpers/pointPath.js.map +1 -0
- package/dist/sdkgen.d.ts +6 -3
- package/dist/sdkgen.js +14 -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 +78 -1
- package/dist/utility.js.map +1 -1
- package/model/sdkgen.aon +58 -0
- package/package.json +2 -2
- package/project/.sdk/model/feature/secrets.aon +82 -0
- package/project/.sdk/src/cmp/c/Config_c.ts +7 -8
- package/project/.sdk/src/cmp/c/TestDirect_c.ts +4 -3
- package/project/.sdk/src/cmp/cpp/Main_cpp.ts +2 -1
- package/project/.sdk/src/cmp/cpp/TestDirect_cpp.ts +4 -3
- 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 +34 -9
- 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 +7 -8
- package/project/.sdk/src/cmp/dart/Main_dart.ts +2 -1
- package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +28 -10
- 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 +9 -8
- package/project/.sdk/src/cmp/go/Config_go.ts +1 -7
- package/project/.sdk/src/cmp/go/Main_go.ts +2 -1
- package/project/.sdk/src/cmp/go/TestDirect_go.ts +5 -4
- package/project/.sdk/src/cmp/go/Test_go.ts +5 -1
- package/project/.sdk/src/cmp/java/Config_java.ts +7 -7
- package/project/.sdk/src/cmp/java/Main_java.ts +2 -1
- package/project/.sdk/src/cmp/java/TestDirect_java.ts +5 -4
- package/project/.sdk/src/cmp/java/Test_java.ts +5 -1
- package/project/.sdk/src/cmp/js/Config_js.ts +7 -8
- package/project/.sdk/src/cmp/js/Main_js.ts +2 -1
- package/project/.sdk/src/cmp/js/TestDirect_js.ts +34 -8
- 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 +7 -7
- package/project/.sdk/src/cmp/kotlin/Main_kotlin.ts +2 -1
- package/project/.sdk/src/cmp/kotlin/TestDirect_kotlin.ts +5 -4
- package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +5 -1
- package/project/.sdk/src/cmp/lean/Config_lean.ts +9 -8
- package/project/.sdk/src/cmp/lua/Config_lua.ts +1 -7
- package/project/.sdk/src/cmp/lua/Main_lua.ts +2 -1
- package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +32 -7
- 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 +29 -7
- 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 +1 -7
- package/project/.sdk/src/cmp/php/Main_php.ts +2 -1
- package/project/.sdk/src/cmp/php/TestDirect_php.ts +28 -8
- 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 +1 -7
- package/project/.sdk/src/cmp/py/Main_py.ts +2 -1
- package/project/.sdk/src/cmp/py/TestDirect_py.ts +5 -4
- package/project/.sdk/src/cmp/py/Test_py.ts +5 -1
- package/project/.sdk/src/cmp/rb/Config_rb.ts +1 -7
- package/project/.sdk/src/cmp/rb/Main_rb.ts +2 -1
- package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +28 -8
- 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 +35 -7
- 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 +9 -7
- package/project/.sdk/src/cmp/scala/Main_scala.ts +2 -1
- package/project/.sdk/src/cmp/scala/TestDirect_scala.ts +4 -3
- package/project/.sdk/src/cmp/scala/Test_scala.ts +5 -1
- package/project/.sdk/src/cmp/seneca-provider/Extras_seneca-provider.ts +3 -1
- package/project/.sdk/src/cmp/seneca-provider/Main_seneca-provider.ts +9 -5
- package/project/.sdk/src/cmp/ts/Config_ts.ts +57 -16
- package/project/.sdk/src/cmp/ts/Main_ts.ts +10 -2
- package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +15 -7
- 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/helpers/opShape.ts +9 -14
- package/src/helpers/pointPath.ts +88 -0
- package/src/sdkgen.ts +18 -0
- package/src/utility.ts +92 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Providers.ts +0 -1221
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// VENDORED: @voxgig/sekreto 0.1.2 (typescript/src/provider/onepassword.ts)
|
|
2
|
+
// Source: https://github.com/voxgig/sekreto @ 65009cb5758850db767785ab666e71895f86086b
|
|
3
|
+
// License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
|
|
4
|
+
/* Copyright (c) 2025 Voxgig Ltd, MIT License */
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
ProviderSpec, Provider, SekretoError, checkname, vaultref,
|
|
8
|
+
} from './support'
|
|
9
|
+
import { checkaddr } from './addr'
|
|
10
|
+
import { fetchjson } from './http'
|
|
11
|
+
|
|
12
|
+
export function onepasswordprovider(options?: {
|
|
13
|
+
addr?: string
|
|
14
|
+
token?: string
|
|
15
|
+
vault?: string
|
|
16
|
+
}): Provider {
|
|
17
|
+
const opts = options || {}
|
|
18
|
+
|
|
19
|
+
let vaultid: string | undefined
|
|
20
|
+
|
|
21
|
+
const auth = (): Record<string, string> => ({
|
|
22
|
+
authorization: 'Bearer ' + (opts.token || ''),
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
const resolvevault = async (addr: string): Promise<string> => {
|
|
26
|
+
const want = opts.vault || ''
|
|
27
|
+
if ('' === want) {
|
|
28
|
+
throw new SekretoError('sekreto: onepassword: no vault')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const res = await fetchjson('GET', addr + '/v1/vaults', auth())
|
|
32
|
+
|
|
33
|
+
if (200 !== res.status || !Array.isArray(res.body)) {
|
|
34
|
+
throw new SekretoError('sekreto: onepassword error: ' + res.status + ': listing vaults')
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
for (const entry of res.body) {
|
|
38
|
+
if (entry && (want === entry.id || want === entry.name)) {
|
|
39
|
+
return String(entry.id)
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
throw new SekretoError('sekreto: onepassword: no vault named ' + want)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return {
|
|
47
|
+
lookup: async (name: string) => {
|
|
48
|
+
checkname(name)
|
|
49
|
+
|
|
50
|
+
const addr = (opts.addr || '').replace(/\/$/, '')
|
|
51
|
+
if ('' === addr) {
|
|
52
|
+
throw new SekretoError('sekreto: onepassword: no addr')
|
|
53
|
+
}
|
|
54
|
+
checkaddr(addr)
|
|
55
|
+
|
|
56
|
+
if (undefined === vaultid) {
|
|
57
|
+
vaultid = await resolvevault(addr)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const filter = encodeURIComponent('title eq "' + name + '"')
|
|
61
|
+
const found = await fetchjson(
|
|
62
|
+
'GET',
|
|
63
|
+
addr + '/v1/vaults/' + vaultid + '/items?filter=' + filter,
|
|
64
|
+
auth(),
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
if (200 !== found.status || !Array.isArray(found.body)) {
|
|
68
|
+
throw new SekretoError('sekreto: onepassword error: ' + found.status + ': finding ' + name)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (0 === found.body.length) {
|
|
72
|
+
return undefined
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const item = await fetchjson(
|
|
76
|
+
'GET',
|
|
77
|
+
addr + '/v1/vaults/' + vaultid + '/items/' + found.body[0].id,
|
|
78
|
+
auth(),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
if (200 !== item.status) {
|
|
82
|
+
throw new SekretoError('sekreto: onepassword error: ' + item.status + ': reading ' + name)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const fields = (item.body && item.body.fields) || []
|
|
86
|
+
|
|
87
|
+
for (const field of fields) {
|
|
88
|
+
if (field && 'PASSWORD' === field.purpose) {
|
|
89
|
+
return undefined === field.value || null === field.value ? undefined : String(field.value)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
for (const field of fields) {
|
|
93
|
+
if (field && 'value' === field.label) {
|
|
94
|
+
return undefined === field.value || null === field.value ? undefined : String(field.value)
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return undefined
|
|
99
|
+
},
|
|
100
|
+
describe: () => 'onepassword:' + (opts.vault || ''),
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** Doppler.
|
|
105
|
+
*
|
|
106
|
+
* The whole config is downloaded once - Doppler's own bulk endpoint -
|
|
107
|
+
* and answered from memory, like a remote .env: `api.token` is the
|
|
108
|
+
* `API_TOKEN` entry. A service token is config-scoped, so project and
|
|
109
|
+
* config are only needed with broader tokens. */
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
// Registering at import is what makes this module's presence the only
|
|
113
|
+
// thing that decides whether the kind exists in a build.
|
|
114
|
+
import { register } from './Registry'
|
|
115
|
+
|
|
116
|
+
register({
|
|
117
|
+
name: 'onepassword',
|
|
118
|
+
needs: ['fetch'],
|
|
119
|
+
define: (spec: ProviderSpec) => onepasswordprovider(spec),
|
|
120
|
+
})
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// VENDORED: @voxgig/sekreto 0.1.2 (typescript/src/provider/support.ts)
|
|
2
|
+
// Source: https://github.com/voxgig/sekreto @ 65009cb5758850db767785ab666e71895f86086b
|
|
3
|
+
// License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
|
|
4
|
+
// The providers a Sekreto chains together.
|
|
5
|
+
//
|
|
6
|
+
// A provider answers one question: "do you have this secret?" It returns
|
|
7
|
+
// the value, or undefined to mean "ask the next one". Nothing else about
|
|
8
|
+
// a provider is visible to the caller - which is the point: an app reads
|
|
9
|
+
// `api.token` and never learns whether it came from the environment, a
|
|
10
|
+
// .env file, HashiCorp Vault, AWS, GCP, Azure or a boru vault.
|
|
11
|
+
//
|
|
12
|
+
// Two failure shapes, and they are never interchangeable. A store that
|
|
13
|
+
// does not hold the secret is a MISS (undefined) - the chain carries on.
|
|
14
|
+
// A store that could not answer - bad credentials, unreachable host,
|
|
15
|
+
// missing configuration - is an ERROR: falling through there would
|
|
16
|
+
// quietly reach for a weaker store.
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
SekretoError,
|
|
20
|
+
awsparam,
|
|
21
|
+
checkname,
|
|
22
|
+
envkey,
|
|
23
|
+
flatname,
|
|
24
|
+
parsedotenv,
|
|
25
|
+
vaultref,
|
|
26
|
+
} from '../Sekreto'
|
|
27
|
+
|
|
28
|
+
// NODE BUILTINS, LOADED ON FIRST USE.
|
|
29
|
+
//
|
|
30
|
+
// These were top-level imports, which made them a side effect of importing
|
|
31
|
+
// sekreto AT ALL: `child_process`, `fs` and `path` entered the module graph
|
|
32
|
+
// for a caller who only ever used a `memory` or `env` provider, and any
|
|
33
|
+
// runtime lacking them failed at import time rather than at the point of
|
|
34
|
+
// use. Sekreto.ts imports makeprovider from this module, so the chain
|
|
35
|
+
// reached everything.
|
|
36
|
+
//
|
|
37
|
+
// A plain require(), not `await import()`: dotenvprovider, fileprovider and
|
|
38
|
+
// boruprovider all have SYNCHRONOUS lookups, and making them async to
|
|
39
|
+
// accommodate a dynamic import would change observable behaviour for anyone
|
|
40
|
+
// calling a provider directly. The package is CommonJS ("type":
|
|
41
|
+
// "commonjs"), so require is available and synchronous.
|
|
42
|
+
//
|
|
43
|
+
// What this buys and what it does not: the builtins are no longer evaluated
|
|
44
|
+
// at import time, so importing sekreto is safe in a runtime that lacks them
|
|
45
|
+
// and a bundler can drop an unreachable provider along with its edge. It is
|
|
46
|
+
// NOT by itself a complete browser story — a bundler still resolves a
|
|
47
|
+
// require it can see statically, so a browser build wants conditional
|
|
48
|
+
// exports ("browser" field) as well. That is a packaging change, tracked
|
|
49
|
+
// separately.
|
|
50
|
+
const nodemods: Record<string, any> = {}
|
|
51
|
+
|
|
52
|
+
function nodemod<T = any>(name: string): T {
|
|
53
|
+
let mod = nodemods[name]
|
|
54
|
+
|
|
55
|
+
if (undefined === mod) {
|
|
56
|
+
try {
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
58
|
+
mod = nodemods[name] = require(name)
|
|
59
|
+
} catch (err: any) {
|
|
60
|
+
throw new SekretoError(
|
|
61
|
+
'sekreto: this provider needs ' +
|
|
62
|
+
name +
|
|
63
|
+
', which this runtime does not provide: ' +
|
|
64
|
+
err.message,
|
|
65
|
+
)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return mod as T
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export type Provider = {
|
|
73
|
+
/** The value, or undefined if this provider does not have it. */
|
|
74
|
+
lookup: (name: string) => Promise<string | undefined> | string | undefined
|
|
75
|
+
/** A short description, shown by `Sekreto.sources()`. */
|
|
76
|
+
describe: () => string
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** The declarative form of a provider, as used in config and in the
|
|
80
|
+
* shared spec. */
|
|
81
|
+
export type ProviderSpec = {
|
|
82
|
+
kind:
|
|
83
|
+
| 'env'
|
|
84
|
+
| 'dotenv'
|
|
85
|
+
| 'memory'
|
|
86
|
+
| 'file'
|
|
87
|
+
| 'hashicorp'
|
|
88
|
+
| 'boru'
|
|
89
|
+
| 'awssecrets'
|
|
90
|
+
| 'awsparams'
|
|
91
|
+
| 'gcpsecrets'
|
|
92
|
+
| 'azuresecrets'
|
|
93
|
+
| 'onepassword'
|
|
94
|
+
| 'doppler'
|
|
95
|
+
| 'infisical'
|
|
96
|
+
/** The store name `Sekreto.getfrom` addresses. Defaults to `kind`. */
|
|
97
|
+
name?: string
|
|
98
|
+
prefix?: string
|
|
99
|
+
/** dotenv: the file to read. */
|
|
100
|
+
file?: string
|
|
101
|
+
/** memory: literal values, keyed like environment variables. */
|
|
102
|
+
values?: Record<string, string>
|
|
103
|
+
/** file: the directory of one-secret-per-file entries. */
|
|
104
|
+
dir?: string
|
|
105
|
+
/** hashicorp / boru (wire) / gcp / 1password / doppler / infisical:
|
|
106
|
+
* the base URL. */
|
|
107
|
+
addr?: string
|
|
108
|
+
/** hashicorp / boru (wire) / gcp / azure / 1password / doppler /
|
|
109
|
+
* infisical: the access token. */
|
|
110
|
+
token?: string
|
|
111
|
+
/** hashicorp / boru (wire): the KV mount (default `secret`). */
|
|
112
|
+
mount?: string
|
|
113
|
+
/** hashicorp: KV engine version, 1 or 2 (default 2). */
|
|
114
|
+
kv?: number
|
|
115
|
+
/** hashicorp: Vault Enterprise namespace (X-Vault-Namespace). */
|
|
116
|
+
vaultnamespace?: string
|
|
117
|
+
/** hashicorp: log in for a token instead of being handed one. */
|
|
118
|
+
auth?: {
|
|
119
|
+
method: 'kubernetes' | 'approle'
|
|
120
|
+
/** The auth mount, defaulting to the method name. */
|
|
121
|
+
mount?: string
|
|
122
|
+
/** kubernetes: the Vault role to log in as. */
|
|
123
|
+
role?: string
|
|
124
|
+
/** kubernetes: the service-account JWT itself (tests). */
|
|
125
|
+
jwt?: string
|
|
126
|
+
/** kubernetes: where the JWT lives; the conventional pod path by
|
|
127
|
+
* default. */
|
|
128
|
+
jwtfile?: string
|
|
129
|
+
/** approle: the role and secret ids. */
|
|
130
|
+
roleid?: string
|
|
131
|
+
secretid?: string
|
|
132
|
+
}
|
|
133
|
+
/** boru: the executable to run (default `boru`). */
|
|
134
|
+
command?: string
|
|
135
|
+
/** boru: the namespace qualifying the alias. */
|
|
136
|
+
namespace?: string
|
|
137
|
+
/** boru: the vault home, passed as BORU_HOME. */
|
|
138
|
+
home?: string
|
|
139
|
+
/** aws: region and credentials; the standard AWS_* environment
|
|
140
|
+
* variables fill whichever are not given. */
|
|
141
|
+
region?: string
|
|
142
|
+
keyid?: string
|
|
143
|
+
secret?: string
|
|
144
|
+
session?: string
|
|
145
|
+
/** gcp / doppler / infisical: the project (GCP project id, Doppler
|
|
146
|
+
* project slug, Infisical workspace id). */
|
|
147
|
+
project?: string
|
|
148
|
+
/** azure: the Key Vault name or full URL. 1password: the vault name
|
|
149
|
+
* or id. */
|
|
150
|
+
vault?: string
|
|
151
|
+
/** azure: client-credential login. infisical: universal-auth login
|
|
152
|
+
* (tenant is Azure-only). */
|
|
153
|
+
tenant?: string
|
|
154
|
+
clientid?: string
|
|
155
|
+
clientsecret?: string
|
|
156
|
+
/** azure: where to log in / where IMDS answers. gcp: where the
|
|
157
|
+
* metadata server answers. Overridable for tests and for clouds with
|
|
158
|
+
* nonstandard endpoints. */
|
|
159
|
+
loginaddr?: string
|
|
160
|
+
imdsaddr?: string
|
|
161
|
+
metadataaddr?: string
|
|
162
|
+
/** azure: the Key Vault API version (default 7.4). */
|
|
163
|
+
apiversion?: string
|
|
164
|
+
/** doppler: the config slug (with `project`). */
|
|
165
|
+
config?: string
|
|
166
|
+
/** infisical: the environment slug and secret path. */
|
|
167
|
+
environment?: string
|
|
168
|
+
path?: string
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Environment variables: `api.token` from `API_TOKEN`. */
|
|
172
|
+
|
|
173
|
+
export {
|
|
174
|
+
SekretoError, awsparam, checkname, envkey, flatname, parsedotenv, vaultref,
|
|
175
|
+
}
|
|
176
|
+
export { nodemod }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// VENDORED: @voxgig/omni 0.1.2 (typescript/src/Runner.ts)
|
|
2
|
-
// Source: https://github.com/voxgig/omni @
|
|
2
|
+
// Source: https://github.com/voxgig/omni @ 5956cc4e5ecdaeebd11eab8bb4b9462dfc76e018
|
|
3
3
|
// License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
|
|
4
4
|
// Omni: the shared multi-language test runner.
|
|
5
5
|
//
|
|
@@ -352,20 +352,22 @@ function fixjsonval(val: Json, donull: boolean): Json {
|
|
|
352
352
|
}
|
|
353
353
|
|
|
354
354
|
// The JSON form of an error: always at least {name,message}.
|
|
355
|
-
//
|
|
356
|
-
//
|
|
357
|
-
//
|
|
358
|
-
// fixture's
|
|
359
|
-
//
|
|
360
|
-
//
|
|
361
|
-
//
|
|
355
|
+
//
|
|
356
|
+
// A thrown value need not be an Error. Ports commonly rethrow an
|
|
357
|
+
// error-SHAPED map ({name, message, ...}) - voxgig/sdkgen's generated
|
|
358
|
+
// makeError rethrows the fixture's own error object verbatim - and
|
|
359
|
+
// collapsing that to String(err) yields '[object Object]', which fails both
|
|
360
|
+
// the `err` check and every `match.err.*` leaf. The struct repository's
|
|
361
|
+
// original runner read `.message` regardless of the thrown value's class.
|
|
362
362
|
function errify(err: any): Json {
|
|
363
363
|
if (err instanceof Error) {
|
|
364
364
|
return { ...err, name: err.name, message: err.message }
|
|
365
365
|
}
|
|
366
|
+
|
|
366
367
|
if (null != err && 'object' === typeof err) {
|
|
367
368
|
return { name: 'Error', ...err }
|
|
368
369
|
}
|
|
370
|
+
|
|
369
371
|
return { name: 'Error', message: String(err) }
|
|
370
372
|
}
|
|
371
373
|
|
|
@@ -481,11 +483,11 @@ function handleerror(flags: Flags, index: number, entry: Json, err: any) {
|
|
|
481
483
|
|
|
482
484
|
// Check that every leaf of `check` is present, and matches, in `base`.
|
|
483
485
|
function match(flags: Flags, index: number, entry: Json, check: Json, base: Json) {
|
|
484
|
-
//
|
|
485
|
-
//
|
|
486
|
-
//
|
|
487
|
-
//
|
|
488
|
-
//
|
|
486
|
+
// Read the base DIRECTLY. The clone bought nothing - the walk below only
|
|
487
|
+
// reads, via getpath - and it blows the stack on a cyclic base. A port
|
|
488
|
+
// that drives entries with live objects rather than pure JSON produces
|
|
489
|
+
// those routinely: voxgig/sdkgen's corpus matches against a live client
|
|
490
|
+
// context whose root context reaches the client again.
|
|
489
491
|
const cbase = base
|
|
490
492
|
|
|
491
493
|
const at = (path: Json[]) => (0 === path.length ? '<root>' : pathify(path))
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// VENDORED: @voxgig/omni 0.1.2 (typescript/src/Util.ts)
|
|
2
|
-
// Source: https://github.com/voxgig/omni @
|
|
2
|
+
// Source: https://github.com/voxgig/omni @ 5956cc4e5ecdaeebd11eab8bb4b9462dfc76e018
|
|
3
3
|
// License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
|
|
4
4
|
// Omni internal JSON utilities.
|
|
5
5
|
//
|
|
@@ -158,12 +158,17 @@ function deepequal(a: Json, b: Json): boolean {
|
|
|
158
158
|
|
|
159
159
|
// Compact JSON text with map keys sorted, so that messages are identical
|
|
160
160
|
// in every port regardless of local map ordering.
|
|
161
|
-
//
|
|
162
|
-
//
|
|
163
|
-
//
|
|
164
|
-
//
|
|
165
|
-
//
|
|
166
|
-
|
|
161
|
+
//
|
|
162
|
+
// CYCLE SAFE. Building a FAILURE MESSAGE must never be the thing that
|
|
163
|
+
// crashes: a port driving entries with live objects rather than pure JSON
|
|
164
|
+
// can carry a cyclic value in the entry bookkeeping fail() prints, and this
|
|
165
|
+
// recursed until the stack gave out. A cycle renders as "[Circular]", as
|
|
166
|
+
// the struct repository's original runner did.
|
|
167
|
+
//
|
|
168
|
+
// `seen` tracks the ANCESTORS of the current value, not every value
|
|
169
|
+
// visited: it is removed again on the way out, so the same object appearing
|
|
170
|
+
// twice as siblings - a DAG, not a cycle - still renders in full.
|
|
171
|
+
function jsonstr(val: Json, seen?: Set<any>): string {
|
|
167
172
|
if (undefined === val) {
|
|
168
173
|
return 'undefined'
|
|
169
174
|
}
|
|
@@ -184,23 +189,24 @@ function jsonstr(val: Json, seen?: WeakSet<object>): string {
|
|
|
184
189
|
return val ? 'true' : 'false'
|
|
185
190
|
}
|
|
186
191
|
|
|
187
|
-
if (islist(val)) {
|
|
188
|
-
seen = seen || new
|
|
189
|
-
if (seen.has(val)) {
|
|
190
|
-
return '"[Circular]"'
|
|
191
|
-
}
|
|
192
|
-
seen.add(val)
|
|
193
|
-
return '[' + val.map((entry: Json) => jsonstr(entry, seen)).join(',') + ']'
|
|
194
|
-
}
|
|
192
|
+
if (islist(val) || ismap(val)) {
|
|
193
|
+
seen = seen || new Set()
|
|
195
194
|
|
|
196
|
-
if (ismap(val)) {
|
|
197
|
-
seen = seen || new WeakSet()
|
|
198
195
|
if (seen.has(val)) {
|
|
199
196
|
return '"[Circular]"'
|
|
200
197
|
}
|
|
198
|
+
|
|
201
199
|
seen.add(val)
|
|
202
|
-
|
|
203
|
-
|
|
200
|
+
|
|
201
|
+
const out = islist(val)
|
|
202
|
+
? '[' + val.map((entry: Json) => jsonstr(entry, seen)).join(',') + ']'
|
|
203
|
+
: '{' + Object.keys(val).sort()
|
|
204
|
+
.map((key) => JSON.stringify(key) + ':' + jsonstr((val as any)[key], seen))
|
|
205
|
+
.join(',') + '}'
|
|
206
|
+
|
|
207
|
+
seen.delete(val)
|
|
208
|
+
|
|
209
|
+
return out
|
|
204
210
|
}
|
|
205
211
|
|
|
206
212
|
if ('function' === typeof val) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// VENDORED: @voxgig/omni 0.1.2 (typescript/compat/struct.ts), import path adapted ('../src' -> './index').
|
|
2
|
-
// Source: https://github.com/voxgig/omni @
|
|
2
|
+
// Source: https://github.com/voxgig/omni @ 5956cc4e5ecdaeebd11eab8bb4b9462dfc76e018
|
|
3
3
|
// License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
|
|
4
4
|
// Drop-in replacement for the in-situ test runner in the voxgig/struct
|
|
5
5
|
// repository (`typescript/test/runner.ts`).
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// VENDORED: @voxgig/omni 0.1.2 (typescript/src/index.ts)
|
|
2
|
-
// Source: https://github.com/voxgig/omni @
|
|
2
|
+
// Source: https://github.com/voxgig/omni @ 5956cc4e5ecdaeebd11eab8bb4b9462dfc76e018
|
|
3
3
|
// License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
|
|
4
4
|
// @voxgig/omni - shared multi-language test runner.
|
|
5
5
|
|
|
@@ -372,7 +372,7 @@ pub fn make_options_util(ctx: *Context) Value {
|
|
|
372
372
|
.{ "base", h.vstr("http://localhost:8000") },
|
|
373
373
|
.{ "prefix", h.vstr("") },
|
|
374
374
|
.{ "suffix", h.vstr("") },
|
|
375
|
-
.{ "auth", h.jo(&.{.{ "prefix", h.vstr("") }}) },
|
|
375
|
+
.{ "auth", h.jo(&.{ .{ "prefix", h.vstr("") }, .{ "basic", h.vbool(false) } }) },
|
|
376
376
|
.{ "headers", h.jo(&.{.{ "`$CHILD`", h.vstr("`$STRING`") }}) },
|
|
377
377
|
.{ "allow", h.jo(&.{
|
|
378
378
|
.{ "method", h.vstr("GET,PUT,POST,PATCH,DELETE,OPTIONS") },
|
package/src/cmp/Feature.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { cmp, Copy, Folder } from 'jostraca'
|
|
|
3
3
|
|
|
4
4
|
import { ensureStdrep } from '../helpers/stdrep'
|
|
5
5
|
import { featureApplies, featureTags } from '../helpers/applicability'
|
|
6
|
+
import { pluginExcludesFor } from '../helpers/featureSource'
|
|
6
7
|
|
|
7
8
|
const Feature = cmp(function Feature(props: any) {
|
|
8
9
|
const { target, feature, ctx$ } = props
|
|
@@ -31,6 +32,10 @@ const Feature = cmp(function Feature(props: any) {
|
|
|
31
32
|
// TODO: Copy should just warn if from not found
|
|
32
33
|
Copy({
|
|
33
34
|
from: 'tm/' + target.name + '/src/feature/' + feature.name,
|
|
35
|
+
// An ACTIVE feature's INACTIVE plugins do not come with it. This
|
|
36
|
+
// is the copy that decides it: Main's exclude never sees these
|
|
37
|
+
// files, because this Copy has already written them.
|
|
38
|
+
exclude: pluginExcludesFor(ctx$.model, feature.name),
|
|
34
39
|
replace: {
|
|
35
40
|
// Feature templates reference the SDK class by placeholder — e.g.
|
|
36
41
|
// tm/ts/.../TestFeature.ts imports `ProjectNameSDK`. Without the
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import Path from 'node:path'
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
cmp,
|
|
5
|
+
File,
|
|
6
|
+
Fragment,
|
|
7
|
+
} from 'jostraca'
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
const TEST_CONTROL_FILE = 'sdk-test-control.json'
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
// Keep the blanket per-target `Copy({ from: 'tm/<lang>' })` from restoring the
|
|
14
|
+
// template default over a project's edited control file. One regex for every
|
|
15
|
+
// target: the file sits under `test/`, `t/`, `tests/` or `sdktest/` depending
|
|
16
|
+
// on the language, and the name is what identifies it either way.
|
|
17
|
+
const TEST_CONTROL_EXCLUDE = new RegExp('(^|/)' + TEST_CONTROL_FILE + '$')
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
// `sdk-test-control.json` is the ONE generated file a project is meant to edit
|
|
21
|
+
// by hand: it names the tests to skip, the live pacing, and the extra client
|
|
22
|
+
// options a live run needs (`test.client.options`).
|
|
23
|
+
//
|
|
24
|
+
// It shipped as part of each target's blanket `Copy({ from: 'tm/<lang>' })`,
|
|
25
|
+
// and a Copy has no per-file "leave it alone if it already exists" — so every
|
|
26
|
+
// `npm run generate` overwrote whatever the project had put there. The
|
|
27
|
+
// documented workaround, editing the template master under `.sdk/tm/`, is
|
|
28
|
+
// worse: `doctor` reports it as drift and the next `target add <lang>` reverts
|
|
29
|
+
// it.
|
|
30
|
+
//
|
|
31
|
+
// So it is emitted HERE instead, write-once: `File({ exclude: true })` returns
|
|
32
|
+
// early when the file already exists (FileOp), which is exactly the semantics
|
|
33
|
+
// the file is documented to have. A project without one yet gets the
|
|
34
|
+
// template's default; a project that has edited one keeps its edits across
|
|
35
|
+
// both `generate` and `target add`.
|
|
36
|
+
//
|
|
37
|
+
// The content still comes from the target's own template, so there remains
|
|
38
|
+
// exactly one copy of the default on disk.
|
|
39
|
+
//
|
|
40
|
+
// The template is addressed the SAME way the Copy this replaces addressed it:
|
|
41
|
+
// `tm/<lang>/...` relative to the working directory, which is the project's
|
|
42
|
+
// `.sdk`. Resolved to absolute here because Fragment resolves a RELATIVE
|
|
43
|
+
// `from` against the OUTPUT folder instead — a different base, and the one
|
|
44
|
+
// place these two could silently disagree.
|
|
45
|
+
const TestControl = cmp(function TestControl(props: {
|
|
46
|
+
target: { name: string }
|
|
47
|
+
dir: string
|
|
48
|
+
ctx$?: any
|
|
49
|
+
}) {
|
|
50
|
+
const { target, dir } = props
|
|
51
|
+
|
|
52
|
+
File({ name: TEST_CONTROL_FILE, exclude: true }, () => {
|
|
53
|
+
Fragment({
|
|
54
|
+
from: Path.resolve('tm', target.name, dir, TEST_CONTROL_FILE)
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
export {
|
|
61
|
+
TestControl,
|
|
62
|
+
TEST_CONTROL_FILE,
|
|
63
|
+
TEST_CONTROL_EXCLUDE,
|
|
64
|
+
}
|