@api-client/core 0.13.6 → 0.14.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.
Files changed (174) hide show
  1. package/build/src/amf/AmfTypes.d.ts +1 -1
  2. package/build/src/amf/AmfTypes.js +1 -1
  3. package/build/src/amf/AmfTypes.js.map +1 -1
  4. package/build/src/amf/Utils.d.ts +0 -6
  5. package/build/src/amf/Utils.d.ts.map +1 -1
  6. package/build/src/amf/Utils.js +0 -14
  7. package/build/src/amf/Utils.js.map +1 -1
  8. package/build/src/browser.d.ts +1 -0
  9. package/build/src/browser.d.ts.map +1 -1
  10. package/build/src/browser.js +1 -0
  11. package/build/src/browser.js.map +1 -1
  12. package/build/src/index.d.ts +1 -0
  13. package/build/src/index.d.ts.map +1 -1
  14. package/build/src/index.js +1 -0
  15. package/build/src/index.js.map +1 -1
  16. package/build/src/legacy.d.ts +0 -8
  17. package/build/src/legacy.d.ts.map +1 -1
  18. package/build/src/legacy.js +0 -9
  19. package/build/src/legacy.js.map +1 -1
  20. package/build/src/modeling/Bindings.d.ts +1 -1
  21. package/build/src/modeling/Bindings.js.map +1 -1
  22. package/build/src/modeling/DataDomain.js +2 -2
  23. package/build/src/modeling/DataDomain.js.map +1 -1
  24. package/build/src/modeling/DataFormat.d.ts +0 -40
  25. package/build/src/modeling/DataFormat.d.ts.map +1 -1
  26. package/build/src/modeling/DataFormat.js +0 -27
  27. package/build/src/modeling/DataFormat.js.map +1 -1
  28. package/build/src/modeling/DomainAssociation.d.ts +28 -0
  29. package/build/src/modeling/DomainAssociation.d.ts.map +1 -1
  30. package/build/src/modeling/DomainAssociation.js +73 -4
  31. package/build/src/modeling/DomainAssociation.js.map +1 -1
  32. package/build/src/modeling/DomainEntity.d.ts +25 -9
  33. package/build/src/modeling/DomainEntity.d.ts.map +1 -1
  34. package/build/src/modeling/DomainEntity.js +65 -21
  35. package/build/src/modeling/DomainEntity.js.map +1 -1
  36. package/build/src/modeling/DomainFile.d.ts +3 -4
  37. package/build/src/modeling/DomainFile.d.ts.map +1 -1
  38. package/build/src/modeling/DomainFile.js +5 -9
  39. package/build/src/modeling/DomainFile.js.map +1 -1
  40. package/build/src/modeling/DomainImpactAnalysis.d.ts +1 -1
  41. package/build/src/modeling/DomainImpactAnalysis.d.ts.map +1 -1
  42. package/build/src/modeling/DomainImpactAnalysis.js +3 -3
  43. package/build/src/modeling/DomainImpactAnalysis.js.map +1 -1
  44. package/build/src/modeling/DomainModel.d.ts +2 -2
  45. package/build/src/modeling/DomainModel.js +2 -2
  46. package/build/src/modeling/DomainModel.js.map +1 -1
  47. package/build/src/modeling/DomainProperty.d.ts +28 -12
  48. package/build/src/modeling/DomainProperty.d.ts.map +1 -1
  49. package/build/src/modeling/DomainProperty.js +61 -26
  50. package/build/src/modeling/DomainProperty.js.map +1 -1
  51. package/build/src/modeling/Semantics.d.ts +109 -0
  52. package/build/src/modeling/Semantics.d.ts.map +1 -0
  53. package/build/src/modeling/Semantics.js +97 -0
  54. package/build/src/modeling/Semantics.js.map +1 -0
  55. package/build/src/models/CertificateFile.d.ts +2 -3
  56. package/build/src/models/CertificateFile.d.ts.map +1 -1
  57. package/build/src/models/CertificateFile.js +4 -8
  58. package/build/src/models/CertificateFile.js.map +1 -1
  59. package/build/src/models/Folder.d.ts +1 -2
  60. package/build/src/models/Folder.d.ts.map +1 -1
  61. package/build/src/models/Folder.js +2 -4
  62. package/build/src/models/Folder.js.map +1 -1
  63. package/build/src/models/Project.d.ts +2 -3
  64. package/build/src/models/Project.d.ts.map +1 -1
  65. package/build/src/models/Project.js +4 -8
  66. package/build/src/models/Project.js.map +1 -1
  67. package/build/src/models/kinds.d.ts +0 -24
  68. package/build/src/models/kinds.d.ts.map +1 -1
  69. package/build/src/models/kinds.js +0 -24
  70. package/build/src/models/kinds.js.map +1 -1
  71. package/build/src/models/store/File.d.ts +1 -21
  72. package/build/src/models/store/File.d.ts.map +1 -1
  73. package/build/src/models/store/File.js +3 -23
  74. package/build/src/models/store/File.js.map +1 -1
  75. package/build/src/models/store/data_catalog.d.ts +1 -1
  76. package/build/src/models/store/data_catalog.js.map +1 -1
  77. package/build/src/sdk/FilesSdk.js +1 -1
  78. package/build/src/sdk/FilesSdk.js.map +1 -1
  79. package/build/tsconfig.tsbuildinfo +1 -1
  80. package/data/models/example-generator-api.json +22 -22
  81. package/eslint.config.js +1 -0
  82. package/package.json +5 -5
  83. package/src/amf/AmfTypes.ts +1 -1
  84. package/src/amf/Utils.ts +0 -15
  85. package/src/modeling/Bindings.ts +1 -1
  86. package/src/modeling/DataDomain.ts +2 -2
  87. package/src/modeling/DataFormat.ts +0 -48
  88. package/src/modeling/DomainAssociation.ts +66 -3
  89. package/src/modeling/DomainEntity.ts +56 -17
  90. package/src/modeling/DomainFile.ts +5 -9
  91. package/src/modeling/DomainImpactAnalysis.ts +3 -3
  92. package/src/modeling/DomainModel.ts +2 -2
  93. package/src/modeling/DomainProperty.ts +60 -21
  94. package/src/modeling/Semantics.ts +178 -0
  95. package/src/modeling/graph.md +14 -14
  96. package/src/modeling/readme.md +29 -29
  97. package/src/models/CertificateFile.ts +4 -12
  98. package/src/models/Folder.ts +2 -4
  99. package/src/models/Project.ts +4 -8
  100. package/src/models/kinds.ts +0 -25
  101. package/src/models/store/File.ts +4 -35
  102. package/src/models/store/data_catalog.ts +1 -1
  103. package/src/sdk/FilesSdk.ts +1 -1
  104. package/tests/unit/modeling/data_domain_change_observers.spec.ts +11 -10
  105. package/tests/unit/modeling/data_domain_entities.spec.ts +129 -1
  106. package/tests/unit/modeling/data_domain_property.spec.ts +1 -1
  107. package/tests/unit/modeling/domain_asociation.spec.ts +177 -0
  108. package/tests/unit/modeling/domain_entity.spec.ts +27 -26
  109. package/tests/unit/modeling/domain_entity_example_generator_json.spec.ts +11 -11
  110. package/tests/unit/modeling/domain_entity_example_generator_xml.spec.ts +10 -10
  111. package/tests/unit/modeling/domain_file.spec.ts +4 -27
  112. package/tests/unit/modeling/{domain.property.spec.ts → domain_property.spec.ts} +139 -23
  113. package/tests/unit/models/Certificate/from_name.spec.ts +3 -15
  114. package/tests/unit/models/File/constructor.spec.ts +0 -1
  115. package/tests/unit/models/File/new.spec.ts +0 -13
  116. package/tests/unit/models/File/shortcutTo.spec.ts +1 -2
  117. package/tests/unit/models/File/toJSON.spec.ts +0 -13
  118. package/tests/unit/models/File/updateByMeMeta.spec.ts +4 -6
  119. package/tests/unit/models/Folder/create.spec.ts +2 -23
  120. package/tests/unit/models/Project/create.spec.ts +6 -32
  121. package/build/src/amf/AmfShapeGenerator.d.ts +0 -103
  122. package/build/src/amf/AmfShapeGenerator.d.ts.map +0 -1
  123. package/build/src/amf/AmfShapeGenerator.js +0 -416
  124. package/build/src/amf/AmfShapeGenerator.js.map +0 -1
  125. package/build/src/modeling/legacy/DataAssociation.d.ts +0 -284
  126. package/build/src/modeling/legacy/DataAssociation.d.ts.map +0 -1
  127. package/build/src/modeling/legacy/DataAssociation.js +0 -443
  128. package/build/src/modeling/legacy/DataAssociation.js.map +0 -1
  129. package/build/src/modeling/legacy/DataEntity.d.ts +0 -358
  130. package/build/src/modeling/legacy/DataEntity.d.ts.map +0 -1
  131. package/build/src/modeling/legacy/DataEntity.js +0 -855
  132. package/build/src/modeling/legacy/DataEntity.js.map +0 -1
  133. package/build/src/modeling/legacy/DataEntityBuilder.d.ts +0 -162
  134. package/build/src/modeling/legacy/DataEntityBuilder.d.ts.map +0 -1
  135. package/build/src/modeling/legacy/DataEntityBuilder.js +0 -221
  136. package/build/src/modeling/legacy/DataEntityBuilder.js.map +0 -1
  137. package/build/src/modeling/legacy/DataImpactAnalysis.d.ts +0 -298
  138. package/build/src/modeling/legacy/DataImpactAnalysis.d.ts.map +0 -1
  139. package/build/src/modeling/legacy/DataImpactAnalysis.js +0 -441
  140. package/build/src/modeling/legacy/DataImpactAnalysis.js.map +0 -1
  141. package/build/src/modeling/legacy/DataModel.d.ts +0 -99
  142. package/build/src/modeling/legacy/DataModel.d.ts.map +0 -1
  143. package/build/src/modeling/legacy/DataModel.js +0 -237
  144. package/build/src/modeling/legacy/DataModel.js.map +0 -1
  145. package/build/src/modeling/legacy/DataNamespace.d.ts +0 -340
  146. package/build/src/modeling/legacy/DataNamespace.d.ts.map +0 -1
  147. package/build/src/modeling/legacy/DataNamespace.js +0 -784
  148. package/build/src/modeling/legacy/DataNamespace.js.map +0 -1
  149. package/build/src/modeling/legacy/DataProperty.d.ts +0 -332
  150. package/build/src/modeling/legacy/DataProperty.d.ts.map +0 -1
  151. package/build/src/modeling/legacy/DataProperty.js +0 -415
  152. package/build/src/modeling/legacy/DataProperty.js.map +0 -1
  153. package/build/src/models/store/DataFile.d.ts +0 -31
  154. package/build/src/models/store/DataFile.d.ts.map +0 -1
  155. package/build/src/models/store/DataFile.js +0 -92
  156. package/build/src/models/store/DataFile.js.map +0 -1
  157. package/src/amf/AmfShapeGenerator.ts +0 -477
  158. package/src/modeling/legacy/DataAssociation.ts +0 -554
  159. package/src/modeling/legacy/DataEntity.ts +0 -1019
  160. package/src/modeling/legacy/DataEntityBuilder.ts +0 -236
  161. package/src/modeling/legacy/DataImpactAnalysis.ts +0 -530
  162. package/src/modeling/legacy/DataModel.ts +0 -276
  163. package/src/modeling/legacy/DataNamespace.ts +0 -929
  164. package/src/modeling/legacy/DataProperty.ts +0 -630
  165. package/src/models/store/DataFile.ts +0 -100
  166. package/tests/unit/modeling/legacy/amf_shape_generator.spec.ts +0 -1041
  167. package/tests/unit/modeling/legacy/data_association.spec.ts +0 -710
  168. package/tests/unit/modeling/legacy/data_entity.spec.ts +0 -2061
  169. package/tests/unit/modeling/legacy/data_entity_generator_json.spec.ts +0 -987
  170. package/tests/unit/modeling/legacy/data_entity_generator_xml.spec.ts +0 -1451
  171. package/tests/unit/modeling/legacy/data_model.spec.ts +0 -395
  172. package/tests/unit/modeling/legacy/data_namespace.spec.ts +0 -1312
  173. package/tests/unit/modeling/legacy/data_property.spec.ts +0 -887
  174. package/tests/unit/modeling/legacy/impact_analysis.spec.ts +0 -373
