@contember/client-content 1.3.0-alpha.25 → 1.3.0-alpha.27

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 (37) hide show
  1. package/dist/development/ContentQueryBuilder.cjs +64 -36
  2. package/dist/development/ContentQueryBuilder.cjs.map +1 -1
  3. package/dist/development/ContentQueryBuilder.js +64 -36
  4. package/dist/development/ContentQueryBuilder.js.map +1 -1
  5. package/dist/development/nodes/ContentEntitySelection.cjs +36 -5
  6. package/dist/development/nodes/ContentEntitySelection.cjs.map +1 -1
  7. package/dist/development/nodes/ContentEntitySelection.js +36 -5
  8. package/dist/development/nodes/ContentEntitySelection.js.map +1 -1
  9. package/dist/development/utils/createTypedArgs.cjs +3 -0
  10. package/dist/development/utils/createTypedArgs.cjs.map +1 -1
  11. package/dist/development/utils/createTypedArgs.js +3 -0
  12. package/dist/development/utils/createTypedArgs.js.map +1 -1
  13. package/dist/production/ContentQueryBuilder.cjs +64 -36
  14. package/dist/production/ContentQueryBuilder.cjs.map +1 -1
  15. package/dist/production/ContentQueryBuilder.js +64 -36
  16. package/dist/production/ContentQueryBuilder.js.map +1 -1
  17. package/dist/production/nodes/ContentEntitySelection.cjs +36 -5
  18. package/dist/production/nodes/ContentEntitySelection.cjs.map +1 -1
  19. package/dist/production/nodes/ContentEntitySelection.js +36 -5
  20. package/dist/production/nodes/ContentEntitySelection.js.map +1 -1
  21. package/dist/production/utils/createTypedArgs.cjs +3 -0
  22. package/dist/production/utils/createTypedArgs.cjs.map +1 -1
  23. package/dist/production/utils/createTypedArgs.js +3 -0
  24. package/dist/production/utils/createTypedArgs.js.map +1 -1
  25. package/dist/types/ContentQueryBuilder.d.ts +3 -1
  26. package/dist/types/ContentQueryBuilder.d.ts.map +1 -1
  27. package/dist/types/nodes/ContentEntitySelection.d.ts +10 -1
  28. package/dist/types/nodes/ContentEntitySelection.d.ts.map +1 -1
  29. package/dist/types/nodes/TypedEntitySelection.d.ts +1 -0
  30. package/dist/types/nodes/TypedEntitySelection.d.ts.map +1 -1
  31. package/dist/types/tsconfig.tsbuildinfo +1 -1
  32. package/dist/types/utils/createTypedArgs.d.ts.map +1 -1
  33. package/package.json +5 -5
  34. package/src/ContentQueryBuilder.ts +74 -51
  35. package/src/nodes/ContentEntitySelection.ts +43 -4
  36. package/src/nodes/TypedEntitySelection.ts +3 -0
  37. package/src/utils/createTypedArgs.ts +3 -0
@@ -1,16 +1,9 @@
1
1
  import { ContentClientInput, MutationResult, SchemaNames, TransactionResult } from './types'
2
- import {
3
- ContentEntitySelection,
4
- ContentEntitySelectionCallback,
5
- ContentEntitySelectionContext,
6
- ContentMutation,
7
- ContentOperation,
8
- ContentQuery,
9
- } from './nodes'
2
+ import { ContentEntitySelection, ContentEntitySelectionCallback, ContentEntitySelectionContext, ContentMutation, ContentOperation, ContentQuery } from './nodes'
10
3
  import { createListArgs } from './utils/createListArgs'
11
4
  import { createTypedArgs } from './utils/createTypedArgs'
12
5
  import { Input } from '@contember/schema'
13
- import { GraphQlField, GraphQlFragmentSpread, GraphQlSelectionSet } from '@contember/graphql-builder'
6
+ import { GraphQlField, GraphQlFieldTypedArgs, GraphQlFragmentSpread, GraphQlSelectionSet } from '@contember/graphql-builder'
14
7
  import { createMutationOperationSet } from './utils/createMutationOperationSet'
15
8
 
16
9
  export type EntitySelectionOrCallback =
@@ -22,6 +15,8 @@ export type MutationTransactionOptions = {
22
15
  deferUniqueConstraints?: boolean
23
16
  }
24
17
 
