@api-client/core 0.18.16 → 0.18.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/{modeling → decorators}/observed.d.ts +3 -3
- package/build/src/decorators/observed.d.ts.map +1 -0
- package/build/src/{modeling → decorators}/observed.js +4 -4
- package/build/src/decorators/observed.js.map +1 -0
- package/build/src/modeling/ApiModel.js +1 -1
- package/build/src/modeling/ApiModel.js.map +1 -1
- package/build/src/modeling/DataDomain.d.ts +7 -2
- package/build/src/modeling/DataDomain.d.ts.map +1 -1
- package/build/src/modeling/DataDomain.js +15 -2
- package/build/src/modeling/DataDomain.js.map +1 -1
- package/build/src/modeling/DomainAssociation.d.ts +7 -0
- package/build/src/modeling/DomainAssociation.d.ts.map +1 -1
- package/build/src/modeling/DomainAssociation.js +44 -1
- package/build/src/modeling/DomainAssociation.js.map +1 -1
- package/build/src/modeling/DomainEntity.d.ts +6 -0
- package/build/src/modeling/DomainEntity.d.ts.map +1 -1
- package/build/src/modeling/DomainEntity.js +21 -1
- package/build/src/modeling/DomainEntity.js.map +1 -1
- package/build/src/modeling/DomainModel.js +1 -1
- package/build/src/modeling/DomainModel.js.map +1 -1
- package/build/src/modeling/DomainNamespace.js +1 -1
- package/build/src/modeling/DomainNamespace.js.map +1 -1
- package/build/src/modeling/DomainProperty.d.ts +5 -0
- package/build/src/modeling/DomainProperty.d.ts.map +1 -1
- package/build/src/modeling/DomainProperty.js +38 -1
- package/build/src/modeling/DomainProperty.js.map +1 -1
- package/build/src/modeling/DomainSerialization.d.ts +6 -3
- package/build/src/modeling/DomainSerialization.d.ts.map +1 -1
- package/build/src/modeling/DomainSerialization.js +374 -52
- package/build/src/modeling/DomainSerialization.js.map +1 -1
- package/build/src/modeling/types.d.ts +69 -2
- package/build/src/modeling/types.d.ts.map +1 -1
- package/build/src/modeling/types.js.map +1 -1
- package/build/src/models/Thing.js +1 -1
- package/build/src/models/Thing.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/data/models/example-generator-api.json +10 -10
- package/package.json +2 -1
- package/src/{modeling → decorators}/observed.ts +5 -5
- package/src/modeling/ApiModel.ts +1 -1
- package/src/modeling/DataDomain.ts +24 -3
- package/src/modeling/DomainAssociation.ts +51 -1
- package/src/modeling/DomainEntity.ts +24 -1
- package/src/modeling/DomainModel.ts +1 -1
- package/src/modeling/DomainNamespace.ts +1 -1
- package/src/modeling/DomainProperty.ts +43 -1
- package/src/modeling/DomainSerialization.ts +440 -56
- package/src/modeling/types.ts +73 -2
- package/src/models/Thing.ts +1 -1
- package/tests/unit/decorators/observed.spec.ts +527 -0
- package/tests/unit/modeling/data_domain_serialization.spec.ts +508 -0
- package/tests/unit/modeling/domain_asociation.spec.ts +376 -0
- package/tests/unit/modeling/domain_entity.spec.ts +147 -0
- package/tests/unit/modeling/domain_property.spec.ts +273 -0
- package/build/src/modeling/observed.d.ts.map +0 -1
- package/build/src/modeling/observed.js.map +0 -1
|
@@ -42071,10 +42071,10 @@
|
|
|
42071
42071
|
"@id": "#197"
|
|
42072
42072
|
},
|
|
42073
42073
|
{
|
|
42074
|
-
"@id": "#
|
|
42074
|
+
"@id": "#200"
|
|
42075
42075
|
},
|
|
42076
42076
|
{
|
|
42077
|
-
"@id": "#
|
|
42077
|
+
"@id": "#203"
|
|
42078
42078
|
},
|
|
42079
42079
|
{
|
|
42080
42080
|
"@id": "#206"
|
|
@@ -42810,10 +42810,10 @@
|
|
|
42810
42810
|
"@id": "#219"
|
|
42811
42811
|
},
|
|
42812
42812
|
{
|
|
42813
|
-
"@id": "#
|
|
42813
|
+
"@id": "#210"
|
|
42814
42814
|
},
|
|
42815
42815
|
{
|
|
42816
|
-
"@id": "#
|
|
42816
|
+
"@id": "#213"
|
|
42817
42817
|
},
|
|
42818
42818
|
{
|
|
42819
42819
|
"@id": "#216"
|
|
@@ -43499,7 +43499,7 @@
|
|
|
43499
43499
|
"doc:ExternalDomainElement",
|
|
43500
43500
|
"doc:DomainElement"
|
|
43501
43501
|
],
|
|
43502
|
-
"doc:raw": "
|
|
43502
|
+
"doc:raw": "class: '3'\ndescription: '150 - 300'\nnumberOfFte: 5500\nnumberOfEmployees: 5232\n",
|
|
43503
43503
|
"core:mediaType": "application/yaml",
|
|
43504
43504
|
"sourcemaps:sources": [
|
|
43505
43505
|
{
|
|
@@ -43520,7 +43520,7 @@
|
|
|
43520
43520
|
"doc:ExternalDomainElement",
|
|
43521
43521
|
"doc:DomainElement"
|
|
43522
43522
|
],
|
|
43523
|
-
"doc:raw": "
|
|
43523
|
+
"doc:raw": "code: 'J'\ndescription: 'Information and communication'\n",
|
|
43524
43524
|
"core:mediaType": "application/yaml",
|
|
43525
43525
|
"sourcemaps:sources": [
|
|
43526
43526
|
{
|
|
@@ -44232,7 +44232,7 @@
|
|
|
44232
44232
|
"doc:ExternalDomainElement",
|
|
44233
44233
|
"doc:DomainElement"
|
|
44234
44234
|
],
|
|
44235
|
-
"doc:raw": "type: 'GENERAL'\ncountryDialCode : '+32'\nareaCode : '
|
|
44235
|
+
"doc:raw": "type: 'GENERAL'\ncountryDialCode : '+32'\nareaCode : '22'\nsubscriberNumber: '12.87.00'\nformatted: '+32-(0)22 000000'\n",
|
|
44236
44236
|
"core:mediaType": "application/yaml",
|
|
44237
44237
|
"sourcemaps:sources": [
|
|
44238
44238
|
{
|
|
@@ -44253,7 +44253,7 @@
|
|
|
44253
44253
|
"doc:ExternalDomainElement",
|
|
44254
44254
|
"doc:DomainElement"
|
|
44255
44255
|
],
|
|
44256
|
-
"doc:raw": "type: 'GENERAL'\ncountryDialCode : '+32'\nareaCode : '
|
|
44256
|
+
"doc:raw": "type: 'GENERAL'\ncountryDialCode : '+32'\nareaCode : '21'\nsubscriberNumber: '12.87.00'\nformatted: '+32-(0)21 302099'\n",
|
|
44257
44257
|
"core:mediaType": "application/yaml",
|
|
44258
44258
|
"sourcemaps:sources": [
|
|
44259
44259
|
{
|
|
@@ -44771,12 +44771,12 @@
|
|
|
44771
44771
|
{
|
|
44772
44772
|
"@id": "#202/source-map/lexical/element_0",
|
|
44773
44773
|
"sourcemaps:element": "amf://id#202",
|
|
44774
|
-
"sourcemaps:value": "[(1,0)-(
|
|
44774
|
+
"sourcemaps:value": "[(1,0)-(5,0)]"
|
|
44775
44775
|
},
|
|
44776
44776
|
{
|
|
44777
44777
|
"@id": "#205/source-map/lexical/element_0",
|
|
44778
44778
|
"sourcemaps:element": "amf://id#205",
|
|
44779
|
-
"sourcemaps:value": "[(1,0)-(
|
|
44779
|
+
"sourcemaps:value": "[(1,0)-(3,0)]"
|
|
44780
44780
|
},
|
|
44781
44781
|
{
|
|
44782
44782
|
"@id": "#208/source-map/lexical/element_0",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@api-client/core",
|
|
3
3
|
"description": "The API Client's core client library. Works in NodeJS and in a ES enabled browser.",
|
|
4
|
-
"version": "0.18.
|
|
4
|
+
"version": "0.18.18",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"exports": {
|
|
7
7
|
"./browser.js": {
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
"#authorization/*": "./src/authorization/*",
|
|
58
58
|
"#cookies/*": "./src/cookies/*",
|
|
59
59
|
"#data/*": "./src/data/*",
|
|
60
|
+
"#decorators/*": "./src/decorators/*",
|
|
60
61
|
"#events/*": "./src/events/*",
|
|
61
62
|
"#lib/*": "./src/lib/*",
|
|
62
63
|
"#mocking/*": "./src/mocking/*",
|
|
@@ -73,10 +73,10 @@ export function toRaw<T extends object = object>(source: object, target: T): T |
|
|
|
73
73
|
* - As a class property decorator
|
|
74
74
|
* - As a class setter decorator
|
|
75
75
|
*
|
|
76
|
-
* The property class either has to have
|
|
76
|
+
* The property class either has to have the `domain` property
|
|
77
77
|
* or a `notifyChange` method. The decorator will call the
|
|
78
78
|
* `notifyChange` method if it exists. Otherwise, it will
|
|
79
|
-
* call the `notifyChange` method of the root domain.
|
|
79
|
+
* call the `notifyChange` method of the root domain (the `domain` property).
|
|
80
80
|
*/
|
|
81
81
|
export function observed(config: ObserveConfig = {}): PropertyDecorator {
|
|
82
82
|
return <C extends DomainInstance, V>(
|
|
@@ -138,7 +138,7 @@ export function observed(config: ObserveConfig = {}): PropertyDecorator {
|
|
|
138
138
|
map = {}
|
|
139
139
|
Reflect.set(this, reactiveSymbol, map)
|
|
140
140
|
}
|
|
141
|
-
if (map[context.name] ===
|
|
141
|
+
if (map[context.name] === value) {
|
|
142
142
|
return
|
|
143
143
|
}
|
|
144
144
|
const notify = () => {
|
|
@@ -196,7 +196,7 @@ export function observed(config: ObserveConfig = {}): PropertyDecorator {
|
|
|
196
196
|
* property itself.
|
|
197
197
|
*/
|
|
198
198
|
export function retargetChange() {
|
|
199
|
-
return <C extends DomainInstance, V extends EventTarget>(
|
|
199
|
+
return <C extends DomainInstance, V extends EventTarget | undefined>(
|
|
200
200
|
target: StandardPropertyTarget<C, V>,
|
|
201
201
|
context: StandardPropertyContext<C, V>
|
|
202
202
|
): any => {
|
|
@@ -215,7 +215,7 @@ export function retargetChange() {
|
|
|
215
215
|
map = {}
|
|
216
216
|
Reflect.set(this, reactiveSymbol, map)
|
|
217
217
|
}
|
|
218
|
-
if (map[context.name] ===
|
|
218
|
+
if (map[context.name] === value) {
|
|
219
219
|
return
|
|
220
220
|
}
|
|
221
221
|
const oldValue = map[context.name]
|
package/src/modeling/ApiModel.ts
CHANGED
|
@@ -14,7 +14,7 @@ import type {
|
|
|
14
14
|
} from './types.js'
|
|
15
15
|
import { DataDomain } from './DataDomain.js'
|
|
16
16
|
import { DependentModel, type DependentModelSchema, type DomainDependency } from './DependentModel.js'
|
|
17
|
-
import { observed, toRaw } from '
|
|
17
|
+
import { observed, toRaw } from '../decorators/observed.js'
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Contact information for the exposed API.
|
|
@@ -8,7 +8,14 @@ import {
|
|
|
8
8
|
DomainNamespaceKind,
|
|
9
9
|
DomainPropertyKind,
|
|
10
10
|
} from '../models/kinds.js'
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
AssociationAddOptions,
|
|
13
|
+
DeserializationIssue,
|
|
14
|
+
DeserializationMode,
|
|
15
|
+
DomainGraphEdge,
|
|
16
|
+
DomainGraphNodeType,
|
|
17
|
+
SerializedGraph,
|
|
18
|
+
} from './types.js'
|
|
12
19
|
import { type DomainNamespaceSchema, DomainNamespace, type NamespaceOrderedItem } from './DomainNamespace.js'
|
|
13
20
|
import { type DomainModelSchema, DomainModel } from './DomainModel.js'
|
|
14
21
|
import { type DomainEntitySchema, DomainEntity } from './DomainEntity.js'
|
|
@@ -146,6 +153,12 @@ export class DataDomain extends DependentModel {
|
|
|
146
153
|
*/
|
|
147
154
|
accessor fields: NamespaceOrderedItem[]
|
|
148
155
|
|
|
156
|
+
/**
|
|
157
|
+
* The list of issues encountered during deserialization.
|
|
158
|
+
* This is only populated when deserialization fails in lenient mode.
|
|
159
|
+
*/
|
|
160
|
+
issues: DeserializationIssue[] = []
|
|
161
|
+
|
|
149
162
|
static createSchema(input: Partial<DataDomainSchema> = {}): DataDomainSchema {
|
|
150
163
|
const { key = nanoid(), fields } = input
|
|
151
164
|
const info = Thing.fromJSON(input.info, { name: 'Unnamed domain' }).toJSON()
|
|
@@ -178,7 +191,7 @@ export class DataDomain extends DependentModel {
|
|
|
178
191
|
* @param state The previously serialized state of the graph.
|
|
179
192
|
* @param dependencies An array of foreign data domains to register with this domain.
|
|
180
193
|
*/
|
|
181
|
-
constructor(state?: Partial<DataDomainSchema>, dependencies: DomainDependency[] = []) {
|
|
194
|
+
constructor(state?: Partial<DataDomainSchema>, dependencies: DomainDependency[] = [], mode?: DeserializationMode) {
|
|
182
195
|
const init = DataDomain.createSchema(state)
|
|
183
196
|
const instances: DataDomain[] = []
|
|
184
197
|
for (const dep of dependencies) {
|
|
@@ -195,7 +208,15 @@ export class DataDomain extends DependentModel {
|
|
|
195
208
|
this.kind = init.kind
|
|
196
209
|
this.key = init.key
|
|
197
210
|
this.info = new Thing(init.info)
|
|
198
|
-
|
|
211
|
+
const result = deserialize(this, {
|
|
212
|
+
json: init.graph,
|
|
213
|
+
dependencies: instances,
|
|
214
|
+
mode: mode || 'strict',
|
|
215
|
+
})
|
|
216
|
+
this.graph = result.graph
|
|
217
|
+
if (result.issues.length > 0 && mode === 'lenient') {
|
|
218
|
+
this.issues = result.issues
|
|
219
|
+
}
|
|
199
220
|
if (Array.isArray(init.fields)) {
|
|
200
221
|
this.fields = [...init.fields]
|
|
201
222
|
} else {
|
|
@@ -3,7 +3,7 @@ import { DomainAssociationKind } from '../models/kinds.js'
|
|
|
3
3
|
import { DomainElement, type DomainElementSchema } from './DomainElement.js'
|
|
4
4
|
import { nanoid } from '../nanoid.js'
|
|
5
5
|
import { type IThing, Thing } from '../models/Thing.js'
|
|
6
|
-
import { observed, retargetChange, toRaw } from '
|
|
6
|
+
import { observed, retargetChange, toRaw } from '../decorators/observed.js'
|
|
7
7
|
import type { DomainEntity } from './DomainEntity.js'
|
|
8
8
|
import type { IApiAssociationShape, IApiPropertyShape } from '../amf/definitions/Shapes.js'
|
|
9
9
|
import type { AssociationBinding, AssociationBindings, AssociationWebBindings } from './Bindings.js'
|
|
@@ -591,4 +591,54 @@ export class DomainAssociation extends DomainElement {
|
|
|
591
591
|
hasSemantic(semanticId: SemanticType): boolean {
|
|
592
592
|
return this.semantics.some((s) => s.id === semanticId)
|
|
593
593
|
}
|
|
594
|
+
|
|
595
|
+
/**
|
|
596
|
+
* Creates a duplicate of this association.
|
|
597
|
+
* It places the duplicate on the parent entity right after the original association.
|
|
598
|
+
*
|
|
599
|
+
* @returns A new `DomainAssociation` instance that is a duplicate of this one.
|
|
600
|
+
*/
|
|
601
|
+
duplicate(): DomainAssociation {
|
|
602
|
+
const parent = this.getParentInstance()
|
|
603
|
+
if (!parent) {
|
|
604
|
+
throw new Error(`Cannot duplicate association ${this.key} as it has no parent entity.`)
|
|
605
|
+
}
|
|
606
|
+
const originalIndex = parent.fields.findIndex((f) => f.key === this.key)
|
|
607
|
+
if (originalIndex === -1) {
|
|
608
|
+
throw new Error(`Cannot duplicate association ${this.key} as it does not exist on the parent entity fields list.`)
|
|
609
|
+
}
|
|
610
|
+
const baseName = this.info.name || 'field'
|
|
611
|
+
const newName = parent.generateUniqueName(baseName)
|
|
612
|
+
|
|
613
|
+
// Making a copy and restoring it through the `addAssociation()` method
|
|
614
|
+
// scales better than copying it manually.
|
|
615
|
+
const copy = this.toJSON() as Partial<DomainAssociationSchema>
|
|
616
|
+
|
|
617
|
+
// Delete properties that should not be copied
|
|
618
|
+
delete copy.key
|
|
619
|
+
delete copy.targets
|
|
620
|
+
|
|
621
|
+
// Set the new name for the duplicated association
|
|
622
|
+
if (copy.info) {
|
|
623
|
+
copy.info.name = newName
|
|
624
|
+
} else {
|
|
625
|
+
copy.info = { name: newName }
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
const result = parent.addAssociation({}, copy)
|
|
629
|
+
|
|
630
|
+
// Copy the target entities
|
|
631
|
+
for (const target of this.targets) {
|
|
632
|
+
result.addTarget(target.key, target.domain)
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// Move the duplicate to be right after the original
|
|
636
|
+
const fromIndex = parent.fields.length - 1
|
|
637
|
+
const duplicateField = parent.fields[fromIndex]
|
|
638
|
+
parent.fields.splice(fromIndex, 1)
|
|
639
|
+
parent.fields.splice(originalIndex + 1, 0, duplicateField)
|
|
640
|
+
|
|
641
|
+
this.domain.notifyChange()
|
|
642
|
+
return result
|
|
643
|
+
}
|
|
594
644
|
}
|
|
@@ -3,7 +3,7 @@ import { DomainAssociationKind, DomainEntityKind, DomainPropertyKind } from '../
|
|
|
3
3
|
import { DomainElement, type DomainElementSchema } from './DomainElement.js'
|
|
4
4
|
import { nanoid } from '../nanoid.js'
|
|
5
5
|
import { type IThing, Thing } from '../models/Thing.js'
|
|
6
|
-
import { observed, retargetChange, toRaw } from '
|
|
6
|
+
import { observed, retargetChange, toRaw } from '../decorators/observed.js'
|
|
7
7
|
import type { IShapeUnion } from '../amf/definitions/Shapes.js'
|
|
8
8
|
import { DomainProperty, type DomainPropertySchema } from './DomainProperty.js'
|
|
9
9
|
import { RemovePropertyException } from '../exceptions/remove_property_exception.js'
|
|
@@ -880,4 +880,27 @@ export class DomainEntity extends DomainElement {
|
|
|
880
880
|
hasSemantic(semanticId: SemanticType): boolean {
|
|
881
881
|
return this.semantics.some((s) => s.id === semanticId)
|
|
882
882
|
}
|
|
883
|
+
|
|
884
|
+
/**
|
|
885
|
+
* Generates a unique name by appending a number to the base name.
|
|
886
|
+
* @param baseName The base name to make unique.
|
|
887
|
+
* @returns A unique name within the current entity.
|
|
888
|
+
*/
|
|
889
|
+
generateUniqueName(baseName: string): string {
|
|
890
|
+
const existingNames = new Set<string>()
|
|
891
|
+
for (const field of this.listFields()) {
|
|
892
|
+
if (field.info.name) {
|
|
893
|
+
existingNames.add(field.info.name)
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
let counter = 2
|
|
898
|
+
let newName = `${baseName}_copy`
|
|
899
|
+
while (existingNames.has(newName)) {
|
|
900
|
+
newName = `${baseName}_copy_${counter}`
|
|
901
|
+
counter++
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
return newName
|
|
905
|
+
}
|
|
883
906
|
}
|
|
@@ -3,7 +3,7 @@ import { DomainEntityKind, DomainModelKind } from '../models/kinds.js'
|
|
|
3
3
|
import { DomainElement, DomainElementSchema } from './DomainElement.js'
|
|
4
4
|
import { nanoid } from '../nanoid.js'
|
|
5
5
|
import { type IThing, Thing } from '../models/Thing.js'
|
|
6
|
-
import { observed, retargetChange } from '
|
|
6
|
+
import { observed, retargetChange } from '../decorators/observed.js'
|
|
7
7
|
import type { DomainNamespace } from './DomainNamespace.js'
|
|
8
8
|
import type { FileBreadcrumb } from '../models/store/File.js'
|
|
9
9
|
import { DomainEntity, type DomainEntitySchema } from './DomainEntity.js'
|
|
@@ -3,7 +3,7 @@ import { DomainModelKind, DomainNamespaceKind } from '../models/kinds.js'
|
|
|
3
3
|
import { DomainElement, DomainElementSchema } from './DomainElement.js'
|
|
4
4
|
import { nanoid } from '../nanoid.js'
|
|
5
5
|
import { IThing, Thing } from '../models/Thing.js'
|
|
6
|
-
import { observed, retargetChange } from '
|
|
6
|
+
import { observed, retargetChange } from '../decorators/observed.js'
|
|
7
7
|
import { DomainModel, DomainModelSchema } from './DomainModel.js'
|
|
8
8
|
import { RemoveNamespaceException } from '../exceptions/remove_namespace_exception.js'
|
|
9
9
|
import { RemoveModelException } from '../exceptions/remove_model_exception.js'
|
|
@@ -3,7 +3,7 @@ import { DomainPropertyKind } from '../models/kinds.js'
|
|
|
3
3
|
import { DomainElement, type DomainElementSchema } from './DomainElement.js'
|
|
4
4
|
import { nanoid } from '../nanoid.js'
|
|
5
5
|
import { type IThing, Thing } from '../models/Thing.js'
|
|
6
|
-
import { observed, retargetChange, toRaw } from '
|
|
6
|
+
import { observed, retargetChange, toRaw } from '../decorators/observed.js'
|
|
7
7
|
import {
|
|
8
8
|
type BinaryFormat,
|
|
9
9
|
BinaryFormats,
|
|
@@ -617,4 +617,46 @@ export class DomainProperty extends DomainElement {
|
|
|
617
617
|
hasSemantic(semanticId: SemanticType): boolean {
|
|
618
618
|
return this.semantics.some((s) => s.id === semanticId)
|
|
619
619
|
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Creates a duplicate of this domain property on the parent entity.
|
|
623
|
+
* It places the duplicate on the parent entity right after the original property.
|
|
624
|
+
*/
|
|
625
|
+
duplicate(): DomainProperty {
|
|
626
|
+
const parent = this.getParentInstance()
|
|
627
|
+
if (!parent) {
|
|
628
|
+
throw new Error(`Cannot duplicate property ${this.key} as it has no parent entity.`)
|
|
629
|
+
}
|
|
630
|
+
const originalIndex = parent.fields.findIndex((f) => f.key === this.key)
|
|
631
|
+
if (originalIndex === -1) {
|
|
632
|
+
throw new Error(`Cannot duplicate property ${this.key} as it does not exist on the parent entity fields list.`)
|
|
633
|
+
}
|
|
634
|
+
const baseName = this.info.name || 'field'
|
|
635
|
+
const newName = parent.generateUniqueName(baseName)
|
|
636
|
+
|
|
637
|
+
// Making a copy and restoring it through the `addProperty()` method
|
|
638
|
+
// scales better than copying it manually.
|
|
639
|
+
const copy = this.toJSON() as Partial<DomainPropertySchema>
|
|
640
|
+
|
|
641
|
+
// Delete properties that should not be copied
|
|
642
|
+
delete copy.key
|
|
643
|
+
delete copy.primary // Don't duplicate the primary key
|
|
644
|
+
|
|
645
|
+
// Set the new name for the duplicated property
|
|
646
|
+
if (copy.info) {
|
|
647
|
+
copy.info.name = newName
|
|
648
|
+
} else {
|
|
649
|
+
copy.info = { name: newName }
|
|
650
|
+
}
|
|
651
|
+
const result = parent.addProperty(copy)
|
|
652
|
+
|
|
653
|
+
// Move the duplicate to be right after the original
|
|
654
|
+
const fromIndex = parent.fields.length - 1
|
|
655
|
+
const duplicateField = parent.fields[fromIndex]
|
|
656
|
+
parent.fields.splice(fromIndex, 1)
|
|
657
|
+
parent.fields.splice(originalIndex + 1, 0, duplicateField)
|
|
658
|
+
|
|
659
|
+
this.domain.notifyChange()
|
|
660
|
+
return result
|
|
661
|
+
}
|
|
620
662
|
}
|