@@ -1,929 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-this-alias */
2
- import { IThing, Thing } from '../../models/Thing.js'
3
- import { IDataAssociation, DataAssociation, AssociationTarget } from './DataAssociation.js'
4
- import { IDataEntity, DataEntity } from './DataEntity.js'
5
- import { IDataModel, DataModel } from './DataModel.js'
6
- import { IDataProperty, DataProperty } from './DataProperty.js'
7
- import {
8
- DataNamespaceKind,
9
- DataModelKind,
10
- DataEntityKind,
11
- DataPropertyKind,
12
- DataAssociationKind,
13
- } from '../../models/kinds.js'
14
- import { nanoid } from '../../nanoid.js'
15
- import type { DataDomainRemoveOptions } from '../types.js'
16
-
17
- /**
18
- * @deprecated
19
- */
20
- type ItemKind = typeof DataNamespaceKind | typeof DataModelKind
21
-
22
- /**
23
- * @deprecated
24
- */
25
- export interface DataItemAdaptingOptions {
26
- /**
27
- * The index at which to adapt the item.
28
- */
29
- index?: number
30
- }
31
- /**
32
- * @deprecated
33
- */
34
- interface IDataDefinitions {
35
- models?: IDataModel[]
36
- entities?: IDataEntity[]
37
- properties?: IDataProperty[]
38
- associations?: IDataAssociation[]
39
- namespaces?: IDataNamespace[]
40
- tags?: string[]
41
- /**
42
- * The list of foreign namespaces associated with this namespace.
43
- */
44
- foreign?: ForeignNamespace[]
45
- }
46
-
47
- /**
48
- * @deprecated
49
- */
50
- interface DataDefinitions {
51
- models: DataModel[]
52
- // @todo: This should be a map of entities with a key of the entity key.
53
- entities: DataEntity[]
54
- // @todo: This should be a map of properties with a key of the property key.
55
- properties: DataProperty[]
56
- // @todo: This should be a map of associations with a key of the association key.
57
- associations: DataAssociation[]
58
- namespaces: DataNamespace[]
59
- /**
60
- * Common for the entire root namespace tags.
61
- * These are kept separately so the UI can generate autocomplete for tags.
62
- */
63
- tags: string[]
64
- /**
65
- * The list of foreign namespaces associated with this namespace.
66
- */
67
- foreign?: ForeignNamespace[]
68
- }
69
-
70
- /**
71
- * Data definition for a foreign namespace.
72
- * Each foreign namespace is resolved to a specific version.
73
- * This makes sure that the local data are always referencing an existing
74
- * entity as breaking changes should be resolved when upgrading a version.
75
- * @deprecated
76
- */
77
- interface ForeignNamespace {
78
- key: string
79
- version: string
80
- }
81
-
82
- /**
83
- * Data namespace is a logical description of the hierarchy in the data.
84
- * @deprecated
85
- */
86
- export interface IDataNamespace {
87
- kind: typeof DataNamespaceKind
88
- /**
89
- * The key of the namespace.
90
- */
91
- key: string
92
- /**
93
- * The ordered list of items in this namespace.
94
- */
95
- items: IDataItem[]
96
- /**
97
- * The data namespace description.
98
- */
99
- info: IThing
100
- /**
101
- * The list of definitions used in the namespace.
102
- */
103
- definitions: IDataDefinitions
104
- }
105
-
106
- /**
107
- * Data item is a reference to an object in the top namespace definitions
108
- * to the namespace items.
109
- * @deprecated
110
- */
111
- export interface IDataItem {
112
- /**
113
- * The kind of the item.
114
- */
115
- kind: ItemKind
116
- /**
117
- * The identifier in the `definitions` array of the namespace.
118
- */
119
- key: string
120
- }
121
-
122
- /**
123
- * @deprecated
124
- */
125
- export class DataItem implements IDataItem {
126
- kind: ItemKind = DataModelKind
127
-
128
- key = ''
129
-
130
- /**
131
- * A reference to the top level namespace.
132
- */
133
- private root: DataNamespace
134
-
135
- static isDataItem(input: unknown): boolean {
136
- const typed = input as IDataItem
137
- if (!input || ![DataModelKind, DataNamespaceKind].includes(typed.kind)) {
138
- return false
139
- }
140
- return true
141
- }
142
-
143
- static dataNamespace(root: DataNamespace, key: string): DataItem {
144
- const item = new DataItem(root, {
145
- kind: DataNamespaceKind,
146
- key,
147
- })
148
- return item
149
- }
150
-
151
- static dataModel(root: DataNamespace, key: string): DataItem {
152
- const item = new DataItem(root, {
153
- kind: DataModelKind,
154
- key,
155
- })
156
- return item
157
- }
158
-
159
- /**
160
- * @param root The top-most data namespace.
161
- * @param input The project item definition used to restore the state.
162
- */
163
- constructor(root: DataNamespace, input: string | IDataItem) {
164
- this.root = root
165
- let init: IDataItem
166
- if (typeof input === 'string') {
167
- init = JSON.parse(input)
168
- } else if (typeof input === 'object') {
169
- init = input
170
- } else {
171
- throw new Error('Specify the type of the item.')
172
- }
173
- this.new(init)
174
- }
175
-
176
- new(init: IDataItem): void {
177
- if (!DataItem.isDataItem(init)) {
178
- throw new Error(`Not a data item.`)
179
- }
180
- const { kind, key } = init
181
- this.kind = kind
182
- this.key = key
183
- }
184
-
185
- toJSON(): IDataItem {
186
- const result: IDataItem = {
187
- kind: this.kind,
188
- key: this.key,
189
- }
190
- return result
191
- }
192
-
193
- getItem(): DataNamespace | DataModel | undefined {
194
- const { root, key, kind } = this
195
- const { definitions } = root
196
- if (kind === DataModelKind) {
197
- return definitions.models.find((i) => i.key === key)
198
- }
199
- if (kind === kind) {
200
- return definitions.namespaces.find((i) => i.key === key)
201
- }
202
- }
203
- }
204
-
205
- /**
206
- * Data namespace is a logical description of the hierarchy in the data.
207
- * @deprecated
208
- */
209
- export class DataNamespace {
210
- kind = DataNamespaceKind
211
-
212
- key = ''
213
-
214
- /**
215
- * The ordered list of items in this namespace.
216
- */
217
- items: DataItem[] = []
218
-
219
- /**
220
- * The description of the data namespace.
221
- */
222
- info: Thing = Thing.fromName('')
223
-
224
- /**
225
- * When a namespace is a sub-namespace this is the reference to the
226
- * root namespace with all definitions.
227
- */
228
- root?: DataNamespace
229
- /**
230
- * The list of definitions used in the namespace.
231
- */
232
- definitions: DataDefinitions
233
-
234
- /**
235
- * The list of foreign namespaces.
236
- * This is used to find entities from foreign namespaces.
237
- * Values here are treated as read only (objects can be frozen).
238
- *
239
- * This should be set by the application and the namespace will do
240
- * nothing to populate this value.
241
- */
242
- foreign: DataNamespace[] = []
243
-
244
- /**
245
- * Creates a new data namespace from a name.
246
- * @param name The name to set.
247
- */
248
- static fromName(name: string, root?: DataNamespace): DataNamespace {
249
- const ns = new DataNamespace(undefined, root)
250
- const info = Thing.fromName(name)
251
- ns.info = info
252
- return ns
253
- }
254
-
255
- /**
256
- * @deprecated
257
- */
258
- static definitions(): DataDefinitions {
259
- return {
260
- models: [],
261
- associations: [],
262
- entities: [],
263
- properties: [],
264
- namespaces: [],
265
- tags: [],
266
- }
267
- }
268
-
269
- constructor(input?: string | IDataNamespace, root?: DataNamespace) {
270
- this.root = root
271
- this.definitions = {
272
- models: [],
273
- associations: [],
274
- entities: [],
275
- properties: [],
276
- namespaces: [],
277
- tags: [],
278
- }
279
-
280
- let init: IDataNamespace
281
- if (typeof input === 'string') {
282
- init = JSON.parse(input)
283
- } else if (typeof input === 'object') {
284
- init = input
285
- if (!init.kind) {
286
- init.kind = DataNamespaceKind
287
- }
288
- } else {
289
- init = {
290
- kind: DataNamespaceKind,
291
- key: nanoid(),
292
- definitions: {},
293
- items: [],
294
- info: Thing.fromName('').toJSON(),
295
- }
296
- }
297
- this.new(init)
298
- }
299
-
300
- new(init: IDataNamespace): void {
301
- if (!init || !init.definitions || !init.items) {
302
- throw new Error(`Not a data namespace.`)
303
- }
304
- const { key = nanoid(), definitions = {}, items, info } = init
305
- this.key = key
306
- if (info) {
307
- this.info = new Thing(info)
308
- } else {
309
- this.info = Thing.fromName('')
310
- }
311
- if (Array.isArray(items)) {
312
- this.items = items.map((i) => new DataItem(this, i))
313
- } else {
314
- this.items = []
315
- }
316
- if (Array.isArray(definitions.associations)) {
317
- this.definitions.associations = definitions.associations.map((i) => new DataAssociation(this, i))
318
- } else {
319
- this.definitions.associations = []
320
- }
321
- if (Array.isArray(definitions.properties)) {
322
- this.definitions.properties = definitions.properties.map((i) => new DataProperty(this, i))
323
- } else {
324
- this.definitions.properties = []
325
- }
326
- // note, entities must be restored after properties / associations
327
- if (Array.isArray(definitions.entities)) {
328
- this.definitions.entities = definitions.entities.map((i) => new DataEntity(this, i))
329
- } else {
330
- this.definitions.entities = []
331
- }
332
- // must be set after entities.
333
- if (Array.isArray(definitions.models)) {
334
- this.definitions.models = definitions.models.map((i) => new DataModel(this, i))
335
- } else {
336
- this.definitions.models = []
337
- }
338
- if (Array.isArray(definitions.namespaces)) {
339
- this.definitions.namespaces = definitions.namespaces.map((i) => new DataNamespace(i, this))
340
- } else {
341
- this.definitions.namespaces = []
342
- }
343
- if (Array.isArray(definitions.tags)) {
344
- this.definitions.tags = [...definitions.tags]
345
- } else {
346
- this.definitions.tags = []
347
- }
348
- }
349
-
350
- toJSON(): IDataNamespace {
351
- const result: IDataNamespace = {
352
- key: this.key,
353
- kind: DataNamespaceKind,
354
- info: this.info.toJSON(),
355
- items: this.items.map((i) => i.toJSON()),
356
- definitions: {},
357
- }
358
- const { associations, entities, models, namespaces, properties, tags } = this.definitions
359
- if (Array.isArray(associations) && associations.length) {
360
- result.definitions.associations = associations.map((i) => i.toJSON())
361
- }
362
- if (Array.isArray(entities) && entities.length) {
363
- result.definitions.entities = entities.map((i) => i.toJSON())
364
- }
365
- if (Array.isArray(models) && models.length) {
366
- result.definitions.models = models.map((i) => i.toJSON())
367
- }
368
- if (Array.isArray(namespaces) && namespaces.length) {
369
- result.definitions.namespaces = namespaces.map((i) => i.toJSON())
370
- }
371
- if (Array.isArray(properties) && properties.length) {
372
- result.definitions.properties = properties.map((i) => i.toJSON())
373
- }
374
- if (Array.isArray(tags) && tags.length) {
375
- result.definitions.tags = [...tags]
376
- }
377
- return result
378
- }
379
-
380
- /**
381
- * @deprecated Use the `getParentInstance()` method instead.
382
- */
383
- getParent(): DataNamespace | undefined {
384
- return this.getParentInstance()
385
- }
386
-
387
- /**
388
- * @returns The parent namespace of this namespace. It returns `undefined` when this is the root namespace.
389
- */
390
- getParentInstance(): DataNamespace | undefined {
391
- const { root, key } = this
392
- if (root) {
393
- return root.findParent(key)
394
- }
395
- // we are the root namespace.
396
- return undefined
397
- }
398
-
399
- /**
400
- * Lists namespaces that are in this namespace items.
401
- */
402
- listNamespaces(): DataNamespace[] {
403
- const result: DataNamespace[] = []
404
- const { items } = this
405
- const root = this.getRoot()
406
- const { namespaces } = root.definitions
407
- items.forEach((i) => {
408
- if (i.kind !== DataNamespaceKind) {
409
- return
410
- }
411
- const def = namespaces.find((j) => j.key === i.key)
412
- if (def) {
413
- result.push(def)
414
- }
415
- })
416
- return result
417
- }
418
-
419
- /**
420
- * Lists namespaces that are in this namespace items.
421
- */
422
- listDataModels(): DataModel[] {
423
- const result: DataModel[] = []
424
- const { items } = this
425
- const root = this.getRoot()
426
- const { models } = root.definitions
427
- items.forEach((i) => {
428
- if (i.kind !== DataModelKind) {
429
- return
430
- }
431
- const def = models.find((j) => j.key === i.key)
432
- if (def) {
433
- result.push(def)
434
- }
435
- })
436
- return result
437
- }
438
-
439
- /**
440
- * @returns The root of the namespaces tree. It might be the same object.
441
- */
442
- getRoot(): DataNamespace {
443
- if (this.root) {
444
- return this.root
445
- }
446
- return this as unknown as DataNamespace
447
- }
448
-
449
- /**
450
- * Removes self from the parent namespace with all data models.
451
- * This does noting for the root namespace.
452
- */
453
- remove(opts?: DataDomainRemoveOptions): void {
454
- const { root } = this
455
- if (!root) {
456
- throw new Error(`Unable to remove the root namespace this way.`)
457
- }
458
- const models = this.listDataModels()
459
- const children = this.listNamespaces()
460
- models.forEach((m) => m.remove(opts))
461
- children.forEach((c) => c.remove(opts))
462
- const index = root.definitions.namespaces.findIndex((i) => i.key === this.key)
463
- if (index >= 0) {
464
- root.definitions.namespaces.splice(index, 1)
465
- }
466
- }
467
-
468
- /**
469
- * Checks if this is the root namespace.
470
- * @returns True if this is the root namespace.
471
- */
472
- isRoot(): boolean {
473
- return this.root === undefined
474
- }
475
-
476
- /**
477
- * Finds a parent namespace for the given namespace.
478
- * @param key The namespace key to find the parent for.
479
- * @returns The parent namespace or undefined when the namespace does not exist. It may return the root namespace.
480
- */
481
- findParent(key: string): DataNamespace | undefined {
482
- const { definitions, items = [] } = this
483
- const rootIndex = items.findIndex((i) => i.key === key)
484
- if (rootIndex >= 0) {
485
- return this
486
- }
487
- const definition = definitions.namespaces.find((i) => i.items.some((item) => item.key === key))
488
- if (definition) {
489
- return definition
490
- }
491
- return undefined
492
- }
493
-
494
- /**
495
- * Adds a data namespace to the structure.
496
- * @param init The name of the namespace to add, namespace's schema, or instance.
497
- * @param parent The optional key of the parent namespace to add the new namespace to.
498
- */
499
- addNamespace(init: string | IDataNamespace | DataNamespace, parent?: string): DataNamespace {
500
- let root: DataNamespace
501
- if (parent) {
502
- const rootCandidate = this.findNamespace(parent)
503
- if (!rootCandidate) {
504
- throw new Error(`Unable to find the parent namespace ${parent}`)
505
- }
506
- root = rootCandidate
507
- } else {
508
- root = this
509
- }
510
- let definition: DataNamespace
511
- if (typeof init === 'string') {
512
- definition = DataNamespace.fromName(init, this.root || this)
513
- } else if (init instanceof DataNamespace) {
514
- definition = init
515
- } else {
516
- definition = new DataNamespace(init, this.root || this)
517
- }
518
- ;(this.root || this).definitions.namespaces.push(definition)
519
- const item = DataItem.dataNamespace(this.root || this, definition.key)
520
- if (!Array.isArray(root.items)) {
521
- root.items = []
522
- }
523
- root.items.push(item)
524
- return definition
525
- }
526
-
527
- /**
528
- * Adapts an existing namespace to this namespace.
529
- * This will remove the namespace from the parent namespace and add it to this one.
530
- *
531
- * @param ns The namespace to adapt.
532
- * @param opts Adapting options.
533
- */
534
- adaptNamespace(ns: DataNamespace, opts: DataItemAdaptingOptions = {}): void {
535
- if (opts.index !== undefined) {
536
- if (opts.index < 0) {
537
- throw new Error(`The index ${opts.index} cannot be below 0.`)
538
- }
539
- if (opts.index >= this.items.length) {
540
- throw new Error(`The index ${opts.index} is not valid.`)
541
- }
542
- }
543
- if (ns === this) {
544
- throw new Error(`Unable to adapt a namespace that is self.`)
545
- }
546
- if (ns.root !== this.root) {
547
- throw new Error(`The namespace ${ns.key} is not in the same namespace as this data namespace.`)
548
- }
549
- if (ns.getParentInstance() === this) {
550
- throw new Error(`The namespace ${ns.key} is already adapted by this data namespace.`)
551
- }
552
- // Check for circular dependency
553
- let current: DataNamespace | undefined = this
554
- while (current) {
555
- if (current === ns) {
556
- throw new Error(`Unable to adapt namespace ${ns.key} under itself or one of its children.`)
557
- }
558
- current = current.getParentInstance()
559
- }
560
- const parent = ns.getParentInstance() || this.root
561
- if (!parent) {
562
- throw new Error(`The namespace ${ns.key} has no parent.`)
563
- }
564
- // it has a parent (above check) so it has the index.
565
- const index = parent.items.findIndex((i) => i.key === ns.key)
566
- const [item] = parent.items.splice(index, 1)
567
- if (opts.index !== undefined) {
568
- this.items.splice(opts.index, 0, item)
569
- } else {
570
- this.items.push(item)
571
- }
572
- }
573
-
574
- /**
575
- * Adapts an existing data model to this namespace.
576
- * This will remove the data model from the parent namespace and add it to this one.
577
- * @param model The data model to adapt.
578
- * @param opts The adapting options.
579
- */
580
- adaptDataModel(model: DataModel, opts: DataItemAdaptingOptions = {}): void {
581
- if (opts.index !== undefined) {
582
- if (opts.index < 0) {
583
- throw new Error(`The index ${opts.index} cannot be below 0.`)
584
- }
585
- if (opts.index >= this.items.length) {
586
- throw new Error(`The index ${opts.index} is not valid.`)
587
- }
588
- }
589
- if (model.root !== this.root) {
590
- throw new Error(`The data model ${model.key} is not in the same namespace as this data namespace.`)
591
- }
592
- const parent = model.getParentInstance()
593
- if (!parent) {
594
- throw new Error(`The data model ${model.key} has no parent.`)
595
- }
596
- if (parent === this) {
597
- throw new Error(`The data model ${model.key} is already adapted by this data namespace.`)
598
- }
599
- // it has a parent (above check) so it has the index.
600
- const index = parent.items.findIndex((i) => i.key === model.key)
601
- const [item] = parent.items.splice(index, 1)
602
- if (opts.index !== undefined) {
603
- this.items.splice(opts.index, 0, item)
604
- } else {
605
- this.items.push(item)
606
- }
607
- }
608
-
609
- /**
610
- * Finds a namespace in the definitions.
611
- * @param key The key of the namespace to find.
612
- * @returns The namespace definition or undefined when not found.
613
- */
614
- findNamespace(key: string): DataNamespace | undefined {
615
- const { definitions } = this.root || this
616
- return definitions.namespaces.find((i) => i.key === key)
617
- }
618
-
619
- /**
620
- * Finds a namespace and calls the `remove()` on it.
621
- * @param key The key of the namespace to find.
622
- */
623
- removeNamespace(key: string, opts?: DataDomainRemoveOptions): void {
624
- const root = this.root || this
625
- if (root.key === key) {
626
- throw new Error(`Unable to remove the root namespace this way.`)
627
- }
628
- const { definitions } = root
629
- const ns = definitions.namespaces.find((i) => i.key === key)
630
- if (ns) {
631
- ns.remove(opts)
632
- }
633
- }
634
-
635
- /**
636
- * Adds a data model to a namespace.
637
- * @param init The name of the data model to add, data model's schema, or its instance.
638
- * @param parent The optional key of the parent namespace to add the new data model to.
639
- */
640
- addDataModel(init: string | IDataModel | DataModel, parent?: string): DataModel {
641
- let root: DataNamespace
642
- if (parent) {
643
- const rootCandidate = this.findNamespace(parent)
644
- if (!rootCandidate) {
645
- throw new Error(`Unable to find the parent namespace ${parent}`)
646
- }
647
- root = rootCandidate
648
- } else {
649
- root = this
650
- }
651
- let definition: DataModel
652
- if (typeof init === 'string') {
653
- definition = DataModel.fromName(this.root || this, init)
654
- } else if (init instanceof DataModel) {
655
- definition = init
656
- } else {
657
- definition = new DataModel(this.root || this, init)
658
- }
659
- ;(this.root || this).definitions.models.push(definition)
660
- const item = DataItem.dataModel(this.root || this, definition.key)
661
- if (!Array.isArray(root.items)) {
662
- root.items = []
663
- }
664
- root.items.push(item)
665
- return definition
666
- }
667
-
668
- /**
669
- * Finds a data model in the definitions.
670
- * @param key The key of the data model to find.
671
- * @returns The data model definition or undefined when not found.
672
- */
673
- findDataModel(key: string): DataModel | undefined {
674
- const { definitions } = this.root || this
675
- return definitions.models.find((i) => i.key === key)
676
- }
677
-
678
- /**
679
- * A convenience function to remove an object from the namespace.
680
- * @param key The key of the object to remove.
681
- * @param kind The kind of the object to remove.
682
- * @param opts The options for the removal.
683
- * @throws Error when the kind is not known.
684
- */
685
- removeObject(key: string, kind: string, opts?: DataDomainRemoveOptions): void {
686
- switch (kind) {
687
- case DataNamespaceKind:
688
- this.findNamespace(key)?.remove(opts)
689
- break
690
- case DataModelKind:
691
- this.findDataModel(key)?.remove(opts)
692
- break
693
- case DataEntityKind:
694
- this.findEntity(key)?.remove(opts)
695
- break
696
- case DataPropertyKind:
697
- this.findProperty(key)?.remove()
698
- break
699
- case DataAssociationKind:
700
- this.findAssociation(key)?.remove()
701
- break
702
- default:
703
- throw new Error(`Unknown kind ${kind} for the object ${key}.`)
704
- }
705
- }
706
-
707
- /**
708
- * Finds a data model and calls the `remove()` on it.
709
- * @param key The key of the data model to find.
710
- */
711
- removeDataModel(key: string, opts?: DataDomainRemoveOptions): void {
712
- const { definitions } = this.root || this
713
- const model = definitions.models.find((i) => i.key === key)
714
- if (model) {
715
- model.remove(opts)
716
- }
717
- }
718
-
719
- /**
720
- * @returns The graph of associations where keys are the source
721
- * entities and the value is the list of all target entities.
722
- */
723
- associationGraph(): Record<string, string[]> {
724
- const graph: Record<string, string[]> = {}
725
- const { definitions } = this.root || this
726
- const { associations, entities } = definitions
727
- for (const assoc of associations) {
728
- if (!assoc.targets.length) {
729
- continue
730
- }
731
- const srcEntity = entities.find((i) => i.associations.some((a) => a === assoc))
732
- if (!srcEntity) {
733
- continue
734
- }
735
- if (!graph[srcEntity.key]) {
736
- graph[srcEntity.key] = []
737
- }
738
- const targetIds = assoc.targets.map((i) => i.key)
739
- graph[srcEntity.key].splice(0, 0, ...targetIds)
740
- }
741
- return graph
742
- }
743
-
744
- /**
745
- * Prints out all associations from one entity to another through all entities that may be in between.
746
- *
747
- * @param from The key of the from entity
748
- * @param to The key of the target entity
749
- * @param g The graph generated with `associationGraph()`
750
- * @param path The current list of entity ids. Do not set this, it is for the recursive processing of the graph.
751
- * @param visited The list of visited paths to avoid cycles.
752
- * Do not set this, it is for the recursive processing of the graph.
753
- */
754
- *associationPath(
755
- from: string,
756
- to: string,
757
- g: Record<string, string[]>,
758
- path: string[] = [],
759
- visited = new Set<string>()
760
- ): Generator<string[]> {
761
- if (from === to) {
762
- yield path.concat(to)
763
- return
764
- }
765
- if (visited.has(from)) {
766
- // it's a cycle
767
- return
768
- }
769
- if (g[from]) {
770
- visited.add(from)
771
- path.push(from)
772
-
773
- for (const neighbor of g[from]) {
774
- yield* this.associationPath(neighbor, to, g, path, visited)
775
- }
776
-
777
- visited.delete(from)
778
- path.pop()
779
- }
780
- }
781
-
782
- /**
783
- * Scans all associations for foreign namespaces and returns
784
- * the list of all namespaces used in the association graph.
785
- * This will never add this namespace's key.
786
- *
787
- * This function should be used to read keys for all related
788
- * namespaces through associations.
789
- *
790
- * @returns All keys of foreign namespaces.
791
- */
792
- computeForeignNamespaceKeys(): string[] {
793
- const result: string[] = []
794
- const { associations = [] } = this.definitions
795
- associations.forEach((association) => {
796
- const { targets = [] } = association
797
- targets.forEach((target) => {
798
- const { namespace } = target
799
- if (!namespace || namespace === this.key) {
800
- return
801
- }
802
- result.push(namespace)
803
- })
804
- })
805
- return result
806
- }
807
-
808
- /**
809
- * Finds an entity in this namespace.
810
- * @param key The key of the entity to find.
811
- */
812
- findEntity(key: string): DataEntity | undefined {
813
- const { definitions } = this.root || this
814
- return definitions.entities.find((i) => i.key === key)
815
- }
816
-
817
- /**
818
- * Finds a property by its key.
819
- * @param key The key of the property to find
820
- * @returns The property or undefined if not found.
821
- */
822
- findProperty(key: string): DataProperty | undefined {
823
- const { definitions } = this.root || this
824
- return definitions.properties.find((i) => i.key === key)
825
- }
826
-
827
- /**
828
- * Finds an association by its key.
829
- * @param key The key of the property to find
830
- * @returns The property or undefined if not found.
831
- */
832
- findAssociation(key: string): DataAssociation | undefined {
833
- const { definitions } = this.root || this
834
- return definitions.associations.find((i) => i.key === key)
835
- }
836
-
837
- /**
838
- * Searches for entities for association targets.
839
- * This is a helper function to discover entities in the current and foreign namespaces.
840
- *
841
- * @param targets The list of targets
842
- * @returns A list of entities. An `undefined` is put at the index where an entity cannot be found
843
- */
844
- findAssociatedEntities(targets: AssociationTarget[]): (DataEntity | undefined)[] {
845
- const result: (DataEntity | undefined)[] = []
846
- targets.forEach((target) => {
847
- let ns: DataNamespace | undefined
848
- if (target.namespace) {
849
- ns = this.foreign.find((i) => i.key === target.namespace)
850
- } else {
851
- ns = this
852
- }
853
- if (!ns) {
854
- result.push(undefined)
855
- return
856
- }
857
- const entity = ns.findEntity(target.key)
858
- if (entity) {
859
- result.push(entity)
860
- } else {
861
- result.push(undefined)
862
- }
863
- })
864
- return result
865
- }
866
-
867
- /**
868
- * Finds an associated entity in the current or foreign namespace.
869
- * This is a helper function to discover entities in the current and foreign namespaces.
870
- *
871
- * @param key The key of the entity to find.
872
- * @param namespace The optional namespace to search in.
873
- * If not set, the current namespace is used.
874
- * This is used to find entities in foreign namespaces.
875
- * @returns The entity or undefined if not found.
876
- */
877
- findAssociatedEntity(key: string, namespace?: string): DataEntity | undefined {
878
- let ns: DataNamespace | undefined
879
- if (namespace) {
880
- ns = this.foreign.find((i) => i.key === namespace)
881
- } else {
882
- ns = this
883
- }
884
- if (!ns) {
885
- return undefined
886
- }
887
- return ns.findEntity(key)
888
- }
889
-
890
- addForeign(ns: DataNamespace): void {
891
- const exists = this.foreign.some((i) => i.key === ns.key)
892
- if (exists) {
893
- return
894
- }
895
- this.foreign.push(ns)
896
- }
897
-
898
- removeForeign(ns: DataNamespace): void {
899
- const index = this.foreign.findIndex((i) => i === ns)
900
- if (index >= 0) {
901
- this.foreign.splice(index, 1)
902
- }
903
- }
904
-
905
- hasForeignNamespace(key: string): boolean {
906
- return this.foreign.some((i) => i.key === key)
907
- }
908
-
909
- /**
910
- * Checks whether the namespace is a child of the given namespace.
911
- * The relationship doesn't have to be direct, as long as the namespace is in the hierarchy it will return true.
912
- *
913
- * @param key The key of the parent namespace to check.
914
- * @returns True if this namespace is a child of the given namespace.
915
- */
916
- isChildOf(key: string): boolean {
917
- if (this.key === key) {
918
- return false
919
- }
920
- const parent = this.getParentInstance()
921
- if (!parent) {
922
- return false
923
- }
924
- if (parent.key === key) {
925
- return true
926
- }
927
- return parent.isChildOf(key)
928
- }
929
- }