@contember/engine-content-api 1.2.0-alpha.3 → 1.2.0-alpha.4

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 (55) hide show
  1. package/dist/src/acl/VariableInjector.d.ts +0 -1
  2. package/dist/src/acl/VariableInjector.d.ts.map +1 -1
  3. package/dist/src/acl/VariableInjector.js +4 -16
  4. package/dist/src/acl/VariableInjector.js.map +1 -1
  5. package/dist/src/acl/VariableUtils.d.ts +2 -13
  6. package/dist/src/acl/VariableUtils.d.ts.map +1 -1
  7. package/dist/src/acl/VariableUtils.js +6 -23
  8. package/dist/src/acl/VariableUtils.js.map +1 -1
  9. package/dist/src/input-validation/EntityRulesResolver.js +3 -3
  10. package/dist/src/input-validation/EntityRulesResolver.js.map +1 -1
  11. package/dist/src/input-validation/ValidationContext.d.ts +2 -2
  12. package/dist/src/input-validation/ValidationContext.d.ts.map +1 -1
  13. package/dist/src/input-validation/ValidationContext.js.map +1 -1
  14. package/dist/src/tsconfig.tsbuildinfo +1 -1
  15. package/dist/tests/cases/integration/graphQlDb/insert/insertSequence.test.d.ts +2 -0
  16. package/dist/tests/cases/integration/graphQlDb/insert/insertSequence.test.d.ts.map +1 -0
  17. package/dist/tests/cases/integration/graphQlDb/insert/insertSequence.test.js +38 -0
  18. package/dist/tests/cases/integration/graphQlDb/insert/insertSequence.test.js.map +1 -0
  19. package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js +1 -6
  20. package/dist/tests/cases/integration/graphQlRequests/delete/aclDelete.test.js.map +1 -1
  21. package/dist/tests/cases/integration/graphQlRequests/insert/acl/setField.test.js +2 -12
  22. package/dist/tests/cases/integration/graphQlRequests/insert/acl/setField.test.js.map +1 -1
  23. package/dist/tests/cases/integration/graphQlRequests/insert/aclInsert.test.js +1 -6
  24. package/dist/tests/cases/integration/graphQlRequests/insert/aclInsert.test.js.map +1 -1
  25. package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js +4 -24
  26. package/dist/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.js.map +1 -1
  27. package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js +1 -6
  28. package/dist/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.js.map +1 -1
  29. package/dist/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.js +4 -24
  30. package/dist/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.js.map +1 -1
  31. package/dist/tests/cases/unit/aclVariablesFactory.test.js +4 -32
  32. package/dist/tests/cases/unit/aclVariablesFactory.test.js.map +1 -1
  33. package/dist/tests/cases/unit/orderbyHelper.test.js +1 -0
  34. package/dist/tests/cases/unit/orderbyHelper.test.js.map +1 -1
  35. package/dist/tests/cases/unit/predicatesInjector.test.js +1 -6
  36. package/dist/tests/cases/unit/predicatesInjector.test.js.map +1 -1
  37. package/dist/tests/cases/unit/variableInjector.test.js +2 -13
  38. package/dist/tests/cases/unit/variableInjector.test.js.map +1 -1
  39. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  40. package/package.json +10 -10
  41. package/src/acl/VariableInjector.ts +2 -17
  42. package/src/acl/VariableUtils.ts +7 -28
  43. package/src/input-validation/EntityRulesResolver.ts +3 -3
  44. package/src/input-validation/ValidationContext.ts +2 -2
  45. package/tests/cases/integration/graphQlDb/insert/insertSequence.test.ts +34 -0
  46. package/tests/cases/integration/graphQlRequests/delete/aclDelete.test.ts +1 -6
  47. package/tests/cases/integration/graphQlRequests/insert/acl/setField.test.ts +2 -12
  48. package/tests/cases/integration/graphQlRequests/insert/aclInsert.test.ts +1 -6
  49. package/tests/cases/integration/graphQlRequests/query/acl/fieldRestrictedByLocale.test.ts +4 -24
  50. package/tests/cases/integration/graphQlRequests/query/acl/nestedPredicate.test.ts +1 -6
  51. package/tests/cases/integration/graphQlRequests/update/acl/aclUpdate.test.ts +5 -25
  52. package/tests/cases/unit/aclVariablesFactory.test.ts +5 -34
  53. package/tests/cases/unit/orderbyHelper.test.ts +1 -0
  54. package/tests/cases/unit/predicatesInjector.test.ts +1 -6
  55. package/tests/cases/unit/variableInjector.test.ts +2 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/engine-content-api",
