@voxgig/apidef 3.1.1 → 3.3.1
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/dist/apidef.js.map +1 -1
- package/dist/guide/guide.js +3 -5
- package/dist/guide/guide.js.map +1 -1
- package/dist/guide/heuristic01.js +42 -34
- package/dist/guide/heuristic01.js.map +1 -1
- package/dist/model.d.ts +5 -0
- package/dist/transform/top.js +1 -1
- package/dist/transform/top.js.map +1 -1
- package/dist/utility.d.ts +1 -0
- package/dist/utility.js +71 -36
- package/dist/utility.js.map +1 -1
- package/model/apidef.jsonic +4 -2
- package/package.json +5 -5
- package/src/apidef.ts +1 -5
- package/src/guide/guide.ts +7 -10
- package/src/guide/heuristic01.ts +37 -142
- package/src/model.ts +8 -0
- package/src/transform/top.ts +2 -2
- package/src/utility.ts +88 -42
package/src/guide/heuristic01.ts
CHANGED
|
@@ -53,6 +53,8 @@ import type {
|
|
|
53
53
|
} from '../utility'
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
const KONSOLE_LOG = console['log']
|
|
57
|
+
|
|
56
58
|
|
|
57
59
|
// Log non - fatal wierdness.
|
|
58
60
|
const dlog = getdlog('apidef', __filename)
|
|
@@ -63,7 +65,6 @@ const IS_ENTCMP_METHOD_RATE = 0.21
|
|
|
63
65
|
const IS_ENTCMP_PATH_RATE = 0.41
|
|
64
66
|
|
|
65
67
|
|
|
66
|
-
|
|
67
68
|
const METHOD_IDOP: Record<string, string> = {
|
|
68
69
|
GET: 'load',
|
|
69
70
|
POST: 'create',
|
|
@@ -88,6 +89,7 @@ const METHOD_CONSIDER_ORDER: Record<string, number> = {
|
|
|
88
89
|
|
|
89
90
|
async function heuristic01(ctx: ApiDefContext): Promise<Guide> {
|
|
90
91
|
|
|
92
|
+
// TODO: Ordu needs better debug output to track task exec
|
|
91
93
|
const analysis = new Ordu({ select: { sort: true } }).add([
|
|
92
94
|
Prepare,
|
|
93
95
|
{
|
|
@@ -120,22 +122,13 @@ async function heuristic01(ctx: ApiDefContext): Promise<Guide> {
|
|
|
120
122
|
|
|
121
123
|
const guide = result.data.guide
|
|
122
124
|
|
|
123
|
-
// console.log('WORK', result.data.work)
|
|
124
|
-
|
|
125
|
-
// console.log('GUIDE')
|
|
126
|
-
// console.dir(guide, { depth: null })
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// TODO: move to Ordu
|
|
130
|
-
// warnOnError('reviewEntityDescs', ctx.warn, () => reviewEntityDescs(ctx, result))
|
|
131
|
-
|
|
132
125
|
return guide
|
|
133
126
|
|
|
134
127
|
}
|
|
135
128
|
|
|
136
129
|
|
|
137
130
|
function ShowNode(spec: TaskSpec) {
|
|
138
|
-
|
|
131
|
+
KONSOLE_LOG('NODE', spec.node.key, spec.node.val)
|
|
139
132
|
}
|
|
140
133
|
|
|
141
134
|
|
|
@@ -242,7 +235,6 @@ function selectCmpXrefs(_source: any, spec: TaskSpec) {
|
|
|
242
235
|
const out = find(spec.ctx.def, 'x-ref')
|
|
243
236
|
.filter(xref => xref.val.match(/\/(components\/schemas|definitions)\//))
|
|
244
237
|
|
|
245
|
-
// console.log('selectCmpXrefs', out)
|
|
246
238
|
return out
|
|
247
239
|
}
|
|
248
240
|
|
|
@@ -271,9 +263,10 @@ function selectAllMethods(_source: any, spec: TaskSpec): MethodDesc[] {
|
|
|
271
263
|
const ctx = spec.ctx
|
|
272
264
|
// const paths = ctx.def.paths
|
|
273
265
|
|
|
266
|
+
/*
|
|
274
267
|
let caught = capture(ctx.def, {
|
|
275
268
|
paths:
|
|
276
|
-
['`$SELECT`',
|
|
269
|
+
['`$SELECT`', /.* /,
|
|
277
270
|
['`$SELECT`', /^get|post|put|patch|delete$/i,
|
|
278
271
|
['`$APPEND`', 'methods', {
|
|
279
272
|
path: '`select$=key.paths`',
|
|
@@ -286,11 +279,35 @@ function selectAllMethods(_source: any, spec: TaskSpec): MethodDesc[] {
|
|
|
286
279
|
}]
|
|
287
280
|
]
|
|
288
281
|
]
|
|
289
|
-
|
|
282
|
+
})
|
|
290
283
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
284
|
+
// TODO: capture should return these empty objects
|
|
285
|
+
caught = caught ?? {}
|
|
286
|
+
caught.methods = caught.methods ?? []
|
|
287
|
+
|
|
288
|
+
*/
|
|
289
|
+
|
|
290
|
+
let caught: any = { methods: [] }
|
|
291
|
+
|
|
292
|
+
Object.entries(ctx.def.paths).map((n: any) => {
|
|
293
|
+
const path = n[0]
|
|
294
|
+
const pdef = n[1]
|
|
295
|
+
|
|
296
|
+
Object.entries(pdef).map((m: any) => {
|
|
297
|
+
const method = m[0].toUpperCase()
|
|
298
|
+
const mdef = m[1]
|
|
299
|
+
|
|
300
|
+
caught.methods.push({
|
|
301
|
+
path,
|
|
302
|
+
method,
|
|
303
|
+
summary: mdef.summary,
|
|
304
|
+
tags: mdef.tags,
|
|
305
|
+
parameters: mdef.parameters,
|
|
306
|
+
responses: mdef.responses,
|
|
307
|
+
requestBody: mdef.requestBody,
|
|
308
|
+
})
|
|
309
|
+
})
|
|
310
|
+
})
|
|
294
311
|
|
|
295
312
|
caught.methods.sort((a: any, b: any) => {
|
|
296
313
|
if (a.path < b.path) {
|
|
@@ -310,8 +327,6 @@ function selectAllMethods(_source: any, spec: TaskSpec): MethodDesc[] {
|
|
|
310
327
|
}
|
|
311
328
|
})
|
|
312
329
|
|
|
313
|
-
// console.log(caught.methods.map((n: any) => n.path + ' ' + n.method))
|
|
314
|
-
|
|
315
330
|
return caught.methods || []
|
|
316
331
|
}
|
|
317
332
|
|
|
@@ -402,7 +417,7 @@ function ResolveEntityComponent(spec: TaskSpec) {
|
|
|
402
417
|
const pcount = metrics.count.path
|
|
403
418
|
const method_rate = (0 < mcount ? (cmprefs / mcount) : -1)
|
|
404
419
|
const path_rate = (0 < pcount ? (cmprefs / pcount) : -1)
|
|
405
|
-
|
|
420
|
+
|
|
406
421
|
const infrequent =
|
|
407
422
|
method_rate < IS_ENTCMP_METHOD_RATE
|
|
408
423
|
|| path_rate < IS_ENTCMP_PATH_RATE
|
|
@@ -1036,8 +1051,6 @@ function ResolveTransform(spec: TaskSpec) {
|
|
|
1036
1051
|
const resprops = getResponseSchema(resokdef)?.properties
|
|
1037
1052
|
debugpath(pathStr, methodName, 'TRANSFORM-RES', keysof(resprops))
|
|
1038
1053
|
|
|
1039
|
-
// console.log('APIDEF-resprops', resprops)
|
|
1040
|
-
|
|
1041
1054
|
if (resprops) {
|
|
1042
1055
|
if (resprops[entdesc.origname]) {
|
|
1043
1056
|
transform.res = '`body.' + entdesc.origname + '`'
|
|
@@ -1067,8 +1080,6 @@ function ResolveTransform(spec: TaskSpec) {
|
|
|
1067
1080
|
|
|
1068
1081
|
function BuildEntity(spec: TaskSpec) {
|
|
1069
1082
|
const entdesc = spec.node.val
|
|
1070
|
-
// console.log('BUILD-ENTITY')
|
|
1071
|
-
// console.dir(entdesc, { depth: null })
|
|
1072
1083
|
|
|
1073
1084
|
const guide: Guide = spec.data.guide
|
|
1074
1085
|
guide.metrics.count.entity++
|
|
@@ -1078,7 +1089,6 @@ function BuildEntity(spec: TaskSpec) {
|
|
|
1078
1089
|
const path: Record<string, GuidePath> = {}
|
|
1079
1090
|
|
|
1080
1091
|
const rename_param = (pathdesc: any) => {
|
|
1081
|
-
// console.log('RENAME-PATHDESC', pathdesc)
|
|
1082
1092
|
const out: Record<string, GuideRenameParam> = {}
|
|
1083
1093
|
each(pathdesc.rename.param, (item: any) => {
|
|
1084
1094
|
out[item.key$] = {
|
|
@@ -1371,8 +1381,6 @@ function entityCmpMatch(
|
|
|
1371
1381
|
pathish: true,
|
|
1372
1382
|
}
|
|
1373
1383
|
|
|
1374
|
-
// console.log('ECM-A', out, ment)
|
|
1375
|
-
|
|
1376
1384
|
const cmpInfrequent = (
|
|
1377
1385
|
ment.method_rate < IS_ENTCMP_METHOD_RATE
|
|
1378
1386
|
|| ment.path_rate < IS_ENTCMP_PATH_RATE
|
|
@@ -1431,8 +1439,6 @@ function entityCmpMatch(
|
|
|
1431
1439
|
mdesc.method, entname + '->', out, why, ment,
|
|
1432
1440
|
IS_ENTCMP_METHOD_RATE, IS_ENTCMP_PATH_RATE)
|
|
1433
1441
|
|
|
1434
|
-
// console.log('ECM-Z', out, why, ment)
|
|
1435
|
-
|
|
1436
1442
|
return out
|
|
1437
1443
|
}
|
|
1438
1444
|
|
|
@@ -1647,7 +1653,6 @@ function findcmps(
|
|
|
1647
1653
|
|
|
1648
1654
|
|
|
1649
1655
|
found.map((xref: { val: string }) => {
|
|
1650
|
-
// console.log('FINDCMPS', pathStr, (md as any).key$, up, xref.val)
|
|
1651
1656
|
let m = xref.val.match(/\/(components\/schemas|definitions)\/(.+)$/)
|
|
1652
1657
|
if (m) {
|
|
1653
1658
|
cmplist.push(m[2])
|
|
@@ -1656,7 +1661,7 @@ function findcmps(
|
|
|
1656
1661
|
})
|
|
1657
1662
|
})
|
|
1658
1663
|
})
|
|
1659
|
-
|
|
1664
|
+
|
|
1660
1665
|
return (opts?.uniq ? Array.from(cmpset) : cmplist).map(n =>
|
|
1661
1666
|
({ cmp: canonize(n), origcmp: n }))
|
|
1662
1667
|
}
|
|
@@ -1714,119 +1719,9 @@ function hasMethod(def: any, pathStr: string, methodName: string) {
|
|
|
1714
1719
|
|| null != pathDef[methodName.toUpperCase()]
|
|
1715
1720
|
)
|
|
1716
1721
|
)
|
|
1717
|
-
console.log('hasMethod', pathStr, methodName, found)
|
|
1718
|
-
return found
|
|
1719
|
-
}
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
/*
|
|
1724
|
-
// Some decisions require the full list of potential entities.
|
|
1725
|
-
function reviewEntityDescs(ctx: ApiDefContext, result: any) {
|
|
1726
|
-
const guide: Guide = result.data.guide
|
|
1727
|
-
const metrics = guide.metrics
|
|
1728
|
-
const entityDescs = result.data.work.entmap
|
|
1729
|
-
|
|
1730
|
-
if (0 < metrics.count.cmp) {
|
|
1731
|
-
items(entityDescs).map(([entname, entdesc]: [string, EntityDesc]) => {
|
|
1732
|
-
|
|
1733
|
-
// Entities with a single path and single op and no cmp are suspicious
|
|
1734
1722
|
|
|
1735
|
-
|
|
1736
|
-
const pathcount = size(pathmap)
|
|
1737
|
-
const hascmp = null != entdesc.cmp?.namedesc
|
|
1738
|
-
|
|
1739
|
-
if (
|
|
1740
|
-
1 === pathcount
|
|
1741
|
-
&& !hascmp
|
|
1742
|
-
) {
|
|
1743
|
-
let pathdesc: EntityPathDesc = each(pathmap)[0]
|
|
1744
|
-
const pathStr = (pathdesc as any).key$
|
|
1745
|
-
|
|
1746
|
-
if (1 === size(pathdesc.op)) {
|
|
1747
|
-
let op = pathdesc.op
|
|
1748
|
-
|
|
1749
|
-
// console.log('REVIEW', entdesc.name, pathcount, hascmp, op)
|
|
1750
|
-
|
|
1751
|
-
if (op.create) {
|
|
1752
|
-
|
|
1753
|
-
// Entities without "good" components
|
|
1754
|
-
if (
|
|
1755
|
-
entname.includes('_')
|
|
1756
|
-
&& pathdesc.pm.expr.endsWith('p/t/')
|
|
1757
|
-
) {
|
|
1758
|
-
const lastpart = canonize(getelem(pathdesc.pm, -1))
|
|
1759
|
-
const tgtent = entityDescs[lastpart]
|
|
1760
|
-
|
|
1761
|
-
// console.log('REVIEW', entname, entdesc.cmp, size(pathmap), lastpart, realent)
|
|
1762
|
-
|
|
1763
|
-
if (
|
|
1764
|
-
null != tgtent
|
|
1765
|
-
&& tgtent.name !== entname
|
|
1766
|
-
&& (
|
|
1767
|
-
null == tgtent.cmp
|
|
1768
|
-
|| lastpart == tgtent.cmp
|
|
1769
|
-
)
|
|
1770
|
-
) {
|
|
1771
|
-
|
|
1772
|
-
// Actually a known component
|
|
1773
|
-
// console.dir(entdesc, { depth: null })
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
const realent = guide.entity[entname]
|
|
1777
|
-
const realpathmap = realent.path
|
|
1778
|
-
let realpath = realpathmap[pathStr]
|
|
1779
|
-
|
|
1780
|
-
if (null == realpath) {
|
|
1781
|
-
realpath = realpathmap[pathStr] = pathdesc
|
|
1782
|
-
}
|
|
1783
|
-
else if (null == realpath.op?.create) {
|
|
1784
|
-
realpath.op = (realpath.op ?? {})
|
|
1785
|
-
realpath.op.create = pathdesc.op.create
|
|
1786
|
-
}
|
|
1787
|
-
|
|
1788
|
-
realpath.op.create.why_op =
|
|
1789
|
-
'was/create/A:' + entname + ':' + realpath.op.create.why_op
|
|
1790
|
-
|
|
1791
|
-
delete entityDescs[entname]
|
|
1792
|
-
|
|
1793
|
-
// console.log('REPLACE', entname, realent.name, realpath)
|
|
1794
|
-
}
|
|
1795
|
-
|
|
1796
|
-
}
|
|
1797
|
-
}
|
|
1798
|
-
|
|
1799
|
-
else if (op.remove) {
|
|
1800
|
-
const otherents: EntityDesc[] = each(entityDescs)
|
|
1801
|
-
.filter((ed: EntityDesc) => ed !== entdesc && each(ed.path)
|
|
1802
|
-
.filter(epd => epd.key$ === pathStr).length)
|
|
1803
|
-
|
|
1804
|
-
const otherent = 1 === otherents.length ? otherents[0] : null
|
|
1805
|
-
|
|
1806
|
-
// console.log('OTHERENT', pathStr, otherents.length, otherent)
|
|
1807
|
-
|
|
1808
|
-
if (null != otherent && null != otherent.cmp) {
|
|
1809
|
-
const otherpath = otherent.path[pathStr]
|
|
1810
|
-
|
|
1811
|
-
if (null == otherpath.op.remove) {
|
|
1812
|
-
otherpath.op.remove = op.remove
|
|
1813
|
-
otherpath.op.remove.why_op =
|
|
1814
|
-
'was/delete/A:' + entname + ':' + op.remove.why_op
|
|
1815
|
-
delete entityDescs[entname]
|
|
1816
|
-
}
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
|
|
1820
|
-
debugpath(pathdesc.pm.path, null,
|
|
1821
|
-
'REVIEW-ENTITY', formatJSONIC(entdesc, { hsepd: 0, $: true, color: true }))
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
}
|
|
1825
|
-
}
|
|
1826
|
-
})
|
|
1827
|
-
}
|
|
1723
|
+
return found
|
|
1828
1724
|
}
|
|
1829
|
-
*/
|
|
1830
1725
|
|
|
1831
1726
|
|
|
1832
1727
|
export {
|
package/src/model.ts
CHANGED
|
@@ -10,6 +10,14 @@ type OpName = 'load' | 'list' | 'create' | 'update' | 'remove' | 'patch' | 'head
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
type Model = {
|
|
13
|
+
name: string
|
|
14
|
+
origin?: string
|
|
15
|
+
|
|
16
|
+
const: {
|
|
17
|
+
// TODO: remove
|
|
18
|
+
Name: string
|
|
19
|
+
}
|
|
20
|
+
|
|
13
21
|
main: {
|
|
14
22
|
kit: {
|
|
15
23
|
entity: Record<string, ModelEntity>
|
package/src/transform/top.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
2
|
+
import { join } from '@voxgig/struct'
|
|
3
3
|
|
|
4
4
|
import { KIT } from '../types'
|
|
5
5
|
|
|
@@ -47,7 +47,7 @@ const topTransform = async function(
|
|
|
47
47
|
// Swagger 2.0
|
|
48
48
|
if (def.host) {
|
|
49
49
|
kit.info.servers.push({
|
|
50
|
-
url: (def.schemes?.[0] ?? 'https') + '://' +
|
|
50
|
+
url: (def.schemes?.[0] ?? 'https') + '://' + join([def.host, def.basePath], '/', true)
|
|
51
51
|
})
|
|
52
52
|
}
|
|
53
53
|
|
package/src/utility.ts
CHANGED
|
@@ -6,7 +6,12 @@ import { snakify, camelify, kebabify, each } from 'jostraca'
|
|
|
6
6
|
import { decircular } from '@voxgig/util'
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
|
-
slice, merge, inject, clone, isnode, walk, transform, select
|
|
9
|
+
slice, merge, inject, clone, isnode, walk, transform, select,
|
|
10
|
+
Injection,
|
|
11
|
+
M_VAL,
|
|
12
|
+
M_KEYPRE,
|
|
13
|
+
M_KEYPOST,
|
|
14
|
+
|
|
10
15
|
} from '@voxgig/struct'
|
|
11
16
|
|
|
12
17
|
|
|
@@ -17,6 +22,8 @@ import type {
|
|
|
17
22
|
} from './types'
|
|
18
23
|
|
|
19
24
|
|
|
25
|
+
const KONSOLE_LOG = console['log']
|
|
26
|
+
|
|
20
27
|
|
|
21
28
|
function makeWarner(spec: { point: string, log: Log }): Warner {
|
|
22
29
|
const { point, log } = spec
|
|
@@ -222,26 +229,28 @@ function capture(data: any, shape: any): Record<string, any> {
|
|
|
222
229
|
})
|
|
223
230
|
|
|
224
231
|
if (0 < errs.length) {
|
|
225
|
-
|
|
232
|
+
KONSOLE_LOG('ERRS', errs)
|
|
226
233
|
dlog(errs)
|
|
227
234
|
}
|
|
228
235
|
return meta.capture
|
|
229
236
|
}
|
|
230
237
|
|
|
231
238
|
|
|
232
|
-
function $CAPTURE(inj:
|
|
239
|
+
function $CAPTURE(inj: Injection) {
|
|
233
240
|
// Set prop foo with value at x: { x: { '`$CAPTURE`': 'foo' } }
|
|
234
|
-
if (
|
|
241
|
+
if (M_KEYPRE === inj.mode) {
|
|
235
242
|
const { val, prior } = inj
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
243
|
+
if (null != prior) {
|
|
244
|
+
const { dparent, key } = prior
|
|
245
|
+
const dval = dparent?.[key]
|
|
246
|
+
if (undefined !== dval) {
|
|
247
|
+
inj.meta.capture[val] = dval
|
|
248
|
+
}
|
|
240
249
|
}
|
|
241
250
|
}
|
|
242
251
|
|
|
243
252
|
// Use key x as prop name: { x: '`$CAPTURE`': }
|
|
244
|
-
else if (
|
|
253
|
+
else if (M_VAL === inj.mode) {
|
|
245
254
|
const { key, dparent } = inj
|
|
246
255
|
const dval = dparent?.[key]
|
|
247
256
|
if (undefined !== dval) {
|
|
@@ -251,22 +260,28 @@ function $CAPTURE(inj: any) {
|
|
|
251
260
|
}
|
|
252
261
|
|
|
253
262
|
|
|
254
|
-
function $APPEND(inj:
|
|
263
|
+
function $APPEND(inj: Injection, val: any, ref: any, store: any) {
|
|
255
264
|
// Set prop foo with value at x: { x: { '`$CAPTURE`': 'foo' } }
|
|
256
|
-
if (
|
|
265
|
+
if (M_KEYPRE === inj.mode) {
|
|
257
266
|
const { val, prior } = inj
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
267
|
+
if (null != prior) {
|
|
268
|
+
const { dparent, key } = prior
|
|
269
|
+
const dval = dparent?.[key]
|
|
270
|
+
if (undefined !== dval) {
|
|
271
|
+
inj.meta.capture[val] = (inj.meta.capture[val] || [])
|
|
272
|
+
inj.meta.capture[val].push(dval)
|
|
273
|
+
}
|
|
263
274
|
}
|
|
264
275
|
}
|
|
265
276
|
|
|
266
277
|
|
|
267
|
-
else if (
|
|
278
|
+
else if (M_VAL === inj.mode) {
|
|
268
279
|
inj.keyI = inj.keys.length
|
|
269
280
|
|
|
281
|
+
if (null == inj.prior) {
|
|
282
|
+
return
|
|
283
|
+
}
|
|
284
|
+
|
|
270
285
|
const [_, prop, xform] = inj.parent
|
|
271
286
|
const { key, dparent } = inj.prior
|
|
272
287
|
const dval = dparent?.[key]
|
|
@@ -291,28 +306,30 @@ function $APPEND(inj: any, val: any, ref: any, store: any) {
|
|
|
291
306
|
|
|
292
307
|
|
|
293
308
|
|
|
294
|
-
function $ANY(inj:
|
|
295
|
-
if (
|
|
309
|
+
function $ANY(inj: Injection, _val: any, _ref: any, store: any) {
|
|
310
|
+
if (M_KEYPRE === inj.mode) {
|
|
296
311
|
const { prior } = inj
|
|
297
312
|
const child = inj.parent[inj.key]
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
let
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
313
|
+
if (null != prior) {
|
|
314
|
+
const { dparent, key } = prior
|
|
315
|
+
const dval = dparent?.[key]
|
|
316
|
+
if (isnode(dval)) {
|
|
317
|
+
for (let n of Object.entries(dval)) {
|
|
318
|
+
let vstore = { ...store }
|
|
319
|
+
vstore.$TOP = { [n[0]]: n[1] }
|
|
320
|
+
inject(clone({ [n[0]]: child }), vstore, {
|
|
321
|
+
meta: inj.meta,
|
|
322
|
+
errs: inj.errs,
|
|
323
|
+
})
|
|
324
|
+
}
|
|
308
325
|
}
|
|
309
326
|
}
|
|
310
327
|
}
|
|
311
328
|
}
|
|
312
329
|
|
|
313
330
|
|
|
314
|
-
function $SELECT(inj:
|
|
315
|
-
if (
|
|
331
|
+
function $SELECT(inj: Injection, _val: any, _ref: any, store: any) {
|
|
332
|
+
if (M_VAL === inj.mode) {
|
|
316
333
|
inj.keyI = inj.keys.length
|
|
317
334
|
|
|
318
335
|
let [_, selector, descendor] = inj.parent
|
|
@@ -352,8 +369,12 @@ function $SELECT(inj: any, _val: any, _ref: any, store: any) {
|
|
|
352
369
|
}
|
|
353
370
|
|
|
354
371
|
|
|
355
|
-
function $RECASE(inj:
|
|
356
|
-
if (
|
|
372
|
+
function $RECASE(inj: Injection, val: any, ref: any, store: any) {
|
|
373
|
+
if (
|
|
374
|
+
M_KEYPRE === inj.mode
|
|
375
|
+
&& null != inj.prior
|
|
376
|
+
&& null != inj.prior.prior
|
|
377
|
+
) {
|
|
357
378
|
const dval = inj.parent[inj.key]
|
|
358
379
|
|
|
359
380
|
// TODO: handle paths more generally! use inj.prior?
|
|
@@ -727,19 +748,22 @@ function warnOnError(where: string, warn: Warner, fn: Function, result?: any) {
|
|
|
727
748
|
|
|
728
749
|
function debugpath(pathStr: string, methodName: string | null | undefined, ...args: any[]): void {
|
|
729
750
|
const apipath = process.env.APIDEF_DEBUG_PATH
|
|
730
|
-
if (!apipath) return
|
|
731
751
|
|
|
732
|
-
|
|
752
|
+
if (null == apipath || '' === apipath) return
|
|
733
753
|
|
|
734
|
-
|
|
735
|
-
|
|
754
|
+
if ('ALL' !== apipath) {
|
|
755
|
+
const [targetPath, targetMethod] = apipath.split(':')
|
|
736
756
|
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
757
|
+
// Check if path matches
|
|
758
|
+
if (pathStr !== targetPath) return
|
|
759
|
+
|
|
760
|
+
// If a method is specified in apipath and we have a method name, check if it matches
|
|
761
|
+
if (targetMethod && methodName) {
|
|
762
|
+
if (methodName.toLowerCase() !== targetMethod.toLowerCase()) return
|
|
763
|
+
}
|
|
740
764
|
}
|
|
741
765
|
|
|
742
|
-
|
|
766
|
+
KONSOLE_LOG(methodName || '', ...args)
|
|
743
767
|
}
|
|
744
768
|
|
|
745
769
|
|
|
@@ -807,12 +831,14 @@ function relativizePath(path: string): string {
|
|
|
807
831
|
}
|
|
808
832
|
|
|
809
833
|
|
|
834
|
+
// NOTE: removes inactive items by default
|
|
810
835
|
function getModelPath(
|
|
811
836
|
model: any,
|
|
812
837
|
path: string,
|
|
813
|
-
flags?: { required?: boolean }
|
|
838
|
+
flags?: { required?: boolean, only_active?: boolean }
|
|
814
839
|
): any {
|
|
815
840
|
const required = flags?.required ?? true
|
|
841
|
+
const only_active = flags?.only_active ?? true
|
|
816
842
|
|
|
817
843
|
if (path === '') {
|
|
818
844
|
if (required) {
|
|
@@ -876,6 +902,26 @@ function getModelPath(
|
|
|
876
902
|
current = current[part]
|
|
877
903
|
}
|
|
878
904
|
|
|
905
|
+
if (current && only_active) {
|
|
906
|
+
if (false === current.active) {
|
|
907
|
+
current = undefined
|
|
908
|
+
}
|
|
909
|
+
if ('object' === typeof current) {
|
|
910
|
+
const out: any = Array.isArray(current) ? [] : {}
|
|
911
|
+
Object.entries(current).map((n: any) => {
|
|
912
|
+
if (null != n[1] && false !== n[1].active) {
|
|
913
|
+
if (Array.isArray(out)) {
|
|
914
|
+
out.push(n[1])
|
|
915
|
+
}
|
|
916
|
+
else {
|
|
917
|
+
out[n[0]] = n[1]
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
})
|
|
921
|
+
current = out
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
|
|
879
925
|
return current
|
|
880
926
|
}
|
|
881
927
|
|