@voxgig/sdkgen 0.43.0 → 0.45.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 (127) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/dist/cmp/ReadmeEntity.js +9 -153
  3. package/dist/cmp/ReadmeEntity.js.map +1 -1
  4. package/dist/cmp/ReadmeIntro.js +9 -14
  5. package/dist/cmp/ReadmeIntro.js.map +1 -1
  6. package/dist/cmp/ReadmeModel.js +6 -4
  7. package/dist/cmp/ReadmeModel.js.map +1 -1
  8. package/dist/cmp/ReadmeOptions.js +9 -61
  9. package/dist/cmp/ReadmeOptions.js.map +1 -1
  10. package/dist/cmp/ReadmeRef.js +10 -1328
  11. package/dist/cmp/ReadmeRef.js.map +1 -1
  12. package/dist/sdkgen.d.ts +2 -2
  13. package/dist/sdkgen.js +2 -1
  14. package/dist/sdkgen.js.map +1 -1
  15. package/dist/utility.d.ts +2 -1
  16. package/dist/utility.js +9 -0
  17. package/dist/utility.js.map +1 -1
  18. package/package.json +1 -1
  19. package/project/.sdk/src/cmp/go/Config_go.ts +9 -4
  20. package/project/.sdk/src/cmp/go/Gitignore_go.ts +47 -0
  21. package/project/.sdk/src/cmp/go/Main_go.ts +3 -0
  22. package/project/.sdk/src/cmp/go/ReadmeEntity_go.ts +138 -0
  23. package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +6 -3
  24. package/project/.sdk/src/cmp/go/ReadmeIntro_go.ts +18 -0
  25. package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +6 -3
  26. package/project/.sdk/src/cmp/go/ReadmeOptions_go.ts +58 -0
  27. package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +11 -7
  28. package/project/.sdk/src/cmp/go/ReadmeRef_go.ts +354 -0
  29. package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +6 -4
  30. package/project/.sdk/src/cmp/go/TestDirect_go.ts +18 -8
  31. package/project/.sdk/src/cmp/go/TestEntity_go.ts +105 -54
  32. package/project/.sdk/src/cmp/js/Config_js.ts +18 -0
  33. package/project/.sdk/src/cmp/js/Gitignore_js.ts +35 -0
  34. package/project/.sdk/src/cmp/js/Main_js.ts +3 -0
  35. package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +138 -0
  36. package/project/.sdk/src/cmp/js/ReadmeHowto_js.ts +11 -6
  37. package/project/.sdk/src/cmp/js/ReadmeIntro_js.ts +18 -0
  38. package/project/.sdk/src/cmp/js/ReadmeModel_js.ts +6 -3
  39. package/project/.sdk/src/cmp/js/ReadmeOptions_js.ts +58 -0
  40. package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +6 -4
  41. package/project/.sdk/src/cmp/js/ReadmeRef_js.ts +384 -0
  42. package/project/.sdk/src/cmp/js/ReadmeTopQuick_js.ts +6 -4
  43. package/project/.sdk/src/cmp/js/TestDirect_js.ts +23 -12
  44. package/project/.sdk/src/cmp/js/TestEntity_js.ts +107 -74
  45. package/project/.sdk/src/cmp/js/fragment/Config.fragment.js +1 -5
  46. package/project/.sdk/src/cmp/lua/Config_lua.ts +9 -4
  47. package/project/.sdk/src/cmp/lua/Gitignore_lua.ts +39 -0
  48. package/project/.sdk/src/cmp/lua/Main_lua.ts +3 -0
  49. package/project/.sdk/src/cmp/lua/ReadmeEntity_lua.ts +138 -0
  50. package/project/.sdk/src/cmp/lua/ReadmeHowto_lua.ts +6 -3
  51. package/project/.sdk/src/cmp/lua/ReadmeIntro_lua.ts +18 -0
  52. package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +6 -3
  53. package/project/.sdk/src/cmp/lua/ReadmeOptions_lua.ts +58 -0
  54. package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +6 -4
  55. package/project/.sdk/src/cmp/lua/ReadmeRef_lua.ts +360 -0
  56. package/project/.sdk/src/cmp/lua/ReadmeTopQuick_lua.ts +6 -4
  57. package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +18 -8
  58. package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +95 -51
  59. package/project/.sdk/src/cmp/php/Config_php.ts +10 -8
  60. package/project/.sdk/src/cmp/php/Gitignore_php.ts +33 -0
  61. package/project/.sdk/src/cmp/php/Main_php.ts +3 -0
  62. package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +138 -0
  63. package/project/.sdk/src/cmp/php/ReadmeHowto_php.ts +6 -3
  64. package/project/.sdk/src/cmp/php/ReadmeIntro_php.ts +18 -0
  65. package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +6 -3
  66. package/project/.sdk/src/cmp/php/ReadmeOptions_php.ts +58 -0
  67. package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +6 -4
  68. package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +358 -0
  69. package/project/.sdk/src/cmp/php/ReadmeTopQuick_php.ts +6 -4
  70. package/project/.sdk/src/cmp/php/TestDirect_php.ts +18 -8
  71. package/project/.sdk/src/cmp/php/TestEntity_php.ts +101 -54
  72. package/project/.sdk/src/cmp/py/Config_py.ts +9 -4
  73. package/project/.sdk/src/cmp/py/Gitignore_py.ts +55 -0
  74. package/project/.sdk/src/cmp/py/Main_py.ts +3 -0
  75. package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +138 -0
  76. package/project/.sdk/src/cmp/py/ReadmeHowto_py.ts +6 -3
  77. package/project/.sdk/src/cmp/py/ReadmeIntro_py.ts +18 -0
  78. package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +6 -3
  79. package/project/.sdk/src/cmp/py/ReadmeOptions_py.ts +58 -0
  80. package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +9 -6
  81. package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +356 -0
  82. package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +9 -6
  83. package/project/.sdk/src/cmp/py/TestDirect_py.ts +18 -8
  84. package/project/.sdk/src/cmp/py/TestEntity_py.ts +100 -50
  85. package/project/.sdk/src/cmp/rb/Config_rb.ts +9 -4
  86. package/project/.sdk/src/cmp/rb/Gitignore_rb.ts +38 -0
  87. package/project/.sdk/src/cmp/rb/Main_rb.ts +3 -0
  88. package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +138 -0
  89. package/project/.sdk/src/cmp/rb/ReadmeHowto_rb.ts +6 -3
  90. package/project/.sdk/src/cmp/rb/ReadmeIntro_rb.ts +18 -0
  91. package/project/.sdk/src/cmp/rb/ReadmeModel_rb.ts +6 -3
  92. package/project/.sdk/src/cmp/rb/ReadmeOptions_rb.ts +58 -0
  93. package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +6 -4
  94. package/project/.sdk/src/cmp/rb/ReadmeRef_rb.ts +361 -0
  95. package/project/.sdk/src/cmp/rb/ReadmeTopQuick_rb.ts +6 -4
  96. package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +18 -8
  97. package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +95 -51
  98. package/project/.sdk/src/cmp/ts/Config_ts.ts +18 -0
  99. package/project/.sdk/src/cmp/ts/Gitignore_ts.ts +37 -0
  100. package/project/.sdk/src/cmp/ts/Main_ts.ts +3 -0
  101. package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +138 -0
  102. package/project/.sdk/src/cmp/ts/ReadmeHowto_ts.ts +11 -6
  103. package/project/.sdk/src/cmp/ts/ReadmeIntro_ts.ts +18 -0
  104. package/project/.sdk/src/cmp/ts/ReadmeModel_ts.ts +9 -5
  105. package/project/.sdk/src/cmp/ts/ReadmeOptions_ts.ts +58 -0
  106. package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +6 -4
  107. package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +384 -0
  108. package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +6 -4
  109. package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +68 -20
  110. package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +109 -74
  111. package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +1 -5
  112. package/project/.sdk/tm/go/utility/prepare_auth.go +15 -1
  113. package/project/.sdk/tm/js/src/utility/PrepareAuthUtility.js +7 -1
  114. package/project/.sdk/tm/lua/utility/prepare_auth.lua +9 -1
  115. package/project/.sdk/tm/php/utility/PrepareAuth.php +11 -1
  116. package/project/.sdk/tm/py/utility/prepare_auth.py +10 -1
  117. package/project/.sdk/tm/rb/utility/prepare_auth.rb +8 -1
  118. package/project/.sdk/tm/ts/src/utility/MakeUrlUtility.ts +7 -8
  119. package/project/.sdk/tm/ts/src/utility/PrepareAuthUtility.ts +7 -1
  120. package/src/cmp/ReadmeEntity.ts +11 -178
  121. package/src/cmp/ReadmeIntro.ts +11 -25
  122. package/src/cmp/ReadmeModel.ts +7 -5
  123. package/src/cmp/ReadmeOptions.ts +12 -74
  124. package/src/cmp/ReadmeRef.ts +11 -1372
  125. package/src/sdkgen.ts +2 -1
  126. package/src/utility.ts +12 -0
  127. /package/project/.sdk/tm/go/utility/{make_target.go → make_point.go} +0 -0