18
+ type MutationOperation = 'create' | 'update' | 'delete' | 'upsert' | 'transaction';
19
+
25
20
  export class ContentQueryBuilder {
26
21
  constructor(private readonly schema: SchemaNames) {
27
22
  }
@@ -61,9 +56,17 @@ export class ContentQueryBuilder {
61
56
  const context = this.createContext(name)
62
57
  const fieldName = `list${name}`
63
58
  const typedArgs = createListArgs(context.entity, args)
64
- const selectionSet = this.resolveSelectionSet(fields, context)
65
-
66
- return new ContentOperation('query', fieldName, typedArgs, selectionSet)
59
+ const selection = this.resolveSelection(fields, context)
60
+
61
+ return new ContentOperation('query', fieldName, typedArgs, selection.selectionSet, it => {
62
+ const transformFn = selection.transformFn
63
+ if (transformFn) {
64
+ return it.map((el: any) => transformFn(el, {
65
+ rootValue: it,
66
+ }))
67
+ }
68
+ return it
69
+ })
67
70
  }
68
71
 
69
72
 
@@ -74,68 +77,83 @@ export class ContentQueryBuilder {
74
77
  by: `${context.entity.name}UniqueWhere!`,
75
78
  filter: `${context.entity.name}Where`,
76
79
  })
77
- const selectionSet = this.resolveSelectionSet(fields, context)
80
+ const selection = this.resolveSelection(fields, context)
78
81
 
79
- return new ContentOperation('query', fieldName, typedArgs, selectionSet)
82
+ return new ContentOperation('query', fieldName, typedArgs, selection.selectionSet, it => {
83
+ if (it && selection.transformFn) {
84
+ return selection.transformFn(it, {
85
+ rootValue: it,
86
+ })
87
+ }
88
+ return it
89
+ })
80
90
  }
81
91
 
82
92
 
83
93
  public create(name: string, args: Input.CreateInput, fields?: EntitySelectionOrCallback): ContentMutation<MutationResult> {
84
94
 
85
- const context = this.createContext(name)
86
- const fieldName = `create${name}`
95
+ const entity = this.getEntity(name)
87
96
  const typedArgs = createTypedArgs(args, {
88
- data: `${context.entity.name}CreateInput!`,
97
+ data: `${entity.name}CreateInput!`,
89
98
  })
90
- const selectionSet = this.createMutationSelection('create', fields ? this.resolveSelectionSet(fields, context) : undefined)
91
99
 
92
- return new ContentOperation('mutation', fieldName, typedArgs, selectionSet)
100
+ return this.createMutationOperation(name, 'create', typedArgs, fields)
93
101
  }
94
102
 
95
-
96
103
  public update(name: string, args: Input.UpdateInput, fields?: EntitySelectionOrCallback): ContentMutation<MutationResult> {
97
104
 
98
- const context = this.createContext(name)
99
- const fieldName = `update${name}`
105
+ const entity = this.getEntity(name)
100
106
  const typedArgs = createTypedArgs(args, {
101
- data: `${context.entity.name}UpdateInput!`,
102
- by: `${context.entity.name}UniqueWhere!`,
103
- filter: `${context.entity.name}Where`,
107
+ data: `${entity.name}UpdateInput!`,
108
+ by: `${entity.name}UniqueWhere!`,
109
+ filter: `${entity.name}Where`,
104
110
  })
105
- const selectionSet = this.createMutationSelection('update', fields ? this.resolveSelectionSet(fields, context) : undefined)
106
-
107
- return new ContentOperation('mutation', fieldName, typedArgs, selectionSet)
111
+ return this.createMutationOperation(name, 'update', typedArgs, fields)
108
112
  }
109
113
 
110
114
 
111
115
  public upsert(name: string, args: Input.UpsertInput, fields?: EntitySelectionOrCallback): ContentMutation<MutationResult> {
112
116
 
113
- const context = this.createContext(name)
114
- const fieldName = `upsert${name}`
117
+ const entity = this.getEntity(name)
115
118
  const typedArgs = createTypedArgs(args, {
116
- update: `${context.entity.name}UpdateInput!`,
117
- create: `${context.entity.name}CreateInput!`,
118
- by: `${context.entity.name}UniqueWhere!`,
119
- filter: `${context.entity.name}Where`,
119
+ update: `${entity.name}UpdateInput!`,
120
+ create: `${entity.name}CreateInput!`,
121
+ by: `${entity.name}UniqueWhere!`,
122
+ filter: `${entity.name}Where`,
120
123
  })
121
-
122
- const selectionSet = this.createMutationSelection('upsert', fields ? this.resolveSelectionSet(fields, context) : undefined)
123
-
124
- return new ContentOperation('mutation', fieldName, typedArgs, selectionSet)
124
+ return this.createMutationOperation(name, 'upsert', typedArgs, fields)
125
125
  }
