@voxgig/sdkgen 4.19.0 → 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.
Files changed (112) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/cmp/AgentGuideContent.js +1 -1
  3. package/dist/sdkgen.d.ts +2 -2
  4. package/dist/sdkgen.js +6 -3
  5. package/dist/sdkgen.js.map +1 -1
  6. package/dist/testkit.js +2 -2
  7. package/dist/testkit.js.map +1 -1
  8. package/dist/tsconfig.tsbuildinfo +1 -1
  9. package/dist/utility.d.ts +4 -1
  10. package/dist/utility.js +60 -0
  11. package/dist/utility.js.map +1 -1
  12. package/model/sdkgen.aon +10 -0
  13. package/package.json +1 -1
  14. package/project/.sdk/model/feature/feature-index.aon +20 -20
  15. package/project/.sdk/src/cmp/c/Config_c.ts +15 -0
  16. package/project/.sdk/src/cmp/c/Main_c.ts +15 -0
  17. package/project/.sdk/src/cmp/c/PrepareAuth_c.ts +371 -0
  18. package/project/.sdk/src/cmp/clojure/Config_clojure.ts +47 -1
  19. package/project/.sdk/src/cmp/clojure/Main_clojure.ts +11 -1
  20. package/project/.sdk/src/cmp/clojure/PrepareAuth_clojure.ts +374 -0
  21. package/project/.sdk/src/cmp/cpp/Config_cpp.ts +40 -0
  22. package/project/.sdk/src/cmp/cpp/Main_cpp.ts +17 -0
  23. package/project/.sdk/src/cmp/cpp/PrepareAuth_cpp.ts +441 -0
  24. package/project/.sdk/src/cmp/csharp/Config_csharp.ts +42 -1
  25. package/project/.sdk/src/cmp/csharp/Main_csharp.ts +18 -0
  26. package/project/.sdk/src/cmp/csharp/PrepareAuth_csharp.ts +392 -0
  27. package/project/.sdk/src/cmp/elixir/Config_elixir.ts +36 -1
  28. package/project/.sdk/src/cmp/elixir/Main_elixir.ts +15 -0
  29. package/project/.sdk/src/cmp/elixir/PrepareAuth_elixir.ts +418 -0
  30. package/project/.sdk/src/cmp/go/Config_go.ts +12 -1
  31. package/project/.sdk/src/cmp/go/Main_go.ts +14 -0
  32. package/project/.sdk/src/cmp/go/PrepareAuth_go.ts +322 -0
  33. package/project/.sdk/src/cmp/java/Config_java.ts +20 -1
  34. package/project/.sdk/src/cmp/java/Main_java.ts +14 -0
  35. package/project/.sdk/src/cmp/java/PrepareAuth_java.ts +298 -0
  36. package/project/.sdk/src/cmp/js/Config_js.ts +12 -1
  37. package/project/.sdk/src/cmp/js/Main_js.ts +6 -0
  38. package/project/.sdk/src/cmp/js/PrepareAuth_js.ts +244 -0
  39. package/project/.sdk/src/cmp/kotlin/Config_kotlin.ts +23 -1
  40. package/project/.sdk/src/cmp/kotlin/Main_kotlin.ts +20 -0
  41. package/project/.sdk/src/cmp/kotlin/PrepareAuth_kotlin.ts +440 -0
  42. package/project/.sdk/src/cmp/lua/Config_lua.ts +15 -1
  43. package/project/.sdk/src/cmp/lua/Main_lua.ts +11 -0
  44. package/project/.sdk/src/cmp/lua/PrepareAuth_lua.ts +364 -0
  45. package/project/.sdk/src/cmp/ocaml/Config_ocaml.ts +31 -1
  46. package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +19 -0
  47. package/project/.sdk/src/cmp/ocaml/PrepareAuth_ocaml.ts +454 -0
  48. package/project/.sdk/src/cmp/perl/Config_perl.ts +30 -0
  49. package/project/.sdk/src/cmp/perl/Main_perl.ts +14 -0
  50. package/project/.sdk/src/cmp/perl/PrepareAuth_perl.ts +387 -0
  51. package/project/.sdk/src/cmp/php/Config_php.ts +12 -1
  52. package/project/.sdk/src/cmp/php/Main_php.ts +7 -0
  53. package/project/.sdk/src/cmp/php/PrepareAuth_php.ts +325 -0
  54. package/project/.sdk/src/cmp/py/Config_py.ts +12 -1
  55. package/project/.sdk/src/cmp/py/Main_py.ts +12 -0
  56. package/project/.sdk/src/cmp/py/PrepareAuth_py.ts +389 -0
  57. package/project/.sdk/src/cmp/rb/Config_rb.ts +18 -1
  58. package/project/.sdk/src/cmp/rb/Main_rb.ts +10 -0
  59. package/project/.sdk/src/cmp/rb/PrepareAuth_rb.ts +305 -0
  60. package/project/.sdk/src/cmp/rust/Config_rust.ts +41 -1
  61. package/project/.sdk/src/cmp/rust/Main_rust.ts +16 -0
  62. package/project/.sdk/src/cmp/rust/PrepareAuth_rust.ts +410 -0
  63. package/project/.sdk/src/cmp/scala/Config_scala.ts +21 -1
  64. package/project/.sdk/src/cmp/scala/Main_scala.ts +14 -0
  65. package/project/.sdk/src/cmp/scala/PrepareAuth_scala.ts +415 -0
  66. package/project/.sdk/src/cmp/swift/Config_swift.ts +37 -1
  67. package/project/.sdk/src/cmp/swift/Main_swift.ts +10 -0
  68. package/project/.sdk/src/cmp/swift/PrepareAuth_swift.ts +439 -0
  69. package/project/.sdk/src/cmp/ts/Config_ts.ts +12 -1
  70. package/project/.sdk/src/cmp/ts/Main_ts.ts +5 -0
  71. package/project/.sdk/src/cmp/ts/PrepareAuth_ts.ts +237 -0
  72. package/project/.sdk/src/cmp/zig/Config_zig.ts +33 -1
  73. package/project/.sdk/src/cmp/zig/Main_zig.ts +16 -0
  74. package/project/.sdk/src/cmp/zig/PrepareAuth_zig.ts +545 -0
  75. package/project/.sdk/tm/clojure/src/sdk/core.clj +31 -20
  76. package/project/.sdk/tm/cpp/utility/pipeline.hpp +36 -40
  77. package/project/.sdk/tm/csharp/utility/MakeOptions.cs +11 -0
  78. package/project/.sdk/tm/elixir/lib/projectname/utility.ex +19 -32
  79. package/project/.sdk/tm/java/utility/MakeOptions.java +13 -1
  80. package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +14 -1
  81. package/project/.sdk/tm/kotlin/utility/Prepare.kt +13 -46
  82. package/project/.sdk/tm/ocaml/Makefile +11 -1
  83. package/project/.sdk/tm/ocaml/sdk_helpers.ml +15 -0
  84. package/project/.sdk/tm/ocaml/sdk_runtime.ml +31 -25
  85. package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +125 -12
  86. package/project/.sdk/tm/ocaml/test/t_pipeline.ml +64 -6
  87. package/project/.sdk/tm/perl/utility/make_options.pm +10 -1
  88. package/project/.sdk/tm/php/utility/MakeOptions.php +8 -1
  89. package/project/.sdk/tm/rust/utility/make_options.rs +13 -1
  90. package/project/.sdk/tm/scala/utility/Make.scala +14 -1
  91. package/project/.sdk/tm/scala/utility/Prepare.scala +16 -40
  92. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +30 -3
  93. package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Prepare.swift +21 -39
  94. package/project/.sdk/tm/zig/core/utility.zig +37 -45
  95. package/project/.sdk/tm/zig/test/pipeline_test.zig +34 -0
  96. package/project/sdkgen-package.json +1 -1
  97. package/src/cmp/AgentGuideContent.ts +1 -1
  98. package/src/sdkgen.ts +4 -1
  99. package/src/testkit.ts +2 -2
  100. package/src/utility.ts +75 -0
  101. package/project/.sdk/tm/c/utility/prepare_auth.c +0 -65
  102. package/project/.sdk/tm/csharp/utility/PrepareAuth.cs +0 -54
  103. package/project/.sdk/tm/go/utility/prepare_auth.go +0 -59
  104. package/project/.sdk/tm/java/utility/PrepareAuth.java +0 -66
  105. package/project/.sdk/tm/js/src/utility/PrepareAuthUtility.js +0 -49
  106. package/project/.sdk/tm/lua/utility/prepare_auth.lua +0 -52
  107. package/project/.sdk/tm/perl/utility/prepare_auth.pm +0 -56
  108. package/project/.sdk/tm/php/utility/PrepareAuth.php +0 -45
  109. package/project/.sdk/tm/py/pkg/utility/prepare_auth.py +0 -46
  110. package/project/.sdk/tm/rb/utility/prepare_auth.rb +0 -35
  111. package/project/.sdk/tm/rust/utility/prepare_auth.rs +0 -65
  112. package/project/.sdk/tm/ts/src/utility/PrepareAuthUtility.ts +0 -78
