@contember/engine-content-api 1.1.0-alpha.1 → 1.1.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 (56) hide show
  1. package/dist/src/acl/Authorizator.d.ts +1 -0
  2. package/dist/src/acl/Authorizator.d.ts.map +1 -1
  3. package/dist/src/acl/Authorizator.js +5 -2
  4. package/dist/src/acl/Authorizator.js.map +1 -1
  5. package/dist/src/index.d.ts +0 -1
  6. package/dist/src/index.d.ts.map +1 -1
  7. package/dist/src/index.js +0 -1
  8. package/dist/src/index.js.map +1 -1
  9. package/dist/src/mapper/select/WhereBuilder.d.ts.map +1 -1
  10. package/dist/src/mapper/select/WhereBuilder.js +13 -14
  11. package/dist/src/mapper/select/WhereBuilder.js.map +1 -1
  12. package/dist/src/resolvers/MutationResolver.d.ts.map +1 -1
  13. package/dist/src/resolvers/MutationResolver.js +14 -4
  14. package/dist/src/resolvers/MutationResolver.js.map +1 -1
  15. package/dist/src/schema/entities/FieldTypeVisitor.d.ts.map +1 -1
  16. package/dist/src/schema/entities/FieldTypeVisitor.js +10 -2
  17. package/dist/src/schema/entities/FieldTypeVisitor.js.map +1 -1
  18. package/dist/src/tsconfig.tsbuildinfo +1 -1
  19. package/dist/tests/cases/bugs/bug102.test.js +4 -4
  20. package/dist/tests/cases/bugs/bug102.test.js.map +1 -1
  21. package/dist/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.js +5 -5
  22. package/dist/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.js.map +1 -1
  23. package/dist/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.js +3 -3
  24. package/dist/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.js.map +1 -1
  25. package/dist/tests/cases/integration/graphQlRequests/query/unique/oneHasManyUnique.test.js +1 -1
  26. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js +23 -1
  27. package/dist/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.js.map +1 -1
  28. package/dist/tests/cases/integration/graphQlSchema/schema-acl-predicate2.gql +110 -0
  29. package/dist/tests/tsconfig.tsbuildinfo +1 -1
  30. package/package.json +11 -11
  31. package/src/acl/Authorizator.ts +5 -1
  32. package/src/index.ts +0 -1
  33. package/src/mapper/select/WhereBuilder.ts +23 -27
  34. package/src/resolvers/MutationResolver.ts +14 -4
  35. package/src/schema/entities/FieldTypeVisitor.ts +10 -2
  36. package/tests/cases/bugs/bug102.test.ts +4 -4
  37. package/tests/cases/integration/graphQlRequests/query/filter/manyHasManyOwnerRelation.test.ts +5 -5
  38. package/tests/cases/integration/graphQlRequests/query/filter/oneHasManyRelation.test.ts +3 -3
  39. package/tests/cases/integration/graphQlRequests/query/unique/oneHasManyUnique.test.ts +1 -1
  40. package/tests/cases/integration/graphQlSchema/graphQlSchemaBuilder.test.ts +28 -1
  41. package/tests/cases/integration/graphQlSchema/schema-acl-predicate2.gql +110 -0
  42. package/dist/src/bridges/index.d.ts +0 -2
  43. package/dist/src/bridges/index.d.ts.map +0 -1
  44. package/dist/src/bridges/index.js +0 -14
  45. package/dist/src/bridges/index.js.map +0 -1
  46. package/dist/src/bridges/system/EntitiesSelector.d.ts +0 -36
  47. package/dist/src/bridges/system/EntitiesSelector.d.ts.map +0 -1
  48. package/dist/src/bridges/system/EntitiesSelector.js +0 -38
  49. package/dist/src/bridges/system/EntitiesSelector.js.map +0 -1
  50. package/dist/src/bridges/system/index.d.ts +0 -2
  51. package/dist/src/bridges/system/index.d.ts.map +0 -1
  52. package/dist/src/bridges/system/index.js +0 -14
  53. package/dist/src/bridges/system/index.js.map +0 -1
  54. package/src/bridges/index.ts +0 -1
  55. package/src/bridges/system/EntitiesSelector.ts +0 -86
  56. package/src/bridges/system/index.ts +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contember/engine-content-api",
