@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.
Files changed (35) hide show
  1. package/dist/development/src/type-schema/acl.cjs +2 -2
  2. package/dist/development/src/type-schema/acl.cjs.map +1 -1
  3. package/dist/development/src/type-schema/acl.js +2 -2
  4. package/dist/development/src/type-schema/acl.js.map +1 -1
  5. package/dist/development/src/validation/MembershipResolver.cjs +10 -7
  6. package/dist/development/src/validation/MembershipResolver.cjs.map +1 -1
  7. package/dist/development/src/validation/MembershipResolver.js +10 -7
  8. package/dist/development/src/validation/MembershipResolver.js.map +1 -1
  9. package/dist/development/src/validation/ModelValidator.cjs +2 -7
  10. package/dist/development/src/validation/ModelValidator.cjs.map +1 -1
  11. package/dist/development/src/validation/ModelValidator.js +2 -7
  12. package/dist/development/src/validation/ModelValidator.js.map +1 -1
  13. package/dist/production/src/type-schema/acl.cjs +2 -2
  14. package/dist/production/src/type-schema/acl.cjs.map +1 -1
  15. package/dist/production/src/type-schema/acl.js +2 -2
  16. package/dist/production/src/type-schema/acl.js.map +1 -1
  17. package/dist/production/src/validation/MembershipResolver.cjs +10 -7
  18. package/dist/production/src/validation/MembershipResolver.cjs.map +1 -1
  19. package/dist/production/src/validation/MembershipResolver.js +10 -7
  20. package/dist/production/src/validation/MembershipResolver.js.map +1 -1
  21. package/dist/production/src/validation/ModelValidator.cjs +2 -7
  22. package/dist/production/src/validation/ModelValidator.cjs.map +1 -1
  23. package/dist/production/src/validation/ModelValidator.js +2 -7
  24. package/dist/production/src/validation/ModelValidator.js.map +1 -1
  25. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  26. package/dist/types/tsconfig.tsbuildinfo +1 -1
  27. package/dist/types/validation/MembershipResolver.d.ts +1 -1
  28. package/dist/types/validation/MembershipResolver.d.ts.map +1 -1
  29. package/dist/types/validation/ModelValidator.d.ts.map +1 -1
  30. package/package.json +4 -4
  31. package/src/type-schema/acl.ts +2 -2
  32. package/src/validation/MembershipResolver.ts +10 -6
  33. package/src/validation/ModelValidator.ts +2 -7
  34. package/tests/cases/unit/membershipResolver.test.ts +67 -8
  35. 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', 'Unique constraint on view entity must be an index. Please set index: true')
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
+ })