@@ -0,0 +1,325 @@
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 in `tm/php/utility/` that hardcoded an
24
+ // `authorization` HEADER. apidef has always resolved the scheme's `in` and
25
+ // `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 repos
29
+ // 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 a
35
+ // bearer-token SDK, and no runtime `if` on a value that is fixed at
36
+ // generation time.
37
+ //
38
+ // The php peer of cmp/ts/PrepareAuth_ts.ts.
39
+ const PrepareAuth = cmp(async function PrepareAuth(props: any) {
40
+ const { target } = props
41
+ const { model } = props.ctx$
42
+
43
+ // FOLDER NESTING. Main_php opens NO folder around its children — it
44
+ // writes `<sdk>_sdk.php`, `features.php` and (inside `Folder('.')`)
45
+ // `config.php` straight into the target root, and each sibling component
46
+ // opens its own single level (EntityTypes -> `types/`, Entity ->
47
+ // `entity/`, Test -> `test/`). The template this replaces lived at
48
+ // `tm/php/utility/PrepareAuth.php` and the blanket Copy puts `tm/php/*`
49
+ // at the target root, so the generated file belongs at `utility/`, one
50
+ // folder deep. (This is NOT the ts layout: there Main already opens
51
+ // `src`, so PrepareAuth_ts must not open a second one.)
52
+ Folder({ name: 'utility' }, () => {
53
+ File({ name: 'PrepareAuth.' + target.ext }, () => {
54
+ Content(render({
55
+ Name: model.const.Name,
56
+ active: authSwitchedOn(model),
57
+ where: resolveAuthIn(model),
58
+ name: resolveAuthName(model),
59
+ basic: isHttpBasicAuth(model),
60
+ // Read so the resolution is exercised here too, even though the
61
+ // prefix is a RUNTIME option (`options.auth.prefix`, emitted by
62
+ // Config_php) rather than something baked into this file.
63
+ prefix: resolveAuthPrefix(model),
64
+ }))
65
+ })
66
+ })
67
+ })
68
+
69
+
70
+ // NOT `isAuthActive`, AND THE DIFFERENCE IS LOAD-BEARING (the py port found
71
+ // this first; same reasoning, same fix, and php's own lane proves it here).
72
+ //
73
+ // `isAuthActive` is false whenever the SPEC declares no security scheme
74
+ // (`main.kit.info.auth: false`). That is a statement about the DEFINITION,
75
+ // not a ban on ever sending a credential: apidef writes it for every spec
76
+ // with no securitySchemes block, GitHub's official OpenAPI included, and
77
+ // those SDKs are still expected to honour an `apikey` the caller passes.
78
+ // The template placed the credential unconditionally, so they did.
79
+ //
80
+ // Gating the body on `isAuthActive` therefore does not trim dead code, it
81
+ // deletes working authentication. MEASURED, not assumed: with the wider gate
82
+ // this component emitted the no-op for generatedcompile's own fixture
83
+ // (`main: kit: info: { ... auth: false }`) and the php lane went red —
84
+ //
85
+ // php: auth null beats an explicit apikey
86
+ // FAIL: baseline broken: an ordinary apikey was not sent
87
+ //
88
+ // So the no-op is emitted only when the PROJECT says so:
89
+ // `config.auth.active: false`, an explicit per-SDK switch nobody sets by
90
+ // accident. A spec that is merely silent keeps the credential path it has
91
+ // always had.
92
+ function authSwitchedOn(model: any): boolean {
93
+ const auth = getModelPath(model, `main.${KIT}.config.auth`,
94
+ { only_active: false, required: false })
95
+ return !(null != auth && false === auth.active)
96
+ }
97
+
98
+
99
+ type AuthSpec = {
100
+ Name: string,
101
+ active: boolean,
102
+ where: string,
103
+ name: string,
104
+ basic: boolean,
105
+ prefix: string,
106
+ }
107
+
108
+
109
+ function render(spec: AuthSpec): string {
110
+ const Name = spec.Name
111
+
112
+ const head = `<?php
113
+ declare(strict_types=1);
114
+
115
+ // ${Name} SDK utility: prepare_auth
116
+
117
+ `
118
+
119
+ // AUTH SWITCHED OFF BY THE PROJECT (see authSwitchedOn for why only an
120
+ // EXPLICIT switch counts). The SDK gets a prepare_auth that is honest
121
+ // about it rather than one that deletes a header nobody set.
122
+ if (!spec.active) {
123
+ return head + `// This SDK is configured with authentication off, so there is no
124
+ // credential to place. The class stays in the pipeline because make_spec
125
+ // calls prepare_auth unconditionally.
126
+ class ${Name}PrepareAuth
127
+ {
128
+ public static function call(${Name}Context $ctx): array
129
+ {
130
+ $spec = $ctx->spec;
131
+ if (!$spec) {
132
+ return [null, $ctx->make_error('auth_no_spec', 'Expected context spec property to be defined.')];
133
+ }
134
+
135
+ return [$spec, null];
136
+ }
137
+ }
138
+ `
139
+ }
140
+
141
+ const bag = bagVar(spec.where)
142
+
143
+ return head + `class ${Name}PrepareAuth
144
+ {
145
+ ${constants(spec)}
146
+ public static function call(${Name}Context $ctx): array
147
+ {
148
+ $spec = $ctx->spec;
149
+ if (!$spec) {
150
+ return [null, $ctx->make_error('auth_no_spec', 'Expected context spec property to be defined.')];
151
+ }
152
+
153
+ $${bag} = &$spec->${bag};
154
+ $options = $ctx->client->options_map();
155
+
156
+ // Public APIs that need no auth omit the options.auth block entirely.
157
+ if (!isset($options['auth']) || $options['auth'] === null) {
158
+ ${suppressed(spec.where)} return [$spec, null];
159
+ }
160
+
161
+ $apikey = \\Voxgig\\Struct\\Struct::getprop($options, self::OPTION_APIKEY, self::NOT_FOUND);
162
+ ${basicBlock(spec)}${placeBlock(spec)}
163
+ return [$spec, null];
164
+ }
165
+ }
166
+ `
167
+ }
168
+
169
+
170
+ // The bag the credential lands in, per placement. Cookies ride the header
171
+ // bag because a cookie IS a header.
172
+ function bagVar(where: string): string {
173
+ return 'query' === where ? 'query' : 'headers'
174
+ }
175
+
176
+
177
+ // The constant holding the credential's NAME, per placement. `HEADER_AUTH`
178
+ // keeps the name the template used, so a header SDK regenerates unchanged.
179
+ function credConst(where: string): string {
180
+ return 'query' === where ? 'QUERY_AUTH' : 'cookie' === where ? 'COOKIE_AUTH' : 'HEADER_AUTH'
181
+ }
182
+
183
+
184
+ function constants(spec: AuthSpec): string {
185
+ // A HEADER NAME GOES IN LOWERCASE, as every target's template has always
186
+ // written it (`authorization`): request header names are case-insensitive,
187
+ // and this SDK's own response headers are lowercased by the fetcher, so
188
+ // lowercasing here keeps one spelling throughout — and keeps the default
189
+ // byte-identical to the template this replaces. A query parameter and a
190
+ // cookie name are CASE-SENSITIVE, so those go in verbatim.
191
+ const name = 'header' === spec.where ? spec.name.toLowerCase() : spec.name
192
+
193
+ const cookieConst = 'cookie' === spec.where ?
194
+ ` private const HEADER_COOKIE = 'cookie';\n` : ''
195
+
196
+ const secretConst = basicActive(spec) ?
197
+ ` private const OPTION_SECRET = 'secret';\n` : ''
198
+
199
+ return ` private const ${credConst(spec.where)} = ${phpstr(name)};
200
+ ${cookieConst} private const OPTION_APIKEY = 'apikey';
201
+ ${secretConst} private const NOT_FOUND = '__NOTFOUND__';
202
+ `
203
+ }
204
+
205
+
206
+ // The `options.auth` block is absent (`auth: null`) — drop any stale
207
+ // credential the caller's own options put in the bag.
208
+ function suppressed(where: string): string {
209
+ if ('cookie' === where) {
210
+ // NOTHING TO CLEAR. The cookie header may carry the caller's own
211
+ // cookies, and this SDK has not written a pair of its own into this
212
+ // spec, so removing the header would throw away someone else's state.
213
+ return ''
214
+ }
215
+ return ` unset($${bagVar(where)}[self::${credConst(where)}]);\n`
216
+ }
217
+
218
+
219
+ // HTTP Basic is header-only by definition: the scheme is
220
+ // `Authorization: Basic base64(user:pass)`. It cannot be expressed as a
221
+ // query parameter or a cookie, so the branch is emitted only where it can
222
+ // mean something.
223
+ function basicActive(spec: AuthSpec): boolean {
224
+ return spec.basic && 'header' === spec.where
225
+ }
226
+
227
+
228
+ function basicBlock(spec: AuthSpec): string {
229
+ if (!basicActive(spec)) {
230
+ return ''
231
+ }
232
+
233
+ return `
234
+ // True HTTP Basic Auth needs TWO credentials, base64-joined - a
235
+ // single token in the header (the branch below) can never
236
+ // authenticate against an API that actually checks
237
+ // \`Authorization: Basic base64(user:pass)\`.
238
+ if (true === (\\Voxgig\\Struct\\Struct::getpath($options, 'auth.basic') ?? false)) {
239
+ $secret = \\Voxgig\\Struct\\Struct::getprop($options, self::OPTION_SECRET, self::NOT_FOUND);
240
+ $apikey_val = is_string($apikey) && $apikey !== self::NOT_FOUND ? $apikey : '';
241
+ $secret_val = is_string($secret) && $secret !== self::NOT_FOUND ? $secret : '';
242
+
243
+ if ($apikey_val === '' || $secret_val === '') {
244
+ unset($headers[self::HEADER_AUTH]);
245
+ } else {
246
+ $auth_prefix = \\Voxgig\\Struct\\Struct::getpath($options, 'auth.prefix') ?? '';
247
+ $b64 = base64_encode("{$apikey_val}:{$secret_val}");
248
+ $headers[self::HEADER_AUTH] = $auth_prefix === ''
249
+ ? $b64 : "{$auth_prefix} {$b64}";
250
+ }
251
+
252
+ return [$spec, null];
253
+ }
254
+ `
255
+ }
256
+
257
+
258
+ function placeBlock(spec: AuthSpec): string {
259
+ const missing = `(is_string($apikey) && ($apikey === self::NOT_FOUND || $apikey === ''))
260
+ || $apikey === null`
261
+
262
+ if ('cookie' === spec.where) {
263
+ // A MISSING CREDENTIAL CLEARS NOTHING HERE, for the reason `suppressed`
264
+ // gives: the cookie header is shared with the caller's own cookies.
265
+ return `
266
+ $missing = ${missing};
267
+
268
+ if (!$missing) {
269
+ // A COOKIE IS APPENDED, NEVER ASSIGNED: the header may already
270
+ // carry the caller's own cookies, and one \`Cookie:\` header
271
+ // holds all of them, separated by '; '.
272
+ $apikey_val = is_string($apikey) ? $apikey : '';
273
+ $existing = $headers[self::HEADER_COOKIE] ?? '';
274
+ $pair = self::COOKIE_AUTH . '=' . $apikey_val;
275
+ $headers[self::HEADER_COOKIE] = $existing === ''
276
+ ? $pair : "{$existing}; {$pair}";
277
+ }
278
+ `
279
+ }
280
+
281
+ if ('query' === spec.where) {
282
+ return `
283
+ if (
284
+ ${missing}
285
+ ) {
286
+ unset($query[self::QUERY_AUTH]);
287
+ } else {
288
+ // NO PREFIX IN A QUERY STRING. \`?token=Bearer%20abc\` is not a
289
+ // thing any API reads; the prefix is a header convention and is
290
+ // dropped here deliberately rather than silently concatenated.
291
+ $query[self::QUERY_AUTH] = is_string($apikey) ? $apikey : '';
292
+ }
293
+ `
294
+ }
295
+
296
+ return `
297
+ if (
298
+ ${missing}
299
+ ) {
300
+ unset($headers[self::HEADER_AUTH]);
301
+ } else {
302
+ $auth_prefix = \\Voxgig\\Struct\\Struct::getpath($options, 'auth.prefix') ?? '';
303
+ $apikey_val = is_string($apikey) ? $apikey : '';
304
+ // Empty prefix (raw apiKey credential) must not add a leading space.
305
+ $headers[self::HEADER_AUTH] = $auth_prefix === ''
306
+ ? $apikey_val : "{$auth_prefix} {$apikey_val}";
307
+ }
308
+ `
309
+ }
310
+
311
+
312
+ // A PHP single-quoted string literal: only the backslash and the quote
313
+ // itself need escaping, and single quotes never interpolate a `$name`.
314
+ function phpstr(s: string): string {
315
+ return "'" + String(s).replace(/\\/g, '\\\\').replace(/'/g, "\\'") + "'"
316
+ }
317
+
318
+
319
+ export {
320
+ PrepareAuth,
321
+ // Exported so the emitted PHP can be exercised directly (tests, and a
322
+ // one-line check of what a given placement renders) without standing up a
323
+ // full generation run.
324
+ render,
325
+ }
@@ -13,6 +13,8 @@ import {
13
13
  each,
14
14
  isAuthActive,
15
15
  isConfigData,
16
+ resolveAuthIn,
17
+ resolveAuthName,
16
18
  resolveAuthPrefix,
17
19
  serverVariables,
18
20
  targetFeatures,
@@ -107,6 +109,13 @@ const Config = cmp(async function Config(props: any) {
107
109
  const authActive = isAuthActive(model)
108
110
  // config.auth.prefix override -> spec-derived info.security.prefix -> 'Bearer'
109
111
  const authPrefix = resolveAuthPrefix(model)
112
+ // `in` and `name` travel with the prefix now. They were resolved by
113
+ // apidef all along and dropped here, so an apiKey-in-query API got an
114
+ // Authorization header it does not read. Emitted only when they differ
115
+ // from the defaults, so a header/Authorization SDK is byte-identical to
116
+ // what it generated before.
117
+ const authIn = resolveAuthIn(model)
118
+ const authName = resolveAuthName(model)
110
119
 
111
120
  let baseUrl = ''
112
121
  try { baseUrl = getModelPath(model, `main.${KIT}.info.servers.0.url`) } catch (_e) { }
@@ -121,7 +130,9 @@ const Config = cmp(async function Config(props: any) {
121
130
 
122
131
  const authBlock = authActive
123
132
  ? ` "auth": {
124
- "prefix": "${authPrefix}",
133
+ "prefix": "${authPrefix}",${'header' === authIn ? '' : `
134
+ "in": "${authIn}",`}${'Authorization' === authName ? '' : `
135
+ "name": "${authName}",`}
125
136
  },\n`
126
137
  : ''
127
138
 
@@ -24,6 +24,7 @@ import {
24
24
 
25
25
  import { Package } from './Package_py'
26
26
  import { Config } from './Config_py'
27
+ import { PrepareAuth } from './PrepareAuth_py'
27
28
  import { Gitignore } from './Gitignore_py'
28
29
  import { MainEntity } from './MainEntity_py'
29
30
  import { EntityTypes } from './EntityTypes_py'
@@ -190,6 +191,17 @@ if TYPE_CHECKING:
190
191
  Config({ target })
191
192
  })
192
193
 
194
+ // GENERATED, NOT COPIED. Where the credential goes is a fact about the
195
+ // API, and tm/ can only hold one answer. The blanket tm/py/pkg copy above
196
+ // no longer brings a prepare_auth.py in - it was deleted, since both
197
+ // writers would claim the same output path. See PrepareAuth_py.
198
+ //
199
+ // Called HERE, inside the <name>_sdk package folder and outside any
200
+ // other, because that is where the deleted template's own path
201
+ // (tm/py/pkg/utility/prepare_auth.py) put it: the component opens the one
202
+ // remaining segment, `utility`, itself.
203
+ PrepareAuth({ target })
204
+
193
205
  // Generate feature factory module
194
206
  File({ name: 'features.' + target.ext }, () => {
195
207
  Content(`# ${model.const.Name} SDK feature factory