@api-client/core 0.17.7 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/src/amf/ApiSchemaGenerator.d.ts +2 -2
- package/build/src/amf/ApiSchemaGenerator.d.ts.map +1 -1
- package/build/src/amf/ApiSchemaGenerator.js.map +1 -1
- package/build/src/amf/ApiSchemaValues.d.ts.map +1 -1
- package/build/src/amf/ApiSchemaValues.js +8 -1
- package/build/src/amf/ApiSchemaValues.js.map +1 -1
- package/build/src/amf/shape/ShapeBase.d.ts +1 -1
- package/build/src/amf/shape/ShapeBase.d.ts.map +1 -1
- package/build/src/amf/shape/ShapeBase.js.map +1 -1
- package/build/src/amf/shape/ShapeJsonSchemaGenerator.d.ts +1 -1
- package/build/src/amf/shape/ShapeJsonSchemaGenerator.d.ts.map +1 -1
- package/build/src/amf/shape/ShapeJsonSchemaGenerator.js +7 -1
- package/build/src/amf/shape/ShapeJsonSchemaGenerator.js.map +1 -1
- package/build/src/amf/shape/ShapeXmlSchemaGenerator.d.ts +1 -1
- package/build/src/amf/shape/ShapeXmlSchemaGenerator.d.ts.map +1 -1
- package/build/src/amf/shape/ShapeXmlSchemaGenerator.js +8 -2
- package/build/src/amf/shape/ShapeXmlSchemaGenerator.js.map +1 -1
- package/build/src/mocking/RandExp.d.ts +55 -0
- package/build/src/mocking/RandExp.d.ts.map +1 -0
- package/build/src/mocking/RandExp.js +302 -0
- package/build/src/mocking/RandExp.js.map +1 -0
- package/build/src/mocking/lib/ret.d.ts +16 -0
- package/build/src/mocking/lib/ret.d.ts.map +1 -0
- package/build/src/mocking/lib/ret.js +284 -0
- package/build/src/mocking/lib/ret.js.map +1 -0
- package/build/src/modeling/Bindings.d.ts +0 -4
- package/build/src/modeling/Bindings.d.ts.map +1 -1
- package/build/src/modeling/Bindings.js.map +1 -1
- package/build/src/modeling/DomainEntity.js +3 -3
- package/build/src/modeling/DomainEntity.js.map +1 -1
- package/build/src/modeling/DomainProperty.d.ts +18 -0
- package/build/src/modeling/DomainProperty.d.ts.map +1 -1
- package/build/src/modeling/DomainProperty.js +31 -0
- package/build/src/modeling/DomainProperty.js.map +1 -1
- package/build/src/modeling/amf/ShapeGenerator.js +3 -3
- package/build/src/modeling/amf/ShapeGenerator.js.map +1 -1
- package/build/src/modeling/types.d.ts +4 -0
- package/build/src/modeling/types.d.ts.map +1 -1
- package/build/src/modeling/types.js.map +1 -1
- package/build/src/models/DataCatalog.d.ts +12 -1
- package/build/src/models/DataCatalog.d.ts.map +1 -1
- package/build/src/models/DataCatalog.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/amf/ApiSchemaGenerator.ts +2 -2
- package/src/amf/ApiSchemaValues.ts +8 -1
- package/src/amf/shape/ShapeBase.ts +1 -1
- package/src/amf/shape/ShapeJsonSchemaGenerator.ts +7 -2
- package/src/amf/shape/ShapeXmlSchemaGenerator.ts +8 -3
- package/src/mocking/RandExp.ts +335 -0
- package/src/mocking/lib/ret.ts +279 -0
- package/src/modeling/Bindings.ts +0 -4
- package/src/modeling/DomainEntity.ts +3 -3
- package/src/modeling/DomainProperty.ts +33 -0
- package/src/modeling/amf/ShapeGenerator.ts +3 -3
- package/src/modeling/types.ts +4 -0
- package/src/models/DataCatalog.ts +13 -1
- package/tests/unit/modeling/amf/shape_generator.spec.ts +3 -8
- package/tests/unit/modeling/domain_property.spec.ts +335 -0
package/src/modeling/Bindings.ts
CHANGED
|
@@ -75,10 +75,6 @@ export interface PropertyWebBindings {
|
|
|
75
75
|
* The list of file mime types.
|
|
76
76
|
*/
|
|
77
77
|
fileTypes?: string[]
|
|
78
|
-
/**
|
|
79
|
-
* The patter to use wit a string scalar
|
|
80
|
-
*/
|
|
81
|
-
pattern?: string
|
|
82
78
|
/**
|
|
83
79
|
* Whether the attribute is hidden in the schema (not a part of it).
|
|
84
80
|
*/
|
|
@@ -786,9 +786,9 @@ export class DomainEntity extends DomainElement {
|
|
|
786
786
|
toExample(mime: string, opts: IShapeRenderOptions = {}): string | number | boolean | null | undefined {
|
|
787
787
|
const shape = this.toApiShape()
|
|
788
788
|
const generator = new ApiSchemaGenerator(mime, {
|
|
789
|
-
renderExamples:
|
|
790
|
-
renderMocked:
|
|
791
|
-
renderOptional:
|
|
789
|
+
renderExamples: opts.renderExamples ?? true,
|
|
790
|
+
renderMocked: opts.renderMocked ?? true,
|
|
791
|
+
renderOptional: opts.renderOptional ?? true,
|
|
792
792
|
selectedUnions: opts.selectedUnions,
|
|
793
793
|
})
|
|
794
794
|
return generator.generate(shape)
|
|
@@ -23,6 +23,8 @@ import type { DomainEntity } from './DomainEntity.js'
|
|
|
23
23
|
import type { IApiPropertyShape } from '../amf/definitions/Shapes.js'
|
|
24
24
|
import type { PropertySchema } from './types.js'
|
|
25
25
|
import { DataSemantics, isPropertySemantic, type SemanticType, type AppliedDataSemantic } from './Semantics.js'
|
|
26
|
+
import { ApiSchemaGenerator } from '../amf/ApiSchemaGenerator.js'
|
|
27
|
+
import type { IShapeRenderOptions } from '../amf/shape/ShapeBase.js'
|
|
26
28
|
|
|
27
29
|
export interface DomainPropertySchema extends DomainElementSchema {
|
|
28
30
|
kind: typeof DomainPropertyKind
|
|
@@ -545,6 +547,37 @@ export class DomainProperty extends DomainElement {
|
|
|
545
547
|
return serializer.property(this)
|
|
546
548
|
}
|
|
547
549
|
|
|
550
|
+
/**
|
|
551
|
+
* Generates an example value for this property based on its schema and type.
|
|
552
|
+
*
|
|
553
|
+
* This method converts the property to an AMF shape and then generates
|
|
554
|
+
* an example value using the ApiSchemaGenerator. The generated example
|
|
555
|
+
* respects the property's type, constraints, and any defined schema.
|
|
556
|
+
*
|
|
557
|
+
* @param mime The mime type of the example (e.g., 'application/json', 'application/xml').
|
|
558
|
+
* @param opts Optional configuration for example generation.
|
|
559
|
+
* @returns The generated example value.
|
|
560
|
+
* @example
|
|
561
|
+
* ```typescript
|
|
562
|
+
* const example = property.toExample('application/json');
|
|
563
|
+
* console.log(example);
|
|
564
|
+
* ```
|
|
565
|
+
*/
|
|
566
|
+
toExample(mime: string, opts: IShapeRenderOptions = {}): string | number | boolean | null | undefined {
|
|
567
|
+
// TODO: add support for semantic extensions and generate example values based on them.
|
|
568
|
+
const shape = this.toApiShape()
|
|
569
|
+
if (!shape.range) {
|
|
570
|
+
return undefined
|
|
571
|
+
}
|
|
572
|
+
const generator = new ApiSchemaGenerator(mime, {
|
|
573
|
+
renderExamples: opts.renderExamples ?? true,
|
|
574
|
+
renderMocked: opts.renderMocked ?? true,
|
|
575
|
+
renderOptional: opts.renderOptional ?? true,
|
|
576
|
+
selectedUnions: opts.selectedUnions,
|
|
577
|
+
})
|
|
578
|
+
return generator.generate(shape)
|
|
579
|
+
}
|
|
580
|
+
|
|
548
581
|
/**
|
|
549
582
|
* Adds or updates a semantic to the property.
|
|
550
583
|
* @param semantic The semantic to add to the property.
|
|
@@ -464,11 +464,11 @@ export class ShapeGenerator {
|
|
|
464
464
|
if (bindings?.xml) {
|
|
465
465
|
result.xmlSerialization = bindings.xml
|
|
466
466
|
}
|
|
467
|
-
if (bindings?.pattern) {
|
|
468
|
-
result.pattern = bindings.pattern
|
|
469
|
-
}
|
|
470
467
|
const { schema, type } = input
|
|
471
468
|
if (schema) {
|
|
469
|
+
if (schema.pattern) {
|
|
470
|
+
result.pattern = schema.pattern
|
|
471
|
+
}
|
|
472
472
|
if (typeof schema.multipleOf === 'number') {
|
|
473
473
|
result.multipleOf = schema.multipleOf
|
|
474
474
|
}
|
package/src/modeling/types.ts
CHANGED
|
@@ -183,6 +183,10 @@ export interface PropertySchema {
|
|
|
183
183
|
* They are always encoded as strings. The actual type is defined in the `dataType` property.
|
|
184
184
|
*/
|
|
185
185
|
examples?: string[]
|
|
186
|
+
/**
|
|
187
|
+
* The pattern to use with a string scalar.
|
|
188
|
+
*/
|
|
189
|
+
pattern?: string
|
|
186
190
|
}
|
|
187
191
|
|
|
188
192
|
/**
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DataCatalogLifecycle } from './DataCatalogVersion.js'
|
|
1
2
|
import { DataCatalogKind } from './kinds.js'
|
|
2
3
|
|
|
3
4
|
export type DataCatalogScope = 'public' | 'private' | 'organization'
|
|
@@ -102,6 +103,17 @@ export interface DataCatalogSchema {
|
|
|
102
103
|
tags: string[]
|
|
103
104
|
}
|
|
104
105
|
|
|
106
|
+
export interface DataCatalogSchemaVersion {
|
|
107
|
+
/**
|
|
108
|
+
* The version of the data catalog entry.
|
|
109
|
+
*/
|
|
110
|
+
version: string
|
|
111
|
+
/**
|
|
112
|
+
* The lifecycle of the data catalog version.
|
|
113
|
+
*/
|
|
114
|
+
lifecycle: DataCatalogLifecycle
|
|
115
|
+
}
|
|
116
|
+
|
|
105
117
|
/**
|
|
106
118
|
* Used with API communication when listing data catalog entries.
|
|
107
119
|
*/
|
|
@@ -110,7 +122,7 @@ export interface DataCatalogSchemaWithVersion extends DataCatalogSchema {
|
|
|
110
122
|
* The list of published versions of the data catalog entry.
|
|
111
123
|
* Note, this is limited to the last 20 versions.
|
|
112
124
|
*/
|
|
113
|
-
versions:
|
|
125
|
+
versions: DataCatalogSchemaVersion[]
|
|
114
126
|
}
|
|
115
127
|
|
|
116
128
|
export interface DataCatalogVersionInfo {
|
|
@@ -452,14 +452,9 @@ test.group('property() / with web bindings', (group) => {
|
|
|
452
452
|
|
|
453
453
|
test('sets the pattern', ({ assert }) => {
|
|
454
454
|
const p1 = e1.addProperty({ key: 'p1', type: 'string', info: { name: 'p1' } })
|
|
455
|
-
p1.
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
schema: {
|
|
459
|
-
pattern: 'a-z',
|
|
460
|
-
},
|
|
461
|
-
},
|
|
462
|
-
]
|
|
455
|
+
p1.schema = {
|
|
456
|
+
pattern: 'a-z',
|
|
457
|
+
}
|
|
463
458
|
const result = p1.toApiShape()
|
|
464
459
|
const string = result.range as IApiScalarShape
|
|
465
460
|
assert.equal(string.pattern, 'a-z')
|
|
@@ -1042,3 +1042,338 @@ test.group('DomainProperty with GeospatialCoordinates semantic', () => {
|
|
|
1042
1042
|
await assert.dispatches(dataDomain, 'change', { timeout: 20 })
|
|
1043
1043
|
})
|
|
1044
1044
|
})
|
|
1045
|
+
|
|
1046
|
+
test.group('DomainProperty.toExample()', () => {
|
|
1047
|
+
test('generates a string example for string property', ({ assert }) => {
|
|
1048
|
+
const dataDomain = new DataDomain()
|
|
1049
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1050
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1051
|
+
const property = entity.addProperty({ key: 'name', type: 'string' })
|
|
1052
|
+
|
|
1053
|
+
const result = property.toExample('application/json')
|
|
1054
|
+
assert.typeOf(result, 'string')
|
|
1055
|
+
assert.isNotEmpty(result as string)
|
|
1056
|
+
})
|
|
1057
|
+
|
|
1058
|
+
test('generates a number example for number property', ({ assert }) => {
|
|
1059
|
+
const dataDomain = new DataDomain()
|
|
1060
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1061
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1062
|
+
const property = entity.addProperty({ key: 'age', type: 'number' })
|
|
1063
|
+
|
|
1064
|
+
const result = property.toExample('application/json')
|
|
1065
|
+
assert.typeOf(result, 'number')
|
|
1066
|
+
})
|
|
1067
|
+
|
|
1068
|
+
test('generates a boolean example for boolean property', ({ assert }) => {
|
|
1069
|
+
const dataDomain = new DataDomain()
|
|
1070
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1071
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1072
|
+
const property = entity.addProperty({ key: 'active', type: 'boolean' })
|
|
1073
|
+
|
|
1074
|
+
const result = property.toExample('application/json')
|
|
1075
|
+
assert.typeOf(result, 'boolean')
|
|
1076
|
+
})
|
|
1077
|
+
|
|
1078
|
+
test('generates a string example for integer property', ({ assert }) => {
|
|
1079
|
+
const dataDomain = new DataDomain()
|
|
1080
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1081
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1082
|
+
const property = entity.addProperty({ key: 'count', type: 'number' })
|
|
1083
|
+
property.getWebBinding().format = 'int32'
|
|
1084
|
+
|
|
1085
|
+
const result = property.toExample('application/json')
|
|
1086
|
+
assert.typeOf(result, 'number')
|
|
1087
|
+
assert.isTrue(Number.isInteger(result as number))
|
|
1088
|
+
})
|
|
1089
|
+
|
|
1090
|
+
test('generates a string example for datetime property', ({ assert }) => {
|
|
1091
|
+
const dataDomain = new DataDomain()
|
|
1092
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1093
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1094
|
+
const property = entity.addProperty({ key: 'created', type: 'datetime' })
|
|
1095
|
+
|
|
1096
|
+
const result = property.toExample('application/json')
|
|
1097
|
+
assert.typeOf(result, 'string')
|
|
1098
|
+
// Should match ISO 8601 format
|
|
1099
|
+
const isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/
|
|
1100
|
+
assert.match(result as string, isoDateRegex)
|
|
1101
|
+
})
|
|
1102
|
+
|
|
1103
|
+
test('generates a string example for date property', ({ assert }) => {
|
|
1104
|
+
const dataDomain = new DataDomain()
|
|
1105
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1106
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1107
|
+
const property = entity.addProperty({ key: 'birthdate', type: 'date' })
|
|
1108
|
+
|
|
1109
|
+
const result = property.toExample('application/json')
|
|
1110
|
+
assert.typeOf(result, 'string')
|
|
1111
|
+
// Should match YYYY-MM-DD format
|
|
1112
|
+
const dateRegex = /^\d{4}-\d{2}-\d{2}$/
|
|
1113
|
+
assert.match(result as string, dateRegex)
|
|
1114
|
+
})
|
|
1115
|
+
|
|
1116
|
+
test('generates a string example for time property', ({ assert }) => {
|
|
1117
|
+
const dataDomain = new DataDomain()
|
|
1118
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1119
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1120
|
+
const property = entity.addProperty({ key: 'appointment', type: 'time' })
|
|
1121
|
+
|
|
1122
|
+
const result = property.toExample('application/json')
|
|
1123
|
+
assert.typeOf(result, 'string')
|
|
1124
|
+
// Should match time format
|
|
1125
|
+
const timeRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$/
|
|
1126
|
+
assert.match(result as string, timeRegex)
|
|
1127
|
+
})
|
|
1128
|
+
|
|
1129
|
+
test('respects minimum constraint for number property', ({ assert }) => {
|
|
1130
|
+
const dataDomain = new DataDomain()
|
|
1131
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1132
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1133
|
+
const property = entity.addProperty({
|
|
1134
|
+
key: 'score',
|
|
1135
|
+
type: 'number',
|
|
1136
|
+
schema: { minimum: 10 },
|
|
1137
|
+
})
|
|
1138
|
+
|
|
1139
|
+
const result = property.toExample('application/json')
|
|
1140
|
+
assert.typeOf(result, 'number')
|
|
1141
|
+
assert.isAtLeast(result as number, 10)
|
|
1142
|
+
})
|
|
1143
|
+
|
|
1144
|
+
test('respects maximum constraint for number property', ({ assert }) => {
|
|
1145
|
+
const dataDomain = new DataDomain()
|
|
1146
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1147
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1148
|
+
const property = entity.addProperty({
|
|
1149
|
+
key: 'score',
|
|
1150
|
+
type: 'number',
|
|
1151
|
+
schema: { maximum: 100 },
|
|
1152
|
+
})
|
|
1153
|
+
|
|
1154
|
+
const result = property.toExample('application/json')
|
|
1155
|
+
assert.typeOf(result, 'number')
|
|
1156
|
+
assert.isAtMost(result as number, 100)
|
|
1157
|
+
})
|
|
1158
|
+
|
|
1159
|
+
test('respects minimum and maximum constraints for number property', ({ assert }) => {
|
|
1160
|
+
const dataDomain = new DataDomain()
|
|
1161
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1162
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1163
|
+
const property = entity.addProperty({
|
|
1164
|
+
key: 'score',
|
|
1165
|
+
type: 'number',
|
|
1166
|
+
schema: { minimum: 10, maximum: 100 },
|
|
1167
|
+
})
|
|
1168
|
+
|
|
1169
|
+
const result = property.toExample('application/json')
|
|
1170
|
+
assert.typeOf(result, 'number')
|
|
1171
|
+
assert.isAtLeast(result as number, 10)
|
|
1172
|
+
assert.isAtMost(result as number, 100)
|
|
1173
|
+
})
|
|
1174
|
+
|
|
1175
|
+
test('respects minimum length constraint for string property', ({ assert }) => {
|
|
1176
|
+
const dataDomain = new DataDomain()
|
|
1177
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1178
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1179
|
+
const property = entity.addProperty({
|
|
1180
|
+
key: 'description',
|
|
1181
|
+
type: 'string',
|
|
1182
|
+
schema: { minimum: 20 },
|
|
1183
|
+
})
|
|
1184
|
+
|
|
1185
|
+
const result = property.toExample('application/json')
|
|
1186
|
+
assert.typeOf(result, 'string')
|
|
1187
|
+
assert.isAtLeast((result as string).length, 20)
|
|
1188
|
+
})
|
|
1189
|
+
|
|
1190
|
+
test('respects maximum length constraint for string property', ({ assert }) => {
|
|
1191
|
+
const dataDomain = new DataDomain()
|
|
1192
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1193
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1194
|
+
const property = entity.addProperty({
|
|
1195
|
+
key: 'name',
|
|
1196
|
+
type: 'string',
|
|
1197
|
+
schema: { maximum: 10 },
|
|
1198
|
+
})
|
|
1199
|
+
|
|
1200
|
+
const result = property.toExample('application/json')
|
|
1201
|
+
assert.typeOf(result, 'string')
|
|
1202
|
+
assert.isAtMost((result as string).length, 10)
|
|
1203
|
+
})
|
|
1204
|
+
|
|
1205
|
+
test('respects enum constraint for string property', ({ assert }) => {
|
|
1206
|
+
const dataDomain = new DataDomain()
|
|
1207
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1208
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1209
|
+
const property = entity.addProperty({
|
|
1210
|
+
key: 'status',
|
|
1211
|
+
type: 'string',
|
|
1212
|
+
schema: { enum: ['active', 'inactive', 'pending'] },
|
|
1213
|
+
})
|
|
1214
|
+
|
|
1215
|
+
const result = property.toExample('application/json')
|
|
1216
|
+
assert.typeOf(result, 'string')
|
|
1217
|
+
assert.oneOf(result as string, ['active', 'inactive', 'pending'])
|
|
1218
|
+
})
|
|
1219
|
+
|
|
1220
|
+
test('uses default value when provided', ({ assert }) => {
|
|
1221
|
+
const dataDomain = new DataDomain()
|
|
1222
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1223
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1224
|
+
const property = entity.addProperty({
|
|
1225
|
+
key: 'status',
|
|
1226
|
+
type: 'string',
|
|
1227
|
+
schema: { defaultValue: { type: 'literal', value: 'default-value' } },
|
|
1228
|
+
})
|
|
1229
|
+
|
|
1230
|
+
const result = property.toExample('application/json')
|
|
1231
|
+
assert.equal(result, 'default-value')
|
|
1232
|
+
})
|
|
1233
|
+
|
|
1234
|
+
test('handles XML mime type', ({ assert }) => {
|
|
1235
|
+
const dataDomain = new DataDomain()
|
|
1236
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1237
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1238
|
+
const property = entity.addProperty({ key: 'name', type: 'string' })
|
|
1239
|
+
|
|
1240
|
+
const result = property.toExample('application/xml')
|
|
1241
|
+
assert.typeOf(result, 'string')
|
|
1242
|
+
assert.isNotEmpty(result as string)
|
|
1243
|
+
})
|
|
1244
|
+
|
|
1245
|
+
test('handles unsupported mime type', ({ assert }) => {
|
|
1246
|
+
const dataDomain = new DataDomain()
|
|
1247
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1248
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1249
|
+
const property = entity.addProperty({ key: 'name', type: 'string' })
|
|
1250
|
+
|
|
1251
|
+
const result = property.toExample('application/octet-stream')
|
|
1252
|
+
assert.isUndefined(result)
|
|
1253
|
+
})
|
|
1254
|
+
|
|
1255
|
+
test('returns undefined when property has no range', ({ assert }) => {
|
|
1256
|
+
const dataDomain = new DataDomain()
|
|
1257
|
+
const property = new DomainProperty(dataDomain, 'test-parent', { key: 'test-prop' })
|
|
1258
|
+
|
|
1259
|
+
// Mock the toApiShape method to return a shape without range
|
|
1260
|
+
const originalToApiShape = property.toApiShape
|
|
1261
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1262
|
+
property.toApiShape = () => ({ range: undefined }) as any
|
|
1263
|
+
|
|
1264
|
+
const result = property.toExample('application/json')
|
|
1265
|
+
assert.isUndefined(result)
|
|
1266
|
+
|
|
1267
|
+
// Restore original method
|
|
1268
|
+
property.toApiShape = originalToApiShape
|
|
1269
|
+
})
|
|
1270
|
+
|
|
1271
|
+
test('respects renderExamples option', ({ assert }) => {
|
|
1272
|
+
const dataDomain = new DataDomain()
|
|
1273
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1274
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1275
|
+
const property = entity.addProperty({ key: 'name', type: 'string' })
|
|
1276
|
+
property.schema = { examples: ['example1', 'example2'] }
|
|
1277
|
+
|
|
1278
|
+
const result = property.toExample('application/json', { renderExamples: false })
|
|
1279
|
+
assert.typeOf(result, 'string')
|
|
1280
|
+
assert.notInclude(['example1', 'example2'], result as string)
|
|
1281
|
+
})
|
|
1282
|
+
|
|
1283
|
+
test('respects renderMocked option', ({ assert }) => {
|
|
1284
|
+
const dataDomain = new DataDomain()
|
|
1285
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1286
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1287
|
+
const property = entity.addProperty({ key: 'name', type: 'string' })
|
|
1288
|
+
|
|
1289
|
+
const result = property.toExample('application/json', { renderMocked: false })
|
|
1290
|
+
// No examples and no mocked value, should return a valid empty example
|
|
1291
|
+
assert.typeOf(result, 'string')
|
|
1292
|
+
assert.isEmpty(result as string)
|
|
1293
|
+
})
|
|
1294
|
+
|
|
1295
|
+
test('respects renderOptional option', ({ assert }) => {
|
|
1296
|
+
const dataDomain = new DataDomain()
|
|
1297
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1298
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1299
|
+
const property = entity.addProperty({ key: 'name', type: 'string', schema: { examples: ['test'] } })
|
|
1300
|
+
|
|
1301
|
+
const result = property.toExample('application/json', { renderOptional: false })
|
|
1302
|
+
assert.isUndefined(result, 'optional properties should not render examples when renderOptional is false')
|
|
1303
|
+
})
|
|
1304
|
+
|
|
1305
|
+
test('handles binary property type', ({ assert }) => {
|
|
1306
|
+
const dataDomain = new DataDomain()
|
|
1307
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1308
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1309
|
+
const property = entity.addProperty({ key: 'data', type: 'binary' })
|
|
1310
|
+
|
|
1311
|
+
const result = property.toExample('application/json')
|
|
1312
|
+
assert.isUndefined(result, 'currently binary properties do not have examples')
|
|
1313
|
+
})
|
|
1314
|
+
|
|
1315
|
+
test('handles array property type', ({ assert }) => {
|
|
1316
|
+
const dataDomain = new DataDomain()
|
|
1317
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1318
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1319
|
+
const property = entity.addProperty({ key: 'tags', type: 'string', multiple: true })
|
|
1320
|
+
|
|
1321
|
+
const result = property.toExample('application/json')
|
|
1322
|
+
assert.typeOf(result, 'string')
|
|
1323
|
+
assert.isNotEmpty(result as string)
|
|
1324
|
+
assert.isArray(JSON.parse(result as string), 'returns an array for "multiple" properties')
|
|
1325
|
+
})
|
|
1326
|
+
|
|
1327
|
+
test('handles property with web binding format', ({ assert }) => {
|
|
1328
|
+
const dataDomain = new DataDomain()
|
|
1329
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1330
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1331
|
+
const property = entity.addProperty({ key: 'price', type: 'number' })
|
|
1332
|
+
|
|
1333
|
+
const webBinding = property.getWebBinding()
|
|
1334
|
+
webBinding.format = 'float'
|
|
1335
|
+
|
|
1336
|
+
const result = property.toExample('application/json')
|
|
1337
|
+
assert.typeOf(result, 'number')
|
|
1338
|
+
})
|
|
1339
|
+
|
|
1340
|
+
test('generates consistent examples for same property', ({ assert }) => {
|
|
1341
|
+
const dataDomain = new DataDomain()
|
|
1342
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1343
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1344
|
+
const property = entity.addProperty({
|
|
1345
|
+
key: 'count',
|
|
1346
|
+
type: 'number',
|
|
1347
|
+
schema: { minimum: 5, maximum: 10 },
|
|
1348
|
+
})
|
|
1349
|
+
|
|
1350
|
+
const result1 = property.toExample('application/json')
|
|
1351
|
+
const result2 = property.toExample('application/json')
|
|
1352
|
+
|
|
1353
|
+
// Both should be numbers within the range
|
|
1354
|
+
assert.typeOf(result1, 'number')
|
|
1355
|
+
assert.typeOf(result2, 'number')
|
|
1356
|
+
assert.isAtLeast(result1 as number, 5)
|
|
1357
|
+
assert.isAtMost(result1 as number, 10)
|
|
1358
|
+
assert.isAtLeast(result2 as number, 5)
|
|
1359
|
+
assert.isAtMost(result2 as number, 10)
|
|
1360
|
+
})
|
|
1361
|
+
|
|
1362
|
+
test('handles property with pattern constraint', ({ assert }) => {
|
|
1363
|
+
const dataDomain = new DataDomain()
|
|
1364
|
+
const model = dataDomain.addModel({ key: 'test-model' })
|
|
1365
|
+
const entity = model.addEntity({ key: 'test-entity' })
|
|
1366
|
+
const property = entity.addProperty({
|
|
1367
|
+
key: 'email',
|
|
1368
|
+
type: 'string',
|
|
1369
|
+
schema: { pattern: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$' },
|
|
1370
|
+
})
|
|
1371
|
+
|
|
1372
|
+
const result = property.toExample('application/json')
|
|
1373
|
+
assert.typeOf(result, 'string')
|
|
1374
|
+
assert.isNotEmpty(result as string)
|
|
1375
|
+
// Should match email pattern
|
|
1376
|
+
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
|
|
1377
|
+
assert.match(result as string, emailRegex)
|
|
1378
|
+
})
|
|
1379
|
+
})
|