3
- "version": "1.2.0-alpha.3",
3
+ "version": "1.2.0-alpha.4",
4
4
  "license": "Apache-2.0",
5
5
  "main": "dist/src/index.js",
6
6
  "typings": "dist/src/index.d.ts",
@@ -10,19 +10,19 @@
10
10
  "test": "vitest --no-threads"
11
11
  },
12
12
  "dependencies": {
13
- "@contember/database": "^1.2.0-alpha.3",
14
- "@contember/dic": "^1.2.0-alpha.3",
15
- "@contember/engine-common": "^1.2.0-alpha.3",
16
- "@contember/graphql-utils": "^1.2.0-alpha.3",
17
- "@contember/schema": "^1.2.0-alpha.3",
18
- "@contember/schema-utils": "^1.2.0-alpha.3",
13
+ "@contember/database": "^1.2.0-alpha.4",
14
+ "@contember/dic": "^1.2.0-alpha.4",
15
+ "@contember/engine-common": "^1.2.0-alpha.4",
16
+ "@contember/graphql-utils": "^1.2.0-alpha.4",
17
+ "@contember/schema": "^1.2.0-alpha.4",
18
+ "@contember/schema-utils": "^1.2.0-alpha.4",
19
19
  "@graphql-tools/schema": "^8.3.5",
20
20
  "graphql-tag": "^2.12.5"
21
21
  },
22
22
  "devDependencies": {
23
- "@contember/database-tester": "^1.2.0-alpha.3",
24
- "@contember/engine-api-tester": "^1.2.0-alpha.3",
25
- "@contember/schema-definition": "^1.2.0-alpha.3",
23
+ "@contember/database-tester": "^1.2.0-alpha.4",
24
+ "@contember/engine-api-tester": "^1.2.0-alpha.4",
25
+ "@contember/schema-definition": "^1.2.0-alpha.4",
26
26
  "@graphql-codegen/cli": "^2.6.2",
27
27
  "@graphql-codegen/typescript": "^2.5.1",
28
28
  "@graphql-codegen/typescript-operations": "^2.4.2",
@@ -10,31 +10,16 @@ export class VariableInjector {
10
10
  return predicateDefinitionProcessor.process(entity, where, {
11
11
  handleColumn: ({ value }) => {
12
12
  if (typeof value === 'string') {
13
- return this.createCondition(this.variables[value] || undefined)
13
+ return this.variables[value] ?? { never: true }
14
14
  }
15
15
  return value as Input.Condition
16
16
  },
17
17
  handleRelation: ({ value, targetEntity }) => {
18
18
  if (typeof value === 'string') {
19
- return { [targetEntity.primary]: this.createCondition(this.variables[value] || undefined) }
19
+ return { [targetEntity.primary]: this.variables[value] ?? { never: true } }
20
20
  }
21
21
  return value
22
22
  },
23
23
  })
24
24
  }
25
-
26
- private createCondition(variable: Acl.VariableMapEntry | undefined): Input.Condition {
27
- if (variable === undefined || variable.value.length === 0) {
28
- return { never: true }
29
- }
30
-
31
- const { value, definition } = variable
32
- if (definition.type === Acl.VariableType.condition) {
33
- if (value.length === 1) {
34
- return value[0] as Input.Condition
35
- }
36
- return { or: value as Input.Condition[] }
37
- }
38
- return { in: value as (string | number)[] }
39
- }
40
25
  }
@@ -1,41 +1,20 @@
1
- import { Acl } from '@contember/schema'
2
- import { getRoleVariables } from '@contember/schema-utils'
1
+ import { Acl, Input } from '@contember/schema'
2
+ import { getRoleVariables, ParsedMembership } from '@contember/schema-utils'
3
3
 
4
- type Memberships = readonly { role: string; variables: readonly { name: string; values: readonly string[] }[] }[]
5
4
 