3
- "version": "1.1.0-alpha.1",
3
+ "version": "1.1.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": "uvu dist/tests/cases/ \\.js$"
11
11
  },
12
12
  "dependencies": {
13
- "@contember/database": "^1.1.0-alpha.1",
14
- "@contember/dic": "^1.1.0-alpha.1",
15
- "@contember/engine-common": "^1.1.0-alpha.1",
16
- "@contember/graphql-utils": "^1.1.0-alpha.1",
17
- "@contember/schema": "^1.1.0-alpha.1",
18
- "@contember/schema-utils": "^1.1.0-alpha.1",
13
+ "@contember/database": "^1.1.0-alpha.4",
14
+ "@contember/dic": "^1.1.0-alpha.4",
15
+ "@contember/engine-common": "^1.1.0-alpha.4",
16
+ "@contember/graphql-utils": "^1.1.0-alpha.4",
17
+ "@contember/schema": "^1.1.0-alpha.4",
18
+ "@contember/schema-utils": "^1.1.0-alpha.4",
19
19
  "@graphql-tools/schema": "^7.1.5",
20
20
  "graphql-tag": "^2.12.5"
21
21
  },
22
22
  "devDependencies": {
23
- "@contember/database-tester": "^1.1.0-alpha.1",
24
- "@contember/engine-api-tester": "^1.1.0-alpha.1",
25
- "@contember/schema-definition": "^1.1.0-alpha.1",
23
+ "@contember/database-tester": "^1.1.0-alpha.4",
24
+ "@contember/engine-api-tester": "^1.1.0-alpha.4",
25
+ "@contember/schema-definition": "^1.1.0-alpha.4",
26
26
  "@graphql-codegen/cli": "^1.15.2",
27
27
  "@graphql-codegen/typescript": "^1.15.2",
28
28
  "@graphql-codegen/typescript-operations": "^1.15.2",
@@ -30,7 +30,7 @@
30
30
  "@types/node": "^17.0.5",
31
31
  "graphql": "^15.4.0",
32
32
  "pg": "^8.5.0",
33
- "uvu": "^0.5.1"
33
+ "uvu": "^0.5.3"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "graphql": ">= 14.6.0",
@@ -23,8 +23,12 @@ export class Authorizator {
23
23
  return Object.values(fieldPermissions).filter(it => !!it).length > 0 ? 'yes' : 'no'
24
24
  }
25
25
 
26
+ getFieldPredicate(operation: Acl.Operation.create | Acl.Operation.read | Acl.Operation.update, entity: string, field: string): Acl.Predicate {
27
+ return this.permissions[entity]?.operations[operation]?.[field] ?? false
28
+ }
29
+
26
30
  getFieldPermissions(operation: Acl.Operation.create | Acl.Operation.read | Acl.Operation.update, entity: string, field: string): AuthorizationResult {
27
- const fieldPermissions = this.permissions[entity]?.operations[operation]?.[field]
31
+ const fieldPermissions = this.getFieldPredicate(operation, entity, field)
28
32
  if (!fieldPermissions) {
29
33
  return 'no'
30
34
  }
package/src/index.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  export * from './acl'
2
- export * from './bridges'
3
2
  export * from './resolvers'
4
3
  export * from './introspection'
5
4
  export * from './schema'
@@ -4,7 +4,7 @@ import { Input, Model } from '@contember/schema'
4
4
  import { Path, PathFactory } from './Path'
5
5
  import { JoinBuilder } from './JoinBuilder'
6
6
  import { ConditionBuilder } from './ConditionBuilder'
7
- import { ConditionBuilder as SqlConditionBuilder, Operator, SelectBuilder } from '@contember/database'
7
+ import { ConditionBuilder as SqlConditionBuilder, Operator, QueryBuilder, SelectBuilder } from '@contember/database'
8
8
 
9
9
  export class WhereBuilder {
10
10
  constructor(
@@ -125,10 +125,9 @@ export class WhereBuilder {
125
125
  }
126
126
  const relationWhere = where[fieldName] as Input.Where
127
127
 
128
- return conditionBuilder.in(
129
- [tableName, entity.primaryColumn],
128
+ return conditionBuilder.exists(
130
129
  this.createManyHasManySubquery(
131
- SelectBuilder.create(),
130
+ [tableName, entity.primaryColumn],
132
131
  relationWhere,
133
132
  targetEntity,
134
133
  targetRelation.joiningTable,
@@ -143,10 +142,9 @@ export class WhereBuilder {
143
142
 
144
143
  const relationWhere = where[fieldName] as Input.Where
145
144
 
146
- return conditionBuilder.in(
147
- [tableName, entity.primaryColumn],
145
+ return conditionBuilder.exists(
148
146
  this.createManyHasManySubquery(
149
- SelectBuilder.create(),
147
+ [tableName, entity.primaryColumn],
150
148
  relationWhere,
151
149
  targetEntity,
152
150
  relation.joiningTable,
@@ -161,15 +159,14 @@ export class WhereBuilder {
161
159
 
162
160
  const relationWhere = where[fieldName] as Input.Where
163
161
 
164
- return conditionBuilder.in(
165
- [tableName, entity.primaryColumn],
162
+ return conditionBuilder.exists(
166
163
  this.build(
167
164
  SelectBuilder.create()
168
- .distinct()
169
- .select(['root_', targetRelation.joiningColumn.columnName])
170
- .from(targetEntity.tableName, 'root_'),
165
+ .select(it => it.raw('1'))
166
+ .from(targetEntity.tableName, 'sub_')
167
+ .where(it => it.columnsEq([tableName, entity.primaryColumn], ['sub_', targetRelation.joiningColumn.columnName])),
171
168
  targetEntity,
172
- this.pathFactory.create([]),
169
+ this.pathFactory.create([], 'sub_'),
173
170
  relationWhere,
174
171
  true,
175
172
  ),
@@ -181,36 +178,35 @@ export class WhereBuilder {
181
178
  }
182
179
 
183
180
  private createManyHasManySubquery(
184
- qb: SelectBuilder<SelectBuilder.Result>,
181
+ outerColumn: QueryBuilder.ColumnIdentifier,
185
182
  relationWhere: Input.Where,
186
183
  targetEntity: Model.Entity,
187
184
  joiningTable: Model.JoiningTable,
188
185
  fromSide: 'owning' | 'inverse',
189
186
  ) {
190
- let augmentedBuilder: SelectBuilder<SelectBuilder.Result> = qb
191
- const fromColumn =
192
- fromSide === 'owning' ? joiningTable.joiningColumn.columnName : joiningTable.inverseJoiningColumn.columnName
193
- const toColumn =
194
- fromSide === 'owning' ? joiningTable.inverseJoiningColumn.columnName : joiningTable.joiningColumn.columnName
195
- augmentedBuilder = augmentedBuilder
187
+ const fromColumn = fromSide === 'owning' ? joiningTable.joiningColumn.columnName : joiningTable.inverseJoiningColumn.columnName
188
+ const toColumn = fromSide === 'owning' ? joiningTable.inverseJoiningColumn.columnName : joiningTable.joiningColumn.columnName
189
+ const qb = SelectBuilder.create<SelectBuilder.Result>()
196
190
  .from(joiningTable.tableName, 'junction_')
197
- .distinct()
198
- .select(['junction_', fromColumn])
191
+ .select(it => it.raw('1'))
192
+ .where(it => it.columnsEq(outerColumn, ['junction_', fromColumn]))
193
+
199
194
  const primaryCondition = this.transformWhereToPrimaryCondition(relationWhere, targetEntity.primary)
200
195
  if (primaryCondition !== null) {
201
- return augmentedBuilder.where(condition =>
196
+
197
+ return qb.where(condition =>
202
198
  this.conditionBuilder.build(condition, 'junction_', toColumn, primaryCondition),
203
199
  )
204
200
  }
205
201
 
206
- augmentedBuilder = augmentedBuilder.join(targetEntity.tableName, 'root_', clause =>
207
- clause.compareColumns(['junction_', toColumn], Operator.eq, ['root_', targetEntity.primary]),
202
+ const qbJoined = qb.join(targetEntity.tableName, 'sub_', clause =>
203
+ clause.compareColumns(['junction_', toColumn], Operator.eq, ['sub_', targetEntity.primary]),
208
204
  )
209
205
  return this.buildAdvanced(
210
206
  targetEntity,
211
- this.pathFactory.create([]),
207
+ this.pathFactory.create([], 'sub_'),
212
208
  relationWhere,
213
- cb => augmentedBuilder.where(clause => cb(clause)),
209
+ cb => qbJoined.where(clause => cb(clause)),
214
210
  true,
215
211
  )
216
212
  }
@@ -66,12 +66,12 @@ export class MutationResolver {
66
66
  const validationResult: Record<string, Result.MutationFieldResult> = {}
67
67
  const validationErrors: Result.ValidationError[] = []
68
68
  for (const field of queryAst.fields) {
69
+ if (field.name === 'query' || field.name === '__typename') {
70
+ continue
71
+ }
69
72
  if (!(field instanceof ObjectNode)) {
70
73
  throw new ImplementationException()
71
74
  }
72
- if (field.name === 'query') {
73
- continue
74
- }
75
75
  const fieldConfig = fields[field.name]
76
76
  if (!fieldConfig) {
77
77
  throw new ImplementationException()
@@ -110,6 +110,7 @@ export class MutationResolver {
110
110
  }
111
111
  if (validationErrors.length) {
112
112
  return {
113
+ __typename: 'MutationTransaction',
113
114
  ok: false,
114
115
  errorMessage: this.stringifyValidationErrors(validationErrors),
115
116
  errors: [],
@@ -123,6 +124,9 @@ export class MutationResolver {
123
124
 
124
125
  const trxResult: Record<string, any> = {}
125
126
  for (const field of queryAst.fields) {
127
+ if (field.name === '__typename') {
128
+ continue
129
+ }
126
130
  if (!(field instanceof ObjectNode)) {
127
131
  throw new ImplementationException()
128
132
  }
@@ -198,7 +202,13 @@ export class MutationResolver {
198
202
  }
199
203
  }
200
204
 
201
- return { ok: true, errors: [], validation: { valid: true, errors: [] }, ...trxResult }
205
+ return {
206
+ __typename: 'MutationTransaction',
207
+ ok: true,
208
+ errors: [],
209
+ validation: { valid: true, errors: [] },
210
+ ...trxResult,
211
+ }
202
212
  })
203
213
  }
204
214
 
@@ -3,6 +3,7 @@ import { Acl, Model } from '@contember/schema'
3
3
  import { ColumnTypeResolver } from '../ColumnTypeResolver'
4
4
  import { EntityTypeProvider } from '../EntityTypeProvider'
5
5
  import { Authorizator } from '../../acl'
6
+ import { ImplementationException } from '../../exception'
6
7
 
7
8
  export class FieldTypeVisitor implements Model.ColumnVisitor<GraphQLOutputType>, Model.RelationByGenericTypeVisitor<GraphQLOutputType> {
8
9
  constructor(
@@ -14,8 +15,15 @@ export class FieldTypeVisitor implements Model.ColumnVisitor<GraphQLOutputType>,
14
15
 
15
16
  public visitColumn(entity: Model.Entity, column: Model.AnyColumn): GraphQLOutputType {
16
17
  const basicType = this.columnTypeResolver.getType(column)
17
- const permissions = this.authorizator.getFieldPermissions(Acl.Operation.read, entity.name, column.name)
18
- return column.nullable || permissions === 'maybe' ? basicType : new GraphQLNonNull(basicType)
18
+ const fieldPredicate = this.authorizator.getFieldPredicate(Acl.Operation.read, entity.name, column.name)
19
+ const idPredicate = this.authorizator.getFieldPredicate(Acl.Operation.read, entity.name, entity.primary)
20
+ if (!fieldPredicate || !idPredicate) {
21
+ throw new ImplementationException()
22
+ }
23
+ if (!column.nullable && (fieldPredicate === true || fieldPredicate === idPredicate)) {
24
+ return new GraphQLNonNull(basicType)
25
+ }
26
+ return basicType
19
27
  }
20
28
 
21
29
  public visitHasMany(entity: Model.Entity, relation: Model.Relation): GraphQLOutputType {
@@ -50,10 +50,10 @@ test('Filter by has many with additional join', async () => {
50
50
  sql: SQL`
51
51
  select "root_"."id" as "root_id", "root_"."short_name" as "root_shortName", "root_"."id" as "root_id"
52
52
  from "public"."person" as "root_"
53
- where "root_"."id" in (select distinct "root_"."person_id"
54
- from "public"."person_locale" as "root_"
55
- left join "public"."language" as "root_locale" on "root_"."locale_id" = "root_locale"."id"
56
- where "root_locale"."slug" = ? and not("root_"."url_slug" is null))`,
53
+ where exists (select 1
54
+ from "public"."person_locale" as "sub_"
55
+ left join "public"."language" as "sub_locale" on "sub_"."locale_id" = "sub_locale"."id"
56
+ where "root_"."id" = "sub_"."person_id" and "sub_locale"."slug" = ? and not("sub_"."url_slug" is null))`,
57
57
  response: { rows: [{ root_id: testUuid(1), root_shortName: 'John' }] },
58
58
  parameters: ['cs'],
59
59
  },
@@ -24,9 +24,9 @@ test('Post by category name (where many has many owning)', async () => {
24
24
  {
25
25
  sql: SQL`select "root_"."id" as "root_id"
26
26
  from "public"."post" as "root_"
27
- where "root_"."id" in (select distinct "junction_"."post_id"
28
- from "public"."post_categories" as "junction_" inner join "public"."category" as "root_" on "junction_"."category_id" = "root_"."id"
29
- where "root_"."name" = ?)`,
27
+ where exists (select 1
28
+ from "public"."post_categories" as "junction_" inner join "public"."category" as "sub_" on "junction_"."category_id" = "sub_"."id"
29
+ where "root_"."id" = "junction_"."post_id" and "sub_"."name" = ?)`,
30
30
  parameters: ['Stuff'],
31
31
  response: {
32
32
  rows: [
@@ -74,9 +74,9 @@ test('Post by category ids (where many has many owning)', async () => {
74
74
  {
75
75
  sql: SQL`select "root_"."id" as "root_id"
76
76
  from "public"."post" as "root_"
77
- where "root_"."id" in (select distinct "junction_"."post_id"
77
+ where exists (select 1
78
78
  from "public"."post_categories" as "junction_"
79
- where "junction_"."category_id" in (?, ?))`,
79
+ where "root_"."id" = "junction_"."post_id" and "junction_"."category_id" in (?, ?))`,
80
80
  parameters: [testUuid(10), testUuid(11)],
81
81
  response: {
82
82
  rows: [
@@ -25,9 +25,9 @@ test('Author by post title (where one has many)', async () => {
25
25
  {
26
26
  sql: SQL`select "root_"."id" as "root_id"
27
27
  from "public"."author" as "root_"
28
- where "root_"."id" in (select distinct "root_"."author_id"
29
- from "public"."post" as "root_"
30
- where "root_"."title" = ?)`,
28
+ where exists (select 1
29
+ from "public"."post" as "sub_"
30
+ where "root_"."id" = "sub_"."author_id" and "sub_"."title" = ?)`,
31
31
  parameters: ['Hello'],
32
32
  response: {
33
33
  rows: [
@@ -30,7 +30,7 @@ test('Post by post locale (one-has-many unique)', async () => {
30
30
  {
31
31
  sql: SQL`SELECT "root_"."id" AS "root_id"
32
32
  FROM "public"."post" AS "root_"
33
- WHERE "root_"."id" IN (SELECT distinct "root_"."post_id" FROM "public"."post_locale" AS "root_" WHERE "root_"."id" = ?)`,
33
+ WHERE EXISTS (SELECT 1 FROM "public"."post_locale" AS "sub_" WHERE "root_"."id" = "sub_"."post_id" AND "sub_"."id" = ?)`,
34
34
  parameters: [testUuid(1)],
35
35
  response: { rows: [{ root_id: testUuid(2) }] },
36
36
  },
@@ -112,7 +112,7 @@ graphqlSchemaBuilderTest('restricted access to fields by permissions', async ()
112
112
  })
113
113
 
114
114
 
115
- graphqlSchemaBuilderTest('conditionally restricted read', async () => {
115
+ graphqlSchemaBuilderTest('conditionally restricted read of some fields', async () => {
116
116
  await testSchema({
117
117
  schema: builder =>
118
118
  builder.entity('Test', e =>
@@ -138,6 +138,33 @@ graphqlSchemaBuilderTest('conditionally restricted read', async () => {
138
138
  })
139
139
  })
140
140
 
141
+
142
+ graphqlSchemaBuilderTest('conditionally restricted read of whole row', async () => {
143
+ await testSchema({
144
+ schema: builder =>
145
+ builder.entity('Test', e =>
146
+ e
147
+ .column('a', c => c.type(Model.ColumnType.String).notNull()),
148
+ ),
149
+ permissions: () => ({
150
+ Test: {
151
+ predicates: {
152
+ testPredicate: {
153
+ a: { eq: 'Foo' },
154
+ },
155
+ },
156
+ operations: {
157
+ read: {
158
+ id: 'testPredicate',
159
+ a: 'testPredicate',
160
+ },
161
+ },
162
+ },
163
+ }),
164
+ graphQlSchemaFile: 'schema-acl-predicate2.gql',
165
+ })
166
+ })
167
+
141
168
  const oneHasManySchema = (builder: SchemaBuilder) =>
142
169
  builder.entity('Root', e =>
143
170
  e
@@ -0,0 +1,110 @@
1
+ type Query {
2
+ getTest(by: TestUniqueWhere!, filter: TestWhere): Test
3
+ listTest(filter: TestWhere, orderBy: [TestOrderBy!], offset: Int, limit: Int): [Test!]!
4
+ paginateTest(filter: TestWhere, orderBy: [TestOrderBy!], skip: Int, first: Int): TestConnection!
5
+ transaction: QueryTransaction
6
+ _info: Info
7
+ }
8
+
9
+ type Test {
10
+ _meta: TestMeta
11
+ id: UUID!
12
+ a: String!
13
+ }
14
+
15
+ type TestMeta {
16
+ id: FieldMeta
17
+ a: FieldMeta
18
+ }
19
+
20
+ type FieldMeta {
21
+ readable: Boolean
22
+ updatable: Boolean
23
+ }
24
+
25
+ scalar UUID
26
+
27
+ input TestUniqueWhere {
28
+ id: UUID
29
+ }
30
+
31
+ input TestWhere {
32
+ id: UUIDCondition
33
+ a: StringCondition
34
+ and: [TestWhere]
35
+ or: [TestWhere]
36
+ not: TestWhere
37
+ }
38
+
39
+ input UUIDCondition {
40
+ and: [UUIDCondition!]
41
+ or: [UUIDCondition!]
42
+ not: UUIDCondition
43
+ null: Boolean
44
+ isNull: Boolean
45
+ eq: UUID
46
+ notEq: UUID
47
+ in: [UUID!]
48
+ notIn: [UUID!]
49
+ lt: UUID
50
+ lte: UUID
51
+ gt: UUID
52
+ gte: UUID
53
+ }
54
+
55
+ input StringCondition {
56
+ and: [StringCondition!]
57
+ or: [StringCondition!]
58
+ not: StringCondition
59
+ null: Boolean
60
+ isNull: Boolean
61
+ eq: String
62
+ notEq: String
63
+ in: [String!]
64
+ notIn: [String!]
65
+ lt: String
66
+ lte: String
67
+ gt: String
68
+ gte: String
69
+ contains: String
70
+ startsWith: String
71
+ endsWith: String
72
+ containsCI: String
73
+ startsWithCI: String
74
+ endsWithCI: String
75
+ }
76
+
77
+ input TestOrderBy {
78
+ _random: Boolean
79
+ _randomSeeded: Int
80
+ id: OrderDirection
81
+ a: OrderDirection
82
+ }
83
+
84
+ enum OrderDirection {
85
+ asc
86
+ desc
87
+ }
88
+
89
+ type TestConnection {
90
+ pageInfo: PageInfo!
91
+ edges: [TestEdge!]!
92
+ }
93
+
94
+ type PageInfo {
95
+ totalCount: Int!
96
+ }
97
+
98
+ type TestEdge {
99
+ node: Test!
100
+ }
101
+
102
+ type QueryTransaction {
103
+ getTest(by: TestUniqueWhere!, filter: TestWhere): Test
104
+ listTest(filter: TestWhere, orderBy: [TestOrderBy!], offset: Int, limit: Int): [Test!]!
105
+ paginateTest(filter: TestWhere, orderBy: [TestOrderBy!], skip: Int, first: Int): TestConnection!
106
+ }
107
+
108
+ type Info {
109
+ description: String
110
+ }
@@ -1,2 +0,0 @@
1
- export * from './system';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/bridges/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA"}
@@ -1,14 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
- };
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- __exportStar(require("./system"), exports);
14
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/bridges/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAwB"}
@@ -1,36 +0,0 @@
1
- import { Client } from '@contember/database';
2
- import { Acl, Schema, Input } from '@contember/schema';
3
- import { Mapper } from '../../mapper';
4
- import { PermissionsByIdentityFactory } from '../../acl';
5
- export declare type EntitiesRelationsInput = readonly {
6
- name: string;
7
- relations: EntitiesRelationsInput;
8
- }[];
9
- export interface EntitiesSelectorContext {
10
- db: Client;
11
- schema: Schema;
12
- identityVariables: Acl.VariablesMap;
13
- roles: string[];
14
- }
15
- export interface EntitiesSelectorInput {
16
- entity: string;
17
- filter: Input.Where;
18
- relations: EntitiesRelationsInput;
19
- }
20
- export declare class EntitiesSelector {
21
- private readonly mapperFactory;
22
- private readonly permissionsByIdentityFactory;
23
- constructor(mapperFactory: EntitiesSelectorMapperFactory, permissionsByIdentityFactory: PermissionsByIdentityFactory);
24
- getEntities(context: EntitiesSelectorContext, input: EntitiesSelectorInput): Promise<EntitiesResult[]>;
25
- private createObjectNode;
26
- private createRelations;
27
- }
28
- interface EntitiesResultRelations {
29
- [relation: string]: EntitiesResult | EntitiesResult[] | null;
30
- }
31
- export declare type EntitiesResult = {
32
- id: string;
33
- } & EntitiesResultRelations;
34
- export declare type EntitiesSelectorMapperFactory = (db: Client, schema: Schema, identityVariables: Acl.VariablesMap, permissions: Acl.Permissions) => Mapper;
35
- export {};
36
- //# sourceMappingURL=EntitiesSelector.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EntitiesSelector.d.ts","sourceRoot":"","sources":["../../../../src/bridges/system/EntitiesSelector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,EAAE,GAAG,EAAS,MAAM,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AAGrC,OAAO,EAAE,4BAA4B,EAAE,MAAM,WAAW,CAAA;AAExD,oBAAY,sBAAsB,GAAG,SAAS;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,sBAAsB,CAAA;CACjC,EAAE,CAAA;AAEH,MAAM,WAAW,uBAAuB;IACvC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,iBAAiB,EAAE,GAAG,CAAC,YAAY,CAAA;IACnC,KAAK,EAAE,MAAM,EAAE,CAAA;CACf;AAED,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,KAAK,CAAC,KAAK,CAAA;IACnB,SAAS,EAAE,sBAAsB,CAAA;CACjC;AAED,qBAAa,gBAAgB;IAE3B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,4BAA4B;gBAD5B,aAAa,EAAE,6BAA6B,EAC5C,4BAA4B,EAAE,4BAA4B;IAGtE,WAAW,CAAC,OAAO,EAAE,uBAAuB,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAY5G,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,eAAe;CAuBvB;AAED,UAAU,uBAAuB;IAChC,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,GAAG,cAAc,EAAE,GAAG,IAAI,CAAA;CAC5D;AAED,oBAAY,cAAc,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAA;CACV,GAAG,uBAAuB,CAAA;AAE3B,oBAAY,6BAA6B,GAAG,CAC3C,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,GAAG,CAAC,YAAY,EACnC,WAAW,EAAE,GAAG,CAAC,WAAW,KACxB,MAAM,CAAA"}
@@ -1,38 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EntitiesSelector = void 0;
4
- const schema_utils_1 = require("@contember/schema-utils");
5
- const inputProcessing_1 = require("../../inputProcessing");
6
- class EntitiesSelector {
7
- constructor(mapperFactory, permissionsByIdentityFactory) {
8
- this.mapperFactory = mapperFactory;
9
- this.permissionsByIdentityFactory = permissionsByIdentityFactory;
10
- }
11
- async getEntities(context, input) {
12
- const { permissions } = this.permissionsByIdentityFactory.createPermissions(context.schema, {
13
- projectRoles: context.roles,
14
- });
15
- const mapper = this.mapperFactory(context.db, context.schema, context.identityVariables, permissions);
16
- const entity = (0, schema_utils_1.getEntity)(context.schema.model, input.entity);
17
- const node = this.createObjectNode(context.schema, entity, input.relations).withArg('filter', input.filter);
18
- const result = await mapper.select(entity, node);
19
- return result;
20
- }
21
- createObjectNode(schema, entity, relations) {
22
- return this.createRelations(schema, entity, new inputProcessing_1.ObjectNode(entity.name, entity.name, [], {}, {}, []), relations);
23
- }
24
- createRelations(schema, entity, node, relations) {
25
- return relations.reduce((node, relation) => {
26
- const fieldName = relation.name;
27
- const newField = (0, schema_utils_1.acceptFieldVisitor)(schema.model, entity, fieldName, {
28
- visitColumn: () => {
29
- throw new Error(`${fieldName} is not a relation`);
30
- },
31
- visitRelation: ({}, {}, targetEntity) => this.createRelations(schema, targetEntity, new inputProcessing_1.ObjectNode(fieldName, fieldName, [], {}, {}, []), relation.relations),
32
- });
33
- return node.withField(newField);
34
- }, node.withField(new inputProcessing_1.FieldNode(entity.primary, 'id', {})));
35
- }
36
- }
37
- exports.EntitiesSelector = EntitiesSelector;
38
- //# sourceMappingURL=EntitiesSelector.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"EntitiesSelector.js","sourceRoot":"","sources":["../../../../src/bridges/system/EntitiesSelector.ts"],"names":[],"mappings":";;;AAGA,0DAAuE;AACvE,2DAA6D;AAqB7D,MAAa,gBAAgB;IAC5B,YACkB,aAA4C,EAC5C,4BAA0D;QAD1D,kBAAa,GAAb,aAAa,CAA+B;QAC5C,iCAA4B,GAA5B,4BAA4B,CAA8B;IACzE,CAAC;IAEJ,KAAK,CAAC,WAAW,CAAC,OAAgC,EAAE,KAA4B;QAC/E,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAC,4BAA4B,CAAC,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE;YAC3F,YAAY,EAAE,OAAO,CAAC,KAAK;SAC3B,CAAC,CAAA;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAA;QACrG,MAAM,MAAM,GAAG,IAAA,wBAAS,EAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QAC5D,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAA;QAE3G,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAChD,OAAO,MAAqC,CAAA;IAC7C,CAAC;IAEO,gBAAgB,CAAC,MAAc,EAAE,MAAoB,EAAE,SAAiC;QAC/F,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,4BAAU,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,SAAS,CAAC,CAAA;IACjH,CAAC;IAEO,eAAe,CACtB,MAAc,EACd,MAAoB,EACpB,IAAgB,EAChB,SAAiC;QAEjC,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,EAAE;YAC1C,MAAM,SAAS,GAAG,QAAQ,CAAC,IAAI,CAAA;YAC/B,MAAM,QAAQ,GAAG,IAAA,iCAAkB,EAAa,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE;gBAChF,WAAW,EAAE,GAAG,EAAE;oBACjB,MAAM,IAAI,KAAK,CAAC,GAAG,SAAS,oBAAoB,CAAC,CAAA;gBAClD,CAAC;gBACD,aAAa,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,CACvC,IAAI,CAAC,eAAe,CACnB,MAAM,EACN,YAAY,EACZ,IAAI,4BAAU,CAAC,SAAS,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EACpD,QAAQ,CAAC,SAAS,CAClB;aACF,CAAC,CAAA;YACF,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAA;QAChC,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,2BAAS,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;IAC5D,CAAC;CACD;AA7CD,4CA6CC"}
@@ -1,2 +0,0 @@
1
- export * from './EntitiesSelector';
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bridges/system/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA"}
@@ -1,14 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
- }) : (function(o, m, k, k2) {
6
- if (k2 === undefined) k2 = k;
7
- o[k2] = m[k];
8
- }));
9
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
- };
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- __exportStar(require("./EntitiesSelector"), exports);
14
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/bridges/system/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qDAAkC"}
@@ -1 +0,0 @@
1
- export * from './system'