@api-client/core 0.12.1 → 0.12.3

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 (67) hide show
  1. package/bin/plugins/sinon/assert.ts +29 -0
  2. package/bin/test.ts +2 -0
  3. package/build/src/browser.d.ts +4 -0
  4. package/build/src/browser.d.ts.map +1 -1
  5. package/build/src/browser.js +3 -0
  6. package/build/src/browser.js.map +1 -1
  7. package/build/src/index.d.ts +4 -0
  8. package/build/src/index.d.ts.map +1 -1
  9. package/build/src/index.js +3 -0
  10. package/build/src/index.js.map +1 -1
  11. package/build/src/modeling/DataDomain.d.ts +4 -0
  12. package/build/src/modeling/DataDomain.d.ts.map +1 -1
  13. package/build/src/modeling/DataDomain.js +11 -0
  14. package/build/src/modeling/DataDomain.js.map +1 -1
  15. package/build/src/modeling/DomainAssociation.js +1 -1
  16. package/build/src/modeling/DomainAssociation.js.map +1 -1
  17. package/build/src/modeling/DomainEntity.d.ts +46 -0
  18. package/build/src/modeling/DomainEntity.d.ts.map +1 -1
  19. package/build/src/modeling/DomainEntity.js +71 -0
  20. package/build/src/modeling/DomainEntity.js.map +1 -1
  21. package/build/src/modeling/DomainImpactAnalysis.d.ts +31 -8
  22. package/build/src/modeling/DomainImpactAnalysis.d.ts.map +1 -1
  23. package/build/src/modeling/DomainImpactAnalysis.js +118 -46
  24. package/build/src/modeling/DomainImpactAnalysis.js.map +1 -1
  25. package/build/src/modeling/DomainProperty.js +1 -1
  26. package/build/src/modeling/DomainProperty.js.map +1 -1
  27. package/build/src/modeling/validation/association_validation.d.ts +38 -0
  28. package/build/src/modeling/validation/association_validation.d.ts.map +1 -0
  29. package/build/src/modeling/validation/association_validation.js +108 -0
  30. package/build/src/modeling/validation/association_validation.js.map +1 -0
  31. package/build/src/modeling/validation/entity_validation.d.ts +52 -0
  32. package/build/src/modeling/validation/entity_validation.d.ts.map +1 -0
  33. package/build/src/modeling/validation/entity_validation.js +241 -0
  34. package/build/src/modeling/validation/entity_validation.js.map +1 -0
  35. package/build/src/modeling/validation/postgresql.d.ts +2 -0
  36. package/build/src/modeling/validation/postgresql.d.ts.map +1 -0
  37. package/build/src/modeling/validation/postgresql.js +58 -0
  38. package/build/src/modeling/validation/postgresql.js.map +1 -0
  39. package/build/src/modeling/validation/property_validation.d.ts +29 -0
  40. package/build/src/modeling/validation/property_validation.d.ts.map +1 -0
  41. package/build/src/modeling/validation/property_validation.js +58 -0
  42. package/build/src/modeling/validation/property_validation.js.map +1 -0
  43. package/build/src/modeling/validation/rules.d.ts +55 -0
  44. package/build/src/modeling/validation/rules.d.ts.map +1 -0
  45. package/build/src/modeling/validation/rules.js +110 -0
  46. package/build/src/modeling/validation/rules.js.map +1 -0
  47. package/package.json +1 -1
  48. package/src/modeling/DataDomain.ts +12 -0
  49. package/src/modeling/DomainAssociation.ts +1 -1
  50. package/src/modeling/DomainEntity.ts +75 -0
  51. package/src/modeling/DomainImpactAnalysis.ts +144 -54
  52. package/src/modeling/DomainProperty.ts +1 -1
  53. package/src/modeling/validation/association_validation.ts +109 -0
  54. package/src/modeling/validation/entity_validation.ts +246 -0
  55. package/src/modeling/validation/postgresql.ts +57 -0
  56. package/src/modeling/validation/property_validation.ts +58 -0
  57. package/src/modeling/validation/rules.ts +152 -0
  58. package/tests/unit/modeling/data_domain_associations.spec.ts +1 -1
  59. package/tests/unit/modeling/data_domain_property.spec.ts +1 -1
  60. package/tests/unit/modeling/domain.property.spec.ts +7 -7
  61. package/tests/unit/modeling/domain_asociation.spec.ts +3 -3
  62. package/tests/unit/modeling/domain_entity_associations.spec.ts +1 -1
  63. package/tests/unit/modeling/domain_entity_properties.spec.ts +2 -2
  64. package/tests/unit/modeling/domain_impact_analysis.spec.ts +138 -29
  65. package/tests/unit/modeling/validation/association_validation.spec.ts +157 -0
  66. package/tests/unit/modeling/validation/entity_validation.spec.ts +192 -0
  67. package/tests/unit/modeling/validation/property_validation.spec.ts +135 -0
