@api-client/core 0.11.11 → 0.12.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/Testing.md +1 -1
- package/bin/plugins/events/EventPlugin.ts +61 -0
- package/bin/plugins/events/assert.ts +193 -0
- package/bin/plugins/events/types.ts +6 -0
- package/bin/test.ts +8 -1
- package/build/src/amf/AmfShapeGenerator.d.ts +6 -3
- package/build/src/amf/AmfShapeGenerator.d.ts.map +1 -1
- package/build/src/amf/AmfShapeGenerator.js +4 -1
- package/build/src/amf/AmfShapeGenerator.js.map +1 -1
- package/build/src/amf/AmfTypes.d.ts +2 -2
- package/build/src/amf/AmfTypes.d.ts.map +1 -1
- package/build/src/amf/AmfTypes.js.map +1 -1
- package/build/src/amf/DataValueGenerator.d.ts +15 -15
- package/build/src/amf/DataValueGenerator.d.ts.map +1 -1
- package/build/src/amf/DataValueGenerator.js +14 -14
- package/build/src/amf/DataValueGenerator.js.map +1 -1
- package/build/src/browser.d.ts +12 -9
- package/build/src/browser.d.ts.map +1 -1
- package/build/src/browser.js +11 -8
- package/build/src/browser.js.map +1 -1
- package/build/src/exceptions/attach_exception.d.ts +11 -0
- package/build/src/exceptions/attach_exception.d.ts.map +1 -0
- package/build/src/exceptions/attach_exception.js +11 -0
- package/build/src/exceptions/attach_exception.js.map +1 -0
- package/build/src/exceptions/detach_exception.d.ts +11 -0
- package/build/src/exceptions/detach_exception.d.ts.map +1 -0
- package/build/src/exceptions/detach_exception.js +11 -0
- package/build/src/exceptions/detach_exception.js.map +1 -0
- package/build/src/exceptions/remove_model_exception.d.ts +8 -0
- package/build/src/exceptions/remove_model_exception.d.ts.map +1 -0
- package/build/src/exceptions/remove_model_exception.js +8 -0
- package/build/src/exceptions/remove_model_exception.js.map +1 -0
- package/build/src/exceptions/remove_namespace_exception.d.ts +8 -0
- package/build/src/exceptions/remove_namespace_exception.d.ts.map +1 -0
- package/build/src/exceptions/remove_namespace_exception.js +8 -0
- package/build/src/exceptions/remove_namespace_exception.js.map +1 -0
- package/build/src/index.d.ts +12 -9
- package/build/src/index.d.ts.map +1 -1
- package/build/src/index.js +11 -8
- package/build/src/index.js.map +1 -1
- package/build/src/legacy.d.ts +8 -0
- package/build/src/legacy.d.ts.map +1 -1
- package/build/src/legacy.js +9 -0
- package/build/src/legacy.js.map +1 -1
- package/build/src/modeling/Bindings.d.ts +2 -2
- package/build/src/modeling/Bindings.d.ts.map +1 -1
- package/build/src/modeling/Bindings.js.map +1 -1
- package/build/src/modeling/DataDomain.d.ts +601 -0
- package/build/src/modeling/DataDomain.d.ts.map +1 -0
- package/build/src/modeling/DataDomain.js +1142 -0
- package/build/src/modeling/DataDomain.js.map +1 -0
- package/build/src/modeling/DataFormat.d.ts +42 -41
- package/build/src/modeling/DataFormat.d.ts.map +1 -1
- package/build/src/modeling/DataFormat.js +30 -131
- package/build/src/modeling/DataFormat.js.map +1 -1
- package/build/src/modeling/DomainAssociation.d.ts +281 -0
- package/build/src/modeling/DomainAssociation.d.ts.map +1 -0
- package/build/src/modeling/DomainAssociation.js +440 -0
- package/build/src/modeling/DomainAssociation.js.map +1 -0
- package/build/src/modeling/DomainElement.d.ts +33 -0
- package/build/src/modeling/DomainElement.d.ts.map +1 -0
- package/build/src/modeling/DomainElement.js +32 -0
- package/build/src/modeling/DomainElement.js.map +1 -0
- package/build/src/modeling/DomainEntity.d.ts +383 -0
- package/build/src/modeling/DomainEntity.d.ts.map +1 -0
- package/build/src/modeling/DomainEntity.js +718 -0
- package/build/src/modeling/DomainEntity.js.map +1 -0
- package/build/src/modeling/DomainFile.d.ts +25 -0
- package/build/src/modeling/DomainFile.d.ts.map +1 -0
- package/build/src/modeling/DomainFile.js +86 -0
- package/build/src/modeling/DomainFile.js.map +1 -0
- package/build/src/modeling/DomainImpactAnalysis.d.ts +60 -47
- package/build/src/modeling/DomainImpactAnalysis.d.ts.map +1 -1
- package/build/src/modeling/DomainImpactAnalysis.js +201 -132
- package/build/src/modeling/DomainImpactAnalysis.js.map +1 -1
- package/build/src/modeling/DomainModel.d.ts +226 -0
- package/build/src/modeling/DomainModel.d.ts.map +1 -0
- package/build/src/modeling/DomainModel.js +401 -0
- package/build/src/modeling/DomainModel.js.map +1 -0
- package/build/src/modeling/DomainNamespace.d.ts +268 -0
- package/build/src/modeling/DomainNamespace.d.ts.map +1 -0
- package/build/src/modeling/DomainNamespace.js +512 -0
- package/build/src/modeling/DomainNamespace.js.map +1 -0
- package/build/src/modeling/DomainProperty.d.ts +281 -0
- package/build/src/modeling/DomainProperty.d.ts.map +1 -0
- package/build/src/modeling/DomainProperty.js +560 -0
- package/build/src/modeling/DomainProperty.js.map +1 -0
- package/build/src/modeling/DomainSerialization.d.ts +40 -0
- package/build/src/modeling/DomainSerialization.d.ts.map +1 -0
- package/build/src/modeling/DomainSerialization.js +288 -0
- package/build/src/modeling/DomainSerialization.js.map +1 -0
- package/build/src/modeling/DomainVersioning.d.ts +17 -0
- package/build/src/modeling/DomainVersioning.d.ts.map +1 -0
- package/build/src/modeling/DomainVersioning.js +124 -0
- package/build/src/modeling/DomainVersioning.js.map +1 -0
- package/build/src/modeling/GraphUtils.d.ts +8 -0
- package/build/src/modeling/GraphUtils.d.ts.map +1 -0
- package/build/src/modeling/GraphUtils.js +26 -0
- package/build/src/modeling/GraphUtils.js.map +1 -0
- package/build/src/modeling/amf/ShapeGenerator.d.ts +164 -0
- package/build/src/modeling/amf/ShapeGenerator.d.ts.map +1 -0
- package/build/src/modeling/amf/ShapeGenerator.js +492 -0
- package/build/src/modeling/amf/ShapeGenerator.js.map +1 -0
- package/build/src/modeling/{DataAssociation.d.ts → legacy/DataAssociation.d.ts} +10 -5
- package/build/src/modeling/legacy/DataAssociation.d.ts.map +1 -0
- package/build/src/modeling/{DataAssociation.js → legacy/DataAssociation.js} +9 -6
- package/build/src/modeling/legacy/DataAssociation.js.map +1 -0
- package/build/src/modeling/{DataEntity.d.ts → legacy/DataEntity.d.ts} +12 -7
- package/build/src/modeling/legacy/DataEntity.d.ts.map +1 -0
- package/build/src/modeling/{DataEntity.js → legacy/DataEntity.js} +19 -18
- package/build/src/modeling/legacy/DataEntity.js.map +1 -0
- package/build/src/modeling/{DataEntityBuilder.d.ts → legacy/DataEntityBuilder.d.ts} +3 -2
- package/build/src/modeling/legacy/DataEntityBuilder.d.ts.map +1 -0
- package/build/src/modeling/{DataEntityBuilder.js → legacy/DataEntityBuilder.js} +3 -2
- package/build/src/modeling/legacy/DataEntityBuilder.js.map +1 -0
- package/build/src/modeling/legacy/DataImpactAnalysis.d.ts +298 -0
- package/build/src/modeling/legacy/DataImpactAnalysis.d.ts.map +1 -0
- package/build/src/modeling/legacy/DataImpactAnalysis.js +441 -0
- package/build/src/modeling/legacy/DataImpactAnalysis.js.map +1 -0
- package/build/src/modeling/{DataModel.d.ts → legacy/DataModel.d.ts} +6 -4
- package/build/src/modeling/legacy/DataModel.d.ts.map +1 -0
- package/build/src/modeling/{DataModel.js → legacy/DataModel.js} +7 -6
- package/build/src/modeling/legacy/DataModel.js.map +1 -0
- package/build/src/modeling/{DataNamespace.d.ts → legacy/DataNamespace.d.ts} +22 -3
- package/build/src/modeling/legacy/DataNamespace.d.ts.map +1 -0
- package/build/src/modeling/{DataNamespace.js → legacy/DataNamespace.js} +7 -3
- package/build/src/modeling/legacy/DataNamespace.js.map +1 -0
- package/build/src/modeling/{DataProperty.d.ts → legacy/DataProperty.d.ts} +13 -5
- package/build/src/modeling/legacy/DataProperty.d.ts.map +1 -0
- package/build/src/modeling/{DataProperty.js → legacy/DataProperty.js} +8 -5
- package/build/src/modeling/legacy/DataProperty.js.map +1 -0
- package/build/src/modeling/observed.d.ts +67 -0
- package/build/src/modeling/observed.d.ts.map +1 -0
- package/build/src/modeling/observed.js +230 -0
- package/build/src/modeling/observed.js.map +1 -0
- package/build/src/modeling/types.d.ts +165 -1
- package/build/src/modeling/types.d.ts.map +1 -1
- package/build/src/modeling/types.js.map +1 -1
- package/build/src/models/Thing.d.ts +26 -5
- package/build/src/models/Thing.d.ts.map +1 -1
- package/build/src/models/Thing.js +193 -91
- package/build/src/models/Thing.js.map +1 -1
- package/build/src/models/kinds.d.ts +31 -6
- package/build/src/models/kinds.d.ts.map +1 -1
- package/build/src/models/kinds.js +31 -6
- package/build/src/models/kinds.js.map +1 -1
- package/build/src/models/store/DataFile.d.ts +3 -1
- package/build/src/models/store/DataFile.d.ts.map +1 -1
- package/build/src/models/store/DataFile.js +2 -0
- package/build/src/models/store/DataFile.js.map +1 -1
- package/build/src/models/types.d.ts +12 -0
- package/build/src/models/types.d.ts.map +1 -0
- package/build/src/models/types.js +2 -0
- package/build/src/models/types.js.map +1 -0
- package/build/src/runtime/store/FilesSdk.d.ts +2 -2
- package/build/src/runtime/store/FilesSdk.d.ts.map +1 -1
- package/build/src/runtime/store/FilesSdk.js.map +1 -1
- package/data/models/example-generator-api.json +16 -16
- package/package.json +20 -6
- package/readme.md +1 -1
- package/src/amf/AmfShapeGenerator.ts +7 -4
- package/src/amf/AmfTypes.ts +2 -2
- package/src/amf/DataValueGenerator.ts +21 -21
- package/src/exceptions/attach_exception.ts +11 -0
- package/src/exceptions/detach_exception.ts +11 -0
- package/src/exceptions/remove_model_exception.ts +8 -0
- package/src/exceptions/remove_namespace_exception.ts +8 -0
- package/src/modeling/Bindings.ts +2 -2
- package/src/modeling/DataDomain.ts +1221 -0
- package/src/modeling/DataFormat.ts +54 -163
- package/src/modeling/DomainAssociation.ts +476 -0
- package/src/modeling/DomainElement.ts +50 -0
- package/src/modeling/DomainEntity.ts +769 -0
- package/src/modeling/DomainFile.ts +94 -0
- package/src/modeling/DomainImpactAnalysis.ts +218 -144
- package/src/modeling/DomainModel.ts +421 -0
- package/src/modeling/DomainNamespace.ts +537 -0
- package/src/modeling/DomainProperty.ts +548 -0
- package/src/modeling/DomainSerialization.ts +312 -0
- package/src/modeling/DomainVersioning.ts +144 -0
- package/src/modeling/GraphUtils.ts +28 -0
- package/src/modeling/amf/ShapeGenerator.ts +552 -0
- package/src/modeling/graph.md +115 -0
- package/src/modeling/{DataAssociation.ts → legacy/DataAssociation.ts} +13 -8
- package/src/modeling/{DataEntity.ts → legacy/DataEntity.ts} +28 -23
- package/src/modeling/{DataEntityBuilder.ts → legacy/DataEntityBuilder.ts} +4 -3
- package/src/modeling/legacy/DataImpactAnalysis.ts +530 -0
- package/src/modeling/{DataModel.ts → legacy/DataModel.ts} +10 -8
- package/src/modeling/{DataNamespace.ts → legacy/DataNamespace.ts} +23 -5
- package/src/modeling/{DataProperty.ts → legacy/DataProperty.ts} +15 -7
- package/src/modeling/observed.ts +267 -0
- package/src/modeling/types.ts +174 -1
- package/src/models/Thing.ts +70 -5
- package/src/models/kinds.ts +32 -6
- package/src/models/store/DataFile.ts +3 -1
- package/src/models/types.ts +11 -0
- package/src/runtime/store/FilesSdk.ts +2 -2
- package/tests/unit/amf/data_value_generator.spec.ts +15 -15
- package/tests/unit/legacy-transformers/ARC-legacy-import.spec.ts +1 -1
- package/tests/unit/modeling/amf/shape_generator.spec.ts +1174 -0
- package/tests/unit/modeling/data_domain.spec.ts +444 -0
- package/tests/unit/modeling/data_domain_associations.spec.ts +279 -0
- package/tests/unit/modeling/data_domain_change_observers.spec.ts +681 -0
- package/tests/unit/modeling/data_domain_entities.spec.ts +449 -0
- package/tests/unit/modeling/data_domain_foreign.spec.ts +355 -0
- package/tests/unit/modeling/data_domain_models.spec.ts +658 -0
- package/tests/unit/modeling/data_domain_namespaces.spec.ts +668 -0
- package/tests/unit/modeling/data_domain_property.spec.ts +264 -0
- package/tests/unit/modeling/data_domain_serialization.spec.ts +294 -0
- package/tests/unit/modeling/domain.property.spec.ts +822 -0
- package/tests/unit/modeling/domain_asociation.spec.ts +643 -0
- package/tests/unit/modeling/domain_asociation_targets.spec.ts +350 -0
- package/tests/unit/modeling/domain_entity.spec.ts +730 -0
- package/tests/unit/modeling/domain_entity_associations.spec.ts +330 -0
- package/tests/unit/modeling/domain_entity_example_generator_json.spec.ts +988 -0
- package/tests/unit/modeling/domain_entity_example_generator_xml.spec.ts +1451 -0
- package/tests/unit/modeling/domain_entity_fields.spec.ts +113 -0
- package/tests/unit/modeling/domain_entity_generators.spec.ts +20 -0
- package/tests/unit/modeling/domain_entity_parents.spec.ts +291 -0
- package/tests/unit/modeling/domain_entity_properties.spec.ts +305 -0
- package/tests/unit/modeling/{data_file.spec.ts → domain_file.spec.ts} +29 -85
- package/tests/unit/modeling/domain_impact_analysis.spec.ts +452 -0
- package/tests/unit/modeling/domain_model.spec.ts +568 -0
- package/tests/unit/modeling/domain_model_entities.spec.ts +408 -0
- package/tests/unit/modeling/domain_namespace.spec.ts +514 -0
- package/tests/unit/modeling/domain_namespace_models.spec.ts +324 -0
- package/tests/unit/modeling/domain_namespace_namespaces.spec.ts +404 -0
- package/tests/unit/modeling/domain_versioning.spec.ts +140 -0
- package/tests/unit/{amf → modeling/legacy}/amf_shape_generator.spec.ts +11 -11
- package/tests/unit/modeling/{data_association.spec.ts → legacy/data_association.spec.ts} +3 -11
- package/tests/unit/modeling/{data_entity.spec.ts → legacy/data_entity.spec.ts} +10 -8
- package/tests/unit/modeling/{data_entity_generator_json.spec.ts → legacy/data_entity_generator_json.spec.ts} +1 -1
- package/tests/unit/modeling/{data_entity_generator_xml.spec.ts → legacy/data_entity_generator_xml.spec.ts} +1 -1
- package/tests/unit/modeling/{data_model.spec.ts → legacy/data_model.spec.ts} +3 -3
- package/tests/unit/modeling/{data_namespace.spec.ts → legacy/data_namespace.spec.ts} +3 -10
- package/tests/unit/modeling/{data_property.spec.ts → legacy/data_property.spec.ts} +3 -6
- package/tests/unit/modeling/{impact_analysis.spec.ts → legacy/impact_analysis.spec.ts} +9 -9
- package/tests/unit/models/File/new.spec.ts +1 -1
- package/tests/unit/models/HttpProject.spec.ts +3 -3
- package/tsconfig.node.json +35 -0
- package/build/src/modeling/DataAssociation.d.ts.map +0 -1
- package/build/src/modeling/DataAssociation.js.map +0 -1
- package/build/src/modeling/DataEntity.d.ts.map +0 -1
- package/build/src/modeling/DataEntity.js.map +0 -1
- package/build/src/modeling/DataEntityBuilder.d.ts.map +0 -1
- package/build/src/modeling/DataEntityBuilder.js.map +0 -1
- package/build/src/modeling/DataModel.d.ts.map +0 -1
- package/build/src/modeling/DataModel.js.map +0 -1
- package/build/src/modeling/DataNamespace.d.ts.map +0 -1
- package/build/src/modeling/DataNamespace.js.map +0 -1
- package/build/src/modeling/DataProperty.d.ts.map +0 -1
- package/build/src/modeling/DataProperty.js.map +0 -1
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { type PropertyWebBindings } from '../Bindings.js';
|
|
2
|
+
import type { DomainAssociation } from '../DomainAssociation.js';
|
|
3
|
+
import type { DomainProperty } from '../DomainProperty.js';
|
|
4
|
+
import type { DomainEntity } from '../DomainEntity.js';
|
|
5
|
+
import { IApiAnyShape, IApiArrayShape, IApiDataExample, IApiFileShape, IApiNodeShape, IApiPropertyShape, IApiRecursiveShape, IApiScalarShape, IApiShape, IApiUnionShape, IShapeUnion } from '../../amf/definitions/Shapes.js';
|
|
6
|
+
import { DataValueGenerator } from '../../amf/DataValueGenerator.js';
|
|
7
|
+
import type { PropertySchema } from '../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Serializes Data Domain elements (DomainEntity, DomainProperty, DomainAssociation)
|
|
10
|
+
* to AMF shapes.
|
|
11
|
+
*
|
|
12
|
+
* This class provides a mechanism to translate a data domain model, defined using
|
|
13
|
+
* custom classes like `DomainEntity`, `DomainProperty`, and `DomainAssociation`,
|
|
14
|
+
* into AMF (API Modeling Framework) shapes. AMF shapes are a standardized way
|
|
15
|
+
* to represent API structures and data models, enabling interoperability and tooling.
|
|
16
|
+
*
|
|
17
|
+
* This is particularly useful when you have a custom data model and need to
|
|
18
|
+
* generate API definitions (e.g., RAML or OAS) from it.
|
|
19
|
+
*
|
|
20
|
+
* **Key Features:**
|
|
21
|
+
*
|
|
22
|
+
* - **Data Domain to AMF Translation:** Converts data domain elements into
|
|
23
|
+
* their corresponding AMF shape representations.
|
|
24
|
+
* - **Recursive Shape Handling:** Detects and handles recursive relationships
|
|
25
|
+
* within the data model to prevent infinite loops during shape generation.
|
|
26
|
+
* - **Union Type Support:** Supports the creation of union types in AMF
|
|
27
|
+
* to represent associations that can point to multiple different entity types.
|
|
28
|
+
* - **Binding Integration:** Leverages binding information (e.g., web bindings)
|
|
29
|
+
* to customize the generated AMF shapes based on the target API format.
|
|
30
|
+
* - **Example and Default Value Generation:** Integrates with a `DataValueGenerator`
|
|
31
|
+
* to automatically generate example values and default values for properties
|
|
32
|
+
* within the AMF shapes.
|
|
33
|
+
*
|
|
34
|
+
* **Usage:**
|
|
35
|
+
*
|
|
36
|
+
* 1. Create an instance of the `ShapeGenerator`.
|
|
37
|
+
* 2. Call the appropriate method (e.g., `entity()`, `property()`, `associationShape()`)
|
|
38
|
+
* to generate the AMF shape for a specific data domain element.
|
|
39
|
+
* 3. The returned AMF shape can then be used with other AMF tools to generate
|
|
40
|
+
* API definitions or perform other API-related tasks.
|
|
41
|
+
*/
|
|
42
|
+
export declare class ShapeGenerator {
|
|
43
|
+
#private;
|
|
44
|
+
/**
|
|
45
|
+
* Used with data domain value generation for entity properties.
|
|
46
|
+
* Lazily loaded class only when functions are used.
|
|
47
|
+
* This needs to be a class instances because some functions are incremental
|
|
48
|
+
*/
|
|
49
|
+
get valueGenerator(): DataValueGenerator;
|
|
50
|
+
/**
|
|
51
|
+
* Serializes a `DomainEntity` to an AMF node shape.
|
|
52
|
+
*
|
|
53
|
+
* This method is the entry point for converting a `DomainEntity` into its
|
|
54
|
+
* AMF representation. It handles recursive relationships, property serialization,
|
|
55
|
+
* and inheritance from parent entities.
|
|
56
|
+
*
|
|
57
|
+
* @param input The `DomainEntity` to serialize.
|
|
58
|
+
* @param visited A `Set` of keys of already generated entities. This prevents
|
|
59
|
+
* recursive shape generation and avoids infinite loops. Defaults to a new empty `Set`.
|
|
60
|
+
* @returns An `IApiNodeShape` or `IApiRecursiveShape` representing the entity in AMF.
|
|
61
|
+
* Returns a `IApiRecursiveShape` if a recursive loop is detected.
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const generator = new ShapeGenerator();
|
|
65
|
+
* const amfShape = generator.entity(myDomainEntity);
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
entity(input: DomainEntity, visited?: Set<string>): IApiNodeShape | IApiRecursiveShape;
|
|
69
|
+
/**
|
|
70
|
+
* Serializes a `DomainProperty` to an AMF property shape.
|
|
71
|
+
*
|
|
72
|
+
* This method converts a `DomainProperty` into an `IApiPropertyShape`,
|
|
73
|
+
* defining its characteristics such as data type, required status, and
|
|
74
|
+
* range (the shape of the property's value).
|
|
75
|
+
*
|
|
76
|
+
* @param input The `DomainProperty` to serialize.
|
|
77
|
+
* @returns An `IApiPropertyShape` representing the property in AMF.
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* const generator = new ShapeGenerator();
|
|
81
|
+
* const amfShape = generator.property(myDomainProperty);
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
property(input: DomainProperty): IApiPropertyShape;
|
|
85
|
+
/**
|
|
86
|
+
* Serializes a `DomainAssociation` to an AMF property shape, handling the
|
|
87
|
+
* association's target entity or entities.
|
|
88
|
+
*
|
|
89
|
+
* This method is similar to `property()`, but it specifically handles
|
|
90
|
+
* associations between entities. It determines the range of the property
|
|
91
|
+
* based on the association's target(s) and generates the appropriate
|
|
92
|
+
* AMF shape (e.g., a scalar shape for a linked schema, a union shape for
|
|
93
|
+
* multiple targets).
|
|
94
|
+
*
|
|
95
|
+
* @param input The `DomainAssociation` to serialize.
|
|
96
|
+
* @param visited A `Set` of keys of already generated entities. This prevents
|
|
97
|
+
* recursive shape generation and avoids infinite loops. Defaults to a new empty `Set`.
|
|
98
|
+
* @returns An `IApiPropertyShape` representing the association in AMF.
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* const generator = new ShapeGenerator();
|
|
102
|
+
* const amfShape = generator.associationProperty(myDomainAssociation);
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
associationProperty(input: DomainAssociation, visited?: Set<string>): IApiPropertyShape;
|
|
106
|
+
/**
|
|
107
|
+
* Generates a shape for an association. Most likely you want to use the `associationProperty()` method instead.
|
|
108
|
+
*
|
|
109
|
+
* @param input The data association instance.
|
|
110
|
+
* @param visited A `Set` of keys of already generated entities. This prevents
|
|
111
|
+
* recursive shape generation and avoids infinite loops. Defaults to a new empty `Set`.
|
|
112
|
+
* @returns The range value for the PropertyShape.
|
|
113
|
+
*/
|
|
114
|
+
associationShape(input: DomainAssociation, visited?: Set<string>): IShapeUnion | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* @param input The data association instance.
|
|
117
|
+
* @returns An AMF API scalar shape with the link to the schema.
|
|
118
|
+
*/
|
|
119
|
+
protected createLinkedShape(input: DomainAssociation): IApiScalarShape;
|
|
120
|
+
protected createUnionShape(input: DomainAssociation, items: IShapeUnion[]): IApiUnionShape | IApiArrayShape;
|
|
121
|
+
/**
|
|
122
|
+
* Generates a shape list for an union. Most likely you want to use the `associationProperty()` method instead.
|
|
123
|
+
*
|
|
124
|
+
* @param input The data association instance.
|
|
125
|
+
* @returns The range value for the PropertyShape.
|
|
126
|
+
*/
|
|
127
|
+
associationUnion(input: DomainAssociation, visited?: Set<string>): IShapeUnion | IShapeUnion[] | undefined;
|
|
128
|
+
/**
|
|
129
|
+
* The DomainProperty may have both the `schema` and the `bindings`. For AMF shape we read `schema` for
|
|
130
|
+
* default value, examples, and enum values. We also look for the `web`
|
|
131
|
+
* bindings for more detailed definition of a shape.
|
|
132
|
+
*
|
|
133
|
+
* @param input
|
|
134
|
+
*/
|
|
135
|
+
protected getRange(input: DomainProperty): IApiArrayShape | IApiFileShape | IApiScalarShape;
|
|
136
|
+
/**
|
|
137
|
+
* Normally this would be part of generating a scalar schema but the the property is an array this
|
|
138
|
+
* is generated on the array and not on the range.
|
|
139
|
+
*
|
|
140
|
+
* @param result The scalar or array shape.
|
|
141
|
+
* @param schema The property schema
|
|
142
|
+
* @param type The data type of the parent property as set on the `range`
|
|
143
|
+
* @param isArray Whether the DomainProperty is multiple
|
|
144
|
+
*/
|
|
145
|
+
protected setShapeSchema(input: DomainProperty, result: IApiAnyShape, schema: PropertySchema, type: string, isArray?: boolean): void;
|
|
146
|
+
protected createArrayShape(input: DomainProperty, schema?: PropertySchema, bindings?: PropertyWebBindings): IApiArrayShape;
|
|
147
|
+
protected createScalarShape(input: DomainProperty, schema?: PropertySchema, bindings?: PropertyWebBindings): IApiScalarShape;
|
|
148
|
+
protected createExamples(examples: string[], type: string): IApiDataExample[];
|
|
149
|
+
protected createArrayExamples(examples: string[], type: string): IApiDataExample[];
|
|
150
|
+
protected createFileShape(input: DomainProperty, bindings?: PropertyWebBindings): IApiFileShape;
|
|
151
|
+
protected setScalarCommonProperties(result: IApiFileShape | IApiScalarShape, input: DomainProperty, bindings?: PropertyWebBindings): void;
|
|
152
|
+
protected updateBaseProperties(input: DomainProperty | DomainAssociation | DomainEntity, target: IApiShape): void;
|
|
153
|
+
protected createRecursiveShape(input: DomainEntity): IApiRecursiveShape;
|
|
154
|
+
/**
|
|
155
|
+
* Translates the shape to an array shape. This happens when data model property
|
|
156
|
+
* is changed from 'multiple' to not-multiple and back.
|
|
157
|
+
*
|
|
158
|
+
* @param id The key of the parameter or an association
|
|
159
|
+
* @param shape The shape to wrap as an array.
|
|
160
|
+
* @returns Array shape.
|
|
161
|
+
*/
|
|
162
|
+
protected refactorShapeToArray(id: string, shape: IShapeUnion): IApiArrayShape;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=ShapeGenerator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShapeGenerator.d.ts","sourceRoot":"","sources":["../../../../src/modeling/amf/ShapeGenerator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
import { IAmfExampleTypes, modelTypeToAmfDataType } from '../../amf/AmfTypes.js';
|
|
2
|
+
import { AmfNamespace } from '../../amf/definitions/Namespace.js';
|
|
3
|
+
import { anyShape, arrayShape, fileShape, nodeShape, propertyShape, recursiveShape, scalarShape, unionShape, } from '../../amf/definitions/Shapes.js';
|
|
4
|
+
import { AmfDataNode } from '../../amf/models/AmfDataNode.js';
|
|
5
|
+
import { DataValueGenerator } from '../../amf/DataValueGenerator.js';
|
|
6
|
+
import { nanoid } from 'nanoid';
|
|
7
|
+
import { DomainEntityKind, DomainPropertyKind } from '../../models/kinds.js';
|
|
8
|
+
const UNION_TYPE_ANY_OF = 'anyOf';
|
|
9
|
+
const UNION_TYPE_ALL_OF = 'allOf';
|
|
10
|
+
const UNION_TYPE_ONE_OF = 'oneOf';
|
|
11
|
+
const UNION_TYPE_NOT = 'not';
|
|
12
|
+
const DATA_TYPE_STRING = 'string';
|
|
13
|
+
const DATA_TYPE_BINARY = 'binary';
|
|
14
|
+
/**
|
|
15
|
+
* Serializes Data Domain elements (DomainEntity, DomainProperty, DomainAssociation)
|
|
16
|
+
* to AMF shapes.
|
|
17
|
+
*
|
|
18
|
+
* This class provides a mechanism to translate a data domain model, defined using
|
|
19
|
+
* custom classes like `DomainEntity`, `DomainProperty`, and `DomainAssociation`,
|
|
20
|
+
* into AMF (API Modeling Framework) shapes. AMF shapes are a standardized way
|
|
21
|
+
* to represent API structures and data models, enabling interoperability and tooling.
|
|
22
|
+
*
|
|
23
|
+
* This is particularly useful when you have a custom data model and need to
|
|
24
|
+
* generate API definitions (e.g., RAML or OAS) from it.
|
|
25
|
+
*
|
|
26
|
+
* **Key Features:**
|
|
27
|
+
*
|
|
28
|
+
* - **Data Domain to AMF Translation:** Converts data domain elements into
|
|
29
|
+
* their corresponding AMF shape representations.
|
|
30
|
+
* - **Recursive Shape Handling:** Detects and handles recursive relationships
|
|
31
|
+
* within the data model to prevent infinite loops during shape generation.
|
|
32
|
+
* - **Union Type Support:** Supports the creation of union types in AMF
|
|
33
|
+
* to represent associations that can point to multiple different entity types.
|
|
34
|
+
* - **Binding Integration:** Leverages binding information (e.g., web bindings)
|
|
35
|
+
* to customize the generated AMF shapes based on the target API format.
|
|
36
|
+
* - **Example and Default Value Generation:** Integrates with a `DataValueGenerator`
|
|
37
|
+
* to automatically generate example values and default values for properties
|
|
38
|
+
* within the AMF shapes.
|
|
39
|
+
*
|
|
40
|
+
* **Usage:**
|
|
41
|
+
*
|
|
42
|
+
* 1. Create an instance of the `ShapeGenerator`.
|
|
43
|
+
* 2. Call the appropriate method (e.g., `entity()`, `property()`, `associationShape()`)
|
|
44
|
+
* to generate the AMF shape for a specific data domain element.
|
|
45
|
+
* 3. The returned AMF shape can then be used with other AMF tools to generate
|
|
46
|
+
* API definitions or perform other API-related tasks.
|
|
47
|
+
*/
|
|
48
|
+
export class ShapeGenerator {
|
|
49
|
+
#valueGenerator;
|
|
50
|
+
/**
|
|
51
|
+
* Used with data domain value generation for entity properties.
|
|
52
|
+
* Lazily loaded class only when functions are used.
|
|
53
|
+
* This needs to be a class instances because some functions are incremental
|
|
54
|
+
*/
|
|
55
|
+
get valueGenerator() {
|
|
56
|
+
// we need a new instance of the generator for each shape generation
|
|
57
|
+
// as the generator is stateful and we need to reset it for each shape.
|
|
58
|
+
if (!this.#valueGenerator) {
|
|
59
|
+
this.#valueGenerator = new DataValueGenerator();
|
|
60
|
+
}
|
|
61
|
+
return this.#valueGenerator;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Serializes a `DomainEntity` to an AMF node shape.
|
|
65
|
+
*
|
|
66
|
+
* This method is the entry point for converting a `DomainEntity` into its
|
|
67
|
+
* AMF representation. It handles recursive relationships, property serialization,
|
|
68
|
+
* and inheritance from parent entities.
|
|
69
|
+
*
|
|
70
|
+
* @param input The `DomainEntity` to serialize.
|
|
71
|
+
* @param visited A `Set` of keys of already generated entities. This prevents
|
|
72
|
+
* recursive shape generation and avoids infinite loops. Defaults to a new empty `Set`.
|
|
73
|
+
* @returns An `IApiNodeShape` or `IApiRecursiveShape` representing the entity in AMF.
|
|
74
|
+
* Returns a `IApiRecursiveShape` if a recursive loop is detected.
|
|
75
|
+
* @example
|
|
76
|
+
* ```typescript
|
|
77
|
+
* const generator = new ShapeGenerator();
|
|
78
|
+
* const amfShape = generator.entity(myDomainEntity);
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
entity(input, visited = new Set()) {
|
|
82
|
+
if (visited.has(input.key)) {
|
|
83
|
+
// create a recursive shape.
|
|
84
|
+
return this.createRecursiveShape(input);
|
|
85
|
+
}
|
|
86
|
+
visited.add(input.key);
|
|
87
|
+
const result = nodeShape(input.key);
|
|
88
|
+
result.id = input.key;
|
|
89
|
+
this.updateBaseProperties(input, result);
|
|
90
|
+
result.properties = [];
|
|
91
|
+
for (const item of input.listProperties()) {
|
|
92
|
+
// we check whether the property is hidden.
|
|
93
|
+
// This is not happening when calling the `property()` because this method
|
|
94
|
+
// always returns the AMF shape.
|
|
95
|
+
const wb = item.readBinding('web');
|
|
96
|
+
if (wb && wb.hidden) {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const shape = this.property(item);
|
|
100
|
+
result.properties.push(shape);
|
|
101
|
+
}
|
|
102
|
+
for (const assoc of input.listAssociations()) {
|
|
103
|
+
const wb = assoc.readBinding('web');
|
|
104
|
+
if (wb && wb.hidden) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const prop = this.associationProperty(assoc, visited);
|
|
108
|
+
result.properties.push(prop);
|
|
109
|
+
}
|
|
110
|
+
for (const parent of input.listParents()) {
|
|
111
|
+
const shape = this.entity(parent, visited);
|
|
112
|
+
result.inherits.push(shape);
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Serializes a `DomainProperty` to an AMF property shape.
|
|
118
|
+
*
|
|
119
|
+
* This method converts a `DomainProperty` into an `IApiPropertyShape`,
|
|
120
|
+
* defining its characteristics such as data type, required status, and
|
|
121
|
+
* range (the shape of the property's value).
|
|
122
|
+
*
|
|
123
|
+
* @param input The `DomainProperty` to serialize.
|
|
124
|
+
* @returns An `IApiPropertyShape` representing the property in AMF.
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const generator = new ShapeGenerator();
|
|
128
|
+
* const amfShape = generator.property(myDomainProperty);
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
property(input) {
|
|
132
|
+
const { required, key } = input;
|
|
133
|
+
const result = propertyShape(key);
|
|
134
|
+
result.path = `${AmfNamespace.aml.vocabularies.data.key}${input.info.name}`;
|
|
135
|
+
if (required) {
|
|
136
|
+
result.minCount = 1;
|
|
137
|
+
}
|
|
138
|
+
result.range = this.getRange(input);
|
|
139
|
+
// for example, Example generator needs to know the name of the property
|
|
140
|
+
// as it does not look into the "range" object.
|
|
141
|
+
this.updateBaseProperties(input, result);
|
|
142
|
+
// sync the name of the property shape with the range, in case it was changed by the bindings
|
|
143
|
+
if (result.range.name) {
|
|
144
|
+
result.name = result.range.name;
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Serializes a `DomainAssociation` to an AMF property shape, handling the
|
|
150
|
+
* association's target entity or entities.
|
|
151
|
+
*
|
|
152
|
+
* This method is similar to `property()`, but it specifically handles
|
|
153
|
+
* associations between entities. It determines the range of the property
|
|
154
|
+
* based on the association's target(s) and generates the appropriate
|
|
155
|
+
* AMF shape (e.g., a scalar shape for a linked schema, a union shape for
|
|
156
|
+
* multiple targets).
|
|
157
|
+
*
|
|
158
|
+
* @param input The `DomainAssociation` to serialize.
|
|
159
|
+
* @param visited A `Set` of keys of already generated entities. This prevents
|
|
160
|
+
* recursive shape generation and avoids infinite loops. Defaults to a new empty `Set`.
|
|
161
|
+
* @returns An `IApiPropertyShape` representing the association in AMF.
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* const generator = new ShapeGenerator();
|
|
165
|
+
* const amfShape = generator.associationProperty(myDomainAssociation);
|
|
166
|
+
* ```
|
|
167
|
+
*/
|
|
168
|
+
associationProperty(input, visited = new Set()) {
|
|
169
|
+
const { required, key } = input;
|
|
170
|
+
const result = propertyShape(key);
|
|
171
|
+
result.path = `${AmfNamespace.aml.vocabularies.data.key}${input.info.name}`;
|
|
172
|
+
if (required) {
|
|
173
|
+
result.minCount = 1;
|
|
174
|
+
}
|
|
175
|
+
result.range = this.associationShape(input, visited);
|
|
176
|
+
this.updateBaseProperties(input, result);
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Generates a shape for an association. Most likely you want to use the `associationProperty()` method instead.
|
|
181
|
+
*
|
|
182
|
+
* @param input The data association instance.
|
|
183
|
+
* @param visited A `Set` of keys of already generated entities. This prevents
|
|
184
|
+
* recursive shape generation and avoids infinite loops. Defaults to a new empty `Set`.
|
|
185
|
+
* @returns The range value for the PropertyShape.
|
|
186
|
+
*/
|
|
187
|
+
associationShape(input, visited = new Set()) {
|
|
188
|
+
const schema = input.schema;
|
|
189
|
+
if (schema && schema.linked) {
|
|
190
|
+
return this.createLinkedShape(input);
|
|
191
|
+
}
|
|
192
|
+
const items = this.associationUnion(input, visited);
|
|
193
|
+
if (!items) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (Array.isArray(items)) {
|
|
197
|
+
return this.createUnionShape(input, items);
|
|
198
|
+
}
|
|
199
|
+
const unionType = (schema && schema.unionType) || UNION_TYPE_ANY_OF;
|
|
200
|
+
if (unionType === UNION_TYPE_NOT) {
|
|
201
|
+
// Need to investigate more about "not" union type.
|
|
202
|
+
// AMF supports it, but I am not sure how to handle it.
|
|
203
|
+
const wrapper = anyShape(input.key);
|
|
204
|
+
wrapper.id = `not-shape-${input.key}`;
|
|
205
|
+
wrapper.not = items;
|
|
206
|
+
return wrapper;
|
|
207
|
+
}
|
|
208
|
+
if (input.multiple) {
|
|
209
|
+
return this.refactorShapeToArray(input.key, items);
|
|
210
|
+
}
|
|
211
|
+
return items;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* @param input The data association instance.
|
|
215
|
+
* @returns An AMF API scalar shape with the link to the schema.
|
|
216
|
+
*/
|
|
217
|
+
createLinkedShape(input) {
|
|
218
|
+
// This is a link to the schema. In an API that would be the id
|
|
219
|
+
// of a resource to request the data from.
|
|
220
|
+
const range = scalarShape(input.key);
|
|
221
|
+
range.id = `link-${input.key}`;
|
|
222
|
+
range.dataType = modelTypeToAmfDataType(DATA_TYPE_STRING);
|
|
223
|
+
return range;
|
|
224
|
+
}
|
|
225
|
+
createUnionShape(input, items) {
|
|
226
|
+
const range = unionShape(input.key);
|
|
227
|
+
this.updateBaseProperties(input, range);
|
|
228
|
+
range.anyOf = [];
|
|
229
|
+
const unionType = (input.schema && input.schema.unionType) || UNION_TYPE_ANY_OF;
|
|
230
|
+
if (unionType === UNION_TYPE_ANY_OF) {
|
|
231
|
+
range.anyOf = items;
|
|
232
|
+
}
|
|
233
|
+
else if (unionType === UNION_TYPE_ALL_OF) {
|
|
234
|
+
range.and = items;
|
|
235
|
+
}
|
|
236
|
+
else if (unionType === UNION_TYPE_ONE_OF) {
|
|
237
|
+
range.xone = items;
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
// the "not" union type only supports a single schema.
|
|
241
|
+
// I am not sure how this should be handled. Will take the first one
|
|
242
|
+
// for now.
|
|
243
|
+
range.not = items[0];
|
|
244
|
+
}
|
|
245
|
+
if (input.multiple) {
|
|
246
|
+
return this.refactorShapeToArray(input.key, range);
|
|
247
|
+
}
|
|
248
|
+
return range;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Generates a shape list for an union. Most likely you want to use the `associationProperty()` method instead.
|
|
252
|
+
*
|
|
253
|
+
* @param input The data association instance.
|
|
254
|
+
* @returns The range value for the PropertyShape.
|
|
255
|
+
*/
|
|
256
|
+
associationUnion(input, visited = new Set()) {
|
|
257
|
+
const result = [];
|
|
258
|
+
for (const item of input.listTargets()) {
|
|
259
|
+
result.push(this.entity(item, visited));
|
|
260
|
+
}
|
|
261
|
+
if (!result.length) {
|
|
262
|
+
return undefined;
|
|
263
|
+
}
|
|
264
|
+
if (result.length > 1) {
|
|
265
|
+
return result;
|
|
266
|
+
}
|
|
267
|
+
return result[0];
|
|
268
|
+
}
|
|
269
|
+
/**
|
|
270
|
+
* The DomainProperty may have both the `schema` and the `bindings`. For AMF shape we read `schema` for
|
|
271
|
+
* default value, examples, and enum values. We also look for the `web`
|
|
272
|
+
* bindings for more detailed definition of a shape.
|
|
273
|
+
*
|
|
274
|
+
* @param input
|
|
275
|
+
*/
|
|
276
|
+
getRange(input) {
|
|
277
|
+
const bindings = input.readBinding('web');
|
|
278
|
+
let schema;
|
|
279
|
+
if (input.schema) {
|
|
280
|
+
schema = input.schema;
|
|
281
|
+
}
|
|
282
|
+
const { multiple, type } = input;
|
|
283
|
+
if (multiple) {
|
|
284
|
+
return this.createArrayShape(input, schema, bindings);
|
|
285
|
+
}
|
|
286
|
+
if (type === DATA_TYPE_BINARY) {
|
|
287
|
+
return this.createFileShape(input, bindings);
|
|
288
|
+
}
|
|
289
|
+
return this.createScalarShape(input, schema, bindings);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Normally this would be part of generating a scalar schema but the the property is an array this
|
|
293
|
+
* is generated on the array and not on the range.
|
|
294
|
+
*
|
|
295
|
+
* @param result The scalar or array shape.
|
|
296
|
+
* @param schema The property schema
|
|
297
|
+
* @param type The data type of the parent property as set on the `range`
|
|
298
|
+
* @param isArray Whether the DomainProperty is multiple
|
|
299
|
+
*/
|
|
300
|
+
setShapeSchema(input, result, schema, type, isArray) {
|
|
301
|
+
if (schema.defaultValue) {
|
|
302
|
+
const { type: dfFormat } = schema.defaultValue;
|
|
303
|
+
const { value } = schema.defaultValue;
|
|
304
|
+
if (dfFormat === 'function') {
|
|
305
|
+
const tmp = this.valueGenerator.generate(value, input.type);
|
|
306
|
+
if (tmp !== DataValueGenerator.noValue) {
|
|
307
|
+
const dt = AmfDataNode.scalar(tmp, dfFormat);
|
|
308
|
+
result.defaultValue = dt.toJSON();
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
const dt = AmfDataNode.scalar(value, type);
|
|
313
|
+
result.defaultValue = dt.toJSON();
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (Array.isArray(schema.enum)) {
|
|
317
|
+
result.values = schema.enum.map((i) => AmfDataNode.scalar(i, type).toJSON());
|
|
318
|
+
}
|
|
319
|
+
if (Array.isArray(schema.examples)) {
|
|
320
|
+
if (isArray) {
|
|
321
|
+
result.examples = this.createArrayExamples(schema.examples, type);
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
result.examples = this.createExamples(schema.examples, type);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
createArrayShape(input, schema, bindings) {
|
|
329
|
+
const result = arrayShape(input.key);
|
|
330
|
+
const { type } = input;
|
|
331
|
+
if (type === DATA_TYPE_BINARY) {
|
|
332
|
+
// we do not pass schema to the range generator as we set schema's properties on the array shape.
|
|
333
|
+
result.items = this.createFileShape(input, bindings);
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
result.items = this.createScalarShape(input, undefined, bindings);
|
|
337
|
+
}
|
|
338
|
+
if (schema) {
|
|
339
|
+
const type = result.items.dataType;
|
|
340
|
+
this.setShapeSchema(input, result, schema, type, input.multiple);
|
|
341
|
+
}
|
|
342
|
+
return result;
|
|
343
|
+
}
|
|
344
|
+
createScalarShape(input, schema, bindings) {
|
|
345
|
+
const result = scalarShape(input.key);
|
|
346
|
+
this.updateBaseProperties(input, result);
|
|
347
|
+
this.setScalarCommonProperties(result, input, bindings);
|
|
348
|
+
if (!result.dataType) {
|
|
349
|
+
result.dataType = modelTypeToAmfDataType(input.type, bindings);
|
|
350
|
+
}
|
|
351
|
+
if (schema) {
|
|
352
|
+
this.setShapeSchema(input, result, schema, result.dataType, input.multiple);
|
|
353
|
+
}
|
|
354
|
+
return result;
|
|
355
|
+
}
|
|
356
|
+
createExamples(examples, type) {
|
|
357
|
+
const result = [];
|
|
358
|
+
for (const current of examples) {
|
|
359
|
+
const item = {
|
|
360
|
+
id: nanoid(),
|
|
361
|
+
customDomainProperties: [],
|
|
362
|
+
strict: true,
|
|
363
|
+
types: IAmfExampleTypes,
|
|
364
|
+
structuredValue: AmfDataNode.scalar(current, type).toJSON(),
|
|
365
|
+
};
|
|
366
|
+
result.push(item);
|
|
367
|
+
}
|
|
368
|
+
return result;
|
|
369
|
+
}
|
|
370
|
+
createArrayExamples(examples, type) {
|
|
371
|
+
const item = {
|
|
372
|
+
id: nanoid(),
|
|
373
|
+
customDomainProperties: [],
|
|
374
|
+
strict: true,
|
|
375
|
+
types: IAmfExampleTypes,
|
|
376
|
+
};
|
|
377
|
+
const value = new AmfDataNode('array');
|
|
378
|
+
for (const item of examples) {
|
|
379
|
+
const member = AmfDataNode.scalar(item, type);
|
|
380
|
+
value.addMember(member);
|
|
381
|
+
}
|
|
382
|
+
item.structuredValue = value.toJSON();
|
|
383
|
+
return [item];
|
|
384
|
+
}
|
|
385
|
+
createFileShape(input, bindings) {
|
|
386
|
+
const result = fileShape(input.key);
|
|
387
|
+
this.updateBaseProperties(input, result);
|
|
388
|
+
if (bindings) {
|
|
389
|
+
if (Array.isArray(bindings.fileTypes)) {
|
|
390
|
+
result.fileTypes = bindings.fileTypes;
|
|
391
|
+
}
|
|
392
|
+
this.setScalarCommonProperties(result, input, bindings);
|
|
393
|
+
if (bindings.format === 'base64') {
|
|
394
|
+
result.format = AmfNamespace.w3.xmlSchema.base64Binary;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return result;
|
|
398
|
+
}
|
|
399
|
+
setScalarCommonProperties(result, input, bindings) {
|
|
400
|
+
if (bindings?.name) {
|
|
401
|
+
result.name = bindings.name;
|
|
402
|
+
}
|
|
403
|
+
if (bindings?.xml) {
|
|
404
|
+
result.xmlSerialization = bindings.xml;
|
|
405
|
+
}
|
|
406
|
+
if (bindings?.pattern) {
|
|
407
|
+
result.pattern = bindings.pattern;
|
|
408
|
+
}
|
|
409
|
+
const { schema, type } = input;
|
|
410
|
+
if (schema) {
|
|
411
|
+
if (typeof schema.multipleOf === 'number') {
|
|
412
|
+
result.multipleOf = schema.multipleOf;
|
|
413
|
+
}
|
|
414
|
+
if (typeof schema.minimum === 'number') {
|
|
415
|
+
if (type === DATA_TYPE_STRING) {
|
|
416
|
+
result.minLength = schema.minimum;
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
result.minimum = schema.minimum;
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
if (typeof schema.maximum === 'number') {
|
|
423
|
+
if (type === DATA_TYPE_STRING) {
|
|
424
|
+
result.maxLength = schema.maximum;
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
result.maximum = schema.maximum;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
if (typeof schema.exclusiveMinimum === 'boolean') {
|
|
431
|
+
result.exclusiveMinimum = schema.exclusiveMinimum;
|
|
432
|
+
}
|
|
433
|
+
if (typeof schema.exclusiveMaximum === 'boolean') {
|
|
434
|
+
result.exclusiveMaximum = schema.exclusiveMaximum;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (bindings?.format) {
|
|
438
|
+
switch (bindings.format) {
|
|
439
|
+
case 'base64':
|
|
440
|
+
result.format = AmfNamespace.w3.xmlSchema.base64Binary;
|
|
441
|
+
break;
|
|
442
|
+
case 'double':
|
|
443
|
+
result.format = AmfNamespace.w3.xmlSchema.double;
|
|
444
|
+
break;
|
|
445
|
+
case 'float':
|
|
446
|
+
result.format = AmfNamespace.w3.xmlSchema.float;
|
|
447
|
+
break;
|
|
448
|
+
case 'int32':
|
|
449
|
+
result.format = AmfNamespace.w3.xmlSchema.integer;
|
|
450
|
+
break;
|
|
451
|
+
case 'int64':
|
|
452
|
+
result.format = AmfNamespace.w3.xmlSchema.integer;
|
|
453
|
+
break;
|
|
454
|
+
}
|
|
455
|
+
// result.format = bindings.format
|
|
456
|
+
}
|
|
457
|
+
if (typeof input.readOnly === 'boolean') {
|
|
458
|
+
result.readOnly = input.readOnly;
|
|
459
|
+
}
|
|
460
|
+
if (typeof input.writeOnly === 'boolean') {
|
|
461
|
+
result.writeOnly = input.writeOnly;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
updateBaseProperties(input, target) {
|
|
465
|
+
target.name = input.info.name;
|
|
466
|
+
target.displayName = input.info.displayName;
|
|
467
|
+
target.description = input.info.description;
|
|
468
|
+
if (input.kind === DomainPropertyKind) {
|
|
469
|
+
target.deprecated = input.deprecated;
|
|
470
|
+
}
|
|
471
|
+
else if (input.kind === DomainEntityKind) {
|
|
472
|
+
target.deprecated = input.deprecated;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
createRecursiveShape(input) {
|
|
476
|
+
return recursiveShape(input.key, input.key);
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Translates the shape to an array shape. This happens when data model property
|
|
480
|
+
* is changed from 'multiple' to not-multiple and back.
|
|
481
|
+
*
|
|
482
|
+
* @param id The key of the parameter or an association
|
|
483
|
+
* @param shape The shape to wrap as an array.
|
|
484
|
+
* @returns Array shape.
|
|
485
|
+
*/
|
|
486
|
+
refactorShapeToArray(id, shape) {
|
|
487
|
+
const result = arrayShape(id);
|
|
488
|
+
result.items = shape;
|
|
489
|
+
return result;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
//# sourceMappingURL=ShapeGenerator.js.map
|