@contember/schema-utils 2.1.0-alpha.2 → 2.1.0-alpha.21
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/dist/development/src/type-schema/acl.cjs +2 -2
- package/dist/development/src/type-schema/acl.cjs.map +1 -1
- package/dist/development/src/type-schema/acl.js +2 -2
- package/dist/development/src/type-schema/acl.js.map +1 -1
- package/dist/development/src/validation/MembershipResolver.cjs +10 -7
- package/dist/development/src/validation/MembershipResolver.cjs.map +1 -1
- package/dist/development/src/validation/MembershipResolver.js +10 -7
- package/dist/development/src/validation/MembershipResolver.js.map +1 -1
- package/dist/development/src/validation/ModelValidator.cjs +2 -7
- package/dist/development/src/validation/ModelValidator.cjs.map +1 -1
- package/dist/development/src/validation/ModelValidator.js +2 -7
- package/dist/development/src/validation/ModelValidator.js.map +1 -1
- package/dist/production/src/type-schema/acl.cjs +2 -2
- package/dist/production/src/type-schema/acl.cjs.map +1 -1
- package/dist/production/src/type-schema/acl.js +2 -2
- package/dist/production/src/type-schema/acl.js.map +1 -1
- package/dist/production/src/validation/MembershipResolver.cjs +10 -7
- package/dist/production/src/validation/MembershipResolver.cjs.map +1 -1
- package/dist/production/src/validation/MembershipResolver.js +10 -7
- package/dist/production/src/validation/MembershipResolver.js.map +1 -1
- package/dist/production/src/validation/ModelValidator.cjs +2 -7
- package/dist/production/src/validation/ModelValidator.cjs.map +1 -1
- package/dist/production/src/validation/ModelValidator.js +2 -7
- package/dist/production/src/validation/ModelValidator.js.map +1 -1
- package/dist/tests/tsconfig.tsbuildinfo +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dist/types/validation/MembershipResolver.d.ts +1 -1
- package/dist/types/validation/MembershipResolver.d.ts.map +1 -1
- package/dist/types/validation/ModelValidator.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/type-schema/acl.ts +2 -2
- package/src/validation/MembershipResolver.ts +10 -6
- package/src/validation/ModelValidator.ts +2 -7
- package/tests/cases/unit/membershipResolver.test.ts +67 -8
- package/tests/cases/unit/modelValidator.test.ts +19 -0
|
@@ -60,8 +60,8 @@ export class ModelValidator {
|
|
|
60
60
|
|
|
61
61
|
private validateUniqueConstraints(entity: Model.Entity, errors: ErrorBuilder): void {
|
|
62
62
|
for (const constraint of entity.unique) {
|
|
63
|
-
if (entity.view && !constraint.index) {
|
|
64
|
-
errors.add('MODEL_INVALID_CONSTRAINT', '
|
|
63
|
+
if (entity.view?.materialized && !constraint.index) {
|
|
64
|
+
errors.add('MODEL_INVALID_CONSTRAINT', 'For materialized views, Unique must be defined as an index. Please set index: true.')
|
|
65
65
|
}
|
|
66
66
|
for (const field of constraint.fields) {
|
|
67
67
|
const fieldDef = entity.fields[field]
|
|
@@ -195,11 +195,6 @@ export class ModelValidator {
|
|
|
195
195
|
}
|
|
196
196
|
} else {
|
|
197
197
|
const inversedBy = field.inversedBy
|
|
198
|
-
if (targetEntity.view) {
|
|
199
|
-
if ('joiningColumn' in field) {
|
|
200
|
-
return errors.add('MODEL_INVALID_VIEW_USAGE', `View entity ${targetEntity.name} cannot be referenced from an owning relation. Try switching the owning side.`)
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
198
|
if (inversedBy) {
|
|
204
199
|
const targetField = targetEntity.fields[inversedBy]
|
|
205
200
|
const relationDescription = `Target relation ${targetEntityName}::${inversedBy}:`
|
|
@@ -3,6 +3,7 @@ import { MembershipResolver, MembershipValidationErrorType } from '../../../src'
|
|
|
3
3
|
import { Acl } from '@contember/schema'
|
|
4
4
|
|
|
5
5
|
const id1 = 'bff057b3-11f7-4bc7-abe3-1f2ef266824d'
|
|
6
|
+
const id2 = '1cdb828f-62f0-4ae5-9b2c-e53b3e7584ef'
|
|
6
7
|
test('read membership with entity variable', () => {
|
|
7
8
|
const reader = new MembershipResolver()
|
|
8
9
|
const result = reader.resolve({
|
|
@@ -16,7 +17,7 @@ test('read membership with entity variable', () => {
|
|
|
16
17
|
},
|
|
17
18
|
}, [
|
|
18
19
|
{ role: 'editor', variables: [{ name: 'localeID', values: [id1] }] },
|
|
19
|
-
], MembershipResolver.UnknownIdentity)
|
|
20
|
+
], MembershipResolver.UnknownIdentity, false)
|
|
20
21
|
expect(result.errors).toStrictEqual([])
|
|
21
22
|
expect(result.memberships).toStrictEqual([
|
|
22
23
|
{ role: 'editor', variables: [{ name: 'localeID', condition: { in: [id1] } }] },
|
|
@@ -36,7 +37,7 @@ test('read fails when variable is not provided', () => {
|
|
|
36
37
|
},
|
|
37
38
|
}, [
|
|
38
39
|
{ role: 'editor', variables: [] },
|
|
39
|
-
], MembershipResolver.UnknownIdentity)
|
|
40
|
+
], MembershipResolver.UnknownIdentity, false)
|
|
40
41
|
expect(result.errors).toEqual([{
|
|
41
42
|
error: MembershipValidationErrorType.VARIABLE_EMPTY,
|
|
42
43
|
role: 'editor',
|
|
@@ -63,7 +64,7 @@ test('read membership with predefined variable', () => {
|
|
|
63
64
|
{ role: 'editor', variables: [] },
|
|
64
65
|
], {
|
|
65
66
|
identityId: id1,
|
|
66
|
-
})
|
|
67
|
+
}, false)
|
|
67
68
|
expect(result.errors).toStrictEqual([])
|
|
68
69
|
expect(result.memberships).toStrictEqual([
|
|
69
70
|
{ role: 'editor', variables: [{ name: 'self', condition: { in: [id1] } }] },
|
|
@@ -83,13 +84,71 @@ test('read membership with condition variable', () => {
|
|
|
83
84
|
},
|
|
84
85
|
}, [
|
|
85
86
|
{ role: 'editor', variables: [{ name: 'cond', values: [JSON.stringify({ eq: 'foo' })] }] },
|
|
86
|
-
], MembershipResolver.UnknownIdentity)
|
|
87
|
+
], MembershipResolver.UnknownIdentity, false)
|
|
87
88
|
expect(result.errors).toStrictEqual([])
|
|
88
89
|
expect(result.memberships).toStrictEqual([
|
|
89
90
|
{ role: 'editor', variables: [{ name: 'cond', condition: { eq: 'foo' } }] },
|
|
90
91
|
])
|
|
91
92
|
})
|
|
92
93
|
|
|
94
|
+
test('fails when trying to override predefined variable with stored', () => {
|
|
95
|
+
const reader = new MembershipResolver()
|
|
96
|
+
const result = reader.resolve({
|
|
97
|
+
roles: {
|
|
98
|
+
editor: {
|
|
99
|
+
variables: {
|
|
100
|
+
self: { type: Acl.VariableType.predefined, value: 'identityID' },
|
|
101
|
+
},
|
|
102
|
+
entities: {},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
}, [
|
|
106
|
+
{
|
|
107
|
+
role: 'editor', variables: [
|
|
108
|
+
{ name: 'self', values: [id2] },
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
], {
|
|
112
|
+
identityId: id1,
|
|
113
|
+
}, false)
|
|
114
|
+
expect(result.errors).toEqual([{
|
|
115
|
+
error: MembershipValidationErrorType.VARIABLE_NOT_FOUND,
|
|
116
|
+
role: 'editor',
|
|
117
|
+
variable: 'self',
|
|
118
|
+
}])
|
|
119
|
+
expect(result.memberships).toStrictEqual([
|
|
120
|
+
{ role: 'editor', variables: [{ name: 'self', condition: { in: [id1] } }] },
|
|
121
|
+
])
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
test('read overridden predefined variable with assume', () => {
|
|
126
|
+
const reader = new MembershipResolver()
|
|
127
|
+
const result = reader.resolve({
|
|
128
|
+
roles: {
|
|
129
|
+
editor: {
|
|
130
|
+
variables: {
|
|
131
|
+
self: { type: Acl.VariableType.predefined, value: 'identityID' },
|
|
132
|
+
},
|
|
133
|
+
entities: {},
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
}, [
|
|
137
|
+
{
|
|
138
|
+
role: 'editor', variables: [
|
|
139
|
+
{ name: 'self', values: [id2] },
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
], {
|
|
143
|
+
identityId: id1,
|
|
144
|
+
}, true)
|
|
145
|
+
expect(result.errors).toEqual([])
|
|
146
|
+
expect(result.memberships).toStrictEqual([
|
|
147
|
+
{ role: 'editor', variables: [{ name: 'self', condition: { in: [id2] } }] },
|
|
148
|
+
])
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
|
|
93
152
|
test('fails on invalid condition', () => {
|
|
94
153
|
const reader = new MembershipResolver()
|
|
95
154
|
const result = reader.resolve({
|
|
@@ -103,7 +162,7 @@ test('fails on invalid condition', () => {
|
|
|
103
162
|
},
|
|
104
163
|
}, [
|
|
105
164
|
{ role: 'editor', variables: [{ name: 'cond', values: [JSON.stringify('abcd')] }] },
|
|
106
|
-
], MembershipResolver.UnknownIdentity)
|
|
165
|
+
], MembershipResolver.UnknownIdentity, false)
|
|
107
166
|
|
|
108
167
|
expect(result.errors).toEqual([{
|
|
109
168
|
error: MembershipValidationErrorType.VARIABLE_INVALID,
|
|
@@ -125,7 +184,7 @@ test('fails on undefined role', () => {
|
|
|
125
184
|
{ role: 'editor', variables: [{ name: 'cond', values: [JSON.stringify('abcd')] }] },
|
|
126
185
|
], {
|
|
127
186
|
identityId: id1,
|
|
128
|
-
})
|
|
187
|
+
}, false)
|
|
129
188
|
|
|
130
189
|
expect(result.errors).toEqual([{
|
|
131
190
|
error: MembershipValidationErrorType.ROLE_NOT_FOUND,
|
|
@@ -147,7 +206,7 @@ test('fails on undefined variable', () => {
|
|
|
147
206
|
},
|
|
148
207
|
}, [
|
|
149
208
|
{ role: 'editor', variables: [{ name: 'cond', values: [JSON.stringify('abcd')] }] },
|
|
150
|
-
], MembershipResolver.UnknownIdentity)
|
|
209
|
+
], MembershipResolver.UnknownIdentity, false)
|
|
151
210
|
|
|
152
211
|
expect(result.errors).toEqual([{
|
|
153
212
|
error: MembershipValidationErrorType.VARIABLE_NOT_FOUND,
|
|
@@ -174,7 +233,7 @@ test('use fallback value', () => {
|
|
|
174
233
|
},
|
|
175
234
|
}, [
|
|
176
235
|
{ role: 'editor', variables: [] },
|
|
177
|
-
], MembershipResolver.UnknownIdentity)
|
|
236
|
+
], MembershipResolver.UnknownIdentity, false)
|
|
178
237
|
expect(result.errors).toStrictEqual([])
|
|
179
238
|
|
|
180
239
|
expect(result.memberships).toStrictEqual([
|
|
@@ -91,3 +91,22 @@ test('column name collision', () => {
|
|
|
91
91
|
},
|
|
92
92
|
])
|
|
93
93
|
})
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
namespace ViewRelations {
|
|
97
|
+
@c.View('SELECT 1')
|
|
98
|
+
export class Foo {
|
|
99
|
+
bars = c.oneHasMany(Bar, 'foo')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
@c.View('SELECT 1')
|
|
103
|
+
export class Bar {
|
|
104
|
+
foo = c.manyHasOne(Foo, 'bars')
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
test('view relations', () => {
|
|
109
|
+
const schema = createSchema(ViewRelations)
|
|
110
|
+
const validator = new ModelValidator(schema.model)
|
|
111
|
+
expect(validator.validate()).toStrictEqual([])
|
|
112
|
+
})
|