@api-client/core 0.6.15 → 0.6.18
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/build/src/amf/AmfShapeGenerator.d.ts +1 -1
- package/build/src/amf/ApiSchemaGenerator.d.ts +5 -5
- package/build/src/amf/ApiSchemaGenerator.js.map +1 -1
- package/build/src/amf/ApiSchemaValues.d.ts +6 -0
- package/build/src/amf/ApiSchemaValues.js +31 -0
- package/build/src/amf/ApiSchemaValues.js.map +1 -1
- package/build/src/amf/shape/ShapeBase.d.ts +3 -3
- package/build/src/amf/shape/ShapeBase.js +3 -0
- package/build/src/amf/shape/ShapeBase.js.map +1 -1
- package/build/src/amf/shape/ShapeJsonSchemaGenerator.js +4 -1
- package/build/src/amf/shape/ShapeJsonSchemaGenerator.js.map +1 -1
- package/build/src/amf/shape/ShapeXmlSchemaGenerator.js +1 -1
- package/build/src/amf/shape/ShapeXmlSchemaGenerator.js.map +1 -1
- package/build/src/models/data/DataAssociation.d.ts +4 -0
- package/build/src/models/data/DataAssociation.js +8 -0
- package/build/src/models/data/DataAssociation.js.map +1 -1
- package/build/src/models/data/DataEntity.d.ts +16 -12
- package/build/src/models/data/DataEntity.js +54 -50
- package/build/src/models/data/DataEntity.js.map +1 -1
- package/build/src/models/data/DataNamespace.d.ts +14 -0
- package/build/src/models/data/DataNamespace.js +50 -0
- package/build/src/models/data/DataNamespace.js.map +1 -1
- package/package.json +1 -1
- package/src/amf/AmfShapeGenerator.ts +1 -1
- package/src/amf/ApiSchemaGenerator.ts +5 -5
- package/src/amf/ApiSchemaValues.ts +32 -0
- package/src/amf/shape/ShapeBase.ts +6 -3
- package/src/amf/shape/ShapeJsonSchemaGenerator.ts +4 -1
- package/src/amf/shape/ShapeXmlSchemaGenerator.ts +1 -1
- package/src/models/data/DataAssociation.ts +9 -0
- package/src/models/data/DataEntity.ts +56 -53
- package/src/models/data/DataNamespace.ts +54 -0
- package/build/src/models/data/DataAssociationSchema.d.ts +0 -68
- package/build/src/models/data/DataAssociationSchema.js +0 -2
- package/build/src/models/data/DataAssociationSchema.js.map +0 -1
- package/src/models/data/DataAssociationSchema.ts +0 -70
|
@@ -8,6 +8,7 @@ import { DataModel } from "./DataModel.js";
|
|
|
8
8
|
import { INodeShape, IShapeUnion } from "../../amf/definitions/Shapes.js";
|
|
9
9
|
import { AmfShapeGenerator } from "../../amf/AmfShapeGenerator.js";
|
|
10
10
|
import { ApiSchemaGenerator } from "../../amf/ApiSchemaGenerator.js";
|
|
11
|
+
import { IShapeRenderOptions } from "../../amf/shape/ShapeBase.js";
|
|
11
12
|
|
|
12
13
|
export const Kind = 'Core#DataEntity';
|
|
13
14
|
|
|
@@ -465,63 +466,38 @@ export class DataEntity {
|
|
|
465
466
|
* @yields The path containing keys of entities from this entity to the `toEntity` (inclusive) and all entities in between.
|
|
466
467
|
*/
|
|
467
468
|
* associationPath(toEntity: string): Generator<string[]> {
|
|
468
|
-
const graph = this.
|
|
469
|
-
for (const path of this.
|
|
469
|
+
const graph = this.root.associationGraph();
|
|
470
|
+
for (const path of this.root.associationPath(this.key, toEntity, graph)) {
|
|
470
471
|
yield path;
|
|
471
472
|
}
|
|
472
473
|
}
|
|
473
474
|
|
|
474
475
|
/**
|
|
475
|
-
*
|
|
476
|
+
* Returns a list of entities that are association with this entity through an association
|
|
477
|
+
* that the target property points to this entity.
|
|
476
478
|
*
|
|
477
|
-
*
|
|
478
|
-
*
|
|
479
|
-
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
}
|
|
488
|
-
if (visited.has(from)) {
|
|
489
|
-
// it's a cycle
|
|
490
|
-
return;
|
|
491
|
-
}
|
|
492
|
-
if (g[from]) {
|
|
493
|
-
visited.add(from);
|
|
494
|
-
path.push(from);
|
|
495
|
-
|
|
496
|
-
for (const neighbor of g[from]) {
|
|
497
|
-
yield *this._associationPath(neighbor, to, g, path, visited);
|
|
498
|
-
}
|
|
499
|
-
|
|
500
|
-
visited.delete(from);
|
|
501
|
-
path.pop();
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
/**
|
|
506
|
-
* @returns The graph of associations where keys are the source entities and the value is the list of all target entities.
|
|
479
|
+
* In other words, if entity `A` has association target with `B`, then asking `B` for related entities will
|
|
480
|
+
* result with `[A]`.
|
|
481
|
+
*
|
|
482
|
+
* ```plain
|
|
483
|
+
* A -> B -> C
|
|
484
|
+
* D -> C
|
|
485
|
+
*
|
|
486
|
+
* C => [B, D]
|
|
487
|
+
* B => [A, C]
|
|
488
|
+
* ```
|
|
507
489
|
*/
|
|
508
|
-
|
|
509
|
-
const
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
if (!srcEntity) {
|
|
517
|
-
continue;
|
|
518
|
-
}
|
|
519
|
-
if (!graph[srcEntity.key]) {
|
|
520
|
-
graph[srcEntity.key] = [];
|
|
490
|
+
getRelatedEntities(): DataEntity[] {
|
|
491
|
+
const { key, root } = this;
|
|
492
|
+
const result: DataEntity[] = [];
|
|
493
|
+
const inverse = root.definitions.associations.filter(i => i.targets.includes(key));
|
|
494
|
+
inverse.forEach((assoc) => {
|
|
495
|
+
const entity = root.definitions.entities.find(e => e.associations.includes(assoc));
|
|
496
|
+
if (entity) {
|
|
497
|
+
result.push(entity);
|
|
521
498
|
}
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
return graph;
|
|
499
|
+
});
|
|
500
|
+
return result;
|
|
525
501
|
}
|
|
526
502
|
|
|
527
503
|
/**
|
|
@@ -617,12 +593,13 @@ export class DataEntity {
|
|
|
617
593
|
/**
|
|
618
594
|
* Reads the schema of the Entity and generates an example for it.
|
|
619
595
|
*/
|
|
620
|
-
toExample(mime: string): string | number | boolean | null | undefined {
|
|
596
|
+
toExample(mime: string, opts: IShapeRenderOptions = {}): string | number | boolean | null | undefined {
|
|
621
597
|
const shape = this.toApiShape();
|
|
622
598
|
const generator = new ApiSchemaGenerator(mime, {
|
|
623
|
-
renderExamples: true,
|
|
624
|
-
renderMocked: true,
|
|
625
|
-
renderOptional: true,
|
|
599
|
+
renderExamples: typeof opts.renderExamples === 'boolean' ? opts.renderExamples : true,
|
|
600
|
+
renderMocked: typeof opts.renderMocked === 'boolean' ? opts.renderMocked : true,
|
|
601
|
+
renderOptional: typeof opts.renderOptional === 'boolean' ? opts.renderOptional : true,
|
|
602
|
+
selectedUnions: opts.selectedUnions,
|
|
626
603
|
});
|
|
627
604
|
return generator.generate(shape);
|
|
628
605
|
}
|
|
@@ -650,4 +627,30 @@ export class DataEntity {
|
|
|
650
627
|
this.adapts = entity.key;
|
|
651
628
|
return entity;
|
|
652
629
|
}
|
|
630
|
+
|
|
631
|
+
hasClosedCycle(rootEntity: string, targetEntity: string): boolean {
|
|
632
|
+
if (targetEntity === this.key) {
|
|
633
|
+
// self association
|
|
634
|
+
return true;
|
|
635
|
+
}
|
|
636
|
+
const g = this.root.associationGraph();
|
|
637
|
+
const selfPaths: string[][] = [];
|
|
638
|
+
const targetPaths: string[][] = [];
|
|
639
|
+
for (const path of this.root.associationPath(rootEntity, this.key, g)) {
|
|
640
|
+
selfPaths.push(path);
|
|
641
|
+
}
|
|
642
|
+
for (const path of this.root.associationPath(targetEntity, this.key, g)) {
|
|
643
|
+
targetPaths.push(path);
|
|
644
|
+
}
|
|
645
|
+
const checker = (arr: string[], target: string[]): boolean => target.every(v => arr.includes(v));
|
|
646
|
+
for (const sp of selfPaths) {
|
|
647
|
+
for (const tp of targetPaths) {
|
|
648
|
+
const result = checker(sp, tp);
|
|
649
|
+
if (result) {
|
|
650
|
+
return result;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
return false;
|
|
655
|
+
}
|
|
653
656
|
}
|
|
@@ -534,4 +534,58 @@ export class DataNamespace extends DataNamespaceParent {
|
|
|
534
534
|
model.remove();
|
|
535
535
|
}
|
|
536
536
|
}
|
|
537
|
+
|
|
538
|
+
/**
|
|
539
|
+
* @returns The graph of associations where keys are the source entities and the value is the list of all target entities.
|
|
540
|
+
*/
|
|
541
|
+
associationGraph(): Record<string, string[]> {
|
|
542
|
+
const graph: Record<string, string[]> = {};
|
|
543
|
+
const { definitions } = this.root || this;
|
|
544
|
+
const { associations, entities } = definitions;
|
|
545
|
+
for (const assoc of associations) {
|
|
546
|
+
if (!assoc.targets.length) {
|
|
547
|
+
continue;
|
|
548
|
+
}
|
|
549
|
+
const srcEntity = entities.find(i => i.associations.some(a => a === assoc));
|
|
550
|
+
if (!srcEntity) {
|
|
551
|
+
continue;
|
|
552
|
+
}
|
|
553
|
+
if (!graph[srcEntity.key]) {
|
|
554
|
+
graph[srcEntity.key] = [];
|
|
555
|
+
}
|
|
556
|
+
graph[srcEntity.key].splice(0, 0, ...assoc.targets);
|
|
557
|
+
}
|
|
558
|
+
return graph;
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Prints out all associations from one entity to another through all entities that may be in between.
|
|
563
|
+
*
|
|
564
|
+
* @param from The key of the from entity
|
|
565
|
+
* @param to The key of the target entity
|
|
566
|
+
* @param g The graph generated with `associationGraph()`
|
|
567
|
+
* @param path The current list of entity ids. Do not set this, it is for the recursive processing of the graph.
|
|
568
|
+
* @param visited The list of visited paths to avoid cycles. Do not set this, it is for the recursive processing of the graph.
|
|
569
|
+
*/
|
|
570
|
+
* associationPath(from: string, to: string, g: Record<string, string[]>, path: string[] = [], visited: Set<string> = new Set()): Generator<string[]> {
|
|
571
|
+
if (from === to) {
|
|
572
|
+
yield path.concat(to);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
if (visited.has(from)) {
|
|
576
|
+
// it's a cycle
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
if (g[from]) {
|
|
580
|
+
visited.add(from);
|
|
581
|
+
path.push(from);
|
|
582
|
+
|
|
583
|
+
for (const neighbor of g[from]) {
|
|
584
|
+
yield *this.associationPath(neighbor, to, g, path, visited);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
visited.delete(from);
|
|
588
|
+
path.pop();
|
|
589
|
+
}
|
|
590
|
+
}
|
|
537
591
|
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
export interface IDataAssociationSchema {
|
|
2
|
-
/**
|
|
3
|
-
* Whether the target entity should be embedded under the property name.
|
|
4
|
-
* When false, this association is just an information that one entity depend on another.
|
|
5
|
-
* When true, it changes the definition of the schema having this association to
|
|
6
|
-
* add the target schema properties inline with this property.
|
|
7
|
-
*
|
|
8
|
-
* **When true**
|
|
9
|
-
*
|
|
10
|
-
* ```javascript
|
|
11
|
-
* // generated schema for `address` association
|
|
12
|
-
* {
|
|
13
|
-
* "name": "example value",
|
|
14
|
-
* "address": {
|
|
15
|
-
* "city": "example value",
|
|
16
|
-
* ...
|
|
17
|
-
* }
|
|
18
|
-
* }
|
|
19
|
-
* ```
|
|
20
|
-
*
|
|
21
|
-
* **When false**
|
|
22
|
-
*
|
|
23
|
-
* ```javascript
|
|
24
|
-
* // generated schema for `address` association
|
|
25
|
-
* {
|
|
26
|
-
* "name": "example value",
|
|
27
|
-
* "address": "the key of the referenced schema"
|
|
28
|
-
* }
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
embedded?: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Describes XML specific serialization.
|
|
34
|
-
*/
|
|
35
|
-
xml?: {
|
|
36
|
-
/**
|
|
37
|
-
* The name of the attribute or a wrapped property to use when serializing the property.
|
|
38
|
-
*
|
|
39
|
-
* ```
|
|
40
|
-
* <Person fullName="John Doe"></Person>
|
|
41
|
-
* ```
|
|
42
|
-
*/
|
|
43
|
-
name?: string;
|
|
44
|
-
/**
|
|
45
|
-
* When the property is an array (has the `multiple` set to true)
|
|
46
|
-
* then it tells that the list of values should be wrapped with a parent
|
|
47
|
-
* element:
|
|
48
|
-
*
|
|
49
|
-
* ```
|
|
50
|
-
* <Person>
|
|
51
|
-
* <Person fullName="John Doe"></Person>
|
|
52
|
-
* </Person>
|
|
53
|
-
* ```
|
|
54
|
-
*
|
|
55
|
-
* Use this with the combination with `name` to describe the name of the wrapped
|
|
56
|
-
* element
|
|
57
|
-
*
|
|
58
|
-
* ```
|
|
59
|
-
* <people>
|
|
60
|
-
* <Person fullName="John Doe"></Person>
|
|
61
|
-
* </people>
|
|
62
|
-
* ```
|
|
63
|
-
*
|
|
64
|
-
* Note, this is mutually exclusive with `attribute`.
|
|
65
|
-
*/
|
|
66
|
-
wrapped?: boolean;
|
|
67
|
-
};
|
|
68
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"DataAssociationSchema.js","sourceRoot":"","sources":["../../../../src/models/data/DataAssociationSchema.ts"],"names":[],"mappings":""}
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
export interface IDataAssociationSchema {
|
|
2
|
-
/**
|
|
3
|
-
* Whether the target entity should be embedded under the property name.
|
|
4
|
-
* When false, this association is just an information that one entity depend on another.
|
|
5
|
-
* When true, it changes the definition of the schema having this association to
|
|
6
|
-
* add the target schema properties inline with this property.
|
|
7
|
-
*
|
|
8
|
-
* **When true**
|
|
9
|
-
*
|
|
10
|
-
* ```javascript
|
|
11
|
-
* // generated schema for `address` association
|
|
12
|
-
* {
|
|
13
|
-
* "name": "example value",
|
|
14
|
-
* "address": {
|
|
15
|
-
* "city": "example value",
|
|
16
|
-
* ...
|
|
17
|
-
* }
|
|
18
|
-
* }
|
|
19
|
-
* ```
|
|
20
|
-
*
|
|
21
|
-
* **When false**
|
|
22
|
-
*
|
|
23
|
-
* ```javascript
|
|
24
|
-
* // generated schema for `address` association
|
|
25
|
-
* {
|
|
26
|
-
* "name": "example value",
|
|
27
|
-
* "address": "the key of the referenced schema"
|
|
28
|
-
* }
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
embedded?: boolean;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Describes XML specific serialization.
|
|
35
|
-
*/
|
|
36
|
-
xml?: {
|
|
37
|
-
/**
|
|
38
|
-
* The name of the attribute or a wrapped property to use when serializing the property.
|
|
39
|
-
*
|
|
40
|
-
* ```
|
|
41
|
-
* <Person fullName="John Doe"></Person>
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
name?: string;
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* When the property is an array (has the `multiple` set to true)
|
|
48
|
-
* then it tells that the list of values should be wrapped with a parent
|
|
49
|
-
* element:
|
|
50
|
-
*
|
|
51
|
-
* ```
|
|
52
|
-
* <Person>
|
|
53
|
-
* <Person fullName="John Doe"></Person>
|
|
54
|
-
* </Person>
|
|
55
|
-
* ```
|
|
56
|
-
*
|
|
57
|
-
* Use this with the combination with `name` to describe the name of the wrapped
|
|
58
|
-
* element
|
|
59
|
-
*
|
|
60
|
-
* ```
|
|
61
|
-
* <people>
|
|
62
|
-
* <Person fullName="John Doe"></Person>
|
|
63
|
-
* </people>
|
|
64
|
-
* ```
|
|
65
|
-
*
|
|
66
|
-
* Note, this is mutually exclusive with `attribute`.
|
|
67
|
-
*/
|
|
68
|
-
wrapped?: boolean;
|
|
69
|
-
}
|
|
70
|
-
}
|