@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(', ')
@@ -150,8 +164,7 @@ end)
150
164
  Content(` local env = runner.env_override({
151
165
  ["${PROJUPPER}_TEST_${entity.name.toUpperCase().replace(/[^A-Z_]/g, '_')}_ENTID"] = idmap,
152
166
  ["${PROJUPPER}_TEST_LIVE"] = "FALSE",
153
- ["${PROJUPPER}_TEST_EXPLAIN"] = "FALSE",
154
- ["${PROJUPPER}_APIKEY"] = "NONE",
167
+ ["${PROJUPPER}_TEST_EXPLAIN"] = "FALSE",${apikeyEnvEntry}
155
168
  })
156
169
 
157
170
  local idmap_resolved = helpers.to_map(
@@ -172,8 +185,7 @@ end)
172
185
  Content(`
173
186
  if env["${PROJUPPER}_TEST_LIVE"] == "TRUE" then
174
187
  local merged_opts = vs.merge({
175
- {
176
- apikey = env["${PROJUPPER}_APIKEY"],
188
+ {${apikeyLiveField}
177
189
  },
178
190
  extra or {},
179
191
  })
@@ -196,9 +208,9 @@ end
196
208
 
197
209
  const generateCreate: OpGen = (ctx, step, index) => {
198
210
  const { entity, flow } = ctx
199
- const ref = step.input?.ref ?? entity.name + '_ref01'
200
- const entvar = step.input?.entvar ?? ref + '_ent'
201
- const datavar = step.input?.datavar ?? (ref + '_data' + (step.input?.suffix ?? ''))
211
+ const ref = step.input.ref ?? entity.name + '_ref01'
212
+ const entvar = step.input.entvar ?? ref + '_ent'
213
+ const datavar = step.input.datavar ?? (ref + '_data' + (step.input.suffix ?? ''))
202
214
 
203
215
  const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
204
216
  const needsEnt = !priorSteps.some((s: any) =>
@@ -206,8 +218,8 @@ const generateCreate: OpGen = (ctx, step, index) => {
206
218
 
207
219
  const hasDatvar = priorSteps.some((s: any) => {
208
220
  if ('create' === s.op) {
209
- const priorRef = s.input?.ref ?? entity.name + '_ref01'
210
- const priorDatvar = s.input?.datavar ?? (priorRef + '_data' + (s.input?.suffix ?? ''))
221
+ const priorRef = s.input.ref ?? entity.name + '_ref01'
222
+ const priorDatvar = s.input.datavar ?? (priorRef + '_data' + (s.input.suffix ?? ''))
211
223
  return priorDatvar === datavar
212
224
  }
213
225
  return false
@@ -241,17 +253,20 @@ const generateCreate: OpGen = (ctx, step, index) => {
241
253
  assert.is_nil(err)
242
254
  ${datavar} = helpers.to_map(${datavar}_result)
243
255
  assert.is_not_nil(${datavar})
244
- assert.is_not_nil(${datavar}["id"])
245
256
  `)
257
+ if (null != ctx.entity.id) {
258
+ Content(` assert.is_not_nil(${datavar}["id"])
259
+ `)
260
+ }
246
261
  }
247
262
 
248
263
 
249
264
  const generateList: OpGen = (ctx, step, index) => {
250
265
  const { entity, flow } = ctx
251
- const ref = step.input?.ref ?? entity.name + '_ref01'
252
- const entvar = step.input?.entvar ?? ref + '_ent'
253
- const matchvar = step.input?.matchvar ?? (ref + '_match' + (step.input?.suffix ?? ''))
254
- const listvar = step.input?.listvar ?? (ref + '_list' + (step.input?.suffix ?? ''))
266
+ const ref = step.input.ref ?? entity.name + '_ref01'
267
+ const entvar = step.input.entvar ?? ref + '_ent'
268
+ const matchvar = step.input.matchvar ?? (ref + '_match' + (step.input.suffix ?? ''))
269
+ const listvar = step.input.listvar ?? (ref + '_list' + (step.input.suffix ?? ''))
255
270
 
256
271
  const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
257
272
  const needsEnt = !priorSteps.some((s: any) =>
@@ -291,7 +306,7 @@ const generateList: OpGen = (ctx, step, index) => {
291
306
  for (const validator of step.valid) {
292
307
  const validRef = validator.def?.ref
293
308
  const hasRefData = validRef && allSteps.some((s: any) => 'create' === s.op &&
294
- ((s.input?.ref ?? entity.name + '_ref01') === validRef))
309
+ ((s.input.ref ?? entity.name + '_ref01') === validRef))
295
310
 
296
311
  if ('ItemExists' === validator.apply && hasRefData) {
297
312
  const refDataVar = validRef + '_data'
@@ -317,17 +332,19 @@ const generateList: OpGen = (ctx, step, index) => {
317
332
 
318
333
  const generateUpdate: OpGen = (ctx, step, index) => {
319
334
  const { entity, flow } = ctx
320
- const ref = step.input?.ref ?? entity.name + '_ref01'
321
- const entvar = step.input?.entvar ?? ref + '_ent'
322
- const datavar = step.input?.datavar ?? (ref + '_data' + (step.input?.suffix ?? ''))
323
- const resdatavar = step.input?.resdatavar ?? (ref + '_resdata' + (step.input?.suffix ?? ''))
324
- const markdefvar = step.input?.markdefvar ?? (ref + '_markdef' + (step.input?.suffix ?? ''))
325
- const srcdatavar = step.input?.srcdatavar ?? (ref + '_data' + (step.input?.suffix ?? ''))
335
+ const ref = step.input.ref ?? entity.name + '_ref01'
336
+ const entvar = step.input.entvar ?? ref + '_ent'
337
+ const datavar = step.input.datavar ?? (ref + '_data' + (step.input.suffix ?? ''))
338
+ const resdatavar = step.input.resdatavar ?? (ref + '_resdata' + (step.input.suffix ?? ''))
339
+ const markdefvar = step.input.markdefvar ?? (ref + '_markdef' + (step.input.suffix ?? ''))
340
+ const srcdatavar = step.input.srcdatavar ?? (ref + '_data' + (step.input.suffix ?? ''))
326
341
 
327
342
  const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
328
343
  const needsEnt = !priorSteps.some((s: any) =>
329
344
  ['create', 'list', 'load', 'update', 'remove'].includes(s.op))
330
345
 
346
+ const hasEntIdU = null != entity.id
347
+
331
348
  Content(` -- UPDATE
332
349
  `)
333
350
  if (needsEnt) {
@@ -335,8 +352,11 @@ const generateUpdate: OpGen = (ctx, step, index) => {
335
352
  `)
336
353
  }
337
354
  Content(` local ${datavar}_up = {
338
- id = ${srcdatavar}["id"],
339
355
  `)
356
+ if (hasEntIdU) {
357
+ Content(` id = ${srcdatavar}["id"],
358
+ `)
359
+ }
340
360
 
341
361
  if (step.data) {
342
362
  const dataEntries = Object.entries(step.data).filter(([k]: any) => k !== 'id' && !k.endsWith('$'))
@@ -351,7 +371,7 @@ const generateUpdate: OpGen = (ctx, step, index) => {
351
371
 
352
372
  if (step.spec) {
353
373
  for (const spec of step.spec) {
354
- if ('TextFieldMark' === spec.apply && null != step.input?.textfield) {
374
+ if ('TextFieldMark' === spec.apply && null != step.input.textfield) {
355
375
  const fieldname = step.input.textfield
356
376
  const fieldvalue = spec.def?.mark ?? `Mark01-${ref}`
357
377
  Content(`
@@ -368,12 +388,15 @@ const generateUpdate: OpGen = (ctx, step, index) => {
368
388
  assert.is_nil(err)
369
389
  local ${resdatavar} = helpers.to_map(${resdatavar}_result)
370
390
  assert.is_not_nil(${resdatavar})
371
- assert.are.equal(${resdatavar}["id"], ${datavar}_up["id"])
372
391
  `)
392
+ if (hasEntIdU) {
393
+ Content(` assert.are.equal(${resdatavar}["id"], ${datavar}_up["id"])
394
+ `)
395
+ }
373
396
 
374
397
  if (step.spec) {
375
398
  for (const spec of step.spec) {
376
- if ('TextFieldMark' === spec.apply && null != step.input?.textfield) {
399
+ if ('TextFieldMark' === spec.apply && null != step.input.textfield) {
377
400
  Content(` assert.are.equal(${resdatavar}[${markdefvar}_name], ${markdefvar}_value)
378
401
  `)
379
402
  }
@@ -384,11 +407,11 @@ const generateUpdate: OpGen = (ctx, step, index) => {
384
407
 
385
408
  const generateLoad: OpGen = (ctx, step, index) => {
386
409
  const { entity, flow } = ctx
387
- const ref = step.input?.ref ?? entity.name + '_ref01'
388
- const entvar = step.input?.entvar ?? ref + '_ent'
389
- const matchvar = step.input?.matchvar ?? (ref + '_match' + (step.input?.suffix ?? ''))
390
- const datavar = step.input?.datavar ?? (ref + '_data' + (step.input?.suffix ?? ''))
391
- const srcdatavar = step.input?.srcdatavar ?? (ref + '_data' + (step.input?.suffix ?? ''))
410
+ const ref = step.input.ref ?? entity.name + '_ref01'
411
+ const entvar = step.input.entvar ?? ref + '_ent'
412
+ const matchvar = step.input.matchvar ?? (ref + '_match' + (step.input.suffix ?? ''))
413
+ const datavar = step.input.datavar ?? (ref + '_data' + (step.input.suffix ?? ''))
414
+ const srcdatavar = step.input.srcdatavar ?? (ref + '_data' + (step.input.suffix ?? ''))
392
415
 
393
416
  const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
394
417
  const hasEntVar = priorSteps.some((s: any) =>
@@ -399,20 +422,22 @@ const generateLoad: OpGen = (ctx, step, index) => {
399
422
  const hasSrcData = (!flowHasCreate && srcdatavar === (preambleRef + '_data')) ||
400
423
  priorSteps.some((s: any) => {
401
424
  if ('create' === s.op) {
402
- const priorRef = s.input?.ref ?? entity.name + '_ref01'
403
- const priorDatvar = s.input?.datavar ?? (priorRef + '_data' + (s.input?.suffix ?? ''))
425
+ const priorRef = s.input.ref ?? entity.name + '_ref01'
426
+ const priorDatvar = s.input.datavar ?? (priorRef + '_data' + (s.input.suffix ?? ''))
404
427
  return priorDatvar === srcdatavar
405
428
  }
406
429
  return false
407
430
  })
408
431
 
432
+ const hasEntId = null != entity.id
433
+
409
434
  Content(` -- LOAD
410
435
  `)
411
436
  if (!hasEntVar) {
412
437
  Content(` local ${entvar} = client:${entity.Name}(nil)
413
438
  `)
414
439
  }
415
- if (!hasSrcData) {
440
+ if (!hasSrcData && hasEntId) {
416
441
  Content(` local ${srcdatavar}_raw = vs.items(helpers.to_map(
417
442
  vs.getpath(setup.data, "existing.${entity.name}")))
418
443
  local ${srcdatavar} = nil
@@ -421,7 +446,8 @@ const generateLoad: OpGen = (ctx, step, index) => {
421
446
  end
422
447
  `)
423
448
  }
424
- Content(` local ${matchvar} = {
449
+ if (hasEntId) {
450
+ Content(` local ${matchvar} = {
425
451
  id = ${srcdatavar}["id"],
426
452
  }
427
453
  local ${datavar}_loaded, err = ${entvar}:load(${matchvar}, nil)
@@ -430,32 +456,50 @@ const generateLoad: OpGen = (ctx, step, index) => {
430
456
  assert.is_not_nil(${datavar}_load_result)
431
457
  assert.are.equal(${datavar}_load_result["id"], ${srcdatavar}["id"])
432
458
  `)
459
+ }
460
+ else {
461
+ Content(` local ${matchvar} = {}
462
+ local ${datavar}_loaded, err = ${entvar}:load(${matchvar}, nil)
463
+ assert.is_nil(err)
464
+ assert.is_not_nil(${datavar}_loaded)
465
+ `)
466
+ }
433
467
  }
434
468
 
435
469
 
436
470
  const generateRemove: OpGen = (ctx, step, index) => {
437
471
  const { entity, flow } = ctx
438
- const ref = step.input?.ref ?? entity.name + '_ref01'
439
- const entvar = step.input?.entvar ?? ref + '_ent'
440
- const matchvar = step.input?.matchvar ?? (ref + '_match' + (step.input?.suffix ?? ''))
441
- const srcdatavar = step.input?.srcdatavar ?? (ref + '_data')
472
+ const ref = step.input.ref ?? entity.name + '_ref01'
473
+ const entvar = step.input.entvar ?? ref + '_ent'
474
+ const matchvar = step.input.matchvar ?? (ref + '_match' + (step.input.suffix ?? ''))
475
+ const srcdatavar = step.input.srcdatavar ?? (ref + '_data')
442
476
 
443
477
  const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
444
478
  const needsEnt = !priorSteps.some((s: any) =>
445
479
  ['create', 'list', 'load', 'update', 'remove'].includes(s.op))
446
480
 
481
+ const hasEntIdR = null != entity.id
482
+
447
483
  Content(` -- REMOVE
448
484
  `)
449
485
  if (needsEnt) {
450
486
  Content(` local ${entvar} = client:${entity.Name}(nil)
451
487
  `)
452
488
  }
453
- Content(` local ${matchvar} = {
489
+ if (hasEntIdR) {
490
+ Content(` local ${matchvar} = {
454
491
  id = ${srcdatavar}["id"],
455
492
  }
456
493
  local _, err = ${entvar}:remove(${matchvar}, nil)
457
494
  assert.is_nil(err)
458
495
  `)
496
+ }
497
+ else {
498
+ Content(` local ${matchvar} = {}
499
+ local _, err = ${entvar}:remove(${matchvar}, nil)
500
+ assert.is_nil(err)
501
+ `)
502
+ }
459
503
  }
460
504
 
461
505
 
@@ -9,6 +9,7 @@ import {
9
9
  Line,
10
10
  cmp,
11
11
  each,
12
+ isAuthActive,
12
13
  } from '@voxgig/sdkgen'
13
14
 
14
15
 
@@ -37,12 +38,19 @@ const Config = cmp(async function Config(props: any) {
37
38
 
38
39
  const headers = getModelPath(model, `main.${KIT}.config.headers`) || {}
39
40
 
41
+ const authActive = isAuthActive(model)
40
42
  let authPrefix = ''
41
43
  try { authPrefix = getModelPath(model, `main.${KIT}.config.auth.prefix`) } catch (_e) { }
42
44
 
43
45
  let baseUrl = ''
44
46
  try { baseUrl = getModelPath(model, `main.${KIT}.info.servers.0.url`) } catch (_e) { }
45
47
 
48
+ const authBlock = authActive
49
+ ? ` "auth" => [
50
+ "prefix" => "${authPrefix}",
51
+ ],\n`
52
+ : ''
53
+
46
54
  File({ name: 'config.' + target.ext }, () => {
47
55
 
48
56
  Content(`<?php
@@ -75,10 +83,7 @@ class ${model.const.Name}Config
75
83
  Content(` ],
76
84
  "options" => [
77
85
  "base" => "${baseUrl}",
78
- "auth" => [
79
- "prefix" => "${authPrefix}",
80
- ],
81
- "headers" => ${formatPhpArray(headers, 4)},
86
+ ${authBlock} "headers" => ${formatPhpArray(headers, 4)},
82
87
  "entity" => (object)[],
83
88
  ],
84
89
  "entity" => (object)[],
@@ -88,10 +93,7 @@ class ${model.const.Name}Config
88
93
  Content(` ],
89
94
  "options" => [
90
95
  "base" => "${baseUrl}",
91
- "auth" => [
92
- "prefix" => "${authPrefix}",
93
- ],
94
- "headers" => ${formatPhpArray(headers, 4)},
96
+ ${authBlock} "headers" => ${formatPhpArray(headers, 4)},
95
97
  "entity" => [
96
98
  `)
97
99
 
@@ -0,0 +1,33 @@
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(`# Composer
12
+ vendor/
13
+ composer.phar
14
+
15
+ # PHPUnit
16
+ .phpunit.cache/
17
+ .phpunit.result.cache
18
+
19
+ # Coverage
20
+ coverage/
21
+
22
+ # IDE / OS
23
+ .idea/
24
+ .vscode/
25
+ .DS_Store
26
+ `)
27
+ })
28
+ })
29
+
30
+
31
+ export {
32
+ Gitignore
33
+ }
@@ -20,6 +20,7 @@ import {
20
20
 
21
21
  import { Package } from './Package_php'
22
22
  import { Config } from './Config_php'
23
+ import { Gitignore } from './Gitignore_php'
23
24
  import { MainEntity } from './MainEntity_php'
24
25
 
25
26
 
@@ -33,6 +34,8 @@ const Main = cmp(async function Main(props: any) {
33
34
 
34
35
  Package({ target })
35
36
 
37
+ Gitignore({})
38
+
36
39
  // Copy tm/php files with replacements
37
40
  Copy({
38
41
  from: 'tm/' + target.name,
@@ -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,10 +1,14 @@
1
1
 
2
- import { cmp, Content } from '@voxgig/sdkgen'
2
+ import { cmp, Content, isAuthActive } from '@voxgig/sdkgen'
3
3
 
4
4
 
5
5
  const ReadmeHowto = cmp(function ReadmeHowto(props: any) {
6
6
  const { target, ctx$: { model } } = props
7
7
 
8
+ const apikeyEnvLine = isAuthActive(model)
9
+ ? `\n${model.NAME}_APIKEY=<your-key>`
10
+ : ''
11
+
8
12
  Content(`### Make a direct HTTP request
9
13
 
10
14
  For endpoints not covered by entity methods:
@@ -81,8 +85,7 @@ $client = new ${model.const.Name}SDK([
81
85
  Create a \`.env.local\` file at the project root:
82
86
 
83
87
  \`\`\`
84
- ${model.NAME}_TEST_LIVE=TRUE
85
- ${model.NAME}_APIKEY=<your-key>
88
+ ${model.NAME}_TEST_LIVE=TRUE${apikeyEnvLine}
86
89
  \`\`\`
87
90
 
88
91
  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 an entity-oriented interface using PHP conventions.
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,6 +13,10 @@ 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 apikeyOptionRow = isAuthActive(model)
17
+ ? '| `apikey` | `string` | API key for authentication. |\n'
18
+ : ''
19
+
16
20
  Content(`### ${model.const.Name}SDK
17
21
 
18
22
  \`\`\`php
@@ -24,8 +28,7 @@ Creates a new SDK client.
24
28
 
25
29
  | Option | Type | Description |
26
30
  | --- | --- | --- |
27
- | \`apikey\` | \`string\` | API key for authentication. |
28
- | \`base\` | \`string\` | Base URL of the API server. |
31
+ ${apikeyOptionRow}| \`base\` | \`string\` | Base URL of the API server. |
29
32
  | \`prefix\` | \`string\` | URL path prefix prepended to all requests. |
30
33
  | \`suffix\` | \`string\` | URL path suffix appended to all requests. |
31
34
  | \`feature\` | \`array\` | Feature activation flags. |
@@ -0,0 +1,58 @@
1
+
2
+ import { cmp, each, Content } from '@voxgig/sdkgen'
3
+
4
+
5
+ const ReadmeOptions = cmp(function ReadmeOptions(props: any) {
6
+ const { target } = props
7
+ const { model } = props.ctx$
8
+
9
+ const publishedOptions = each(target.options).filter((option: any) => option.publish)
10
+ if (0 === publishedOptions.length) {
11
+ return
12
+ }
13
+
14
+ Content(`
15
+
16
+ ## Options
17
+
18
+ Pass options when creating a client instance:
19
+
20
+ `)
21
+
22
+ Content(`\`\`\`php
23
+ $client = new ${model.Name}SDK([
24
+ `)
25
+
26
+ publishedOptions.map((option: any) => {
27
+ if ('apikey' === option.name) {
28
+ Content(` "${option.name}" => getenv("${model.NAME}_APIKEY"),
29
+ `)
30
+ }
31
+ else {
32
+ Content(` // "${option.name}" => ${option.kind === 'string' ? '"..."' : '...'},
33
+ `)
34
+ }
35
+ })
36
+
37
+ Content(`]);
38
+ \`\`\`
39
+
40
+ `)
41
+
42
+ Content(`| Option | Type | Description |
43
+ | --- | --- | --- |
44
+ `)
45
+
46
+ publishedOptions.map((option: any) => {
47
+ Content(`| \`${option.name}\` | \`${option.kind}\` | ${option.short} |
48
+ `)
49
+ })
50
+
51
+ Content(`
52
+ `)
53
+ })
54
+
55
+
56
+ export {
57
+ ReadmeOptions
58
+ }