@api-client/core 0.11.7 → 0.11.8
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/browser.d.ts +2 -0
- package/build/src/browser.d.ts.map +1 -1
- package/build/src/browser.js +2 -0
- package/build/src/browser.js.map +1 -1
- package/build/src/index.d.ts +2 -0
- package/build/src/index.d.ts.map +1 -1
- package/build/src/index.js +2 -0
- package/build/src/index.js.map +1 -1
- package/build/src/modeling/DataAssociation.d.ts +8 -0
- package/build/src/modeling/DataAssociation.d.ts.map +1 -1
- package/build/src/modeling/DataAssociation.js +20 -0
- package/build/src/modeling/DataAssociation.js.map +1 -1
- package/build/src/modeling/DataEntity.d.ts +17 -1
- package/build/src/modeling/DataEntity.d.ts.map +1 -1
- package/build/src/modeling/DataEntity.js +48 -6
- package/build/src/modeling/DataEntity.js.map +1 -1
- package/build/src/modeling/DataModel.d.ts +10 -1
- package/build/src/modeling/DataModel.d.ts.map +1 -1
- package/build/src/modeling/DataModel.js +22 -2
- package/build/src/modeling/DataModel.js.map +1 -1
- package/build/src/modeling/DataNamespace.d.ts +60 -55
- package/build/src/modeling/DataNamespace.d.ts.map +1 -1
- package/build/src/modeling/DataNamespace.js +133 -116
- package/build/src/modeling/DataNamespace.js.map +1 -1
- package/build/src/modeling/DataProperty.d.ts +16 -3
- package/build/src/modeling/DataProperty.d.ts.map +1 -1
- package/build/src/modeling/DataProperty.js +28 -2
- package/build/src/modeling/DataProperty.js.map +1 -1
- package/build/src/modeling/ImpactAnalysis.d.ts +290 -0
- package/build/src/modeling/ImpactAnalysis.d.ts.map +1 -0
- package/build/src/modeling/ImpactAnalysis.js +437 -0
- package/build/src/modeling/ImpactAnalysis.js.map +1 -0
- package/build/src/modeling/types.d.ts +14 -0
- package/build/src/modeling/types.d.ts.map +1 -0
- package/build/src/modeling/types.js +2 -0
- package/build/src/modeling/types.js.map +1 -0
- package/package.json +6 -6
- package/src/modeling/DataAssociation.ts +21 -0
- package/src/modeling/DataEntity.ts +59 -10
- package/src/modeling/DataModel.ts +24 -2
- package/src/modeling/DataNamespace.ts +150 -137
- package/src/modeling/DataProperty.ts +32 -3
- package/src/modeling/ImpactAnalysis.ts +519 -0
- package/src/modeling/types.ts +13 -0
- package/tests/servers/ExpressServer.ts +1 -0
- package/tests/servers/express-routes/BaseApi.ts +1 -1
- package/tests/servers/express-routes/TestsApi.ts +1 -1
- package/tests/unit/modeling/data_association.spec.ts +73 -0
- package/tests/unit/modeling/data_entity.spec.ts +111 -1
- package/tests/unit/modeling/data_model.spec.ts +54 -0
- package/tests/unit/modeling/data_namespace.spec.ts +46 -1
- package/tests/unit/modeling/data_property.spec.ts +73 -0
- package/tests/unit/modeling/impact_analysis.spec.ts +373 -0
|
@@ -16,9 +16,16 @@ import { RemoveAssociationException } from '../exceptions/remove_association_exc
|
|
|
16
16
|
import { ValidationError, type FieldValidationMessage } from '../exceptions/validation_error.js'
|
|
17
17
|
import { RemoveEntityException } from '../exceptions/remove_entity_exception.js'
|
|
18
18
|
import { ForeignAssociationException } from '../exceptions/foreign_association_exception.js'
|
|
19
|
+
import type { DataDomainRemoveOptions } from './types.js'
|
|
19
20
|
|
|
20
21
|
interface OrderedItem {
|
|
22
|
+
/**
|
|
23
|
+
* The type of the ordered item.
|
|
24
|
+
*/
|
|
21
25
|
type: 'property' | 'association'
|
|
26
|
+
/**
|
|
27
|
+
* The key of the ordered item.
|
|
28
|
+
*/
|
|
22
29
|
key: string
|
|
23
30
|
}
|
|
24
31
|
|
|
@@ -556,6 +563,7 @@ export class DataEntity {
|
|
|
556
563
|
|
|
557
564
|
/**
|
|
558
565
|
* Computes a list of entities that are associated with the current entity.
|
|
566
|
+
* This is the association-out (out-edge) direction.
|
|
559
567
|
*/
|
|
560
568
|
getComputedAssociations(): DataEntity[] {
|
|
561
569
|
const { associations } = this
|
|
@@ -577,23 +585,43 @@ export class DataEntity {
|
|
|
577
585
|
/**
|
|
578
586
|
* Removes self from the namespace with all properties and attributes.
|
|
579
587
|
*/
|
|
580
|
-
remove(): void {
|
|
588
|
+
remove(opts: DataDomainRemoveOptions = {}): void {
|
|
581
589
|
const { key, properties, associations, root } = this
|
|
582
590
|
// check if some entity has reference to this entity as a target
|
|
583
|
-
const
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
if (associationsToEntity.length > 0) {
|
|
587
|
-
const entitiesNames = associationsToEntity.reduce<string[]>((acc, association) => {
|
|
591
|
+
const toEdges = this.root.definitions.associations.filter((a) => a.targets.some((t) => t.key === this.key))
|
|
592
|
+
if (toEdges.length > 0) {
|
|
593
|
+
const result = toEdges.reduce<{ entity: DataEntity; association: DataAssociation }[]>((acc, association) => {
|
|
588
594
|
const entity = root.definitions.entities.find((e) => e.associations.some((a) => a.key === association.key))
|
|
589
595
|
if (entity) {
|
|
590
|
-
acc.push(entity
|
|
596
|
+
acc.push({ entity, association })
|
|
591
597
|
}
|
|
592
598
|
return acc
|
|
593
599
|
}, [])
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
600
|
+
if (opts.force) {
|
|
601
|
+
// remove the association from the entity
|
|
602
|
+
result.forEach(({ entity: item, association }) => {
|
|
603
|
+
item.removeAssociation(association.key)
|
|
604
|
+
})
|
|
605
|
+
} else {
|
|
606
|
+
const entitiesNames = result.map(({ entity }) => entity.info.renderLabel || entity.key)
|
|
607
|
+
throw new RemoveEntityException(
|
|
608
|
+
`Cannot remove entity ${this.info.renderLabel} because it is used as a target in associations in entities: ${entitiesNames.join(', ')}.`
|
|
609
|
+
)
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
const children = this.getComputedChildren()
|
|
614
|
+
if (children.length > 0) {
|
|
615
|
+
if (opts.force) {
|
|
616
|
+
children.forEach((child) => {
|
|
617
|
+
child.parents = child.parents.filter((i) => i !== this.key)
|
|
618
|
+
})
|
|
619
|
+
} else {
|
|
620
|
+
const childrenNames = children.map((i) => i.info.renderLabel || i.key)
|
|
621
|
+
throw new RemoveEntityException(
|
|
622
|
+
`Cannot remove entity ${this.info.renderLabel} because it is a parent for the following entities: ${childrenNames.join(', ')}.`
|
|
623
|
+
)
|
|
624
|
+
}
|
|
597
625
|
}
|
|
598
626
|
|
|
599
627
|
// remove own stuff
|
|
@@ -962,4 +990,25 @@ export class DataEntity {
|
|
|
962
990
|
}
|
|
963
991
|
return false
|
|
964
992
|
}
|
|
993
|
+
|
|
994
|
+
/**
|
|
995
|
+
* Checks whether the entity is a child of the given namespace or data model.
|
|
996
|
+
* The relationship doesn't have to be direct, as long as the entity is in the hierarchy it will return true.
|
|
997
|
+
*
|
|
998
|
+
* @param key The key of the parent to check.
|
|
999
|
+
* @returns True if this entity is a child of the given namespace or data model.
|
|
1000
|
+
*/
|
|
1001
|
+
isChildOf(key: string): boolean {
|
|
1002
|
+
if (this.key === key) {
|
|
1003
|
+
return false
|
|
1004
|
+
}
|
|
1005
|
+
const parent = this.getParentInstance()
|
|
1006
|
+
if (!parent) {
|
|
1007
|
+
return false
|
|
1008
|
+
}
|
|
1009
|
+
if (parent.key === key) {
|
|
1010
|
+
return true
|
|
1011
|
+
}
|
|
1012
|
+
return parent.isChildOf(key)
|
|
1013
|
+
}
|
|
965
1014
|
}
|
|
@@ -4,6 +4,7 @@ import { DataEntity, IDataEntity } from './DataEntity.js'
|
|
|
4
4
|
import type { DataItemAdaptingOptions, DataNamespace } from './DataNamespace.js'
|
|
5
5
|
import { FileBreadcrumb } from '../models/store/File.js'
|
|
6
6
|
import { DataModelKind } from '../models/kinds.js'
|
|
7
|
+
import type { DataDomainRemoveOptions } from './types.js'
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Data model creates a logical structure around data entities.
|
|
@@ -129,10 +130,10 @@ export class DataModel {
|
|
|
129
130
|
/**
|
|
130
131
|
* Removes self from the namespace with all entities.
|
|
131
132
|
*/
|
|
132
|
-
remove(): void {
|
|
133
|
+
remove(opts?: DataDomainRemoveOptions): void {
|
|
133
134
|
const { key, entities, root } = this
|
|
134
135
|
// remove children
|
|
135
|
-
entities.forEach((e) => e.remove())
|
|
136
|
+
entities.forEach((e) => e.remove(opts))
|
|
136
137
|
|
|
137
138
|
// remove self from the parent
|
|
138
139
|
const parent = this.getParentInstance()
|
|
@@ -249,4 +250,25 @@ export class DataModel {
|
|
|
249
250
|
})
|
|
250
251
|
return result.reverse()
|
|
251
252
|
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Checks whether the data model is a child of the given namespace.
|
|
256
|
+
* The relationship doesn't have to be direct, as long as the data model is in the hierarchy it will return true.
|
|
257
|
+
*
|
|
258
|
+
* @param key The key of the parent namespace to check.
|
|
259
|
+
* @returns True if this data model is a child of the given namespace.
|
|
260
|
+
*/
|
|
261
|
+
isChildOf(key: string): boolean {
|
|
262
|
+
if (this.key === key) {
|
|
263
|
+
return false
|
|
264
|
+
}
|
|
265
|
+
const parent = this.getParentInstance()
|
|
266
|
+
if (!parent) {
|
|
267
|
+
return false
|
|
268
|
+
}
|
|
269
|
+
if (parent.key === key) {
|
|
270
|
+
return true
|
|
271
|
+
}
|
|
272
|
+
return parent.isChildOf(key)
|
|
273
|
+
}
|
|
252
274
|
}
|
|
@@ -6,6 +6,7 @@ import { IDataModel, DataModel } from './DataModel.js'
|
|
|
6
6
|
import { IDataProperty, DataProperty } from './DataProperty.js'
|
|
7
7
|
import { DataNamespaceKind, DataModelKind } from '../models/kinds.js'
|
|
8
8
|
import v4 from '../lib/uuid.js'
|
|
9
|
+
import type { DataDomainRemoveOptions } from './types.js'
|
|
9
10
|
|
|
10
11
|
type ItemKind = typeof DataNamespaceKind | typeof DataModelKind
|
|
11
12
|
|
|
@@ -60,7 +61,10 @@ interface ForeignNamespace {
|
|
|
60
61
|
version: string
|
|
61
62
|
}
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Data namespace is a logical description of the hierarchy in the data.
|
|
66
|
+
*/
|
|
67
|
+
export interface IDataNamespace {
|
|
64
68
|
kind: typeof DataNamespaceKind
|
|
65
69
|
/**
|
|
66
70
|
* The key of the namespace.
|
|
@@ -74,12 +78,6 @@ interface IDataNamespaceParent {
|
|
|
74
78
|
* The data namespace description.
|
|
75
79
|
*/
|
|
76
80
|
info: IThing
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Data namespace is a logical description of the hierarchy in the data.
|
|
81
|
-
*/
|
|
82
|
-
export interface IDataNamespace extends IDataNamespaceParent {
|
|
83
81
|
/**
|
|
84
82
|
* The list of definitions used in the namespace.
|
|
85
83
|
*/
|
|
@@ -101,132 +99,6 @@ export interface IDataItem {
|
|
|
101
99
|
key: string
|
|
102
100
|
}
|
|
103
101
|
|
|
104
|
-
class DataNamespaceParent {
|
|
105
|
-
kind = DataNamespaceKind
|
|
106
|
-
|
|
107
|
-
key = ''
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* The ordered list of items in this namespace.
|
|
111
|
-
*/
|
|
112
|
-
items: DataItem[] = []
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* The description of the data namespace.
|
|
116
|
-
*/
|
|
117
|
-
info: Thing = Thing.fromName('')
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* When a namespace is a sub-namespace this is the reference to the
|
|
121
|
-
* root namespace with all definitions.
|
|
122
|
-
*/
|
|
123
|
-
root?: DataNamespace
|
|
124
|
-
|
|
125
|
-
constructor(root?: DataNamespace) {
|
|
126
|
-
this.root = root
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* @deprecated Use the `getParentInstance()` method instead.
|
|
131
|
-
*/
|
|
132
|
-
getParent(): DataNamespace | undefined {
|
|
133
|
-
return this.getParentInstance()
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* @returns The parent namespace of this namespace. It returns `undefined` when this is the root namespace.
|
|
138
|
-
*/
|
|
139
|
-
getParentInstance(): DataNamespace | undefined {
|
|
140
|
-
const { root, key } = this
|
|
141
|
-
if (root) {
|
|
142
|
-
const result = (root as DataNamespace).findParent(key)
|
|
143
|
-
if (result === this.root) {
|
|
144
|
-
return undefined
|
|
145
|
-
}
|
|
146
|
-
return result
|
|
147
|
-
}
|
|
148
|
-
// we are the root namespace.
|
|
149
|
-
return undefined
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* Adds a data namespace to the structure.
|
|
154
|
-
* @param init The name of the namespace to add, namespace's schema, or instance.
|
|
155
|
-
*/
|
|
156
|
-
addNamespace(init: string | IDataNamespace | DataNamespace): DataNamespace {
|
|
157
|
-
return (this.root as DataNamespace).addNamespace(init, this.key)
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Lists namespaces that are in this namespace items.
|
|
162
|
-
*/
|
|
163
|
-
listNamespaces(): DataNamespace[] {
|
|
164
|
-
const result: DataNamespace[] = []
|
|
165
|
-
const { items } = this
|
|
166
|
-
const root = this.getRoot()
|
|
167
|
-
const { namespaces } = root.definitions
|
|
168
|
-
items.forEach((i) => {
|
|
169
|
-
if (i.kind !== DataNamespaceKind) {
|
|
170
|
-
return
|
|
171
|
-
}
|
|
172
|
-
const def = namespaces.find((j) => j.key === i.key)
|
|
173
|
-
if (def) {
|
|
174
|
-
result.push(def)
|
|
175
|
-
}
|
|
176
|
-
})
|
|
177
|
-
return result
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Lists namespaces that are in this namespace items.
|
|
182
|
-
*/
|
|
183
|
-
listDataModels(): DataModel[] {
|
|
184
|
-
const result: DataModel[] = []
|
|
185
|
-
const { items } = this
|
|
186
|
-
const root = this.getRoot()
|
|
187
|
-
const { models } = root.definitions
|
|
188
|
-
items.forEach((i) => {
|
|
189
|
-
if (i.kind !== DataModelKind) {
|
|
190
|
-
return
|
|
191
|
-
}
|
|
192
|
-
const def = models.find((j) => j.key === i.key)
|
|
193
|
-
if (def) {
|
|
194
|
-
result.push(def)
|
|
195
|
-
}
|
|
196
|
-
})
|
|
197
|
-
return result
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* @returns The root of the namespaces tree. It might be the same object.
|
|
202
|
-
*/
|
|
203
|
-
getRoot(): DataNamespace {
|
|
204
|
-
if (this.root) {
|
|
205
|
-
return this.root
|
|
206
|
-
}
|
|
207
|
-
return this as unknown as DataNamespace
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/**
|
|
211
|
-
* Removes self from the parent namespace with all data models.
|
|
212
|
-
* This does noting for the root namespace.
|
|
213
|
-
*/
|
|
214
|
-
remove(): void {
|
|
215
|
-
const { root } = this
|
|
216
|
-
if (!root) {
|
|
217
|
-
throw new Error(`Unable to remove the root namespace this way.`)
|
|
218
|
-
}
|
|
219
|
-
const models = this.listDataModels()
|
|
220
|
-
const children = this.listNamespaces()
|
|
221
|
-
models.forEach((m) => m.remove())
|
|
222
|
-
children.forEach((c) => c.remove())
|
|
223
|
-
const index = root.definitions.namespaces.findIndex((i) => i.key === this.key)
|
|
224
|
-
if (index >= 0) {
|
|
225
|
-
root.definitions.namespaces.splice(index, 1)
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
102
|
export class DataItem implements IDataItem {
|
|
231
103
|
kind: ItemKind = DataModelKind
|
|
232
104
|
|
|
@@ -310,7 +182,29 @@ export class DataItem implements IDataItem {
|
|
|
310
182
|
/**
|
|
311
183
|
* Data namespace is a logical description of the hierarchy in the data.
|
|
312
184
|
*/
|
|
313
|
-
export class DataNamespace
|
|
185
|
+
export class DataNamespace {
|
|
186
|
+
kind = DataNamespaceKind
|
|
187
|
+
|
|
188
|
+
key = ''
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* The ordered list of items in this namespace.
|
|
192
|
+
*/
|
|
193
|
+
items: DataItem[] = []
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The description of the data namespace.
|
|
197
|
+
*/
|
|
198
|
+
info: Thing = Thing.fromName('')
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* When a namespace is a sub-namespace this is the reference to the
|
|
202
|
+
* root namespace with all definitions.
|
|
203
|
+
*/
|
|
204
|
+
root?: DataNamespace
|
|
205
|
+
/**
|
|
206
|
+
* The list of definitions used in the namespace.
|
|
207
|
+
*/
|
|
314
208
|
definitions: DataDefinitions
|
|
315
209
|
|
|
316
210
|
/**
|
|
@@ -334,6 +228,9 @@ export class DataNamespace extends DataNamespaceParent {
|
|
|
334
228
|
return ns
|
|
335
229
|
}
|
|
336
230
|
|
|
231
|
+
/**
|
|
232
|
+
* @deprecated
|
|
233
|
+
*/
|
|
337
234
|
static definitions(): DataDefinitions {
|
|
338
235
|
return {
|
|
339
236
|
models: [],
|
|
@@ -346,8 +243,15 @@ export class DataNamespace extends DataNamespaceParent {
|
|
|
346
243
|
}
|
|
347
244
|
|
|
348
245
|
constructor(input?: string | IDataNamespace, root?: DataNamespace) {
|
|
349
|
-
|
|
350
|
-
this.definitions =
|
|
246
|
+
this.root = root
|
|
247
|
+
this.definitions = {
|
|
248
|
+
models: [],
|
|
249
|
+
associations: [],
|
|
250
|
+
entities: [],
|
|
251
|
+
properties: [],
|
|
252
|
+
namespaces: [],
|
|
253
|
+
tags: [],
|
|
254
|
+
}
|
|
351
255
|
|
|
352
256
|
let init: IDataNamespace
|
|
353
257
|
if (typeof input === 'string') {
|
|
@@ -449,6 +353,94 @@ export class DataNamespace extends DataNamespaceParent {
|
|
|
449
353
|
return result
|
|
450
354
|
}
|
|
451
355
|
|
|
356
|
+
/**
|
|
357
|
+
* @deprecated Use the `getParentInstance()` method instead.
|
|
358
|
+
*/
|
|
359
|
+
getParent(): DataNamespace | undefined {
|
|
360
|
+
return this.getParentInstance()
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* @returns The parent namespace of this namespace. It returns `undefined` when this is the root namespace.
|
|
365
|
+
*/
|
|
366
|
+
getParentInstance(): DataNamespace | undefined {
|
|
367
|
+
const { root, key } = this
|
|
368
|
+
if (root) {
|
|
369
|
+
return root.findParent(key)
|
|
370
|
+
}
|
|
371
|
+
// we are the root namespace.
|
|
372
|
+
return undefined
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Lists namespaces that are in this namespace items.
|
|
377
|
+
*/
|
|
378
|
+
listNamespaces(): DataNamespace[] {
|
|
379
|
+
const result: DataNamespace[] = []
|
|
380
|
+
const { items } = this
|
|
381
|
+
const root = this.getRoot()
|
|
382
|
+
const { namespaces } = root.definitions
|
|
383
|
+
items.forEach((i) => {
|
|
384
|
+
if (i.kind !== DataNamespaceKind) {
|
|
385
|
+
return
|
|
386
|
+
}
|
|
387
|
+
const def = namespaces.find((j) => j.key === i.key)
|
|
388
|
+
if (def) {
|
|
389
|
+
result.push(def)
|
|
390
|
+
}
|
|
391
|
+
})
|
|
392
|
+
return result
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* Lists namespaces that are in this namespace items.
|
|
397
|
+
*/
|
|
398
|
+
listDataModels(): DataModel[] {
|
|
399
|
+
const result: DataModel[] = []
|
|
400
|
+
const { items } = this
|
|
401
|
+
const root = this.getRoot()
|
|
402
|
+
const { models } = root.definitions
|
|
403
|
+
items.forEach((i) => {
|
|
404
|
+
if (i.kind !== DataModelKind) {
|
|
405
|
+
return
|
|
406
|
+
}
|
|
407
|
+
const def = models.find((j) => j.key === i.key)
|
|
408
|
+
if (def) {
|
|
409
|
+
result.push(def)
|
|
410
|
+
}
|
|
411
|
+
})
|
|
412
|
+
return result
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* @returns The root of the namespaces tree. It might be the same object.
|
|
417
|
+
*/
|
|
418
|
+
getRoot(): DataNamespace {
|
|
419
|
+
if (this.root) {
|
|
420
|
+
return this.root
|
|
421
|
+
}
|
|
422
|
+
return this as unknown as DataNamespace
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Removes self from the parent namespace with all data models.
|
|
427
|
+
* This does noting for the root namespace.
|
|
428
|
+
*/
|
|
429
|
+
remove(opts?: DataDomainRemoveOptions): void {
|
|
430
|
+
const { root } = this
|
|
431
|
+
if (!root) {
|
|
432
|
+
throw new Error(`Unable to remove the root namespace this way.`)
|
|
433
|
+
}
|
|
434
|
+
const models = this.listDataModels()
|
|
435
|
+
const children = this.listNamespaces()
|
|
436
|
+
models.forEach((m) => m.remove(opts))
|
|
437
|
+
children.forEach((c) => c.remove(opts))
|
|
438
|
+
const index = root.definitions.namespaces.findIndex((i) => i.key === this.key)
|
|
439
|
+
if (index >= 0) {
|
|
440
|
+
root.definitions.namespaces.splice(index, 1)
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
452
444
|
/**
|
|
453
445
|
* Checks if this is the root namespace.
|
|
454
446
|
* @returns True if this is the root namespace.
|
|
@@ -480,7 +472,7 @@ export class DataNamespace extends DataNamespaceParent {
|
|
|
480
472
|
* @param init The name of the namespace to add, namespace's schema, or instance.
|
|
481
473
|
* @param parent The optional key of the parent namespace to add the new namespace to.
|
|
482
474
|
*/
|
|
483
|
-
|
|
475
|
+
addNamespace(init: string | IDataNamespace | DataNamespace, parent?: string): DataNamespace {
|
|
484
476
|
let root: DataNamespace
|
|
485
477
|
if (parent) {
|
|
486
478
|
const rootCandidate = this.findParent(parent)
|
|
@@ -860,4 +852,25 @@ export class DataNamespace extends DataNamespaceParent {
|
|
|
860
852
|
hasForeignNamespace(key: string): boolean {
|
|
861
853
|
return this.foreign.some((i) => i.key === key)
|
|
862
854
|
}
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Checks whether the namespace is a child of the given namespace.
|
|
858
|
+
* The relationship doesn't have to be direct, as long as the namespace is in the hierarchy it will return true.
|
|
859
|
+
*
|
|
860
|
+
* @param key The key of the parent namespace to check.
|
|
861
|
+
* @returns True if this namespace is a child of the given namespace.
|
|
862
|
+
*/
|
|
863
|
+
isChildOf(key: string): boolean {
|
|
864
|
+
if (this.key === key) {
|
|
865
|
+
return false
|
|
866
|
+
}
|
|
867
|
+
const parent = this.getParentInstance()
|
|
868
|
+
if (!parent) {
|
|
869
|
+
return false
|
|
870
|
+
}
|
|
871
|
+
if (parent.key === key) {
|
|
872
|
+
return true
|
|
873
|
+
}
|
|
874
|
+
return parent.isChildOf(key)
|
|
875
|
+
}
|
|
863
876
|
}
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
type NumberFormat,
|
|
19
19
|
NumberFormats,
|
|
20
20
|
} from './DataFormat.js'
|
|
21
|
+
import type { DataEntity } from './DataEntity.js'
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Describes the default value set on a property schema.
|
|
@@ -88,7 +89,7 @@ export interface DataPropertySchema {
|
|
|
88
89
|
* Examples:
|
|
89
90
|
* - if `1` then every integer is allowed
|
|
90
91
|
* - if `2` than every even number is allowed
|
|
91
|
-
* - if `0.5` than every number
|
|
92
|
+
* - if `0.5` than every number dividable by `0.5` is allowed
|
|
92
93
|
*/
|
|
93
94
|
multipleOf?: number
|
|
94
95
|
/**
|
|
@@ -524,9 +525,9 @@ export class DataProperty {
|
|
|
524
525
|
}
|
|
525
526
|
|
|
526
527
|
/**
|
|
527
|
-
* Checks whether the passed value is one of the supported data
|
|
528
|
+
* Checks whether the passed value is one of the supported data property attributes.
|
|
528
529
|
* @param value The value to test
|
|
529
|
-
* @returns True when the passed value is one of the supported data
|
|
530
|
+
* @returns True when the passed value is one of the supported data property attributes.
|
|
530
531
|
*/
|
|
531
532
|
static isValidAttribute(value: unknown): value is DataPropertyAttribute {
|
|
532
533
|
if (typeof value !== 'string') {
|
|
@@ -591,4 +592,32 @@ export class DataProperty {
|
|
|
591
592
|
const item = this.bindings.find((i) => i.type === type) as PropertyBinding
|
|
592
593
|
return item?.schema
|
|
593
594
|
}
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* Returns a parent data entity where this data property exist.
|
|
598
|
+
*/
|
|
599
|
+
getParentInstance(): DataEntity | undefined {
|
|
600
|
+
return this.root.definitions.entities.find((e) => e.properties.some((e) => e.key === this.key))
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/**
|
|
604
|
+
* Checks whether the property is a child of the given namespace, data model, or an entity.
|
|
605
|
+
* The relationship doesn't have to be direct, as long as the property is in the hierarchy it will return true.
|
|
606
|
+
*
|
|
607
|
+
* @param key The key of the parent to check.
|
|
608
|
+
* @returns True if this data property is a child of the given namespace, data model, or an entity
|
|
609
|
+
*/
|
|
610
|
+
isChildOf(key: string): boolean {
|
|
611
|
+
if (this.key === key) {
|
|
612
|
+
return false
|
|
613
|
+
}
|
|
614
|
+
const parent = this.getParentInstance()
|
|
615
|
+
if (!parent) {
|
|
616
|
+
return false
|
|
617
|
+
}
|
|
618
|
+
if (parent.key === key) {
|
|
619
|
+
return true
|
|
620
|
+
}
|
|
621
|
+
return parent.isChildOf(key)
|
|
622
|
+
}
|
|
594
623
|
}
|