6
5
  export const createAclVariables = (
7
6
  aclSchema: Acl.Schema,
8
- identity: {
9
- identityId: string
10
- personId: string | null
11
- memberships: Memberships
12
- },
7
+ memberships: readonly ParsedMembership[],
13
8
  ): Acl.VariablesMap => {
14
9
 
15
- const variablesEntries = identity.memberships.flatMap(
10
+ const variablesEntries = memberships.flatMap(
16
11
  membership => {
17
12
  const roleVariables = getRoleVariables(membership.role, aclSchema)
18
- const membershipVariablesMap = Object.fromEntries(membership.variables.map(it => [it.name, it.values]))
13
+ const membershipVariablesMap = Object.fromEntries(membership.variables.map(it => [it.name, it.condition]))
19
14
 
20
- return Object.entries(roleVariables).map(([name, def]): [string, Acl.VariableMapEntry] => {
15
+ return Object.keys(roleVariables).map((name): [string, Input.Condition] => {
21
16
  const prefixed = prefixVariable(membership.role, name)
22
- const value = (() => {
23
- switch (def.type) {
24
- case Acl.VariableType.entity:
25
- return membershipVariablesMap[name] ?? []
26
- case Acl.VariableType.predefined:
27
- switch (def.value) {
28
- case 'identityID':
29
- return [identity.identityId]
30
- case 'personID':
31
- return identity.personId ? [identity.personId] : []
32
- }
33
- throw new Error(`Unknown predefined variable ${def.value}`)
34
- case Acl.VariableType.condition:
35
- return (membershipVariablesMap[name] ?? []).map(it => JSON.parse(it))
36
- }
37
- })()
38
- return [prefixed, { value: value, definition: def }]
17
+ return [prefixed, membershipVariablesMap[name] ?? { never: true }]
39
18
  })
40
19
  },
41
20
  )
@@ -35,7 +35,7 @@ export class EntityRulesResolver {
35
35
 
36
36
  public getEntityRules(entityName: string): Validation.EntityRules {
37
37
  const definedRules = this.validationSchema[entityName] || {}
38
- const fieldsNotNullFlag = acceptEveryFieldVisitor(this.model, entityName, new NotNullFieldsVisitor())
38
+ const fieldsNotNullFlag = acceptEveryFieldVisitor(this.model, entityName, new RequiredFieldsVisitor())
39
39
  const notNullFields = Object.keys(filterObject(fieldsNotNullFlag, (field, val) => val))
40
40
  return notNullFields.reduce(
41
41
  (entityRules, field) => ({
@@ -50,9 +50,9 @@ export class EntityRulesResolver {
50
50
  }
51
51
  }
52
52
 
53
- class NotNullFieldsVisitor implements Model.RelationByTypeVisitor<boolean>, Model.ColumnVisitor<boolean> {
53
+ class RequiredFieldsVisitor implements Model.RelationByTypeVisitor<boolean>, Model.ColumnVisitor<boolean> {
54
54
  visitColumn(entity: Model.Entity, column: Model.AnyColumn): boolean {
55
- return !column.nullable
55
+ return !column.nullable && typeof column.default === 'undefined' && !column.sequence
56
56
  }
57
57
 
58
58
  visitManyHasManyInverse(): boolean {
@@ -10,7 +10,7 @@ namespace ValidationContext {
10
10
  }
11
11
 
12
12
  export type NodeType = Value.Object
13
- export type ValueType = Value.FieldValue
13
+ export type ValueType = Value.FieldValue | undefined
14
14
 
15
15
  export enum NodeContextType {
16
16
  value = 'value',
@@ -69,7 +69,7 @@ namespace ValidationContext {
69
69
 
70
70
  export const createSingleNodeContext = (
71
71
  parent: NodeContext | ValueContext,
72
- value: object | null | string | number | boolean,
72
+ value: ValueType,
73
73
  ): NodeContext | ValueContext => {
74
74
  if (Array.isArray(value)) {
75
75
  throw new Error('Nested arrays are not allowed')
@@ -0,0 +1,34 @@
1
+ import { SchemaDefinition as def } from '@contember/schema-definition'
2
+ import { GQL } from '../../../../src/tags'
3
+ import { test } from 'vitest'
4
+ import { executeDbTest } from '@contember/engine-api-tester'
5
+
6
+ namespace SeqModel {
7
+ export class Order {
8
+ seqId = def.intColumn().sequence().notNull()
9
+ }
10
+ }
11
+
12
+ test('insert author with id', async () => {
13
+ const schema = def.createModel(SeqModel)
14
+ await executeDbTest({
15
+ schema: schema,
16
+ query: GQL`
17
+ mutation {
18
+ createOrder(data: {}) {
19
+ node {
20
+ seqId
21
+ }
22
+ }
23
+ }`,
24
+ seed: [],
25
+ return: {
26
+ createOrder: {
27
+ node: {
28
+ seqId: 1,
29
+ },
30
+ },
31
+ },
32
+ })
33
+ })
34
+
@@ -32,12 +32,7 @@ test('delete post with acl', async () => {
32
32
  },
33
33
  },
34
34
  variables: {
35
- locale_variable: {
36
- definition: {
37
- type: Acl.VariableType.condition,
38
- },
39
- value: [{ in: ['cs'] }],
40
- },
35
+ locale_variable: { in: ['cs'] },
41
36
  },
42
37
  executes: [
43
38
  ...sqlTransaction([
@@ -34,12 +34,7 @@ test('set a name - allowed', async () => {
34
34
  },
35
35
  },
36
36
  variables: {
37
- name_variable: {
38
- definition: {
39
- type: Acl.VariableType.condition,
40
- },
41
- value: [{ in: ['John', 'Jack'] }],
42
- },
37
+ name_variable: { in: ['John', 'Jack'] },
43
38
  },
44
39
  executes: [
45
40
  ...sqlTransaction([
@@ -94,12 +89,7 @@ test('set a name - denied', async () => {
94
89
  },
95
90
  },
96
91
  variables: {
97
- name_variable: {
98
- definition: {
99
- type: Acl.VariableType.condition,
100
- },
101
- value: [{ in: ['John', 'Jack'] }],
102
- },
92
+ name_variable: { in: ['John', 'Jack'] },
103
93
  },
104
94
  executes: [
105
95
  ...failedTransaction([
@@ -27,12 +27,7 @@ test('insert author (with acl)', async () => {
27
27
  },
28
28
  },
29
29
  variables: {
30
- name_variable: {
31
- definition: {
32
- type: Acl.VariableType.condition,
33
- },
34
- value: [{ in: ['John', 'Jack'] }],
35
- },
30
+ name_variable: { in: ['John', 'Jack'] },
36
31
  },
37
32
  query: GQL`
38
33
  mutation {
@@ -45,12 +45,7 @@ test('querying id and title', async () => {
45
45
  schema: schema,
46
46
  permissions: permissions,
47
47
  variables: {
48
- localeVariable: {
49
- definition: {
50
- type: Acl.VariableType.condition,
51
- },
52
- value: [{ in: ['cs'] }],
53
- },
48
+ localeVariable: { in: ['cs'] },
54
49
  },
55
50
  query: GQL`
56
51
  query {
@@ -126,12 +121,7 @@ test('querying with extra where', async () => {
126
121
  schema: schema,
127
122
  permissions: permissions,
128
123
  variables: {
129
- localeVariable: {
130
- definition: {
131
- type: Acl.VariableType.condition,
132
- },
133
- value: [{ in: ['cs'] }],
134
- },
124
+ localeVariable: { in: ['cs'] },
135
125
  },
136
126
  query: GQL`
137
127
  query {
@@ -177,12 +167,7 @@ test('querying only id', async () => {
177
167
  schema: schema,
178
168
  permissions: permissions,
179
169
  variables: {
180
- localeVariable: {
181
- definition: {
182
- type: Acl.VariableType.condition,
183
- },
184
- value: [{ in: ['cs'] }],
185
- },
170
+ localeVariable: { in: ['cs'] },
186
171
  },
187
172
  query: GQL`
188
173
  query {
@@ -254,12 +239,7 @@ test('querying on nested field', async () => {
254
239
  schema: schema,
255
240
  permissions: permissions,
256
241
  variables: {
257
- localeVariable: {
258
- definition: {
259
- type: Acl.VariableType.condition,
260
- },
261
- value: [{ in: ['cs'] }],
262
- },
242
+ localeVariable: { in: ['cs'] },
263
243
  },
264
244
  query: GQL`
265
245
  query {
@@ -58,12 +58,7 @@ test('querying post + author name', async () => {
58
58
  schema: schema,
59
59
  permissions: permissions,
60
60
  variables: {
61
- countryVariable: {
62
- definition: {
63
- type: Acl.VariableType.condition,
64
- },
65
- value: [{ in: ['Czechia'] }],
66
- },
61
+ countryVariable: { in: ['Czechia'] },
67
62
  },
68
63
  query: GQL`
69
64
  query {
@@ -1,7 +1,7 @@
1
1
  import { test } from 'vitest'
2
2
  import { execute, failedTransaction, sqlTransaction } from '../../../../../src/test'
3
3
  import { SchemaBuilder } from '@contember/schema-definition'
4
- import { Acl, Model } from '@contember/schema'
4
+ import { Model } from '@contember/schema'
5
5
  import { GQL, SQL } from '../../../../../src/tags'
6
6
  import { testUuid } from '../../../../../src/testUuid'
7
7
 
@@ -35,12 +35,7 @@ test('update name', async () => {
35
35
  },
36
36
  },
37
37
  variables: {
38
- name_variable: {
39
- definition: {
40
- type: Acl.VariableType.condition,
41
- },
42
- value: [{ in: ['John', 'Jack'] }],
43
- },
38
+ name_variable: { in: ['John', 'Jack'] },
44
39
  },
45
40
  executes: [
46
41
  ...sqlTransaction([
@@ -103,12 +98,7 @@ test('update name - denied', async () => {
103
98
  },
104
99
  },
105
100
  variables: {
106
- name_variable: {
107
- definition: {
108
- type: Acl.VariableType.condition,
109
- },
110
- value: [{ in: ['John', 'Jack'] }],
111
- },
101
+ name_variable: { in: ['John', 'Jack'] },
112
102
  },
113
103
  executes: [
114
104
  ...failedTransaction([
@@ -186,18 +176,8 @@ test('update m:n', async () => {
186
176
  },
187
177
  },
188
178
  variables: {
189
- post_name_variable: {
190
- definition: {
191
- type: Acl.VariableType.condition,
192
- },
193
- value: [{ in: ['Lorem ipsum', 'Dolor sit'] }],
194
- },
195
- category_name_variable: {
196
- definition: {
197
- type: Acl.VariableType.condition,
198
- },
199
- value: [{ in: ['foo', 'bar'] }],
200
- },
179
+ post_name_variable: { in: ['Lorem ipsum', 'Dolor sit'] },
180
+ category_name_variable: { in: ['foo', 'bar'] },
201
181
  },
202
182
  query: GQL`mutation {
203
183
  updatePost(by: {id: "${testUuid(1)}"}, data: {categories: [
@@ -18,12 +18,8 @@ describe('create acl variables', () => {
18
18
  },
19
19
  },
20
20
  },
21
- }, {
22
- identityId: testUuid(1),
23
- personId: null,
24
- memberships: [{ role: 'author', variables: [{ name: 'authorID', values: [testUuid(2)] }] }],
25
- }), {
26
- author__authorID: { definition, value: [testUuid(2)] },
21
+ }, [{ role: 'author', variables: [{ name: 'authorID', condition: { in: [testUuid(2)] } }] }]), {
22
+ author__authorID: { in: [testUuid(2)] },
27
23
  })
28
24
  })
29
25
 
@@ -39,34 +35,9 @@ describe('create acl variables', () => {
39
35
  entities: {},
40
36
  },
41
37
  },
42
- }, {
43
- identityId: testUuid(1),
44
- personId: null,
45
- memberships: [{ role: 'author', variables: [] }],
46
- }), {
47
- author__authorID: { definition, value: [] },
48
- })
49
- })
50
-
51
-
52
- it('predefined', () => {
53
- const definition: Acl.PredefinedVariable = { type: Acl.VariableType.predefined, value: 'identityID' }
54
- assert.deepStrictEqual(createAclVariables({
55
- roles: {
56
- author: {
57
- stages: '*',
58
- variables: {
59
- authorIdentity: definition,
60
- },
61
- entities: {},
62
- },
63
- },
64
- }, {
65
- identityId: testUuid(1),
66
- personId: null,
67
- memberships: [{ role: 'author', variables: [] }],
68
- }), {
69
- author__authorIdentity: { definition, value: [testUuid(1)] },
38
+ }, [{ role: 'author', variables: [] }],
39
+ ), {
40
+ author__authorID: { never: true },
70
41
  })
71
42
  })
72
43
  })
@@ -11,6 +11,7 @@ const entity: Model.Entity = {
11
11
  fields: {},
12
12
  unique: {},
13
13
  eventLog: { enabled: true },
14
+ indexes: {},
14
15
  }
15
16
 
16
17
  describe('order by helper', () => {
@@ -45,12 +45,7 @@ const permissions: Acl.Permissions = {
45
45
  describe('Predicates injector', () => {
46
46
 
47
47
  const variables: Acl.VariablesMap = {
48
- localeVariable: {
49
- definition: {
50
- type: Acl.VariableType.condition,
51
- },
52
- value: [{ in: ['cs'] }],
53
- },
48
+ localeVariable: { in: ['cs'] },
54
49
  }
55
50
  it('injects predicate', () => {
56
51
  const injector = new PredicatesInjector(
@@ -19,19 +19,8 @@ describe('Variable injector', () => {
19
19
 
20
20
  const ids = ['91528a5c-839b-4114-9952-d661914a607f', '1e2f3937-a0b1-4105-8aae-6da8ac9fc146']
21
21
  const injector = new VariableInjector(schema, {
22
- site: {
23
- definition: {
24
- type: Acl.VariableType.entity,
25
- entityName: 'Site',
26
- },
27
- value: ids,
28
- },
29
- locale: {
30
- definition: {
31
- type: Acl.VariableType.condition,
32
- },
33
- value: [{ eq: 'cs' }],
34
- },
22
+ site: { in: ids },
23
+ locale: { eq: 'cs' },
35
24
  })
36
25
  const result = injector.inject(schema.entities['PostLocale'], {
37
26
  or: [