@voxgig/sdkgen 0.44.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.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/cmp/ReadmeEntity.js +9 -153
- package/dist/cmp/ReadmeEntity.js.map +1 -1
- package/dist/cmp/ReadmeIntro.js +9 -14
- package/dist/cmp/ReadmeIntro.js.map +1 -1
- package/dist/cmp/ReadmeModel.js +6 -4
- package/dist/cmp/ReadmeModel.js.map +1 -1
- package/dist/cmp/ReadmeOptions.js +9 -61
- package/dist/cmp/ReadmeOptions.js.map +1 -1
- package/dist/cmp/ReadmeRef.js +10 -1328
- package/dist/cmp/ReadmeRef.js.map +1 -1
- package/dist/sdkgen.d.ts +2 -2
- package/dist/sdkgen.js +2 -1
- package/dist/sdkgen.js.map +1 -1
- package/dist/utility.d.ts +2 -1
- package/dist/utility.js +9 -0
- package/dist/utility.js.map +1 -1
- package/package.json +1 -1
- package/project/.sdk/src/cmp/go/Config_go.ts +9 -4
- package/project/.sdk/src/cmp/go/ReadmeEntity_go.ts +138 -0
- package/project/.sdk/src/cmp/go/ReadmeHowto_go.ts +6 -3
- package/project/.sdk/src/cmp/go/ReadmeIntro_go.ts +18 -0
- package/project/.sdk/src/cmp/go/ReadmeModel_go.ts +6 -3
- package/project/.sdk/src/cmp/go/ReadmeOptions_go.ts +58 -0
- package/project/.sdk/src/cmp/go/ReadmeQuick_go.ts +11 -7
- package/project/.sdk/src/cmp/go/ReadmeRef_go.ts +354 -0
- package/project/.sdk/src/cmp/go/ReadmeTopQuick_go.ts +6 -4
- package/project/.sdk/src/cmp/go/TestDirect_go.ts +18 -8
- package/project/.sdk/src/cmp/go/TestEntity_go.ts +105 -54
- package/project/.sdk/src/cmp/js/Config_js.ts +18 -0
- package/project/.sdk/src/cmp/js/ReadmeEntity_js.ts +138 -0
- package/project/.sdk/src/cmp/js/ReadmeHowto_js.ts +11 -6
- package/project/.sdk/src/cmp/js/ReadmeIntro_js.ts +18 -0
- package/project/.sdk/src/cmp/js/ReadmeModel_js.ts +6 -3
- package/project/.sdk/src/cmp/js/ReadmeOptions_js.ts +58 -0
- package/project/.sdk/src/cmp/js/ReadmeQuick_js.ts +6 -4
- package/project/.sdk/src/cmp/js/ReadmeRef_js.ts +384 -0
- package/project/.sdk/src/cmp/js/ReadmeTopQuick_js.ts +6 -4
- package/project/.sdk/src/cmp/js/TestDirect_js.ts +23 -12
- package/project/.sdk/src/cmp/js/TestEntity_js.ts +107 -74
- package/project/.sdk/src/cmp/js/fragment/Config.fragment.js +1 -5
- package/project/.sdk/src/cmp/lua/Config_lua.ts +9 -4
- package/project/.sdk/src/cmp/lua/ReadmeEntity_lua.ts +138 -0
- package/project/.sdk/src/cmp/lua/ReadmeHowto_lua.ts +6 -3
- package/project/.sdk/src/cmp/lua/ReadmeIntro_lua.ts +18 -0
- package/project/.sdk/src/cmp/lua/ReadmeModel_lua.ts +6 -3
- package/project/.sdk/src/cmp/lua/ReadmeOptions_lua.ts +58 -0
- package/project/.sdk/src/cmp/lua/ReadmeQuick_lua.ts +6 -4
- package/project/.sdk/src/cmp/lua/ReadmeRef_lua.ts +360 -0
- package/project/.sdk/src/cmp/lua/ReadmeTopQuick_lua.ts +6 -4
- package/project/.sdk/src/cmp/lua/TestDirect_lua.ts +18 -8
- package/project/.sdk/src/cmp/lua/TestEntity_lua.ts +95 -51
- package/project/.sdk/src/cmp/php/Config_php.ts +10 -8
- package/project/.sdk/src/cmp/php/ReadmeEntity_php.ts +138 -0
- package/project/.sdk/src/cmp/php/ReadmeHowto_php.ts +6 -3
- package/project/.sdk/src/cmp/php/ReadmeIntro_php.ts +18 -0
- package/project/.sdk/src/cmp/php/ReadmeModel_php.ts +6 -3
- package/project/.sdk/src/cmp/php/ReadmeOptions_php.ts +58 -0
- package/project/.sdk/src/cmp/php/ReadmeQuick_php.ts +6 -4
- package/project/.sdk/src/cmp/php/ReadmeRef_php.ts +358 -0
- package/project/.sdk/src/cmp/php/ReadmeTopQuick_php.ts +6 -4
- package/project/.sdk/src/cmp/php/TestDirect_php.ts +18 -8
- package/project/.sdk/src/cmp/php/TestEntity_php.ts +101 -54
- package/project/.sdk/src/cmp/py/Config_py.ts +9 -4
- package/project/.sdk/src/cmp/py/ReadmeEntity_py.ts +138 -0
- package/project/.sdk/src/cmp/py/ReadmeHowto_py.ts +6 -3
- package/project/.sdk/src/cmp/py/ReadmeIntro_py.ts +18 -0
- package/project/.sdk/src/cmp/py/ReadmeModel_py.ts +6 -3
- package/project/.sdk/src/cmp/py/ReadmeOptions_py.ts +58 -0
- package/project/.sdk/src/cmp/py/ReadmeQuick_py.ts +9 -6
- package/project/.sdk/src/cmp/py/ReadmeRef_py.ts +356 -0
- package/project/.sdk/src/cmp/py/ReadmeTopQuick_py.ts +9 -6
- package/project/.sdk/src/cmp/py/TestDirect_py.ts +18 -8
- package/project/.sdk/src/cmp/py/TestEntity_py.ts +100 -50
- package/project/.sdk/src/cmp/rb/Config_rb.ts +9 -4
- package/project/.sdk/src/cmp/rb/ReadmeEntity_rb.ts +138 -0
- package/project/.sdk/src/cmp/rb/ReadmeHowto_rb.ts +6 -3
- package/project/.sdk/src/cmp/rb/ReadmeIntro_rb.ts +18 -0
- package/project/.sdk/src/cmp/rb/ReadmeModel_rb.ts +6 -3
- package/project/.sdk/src/cmp/rb/ReadmeOptions_rb.ts +58 -0
- package/project/.sdk/src/cmp/rb/ReadmeQuick_rb.ts +6 -4
- package/project/.sdk/src/cmp/rb/ReadmeRef_rb.ts +361 -0
- package/project/.sdk/src/cmp/rb/ReadmeTopQuick_rb.ts +6 -4
- package/project/.sdk/src/cmp/rb/TestDirect_rb.ts +18 -8
- package/project/.sdk/src/cmp/rb/TestEntity_rb.ts +95 -51
- package/project/.sdk/src/cmp/ts/Config_ts.ts +18 -0
- package/project/.sdk/src/cmp/ts/ReadmeEntity_ts.ts +138 -0
- package/project/.sdk/src/cmp/ts/ReadmeHowto_ts.ts +11 -6
- package/project/.sdk/src/cmp/ts/ReadmeIntro_ts.ts +18 -0
- package/project/.sdk/src/cmp/ts/ReadmeModel_ts.ts +9 -5
- package/project/.sdk/src/cmp/ts/ReadmeOptions_ts.ts +58 -0
- package/project/.sdk/src/cmp/ts/ReadmeQuick_ts.ts +6 -4
- package/project/.sdk/src/cmp/ts/ReadmeRef_ts.ts +384 -0
- package/project/.sdk/src/cmp/ts/ReadmeTopQuick_ts.ts +6 -4
- package/project/.sdk/src/cmp/ts/TestDirect_ts.ts +68 -20
- package/project/.sdk/src/cmp/ts/TestEntity_ts.ts +109 -74
- package/project/.sdk/src/cmp/ts/fragment/Config.fragment.ts +1 -5
- package/project/.sdk/tm/go/utility/prepare_auth.go +15 -1
- package/project/.sdk/tm/js/src/utility/PrepareAuthUtility.js +7 -1
- package/project/.sdk/tm/lua/utility/prepare_auth.lua +9 -1
- package/project/.sdk/tm/php/utility/PrepareAuth.php +11 -1
- package/project/.sdk/tm/py/utility/prepare_auth.py +10 -1
- package/project/.sdk/tm/rb/utility/prepare_auth.rb +8 -1
- package/project/.sdk/tm/ts/src/utility/MakeUrlUtility.ts +7 -8
- package/project/.sdk/tm/ts/src/utility/PrepareAuthUtility.ts +7 -1
- package/src/cmp/ReadmeEntity.ts +11 -178
- package/src/cmp/ReadmeIntro.ts +11 -25
- package/src/cmp/ReadmeModel.ts +7 -5
- package/src/cmp/ReadmeOptions.ts +12 -74
- package/src/cmp/ReadmeRef.ts +11 -1372
- package/src/sdkgen.ts +2 -1
- package/src/utility.ts +12 -0
- /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,42 +23,54 @@ import {
|
|
|
18
23
|
each,
|
|
19
24
|
buildIdNames,
|
|
20
25
|
getMatchEntries,
|
|
26
|
+
isAuthActive,
|
|
21
27
|
} from '@voxgig/sdkgen'
|
|
22
28
|
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
// PHP's GenCtx mirrors the shared shape (see TestEntity_ts.ts) plus an
|
|
31
|
+
// `accessor` slot used to mangle the entity factory name when it collides
|
|
32
|
+
// with PHP's case-insensitive `test()` static constructor.
|
|
26
33
|
type GenCtx = {
|
|
27
|
-
model:
|
|
28
|
-
entity:
|
|
29
|
-
flow:
|
|
34
|
+
model: Model
|
|
35
|
+
entity: ModelEntity
|
|
36
|
+
flow: ModelEntityFlow
|
|
30
37
|
PROJUPPER: string
|
|
31
38
|
accessor: string
|
|
32
39
|
}
|
|
33
40
|
|
|
41
|
+
type OpGen = (ctx: GenCtx, step: ModelEntityFlowStep, index: number) => void
|
|
42
|
+
|
|
34
43
|
|
|
35
44
|
const TestEntity = cmp(function TestEntity(props: any) {
|
|
36
45
|
const ctx$ = props.ctx$
|
|
37
|
-
const model = ctx$.model
|
|
46
|
+
const model: Model = ctx$.model
|
|
38
47
|
|
|
39
48
|
const target = props.target
|
|
40
|
-
const entity = props.entity
|
|
49
|
+
const entity: ModelEntity = props.entity
|
|
41
50
|
|
|
42
|
-
const basicflow
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
if (!dobasic) {
|
|
51
|
+
const basicflow: ModelEntityFlow | undefined =
|
|
52
|
+
getModelPath(model, `main.${KIT}.flow.Basic${nom(entity, 'Name')}Flow`)
|
|
53
|
+
if (null == basicflow || true !== basicflow.active) {
|
|
46
54
|
return
|
|
47
55
|
}
|
|
48
56
|
|
|
49
57
|
// PHP method names are case-insensitive — an entity literally named 'test'
|
|
50
58
|
// collides with the static `test()` test-mode constructor on the SDK class.
|
|
51
59
|
// Mirror the mangling done in MainEntity_php.ts.
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
const entName = nom(entity, 'Name')
|
|
61
|
+
const accessor = 'test' === entName.toLowerCase()
|
|
62
|
+
? entName + '_'
|
|
63
|
+
: entName
|
|
64
|
+
|
|
65
|
+
const PROJUPPER = nom(model.const, 'Name').toUpperCase().replace(/[^A-Z_]/g, '_')
|
|
55
66
|
|
|
56
|
-
const
|
|
67
|
+
const authActive = isAuthActive(model)
|
|
68
|
+
const apikeyEnvEntry = authActive
|
|
69
|
+
? `\n "${PROJUPPER}_APIKEY" => "NONE",`
|
|
70
|
+
: ''
|
|
71
|
+
const apikeyLiveField = authActive
|
|
72
|
+
? `\n "apikey" => $env["${PROJUPPER}_APIKEY"],`
|
|
73
|
+
: ''
|
|
57
74
|
|
|
58
75
|
const idnames = buildIdNames(entity, basicflow)
|
|
59
76
|
const idnamesStr = idnames.map(n => `"${n}"`).join(', ')
|
|
@@ -152,8 +169,7 @@ class ${entity.Name}EntityTest extends TestCase
|
|
|
152
169
|
Content(` $env = Runner::env_override([
|
|
153
170
|
"${PROJUPPER}_TEST_${entity.name.toUpperCase().replace(/[^A-Z_]/g, '_')}_ENTID" => $idmap,
|
|
154
171
|
"${PROJUPPER}_TEST_LIVE" => "FALSE",
|
|
155
|
-
"${PROJUPPER}_TEST_EXPLAIN" => "FALSE"
|
|
156
|
-
"${PROJUPPER}_APIKEY" => "NONE",
|
|
172
|
+
"${PROJUPPER}_TEST_EXPLAIN" => "FALSE",${apikeyEnvEntry}
|
|
157
173
|
]);
|
|
158
174
|
|
|
159
175
|
$idmap_resolved = Helpers::to_map(
|
|
@@ -174,8 +190,7 @@ class ${entity.Name}EntityTest extends TestCase
|
|
|
174
190
|
Content(`
|
|
175
191
|
if ($env["${PROJUPPER}_TEST_LIVE"] === "TRUE") {
|
|
176
192
|
$merged_opts = Vs::merge([
|
|
177
|
-
[
|
|
178
|
-
"apikey" => $env["${PROJUPPER}_APIKEY"],
|
|
193
|
+
[${apikeyLiveField}
|
|
179
194
|
],
|
|
180
195
|
$extra ?? [],
|
|
181
196
|
]);
|
|
@@ -198,9 +213,9 @@ class ${entity.Name}EntityTest extends TestCase
|
|
|
198
213
|
|
|
199
214
|
const generateCreate: OpGen = (ctx, step, index) => {
|
|
200
215
|
const { entity, flow, accessor } = ctx
|
|
201
|
-
const ref = step.input
|
|
202
|
-
const entvar = step.input
|
|
203
|
-
const datavar = step.input
|
|
216
|
+
const ref = step.input.ref ?? entity.name + '_ref01'
|
|
217
|
+
const entvar = step.input.entvar ?? ref + '_ent'
|
|
218
|
+
const datavar = step.input.datavar ?? (ref + '_data' + (step.input.suffix ?? ''))
|
|
204
219
|
|
|
205
220
|
const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
|
|
206
221
|
const needsEnt = !priorSteps.some((s: any) =>
|
|
@@ -208,8 +223,8 @@ const generateCreate: OpGen = (ctx, step, index) => {
|
|
|
208
223
|
|
|
209
224
|
const hasDatvar = priorSteps.some((s: any) => {
|
|
210
225
|
if ('create' === s.op) {
|
|
211
|
-
const priorRef = s.input
|
|
212
|
-
const priorDatvar = s.input
|
|
226
|
+
const priorRef = s.input.ref ?? entity.name + '_ref01'
|
|
227
|
+
const priorDatvar = s.input.datavar ?? (priorRef + '_data' + (s.input.suffix ?? ''))
|
|
213
228
|
return priorDatvar === datavar
|
|
214
229
|
}
|
|
215
230
|
return false
|
|
@@ -243,17 +258,20 @@ const generateCreate: OpGen = (ctx, step, index) => {
|
|
|
243
258
|
$this->assertNull($err);
|
|
244
259
|
$${datavar} = Helpers::to_map($${datavar}_result);
|
|
245
260
|
$this->assertNotNull($${datavar});
|
|
246
|
-
$this->assertNotNull($${datavar}["id"]);
|
|
247
261
|
`)
|
|
262
|
+
if (null != ctx.entity.id) {
|
|
263
|
+
Content(` $this->assertNotNull($${datavar}["id"]);
|
|
264
|
+
`)
|
|
265
|
+
}
|
|
248
266
|
}
|
|
249
267
|
|
|
250
268
|
|
|
251
269
|
const generateList: OpGen = (ctx, step, index) => {
|
|
252
270
|
const { entity, flow, accessor } = ctx
|
|
253
|
-
const ref = step.input
|
|
254
|
-
const entvar = step.input
|
|
255
|
-
const matchvar = step.input
|
|
256
|
-
const listvar = step.input
|
|
271
|
+
const ref = step.input.ref ?? entity.name + '_ref01'
|
|
272
|
+
const entvar = step.input.entvar ?? ref + '_ent'
|
|
273
|
+
const matchvar = step.input.matchvar ?? (ref + '_match' + (step.input.suffix ?? ''))
|
|
274
|
+
const listvar = step.input.listvar ?? (ref + '_list' + (step.input.suffix ?? ''))
|
|
257
275
|
|
|
258
276
|
const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
|
|
259
277
|
const needsEnt = !priorSteps.some((s: any) =>
|
|
@@ -293,7 +311,7 @@ const generateList: OpGen = (ctx, step, index) => {
|
|
|
293
311
|
for (const validator of step.valid) {
|
|
294
312
|
const validRef = validator.def?.ref
|
|
295
313
|
const hasRefData = validRef && allSteps.some((s: any) => 'create' === s.op &&
|
|
296
|
-
((s.input
|
|
314
|
+
((s.input.ref ?? entity.name + '_ref01') === validRef))
|
|
297
315
|
|
|
298
316
|
if ('ItemExists' === validator.apply && hasRefData) {
|
|
299
317
|
const refDataVar = validRef + '_data'
|
|
@@ -319,17 +337,19 @@ const generateList: OpGen = (ctx, step, index) => {
|
|
|
319
337
|
|
|
320
338
|
const generateUpdate: OpGen = (ctx, step, index) => {
|
|
321
339
|
const { entity, flow, accessor } = ctx
|
|
322
|
-
const ref = step.input
|
|
323
|
-
const entvar = step.input
|
|
324
|
-
const datavar = step.input
|
|
325
|
-
const resdatavar = step.input
|
|
326
|
-
const markdefvar = step.input
|
|
327
|
-
const srcdatavar = step.input
|
|
340
|
+
const ref = step.input.ref ?? entity.name + '_ref01'
|
|
341
|
+
const entvar = step.input.entvar ?? ref + '_ent'
|
|
342
|
+
const datavar = step.input.datavar ?? (ref + '_data' + (step.input.suffix ?? ''))
|
|
343
|
+
const resdatavar = step.input.resdatavar ?? (ref + '_resdata' + (step.input.suffix ?? ''))
|
|
344
|
+
const markdefvar = step.input.markdefvar ?? (ref + '_markdef' + (step.input.suffix ?? ''))
|
|
345
|
+
const srcdatavar = step.input.srcdatavar ?? (ref + '_data' + (step.input.suffix ?? ''))
|
|
328
346
|
|
|
329
347
|
const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
|
|
330
348
|
const needsEnt = !priorSteps.some((s: any) =>
|
|
331
349
|
['create', 'list', 'load', 'update', 'remove'].includes(s.op))
|
|
332
350
|
|
|
351
|
+
const hasEntIdU = null != entity.id
|
|
352
|
+
|
|
333
353
|
Content(` // UPDATE
|
|
334
354
|
`)
|
|
335
355
|
if (needsEnt) {
|
|
@@ -337,8 +357,11 @@ const generateUpdate: OpGen = (ctx, step, index) => {
|
|
|
337
357
|
`)
|
|
338
358
|
}
|
|
339
359
|
Content(` $${datavar}_up = [
|
|
340
|
-
"id" => $${srcdatavar}["id"],
|
|
341
360
|
`)
|
|
361
|
+
if (hasEntIdU) {
|
|
362
|
+
Content(` "id" => $${srcdatavar}["id"],
|
|
363
|
+
`)
|
|
364
|
+
}
|
|
342
365
|
|
|
343
366
|
if (step.data) {
|
|
344
367
|
const dataEntries = Object.entries(step.data).filter(([k]: any) => k !== 'id' && !k.endsWith('$'))
|
|
@@ -353,7 +376,7 @@ const generateUpdate: OpGen = (ctx, step, index) => {
|
|
|
353
376
|
|
|
354
377
|
if (step.spec) {
|
|
355
378
|
for (const spec of step.spec) {
|
|
356
|
-
if ('TextFieldMark' === spec.apply && null != step.input
|
|
379
|
+
if ('TextFieldMark' === spec.apply && null != step.input.textfield) {
|
|
357
380
|
const fieldname = step.input.textfield
|
|
358
381
|
const fieldvalue = spec.def?.mark ?? `Mark01-${ref}`
|
|
359
382
|
Content(`
|
|
@@ -370,12 +393,15 @@ const generateUpdate: OpGen = (ctx, step, index) => {
|
|
|
370
393
|
$this->assertNull($err);
|
|
371
394
|
$${resdatavar} = Helpers::to_map($${resdatavar}_result);
|
|
372
395
|
$this->assertNotNull($${resdatavar});
|
|
373
|
-
$this->assertEquals($${resdatavar}["id"], $${datavar}_up["id"]);
|
|
374
396
|
`)
|
|
397
|
+
if (hasEntIdU) {
|
|
398
|
+
Content(` $this->assertEquals($${resdatavar}["id"], $${datavar}_up["id"]);
|
|
399
|
+
`)
|
|
400
|
+
}
|
|
375
401
|
|
|
376
402
|
if (step.spec) {
|
|
377
403
|
for (const spec of step.spec) {
|
|
378
|
-
if ('TextFieldMark' === spec.apply && null != step.input
|
|
404
|
+
if ('TextFieldMark' === spec.apply && null != step.input.textfield) {
|
|
379
405
|
Content(` $this->assertEquals($${resdatavar}[$${markdefvar}_name], $${markdefvar}_value);
|
|
380
406
|
`)
|
|
381
407
|
}
|
|
@@ -386,11 +412,11 @@ const generateUpdate: OpGen = (ctx, step, index) => {
|
|
|
386
412
|
|
|
387
413
|
const generateLoad: OpGen = (ctx, step, index) => {
|
|
388
414
|
const { entity, flow, accessor } = ctx
|
|
389
|
-
const ref = step.input
|
|
390
|
-
const entvar = step.input
|
|
391
|
-
const matchvar = step.input
|
|
392
|
-
const datavar = step.input
|
|
393
|
-
const srcdatavar = step.input
|
|
415
|
+
const ref = step.input.ref ?? entity.name + '_ref01'
|
|
416
|
+
const entvar = step.input.entvar ?? ref + '_ent'
|
|
417
|
+
const matchvar = step.input.matchvar ?? (ref + '_match' + (step.input.suffix ?? ''))
|
|
418
|
+
const datavar = step.input.datavar ?? (ref + '_data' + (step.input.suffix ?? ''))
|
|
419
|
+
const srcdatavar = step.input.srcdatavar ?? (ref + '_data' + (step.input.suffix ?? ''))
|
|
394
420
|
|
|
395
421
|
const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
|
|
396
422
|
const hasEntVar = priorSteps.some((s: any) =>
|
|
@@ -401,20 +427,22 @@ const generateLoad: OpGen = (ctx, step, index) => {
|
|
|
401
427
|
const hasSrcData = (!flowHasCreate && srcdatavar === (preambleRef + '_data')) ||
|
|
402
428
|
priorSteps.some((s: any) => {
|
|
403
429
|
if ('create' === s.op) {
|
|
404
|
-
const priorRef = s.input
|
|
405
|
-
const priorDatvar = s.input
|
|
430
|
+
const priorRef = s.input.ref ?? entity.name + '_ref01'
|
|
431
|
+
const priorDatvar = s.input.datavar ?? (priorRef + '_data' + (s.input.suffix ?? ''))
|
|
406
432
|
return priorDatvar === srcdatavar
|
|
407
433
|
}
|
|
408
434
|
return false
|
|
409
435
|
})
|
|
410
436
|
|
|
437
|
+
const hasEntId = null != entity.id
|
|
438
|
+
|
|
411
439
|
Content(` // LOAD
|
|
412
440
|
`)
|
|
413
441
|
if (!hasEntVar) {
|
|
414
442
|
Content(` $${entvar} = $client->${accessor}(null);
|
|
415
443
|
`)
|
|
416
444
|
}
|
|
417
|
-
if (!hasSrcData) {
|
|
445
|
+
if (!hasSrcData && hasEntId) {
|
|
418
446
|
Content(` $${srcdatavar}_raw = Vs::items(Helpers::to_map(
|
|
419
447
|
Vs::getpath($setup["data"], "existing.${entity.name}")));
|
|
420
448
|
$${srcdatavar} = null;
|
|
@@ -423,7 +451,8 @@ const generateLoad: OpGen = (ctx, step, index) => {
|
|
|
423
451
|
}
|
|
424
452
|
`)
|
|
425
453
|
}
|
|
426
|
-
|
|
454
|
+
if (hasEntId) {
|
|
455
|
+
Content(` $${matchvar} = [
|
|
427
456
|
"id" => $${srcdatavar}["id"],
|
|
428
457
|
];
|
|
429
458
|
[$${datavar}_loaded, $err] = $${entvar}->load($${matchvar}, null);
|
|
@@ -432,32 +461,50 @@ const generateLoad: OpGen = (ctx, step, index) => {
|
|
|
432
461
|
$this->assertNotNull($${datavar}_load_result);
|
|
433
462
|
$this->assertEquals($${datavar}_load_result["id"], $${srcdatavar}["id"]);
|
|
434
463
|
`)
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
Content(` $${matchvar} = [];
|
|
467
|
+
[$${datavar}_loaded, $err] = $${entvar}->load($${matchvar}, null);
|
|
468
|
+
$this->assertNull($err);
|
|
469
|
+
$this->assertNotNull($${datavar}_loaded);
|
|
470
|
+
`)
|
|
471
|
+
}
|
|
435
472
|
}
|
|
436
473
|
|
|
437
474
|
|
|
438
475
|
const generateRemove: OpGen = (ctx, step, index) => {
|
|
439
476
|
const { entity, flow, accessor } = ctx
|
|
440
|
-
const ref = step.input
|
|
441
|
-
const entvar = step.input
|
|
442
|
-
const matchvar = step.input
|
|
443
|
-
const srcdatavar = step.input
|
|
477
|
+
const ref = step.input.ref ?? entity.name + '_ref01'
|
|
478
|
+
const entvar = step.input.entvar ?? ref + '_ent'
|
|
479
|
+
const matchvar = step.input.matchvar ?? (ref + '_match' + (step.input.suffix ?? ''))
|
|
480
|
+
const srcdatavar = step.input.srcdatavar ?? (ref + '_data')
|
|
444
481
|
|
|
445
482
|
const priorSteps = Object.values(flow.step).slice(0, Number(index)) as any[]
|
|
446
483
|
const needsEnt = !priorSteps.some((s: any) =>
|
|
447
484
|
['create', 'list', 'load', 'update', 'remove'].includes(s.op))
|
|
448
485
|
|
|
486
|
+
const hasEntIdR = null != entity.id
|
|
487
|
+
|
|
449
488
|
Content(` // REMOVE
|
|
450
489
|
`)
|
|
451
490
|
if (needsEnt) {
|
|
452
491
|
Content(` $${entvar} = $client->${accessor}(null);
|
|
453
492
|
`)
|
|
454
493
|
}
|
|
455
|
-
|
|
494
|
+
if (hasEntIdR) {
|
|
495
|
+
Content(` $${matchvar} = [
|
|
456
496
|
"id" => $${srcdatavar}["id"],
|
|
457
497
|
];
|
|
458
498
|
[$_, $err] = $${entvar}->remove($${matchvar}, null);
|
|
459
499
|
$this->assertNull($err);
|
|
460
500
|
`)
|
|
501
|
+
}
|
|
502
|
+
else {
|
|
503
|
+
Content(` $${matchvar} = [];
|
|
504
|
+
[$_, $err] = $${entvar}->remove($${matchvar}, null);
|
|
505
|
+
$this->assertNull($err);
|
|
506
|
+
`)
|
|
507
|
+
}
|
|
461
508
|
}
|
|
462
509
|
|
|
463
510
|
|
|
@@ -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(`# ${model.const.Name} SDK configuration
|
|
@@ -65,10 +73,7 @@ def make_config():
|
|
|
65
73
|
Content(` },
|
|
66
74
|
"options": {
|
|
67
75
|
"base": "${baseUrl}",
|
|
68
|
-
"
|
|
69
|
-
"prefix": "${authPrefix}",
|
|
70
|
-
},
|
|
71
|
-
"headers": ${formatPyDict(headers, 3)},
|
|
76
|
+
${authBlock} "headers": ${formatPyDict(headers, 3)},
|
|
72
77
|
"entity": {
|
|
73
78
|
`)
|
|
74
79
|
|
|
@@ -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:
|
|
@@ -78,8 +82,7 @@ client = ${model.const.Name}SDK({
|
|
|
78
82
|
Create a \`.env.local\` file at the project root:
|
|
79
83
|
|
|
80
84
|
\`\`\`
|
|
81
|
-
${model.NAME}_TEST_LIVE=TRUE
|
|
82
|
-
${model.NAME}_APIKEY=<your-key>
|
|
85
|
+
${model.NAME}_TEST_LIVE=TRUE${apikeyEnvLine}
|
|
83
86
|
\`\`\`
|
|
84
87
|
|
|
85
88
|
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 following Pythonic 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` | `str` | API key for authentication. |\n'
|
|
18
|
+
: ''
|
|
19
|
+
|
|
16
20
|
Content(`### ${model.const.Name}SDK
|
|
17
21
|
|
|
18
22
|
\`\`\`python
|
|
@@ -25,8 +29,7 @@ Creates a new SDK client.
|
|
|
25
29
|
|
|
26
30
|
| Option | Type | Description |
|
|
27
31
|
| --- | --- | --- |
|
|
28
|
-
| \`
|
|
29
|
-
| \`base\` | \`str\` | Base URL of the API server. |
|
|
32
|
+
${apikeyOptionRow}| \`base\` | \`str\` | Base URL of the API server. |
|
|
30
33
|
| \`prefix\` | \`str\` | URL path prefix prepended to all requests. |
|
|
31
34
|
| \`suffix\` | \`str\` | URL path suffix appended to all requests. |
|
|
32
35
|
| \`feature\` | \`dict\` | 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(`\`\`\`python
|
|
23
|
+
client = ${model.Name}SDK({
|
|
24
|
+
`)
|
|
25
|
+
|
|
26
|
+
publishedOptions.map((option: any) => {
|
|
27
|
+
if ('apikey' === option.name) {
|
|
28
|
+
Content(` "${option.name}": os.environ.get("${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
|
+
}
|
|
@@ -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,
|
|
@@ -18,15 +18,18 @@ const ReadmeQuick = cmp(function ReadmeQuick(props: any) {
|
|
|
18
18
|
e.active !== false && e.ancestors && e.ancestors.length > 0
|
|
19
19
|
) as any
|
|
20
20
|
|
|
21
|
+
const authActive = isAuthActive(model)
|
|
22
|
+
const apikeyImport = authActive ? `import os\n` : ''
|
|
23
|
+
const apikeyArg = authActive
|
|
24
|
+
? `\n "apikey": os.environ.get("${model.NAME}_APIKEY"),\n`
|
|
25
|
+
: ''
|
|
26
|
+
|
|
21
27
|
Content(`### 1. Create a client
|
|
22
28
|
|
|
23
29
|
\`\`\`python
|
|
24
|
-
import
|
|
25
|
-
from ${model.const.Name.toLowerCase()}_sdk import ${model.const.Name}SDK
|
|
30
|
+
${apikeyImport}from ${model.const.Name.toLowerCase()}_sdk import ${model.const.Name}SDK
|
|
26
31
|
|
|
27
|
-
client = ${model.const.Name}SDK({
|
|
28
|
-
"apikey": os.environ.get("${model.NAME}_APIKEY"),
|
|
29
|
-
})
|
|
32
|
+
client = ${model.const.Name}SDK({${apikeyArg}})
|
|
30
33
|
\`\`\`
|
|
31
34
|
|
|
32
35
|
`)
|