@voxgig/sdkgen 4.19.1 → 4.20.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/sdkgen.d.ts +2 -2
- package/dist/sdkgen.js +6 -3
- package/dist/sdkgen.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utility.d.ts +4 -1
- package/dist/utility.js +60 -0
- package/dist/utility.js.map +1 -1
- package/model/sdkgen.aon +10 -0
- package/package.json +1 -1
- package/project/.sdk/src/cmp/c/Config_c.ts +15 -0
- package/project/.sdk/src/cmp/c/Main_c.ts +15 -0
- package/project/.sdk/src/cmp/c/PrepareAuth_c.ts +371 -0
- package/project/.sdk/src/cmp/clojure/Config_clojure.ts +47 -1
- package/project/.sdk/src/cmp/clojure/Main_clojure.ts +11 -1
- package/project/.sdk/src/cmp/clojure/PrepareAuth_clojure.ts +374 -0
- package/project/.sdk/src/cmp/cpp/Config_cpp.ts +40 -0
- package/project/.sdk/src/cmp/cpp/Main_cpp.ts +17 -0
- package/project/.sdk/src/cmp/cpp/PrepareAuth_cpp.ts +441 -0
- package/project/.sdk/src/cmp/csharp/Config_csharp.ts +42 -1
- package/project/.sdk/src/cmp/csharp/Main_csharp.ts +18 -0
- package/project/.sdk/src/cmp/csharp/PrepareAuth_csharp.ts +392 -0
- package/project/.sdk/src/cmp/elixir/Config_elixir.ts +36 -1
- package/project/.sdk/src/cmp/elixir/Main_elixir.ts +15 -0
- package/project/.sdk/src/cmp/elixir/PrepareAuth_elixir.ts +418 -0
- package/project/.sdk/src/cmp/go/Config_go.ts +12 -1
- package/project/.sdk/src/cmp/go/Main_go.ts +14 -0
- package/project/.sdk/src/cmp/go/PrepareAuth_go.ts +322 -0
- package/project/.sdk/src/cmp/java/Config_java.ts +20 -1
- package/project/.sdk/src/cmp/java/Main_java.ts +14 -0
- package/project/.sdk/src/cmp/java/PrepareAuth_java.ts +298 -0
- package/project/.sdk/src/cmp/js/Config_js.ts +12 -1
- package/project/.sdk/src/cmp/js/Main_js.ts +6 -0
- package/project/.sdk/src/cmp/js/PrepareAuth_js.ts +244 -0
- package/project/.sdk/src/cmp/kotlin/Config_kotlin.ts +23 -1
- package/project/.sdk/src/cmp/kotlin/Main_kotlin.ts +20 -0
- package/project/.sdk/src/cmp/kotlin/PrepareAuth_kotlin.ts +440 -0
- package/project/.sdk/src/cmp/lua/Config_lua.ts +15 -1
- package/project/.sdk/src/cmp/lua/Main_lua.ts +11 -0
- package/project/.sdk/src/cmp/lua/PrepareAuth_lua.ts +364 -0
- package/project/.sdk/src/cmp/ocaml/Config_ocaml.ts +31 -1
- package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +19 -0
- package/project/.sdk/src/cmp/ocaml/PrepareAuth_ocaml.ts +454 -0
- package/project/.sdk/src/cmp/perl/Config_perl.ts +30 -0
- package/project/.sdk/src/cmp/perl/Main_perl.ts +14 -0
- package/project/.sdk/src/cmp/perl/PrepareAuth_perl.ts +387 -0
- package/project/.sdk/src/cmp/php/Config_php.ts +12 -1
- package/project/.sdk/src/cmp/php/Main_php.ts +7 -0
- package/project/.sdk/src/cmp/php/PrepareAuth_php.ts +325 -0
- package/project/.sdk/src/cmp/py/Config_py.ts +12 -1
- package/project/.sdk/src/cmp/py/Main_py.ts +12 -0
- package/project/.sdk/src/cmp/py/PrepareAuth_py.ts +389 -0
- package/project/.sdk/src/cmp/rb/Config_rb.ts +18 -1
- package/project/.sdk/src/cmp/rb/Main_rb.ts +10 -0
- package/project/.sdk/src/cmp/rb/PrepareAuth_rb.ts +305 -0
- package/project/.sdk/src/cmp/rust/Config_rust.ts +41 -1
- package/project/.sdk/src/cmp/rust/Main_rust.ts +16 -0
- package/project/.sdk/src/cmp/rust/PrepareAuth_rust.ts +410 -0
- package/project/.sdk/src/cmp/scala/Config_scala.ts +21 -1
- package/project/.sdk/src/cmp/scala/Main_scala.ts +14 -0
- package/project/.sdk/src/cmp/scala/PrepareAuth_scala.ts +415 -0
- package/project/.sdk/src/cmp/swift/Config_swift.ts +37 -1
- package/project/.sdk/src/cmp/swift/Main_swift.ts +10 -0
- package/project/.sdk/src/cmp/swift/PrepareAuth_swift.ts +439 -0
- package/project/.sdk/src/cmp/ts/Config_ts.ts +12 -1
- package/project/.sdk/src/cmp/ts/Main_ts.ts +5 -0
- package/project/.sdk/src/cmp/ts/PrepareAuth_ts.ts +237 -0
- package/project/.sdk/src/cmp/zig/Config_zig.ts +33 -1
- package/project/.sdk/src/cmp/zig/Main_zig.ts +16 -0
- package/project/.sdk/src/cmp/zig/PrepareAuth_zig.ts +545 -0
- package/project/.sdk/tm/clojure/src/sdk/core.clj +31 -20
- package/project/.sdk/tm/cpp/utility/pipeline.hpp +36 -40
- package/project/.sdk/tm/csharp/utility/MakeOptions.cs +11 -0
- package/project/.sdk/tm/elixir/lib/projectname/utility.ex +19 -32
- package/project/.sdk/tm/java/utility/MakeOptions.java +13 -1
- package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +14 -1
- package/project/.sdk/tm/kotlin/utility/Prepare.kt +13 -46
- package/project/.sdk/tm/ocaml/Makefile +11 -1
- package/project/.sdk/tm/ocaml/sdk_helpers.ml +15 -0
- package/project/.sdk/tm/ocaml/sdk_runtime.ml +31 -25
- package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +125 -12
- package/project/.sdk/tm/ocaml/test/t_pipeline.ml +64 -6
- package/project/.sdk/tm/perl/utility/make_options.pm +10 -1
- package/project/.sdk/tm/php/utility/MakeOptions.php +8 -1
- package/project/.sdk/tm/rust/utility/make_options.rs +13 -1
- package/project/.sdk/tm/scala/utility/Make.scala +14 -1
- package/project/.sdk/tm/scala/utility/Prepare.scala +16 -40
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +30 -3
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Prepare.swift +21 -39
- package/project/.sdk/tm/zig/core/utility.zig +37 -45
- package/project/.sdk/tm/zig/test/pipeline_test.zig +34 -0
- package/project/sdkgen-package.json +1 -1
- package/src/sdkgen.ts +4 -1
- package/src/utility.ts +75 -0
- package/project/.sdk/tm/c/utility/prepare_auth.c +0 -65
- package/project/.sdk/tm/csharp/utility/PrepareAuth.cs +0 -54
- package/project/.sdk/tm/go/utility/prepare_auth.go +0 -59
- package/project/.sdk/tm/java/utility/PrepareAuth.java +0 -66
- package/project/.sdk/tm/js/src/utility/PrepareAuthUtility.js +0 -49
- package/project/.sdk/tm/lua/utility/prepare_auth.lua +0 -52
- package/project/.sdk/tm/perl/utility/prepare_auth.pm +0 -56
- package/project/.sdk/tm/php/utility/PrepareAuth.php +0 -45
- package/project/.sdk/tm/py/pkg/utility/prepare_auth.py +0 -46
- package/project/.sdk/tm/rb/utility/prepare_auth.rb +0 -35
- package/project/.sdk/tm/rust/utility/prepare_auth.rs +0 -65
- package/project/.sdk/tm/ts/src/utility/PrepareAuthUtility.ts +0 -78
|
@@ -14,6 +14,8 @@ import {
|
|
|
14
14
|
indent,
|
|
15
15
|
isAuthActive,
|
|
16
16
|
isConfigData,
|
|
17
|
+
resolveAuthIn,
|
|
18
|
+
resolveAuthName,
|
|
17
19
|
resolveAuthPrefix,
|
|
18
20
|
serverVariables,
|
|
19
21
|
targetFeatures,
|
|
@@ -52,9 +54,18 @@ const Config = cmp(async function Config(props: any) {
|
|
|
52
54
|
const authActive = isAuthActive(model)
|
|
53
55
|
// config.auth.prefix override -> spec-derived info.security.prefix -> 'Bearer'
|
|
54
56
|
const authPrefix = resolveAuthPrefix(model)
|
|
57
|
+
// `in` and `name` travel with the prefix now. They were resolved by
|
|
58
|
+
// apidef all along and dropped here, so an apiKey-in-query API got an
|
|
59
|
+
// Authorization header it does not read. Emitted only when they differ
|
|
60
|
+
// from the defaults, so a header/Authorization SDK is byte-identical to
|
|
61
|
+
// what it generated before.
|
|
62
|
+
const authIn = resolveAuthIn(model)
|
|
63
|
+
const authName = resolveAuthName(model)
|
|
55
64
|
const authBlock = authActive
|
|
56
65
|
? `auth: {
|
|
57
|
-
prefix: '${authPrefix}'
|
|
66
|
+
prefix: '${authPrefix}',${'header' === authIn ? '' : `
|
|
67
|
+
in: '${authIn}',`}${'Authorization' === authName ? '' : `
|
|
68
|
+
name: '${authName}',`}
|
|
58
69
|
},
|
|
59
70
|
|
|
60
71
|
`
|
|
@@ -28,6 +28,7 @@ import { Schema } from './Schema_js'
|
|
|
28
28
|
import { Gitignore } from './Gitignore_js'
|
|
29
29
|
import { MainEntity } from './MainEntity_js'
|
|
30
30
|
import { SdkError } from './SdkError_js'
|
|
31
|
+
import { PrepareAuth } from './PrepareAuth_js'
|
|
31
32
|
import { EntityBase } from './EntityBase_js'
|
|
32
33
|
import { EntityTypes } from './EntityTypes_js'
|
|
33
34
|
|
|
@@ -194,6 +195,11 @@ if (fres instanceof Promise) { await fres }
|
|
|
194
195
|
})
|
|
195
196
|
|
|
196
197
|
Config({ target })
|
|
198
|
+
|
|
199
|
+
// GENERATED, NOT COPIED. Where the credential goes is a fact about the
|
|
200
|
+
// API, and tm/ can only hold one answer. See PrepareAuth_js.
|
|
201
|
+
PrepareAuth({ target })
|
|
202
|
+
|
|
197
203
|
Schema({ target })
|
|
198
204
|
|
|
199
205
|
EntityBase({ target })
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
|
|
2
|
+
import {
|
|
3
|
+
Content,
|
|
4
|
+
File,
|
|
5
|
+
Folder,
|
|
6
|
+
cmp,
|
|
7
|
+
isHttpBasicAuth,
|
|
8
|
+
resolveAuthIn,
|
|
9
|
+
resolveAuthName,
|
|
10
|
+
resolveAuthPrefix,
|
|
11
|
+
} from '@voxgig/sdkgen'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
KIT,
|
|
16
|
+
getModelPath,
|
|
17
|
+
} from '@voxgig/apidef'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
// WHERE THE CREDENTIAL GOES IS A FACT ABOUT THE API, so it is generated
|
|
21
|
+
// rather than templated.
|
|
22
|
+
//
|
|
23
|
+
// This was a static file at `tm/js/src/utility/PrepareAuthUtility.js` that
|
|
24
|
+
// hardcoded `authorization` and a header. apidef has always resolved the
|
|
25
|
+
// scheme's `in` and `name` into `main.kit.info.security` — joplin's says
|
|
26
|
+
// `in: "query", name: "token"` — and generation dropped both. The result
|
|
27
|
+
// was an SDK that sent a header the API does not read and never sent the
|
|
28
|
+
// query parameter it does, so it could not authenticate at all. Four
|
|
29
|
+
// repos in the cedar fleet shipped that way: joplin (`token`), pipedrive
|
|
30
|
+
// (`api_token`), trello (`key`), lm-umbrella (`apiKey`).
|
|
31
|
+
//
|
|
32
|
+
// A template cannot fix this, because the three placements need three
|
|
33
|
+
// different bodies and a template has to pick one. A component emits the
|
|
34
|
+
// branch this API actually uses and nothing else — no dead query code in
|
|
35
|
+
// a bearer-token SDK, and no runtime `if` on a value that is fixed at
|
|
36
|
+
// generation time.
|
|
37
|
+
//
|
|
38
|
+
// Ported from PrepareAuth_ts, which is the proven shape. The differences
|
|
39
|
+
// are the language's, not the design's: no type import, `module.exports`
|
|
40
|
+
// instead of `export {}`, and the prefix read inline off `options.auth`
|
|
41
|
+
// exactly as the js template read it, rather than hoisted into a local
|
|
42
|
+
// that the query and cookie bodies would leave unused.
|
|
43
|
+
const PrepareAuth = cmp(async function PrepareAuth(props: any) {
|
|
44
|
+
const { target } = props
|
|
45
|
+
const { model } = props.ctx$
|
|
46
|
+
|
|
47
|
+
const active = isAuthActive_js(model)
|
|
48
|
+
const where = resolveAuthIn(model)
|
|
49
|
+
// LOWERCASED FOR A HEADER, VERBATIM OTHERWISE. The js runtime keys its
|
|
50
|
+
// header map in lower case — the old template hardcoded 'authorization',
|
|
51
|
+
// the shared corpus asserts ctx:spec:headers:authorization, and every
|
|
52
|
+
// generatedcompile probe reads the lower-case key. apidef writes
|
|
53
|
+
// name: "Authorization", so emitting it verbatim hides the credential
|
|
54
|
+
// under a key nothing reads. Query parameters and cookies ARE
|
|
55
|
+
// case-sensitive and keep the spec's spelling.
|
|
56
|
+
const resolvedName = resolveAuthName(model)
|
|
57
|
+
const name = 'header' === where ? resolvedName.toLowerCase() : resolvedName
|
|
58
|
+
const prefix = resolveAuthPrefix(model)
|
|
59
|
+
const basic = isHttpBasicAuth(model)
|
|
60
|
+
|
|
61
|
+
// No `src` folder here: Main_js already opened it, and Config, Schema,
|
|
62
|
+
// SdkError, EntityBase and EntityTypes all write straight into it. The
|
|
63
|
+
// template this replaces lived at `tm/js/src/utility/`, so relative to
|
|
64
|
+
// that open folder the file needs `utility` and nothing more. Opening a
|
|
65
|
+
// second `src` would put it at src/src/utility/ — where nothing imports
|
|
66
|
+
// it, and the stale copy at src/utility/ keeps being used.
|
|
67
|
+
Folder({ name: 'utility' }, () => {
|
|
68
|
+
File({ name: 'PrepareAuthUtility.' + target.ext }, () => {
|
|
69
|
+
Content(render({ active, where, name, prefix, basic }))
|
|
70
|
+
})
|
|
71
|
+
})
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
function render(spec: {
|
|
76
|
+
active: boolean, where: string, name: string, prefix: string, basic: boolean
|
|
77
|
+
}): string {
|
|
78
|
+
|
|
79
|
+
// NO AUTH AT ALL. A public API's SDK gets a prepareAuth that is honest
|
|
80
|
+
// about it rather than one that deletes a header nobody set.
|
|
81
|
+
if (!spec.active) {
|
|
82
|
+
return `
|
|
83
|
+
// This API declares no authentication, so there is no credential to
|
|
84
|
+
// place. The function stays in the pipeline because makeSpec calls it
|
|
85
|
+
// unconditionally.
|
|
86
|
+
function prepareAuth(ctx) {
|
|
87
|
+
const spec = ctx.spec
|
|
88
|
+
|
|
89
|
+
if (null == spec) {
|
|
90
|
+
return ctx.error('auth_no_spec', 'Expected context spec property to be defined.')
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return spec
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
module.exports = {
|
|
97
|
+
prepareAuth
|
|
98
|
+
}
|
|
99
|
+
`
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const preamble = `
|
|
103
|
+
const CRED_name = '${jsstr(spec.name)}'
|
|
104
|
+
|
|
105
|
+
const OPTION_apikey = 'apikey'${spec.basic && 'header' === spec.where ? `
|
|
106
|
+
const OPTION_secret = 'secret'` : ''}
|
|
107
|
+
|
|
108
|
+
const NOTFOUND = '__NOTFOUND__'
|
|
109
|
+
|
|
110
|
+
function prepareAuth(ctx) {
|
|
111
|
+
const utility = ctx.utility
|
|
112
|
+
|
|
113
|
+
const struct = utility.struct
|
|
114
|
+
const getprop = struct.getprop
|
|
115
|
+
const setprop = struct.setprop
|
|
116
|
+
const delprop = struct.delprop
|
|
117
|
+
|
|
118
|
+
const client = ctx.client
|
|
119
|
+
const spec = ctx.spec
|
|
120
|
+
|
|
121
|
+
if (null == spec) {
|
|
122
|
+
return ctx.error('auth_no_spec', 'Expected context spec property to be defined.')
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const ${bag(spec.where)} = spec.${bag(spec.where)}
|
|
126
|
+
|
|
127
|
+
const options = client.options()
|
|
128
|
+
|
|
129
|
+
// Public APIs that need no auth omit the options.auth block entirely.
|
|
130
|
+
if (null == options.auth) {
|
|
131
|
+
${clear(spec.where)}
|
|
132
|
+
return spec
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const apikey = getprop(options, OPTION_apikey, NOTFOUND)
|
|
136
|
+
`
|
|
137
|
+
|
|
138
|
+
// HTTP Basic is header-only by definition: the scheme is
|
|
139
|
+
// `Authorization: Basic base64(user:pass)`. It cannot be expressed as a
|
|
140
|
+
// query parameter or a cookie, so the branch is emitted only where it
|
|
141
|
+
// can mean something.
|
|
142
|
+
const basicBlock = (spec.basic && 'header' === spec.where) ? `
|
|
143
|
+
// True HTTP Basic Auth needs TWO credentials, base64-joined - a single
|
|
144
|
+
// token in the header (the branch below) can never authenticate against
|
|
145
|
+
// an API that actually checks \`Authorization: Basic base64(user:pass)\`.
|
|
146
|
+
if (true === options.auth.basic) {
|
|
147
|
+
const secret = getprop(options, OPTION_secret, NOTFOUND)
|
|
148
|
+
const noApikey = NOTFOUND === apikey || null == apikey || '' === apikey
|
|
149
|
+
const noSecret = NOTFOUND === secret || null == secret || '' === secret
|
|
150
|
+
|
|
151
|
+
if (noApikey || noSecret) {
|
|
152
|
+
delprop(headers, CRED_name)
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
const b64 = Buffer.from(apikey + ':' + secret).toString('base64')
|
|
156
|
+
setprop(headers, CRED_name,
|
|
157
|
+
options.auth.prefix ? options.auth.prefix + ' ' + b64 : b64)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return spec
|
|
161
|
+
}
|
|
162
|
+
` : ''
|
|
163
|
+
|
|
164
|
+
return preamble + basicBlock + `
|
|
165
|
+
if (NOTFOUND === apikey || null == apikey || '' === apikey) {
|
|
166
|
+
${clear(spec.where)}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
${place(spec.where)}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return spec
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
module.exports = {
|
|
176
|
+
prepareAuth
|
|
177
|
+
}
|
|
178
|
+
`
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
// The bag the credential lands in, per placement. Cookies ride the header
|
|
183
|
+
// bag because a cookie IS a header.
|
|
184
|
+
function bag(where: string): string {
|
|
185
|
+
return 'query' === where ? 'query' : 'headers'
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
function clear(where: string): string {
|
|
190
|
+
return 'query' === where ? 'delprop(query, CRED_name)' : 'delprop(headers, CRED_name)'
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
function place(where: string): string {
|
|
195
|
+
if ('query' === where) {
|
|
196
|
+
// NO PREFIX IN A QUERY STRING. `?token=Bearer%20abc` is not a thing any
|
|
197
|
+
// API reads; the prefix is a header convention and is dropped here
|
|
198
|
+
// deliberately rather than silently concatenated.
|
|
199
|
+
return ` setprop(query, CRED_name, apikey)`
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if ('cookie' === where) {
|
|
203
|
+
// APPEND, never clobber: the request may already carry a session
|
|
204
|
+
// cookie set from options.headers, and a cookie header holds a
|
|
205
|
+
// '; '-joined list of pairs.
|
|
206
|
+
return ` const existing = getprop(headers, 'cookie', '')
|
|
207
|
+
const pair = CRED_name + '=' + apikey
|
|
208
|
+
setprop(headers, 'cookie', existing ? existing + '; ' + pair : pair)`
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return ` // Empty prefix (raw apiKey credential) must not add a leading space.
|
|
212
|
+
setprop(headers, CRED_name,
|
|
213
|
+
options.auth.prefix ? options.auth.prefix + ' ' + apikey : apikey)`
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
|
|
217
|
+
function jsstr(s: string): string {
|
|
218
|
+
return String(s).replace(/\\/g, '\\\\').replace(/'/g, "\\'")
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
export {
|
|
223
|
+
PrepareAuth
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
// NOT `isAuthActive`, AND THE DIFFERENCE IS LOAD-BEARING. That helper is
|
|
228
|
+
// also false whenever the SPEC declares no security scheme
|
|
229
|
+
// (`main.kit.info.auth: false`) — a statement about the DEFINITION, not a
|
|
230
|
+
// ban on ever sending a credential. `optspec` still declares `apikey` and
|
|
231
|
+
// makeOptions fills `options.auth` from its defaults, so the runtime
|
|
232
|
+
// `options.auth == null` guard never fired and those SDKs have always sent
|
|
233
|
+
// the credential. Gating the body on `isAuthActive` does not trim dead
|
|
234
|
+
// code, it removes working authentication — which
|
|
235
|
+
// `js: auth null suppresses the credential` catches, and which takes the
|
|
236
|
+
// secrets feature down with it.
|
|
237
|
+
//
|
|
238
|
+
// `main.kit.config.auth.active: false` is the project saying "no credential,
|
|
239
|
+
// ever", and it is the only signal that can be honoured before runtime.
|
|
240
|
+
function isAuthActive_js(model: any): boolean {
|
|
241
|
+
const auth = getModelPath(model, `main.${KIT}.config.auth`,
|
|
242
|
+
{ only_active: false, required: false })
|
|
243
|
+
return !(null != auth && false === auth.active)
|
|
244
|
+
}
|
|
@@ -6,6 +6,9 @@ import {
|
|
|
6
6
|
configDefinition,
|
|
7
7
|
each,
|
|
8
8
|
isAuthActive,
|
|
9
|
+
isHttpBasicAuth,
|
|
10
|
+
resolveAuthIn,
|
|
11
|
+
resolveAuthName,
|
|
9
12
|
resolveAuthPrefix,
|
|
10
13
|
targetFeatures,
|
|
11
14
|
} from '@voxgig/sdkgen'
|
|
@@ -46,6 +49,17 @@ const Config = cmp(async function Config(props: any) {
|
|
|
46
49
|
|
|
47
50
|
const authActive = isAuthActive(model)
|
|
48
51
|
const authPrefix = resolveAuthPrefix(model)
|
|
52
|
+
const authBasic = isHttpBasicAuth(model)
|
|
53
|
+
// `in` and `name` travel with the prefix now. apidef resolved both all
|
|
54
|
+
// along, into main.kit.info.security, and this emitter dropped them - so
|
|
55
|
+
// an apiKey-in-query API got an Authorization header it does not read.
|
|
56
|
+
// The generated utility/PrepareAuth.kt is built from the same two values.
|
|
57
|
+
//
|
|
58
|
+
// Emitted only when they DIFFER from the defaults, so a
|
|
59
|
+
// header/Authorization SDK's Config.kt is byte-identical to what it
|
|
60
|
+
// generated before.
|
|
61
|
+
const authIn = resolveAuthIn(model)
|
|
62
|
+
const authName = resolveAuthName(model)
|
|
49
63
|
|
|
50
64
|
let baseUrl = ''
|
|
51
65
|
try { baseUrl = getModelPath(model, `main.${KIT}.info.servers.0.url`) } catch (_e) { }
|
|
@@ -74,7 +88,15 @@ const Config = cmp(async function Config(props: any) {
|
|
|
74
88
|
base: baseUrl,
|
|
75
89
|
}
|
|
76
90
|
if (authActive) {
|
|
77
|
-
|
|
91
|
+
const auth: Record<string, any> = { prefix: authPrefix }
|
|
92
|
+
// `basic` joins them for the same reason: the generated prepareAuth
|
|
93
|
+
// emits the base64(user:pass) branch only for a spec-declared HTTP
|
|
94
|
+
// Basic scheme, and that branch reads this option at runtime - without
|
|
95
|
+
// it the branch could never fire.
|
|
96
|
+
if (authBasic) { auth.basic = true }
|
|
97
|
+
if ('header' !== authIn) { auth.in = authIn }
|
|
98
|
+
if ('Authorization' !== authName) { auth.name = authName }
|
|
99
|
+
options.auth = auth
|
|
78
100
|
}
|
|
79
101
|
options.headers = headers
|
|
80
102
|
options.entity = optionsEntity
|
|
@@ -27,6 +27,7 @@ import { MainEntity } from './MainEntity_kotlin'
|
|
|
27
27
|
import { EntityBase } from './EntityBase_kotlin'
|
|
28
28
|
import { EntityTypes } from './EntityTypes_kotlin'
|
|
29
29
|
import { SdkError } from './SdkError_kotlin'
|
|
30
|
+
import { PrepareAuth } from './PrepareAuth_kotlin'
|
|
30
31
|
import { kotlinPackage } from './utility_kotlin'
|
|
31
32
|
|
|
32
33
|
|
|
@@ -88,6 +89,25 @@ const Main = cmp(async function Main(props: any) {
|
|
|
88
89
|
// Shared entity runtime (entity/EntityBase.kt).
|
|
89
90
|
EntityBase({ target })
|
|
90
91
|
|
|
92
|
+
// utility/PrepareAuth.kt. GENERATED, NOT COPIED: where the credential
|
|
93
|
+
// goes - header, query parameter or cookie, under the name the spec gives
|
|
94
|
+
// - is a fact about the API, and tm/ can only hold one answer. It was
|
|
95
|
+
// embedded in tm/kotlin/utility/Prepare.kt among the other prepare*
|
|
96
|
+
// helpers, hardcoding an `authorization` header; that one function has
|
|
97
|
+
// moved out into its own compilation unit in the same package, so
|
|
98
|
+
// Register.kt's `u.prepareAuth = ::prepareAuth` binds it unchanged.
|
|
99
|
+
//
|
|
100
|
+
// Called HERE, at Main's TOP LEVEL, and deliberately NOT inside the
|
|
101
|
+
// `core` Folder below. The kotlin tree is FLAT: build.gradle.kts declares
|
|
102
|
+
// core/, utility/, feature/ and entity/ as four sibling source roots, and
|
|
103
|
+
// the Copy above lands tm/kotlin/utility/* at <out>/utility/. The
|
|
104
|
+
// component opens `utility` itself, exactly as EntityBase opens `entity`.
|
|
105
|
+
// Nested in `core` it would write core/utility/PrepareAuth.kt - which
|
|
106
|
+
// still COMPILES, because core/ is scanned recursively and the package
|
|
107
|
+
// declaration is what resolves the symbol, so the misfiling would be
|
|
108
|
+
// invisible to every check. See PrepareAuth_kotlin.
|
|
109
|
+
PrepareAuth({ target })
|
|
110
|
+
|
|
91
111
|
// Generate the client class and config in core/.
|
|
92
112
|
Folder({ name: 'core' }, () => {
|
|
93
113
|
|