@voxgig/apidef 6.3.6 → 6.3.8
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.d.ts +2 -2
- package/dist/apidef.js +27 -6
- package/dist/apidef.js.map +1 -1
- package/dist/builder/entity/entity.js.map +1 -1
- package/dist/builder/entity/info.js.map +1 -1
- package/dist/builder/entity.js.map +1 -1
- package/dist/builder/flow/flowHeuristic01.js.map +1 -1
- package/dist/builder/flow.js.map +1 -1
- package/dist/guide/guide.js +49 -6
- package/dist/guide/guide.js.map +1 -1
- package/dist/guide/heuristic01.js +99 -89
- package/dist/guide/heuristic01.js.map +1 -1
- package/dist/parse.js +151 -18
- package/dist/parse.js.map +1 -1
- package/dist/resolver.js.map +1 -1
- package/dist/transform/args.js.map +1 -1
- package/dist/transform/clean.js.map +1 -1
- package/dist/transform/entity.js.map +1 -1
- package/dist/transform/field.js +14 -0
- package/dist/transform/field.js.map +1 -1
- package/dist/transform/flow.js.map +1 -1
- package/dist/transform/flowstep.js.map +1 -1
- package/dist/transform/operation.js.map +1 -1
- package/dist/transform/select.js.map +1 -1
- package/dist/transform/top.d.ts +2 -1
- package/dist/transform/top.js +32 -2
- package/dist/transform/top.js.map +1 -1
- package/dist/transform.d.ts +8 -7
- package/dist/transform.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types.d.ts +97 -84
- package/dist/types.js.map +1 -1
- package/dist/utility.d.ts +6 -1
- package/dist/utility.js +169 -8
- package/dist/utility.js.map +1 -1
- package/package.json +8 -8
- package/src/apidef.ts +28 -5
- package/src/guide/guide.ts +50 -6
- package/src/guide/heuristic01.ts +37 -28
- package/src/parse.ts +161 -20
- package/src/transform/field.ts +16 -1
- package/src/transform/top.ts +37 -2
- package/src/tsconfig.json +1 -0
- package/src/types.ts +5 -0
- package/src/utility.ts +186 -8
|
@@ -5,11 +5,12 @@ const ordu_1 = require("ordu");
|
|
|
5
5
|
const jostraca_1 = require("jostraca");
|
|
6
6
|
const struct_1 = require("@voxgig/struct");
|
|
7
7
|
const utility_1 = require("../utility");
|
|
8
|
+
const utility_2 = require("../utility");
|
|
8
9
|
const jostraca_2 = require("jostraca");
|
|
9
10
|
const entity_1 = require("../transform/entity");
|
|
10
11
|
const KONSOLE_LOG = console['log'];
|
|
11
12
|
// Log non - fatal wierdness.
|
|
12
|
-
const dlog = (0,
|
|
13
|
+
const dlog = (0, utility_2.getdlog)('apidef', __filename);
|
|
13
14
|
// Schema components that occur less than this rate(over total method count) qualify
|
|
14
15
|
// as unique entities, not shared schemas
|
|
15
16
|
const IS_ENTCMP_METHOD_RATE = 0.21;
|
|
@@ -80,10 +81,10 @@ async function heuristic01(ctx) {
|
|
|
80
81
|
let totalPaths = 0;
|
|
81
82
|
let totalOps = 0;
|
|
82
83
|
for (const ent of entities) {
|
|
83
|
-
const pathKeys = (0,
|
|
84
|
+
const pathKeys = (0, utility_2.sortedKeys)(ent.path || {});
|
|
84
85
|
totalPaths += pathKeys.length;
|
|
85
86
|
for (const p of pathKeys) {
|
|
86
|
-
totalOps += (0,
|
|
87
|
+
totalOps += (0, utility_2.sortedKeys)(ent.path[p].op || {}).length;
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
ctx.log.info({
|
|
@@ -162,7 +163,7 @@ function MeasureMethod(spec) {
|
|
|
162
163
|
metrics.count.tag++;
|
|
163
164
|
metrics.found.tag[tag] = {
|
|
164
165
|
name: tag,
|
|
165
|
-
canon: (0,
|
|
166
|
+
canon: (0, utility_2.canonize)(tag),
|
|
166
167
|
};
|
|
167
168
|
}
|
|
168
169
|
}
|
|
@@ -182,7 +183,7 @@ function PreparePath(spec) {
|
|
|
182
183
|
work.pathmap[pathstr] = pathdesc;
|
|
183
184
|
}
|
|
184
185
|
function selectCmpXrefs(_source, spec) {
|
|
185
|
-
const out = (0,
|
|
186
|
+
const out = (0, utility_2.find)(spec.ctx.def, 'x-ref')
|
|
186
187
|
.filter(xref => xref.val.match(/\/(components\/schemas|definitions)\//));
|
|
187
188
|
return out;
|
|
188
189
|
}
|
|
@@ -191,7 +192,7 @@ function MeasureRef(spec) {
|
|
|
191
192
|
const metrics = guide.metrics;
|
|
192
193
|
let m = spec.node.val.val.match(/\/(components\/schemas|definitions)\/(.+)$/);
|
|
193
194
|
if (m) {
|
|
194
|
-
const name = (0,
|
|
195
|
+
const name = (0, utility_2.canonizeCmpName)(m[2]);
|
|
195
196
|
if (null == metrics.count.origcmprefs[name]) {
|
|
196
197
|
metrics.count.cmp++;
|
|
197
198
|
metrics.count.origcmprefs[name] = 0;
|
|
@@ -229,8 +230,8 @@ function selectAllMethods(_source, spec) {
|
|
|
229
230
|
|
|
230
231
|
*/
|
|
231
232
|
let caught = { methods: [] };
|
|
232
|
-
for (const [path, pdef] of (0,
|
|
233
|
-
for (const [m, mdef] of (0,
|
|
233
|
+
for (const [path, pdef] of (0, utility_2.sortedEntries)(ctx.def.paths)) {
|
|
234
|
+
for (const [m, mdef] of (0, utility_2.sortedEntries)(pdef)) {
|
|
234
235
|
const method = m.toUpperCase();
|
|
235
236
|
caught.methods.push({
|
|
236
237
|
path,
|
|
@@ -284,7 +285,7 @@ function ResolveEntityComponent(spec) {
|
|
|
284
285
|
m = xref.val.match(/\/definitions\/(.+)$/);
|
|
285
286
|
}
|
|
286
287
|
if (m) {
|
|
287
|
-
const cmp = (0,
|
|
288
|
+
const cmp = (0, utility_2.canonizeCmpName)(m[1]);
|
|
288
289
|
xref.cmp = cmp;
|
|
289
290
|
xref.origcmp = m[1];
|
|
290
291
|
xref.origcmpref = cmp;
|
|
@@ -299,7 +300,7 @@ function ResolveEntityComponent(spec) {
|
|
|
299
300
|
// Guarded wrapper-suffix stripping folds e.g. BeneficiaryPageResponse
|
|
300
301
|
// into beneficiary — but only when the remainder is itself a schema
|
|
301
302
|
// measured by MeasureRef (keys are canonizeCmpName, pre-clean).
|
|
302
|
-
xref.cmp = (0,
|
|
303
|
+
xref.cmp = (0, utility_2.cleanComponentName)(xref.cmp, (n) => null != metrics.count.origcmprefs[n]);
|
|
303
304
|
return xref;
|
|
304
305
|
});
|
|
305
306
|
let goodxrefs = cleanxrefs
|
|
@@ -319,7 +320,7 @@ function ResolveEntityComponent(spec) {
|
|
|
319
320
|
const infrequent = method_rate < IS_ENTCMP_METHOD_RATE
|
|
320
321
|
|| path_rate < IS_ENTCMP_PATH_RATE;
|
|
321
322
|
if (!infrequent) {
|
|
322
|
-
(0,
|
|
323
|
+
(0, utility_2.debugpath)(pathStr, methodName, 'CMP-INFREQ', xref.val, 'method:', method_rate, IS_ENTCMP_METHOD_RATE, 'path:', path_rate, IS_ENTCMP_PATH_RATE);
|
|
323
324
|
}
|
|
324
325
|
return infrequent;
|
|
325
326
|
});
|
|
@@ -343,7 +344,7 @@ function ResolveEntityComponent(spec) {
|
|
|
343
344
|
|| null == fcmp // there's no cmp, so use tag
|
|
344
345
|
);
|
|
345
346
|
});
|
|
346
|
-
(0,
|
|
347
|
+
(0, utility_2.debugpath)(pathStr, methodName, 'TAGS', tags, goodtags, fcmp, methodDef, metrics.found);
|
|
347
348
|
const ftag = goodtags[0];
|
|
348
349
|
if (null != ftag) {
|
|
349
350
|
const tagdesc = metrics.found.tag[ftag];
|
|
@@ -380,7 +381,7 @@ function ResolveEntityComponent(spec) {
|
|
|
380
381
|
out.method_rate = 0 == metrics.count.method ? -1 : (out.cmpoccur / metrics.count.method);
|
|
381
382
|
methodDef.MethodEntity = out;
|
|
382
383
|
}
|
|
383
|
-
(0,
|
|
384
|
+
(0, utility_2.debugpath)(pathStr, methodName, 'CMP-NAME', out, origxrefs, cleanxrefs, goodxrefs, goodtags);
|
|
384
385
|
}
|
|
385
386
|
function ResolveEntityName(spec) {
|
|
386
387
|
const ctx = spec.ctx;
|
|
@@ -403,19 +404,19 @@ function ResolveEntityName(spec) {
|
|
|
403
404
|
why_path.push(...(ment.why_cmp ?? []));
|
|
404
405
|
let entname;
|
|
405
406
|
let pm = undefined;
|
|
406
|
-
if (pm = (0,
|
|
407
|
+
if (pm = (0, utility_2.pathMatch)(parts, 't/p/t/')) {
|
|
407
408
|
entname = entityPathMatch_tpte(data, pm, mdesc, why_path);
|
|
408
409
|
}
|
|
409
|
-
else if (pm = (0,
|
|
410
|
+
else if (pm = (0, utility_2.pathMatch)(parts, 't/p/')) {
|
|
410
411
|
entname = entityPathMatch_tpe(data, pm, mdesc, why_path);
|
|
411
412
|
}
|
|
412
|
-
else if (pm = (0,
|
|
413
|
+
else if (pm = (0, utility_2.pathMatch)(parts, 'p/t/')) {
|
|
413
414
|
entname = entityPathMatch_pte(data, pm, mdesc, why_path);
|
|
414
415
|
}
|
|
415
|
-
else if (pm = (0,
|
|
416
|
+
else if (pm = (0, utility_2.pathMatch)(parts, 't/')) {
|
|
416
417
|
entname = entityPathMatch_te(data, pm, mdesc, why_path);
|
|
417
418
|
}
|
|
418
|
-
else if (pm = (0,
|
|
419
|
+
else if (pm = (0, utility_2.pathMatch)(parts, 't/p/p')) {
|
|
419
420
|
entname = entityPathMatch_tpp(data, pm, mdesc, why_path);
|
|
420
421
|
}
|
|
421
422
|
else {
|
|
@@ -429,7 +430,7 @@ function ResolveEntityName(spec) {
|
|
|
429
430
|
// re-encounter of the SAME origin (merge) from a genuinely different one
|
|
430
431
|
// (numeric suffix) — see ensureMinEntityName.
|
|
431
432
|
const rawEntname = entname;
|
|
432
|
-
entname = (0,
|
|
433
|
+
entname = (0, utility_2.ensureMinEntityName)(entname, work.entmap);
|
|
433
434
|
const entdesc = work.entmap[entname] = work.entmap[entname] ?? {
|
|
434
435
|
name: entname,
|
|
435
436
|
id: 'N' + ('' + Math.random()).substring(2, 10),
|
|
@@ -448,7 +449,7 @@ function ResolveEntityName(spec) {
|
|
|
448
449
|
entdesc.path[pathStr].why_path = why_path;
|
|
449
450
|
ment.entname = entname;
|
|
450
451
|
ment.pm = pm;
|
|
451
|
-
(0,
|
|
452
|
+
(0, utility_2.debugpath)(pathStr, methodName, 'RESOLVE-ENTITY-NAME', (0, utility_2.formatJSONIC)({ entdesc, ment }, { hsepd: 0, $: true, color: true }));
|
|
452
453
|
}
|
|
453
454
|
function RenameParams(spec) {
|
|
454
455
|
const ctx = spec.ctx;
|
|
@@ -491,7 +492,7 @@ function RenameParams(spec) {
|
|
|
491
492
|
if (!m)
|
|
492
493
|
continue;
|
|
493
494
|
const placeholder = m[1];
|
|
494
|
-
const snake = (0,
|
|
495
|
+
const snake = (0, utility_2.depluralize)((0, jostraca_2.snakify)((0, utility_2.normalizeFieldName)(placeholder)));
|
|
495
496
|
if (snake !== placeholder && paramRenameCapture.rename[placeholder] === undefined) {
|
|
496
497
|
paramRenameCapture.why[placeholder] = (paramRenameCapture.why[placeholder] ?? []);
|
|
497
498
|
updateParamRename(ctx, data, pathStr, methodName, paramRenameCapture, placeholder, snake, 'snake-case');
|
|
@@ -499,7 +500,7 @@ function RenameParams(spec) {
|
|
|
499
500
|
}
|
|
500
501
|
};
|
|
501
502
|
// id needs to be t/p/
|
|
502
|
-
const multParamEndMatch = (0,
|
|
503
|
+
const multParamEndMatch = (0, utility_2.pathMatch)(mdesc.path, 'p/p/');
|
|
503
504
|
if (multParamEndMatch) {
|
|
504
505
|
applySnakeCaseRename();
|
|
505
506
|
ment.rename = paramRenameCapture.rename;
|
|
@@ -522,12 +523,12 @@ function RenameParams(spec) {
|
|
|
522
523
|
const secondLastPart = partI === parts.length - 2;
|
|
523
524
|
const notLastPart = partI < parts.length - 1;
|
|
524
525
|
const hasParent = 0 < partI && !isParam(parts[partI - 1]);
|
|
525
|
-
const parentName = hasParent ? (0,
|
|
526
|
+
const parentName = hasParent ? (0, utility_2.canonize)(parts[partI - 1]) : null;
|
|
526
527
|
const not_exact_id = 'id' !== oldParam;
|
|
527
528
|
const probably_an_id = oldParam.endsWith('id')
|
|
528
529
|
|| oldParam.endsWith('Id')
|
|
529
|
-
|| (0,
|
|
530
|
-
(0,
|
|
530
|
+
|| (0, utility_2.canonize)(oldParam) === parentName;
|
|
531
|
+
(0, utility_2.debugpath)(pathStr, mdesc.method, 'RENAME-PARAM-PART', parts, partI, partStr, {
|
|
531
532
|
lastPart,
|
|
532
533
|
secondLastPart,
|
|
533
534
|
notLastPart,
|
|
@@ -591,7 +592,7 @@ function RenameParams(spec) {
|
|
|
591
592
|
why.push('second-last');
|
|
592
593
|
if ('id' !== oldParam
|
|
593
594
|
// && fixEntName(partStr) === entdesc.name
|
|
594
|
-
&& (0,
|
|
595
|
+
&& (0, utility_2.canonize)(partStr) === entdesc.name) {
|
|
595
596
|
updateParamRename(ctx, data, pathStr, methodName, paramRenameCapture, oldParam, 'id', 'end-action');
|
|
596
597
|
why.push('end-action');
|
|
597
598
|
updateAction(methodName, oldParam, parts[partI + 1], entdesc, pathDesc, 'end-action');
|
|
@@ -627,7 +628,7 @@ function RenameParams(spec) {
|
|
|
627
628
|
delete paramRenameCapture.why[oldParam];
|
|
628
629
|
}
|
|
629
630
|
// TODO: these need to done via an API
|
|
630
|
-
(0,
|
|
631
|
+
(0, utility_2.debugpath)(pathStr, methodName, 'RENAME-PARAM', {
|
|
631
632
|
pathStr,
|
|
632
633
|
methodName,
|
|
633
634
|
partStr,
|
|
@@ -667,13 +668,13 @@ function FindActions(spec) {
|
|
|
667
668
|
pathdesc.why_action = (pathdesc.why_action ?? {});
|
|
668
669
|
const parts = spec.data.work.pathmap[pathStr].parts;
|
|
669
670
|
const fourthLastPart = parts[parts.length - 4];
|
|
670
|
-
const fourthLastPartCanon = (0,
|
|
671
|
+
const fourthLastPartCanon = (0, utility_2.canonize)(fourthLastPart);
|
|
671
672
|
const thirdLastPart = parts[parts.length - 3];
|
|
672
|
-
const thirdLastPartCanon = (0,
|
|
673
|
+
const thirdLastPartCanon = (0, utility_2.canonize)(thirdLastPart);
|
|
673
674
|
const secondLastPart = parts[parts.length - 2];
|
|
674
|
-
const secondLastPartCanon = (0,
|
|
675
|
+
const secondLastPartCanon = (0, utility_2.canonize)(secondLastPart);
|
|
675
676
|
const lastPart = parts[parts.length - 1];
|
|
676
|
-
const lastPartCanon = (0,
|
|
677
|
+
const lastPartCanon = (0, utility_2.canonize)(lastPart);
|
|
677
678
|
const cmp = ment.cmp;
|
|
678
679
|
// /api/foo/bar where foo is the entity and bar is the action, no id param
|
|
679
680
|
if (secondLastPartCanon === cmp
|
|
@@ -701,7 +702,7 @@ function FindActions(spec) {
|
|
|
701
702
|
updateAction(methodName, oldActionName, actionName, entdesc, pathdesc, 'ent-param-3rd-last');
|
|
702
703
|
}
|
|
703
704
|
}
|
|
704
|
-
(0,
|
|
705
|
+
(0, utility_2.debugpath)(pathStr, methodName, 'FIND-ACTIONS', cmp, parts, pathdesc.action, pathdesc.why_action);
|
|
705
706
|
// return pathdesc.action
|
|
706
707
|
}
|
|
707
708
|
function ResolveOperation(spec) {
|
|
@@ -769,7 +770,7 @@ function ResolveOperation(spec) {
|
|
|
769
770
|
else {
|
|
770
771
|
op[methodName.toLowerCase()] = opdef;
|
|
771
772
|
}
|
|
772
|
-
(0,
|
|
773
|
+
(0, utility_2.debugpath)(pathStr, methodName, 'ResolveOperation', standard_opname, opname, why_op, op);
|
|
773
774
|
}
|
|
774
775
|
function ResolveTransform(spec) {
|
|
775
776
|
const mdesc = spec.node.val;
|
|
@@ -790,7 +791,7 @@ function ResolveTransform(spec) {
|
|
|
790
791
|
};
|
|
791
792
|
const resokdef = mdesc.responses?.[200] || mdesc.responses?.[201];
|
|
792
793
|
const resprops = getResponseSchema(resokdef)?.properties;
|
|
793
|
-
(0,
|
|
794
|
+
(0, utility_2.debugpath)(pathStr, methodName, 'TRANSFORM-RES', (0, struct_1.keysof)(resprops));
|
|
794
795
|
if (resprops) {
|
|
795
796
|
// Only unwrap `body.<entity>` when the entity-named response property is
|
|
796
797
|
// itself a structured value (object/array/ref/composed schema) that could
|
|
@@ -798,22 +799,53 @@ function ResolveTransform(spec) {
|
|
|
798
799
|
// entity's name (e.g. an entity `advice` whose own fields include a
|
|
799
800
|
// string field `advice`) is a FIELD of the entity, not a wrapper around
|
|
800
801
|
// it: the response IS the entity, so it must stay `body` (the default).
|
|
801
|
-
if (isEntityWrapperProp(resprops[entdesc.origname])) {
|
|
802
|
+
if ((0, utility_1.isEntityWrapperProp)(resprops[entdesc.origname])) {
|
|
802
803
|
transform.res = '`body.' + entdesc.origname + '`';
|
|
803
804
|
}
|
|
804
|
-
else if (isEntityWrapperProp(resprops[entdesc.name])) {
|
|
805
|
+
else if ((0, utility_1.isEntityWrapperProp)(resprops[entdesc.name])) {
|
|
805
806
|
transform.res = '`body.' + entdesc.name + '`';
|
|
806
807
|
}
|
|
808
|
+
else {
|
|
809
|
+
// The wrapper is often named for the CARDINALITY rather than the
|
|
810
|
+
// entity — `{item: {...}}` from a load, `{items: [...]}` from a list —
|
|
811
|
+
// which the entity-name rules above cannot see. Left unwrapped, list()
|
|
812
|
+
// hands back the envelope where the caller expects an array, and the
|
|
813
|
+
// envelope key is mistaken for a field of the entity.
|
|
814
|
+
const envelope = (0, utility_1.envelopeProp)(resprops, opname);
|
|
815
|
+
if (null != envelope) {
|
|
816
|
+
transform.res = '`body.' + envelope + '`';
|
|
817
|
+
}
|
|
818
|
+
}
|
|
807
819
|
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
820
|
+
// The SCHEMA is what closedBodyTransform needs (it reads
|
|
821
|
+
// additionalProperties); the wrapper-name checks need its PROPERTIES. They
|
|
822
|
+
// used to share one value and index the schema itself, so
|
|
823
|
+
// `schema['todoitem']` was always undefined and the entity-name request
|
|
824
|
+
// envelope was never detected — while the Go port read `.properties` and
|
|
825
|
+
// did detect it. That divergence was inert only because `req` was never
|
|
826
|
+
// serialised; now that it is, the two implementations would emit different
|
|
827
|
+
// request bodies for the same spec.
|
|
828
|
+
const reqschema = getRequestBodySchema(mdesc.requestBody);
|
|
829
|
+
const reqprops = reqschema?.properties;
|
|
830
|
+
(0, utility_2.debugpath)(pathStr, methodName, 'TRANSFORM-REQ', (0, struct_1.keysof)(reqprops));
|
|
831
|
+
if (reqschema) {
|
|
832
|
+
if (null != reqprops?.[entdesc.origname]) {
|
|
812
833
|
transform.req = { [entdesc.origname]: '`reqdata`' };
|
|
813
834
|
}
|
|
814
|
-
else if (reqprops[entdesc.name]) {
|
|
835
|
+
else if (null != reqprops?.[entdesc.name]) {
|
|
815
836
|
transform.req = { [entdesc.name]: '`reqdata`' };
|
|
816
837
|
}
|
|
838
|
+
else {
|
|
839
|
+
// A CLOSED body schema names every property the server will accept, so
|
|
840
|
+
// the body is those properties — not the whole request payload. The
|
|
841
|
+
// payload also carries the op's PATH params (`id` for
|
|
842
|
+
// `PUT /item/{id}`), and a closed shape rejects the entire request over
|
|
843
|
+
// that one extra key: every update came back 400 with `invalid-data`.
|
|
844
|
+
const body = (0, utility_1.closedBodyTransform)(reqschema);
|
|
845
|
+
if (null != body) {
|
|
846
|
+
transform.req = body;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
817
849
|
}
|
|
818
850
|
if (!(0, struct_1.isempty)(transform) && null != op[opname]) {
|
|
819
851
|
op[opname].transform = transform;
|
|
@@ -857,7 +889,7 @@ function entityPathMatch_tpte(data, pm, mdesc, why) {
|
|
|
857
889
|
const pathNameIndex = 2;
|
|
858
890
|
why.push('path=t/p/t/');
|
|
859
891
|
const origPathName = pm[pathNameIndex];
|
|
860
|
-
let entname = (0,
|
|
892
|
+
let entname = (0, utility_2.canonize)(origPathName);
|
|
861
893
|
let ecm = undefined;
|
|
862
894
|
if (null != ment.cmp) {
|
|
863
895
|
ecm = entityCmpMatch(data, entname, mdesc, why);
|
|
@@ -871,34 +903,34 @@ function entityPathMatch_tpte(data, pm, mdesc, why) {
|
|
|
871
903
|
why.push('prob-ent=' + ecm.orig);
|
|
872
904
|
}
|
|
873
905
|
else if (endsWithCmp(data, pm)) {
|
|
874
|
-
entname = (0,
|
|
906
|
+
entname = (0, utility_2.canonize)((0, struct_1.getelem)(pm, -1));
|
|
875
907
|
why.push('prob-ent-last=' + ecm.orig);
|
|
876
908
|
}
|
|
877
|
-
else if (0 < (0,
|
|
878
|
-
entname = (0,
|
|
909
|
+
else if (0 < (0, utility_2.findPathsWithPrefix)(data, pm.path, { strict: true })) {
|
|
910
|
+
entname = (0, utility_2.canonize)((0, struct_1.getelem)(pm, -1));
|
|
879
911
|
why.push('prob-ent-prefix=' + ecm.orig);
|
|
880
912
|
}
|
|
881
913
|
else {
|
|
882
|
-
entname = (0,
|
|
914
|
+
entname = (0, utility_2.canonize)((0, struct_1.getelem)(pm, -3)) + '_' + entname;
|
|
883
915
|
why.push('prob-ent-part');
|
|
884
916
|
}
|
|
885
917
|
}
|
|
886
918
|
// Probably an entity action suffix
|
|
887
919
|
else {
|
|
888
920
|
why.push('prob-ent-act');
|
|
889
|
-
entname = (0,
|
|
921
|
+
entname = (0, utility_2.canonize)((0, struct_1.getelem)(pm, -3));
|
|
890
922
|
}
|
|
891
923
|
return entname;
|
|
892
924
|
}
|
|
893
925
|
function endsWithCmp(data, pm) {
|
|
894
|
-
const last = (0,
|
|
926
|
+
const last = (0, utility_2.canonize)((0, struct_1.getelem)(pm, -1));
|
|
895
927
|
return isOrigCmp(data, last);
|
|
896
928
|
}
|
|
897
929
|
function isOrigCmp(data, name) {
|
|
898
930
|
return null != data.guide.metrics.count.origcmprefs[name];
|
|
899
931
|
}
|
|
900
932
|
function entityOccursInPath(parts, entname) {
|
|
901
|
-
return parts.some(p => p[0] !== '{' && (0,
|
|
933
|
+
return parts.some(p => p[0] !== '{' && (0, utility_2.canonize)(p.toLowerCase()) === entname);
|
|
902
934
|
}
|
|
903
935
|
function entityPathMatch_tpe(data, pm, mdesc, why) {
|
|
904
936
|
const ment = mdesc.MethodEntity;
|
|
@@ -906,7 +938,7 @@ function entityPathMatch_tpe(data, pm, mdesc, why) {
|
|
|
906
938
|
why.push('path=t/p/');
|
|
907
939
|
const origPathName = pm[pathNameIndex];
|
|
908
940
|
// let entname = fixEntName(origPathName)
|
|
909
|
-
let entname = (0,
|
|
941
|
+
let entname = (0, utility_2.canonize)(origPathName);
|
|
910
942
|
if (null != ment.cmp || probableEntityMethod(data, mdesc, pm, why)) {
|
|
911
943
|
let ecm = entityCmpMatch(data, entname, mdesc, why);
|
|
912
944
|
entname = ecm.name;
|
|
@@ -921,7 +953,7 @@ function entityPathMatch_pte(data, pm, mdesc, why) {
|
|
|
921
953
|
const pathNameIndex = 1;
|
|
922
954
|
why.push('path=p/t/');
|
|
923
955
|
const origPathName = pm[pathNameIndex];
|
|
924
|
-
let entname = (0,
|
|
956
|
+
let entname = (0, utility_2.canonize)(origPathName);
|
|
925
957
|
if (null != ment.cmp || probableEntityMethod(data, mdesc, pm, why)) {
|
|
926
958
|
let ecm = entityCmpMatch(data, entname, mdesc, why);
|
|
927
959
|
entname = ecm.name;
|
|
@@ -937,7 +969,7 @@ function entityPathMatch_te(data, pm, mdesc, why) {
|
|
|
937
969
|
why.push('path=t/');
|
|
938
970
|
const origPathName = pm[pathNameIndex];
|
|
939
971
|
// let entname = fixEntName(origPathName)
|
|
940
|
-
let entname = (0,
|
|
972
|
+
let entname = (0, utility_2.canonize)(origPathName);
|
|
941
973
|
if (null != ment.cmp || probableEntityMethod(data, mdesc, pm, why)) {
|
|
942
974
|
let ecm = entityCmpMatch(data, entname, mdesc, why);
|
|
943
975
|
entname = ecm.name;
|
|
@@ -953,7 +985,7 @@ function entityPathMatch_tpp(data, pm, mdesc, why) {
|
|
|
953
985
|
why.push('path=t/p/p');
|
|
954
986
|
const origPathName = pm[pathNameIndex];
|
|
955
987
|
// let entname = fixEntName(origPathName)
|
|
956
|
-
let entname = (0,
|
|
988
|
+
let entname = (0, utility_2.canonize)(origPathName);
|
|
957
989
|
if (null != ment.cmp || probableEntityMethod(data, mdesc, pm, why)) {
|
|
958
990
|
let ecm = entityCmpMatch(data, entname, mdesc, why);
|
|
959
991
|
entname = ecm.name;
|
|
@@ -971,32 +1003,10 @@ function getResponseSchema(response) {
|
|
|
971
1003
|
return response?.content?.['application/json']?.schema ??
|
|
972
1004
|
response?.schema;
|
|
973
1005
|
}
|
|
974
|
-
// A response property only "wraps" the entity when it is itself a structured
|
|
975
|
-
// value that could contain the entity: an object, an array, a $ref, or a
|
|
976
|
-
// composed (allOf/oneOf/anyOf) schema. A scalar property (string, integer,
|
|
977
|
-
// number, boolean) that merely shares the entity's name is a field of the
|
|
978
|
-
// entity, not a wrapper, so the response must not be unwrapped down to it.
|
|
979
|
-
function isEntityWrapperProp(propSchema) {
|
|
980
|
-
if (null == propSchema || 'object' !== typeof propSchema) {
|
|
981
|
-
return false;
|
|
982
|
-
}
|
|
983
|
-
if (null != propSchema.$ref) {
|
|
984
|
-
return true;
|
|
985
|
-
}
|
|
986
|
-
if (null != propSchema.properties ||
|
|
987
|
-
null != propSchema.items ||
|
|
988
|
-
null != propSchema.allOf ||
|
|
989
|
-
null != propSchema.oneOf ||
|
|
990
|
-
null != propSchema.anyOf) {
|
|
991
|
-
return true;
|
|
992
|
-
}
|
|
993
|
-
const t = propSchema.type;
|
|
994
|
-
return 'object' === t || 'array' === t;
|
|
995
|
-
}
|
|
996
1006
|
function inferEntityName(mdesc, parts, why) {
|
|
997
1007
|
// Try operationId: e.g. "getUser" -> "user", "listProducts" -> "product"
|
|
998
1008
|
if (mdesc.operationId) {
|
|
999
|
-
const opid = (0,
|
|
1009
|
+
const opid = (0, utility_2.canonize)(mdesc.operationId);
|
|
1000
1010
|
if (opid.length >= 3) {
|
|
1001
1011
|
why.push('infer-opid');
|
|
1002
1012
|
return opid;
|
|
@@ -1006,7 +1016,7 @@ function inferEntityName(mdesc, parts, why) {
|
|
|
1006
1016
|
const response = mdesc.responses?.[200] ?? mdesc.responses?.[201];
|
|
1007
1017
|
const resSchema = getResponseSchema(response);
|
|
1008
1018
|
if (resSchema?.title) {
|
|
1009
|
-
const title = (0,
|
|
1019
|
+
const title = (0, utility_2.canonize)(resSchema.title);
|
|
1010
1020
|
if (title.length >= 3) {
|
|
1011
1021
|
why.push('infer-res-title');
|
|
1012
1022
|
return title;
|
|
@@ -1015,7 +1025,7 @@ function inferEntityName(mdesc, parts, why) {
|
|
|
1015
1025
|
// Try last non-param path segment
|
|
1016
1026
|
for (let i = parts.length - 1; i >= 0; i--) {
|
|
1017
1027
|
if (!isParam(parts[i])) {
|
|
1018
|
-
const seg = (0,
|
|
1028
|
+
const seg = (0, utility_2.canonize)(parts[i]);
|
|
1019
1029
|
if (seg.length >= 3) {
|
|
1020
1030
|
why.push('infer-path-seg');
|
|
1021
1031
|
return seg;
|
|
@@ -1043,7 +1053,7 @@ function probableEntityMethod(data, mdesc, pm, why) {
|
|
|
1043
1053
|
&& !pm.expr.endsWith('/p/')
|
|
1044
1054
|
// A real entity would probably occur in at least one other t/p path
|
|
1045
1055
|
// otherwise this is probably an action
|
|
1046
|
-
&& (1 < (0,
|
|
1056
|
+
&& (1 < (0, utility_2.sortedKeys)(data.def.paths).filter(path => path.includes('/' + pm[pm.length - 1] + '/')).length)) {
|
|
1047
1057
|
prob_why = 'post';
|
|
1048
1058
|
probent = true;
|
|
1049
1059
|
}
|
|
@@ -1063,8 +1073,8 @@ function probableEntityMethod(data, mdesc, pm, why) {
|
|
|
1063
1073
|
prob_why = 'get';
|
|
1064
1074
|
probent = true;
|
|
1065
1075
|
}
|
|
1066
|
-
const rescodes = (0,
|
|
1067
|
-
(0,
|
|
1076
|
+
const rescodes = (0, utility_2.sortedKeys)(mdesc.responses ?? {});
|
|
1077
|
+
(0, utility_2.debugpath)(mdesc.path, mdesc.method, 'PROBABLE-ENTITY-RESPONSE', { mdesc, responses: rescodes, probent, prob_why });
|
|
1068
1078
|
why.push('entres=' + probent + '/' + rescodes + ('' === prob_why ? '' : '/' + prob_why));
|
|
1069
1079
|
return probent;
|
|
1070
1080
|
}
|
|
@@ -1118,7 +1128,7 @@ function entityCmpMatch(data, entname, mdesc, why) {
|
|
|
1118
1128
|
else {
|
|
1119
1129
|
why.push('path-primary');
|
|
1120
1130
|
}
|
|
1121
|
-
(0,
|
|
1131
|
+
(0, utility_2.debugpath)(mdesc.path, mdesc.method, 'ENTITY-CMP-NAME', mdesc.path, mdesc.method, entname + '->', out, why, ment, IS_ENTCMP_METHOD_RATE, IS_ENTCMP_PATH_RATE);
|
|
1122
1132
|
return out;
|
|
1123
1133
|
}
|
|
1124
1134
|
function cmpOccursInPath(data, cmpname) {
|
|
@@ -1128,7 +1138,7 @@ function cmpOccursInPath(data, cmpname) {
|
|
|
1128
1138
|
const parts = data.work.pathmap[pathstr].parts;
|
|
1129
1139
|
parts
|
|
1130
1140
|
.filter(p => !p.startsWith('{'))
|
|
1131
|
-
.map(p => data.work.potentialCmpsFromPaths[(0,
|
|
1141
|
+
.map(p => data.work.potentialCmpsFromPaths[(0, utility_2.canonize)(p)] = true);
|
|
1132
1142
|
});
|
|
1133
1143
|
}
|
|
1134
1144
|
return null != data.work.potentialCmpsFromPaths[cmpname];
|
|
@@ -1166,7 +1176,7 @@ function isListResponse(mdesc, pathStr, why) {
|
|
|
1166
1176
|
}
|
|
1167
1177
|
}
|
|
1168
1178
|
}
|
|
1169
|
-
(0,
|
|
1179
|
+
(0, utility_2.debugpath)(pathStr, mdesc.method, 'IS-LIST', islist, why, schema);
|
|
1170
1180
|
return islist;
|
|
1171
1181
|
}
|
|
1172
1182
|
function resolveSchemaProperties(schema) {
|
|
@@ -1185,7 +1195,7 @@ function resolveSchemaProperties(schema) {
|
|
|
1185
1195
|
function updateAction(methodName, oldParam, actionName, entityDesc, pathdesc, why) {
|
|
1186
1196
|
if (
|
|
1187
1197
|
// Entity not already encoding action.
|
|
1188
|
-
!entityDesc.name.endsWith((0,
|
|
1198
|
+
!entityDesc.name.endsWith((0, utility_2.canonize)(actionName))
|
|
1189
1199
|
&& null == pathdesc.action[actionName]) {
|
|
1190
1200
|
pathdesc.action[actionName] = {
|
|
1191
1201
|
// kind: '`$BOOLEAN`',
|
|
@@ -1196,7 +1206,7 @@ function updateAction(methodName, oldParam, actionName, entityDesc, pathdesc, wh
|
|
|
1196
1206
|
function updateParamRename(ctx, data, path, method, paramRenameCapture, oldParamName, newParamName, why) {
|
|
1197
1207
|
const existingNewName = paramRenameCapture.rename[oldParamName];
|
|
1198
1208
|
const existingWhy = paramRenameCapture.why[oldParamName];
|
|
1199
|
-
(0,
|
|
1209
|
+
(0, utility_2.debugpath)(path, method, 'UPDATE-PARAM-RENAME', path, oldParamName, newParamName, existingNewName);
|
|
1200
1210
|
if (null == existingNewName) {
|
|
1201
1211
|
paramRenameCapture.rename[oldParamName] = newParamName;
|
|
1202
1212
|
if (!existingWhy.includes(why)) {
|
|
@@ -1236,7 +1246,7 @@ function findcmps(data, pathStr, underprops, opts) {
|
|
|
1236
1246
|
(0, jostraca_1.each)(data.def.paths[pathStr])
|
|
1237
1247
|
.map((md) => {
|
|
1238
1248
|
underprops.map((up) => {
|
|
1239
|
-
let found = (0,
|
|
1249
|
+
let found = (0, utility_2.find)(md[up], 'x-ref');
|
|
1240
1250
|
found.map((xref) => {
|
|
1241
1251
|
let m = xref.val.match(/\/(components\/schemas|definitions)\/(.+)$/);
|
|
1242
1252
|
if (m) {
|
|
@@ -1246,7 +1256,7 @@ function findcmps(data, pathStr, underprops, opts) {
|
|
|
1246
1256
|
});
|
|
1247
1257
|
});
|
|
1248
1258
|
});
|
|
1249
|
-
return (opts?.uniq ? Array.from(cmpset) : cmplist).map(n => ({ cmp: (0,
|
|
1259
|
+
return (opts?.uniq ? Array.from(cmpset) : cmplist).map(n => ({ cmp: (0, utility_2.canonizeCmpName)(n), origcmp: n }));
|
|
1250
1260
|
}
|
|
1251
1261
|
function makeMethodEntityDesc(desc) {
|
|
1252
1262
|
let ment = {
|
|
@@ -1285,7 +1295,7 @@ function findPotentialSchemaRefs(pathStr, methodName, responses) {
|
|
|
1285
1295
|
}
|
|
1286
1296
|
}
|
|
1287
1297
|
}
|
|
1288
|
-
(0,
|
|
1298
|
+
(0, utility_2.debugpath)(pathStr, methodName, 'POTENTIAL-SCHEMA-REFS', xrefs);
|
|
1289
1299
|
return xrefs;
|
|
1290
1300
|
}
|
|
1291
1301
|
function hasMethod(def, pathStr, methodName) {
|