@@ -7,7 +7,12 @@ import {
7
7
 
8
8
  import {
9
9
  KIT,
10
+ Model,
11
+ ModelEntity,
12
+ ModelEntityFlow,
13
+ ModelEntityFlowStep,
10
14
  getModelPath,
15
+ nom,
11
16
  } from '@voxgig/apidef'
12
17
 
13
18
 
@@ -18,34 +23,43 @@ import {
18
23
  each,
19
24
  buildIdNames,
20
25
  getMatchEntries,
26
+ isAuthActive,
21
27
  } from '@voxgig/sdkgen'
22
28
 
23
29
 
24
- type OpGen = (ctx: GenCtx, step: any, index: any) => void
25
-
30
+ // See TestEntity_ts.ts for the GenCtx/OpGen contract.
26
31
  type GenCtx = {
27
- model: any
28
- entity: any
29
- flow: any
32
+ model: Model
33
+ entity: ModelEntity
34
+ flow: ModelEntityFlow
30
35
  PROJUPPER: string
31
36
  }
32
37
 
38
+ type OpGen = (ctx: GenCtx, step: ModelEntityFlowStep, index: number) => void
39
+
33
40
 
34
41
  const TestEntity = cmp(function TestEntity(props: any) {
35
42
  const ctx$ = props.ctx$
36
- const model = ctx$.model
43
+ const model: Model = ctx$.model
37
44
 
38
45
  const target = props.target
39
- const entity = props.entity
46
+ const entity: ModelEntity = props.entity
40
47
 
41
- const basicflow = getModelPath(model, `main.${KIT}.flow.Basic${entity.Name}Flow`)
42
- const dobasic = basicflow && true === basicflow.active
43
-
44
- if (!dobasic) {
48
+ const basicflow: ModelEntityFlow | undefined =
49
+ getModelPath(model, `main.${KIT}.flow.Basic${nom(entity, 'Name')}Flow`)
50
+ if (null == basicflow || true !== basicflow.active) {
45
51
  return
46
52
  }
47
53
 
48
- const PROJUPPER = model.const.Name.toUpperCase().replace(/[^A-Z_]/g, '_')
54
+ const PROJUPPER = nom(model.const, 'Name').toUpperCase().replace(/[^A-Z_]/g, '_')
55
+
56
+ const authActive = isAuthActive(model)
57
+ const apikeyEnvEntry = authActive
58
+ ? `\n "${PROJUPPER}_APIKEY" => "NONE",`
59
+ : ''
60
+ const apikeyLiveField = authActive
61
+ ? `\n "apikey" => env["${PROJUPPER}_APIKEY"],`
62
+ : ''
49
63
 
50
64
  const idnames = buildIdNames(entity, basicflow)
51
65
  const idnamesStr = idnames.map(n => `"${n}"`).join(', ')
@@ -141,8 +155,7 @@ end
141
155
  Content(` env = Runner.env_override({
142
156
  "${PROJUPPER}_TEST_${entity.name.toUpperCase().replace(/[^A-Z_]/g, '_')}_ENTID" => idmap,
143
157
  "${PROJUPPER}_TEST_LIVE" => "FALSE",
144
- "${PROJUPPER}_TEST_EXPLAIN" => "FALSE",
145
- "${PROJUPPER}_APIKEY" => "NONE",
158
+ "${PROJUPPER}_TEST_EXPLAIN" => "FALSE",${apikeyEnvEntry}
146
159
  })
147
160
 
148
161
  idmap_resolved = Helpers.to_map(
@@ -163,8 +176,7 @@ end
163
176
  Content(`
164
177
  if env["${PROJUPPER}_TEST_LIVE"] == "TRUE"
165
178
  merged_opts = Vs.merge([
166
- {
167
- "apikey" => env["${PROJUPPER}_APIKEY"],
179
+ {${apikeyLiveField}
168
180
  },
169
181
  extra || {},
170
182
  ])
@@ -187,9 +199,9 @@ end
187
199
 
188
200
  const generateCreate: OpGen = (ctx, step, index) => {
189
201
  const { entity, flow } = ctx
190
- const ref = step.input?.ref ?? entity.name + '_ref01'
191
- const entvar = step.input?.entvar ?? ref + '_ent'
192
- const datavar = step.input?.datavar ?? (ref + '_data' + (step.input?.suffix ?? ''))
202
+ const ref = step.input.ref ?? entity.name + '_ref01'
203
+ const entvar = step.input.entvar ?? ref + '_ent'
204
+ const datavar = step.input.datavar ?? (ref + '_data' + (step.input.suffix ?? ''))
193
205
 
194
206
  const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
195
207
  const needsEnt = !priorSteps.some((s: any) =>
@@ -197,8 +209,8 @@ const generateCreate: OpGen = (ctx, step, index) => {
197
209
 
198
210
  const hasDatvar = priorSteps.some((s: any) => {
199
211
  if ('create' === s.op) {
200
- const priorRef = s.input?.ref ?? entity.name + '_ref01'
201
- const priorDatvar = s.input?.datavar ?? (priorRef + '_data' + (s.input?.suffix ?? ''))
212
+ const priorRef = s.input.ref ?? entity.name + '_ref01'
213
+ const priorDatvar = s.input.datavar ?? (priorRef + '_data' + (s.input.suffix ?? ''))
202
214
  return priorDatvar === datavar
203
215
  }
204
216
  return false
@@ -232,17 +244,20 @@ const generateCreate: OpGen = (ctx, step, index) => {
232
244
  assert_nil err
233
245
  ${datavar} = Helpers.to_map(${datavar}_result)
234
246
  assert !${datavar}.nil?
235
- assert !${datavar}["id"].nil?
236
247
  `)
248
+ if (null != ctx.entity.id) {
249
+ Content(` assert !${datavar}["id"].nil?
250
+ `)
251
+ }
237
252
  }
238
253
 
239
254
 
240
255
  const generateList: OpGen = (ctx, step, index) => {
241
256
  const { entity, flow } = ctx
242
- const ref = step.input?.ref ?? entity.name + '_ref01'
243
- const entvar = step.input?.entvar ?? ref + '_ent'
244
- const matchvar = step.input?.matchvar ?? (ref + '_match' + (step.input?.suffix ?? ''))
245
- const listvar = step.input?.listvar ?? (ref + '_list' + (step.input?.suffix ?? ''))
257
+ const ref = step.input.ref ?? entity.name + '_ref01'
258
+ const entvar = step.input.entvar ?? ref + '_ent'
259
+ const matchvar = step.input.matchvar ?? (ref + '_match' + (step.input.suffix ?? ''))
260
+ const listvar = step.input.listvar ?? (ref + '_list' + (step.input.suffix ?? ''))
246
261
 
247
262
  const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
248
263
  const needsEnt = !priorSteps.some((s: any) =>
@@ -282,7 +297,7 @@ const generateList: OpGen = (ctx, step, index) => {
282
297
  for (const validator of step.valid) {
283
298
  const validRef = validator.def?.ref
284
299
  const hasRefData = validRef && allSteps.some((s: any) => 'create' === s.op &&
285
- ((s.input?.ref ?? entity.name + '_ref01') === validRef))
300
+ ((s.input.ref ?? entity.name + '_ref01') === validRef))
286
301
 
287
302
  if ('ItemExists' === validator.apply && hasRefData) {
288
303
  const refDataVar = validRef + '_data'
@@ -308,17 +323,19 @@ const generateList: OpGen = (ctx, step, index) => {
308
323
 
309
324
  const generateUpdate: OpGen = (ctx, step, index) => {
310
325
  const { entity, flow } = ctx
311
- const ref = step.input?.ref ?? entity.name + '_ref01'
312
- const entvar = step.input?.entvar ?? ref + '_ent'
313
- const datavar = step.input?.datavar ?? (ref + '_data' + (step.input?.suffix ?? ''))
314
- const resdatavar = step.input?.resdatavar ?? (ref + '_resdata' + (step.input?.suffix ?? ''))
315
- const markdefvar = step.input?.markdefvar ?? (ref + '_markdef' + (step.input?.suffix ?? ''))
316
- const srcdatavar = step.input?.srcdatavar ?? (ref + '_data' + (step.input?.suffix ?? ''))
326
+ const ref = step.input.ref ?? entity.name + '_ref01'
327
+ const entvar = step.input.entvar ?? ref + '_ent'
328
+ const datavar = step.input.datavar ?? (ref + '_data' + (step.input.suffix ?? ''))
329
+ const resdatavar = step.input.resdatavar ?? (ref + '_resdata' + (step.input.suffix ?? ''))
330
+ const markdefvar = step.input.markdefvar ?? (ref + '_markdef' + (step.input.suffix ?? ''))
331
+ const srcdatavar = step.input.srcdatavar ?? (ref + '_data' + (step.input.suffix ?? ''))
317
332
 
318
333
  const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
319
334
  const needsEnt = !priorSteps.some((s: any) =>
320
335
  ['create', 'list', 'load', 'update', 'remove'].includes(s.op))
321
336
 
337
+ const hasEntIdU = null != entity.id
338
+
322
339
  Content(` # UPDATE
323
340
  `)
324
341
  if (needsEnt) {
@@ -326,8 +343,11 @@ const generateUpdate: OpGen = (ctx, step, index) => {
326
343
  `)
327
344
  }
328
345
  Content(` ${datavar}_up = {
329
- "id" => ${srcdatavar}["id"],
330
346
  `)
347
+ if (hasEntIdU) {
348
+ Content(` "id" => ${srcdatavar}["id"],
349
+ `)
350
+ }
331
351
 
332
352
  if (step.data) {
333
353
  const dataEntries = Object.entries(step.data).filter(([k]: any) => k !== 'id' && !k.endsWith('$'))
@@ -342,7 +362,7 @@ const generateUpdate: OpGen = (ctx, step, index) => {
342
362
 
343
363
  if (step.spec) {
344
364
  for (const spec of step.spec) {
345
- if ('TextFieldMark' === spec.apply && null != step.input?.textfield) {
365
+ if ('TextFieldMark' === spec.apply && null != step.input.textfield) {
346
366
  const fieldname = step.input.textfield
347
367
  const fieldvalue = spec.def?.mark ?? `Mark01-${ref}`
348
368
  Content(`
@@ -359,12 +379,15 @@ const generateUpdate: OpGen = (ctx, step, index) => {
359
379
  assert_nil err
360
380
  ${resdatavar} = Helpers.to_map(${resdatavar}_result)
361
381
  assert !${resdatavar}.nil?
362
- assert_equal ${resdatavar}["id"], ${datavar}_up["id"]
363
382
  `)
383
+ if (hasEntIdU) {
384
+ Content(` assert_equal ${resdatavar}["id"], ${datavar}_up["id"]
385
+ `)
386
+ }
364
387
 
365
388
  if (step.spec) {
366
389
  for (const spec of step.spec) {
367
- if ('TextFieldMark' === spec.apply && null != step.input?.textfield) {
390
+ if ('TextFieldMark' === spec.apply && null != step.input.textfield) {
368
391
  Content(` assert_equal ${resdatavar}[${markdefvar}_name], ${markdefvar}_value
369
392
  `)
370
393
  }
@@ -375,11 +398,11 @@ const generateUpdate: OpGen = (ctx, step, index) => {
375
398
 
376
399
  const generateLoad: OpGen = (ctx, step, index) => {
377
400
  const { entity, flow } = ctx
378
- const ref = step.input?.ref ?? entity.name + '_ref01'
379
- const entvar = step.input?.entvar ?? ref + '_ent'
380
- const matchvar = step.input?.matchvar ?? (ref + '_match' + (step.input?.suffix ?? ''))
381
- const datavar = step.input?.datavar ?? (ref + '_data' + (step.input?.suffix ?? ''))
382
- const srcdatavar = step.input?.srcdatavar ?? (ref + '_data' + (step.input?.suffix ?? ''))
401
+ const ref = step.input.ref ?? entity.name + '_ref01'
402
+ const entvar = step.input.entvar ?? ref + '_ent'
403
+ const matchvar = step.input.matchvar ?? (ref + '_match' + (step.input.suffix ?? ''))
404
+ const datavar = step.input.datavar ?? (ref + '_data' + (step.input.suffix ?? ''))
405
+ const srcdatavar = step.input.srcdatavar ?? (ref + '_data' + (step.input.suffix ?? ''))
383
406
 
384
407
  const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
385
408
  const hasEntVar = priorSteps.some((s: any) =>
@@ -390,20 +413,22 @@ const generateLoad: OpGen = (ctx, step, index) => {
390
413
  const hasSrcData = (!flowHasCreate && srcdatavar === (preambleRef + '_data')) ||
391
414
  priorSteps.some((s: any) => {
392
415
  if ('create' === s.op) {
393
- const priorRef = s.input?.ref ?? entity.name + '_ref01'
394
- const priorDatvar = s.input?.datavar ?? (priorRef + '_data' + (s.input?.suffix ?? ''))
416
+ const priorRef = s.input.ref ?? entity.name + '_ref01'
417
+ const priorDatvar = s.input.datavar ?? (priorRef + '_data' + (s.input.suffix ?? ''))
395
418
  return priorDatvar === srcdatavar
396
419
  }
397
420
  return false
398
421
  })
399
422
 
423
+ const hasEntId = null != entity.id
424
+
400
425
  Content(` # LOAD
401
426
  `)
402
427
  if (!hasEntVar) {
403
428
  Content(` ${entvar} = client.${entity.Name}(nil)
404
429
  `)
405
430
  }
406
- if (!hasSrcData) {
431
+ if (!hasSrcData && hasEntId) {
407
432
  Content(` ${srcdatavar}_raw = Vs.items(Helpers.to_map(
408
433
  Vs.getpath(setup[:data], "existing.${entity.name}")))
409
434
  ${srcdatavar} = nil
@@ -412,7 +437,8 @@ const generateLoad: OpGen = (ctx, step, index) => {
412
437
  end
413
438
  `)
414
439
  }
415
- Content(` ${matchvar} = {
440
+ if (hasEntId) {
441
+ Content(` ${matchvar} = {
416
442
  "id" => ${srcdatavar}["id"],
417
443
  }
418
444
  ${datavar}_loaded, err = ${entvar}.load(${matchvar}, nil)
@@ -421,32 +447,50 @@ const generateLoad: OpGen = (ctx, step, index) => {
421
447
  assert !${datavar}_load_result.nil?
422
448
  assert_equal ${datavar}_load_result["id"], ${srcdatavar}["id"]
423
449
  `)
450
+ }
451
+ else {
452
+ Content(` ${matchvar} = {}
453
+ ${datavar}_loaded, err = ${entvar}.load(${matchvar}, nil)
454
+ assert_nil err
455
+ assert !${datavar}_loaded.nil?
456
+ `)
457
+ }
424
458
  }
425
459
 
426
460
 
427
461
  const generateRemove: OpGen = (ctx, step, index) => {
428
462
  const { entity, flow } = ctx
429
- const ref = step.input?.ref ?? entity.name + '_ref01'
430
- const entvar = step.input?.entvar ?? ref + '_ent'
431
- const matchvar = step.input?.matchvar ?? (ref + '_match' + (step.input?.suffix ?? ''))
432
- const srcdatavar = step.input?.srcdatavar ?? (ref + '_data')
463
+ const ref = step.input.ref ?? entity.name + '_ref01'
464
+ const entvar = step.input.entvar ?? ref + '_ent'
465
+ const matchvar = step.input.matchvar ?? (ref + '_match' + (step.input.suffix ?? ''))
466
+ const srcdatavar = step.input.srcdatavar ?? (ref + '_data')
433
467
 
434
468
  const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
435
469
  const needsEnt = !priorSteps.some((s: any) =>
436
470
  ['create', 'list', 'load', 'update', 'remove'].includes(s.op))
437
471
 
472
+ const hasEntIdR = null != entity.id
473
+
438
474
  Content(` # REMOVE
439
475
  `)
440
476
  if (needsEnt) {
441
477
  Content(` ${entvar} = client.${entity.Name}(nil)
442
478
  `)
443
479
  }
444
- Content(` ${matchvar} = {
480
+ if (hasEntIdR) {
481
+ Content(` ${matchvar} = {
445
482
  "id" => ${srcdatavar}["id"],
446
483
  }
447
484
  _, err = ${entvar}.remove(${matchvar}, nil)
448
485
  assert_nil err
449
486
  `)
487
+ }
488
+ else {
489
+ Content(` ${matchvar} = {}
490
+ _, err = ${entvar}.remove(${matchvar}, nil)
491
+ assert_nil err
492
+ `)
493
+ }
450
494
  }
451
495
 
452
496
 
@@ -10,6 +10,7 @@ import {
10
10
  cmp,
11
11
  each,
12
12
  indent,
13
+ isAuthActive,
13
14
  } from '@voxgig/sdkgen'
14
15
 
15
16
 
@@ -40,6 +41,21 @@ const Config = cmp(async function Config(props: any) {
40
41
 
41
42
  const headers = getModelPath(model, `main.${KIT}.config.headers`) || {}
42
43
 
44
+ const authActive = isAuthActive(model)
45
+ let authPrefix = 'Bearer'
46
+ try {
47
+ const v = getModelPath(model, `main.${KIT}.config.auth.prefix`,
48
+ { only_active: false, required: false })
49
+ if (null != v) authPrefix = v
50
+ } catch (_e) { /* ignore */ }
51
+ const authBlock = authActive
52
+ ? `auth: {
53
+ prefix: '${authPrefix}',
54
+ },
55
+
56
+ `
57
+ : ''
58
+
43
59
  File({ name: 'Config.' + target.ext }, () => {
44
60
 
45
61
  Fragment({
@@ -47,6 +63,8 @@ const Config = cmp(async function Config(props: any) {
47
63
 
48
64
  replace: {
49
65
 
66
+ "'AUTHBLOCK'": authBlock,
67
+
50
68
  "'HEADERS'": indent(JSON.stringify(headers, null, 2), 4).trim(),
51
69
 
52
70
  '// #ImportFeatures': () => each(feature, (f: any) => {
@@ -0,0 +1,37 @@
1
+
2
+ import {
3
+ Content,
4
+ File,
5
+ cmp,
6
+ } from '@voxgig/sdkgen'
7
+
8
+
9
+ const Gitignore = cmp(async function Gitignore(_props: any) {
10
+ File({ name: '.gitignore' }, () => {
11
+ Content(`# Dependencies
12
+ node_modules/
13
+
14
+ # Build output
15
+ dist/
16
+ dist-test/
17
+ *.tsbuildinfo
18
+
19
+ # Coverage
20
+ coverage/
21
+
22
+ # Logs
23
+ *.log
24
+ npm-debug.log*
25
+
26
+ # IDE / OS
27
+ .idea/
28
+ .vscode/
29
+ .DS_Store
30
+ `)
31
+ })
32
+ })
33
+
34
+
35
+ export {
36
+ Gitignore
37
+ }
@@ -20,6 +20,7 @@ import {
20
20
 
21
21
  import { Package } from './Package_ts'
22
22
  import { Config } from './Config_ts'
23
+ import { Gitignore } from './Gitignore_ts'
23
24
  import { MainEntity } from './MainEntity_ts'
24
25
  import { EntityBase } from './EntityBase_ts'
25
26
  import { SdkError } from './SdkError_ts'
@@ -36,6 +37,8 @@ const Main = cmp(async function Main(props: any) {
36
37
 
37
38
  Package({ target })
38
39
 
40
+ Gitignore({})
41
+
39
42
  Copy({
40
43
  from: 'tm/' + target.name,
41
44
  replace: {
@@ -0,0 +1,138 @@
1
+
2
+ import { cmp, each, Content } from '@voxgig/sdkgen'
3
+
4
+ import {
5
+ KIT,
6
+ getModelPath,
7
+ } from '@voxgig/apidef'
8
+
9
+
10
+ // Operation method spelling differs between Go and other languages — Go
11
+ // uses PascalCase methods with explicit ctrl arg, others use lowercase
12
+ // methods with optional ctrl. The op descriptions are language-agnostic.
13
+ const OP_DESC: Record<string, { method: string, desc: string }> = {
14
+ load: { method: 'load(match)', desc: 'Load a single entity by match criteria.' },
15
+ list: { method: 'list(match)', desc: 'List entities matching the criteria.' },
16
+ create: { method: 'create(data)', desc: 'Create a new entity with the given data.' },
17
+ update: { method: 'update(data)', desc: 'Update an existing entity.' },
18
+ remove: { method: 'remove(match)', desc: 'Remove the matching entity.' },
19
+ }
20
+
21
+
22
+ const ReadmeEntity = cmp(function ReadmeEntity(props: any) {
23
+ const { target } = props
24
+ const { model } = props.ctx$
25
+
26
+ const entity = getModelPath(model, `main.${KIT}.entity`)
27
+
28
+ const publishedEntities = each(entity)
29
+ .filter((entity: any) => entity.active !== false)
30
+
31
+ if (0 === publishedEntities.length) {
32
+ return
33
+ }
34
+
35
+ Content(`
36
+
37
+ ## Entities
38
+
39
+ `)
40
+
41
+ publishedEntities.map((entity: any) => {
42
+ const opnames = Object.keys(entity.op || {})
43
+ const fields = entity.fields || []
44
+
45
+ Content(`
46
+ ### ${entity.Name}
47
+
48
+ `)
49
+
50
+ if (entity.short) {
51
+ Content(`${entity.short}
52
+
53
+ `)
54
+ }
55
+
56
+ Content(`Create an instance: \`const ${entity.name} = client.${entity.Name}()\`
57
+
58
+ `)
59
+
60
+ if (opnames.length > 0) {
61
+ Content(`#### Operations
62
+
63
+ | Method | Description |
64
+ | --- | --- |
65
+ `)
66
+ opnames.map((opname: string) => {
67
+ const info = OP_DESC[opname]
68
+ if (info) {
69
+ Content(`| \`${info.method}\` | ${info.desc} |
70
+ `)
71
+ }
72
+ })
73
+
74
+ Content(`
75
+ `)
76
+ }
77
+
78
+ if (fields.length > 0) {
79
+ Content(`#### Fields
80
+
81
+ | Field | Type | Description |
82
+ | --- | --- | --- |
83
+ `)
84
+
85
+ each(fields, (field: any) => {
86
+ const desc = field.short || ''
87
+ Content(`| \`${field.name}\` | \`${field.type || 'any'}\` | ${desc} |
88
+ `)
89
+ })
90
+
91
+ Content(`
92
+ `)
93
+ }
94
+
95
+ if (opnames.includes('load')) {
96
+ Content(`#### Example: Load
97
+
98
+ \`\`\`ts
99
+ const ${entity.name} = await client.${entity.Name}().load({ id: '${entity.name}_id' })
100
+ \`\`\`
101
+
102
+ `)
103
+ }
104
+
105
+ if (opnames.includes('list')) {
106
+ Content(`#### Example: List
107
+
108
+ \`\`\`ts
109
+ const ${entity.name}s = await client.${entity.Name}().list()
110
+ \`\`\`
111
+
112
+ `)
113
+ }
114
+
115
+ if (opnames.includes('create')) {
116
+ Content(`#### Example: Create
117
+
118
+ \`\`\`ts
119
+ const ${entity.name} = await client.${entity.Name}().create({
120
+ `)
121
+ each(fields, (field: any) => {
122
+ if ('id' !== field.name && field.req) {
123
+ Content(` ${field.name}: /* ${field.type || 'value'} */,
124
+ `)
125
+ }
126
+ })
127
+ Content(`})
128
+ \`\`\`
129
+
130
+ `)
131
+ }
132
+ })
133
+ })
134
+
135
+
136
+ export {
137
+ ReadmeEntity
138
+ }
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, Content } from '@voxgig/sdkgen'
2
+ import { cmp, Content, isAuthActive } from '@voxgig/sdkgen'
3
3
 
4
4
  import {
5
5
  KIT,
@@ -10,6 +10,13 @@ import {
10
10
  const ReadmeHowto = cmp(function ReadmeHowto(props: any) {
11
11
  const { target, ctx$: { model } } = props
12
12
 
13
+ const authActive = isAuthActive(model)
14
+ const apikeyTesterCtor = authActive
15
+ ? `new ${model.const.Name}SDK({ apikey: '...' })`
16
+ : `new ${model.const.Name}SDK()`
17
+ const apikeyExtendField = authActive ? `\n apikey: '...',` : ''
18
+ const apikeyEnvLine = authActive ? `\n${model.NAME}_APIKEY=<your-key>` : ''
19
+
13
20
  Content(`### Make a direct HTTP request
14
21
 
15
22
  For endpoints not covered by entity methods:
@@ -57,7 +64,7 @@ const result = await client.Planet().load({ id: 'test01' })
57
64
  You can also use the instance method:
58
65
 
59
66
  \`\`\`ts
60
- const client = new ${model.const.Name}SDK({ apikey: '...' })
67
+ const client = ${apikeyTesterCtor}
61
68
  const testClient = client.tester()
62
69
  \`\`\`
63
70
 
@@ -92,8 +99,7 @@ const logger = {
92
99
  },
93
100
  }
94
101
 
95
- const client = new ${model.const.Name}SDK({
96
- apikey: '...',
102
+ const client = new ${model.const.Name}SDK({${apikeyExtendField}
97
103
  extend: [logger],
98
104
  })
99
105
  \`\`\`
@@ -103,8 +109,7 @@ const client = new ${model.const.Name}SDK({
103
109
  Create a \`.env.local\` file at the project root:
104
110
 
105
111
  \`\`\`
106
- ${model.NAME}_TEST_LIVE=TRUE
107
- ${model.NAME}_APIKEY=<your-key>
112
+ ${model.NAME}_TEST_LIVE=TRUE${apikeyEnvLine}
108
113
  \`\`\`
109
114
 
110
115
  Then run:
@@ -0,0 +1,18 @@
1
+
2
+ import { cmp, Content } from '@voxgig/sdkgen'
3
+
4
+
5
+ const ReadmeIntro = cmp(function ReadmeIntro(props: any) {
6
+ const { target, ctx$: { model } } = props
7
+
8
+ Content(`# ${model.Name} ${target.title} SDK
9
+
10
+ The ${target.title} SDK for the ${model.Name} API. Provides a type-safe, entity-oriented interface with full async/await support.
11
+
12
+ `)
13
+ })
14
+
15
+
16
+ export {
17
+ ReadmeIntro
18
+ }
@@ -1,5 +1,5 @@
1
1
 
2
- import { cmp, each, Content } from '@voxgig/sdkgen'
2
+ import { cmp, each, Content, isAuthActive } from '@voxgig/sdkgen'
3
3
 
4
4
  import {
5
5
  KIT,
@@ -13,13 +13,18 @@ const ReadmeModel = cmp(function ReadmeModel(props: any) {
13
13
  const entity = getModelPath(model, `main.${KIT}.entity`)
14
14
  const entityList = each(entity).filter((e: any) => e.active !== false)
15
15
 
16
+ const authActive = isAuthActive(model)
17
+ const apikeyOptionType = authActive ? `\n apikey?: string` : ''
18
+ const apikeyOptionRow = authActive
19
+ ? '| `apikey` | `string` | API key for authentication. |\n'
20
+ : ''
21
+
16
22
  Content(`### ${model.const.Name}SDK
17
23
 
18
24
  #### Constructor
19
25
 
20
26
  \`\`\`ts
21
- new ${model.const.Name}SDK(options?: {
22
- apikey?: string
27
+ new ${model.const.Name}SDK(options?: {${apikeyOptionType}
23
28
  base?: string
24
29
  prefix?: string
25
30
  suffix?: string
@@ -30,8 +35,7 @@ new ${model.const.Name}SDK(options?: {
30
35
 
31
36
  | Option | Type | Description |
32
37
  | --- | --- | --- |
33
- | \`apikey\` | \`string\` | API key for authentication. |
34
- | \`base\` | \`string\` | Base URL of the API server. |
38
+ ${apikeyOptionRow}| \`base\` | \`string\` | Base URL of the API server. |
35
39
  | \`prefix\` | \`string\` | URL path prefix prepended to all requests. |
36
40
  | \`suffix\` | \`string\` | URL path suffix appended to all requests. |
37
41
  | \`feature\` | \`object\` | Feature activation flags (e.g. \`{ test: { active: true } }\`). |