126
126
 
127
127
 
128
128
  public delete(name: string, args: Input.UniqueQueryInput, fields?: EntitySelectionOrCallback): ContentMutation<MutationResult> {
129
129
 
130
- const context = this.createContext(name)
130
+ const entity = this.getEntity(name)
131
131
  const typedArgs = createTypedArgs(args, {
132
- by: `${context.entity.name}UniqueWhere!`,
133
- filter: `${context.entity.name}Where`,
132
+ by: `${entity.name}UniqueWhere!`,
133
+ filter: `${entity.name}Where`,
134
134
  })
135
- const fieldName = `delete${name}`
136
- const selectionSet = this.createMutationSelection('delete', fields ? this.resolveSelectionSet(fields, context) : undefined)
135
+ return this.createMutationOperation(name, 'delete', typedArgs, fields)
136
+ }
137
+
138
+
139
+ private createMutationOperation(name: string, operation: MutationOperation, args: GraphQlFieldTypedArgs, fields?: EntitySelectionOrCallback): ContentMutation<MutationResult> {
140
+
141
+ const context = this.createContext(name)
142
+ const fieldName = `${operation}${name}`
143
+ const nodeSelection = fields ? this.resolveSelection(fields, context) : undefined
144
+ const selectionSet = this.createMutationSelection(operation, nodeSelection?.selectionSet)
137
145
 
138
- return new ContentOperation('mutation', fieldName, typedArgs, selectionSet)
146
+ return new ContentOperation('mutation', fieldName, args, selectionSet, it => {
147
+ if (!nodeSelection?.transformFn) {
148
+ return it
149
+ }
150
+ return {
151
+ ...it,
152
+ node: it.node ? nodeSelection.transformFn(it.node, {
153
+ rootValue: it.node,
154
+ }) : null,
155
+ }
156
+ })
139
157
  }
140
158
 
141
159
  public transaction(
@@ -162,7 +180,7 @@ export class ContentQueryBuilder {
162
180
  })
163
181
  }
164
182
 
