@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.
Files changed (248) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/action/check.js +15 -0
  3. package/dist/action/check.js.map +1 -1
  4. package/dist/cmp/AgentGuide.js +1 -1
  5. package/dist/cmp/AgentGuide.js.map +1 -1
  6. package/dist/cmp/AgentGuideContent.d.ts +1 -1
  7. package/dist/cmp/AgentGuideContent.js +8 -2
  8. package/dist/cmp/AgentGuideContent.js.map +1 -1
  9. package/dist/cmp/Feature.js +22 -0
  10. package/dist/cmp/Feature.js.map +1 -1
  11. package/dist/cmp/FeatureDocs.d.ts +1 -1
  12. package/dist/cmp/FeatureDocs.js +6 -1
  13. package/dist/cmp/FeatureDocs.js.map +1 -1
  14. package/dist/cmp/ReadmeExplanation.js +3 -1
  15. package/dist/cmp/ReadmeExplanation.js.map +1 -1
  16. package/dist/cmp/ReadmeFeatures.js +1 -1
  17. package/dist/cmp/ReadmeFeatures.js.map +1 -1
  18. package/dist/cmp/ReadmeRefFeatures.js +1 -1
  19. package/dist/cmp/ReadmeRefFeatures.js.map +1 -1
  20. package/dist/cmp/TestControl.d.ts +4 -0
  21. package/dist/cmp/TestControl.js +51 -0
  22. package/dist/cmp/TestControl.js.map +1 -0
  23. package/dist/helpers/applicability.d.ts +6 -0
  24. package/dist/helpers/applicability.js +103 -0
  25. package/dist/helpers/applicability.js.map +1 -0
  26. package/dist/helpers/collectDeps.js +4 -2
  27. package/dist/helpers/collectDeps.js.map +1 -1
  28. package/dist/helpers/featureSource.d.ts +3 -1
  29. package/dist/helpers/featureSource.js +105 -0
  30. package/dist/helpers/featureSource.js.map +1 -1
  31. package/dist/helpers/serverVars.d.ts +2 -1
  32. package/dist/helpers/serverVars.js +17 -0
  33. package/dist/helpers/serverVars.js.map +1 -1
  34. package/dist/sdkgen.d.ts +5 -3
  35. package/dist/sdkgen.js +16 -4
  36. package/dist/sdkgen.js.map +1 -1
  37. package/dist/tsconfig.tsbuildinfo +1 -1
  38. package/dist/utility.d.ts +2 -1
  39. package/dist/utility.js +59 -1
  40. package/dist/utility.js.map +1 -1
  41. package/model/sdkgen.aon +97 -0
  42. package/package.json +1 -1
  43. package/project/.sdk/model/feature/feature-index.aon +1 -0
  44. package/project/.sdk/model/feature/secrets.aon +200 -0
  45. package/project/.sdk/model/target/ts.aon +8 -1
  46. package/project/.sdk/src/cmp/c/Config_c.ts +5 -1
  47. package/project/.sdk/src/cmp/cpp/Config_cpp.ts +5 -1
  48. package/project/.sdk/src/cmp/cpp/Main_cpp.ts +2 -1
  49. package/project/.sdk/src/cmp/cpp/Test_cpp.ts +5 -1
  50. package/project/.sdk/src/cmp/csharp/Config_csharp.ts +5 -1
  51. package/project/.sdk/src/cmp/csharp/Main_csharp.ts +2 -1
  52. package/project/.sdk/src/cmp/csharp/TestDirect_csharp.ts +30 -6
  53. package/project/.sdk/src/cmp/csharp/TestEntity_csharp.ts +29 -5
  54. package/project/.sdk/src/cmp/csharp/Test_csharp.ts +5 -1
  55. package/project/.sdk/src/cmp/dart/Config_dart.ts +5 -1
  56. package/project/.sdk/src/cmp/dart/Main_dart.ts +2 -1
  57. package/project/.sdk/src/cmp/dart/TestDirect_dart.ts +23 -6
  58. package/project/.sdk/src/cmp/dart/TestEntity_dart.ts +28 -7
  59. package/project/.sdk/src/cmp/dart/Test_dart.ts +5 -1
  60. package/project/.sdk/src/cmp/elixir/Config_elixir.ts +5 -1
  61. package/project/.sdk/src/cmp/elixir/Main_elixir.ts +5 -1
  62. package/project/.sdk/src/cmp/go/Config_go.ts +5 -1
  63. package/project/.sdk/src/cmp/go/Main_go.ts +8 -3
  64. package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +16 -3
  65. package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +16 -3
  66. package/project/.sdk/src/cmp/go/TestDirect_go.ts +28 -4
  67. package/project/.sdk/src/cmp/go/TestEntity_go.ts +43 -10
  68. package/project/.sdk/src/cmp/go/Test_go.ts +5 -1
  69. package/project/.sdk/src/cmp/go/fragment/Main.fragment.go +5 -5
  70. package/project/.sdk/src/cmp/java/Config_java.ts +22 -1
  71. package/project/.sdk/src/cmp/java/Main_java.ts +7 -2
  72. package/project/.sdk/src/cmp/java/ReadmeQuick_java.ts +17 -3
  73. package/project/.sdk/src/cmp/java/ReadmeTopQuick_java.ts +17 -3
  74. package/project/.sdk/src/cmp/java/TestDirect_java.ts +23 -4
  75. package/project/.sdk/src/cmp/java/TestEntity_java.ts +29 -4
  76. package/project/.sdk/src/cmp/java/Test_java.ts +5 -1
  77. package/project/.sdk/src/cmp/js/Config_js.ts +5 -1
  78. package/project/.sdk/src/cmp/js/Main_js.ts +7 -2
  79. package/project/.sdk/src/cmp/js/Package_js.ts +4 -1
  80. package/project/.sdk/src/cmp/js/TestDirect_js.ts +30 -5
  81. package/project/.sdk/src/cmp/js/TestEntity_js.ts +35 -5
  82. package/project/.sdk/src/cmp/js/Test_js.ts +5 -1
  83. package/project/.sdk/src/cmp/js/fragment/Direct.test.fragment.js +7 -1
  84. package/project/.sdk/src/cmp/js/fragment/Entity.test.fragment.js +7 -1
  85. package/project/.sdk/src/cmp/kotlin/Config_kotlin.ts +5 -1
  86. package/project/.sdk/src/cmp/kotlin/Main_kotlin.ts +2 -1
  87. package/project/.sdk/src/cmp/kotlin/Test_kotlin.ts +5 -1
  88. package/project/.sdk/src/cmp/lean/Config_lean.ts +5 -1
  89. package/project/.sdk/src/cmp/lua/Config_lua.ts +5 -1
  90. package/project/.sdk/src/cmp/lua/Main_lua.ts +7 -2
  91. package/project/.sdk/src/cmp/lua/Package_lua.ts +4 -1
  92. package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +28 -4
  93. package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +24 -4
  94. package/project/.sdk/src/cmp/lua/Test_lua.ts +5 -1
  95. package/project/.sdk/src/cmp/ocaml/Config_ocaml.ts +5 -1
  96. package/project/.sdk/src/cmp/ocaml/Gitignore_ocaml.ts +1 -0
  97. package/project/.sdk/src/cmp/perl/Main_perl.ts +7 -2
  98. package/project/.sdk/src/cmp/perl/TestDirect_perl.ts +25 -4
  99. package/project/.sdk/src/cmp/perl/TestEntity_perl.ts +24 -4
  100. package/project/.sdk/src/cmp/perl/Test_perl.ts +5 -1
  101. package/project/.sdk/src/cmp/perl/utility_perl.ts +10 -0
  102. package/project/.sdk/src/cmp/php/Config_php.ts +5 -1
  103. package/project/.sdk/src/cmp/php/Main_php.ts +7 -2
  104. package/project/.sdk/src/cmp/php/TestDirect_php.ts +24 -5
  105. package/project/.sdk/src/cmp/php/TestEntity_php.ts +28 -4
  106. package/project/.sdk/src/cmp/php/Test_php.ts +5 -1
  107. package/project/.sdk/src/cmp/py/Config_py.ts +5 -1
  108. package/project/.sdk/src/cmp/py/Main_py.ts +7 -2
  109. package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +16 -3
  110. package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +16 -3
  111. package/project/.sdk/src/cmp/py/TestDirect_py.ts +24 -5
  112. package/project/.sdk/src/cmp/py/TestEntity_py.ts +23 -3
  113. package/project/.sdk/src/cmp/py/Test_py.ts +5 -1
  114. package/project/.sdk/src/cmp/rb/Config_rb.ts +5 -1
  115. package/project/.sdk/src/cmp/rb/Main_rb.ts +7 -2
  116. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +24 -5
  117. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +24 -4
  118. package/project/.sdk/src/cmp/rb/Test_rb.ts +5 -1
  119. package/project/.sdk/src/cmp/rb/utility_rb.ts +3 -1
  120. package/project/.sdk/src/cmp/rust/Config_rust.ts +5 -1
  121. package/project/.sdk/src/cmp/rust/Main_rust.ts +7 -2
  122. package/project/.sdk/src/cmp/rust/TestDirect_rust.ts +31 -4
  123. package/project/.sdk/src/cmp/rust/TestEntity_rust.ts +37 -4
  124. package/project/.sdk/src/cmp/rust/Test_rust.ts +5 -1
  125. package/project/.sdk/src/cmp/scala/Config_scala.ts +5 -1
  126. package/project/.sdk/src/cmp/scala/Main_scala.ts +7 -2
  127. package/project/.sdk/src/cmp/scala/Test_scala.ts +5 -1
  128. package/project/.sdk/src/cmp/swift/Config_swift.ts +5 -1
  129. package/project/.sdk/src/cmp/ts/Config_ts.ts +55 -9
  130. package/project/.sdk/src/cmp/ts/Main_ts.ts +67 -3
  131. package/project/.sdk/src/cmp/ts/Package_ts.ts +4 -1
  132. package/project/.sdk/src/cmp/ts/ReadmeModel_ts.ts +15 -3
  133. package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +18 -5
  134. package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +19 -5
  135. package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +75 -8
  136. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +36 -5
  137. package/project/.sdk/src/cmp/ts/Test_ts.ts +5 -1
  138. package/project/.sdk/src/cmp/ts/fragment/Direct.test.fragment.ts +9 -2
  139. package/project/.sdk/src/cmp/ts/fragment/Entity.test.fragment.ts +9 -2
  140. package/project/.sdk/src/cmp/ts/fragment/Main.fragment.ts +7 -0
  141. package/project/.sdk/src/cmp/zig/Config_zig.ts +5 -1
  142. package/project/.sdk/tm/c/utility/make_options.c +22 -0
  143. package/project/.sdk/tm/clojure/src/sdk/core.clj +18 -1
  144. package/project/.sdk/tm/cpp/utility/pipeline.hpp +23 -0
  145. package/project/.sdk/tm/csharp/test/CustomUtilityTest.cs +15 -0
  146. package/project/.sdk/tm/csharp/test/Runner.cs +45 -0
  147. package/project/.sdk/tm/csharp/utility/MakeOptions.cs +23 -0
  148. package/project/.sdk/tm/dart/lib/utility/MakeOptionsUtility.dart +22 -0
  149. package/project/.sdk/tm/dart/test/utility.dart +39 -0
  150. package/project/.sdk/tm/elixir/lib/projectname/utility.ex +19 -0
  151. package/project/.sdk/tm/go/core/context.go +1 -1
  152. package/project/.sdk/tm/go/feature/cost_feature.go +1 -1
  153. package/project/.sdk/tm/go/feature/paging_feature.go +5 -5
  154. package/project/.sdk/tm/go/feature/test_feature.go +12 -5
  155. package/project/.sdk/tm/go/test/custom_utility_test.go +15 -0
  156. package/project/.sdk/tm/go/test/feature_corpus_test.go +7 -0
  157. package/project/.sdk/tm/go/test/runner_test.go +46 -0
  158. package/project/.sdk/tm/go/test/struct_runner_test.go +7 -7
  159. package/project/.sdk/tm/go/test/struct_utility_test.go +63 -27
  160. package/project/.sdk/tm/go/utility/fetcher.go +2 -2
  161. package/project/.sdk/tm/go/utility/make_options.go +24 -5
  162. package/project/.sdk/tm/go/utility/make_point.go +1 -1
  163. package/project/.sdk/tm/go/utility/make_spec.go +17 -1
  164. package/project/.sdk/tm/go/utility/prepare_auth.go +1 -1
  165. package/project/.sdk/tm/go/utility/struct/voxgigstruct.go +370 -307
  166. package/project/.sdk/tm/go/utility/transform_request.go +29 -1
  167. package/project/.sdk/tm/go/utility/transform_response.go +20 -1
  168. package/project/.sdk/tm/java/test/CustomUtilityTest.java +10 -0
  169. package/project/.sdk/tm/java/test/FeatureCorpusTest.java +7 -0
  170. package/project/.sdk/tm/java/test/PrimaryUtilityTest.java +6 -0
  171. package/project/.sdk/tm/java/test/RunnerSupport.java +43 -0
  172. package/project/.sdk/tm/java/utility/MakeOptions.java +84 -1
  173. package/project/.sdk/tm/js/src/utility/MakeOptionsUtility.js +24 -0
  174. package/project/.sdk/tm/js/src/utility/StructUtility.js +2076 -1837
  175. package/project/.sdk/tm/js/test/feature/Corpus.test.js +9 -0
  176. package/project/.sdk/tm/js/test/sdk-test-control.json +19 -0
  177. package/project/.sdk/tm/js/test/utility.js +91 -1
  178. package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +21 -0
  179. package/project/.sdk/tm/lean/src/SdkUtility.lean +12 -1
  180. package/project/.sdk/tm/lua/test/runner.lua +40 -0
  181. package/project/.sdk/tm/ocaml/sdk_runtime.ml +11 -0
  182. package/project/.sdk/tm/ocaml/test/harness.ml +14 -4
  183. package/project/.sdk/tm/perl/t/runner.pm +30 -0
  184. package/project/.sdk/tm/perl/utility/make_options.pm +18 -0
  185. package/project/.sdk/tm/php/test/FeatureCorpusTest.php +10 -1
  186. package/project/.sdk/tm/php/test/Runner.php +36 -0
  187. package/project/.sdk/tm/php/utility/MakeOptions.php +24 -0
  188. package/project/.sdk/tm/py/pkg/utility/make_options.py +20 -0
  189. package/project/.sdk/tm/py/test/runner.py +32 -0
  190. package/project/.sdk/tm/py/test/test_feature_corpus.py +10 -1
  191. package/project/.sdk/tm/rb/test/feature_corpus_test.rb +9 -1
  192. package/project/.sdk/tm/rb/test/runner.rb +25 -0
  193. package/project/.sdk/tm/rb/utility/make_options.rb +17 -0
  194. package/project/.sdk/tm/rust/tests/common/mod.rs +32 -0
  195. package/project/.sdk/tm/rust/utility/make_options.rs +26 -1
  196. package/project/.sdk/tm/scala/utility/Make.scala +17 -0
  197. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +21 -0
  198. package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +419 -0
  199. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +387 -0
  200. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sigv4.ts +175 -0
  201. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +51 -0
  202. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/Registry.ts +90 -0
  203. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/addr.ts +48 -0
  204. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/aws.ts +219 -0
  205. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/azuresecrets.ts +144 -0
  206. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/boru.ts +113 -0
  207. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/doppler.ts +77 -0
  208. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/dotenv.ts +51 -0
  209. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/env.ts +31 -0
  210. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/file.ts +54 -0
  211. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/gcpsecrets.ts +118 -0
  212. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/hashicorp.ts +159 -0
  213. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/http.ts +66 -0
  214. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/infisical.ts +107 -0
  215. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/memory.ts +33 -0
  216. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/onepassword.ts +120 -0
  217. package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/support.ts +176 -0
  218. package/project/.sdk/tm/ts/src/utility/MakeOptionsUtility.ts +18 -0
  219. package/project/.sdk/tm/ts/src/utility/StructUtility.ts +1321 -710
  220. package/project/.sdk/tm/ts/test/feature/Corpus.test.ts +9 -0
  221. package/project/.sdk/tm/ts/test/feature/secrets/Secrets.test.ts +764 -0
  222. package/project/.sdk/tm/ts/test/omni.test.ts +84 -0
  223. package/project/.sdk/tm/ts/test/omni.ts +86 -0
  224. package/project/.sdk/tm/ts/test/utility/PrimaryUtility.test.ts +6 -2
  225. package/project/.sdk/tm/ts/test/utility/StructUtility.test.ts +2 -2
  226. package/project/.sdk/tm/ts/test/utility.ts +122 -0
  227. package/project/.sdk/tm/ts/test/vendor/omni/Runner.ts +694 -0
  228. package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +244 -0
  229. package/project/.sdk/tm/ts/test/vendor/omni/compat.ts +188 -0
  230. package/project/.sdk/tm/ts/test/vendor/omni/index.ts +38 -0
  231. package/project/.sdk/tm/zig/core/utility.zig +24 -1
  232. package/project/sdkgen-package.json +2 -1
  233. package/src/action/check.ts +18 -0
  234. package/src/cmp/AgentGuide.ts +1 -1
  235. package/src/cmp/AgentGuideContent.ts +9 -2
  236. package/src/cmp/Feature.ts +24 -0
  237. package/src/cmp/FeatureDocs.ts +7 -1
  238. package/src/cmp/ReadmeExplanation.ts +4 -1
  239. package/src/cmp/ReadmeFeatures.ts +1 -1
  240. package/src/cmp/ReadmeRefFeatures.ts +1 -1
  241. package/src/cmp/TestControl.ts +64 -0
  242. package/src/helpers/applicability.ts +123 -0
  243. package/src/helpers/collectDeps.ts +5 -1
  244. package/src/helpers/featureSource.ts +130 -0
  245. package/src/helpers/serverVars.ts +19 -0
  246. package/src/sdkgen.ts +16 -1
  247. package/src/utility.ts +71 -1
  248. package/project/.sdk/tm/ts/test/runner.ts +0 -425
