@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.
Files changed (36) hide show
  1. package/build/src/amf/AmfShapeGenerator.d.ts +1 -1
  2. package/build/src/amf/ApiSchemaGenerator.d.ts +5 -5
  3. package/build/src/amf/ApiSchemaGenerator.js.map +1 -1
  4. package/build/src/amf/ApiSchemaValues.d.ts +6 -0
  5. package/build/src/amf/ApiSchemaValues.js +31 -0
  6. package/build/src/amf/ApiSchemaValues.js.map +1 -1
  7. package/build/src/amf/shape/ShapeBase.d.ts +3 -3
  8. package/build/src/amf/shape/ShapeBase.js +3 -0
  9. package/build/src/amf/shape/ShapeBase.js.map +1 -1
  10. package/build/src/amf/shape/ShapeJsonSchemaGenerator.js +4 -1
  11. package/build/src/amf/shape/ShapeJsonSchemaGenerator.js.map +1 -1
  12. package/build/src/amf/shape/ShapeXmlSchemaGenerator.js +1 -1
  13. package/build/src/amf/shape/ShapeXmlSchemaGenerator.js.map +1 -1
  14. package/build/src/models/data/DataAssociation.d.ts +4 -0
  15. package/build/src/models/data/DataAssociation.js +8 -0
  16. package/build/src/models/data/DataAssociation.js.map +1 -1
  17. package/build/src/models/data/DataEntity.d.ts +16 -12
  18. package/build/src/models/data/DataEntity.js +54 -50
  19. package/build/src/models/data/DataEntity.js.map +1 -1
  20. package/build/src/models/data/DataNamespace.d.ts +14 -0
  21. package/build/src/models/data/DataNamespace.js +50 -0
  22. package/build/src/models/data/DataNamespace.js.map +1 -1
  23. package/package.json +1 -1
  24. package/src/amf/AmfShapeGenerator.ts +1 -1
  25. package/src/amf/ApiSchemaGenerator.ts +5 -5
  26. package/src/amf/ApiSchemaValues.ts +32 -0
  27. package/src/amf/shape/ShapeBase.ts +6 -3
  28. package/src/amf/shape/ShapeJsonSchemaGenerator.ts +4 -1
  29. package/src/amf/shape/ShapeXmlSchemaGenerator.ts +1 -1
  30. package/src/models/data/DataAssociation.ts +9 -0
  31. package/src/models/data/DataEntity.ts +56 -53
  32. package/src/models/data/DataNamespace.ts +54 -0
  33. package/build/src/models/data/DataAssociationSchema.d.ts +0 -68
  34. package/build/src/models/data/DataAssociationSchema.js +0 -2
  35. package/build/src/models/data/DataAssociationSchema.js.map +0 -1
  36. 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._associationGraph();
469
- for (const path of this._associationPath(this.key, toEntity, graph)) {
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
- * The actual implementation of the graph search.
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
- * @param from The current from node
478
- * @param to The target node
479
- * @param g The graph
480
- * @param path The current list of entity ids.
481
- * @param visited The list of visited paths to avoid cycles
482
- */
483
- protected * _associationPath(from: string, to: string, g: Record<string, string[]>, path: string[] = [], visited: Set<string> = new Set()): Generator<string[]> {
484
- if (from === to) {
485
- yield path.concat(to);
486
- return;
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
- protected _associationGraph(): Record<string, string[]> {
509
- const graph: Record<string, string[]> = {};
510
- const { associations, entities } = this.root.definitions;
511
- for (const assoc of associations) {
512
- if (!assoc.targets.length) {
513
- continue;
514
- }
515
- const srcEntity = entities.find(i => i.associations.some(a => a === assoc));
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
- graph[srcEntity.key].splice(0, 0, ...assoc.targets);
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,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=DataAssociationSchema.js.map
@@ -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
- }