165
- private createMutationSelection(operation: 'create' | 'update' | 'delete' | 'upsert' | 'transaction', selection?: GraphQlSelectionSet): GraphQlSelectionSet {
183
+ private createMutationSelection(operation: MutationOperation, selection?: GraphQlSelectionSet): GraphQlSelectionSet {
166
184
  const items: GraphQlSelectionSet = [
167
185
  new GraphQlField(null, 'ok'),
168
186
  new GraphQlField(null, 'errorMessage'),
@@ -182,23 +200,28 @@ export class ContentQueryBuilder {
182
200
  }
183
201
 
184
202
 
185
- private resolveSelectionSet(
203
+ private resolveSelection(
186
204
  fields: EntitySelectionOrCallback,
187
205
  context: ContentEntitySelectionContext<string>,
188
206
  ) {
189
- return (typeof fields === 'function' ? fields(new ContentEntitySelection(context, [])) : fields).selectionSet
207
+ return (typeof fields === 'function' ? fields(new ContentEntitySelection(context, [])) : fields)
190
208
  }
191
209
 
192
210
  private createContext(
193
211
  name: string,
194
212
  ): ContentEntitySelectionContext<string> {
195
- const entity = this.schema.entities[name]
196
- if (!entity) {
197
- throw new Error(`Entity ${name} not found`)
198
- }
213
+ const entity = this.getEntity(name)
199
214
  return {
200
215
  entity: entity,
201
216
  schema: this.schema,
202
217
  }
203
218
  }
219
+
220
+ private getEntity(name: string) {
221
+ const entity = this.schema.entities[name]
222
+ if (!entity) {
223
+ throw new Error(`Entity ${name} not found`)
224
+ }
225
+ return entity
226
+ }
204
227
  }
@@ -28,6 +28,10 @@ export type EntitySelectionAnyArgs =
28
28
  export type ContentEntitySelectionOrCallback = ContentEntitySelectionCallback | ContentEntitySelection
29
29
 
30
30
 
31
+ export type ContentTransformContext = {
32
+ rootValue: unknown
33
+ }
34
+
31
35
  export class ContentEntitySelection {
32
36
 
33
37
  /**
@@ -38,6 +42,8 @@ export class ContentEntitySelection {
38
42
  public readonly context: ContentEntitySelectionContext<string>,
39
43
  /** @internal */
40
44
  public readonly selectionSet: GraphQlSelectionSet,
45
+ /** @internal */
46
+ public readonly transformFn?: (value: any, ctx: ContentTransformContext) => any,
41
47
  ) {
42
48
  }
43
49
 
@@ -93,6 +99,13 @@ export class ContentEntitySelection {
93
99
  return new ContentEntitySelection(this.context, nodes)
94
100
  }
95
101
 
102
+
103
+ transform(transform: (value: any, context: ContentTransformContext) => any): ContentEntitySelection {
104
+ return new ContentEntitySelection(this.context, this.selectionSet, !this.transformFn ? transform : (value, ctx) => {
105
+ return transform(this.transformFn!(value, ctx), ctx)
106
+ })
107
+ }
108
+
96
109
  private _column(
97
110
  name: string,
98
111
  args: EntitySelectionCommonInput = {},
@@ -141,7 +154,12 @@ export class ContentEntitySelection {
141
154
  createListArgs(entity, args),
142
155
  entitySelection.selectionSet,
143
156
  )
144
- return this.withField(newObjectField)
157
+ const selectionWithField = this.withField(newObjectField)
158
+ const nestedTransform = entitySelection.transformFn
159
+ if (!nestedTransform) {
160
+ return selectionWithField
161
+ }
162
+ return this.withFieldTransform(alias, it => it.map(nestedTransform))
145
163
  }
146
164
 
147
165
 
@@ -188,7 +206,12 @@ export class ContentEntitySelection {
188
206
  argsWithType,
189
207
  entitySelection.selectionSet,
190
208
  )
191
- return this.withField(newObjectField)
209
+ const selectionWithField = this.withField(newObjectField)
210
+ const nestedTransform = entitySelection.transformFn
211
+ if (!nestedTransform) {
212
+ return selectionWithField
213
+ }
214
+ return this.withFieldTransform(alias, (it, ctx) => it !== null ? nestedTransform(it, ctx) : null)
192
215
  }
193
216
 
194
217
  private _one(
@@ -227,7 +250,12 @@ export class ContentEntitySelection {
227
250
  argsWithType,
228
251
  entitySelection.selectionSet,
229
252
  )
230
- return this.withField(newObjectField)
253
+ const selectionWithField = this.withField(newObjectField)
254
+ const nestedTransform = entitySelection.transformFn
255
+ if (!nestedTransform) {
256
+ return selectionWithField
257
+ }
258
+ return this.withFieldTransform(alias, (it, ctx) => it !== null ? nestedTransform(it, ctx) : null)
231
259
  }
232
260
 
233
261
 
@@ -235,6 +263,17 @@ export class ContentEntitySelection {
235
263
  return new ContentEntitySelection(this.context, [
236
264
  ...this.selectionSet,
237
265
  field,
238
- ])
266
+ ], this.transformFn)
267
+ }
268
+
269
+ private withFieldTransform(alias: string, transform: (value: any, ctx: ContentTransformContext) => any) {
270
+ return new ContentEntitySelection(this.context, this.selectionSet, (value, ctx) => {
271
+ const transformedValue = transform(value[alias], ctx)
272
+ const newValue = {
273
+ ...value,
274
+ [alias]: transformedValue,
275
+ }
276
+ return this.transformFn ? this.transformFn(newValue, ctx) : newValue
277
+ })
239
278
  }
240
279
  }
@@ -12,6 +12,9 @@ export interface TypedEntitySelection<TSchema extends SchemaTypeLike, TEntityNam
12
12
  [key in keyof TEntity['columns']]: TEntity['columns'][key]
13
13
  }>
14
14
 
15
+
16
+ transform<T>(cb: (value: TValue) => T): TypedEntitySelection<TSchema, TEntityName, TEntity, T>
17
+
15
18
  $<
16
19
  TNestedValue,
17
20
  TKey extends (keyof TEntity['columns'] | keyof TEntity['hasMany'] | keyof TEntity['hasManyBy'] | keyof TEntity['hasOne']) & string,
@@ -6,6 +6,9 @@ export const createTypedArgs = <TArgs extends Record<string, any>>(
6
6
  ): GraphQlFieldTypedArgs => {
7
7
  const typedArgs: GraphQlFieldTypedArgs = {}
8
8
  for (const key in args) {
9
+ if (!types.hasOwnProperty(key)) {
10
+ throw new Error(`Unknown argument ${key}`)
11
+ }
9
12
  typedArgs[key] = {
10
13
  graphQlType: types[key],
11
14
  value: args[key],