@@ -0,0 +1,192 @@
1
+ import { test } from '@japa/runner'
2
+ import { DataDomain, EntityValidation } from '../../../../src/index.js'
3
+
4
+ test.group('EntityValidation', (group) => {
5
+ let domain: DataDomain
6
+ let validation: EntityValidation
7
+
8
+ group.each.setup(() => {
9
+ domain = new DataDomain()
10
+ validation = new EntityValidation(domain)
11
+ })
12
+
13
+ test('validate() should return an error when the entity does not exist', ({ assert }) => {
14
+ const results = validation.validate('nonExistentEntity')
15
+ assert.lengthOf(results, 1)
16
+ assert.equal(results[0].rule, 'exists')
17
+ assert.equal(results[0].severity, 'error')
18
+ })
19
+
20
+ test('validate() should call other validation methods', ({ assert, sinon }) => {
21
+ const model = domain.addModel({ key: 'model' })
22
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
23
+ const primaryKeySpy = sinon.spy(validation, 'validatePrimaryKey')
24
+ const minimumRequiredPropertiesSpy = sinon.spy(validation, 'minimumRequiredProperties')
25
+ const validateNameSpy = sinon.spy(validation, 'validateName')
26
+ const uniqueNameSpy = sinon.spy(validation, 'uniqueName')
27
+
28
+ validation.validate(entity)
29
+
30
+ assert.calledWith(primaryKeySpy, entity)
31
+ assert.calledWith(minimumRequiredPropertiesSpy, entity)
32
+ assert.calledWith(validateNameSpy, entity)
33
+ assert.calledWith(uniqueNameSpy, entity)
34
+ sinon.restore()
35
+ })
36
+
37
+ test('validatePrimaryKey() should return an error when the entity has no primary key', ({ assert }) => {
38
+ const model = domain.addModel({ key: 'model' })
39
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
40
+ const results = validation.validatePrimaryKey(entity)
41
+ assert.lengthOf(results, 1)
42
+ assert.equal(results[0].rule, 'primary_key')
43
+ assert.equal(results[0].severity, 'error')
44
+ })
45
+
46
+ test('validatePrimaryKey() should return no errors when the entity has a primary key', ({ assert }) => {
47
+ const model = domain.addModel({ key: 'model' })
48
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
49
+ entity.addProperty({ key: 'id', type: 'string', primary: true })
50
+ const results = validation.validatePrimaryKey(entity)
51
+ assert.lengthOf(results, 0)
52
+ })
53
+
54
+ test('validatePrimaryKey() should return no errors when the entity inherits a primary key', ({ assert }) => {
55
+ const model = domain.addModel({ key: 'model' })
56
+ const parent = model.addEntity({ key: 'parent', info: { name: 'Parent' } })
57
+ parent.addProperty({ key: 'id', type: 'string', primary: true })
58
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
59
+ entity.addParent(parent.key)
60
+ const results = validation.validatePrimaryKey(entity)
61
+ assert.lengthOf(results, 0)
62
+ })
63
+
64
+ test('minimumRequiredProperties() should return a warning when the entity has no properties', ({ assert }) => {
65
+ const model = domain.addModel({ key: 'model' })
66
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
67
+ const results = validation.minimumRequiredProperties(entity)
68
+ assert.lengthOf(results, 1)
69
+ assert.equal(results[0].rule, 'required')
70
+ assert.equal(results[0].severity, 'warning')
71
+ })
72
+
73
+ test('minimumRequiredProperties() should return no errors when the entity has properties', ({ assert }) => {
74
+ const model = domain.addModel({ key: 'model' })
75
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
76
+ entity.addProperty({ key: 'name', type: 'string' })
77
+ const results = validation.minimumRequiredProperties(entity)
78
+ assert.lengthOf(results, 0)
79
+ })
80
+
81
+ test('validateName() should return an error when the entity has no name', ({ assert }) => {
82
+ const model = domain.addModel({ key: 'model' })
83
+ const entity = model.addEntity({ key: 'entity', info: {} })
84
+ entity.info.name = undefined
85
+ const results = validation.validateName(entity)
86
+ assert.lengthOf(results, 1)
87
+ assert.equal(results[0].rule, 'required')
88
+ assert.equal(results[0].severity, 'error')
89
+ })
90
+
91
+ test('validateName() should return an error when the entity name is too short', ({ assert }) => {
92
+ const model = domain.addModel({ key: 'model' })
93
+ const entity = model.addEntity({ key: 'entity', info: { name: 'a' } })
94
+ const results = validation.validateName(entity)
95
+ assert.lengthOf(results, 1)
96
+ assert.equal(results[0].rule, 'length')
97
+ assert.equal(results[0].severity, 'error')
98
+ })
99
+
100
+ test('validateName() should return an error when the entity name is too long', ({ assert }) => {
101
+ const model = domain.addModel({ key: 'model' })
102
+ const entity = model.addEntity({ key: 'entity', info: { name: 'a'.repeat(32) } })
103
+ const results = validation.validateName(entity)
104
+ assert.lengthOf(results, 1)
105
+ assert.equal(results[0].rule, 'length')
106
+ assert.equal(results[0].severity, 'error')
107
+ })
108
+
109
+ test('validateName() should return an error when the entity name has invalid characters', ({ assert }) => {
110
+ const model = domain.addModel({ key: 'model' })
111
+ const entity = model.addEntity({ key: 'entity', info: { name: 'invalid-name' } })
112
+ const results = validation.validateName(entity)
113
+ assert.lengthOf(results, 1)
114
+ assert.equal(results[0].rule, 'format')
115
+ assert.equal(results[0].severity, 'error')
116
+ })
117
+
118
+ test('validateName() should return an info when the entity name is not in snake case', ({ assert }) => {
119
+ const model = domain.addModel({ key: 'model' })
120
+ const entity = model.addEntity({ key: 'entity', info: { name: 'EntityName' } })
121
+ const results = validation.validateName(entity)
122
+ assert.lengthOf(results, 1)
123
+ assert.equal(results[0].rule, 'snake_case')
124
+ assert.equal(results[0].severity, 'info')
125
+ })
126
+
127
+ test('validateName() should return an error when the entity name is a reserved keyword', ({ assert }) => {
128
+ const model = domain.addModel({ key: 'model' })
129
+ const entity = model.addEntity({ key: 'entity', info: { name: 'select' } })
130
+ const results = validation.validateName(entity)
131
+ assert.lengthOf(results, 1)
132
+ assert.equal(results[0].rule, 'reserved')
133
+ assert.equal(results[0].severity, 'error')
134
+ })
135
+
136
+ test('validateName() should return no errors when the entity name is valid', ({ assert }) => {
137
+ const model = domain.addModel({ key: 'model' })
138
+ const entity = model.addEntity({ key: 'entity', info: { name: 'valid_name' } })
139
+ const results = validation.validateName(entity)
140
+ assert.lengthOf(results, 0)
141
+ })
142
+
143
+ test('uniqueName() should return an error when the entity name is not unique', ({ assert }) => {
144
+ const model = domain.addModel({ key: 'model' })
145
+ model.addEntity({ key: 'entity1', info: { name: 'entity_name' } })
146
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'entity_name' } })
147
+ const results = validation.uniqueName(entity2)
148
+ assert.lengthOf(results, 1)
149
+ assert.equal(results[0].rule, 'unique')
150
+ assert.equal(results[0].severity, 'error')
151
+ })
152
+
153
+ test('uniqueName() should return no errors when the entity name is unique', ({ assert }) => {
154
+ const model = domain.addModel({ key: 'model' })
155
+ model.addEntity({ key: 'entity1', info: { name: 'entity_name_1' } })
156
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'entity_name_2' } })
157
+ const results = validation.uniqueName(entity2)
158
+ assert.lengthOf(results, 0)
159
+ })
160
+
161
+ test('uniqueName() should return an error when the entity name is not unique (case insensitive)', ({ assert }) => {
162
+ const model = domain.addModel({ key: 'model' })
163
+ model.addEntity({ key: 'entity1', info: { name: 'Entity_Name1' } })
164
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'entity_name1' } })
165
+ const results = validation.uniqueName(entity2)
166
+ assert.lengthOf(results, 1)
167
+ assert.equal(results[0].rule, 'unique')
168
+ assert.equal(results[0].severity, 'error')
169
+ })
170
+
171
+ test('uniqueName() should return no errors when the entity name is not set', ({ assert }) => {
172
+ const model = domain.addModel({ key: 'model' })
173
+ model.addEntity({ key: 'entity1', info: { name: 'EntityName1' } })
174
+ const entity2 = model.addEntity({ key: 'entity2', info: {} })
175
+ const results = validation.uniqueName(entity2)
176
+ assert.lengthOf(results, 0)
177
+ })
178
+
179
+ test('uniqueName() should return an error when the entity name is not unique in a foreign domain', ({ assert }) => {
180
+ const foreignDomain = new DataDomain()
181
+ const foreignModel = foreignDomain.addModel({ key: 'foreignModel' })
182
+ foreignModel.addEntity({ key: 'foreignEntity', info: { name: 'entity_name' } })
183
+ foreignDomain.info.version = '1.0.0'
184
+ domain.registerForeignDomain(foreignDomain)
185
+ const model = domain.addModel({ key: 'model' })
186
+ const entity2 = model.addEntity({ key: 'entity2', info: { name: 'entity_name' } })
187
+ const results = validation.uniqueName(entity2)
188
+ assert.lengthOf(results, 1)
189
+ assert.equal(results[0].rule, 'unique')
190
+ assert.equal(results[0].severity, 'error')
191
+ })
192
+ })
@@ -0,0 +1,135 @@
1
+ import { test } from '@japa/runner'
2
+ import { DataDomain, PropertyValidation } from '../../../../src/index.js'
3
+
4
+ test.group('PropertyValidation', (group) => {
5
+ let domain: DataDomain
6
+ let validation: PropertyValidation
7
+
8
+ group.each.setup(() => {
9
+ domain = new DataDomain()
10
+ validation = new PropertyValidation(domain)
11
+ })
12
+
13
+ test('validate() should return an error when the property does not exist', ({ assert }) => {
14
+ const results = validation.validate('nonExistentProperty')
15
+ assert.lengthOf(results, 1)
16
+ assert.equal(results[0].rule, 'exists')
17
+ assert.equal(results[0].severity, 'error')
18
+ })
19
+
20
+ test('validate() should call other validation methods', ({ assert, sinon }) => {
21
+ const model = domain.addModel({ key: 'model' })
22
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
23
+ const property = entity.addProperty({ key: 'property', type: 'string', info: { name: 'property' } })
24
+ const validateNameSpy = sinon.spy(validation, 'validateName')
25
+
26
+ validation.validate(property)
27
+
28
+ assert.calledWith(validateNameSpy, property)
29
+ sinon.restore()
30
+ })
31
+
32
+ test('validateName() should return an error when the property has no name', ({ assert }) => {
33
+ const model = domain.addModel({ key: 'model' })
34
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
35
+ const property = entity.addProperty({ key: 'property', type: 'string' })
36
+ property.info.name = undefined
37
+ const results = validation.validateName(property)
38
+ assert.lengthOf(results, 1)
39
+ assert.equal(results[0].rule, 'required')
40
+ assert.equal(results[0].severity, 'error')
41
+ })
42
+
43
+ test('validateName() should return an error when the property name starts with a number', ({ assert }) => {
44
+ const model = domain.addModel({ key: 'model' })
45
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
46
+ const property = entity.addProperty({ key: '1property', type: 'string', info: { name: '1property' } })
47
+ const results = validation.validateName(property)
48
+ assert.lengthOf(results, 1)
49
+ assert.equal(results[0].rule, 'format')
50
+ assert.equal(results[0].severity, 'error')
51
+ })
52
+
53
+ test('validateName() should return an error when the property name contains invalid characters', ({ assert }) => {
54
+ const model = domain.addModel({ key: 'model' })
55
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
56
+ const property = entity.addProperty({
57
+ key: 'invalid-property!',
58
+ type: 'string',
59
+ info: { name: 'invalid-property!' },
60
+ })
61
+ const results = validation.validateName(property)
62
+ assert.lengthOf(results, 1)
63
+ assert.equal(results[0].rule, 'format')
64
+ assert.equal(results[0].severity, 'error')
65
+ })
66
+
67
+ test('validateName() should return an error when the property name is too short', ({ assert }) => {
68
+ const model = domain.addModel({ key: 'model' })
69
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
70
+ const property = entity.addProperty({ key: 'a', type: 'string', info: { name: 'a' } })
71
+ const results = validation.validateName(property)
72
+ assert.lengthOf(results, 1)
73
+ assert.equal(results[0].rule, 'length')
74
+ assert.equal(results[0].severity, 'error')
75
+ })
76
+
77
+ test('validateName() should return an error when the property name is too long', ({ assert }) => {
78
+ const model = domain.addModel({ key: 'model' })
79
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
80
+ const property = entity.addProperty({ key: 'a'.repeat(60), type: 'string', info: { name: 'a'.repeat(60) } })
81
+ const results = validation.validateName(property)
82
+ assert.lengthOf(results, 1)
83
+ assert.equal(results[0].rule, 'length')
84
+ assert.equal(results[0].severity, 'error')
85
+ })
86
+
87
+ test('validateName() should return no errors when the property name is valid', ({ assert }) => {
88
+ const model = domain.addModel({ key: 'model' })
89
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
90
+ const property = entity.addProperty({
91
+ key: 'valid_property123',
92
+ type: 'string',
93
+ info: { name: 'valid_property123' },
94
+ })
95
+ const results = validation.validateName(property)
96
+ assert.lengthOf(results, 0)
97
+ })
98
+
99
+ test('validateName() should return no errors when the property name starts with underscore', ({ assert }) => {
100
+ const model = domain.addModel({ key: 'model' })
101
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
102
+ const property = entity.addProperty({ key: '_property', type: 'string', info: { name: '_property' } })
103
+ const results = validation.validateName(property)
104
+ assert.lengthOf(results, 0)
105
+ })
106
+
107
+ test('validate() should return an error when the target property is not found (string)', ({ assert }) => {
108
+ const model = domain.addModel({ key: 'model' })
109
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
110
+ entity.addProperty({ key: 'existingProperty', type: 'string', info: { name: 'existing_property' } })
111
+ const results = validation.validate('nonExistingProperty')
112
+ assert.lengthOf(results, 1)
113
+ assert.equal(results[0].rule, 'exists')
114
+ assert.equal(results[0].severity, 'error')
115
+ assert.equal(results[0].key, 'nonExistingProperty')
116
+ })
117
+
118
+ test('validate() should return validation errors for an invalid property name', ({ assert }) => {
119
+ const model = domain.addModel({ key: 'model' })
120
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
121
+ const property = entity.addProperty({ key: 'invalid-name', type: 'string', info: { name: 'invalid-name' } })
122
+ const results = validation.validate(property)
123
+ assert.lengthOf(results, 1)
124
+ assert.equal(results[0].rule, 'format')
125
+ assert.equal(results[0].severity, 'error')
126
+ })
127
+
128
+ test('validate() should return no errors for a valid property name', ({ assert }) => {
129
+ const model = domain.addModel({ key: 'model' })
130
+ const entity = model.addEntity({ key: 'entity', info: { name: 'Entity' } })
131
+ const property = entity.addProperty({ key: 'valid_name', type: 'string', info: { name: 'valid_name' } })
132
+ const results = validation.validate(property)
133
+ assert.lengthOf(results, 0)
134
+ })
135
+ })