@@ -0,0 +1,387 @@
1
+ // VENDORED: @voxgig/sekreto 0.1.2 (typescript/src/Sekreto.ts)
2
+ // Source: https://github.com/voxgig/sekreto @ 65009cb5758850db767785ab666e71895f86086b
3
+ // License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
4
+ // sekreto: one interface for secrets, wherever they live.
5
+ //
6
+ // A Sekreto is an ordered chain of providers. `get` asks each in turn and
7
+ // returns the first hit, so an app can be configured from environment
8
+ // variables in development and a vault in production without changing a
9
+ // line of its own code.
10
+ //
11
+ // This file is CANONICAL. Every other port is a translation of it, and
12
+ // spec/sekreto.json is the behavioural contract they all run.
13
+
14
+ // The REGISTRY, never './Providers'. Importing the barrel here is what
15
+ // made every provider kind reachable from the core: the chain needs
16
+ // `makeprovider`, and the barrel's edge dragged AWS request signing and
17
+ // seven HTTP clients in behind it. The registry knows only the kinds
18
+ // something actually imported. See docs/design/plugin-providers.md.
19
+ import { Provider, ProviderSpec } from './provider/support'
20
+ import { makeprovider } from './provider/Registry'
21
+
22
+ /** A secret name: dot-separated lowercase segments, e.g. `api.token`. */
23
+ export type Name = string
24
+
25
+ export type SekretoOptions = {
26
+ /** The provider chain, in resolution order. */
27
+ providers?: (Provider | ProviderSpec)[]
28
+ /** Cache resolved values (default: true). */
29
+ cache?: boolean
30
+ }
31
+
32
+ /** Anything sekreto refuses to do: a bad name, a missing secret, a
33
+ * provider that could not be reached. */
34
+ export class SekretoError extends Error {
35
+ constructor(message: string) {
36
+ super(message)
37
+ this.name = 'SekretoError'
38
+ }
39
+ }
40
+
41
+ const NAMEPART = /^[a-z0-9_]+$/
42
+
43
+ /** Is this a well-formed secret name? */
44
+ export function validname(name: any): boolean {
45
+ if ('string' !== typeof name || 0 === name.length) {
46
+ return false
47
+ }
48
+
49
+ const parts = name.split('.')
50
+
51
+ for (const part of parts) {
52
+ if (!NAMEPART.test(part)) {
53
+ return false
54
+ }
55
+ }
56
+
57
+ return true
58
+ }
59
+
60
+ export function checkname(name: any): string {
61
+ if (!validname(name)) {
62
+ throw new SekretoError('sekreto: invalid name: ' + String(null == name ? '' : name))
63
+ }
64
+ return name
65
+ }
66
+
67
+ /** The environment-variable key for a name: `api.token` -> `API_TOKEN`. */
68
+ export function envkey(name: Name, prefix?: string): string {
69
+ checkname(name)
70
+ return (prefix || '') + name.split('.').join('_').toUpperCase()
71
+ }
72
+
73
+ /** Where a name lives in a KV vault: `api.token` -> `api` / `token`.
74
+ *
75
+ * A single-segment name has no path of its own, so it becomes a secret of
76
+ * that name with the conventional field `value`. */
77
+ export function vaultref(name: Name): { path: string; field: string } {
78
+ checkname(name)
79
+
80
+ const parts = name.split('.')
81
+
82
+ if (1 === parts.length) {
83
+ return { path: parts[0], field: 'value' }
84
+ }
85
+
86
+ return { path: parts.slice(0, -1).join('/'), field: parts[parts.length - 1] }
87
+ }
88
+
89
+ /** A name flattened to one segment: `api.token` -> `api_token` (GCP
90
+ * Secret Manager, `_`) or `api-token` (Azure Key Vault, `-`).
91
+ *
92
+ * Those stores have no path hierarchy and reject dots in ids, so the
93
+ * dots become the store's conventional separator. With `-` as the
94
+ * separator, underscores flatten too: Azure Key Vault's alphabet is
95
+ * letters, digits and hyphens only, and a valid sekreto name like
96
+ * `with_underscore` must still be representable there. (The resulting
97
+ * `.`/`_` collision mirrors the documented envkey behaviour, where
98
+ * both already map to `_`.) */
99
+ export function flatname(name: Name, sep: string): string {
100
+ checkname(name)
101
+ const flat = name.split('.').join(sep)
102
+ return '-' === sep ? flat.split('_').join('-') : flat
103
+ }
104
+
105
+ /** The AWS SSM Parameter Store name for a name: dots become the path
106
+ * hierarchy, rooted at `/` (or at a prefix): `db.pass.main` ->
107
+ * `/db/pass/main`, or `/app/db/pass/main` under prefix `/app`. */
108
+ export function awsparam(name: Name, prefix?: string): string {
109
+ checkname(name)
110
+
111
+ let base = prefix || ''
112
+ if ('' !== base && !base.startsWith('/')) {
113
+ base = '/' + base
114
+ }
115
+ base = base.replace(/\/$/, '')
116
+
117
+ return base + '/' + name.split('.').join('/')
118
+ }
119
+
120
+ /** Parse `.env` text into a map of raw keys to values.
121
+ *
122
+ * Deliberately small: `KEY=value`, optional `export`, `#` comments on their
123
+ * own line, and single- or double-quoted values (double quotes also
124
+ * unescape `\n`, `\r`, `\t` and `\\`). A line with no `=` is skipped. */
125
+ export function parsedotenv(text: string): Record<string, string> {
126
+ const out: Record<string, string> = {}
127
+
128
+ if ('string' !== typeof text) {
129
+ return out
130
+ }
131
+
132
+ for (const rawline of text.split('\n')) {
133
+ const line = rawline.replace(/\r$/, '').trim()
134
+
135
+ if (0 === line.length || line.startsWith('#')) {
136
+ continue
137
+ }
138
+
139
+ const body = line.startsWith('export ') ? line.slice(7).trim() : line
140
+
141
+ const eq = body.indexOf('=')
142
+ if (0 >= eq) {
143
+ continue
144
+ }
145
+
146
+ const key = body.slice(0, eq).trim()
147
+ let value = body.slice(eq + 1).trim()
148
+
149
+ if (2 <= value.length && value.startsWith('"') && value.endsWith('"')) {
150
+ value = unescape(value.slice(1, -1))
151
+ } else if (2 <= value.length && value.startsWith("'") && value.endsWith("'")) {
152
+ value = value.slice(1, -1)
153
+ }
154
+
155
+ out[key] = value
156
+ }
157
+
158
+ return out
159
+ }
160
+
161
+ function unescape(text: string): string {
162
+ let out = ''
163
+
164
+ for (let index = 0; index < text.length; index++) {
165
+ if ('\\' === text[index] && index + 1 < text.length) {
166
+ const next = text[index + 1]
167
+ index++
168
+ if ('n' === next) {
169
+ out += '\n'
170
+ } else if ('r' === next) {
171
+ out += '\r'
172
+ } else if ('t' === next) {
173
+ out += '\t'
174
+ } else if ('\\' === next) {
175
+ out += '\\'
176
+ } else if ('"' === next) {
177
+ out += '"'
178
+ } else {
179
+ out += '\\' + next
180
+ }
181
+ } else {
182
+ out += text[index]
183
+ }
184
+ }
185
+
186
+ return out
187
+ }
188
+
189
+ /** Replace known secret values in text with `[redacted]`.
190
+ *
191
+ * Only values of four characters or more are replaced: shorter ones are
192
+ * too likely to appear in ordinary text, and redacting them would make
193
+ * logs unreadable without making them safer. */
194
+ export function redact(text: string, values: string[]): string {
195
+ let out = 'string' === typeof text ? text : ''
196
+
197
+ for (const value of values || []) {
198
+ if ('string' !== typeof value || 4 > value.length) {
199
+ continue
200
+ }
201
+ out = out.split(value).join('[redacted]')
202
+ }
203
+
204
+ return out
205
+ }
206
+
207
+ /** One provider in the chain, under the store name it answers to. */
208
+ type Entry = { store: string; provider: Provider }
209
+
210
+ /** One resolved value. Kept as a list rather than a map so that the store
211
+ * a value came from stays attached, and so redaction order is stable. */
212
+ type Cached = { store: string; name: Name; value: string }
213
+
214
+ /** The store name a provider answers to when its spec does not say.
215
+ *
216
+ * `describe()` opens with the provider's kind - `vault:...`, `dotenv:...`,
217
+ * plain `env` - so the kind is the natural default, and a custom provider
218
+ * gets a sensible name without having to implement anything extra. */
219
+ function storename(provider: Provider, spec?: ProviderSpec): string {
220
+ if (spec && spec.name) {
221
+ return spec.name
222
+ }
223
+ return provider.describe().split(':')[0]
224
+ }
225
+
226
+ /** The secrets facade: a chain of providers plus a cache.
227
+ *
228
+ * Two ways to read. `get` is transparent - it walks the chain and takes
229
+ * the first hit, and the caller never learns which store answered. `getfrom`
230
+ * is directed - it names the store, and only that store is asked. Use the
231
+ * first for ordinary configuration, the second when *which* store holds a
232
+ * secret is part of what you mean. */
233
+ export class Sekreto {
234
+ private entries: Entry[]
235
+ private docache: boolean
236
+ private cache: Cached[]
237
+ // Every value ever resolved, for redact(). Kept independently of the
238
+ // read cache so that redaction still works when cache is off - otherwise
239
+ // `cache: false` would silently disable redact() and leak secrets to logs.
240
+ private seen: string[]
241
+
242
+ constructor(options?: SekretoOptions) {
243
+ const opts = options || {}
244
+
245
+ this.entries = (opts.providers || []).map((entry) => {
246
+ if ('function' === typeof (entry as Provider).lookup) {
247
+ const provider = entry as Provider
248
+ return { store: storename(provider), provider }
249
+ }
250
+
251
+ const spec = entry as ProviderSpec
252
+ const provider = makeprovider(spec)
253
+ return { store: storename(provider, spec), provider }
254
+ })
255
+
256
+ this.docache = false === opts.cache ? false : true
257
+ this.cache = []
258
+ this.seen = []
259
+ }
260
+
261
+ /** The secret, or a SekretoError if no provider has it. */
262
+ async get(name: Name): Promise<string> {
263
+ const found = await this.try(name)
264
+
265
+ if (undefined === found) {
266
+ throw new SekretoError('sekreto: unknown secret: ' + name)
267
+ }
268
+
269
+ return found
270
+ }
271
+
272
+ /** The secret, or undefined if no provider has it. */
273
+ async try(name: Name): Promise<string | undefined> {
274
+ return this.resolve('', name, this.entries)
275
+ }
276
+
277
+ /** The secret from one named store, or a SekretoError if that store does
278
+ * not have it. */
279
+ async getfrom(store: string, name: Name): Promise<string> {
280
+ const found = await this.tryfrom(store, name)
281
+
282
+ if (undefined === found) {
283
+ throw new SekretoError('sekreto: unknown secret: ' + store + ':' + name)
284
+ }
285
+
286
+ return found
287
+ }
288
+
289
+ /** The secret from one named store, or undefined if that store does not
290
+ * have it.
291
+ *
292
+ * Naming a store that is not in the chain is an error, not a miss: `try`
293
+ * already means "this store may not have it", so it cannot also mean
294
+ * "this store may not exist" without hiding a typo. */
295
+ async tryfrom(store: string, name: Name): Promise<string | undefined> {
296
+ const matching = this.entries.filter((entry) => entry.store === store)
297
+
298
+ if (0 === matching.length) {
299
+ throw new SekretoError('sekreto: unknown store: ' + store)
300
+ }
301
+
302
+ return this.resolve(store, name, matching)
303
+ }
304
+
305
+ private async resolve(store: string, name: Name, entries: Entry[]): Promise<string | undefined> {
306
+ checkname(name)
307
+
308
+ if (this.docache) {
309
+ const hit = this.cache.find((entry) => entry.store === store && entry.name === name)
310
+ if (undefined !== hit) {
311
+ return hit.value
312
+ }
313
+ }
314
+
315
+ for (const entry of entries) {
316
+ const found = await entry.provider.lookup(name)
317
+
318
+ if (undefined !== found && null !== found) {
319
+ if (this.docache) {
320
+ this.cache.push({ store, name, value: found })
321
+ }
322
+ this.seen.push(found)
323
+ return found
324
+ }
325
+ }
326
+
327
+ return undefined
328
+ }
329
+
330
+ /** Does any provider have this secret? */
331
+ async has(name: Name): Promise<boolean> {
332
+ return undefined !== (await this.try(name))
333
+ }
334
+
335
+ /** Does this named store have this secret? */
336
+ async hasin(store: string, name: Name): Promise<boolean> {
337
+ return undefined !== (await this.tryfrom(store, name))
338
+ }
339
+
340
+ /** Every named secret at once. Missing ones are an error. */
341
+ async all(names: Name[]): Promise<Record<string, string>> {
342
+ const out: Record<string, string> = {}
343
+
344
+ for (const name of names) {
345
+ out[name] = await this.get(name)
346
+ }
347
+
348
+ return out
349
+ }
350
+
351
+ /** A description of each provider, in resolution order. */
352
+ sources(): string[] {
353
+ return this.entries.map((entry) => entry.provider.describe())
354
+ }
355
+
356
+ /** The name of each store that can be named by `getfrom`, in resolution
357
+ * order and without repeats. */
358
+ stores(): string[] {
359
+ const out: string[] = []
360
+
361
+ for (const entry of this.entries) {
362
+ if (!out.includes(entry.store)) {
363
+ out.push(entry.store)
364
+ }
365
+ }
366
+
367
+ return out
368
+ }
369
+
370
+ /** Replace every value this Sekreto has resolved with `[redacted]`.
371
+ *
372
+ * Works whether or not caching is enabled: the redaction list is kept
373
+ * independently of the read cache. */
374
+ redact(text: string): string {
375
+ return redact(text, this.seen)
376
+ }
377
+
378
+ /** Drop cached values, so the next `get` asks the providers again. */
379
+ refresh(): void {
380
+ this.cache = []
381
+ }
382
+ }
383
+
384
+ /** Make a Sekreto from options. */
385
+ export function sekreto(options?: SekretoOptions): Sekreto {
386
+ return new Sekreto(options)
387
+ }
@@ -0,0 +1,175 @@
1
+ // VENDORED: @voxgig/sekreto 0.1.2 (typescript/src/Sigv4.ts)
2
+ // Source: https://github.com/voxgig/sekreto @ 65009cb5758850db767785ab666e71895f86086b
3
+ // License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
4
+ // AWS Signature Version 4, hand-rolled.
5
+ //
6
+ // The AWS providers need exactly one thing from the AWS SDK - request
7
+ // signing - and taking the SDK for it would break the no-dependency rule
8
+ // that keeps ten ports honest. SigV4 is a stable, published algorithm
9
+ // built from HMAC-SHA256, which every port's standard library (or, for
10
+ // Rust, a small in-tree implementation) already has.
11
+ //
12
+ // `sigv4` is pure: the caller passes the timestamp, so the same input
13
+ // yields the same signature everywhere. That is what lets the shared spec
14
+ // carry known-answer cases that all ten ports must reproduce bit-for-bit,
15
+ // and lets the integration mock recompute the signature server-side.
16
+
17
+ // node:crypto is loaded ON FIRST USE, not at import time.
18
+ //
19
+ // Providers.ts imports sigv4 for the AWS providers, and Sekreto.ts imports
20
+ // Providers — so a top-level `node:crypto` here put it in the module graph
21
+ // of every sekreto consumer, including one that never signs anything.
22
+ // Deferring keeps this module pure until an AWS provider actually runs.
23
+ //
24
+ // require(), not `await import()`: these helpers are synchronous and are
25
+ // called from synchronous signing code. The package is CommonJS.
26
+ function crypto(): typeof import('node:crypto') {
27
+ try {
28
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
29
+ return require('node:crypto')
30
+ } catch (err: any) {
31
+ throw new Error(
32
+ 'sekreto: AWS request signing needs node:crypto, which this runtime ' +
33
+ 'does not provide: ' +
34
+ err.message,
35
+ { cause: err },
36
+ )
37
+ }
38
+ }
39
+
40
+ export type Sigv4Input = {
41
+ method: string
42
+ /** Full request URL; the host, path and query are signed. */
43
+ url: string
44
+ /** Extra headers to sign, e.g. content-type and x-amz-target. */
45
+ headers?: Record<string, string>
46
+ body?: string
47
+ service: string
48
+ region: string
49
+ keyid: string
50
+ secret: string
51
+ /** STS session token; signed as x-amz-security-token when present. */
52
+ session?: string
53
+ /** The signing moment, `YYYYMMDDTHHMMSSZ`. Passed in, never sampled,
54
+ * so the function stays pure. */
55
+ datetime: string
56
+ }
57
+
58
+ /** The headers to attach to the request: authorization, x-amz-date, and
59
+ * x-amz-security-token when a session token was given. */
60
+ export type Sigv4Output = Record<string, string>
61
+
62
+ function sha256hex(text: string): string {
63
+ return crypto().createHash('sha256').update(text, 'utf8').digest('hex')
64
+ }
65
+
66
+ function hmac(key: Buffer | string, text: string): Buffer {
67
+ return crypto().createHmac('sha256', key).update(text, 'utf8').digest()
68
+ }
69
+
70
+ /** RFC 3986 escaping, which is stricter than encodeURIComponent: AWS
71
+ * wants `!`, `'`, `(`, `)` and `*` escaped too. */
72
+ function uriescape(text: string): string {
73
+ return encodeURIComponent(text).replace(
74
+ /[!'()*]/g,
75
+ (ch) => '%' + ch.charCodeAt(0).toString(16).toUpperCase(),
76
+ )
77
+ }
78
+
79
+ /** The canonical query string: each pair RFC 3986-escaped, sorted by
80
+ * escaped key then escaped value. */
81
+ function canonicalquery(query: string): string {
82
+ if ('' === query) {
83
+ return ''
84
+ }
85
+
86
+ const pairs = query.split('&').map((pair) => {
87
+ const eq = pair.indexOf('=')
88
+ const key = -1 === eq ? pair : pair.slice(0, eq)
89
+ const value = -1 === eq ? '' : pair.slice(eq + 1)
90
+ return [uriescape(decodeURIComponent(key)), uriescape(decodeURIComponent(value))]
91
+ })
92
+
93
+ pairs.sort((left, right) => {
94
+ if (left[0] !== right[0]) {
95
+ return left[0] < right[0] ? -1 : 1
96
+ }
97
+ return left[1] < right[1] ? -1 : left[1] > right[1] ? 1 : 0
98
+ })
99
+
100
+ return pairs.map((pair) => pair[0] + '=' + pair[1]).join('&')
101
+ }
102
+
103
+ /** Sign one request. Returns the headers to attach. */
104
+ export function sigv4(input: Sigv4Input): Sigv4Output {
105
+ const url = new URL(input.url)
106
+
107
+ const date = input.datetime.slice(0, 8)
108
+ const body = input.body || ''
109
+
110
+ // Every header that will be signed: the caller's extras, plus host and
111
+ // x-amz-date (and the session token when present), lower-cased and
112
+ // trimmed the way the canonical form requires.
113
+ // Canonical header values are trimmed AND internally collapsed -
114
+ // AWS folds sequential whitespace to one space before signing, so a
115
+ // header like "a b" must sign as "a b" or the service refuses it.
116
+ const headers: Record<string, string> = {}
117
+ for (const [key, value] of Object.entries(input.headers || {})) {
118
+ headers[key.toLowerCase()] = String(value).trim().replace(/\s+/g, ' ')
119
+ }
120
+ headers['host'] = url.host
121
+ headers['x-amz-date'] = input.datetime
122
+ if (input.session) {
123
+ headers['x-amz-security-token'] = input.session
124
+ }
125
+
126
+ const names = Object.keys(headers).sort()
127
+ const canonicalheaders = names.map((name) => name + ':' + headers[name] + '\n').join('')
128
+ const signedheaders = names.join(';')
129
+
130
+ const canonicalrequest = [
131
+ input.method.toUpperCase(),
132
+ url.pathname || '/',
133
+ canonicalquery(url.search.replace(/^\?/, '')),
134
+ canonicalheaders,
135
+ signedheaders,
136
+ sha256hex(body),
137
+ ].join('\n')
138
+
139
+ const scope = date + '/' + input.region + '/' + input.service + '/aws4_request'
140
+
141
+ const stringtosign = [
142
+ 'AWS4-HMAC-SHA256',
143
+ input.datetime,
144
+ scope,
145
+ sha256hex(canonicalrequest),
146
+ ].join('\n')
147
+
148
+ const kdate = hmac('AWS4' + input.secret, date)
149
+ const kregion = hmac(kdate, input.region)
150
+ const kservice = hmac(kregion, input.service)
151
+ const ksigning = hmac(kservice, 'aws4_request')
152
+ const signature = crypto()
153
+ .createHmac('sha256', ksigning)
154
+ .update(stringtosign, 'utf8')
155
+ .digest('hex')
156
+
157
+ const out: Sigv4Output = {
158
+ authorization:
159
+ 'AWS4-HMAC-SHA256 Credential=' +
160
+ input.keyid +
161
+ '/' +
162
+ scope +
163
+ ', SignedHeaders=' +
164
+ signedheaders +
165
+ ', Signature=' +
166
+ signature,
167
+ 'x-amz-date': input.datetime,
168
+ }
169
+
170
+ if (input.session) {
171
+ out['x-amz-security-token'] = input.session
172
+ }
173
+
174
+ return out
175
+ }
@@ -0,0 +1,51 @@
1
+ // VENDORED: @voxgig/sekreto 0.1.2 (typescript/src/index.ts)
2
+ // Source: https://github.com/voxgig/sekreto @ 65009cb5758850db767785ab666e71895f86086b
3
+ // License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
4
+ // @voxgig/sekreto - one interface for secrets, wherever they live.
5
+
6
+ export {
7
+ Sekreto,
8
+ SekretoError,
9
+ awsparam,
10
+ envkey,
11
+ flatname,
12
+ parsedotenv,
13
+ redact,
14
+ sekreto,
15
+ validname,
16
+ vaultref,
17
+ } from './Sekreto'
18
+
19
+ export type { Name, SekretoOptions } from './Sekreto'
20
+
21
+ // THE CORE SURFACE. Deliberately does NOT re-export the eleven provider
22
+ // kinds that need something of their runtime: pulling one through this
23
+ // file would make all of them reachable and put AWS request signing in
24
+ // every build, which is the thing the split removes.
25
+ //
26
+ // `env` and `memory` are here because they import nothing at all, and a
27
+ // chain with nowhere to read from is not usable or testable.
28
+ //
29
+ // Everything else registers itself when its module is imported:
30
+ //
31
+ // import '@voxgig/sekreto/provider/dotenv'
32
+ //
33
+ // or, for the old all-in behaviour, `from '@voxgig/sekreto/Providers'`.
34
+ // See docs/design/plugin-providers.md.
35
+ export { envprovider } from './provider/env'
36
+ export { memoryprovider } from './provider/memory'
37
+
38
+ // A pure validator, no platform dependency - kept on the core surface
39
+ // because callers validate an address before configuring a provider.
40
+ export { checkaddr } from './provider/addr'
41
+
42
+ export { makeprovider, register, registered, kinds } from './provider/Registry'
43
+ export type { ProviderDefinition } from './provider/Registry'
44
+
45
+ export type { Provider, ProviderSpec } from './provider/support'
46
+
47
+ // `sigv4` is NOT on the core surface: it is the node:crypto edge, and
48
+ // only the two aws providers use it. Import it from the module that
49
+ // needs it - `@voxgig/sekreto/provider/aws` - or from the full-set
50
+ // barrel. Re-exporting it here would put request signing in every
51
+ // build again, which is the thing the split removes.