@contember/client-content 2.1.0-alpha.9 → 2.1.0-beta.1
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/CLAUDE.md +52 -0
- package/dist/development/src/ContentClient.cjs +12 -0
- package/dist/development/src/ContentClient.cjs.map +1 -1
- package/dist/development/src/ContentClient.js +12 -0
- package/dist/development/src/ContentClient.js.map +1 -1
- package/dist/development/src/ContentQueryBuilder.cjs +26 -15
- package/dist/development/src/ContentQueryBuilder.cjs.map +1 -1
- package/dist/development/src/ContentQueryBuilder.js +26 -15
- package/dist/development/src/ContentQueryBuilder.js.map +1 -1
- package/dist/development/src/MutationFailedError.cjs +11 -0
- package/dist/development/src/MutationFailedError.cjs.map +1 -0
- package/dist/development/src/MutationFailedError.js +11 -0
- package/dist/development/src/MutationFailedError.js.map +1 -0
- package/dist/development/src/nodes/ContentEntitySelection.cjs +47 -12
- package/dist/development/src/nodes/ContentEntitySelection.cjs.map +1 -1
- package/dist/development/src/nodes/ContentEntitySelection.js +47 -12
- package/dist/development/src/nodes/ContentEntitySelection.js.map +1 -1
- package/dist/development/src/nodes/ContentOperation.cjs.map +1 -1
- package/dist/development/src/nodes/ContentOperation.js.map +1 -1
- package/dist/development/src/utils/ContentOperationSet.cjs.map +1 -1
- package/dist/development/src/utils/ContentOperationSet.js.map +1 -1
- package/dist/development/src/utils/createListArgs.cjs.map +1 -1
- package/dist/development/src/utils/createListArgs.js.map +1 -1
- package/dist/development/src/utils/createMutationOperationSet.cjs +8 -6
- package/dist/development/src/utils/createMutationOperationSet.cjs.map +1 -1
- package/dist/development/src/utils/createMutationOperationSet.js +8 -6
- package/dist/development/src/utils/createMutationOperationSet.js.map +1 -1
- package/dist/development/src/utils/createQueryOperationSet.cjs.map +1 -1
- package/dist/development/src/utils/createQueryOperationSet.js.map +1 -1
- package/dist/development/src/utils/createTypedArgs.cjs.map +1 -1
- package/dist/development/src/utils/createTypedArgs.js.map +1 -1
- package/dist/development/src/utils/mutationFragments.cjs.map +1 -1
- package/dist/development/src/utils/mutationFragments.js.map +1 -1
- package/dist/production/src/ContentClient.cjs +12 -0
- package/dist/production/src/ContentClient.cjs.map +1 -1
- package/dist/production/src/ContentClient.js +12 -0
- package/dist/production/src/ContentClient.js.map +1 -1
- package/dist/production/src/ContentQueryBuilder.cjs +26 -15
- package/dist/production/src/ContentQueryBuilder.cjs.map +1 -1
- package/dist/production/src/ContentQueryBuilder.js +26 -15
- package/dist/production/src/ContentQueryBuilder.js.map +1 -1
- package/dist/production/src/MutationFailedError.cjs +11 -0
- package/dist/production/src/MutationFailedError.cjs.map +1 -0
- package/dist/production/src/MutationFailedError.js +11 -0
- package/dist/production/src/MutationFailedError.js.map +1 -0
- package/dist/production/src/nodes/ContentEntitySelection.cjs +47 -12
- package/dist/production/src/nodes/ContentEntitySelection.cjs.map +1 -1
- package/dist/production/src/nodes/ContentEntitySelection.js +47 -12
- package/dist/production/src/nodes/ContentEntitySelection.js.map +1 -1
- package/dist/production/src/nodes/ContentOperation.cjs.map +1 -1
- package/dist/production/src/nodes/ContentOperation.js.map +1 -1
- package/dist/production/src/utils/ContentOperationSet.cjs.map +1 -1
- package/dist/production/src/utils/ContentOperationSet.js.map +1 -1
- package/dist/production/src/utils/createListArgs.cjs.map +1 -1
- package/dist/production/src/utils/createListArgs.js.map +1 -1
- package/dist/production/src/utils/createMutationOperationSet.cjs +8 -6
- package/dist/production/src/utils/createMutationOperationSet.cjs.map +1 -1
- package/dist/production/src/utils/createMutationOperationSet.js +8 -6
- package/dist/production/src/utils/createMutationOperationSet.js.map +1 -1
- package/dist/production/src/utils/createQueryOperationSet.cjs.map +1 -1
- package/dist/production/src/utils/createQueryOperationSet.js.map +1 -1
- package/dist/production/src/utils/createTypedArgs.cjs.map +1 -1
- package/dist/production/src/utils/createTypedArgs.js.map +1 -1
- package/dist/production/src/utils/mutationFragments.cjs.map +1 -1
- package/dist/production/src/utils/mutationFragments.js.map +1 -1
- package/dist/types/ContentClient.d.ts +10 -0
- package/dist/types/ContentClient.d.ts.map +1 -1
- package/dist/types/ContentQueryBuilder.d.ts.map +1 -1
- package/dist/types/MutationFailedError.d.ts +13 -0
- package/dist/types/MutationFailedError.d.ts.map +1 -0
- package/dist/types/TypedContentQueryBuilder.d.ts.map +1 -1
- package/dist/types/nodes/ContentEntitySelection.d.ts +4 -1
- package/dist/types/nodes/ContentEntitySelection.d.ts.map +1 -1
- package/dist/types/nodes/TypedEntitySelection.d.ts +1 -0
- package/dist/types/nodes/TypedEntitySelection.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/dist/types/types/Input.d.ts.map +1 -1
- package/dist/types/types/Result.d.ts +30 -9
- package/dist/types/types/Result.d.ts.map +1 -1
- package/dist/types/utils/createListArgs.d.ts.map +1 -1
- package/dist/types/utils/createMutationOperationSet.d.ts.map +1 -1
- package/dist/types/utils/createQueryOperationSet.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/ContentClient.ts +36 -9
- package/src/ContentQueryBuilder.ts +45 -35
- package/src/MutationFailedError.ts +19 -0
- package/src/TypedContentQueryBuilder.ts +0 -4
- package/src/nodes/ContentEntitySelection.ts +67 -23
- package/src/nodes/TypedEntitySelection.ts +96 -48
- package/src/types/Input.ts +1 -9
- package/src/types/Result.ts +41 -9
- package/src/types/Schema.ts +0 -1
- package/src/utils/createListArgs.ts +5 -1
- package/src/utils/createMutationOperationSet.ts +9 -7
- package/src/utils/createQueryOperationSet.ts +0 -1
- package/tests/cases/unit/__snapshots__/mutation.test.ts.snap +952 -818
- package/tests/cases/unit/__snapshots__/query.test.ts.snap +216 -60
- package/tests/cases/unit/mutation.test.ts +48 -3
- package/tests/cases/unit/query.test.ts +103 -82
- package/tests/cases/unit/types.test.ts +31 -27
- package/tests/client/entities.ts +2 -0
- package/tests/client/enums.ts +5 -0
- package/tests/client/names.ts +129 -117
- package/tests/generate.ts +0 -1
- package/tests/lib.ts +0 -1
- package/tests/schema.ts +1 -2
package/src/ContentClient.ts
CHANGED
|
@@ -4,10 +4,10 @@ import { GraphQlQueryPrinter } from '@contember/graphql-builder'
|
|
|
4
4
|
import { ContentMutation, ContentQuery } from './nodes'
|
|
5
5
|
import { createMutationOperationSet } from './utils/createMutationOperationSet'
|
|
6
6
|
import { createQueryOperationSet } from './utils/createQueryOperationSet'
|
|
7
|
+
import { MutationError, ValidationResult } from './types'
|
|
8
|
+
import { MutationFailedError } from './MutationFailedError'
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
export type QueryExecutorOptions =
|
|
10
|
-
& GraphQlClientRequestOptions
|
|
10
|
+
export type QueryExecutorOptions = GraphQlClientRequestOptions
|
|
11
11
|
|
|
12
12
|
export class ContentClient {
|
|
13
13
|
constructor(
|
|
@@ -15,9 +15,11 @@ export class ContentClient {
|
|
|
15
15
|
) {
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
|
|
19
18
|
public async query<Value>(query: ContentQuery<Value>, options?: QueryExecutorOptions): Promise<Value>
|
|
20
|
-
public async query<Values extends Record<string, any>>(
|
|
19
|
+
public async query<Values extends Record<string, any>>(
|
|
20
|
+
queries: { [K in keyof Values]: ContentQuery<Values[K]> },
|
|
21
|
+
options?: QueryExecutorOptions,
|
|
22
|
+
): Promise<Values>
|
|
21
23
|
public async query(queries: Record<string, ContentQuery<any>> | ContentQuery<any>, options?: QueryExecutorOptions): Promise<any> {
|
|
22
24
|
const printer = new GraphQlQueryPrinter()
|
|
23
25
|
const operationSet = createQueryOperationSet(queries)
|
|
@@ -26,10 +28,16 @@ export class ContentClient {
|
|
|
26
28
|
return operationSet.parse(result)
|
|
27
29
|
}
|
|
28
30
|
|
|
29
|
-
public async mutate<Value>(mutation: ContentMutation<Value>, options?: QueryExecutorOptions
|
|
30
|
-
public async mutate<Value>(mutations: ContentMutation<Value>[], options?: QueryExecutorOptions
|
|
31
|
-
public async mutate<Values extends Record<string, any>>(
|
|
32
|
-
|
|
31
|
+
public async mutate<Value>(mutation: ContentMutation<Value>, options?: QueryExecutorOptions): Promise<Value>
|
|
32
|
+
public async mutate<Value>(mutations: ContentMutation<Value>[], options?: QueryExecutorOptions): Promise<Value[]>
|
|
33
|
+
public async mutate<Values extends Record<string, any>>(
|
|
34
|
+
mutations: { [K in keyof Values]: ContentMutation<Values[K]> | ContentQuery<Values[K]> },
|
|
35
|
+
options?: QueryExecutorOptions,
|
|
36
|
+
): Promise<Values>
|
|
37
|
+
public async mutate(
|
|
38
|
+
input: Record<string, ContentMutation<any> | ContentQuery<any>> | ContentMutation<any> | ContentMutation<any>[],
|
|
39
|
+
options?: QueryExecutorOptions,
|
|
40
|
+
): Promise<any> {
|
|
33
41
|
const operationSet = createMutationOperationSet(input)
|
|
34
42
|
|
|
35
43
|
const printer = new GraphQlQueryPrinter()
|
|
@@ -38,4 +46,23 @@ export class ContentClient {
|
|
|
38
46
|
|
|
39
47
|
return operationSet.parse(result)
|
|
40
48
|
}
|
|
49
|
+
|
|
50
|
+
public async mutateOrThrow<
|
|
51
|
+
Value extends {
|
|
52
|
+
readonly ok: boolean
|
|
53
|
+
readonly errorMessage: string | null
|
|
54
|
+
readonly errors: MutationError[]
|
|
55
|
+
readonly validation: ValidationResult
|
|
56
|
+
},
|
|
57
|
+
>(mutation: ContentMutation<Value>, options?: QueryExecutorOptions): Promise<Value & { readonly ok: true; readonly errorMessage: null }> {
|
|
58
|
+
const result = await this.mutate(mutation, options)
|
|
59
|
+
if (!result.ok) {
|
|
60
|
+
throw new MutationFailedError(
|
|
61
|
+
result.errorMessage ?? 'Unknown error',
|
|
62
|
+
mutation as ContentMutation<Value & { readonly ok: false; readonly errorMessage: string }>,
|
|
63
|
+
result as Value & { readonly ok: false; readonly errorMessage: string },
|
|
64
|
+
)
|
|
65
|
+
}
|
|
66
|
+
return result as Value & { readonly ok: true; readonly errorMessage: null }
|
|
67
|
+
}
|
|
41
68
|
}
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { ContentClientInput, MutationResult, SchemaNames, TransactionResult } from './types'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ContentEntitySelection,
|
|
4
|
+
ContentEntitySelectionCallback,
|
|
5
|
+
ContentEntitySelectionContext,
|
|
6
|
+
ContentMutation,
|
|
7
|
+
ContentOperation,
|
|
8
|
+
ContentQuery,
|
|
9
|
+
} from './nodes'
|
|
3
10
|
import { createListArgs } from './utils/createListArgs'
|
|
4
11
|
import { createTypedArgs } from './utils/createTypedArgs'
|
|
5
12
|
import { Input } from '@contember/schema'
|
|
@@ -21,7 +28,6 @@ export class ContentQueryBuilder {
|
|
|
21
28
|
constructor(private readonly schema: SchemaNames) {
|
|
22
29
|
}
|
|
23
30
|
|
|
24
|
-
|
|
25
31
|
public fragment(name: string, fieldsCallback?: ContentEntitySelectionCallback): ContentEntitySelection {
|
|
26
32
|
const context = this.createContext(name)
|
|
27
33
|
|
|
@@ -32,8 +38,6 @@ export class ContentQueryBuilder {
|
|
|
32
38
|
return fieldsCallback(entitySelection)
|
|
33
39
|
}
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
37
41
|
public count(name: string, args: Pick<ContentClientInput.AnyListQueryInput, 'filter'>): ContentQuery<number> {
|
|
38
42
|
const context = this.createContext(name)
|
|
39
43
|
const fieldName = `paginate${name}`
|
|
@@ -51,7 +55,6 @@ export class ContentQueryBuilder {
|
|
|
51
55
|
})
|
|
52
56
|
}
|
|
53
57
|
|
|
54
|
-
|
|
55
58
|
public list(name: string, args: ContentClientInput.AnyListQueryInput, fields: EntitySelectionOrCallback): ContentQuery<any[]> {
|
|
56
59
|
const context = this.createContext(name)
|
|
57
60
|
const fieldName = `list${name}`
|
|
@@ -59,17 +62,19 @@ export class ContentQueryBuilder {
|
|
|
59
62
|
const selection = this.resolveSelection(fields, context)
|
|
60
63
|
|
|
61
64
|
return new ContentOperation('query', fieldName, typedArgs, selection.selectionSet, it => {
|
|
65
|
+
if (!it) return it
|
|
62
66
|
const transformFn = selection.transformFn
|
|
63
67
|
if (transformFn) {
|
|
64
|
-
return it.map((el: any) =>
|
|
65
|
-
|
|
66
|
-
|
|
68
|
+
return it.map((el: any) =>
|
|
69
|
+
transformFn(el, {
|
|
70
|
+
rootValue: it,
|
|
71
|
+
})
|
|
72
|
+
)
|
|
67
73
|
}
|
|
68
74
|
return it
|
|
69
75
|
})
|
|
70
76
|
}
|
|
71
77
|
|
|
72
|
-
|
|
73
78
|
public get(name: string, args: Input.UniqueQueryInput, fields: EntitySelectionOrCallback): ContentQuery<Record<string, unknown> | null> {
|
|
74
79
|
const context = this.createContext(name)
|
|
75
80
|
const fieldName = `get${name}`
|
|
@@ -89,9 +94,7 @@ export class ContentQueryBuilder {
|
|
|
89
94
|
})
|
|
90
95
|
}
|
|
91
96
|
|
|
92
|
-
|
|
93
97
|
public create(name: string, args: Input.CreateInput, fields?: EntitySelectionOrCallback): ContentMutation<MutationResult> {
|
|
94
|
-
|
|
95
98
|
const entity = this.getEntity(name)
|
|
96
99
|
const typedArgs = createTypedArgs(args, {
|
|
97
100
|
data: `${entity.name}CreateInput!`,
|
|
@@ -101,7 +104,6 @@ export class ContentQueryBuilder {
|
|
|
101
104
|
}
|
|
102
105
|
|
|
103
106
|
public update(name: string, args: Input.UpdateInput, fields?: EntitySelectionOrCallback): ContentMutation<MutationResult> {
|
|
104
|
-
|
|
105
107
|
const entity = this.getEntity(name)
|
|
106
108
|
const typedArgs = createTypedArgs(args, {
|
|
107
109
|
data: `${entity.name}UpdateInput!`,
|
|
@@ -111,9 +113,7 @@ export class ContentQueryBuilder {
|
|
|
111
113
|
return this.createMutationOperation(name, 'update', typedArgs, fields)
|
|
112
114
|
}
|
|
113
115
|
|
|
114
|
-
|
|
115
116
|
public upsert(name: string, args: Input.UpsertInput, fields?: EntitySelectionOrCallback): ContentMutation<MutationResult> {
|
|
116
|
-
|
|
117
117
|
const entity = this.getEntity(name)
|
|
118
118
|
const typedArgs = createTypedArgs(args, {
|
|
119
119
|
update: `${entity.name}UpdateInput!`,
|
|
@@ -124,9 +124,7 @@ export class ContentQueryBuilder {
|
|
|
124
124
|
return this.createMutationOperation(name, 'upsert', typedArgs, fields)
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
|
|
128
127
|
public delete(name: string, args: Input.UniqueQueryInput, fields?: EntitySelectionOrCallback): ContentMutation<MutationResult> {
|
|
129
|
-
|
|
130
128
|
const entity = this.getEntity(name)
|
|
131
129
|
const typedArgs = createTypedArgs(args, {
|
|
132
130
|
by: `${entity.name}UniqueWhere!`,
|
|
@@ -135,9 +133,12 @@ export class ContentQueryBuilder {
|
|
|
135
133
|
return this.createMutationOperation(name, 'delete', typedArgs, fields)
|
|
136
134
|
}
|
|
137
135
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
private createMutationOperation(
|
|
137
|
+
name: string,
|
|
138
|
+
operation: MutationOperation,
|
|
139
|
+
args: GraphQlFieldTypedArgs,
|
|
140
|
+
fields?: EntitySelectionOrCallback,
|
|
141
|
+
): ContentMutation<MutationResult> {
|
|
141
142
|
const context = this.createContext(name)
|
|
142
143
|
const fieldName = `${operation}${name}`
|
|
143
144
|
const nodeSelection = fields ? this.resolveSelection(fields, context) : undefined
|
|
@@ -149,9 +150,11 @@ export class ContentQueryBuilder {
|
|
|
149
150
|
}
|
|
150
151
|
return {
|
|
151
152
|
...it,
|
|
152
|
-
node: it.node
|
|
153
|
-
|
|
154
|
-
|
|
153
|
+
node: it.node
|
|
154
|
+
? nodeSelection.transformFn(it.node, {
|
|
155
|
+
rootValue: it.node,
|
|
156
|
+
})
|
|
157
|
+
: null,
|
|
155
158
|
}
|
|
156
159
|
})
|
|
157
160
|
}
|
|
@@ -169,15 +172,21 @@ export class ContentQueryBuilder {
|
|
|
169
172
|
...this.createMutationSelection('transaction'),
|
|
170
173
|
...combined.selection,
|
|
171
174
|
]
|
|
172
|
-
return new ContentOperation<TransactionResult<any>, 'mutation'>(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
175
|
+
return new ContentOperation<TransactionResult<any>, 'mutation'>(
|
|
176
|
+
'mutation',
|
|
177
|
+
'transaction',
|
|
178
|
+
transactionArgs,
|
|
179
|
+
items,
|
|
180
|
+
({ ok, errorMessage, errors, validation, ...data }) => {
|
|
181
|
+
return {
|
|
182
|
+
ok,
|
|
183
|
+
errorMessage,
|
|
184
|
+
errors,
|
|
185
|
+
validation,
|
|
186
|
+
data: combined.parse(data),
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
)
|
|
181
190
|
}
|
|
182
191
|
|
|
183
192
|
private createMutationSelection(operation: MutationOperation, selection?: GraphQlSelectionSet): GraphQlSelectionSet {
|
|
@@ -189,9 +198,11 @@ export class ContentQueryBuilder {
|
|
|
189
198
|
]),
|
|
190
199
|
]
|
|
191
200
|
if (operation !== 'delete') {
|
|
192
|
-
items.push(
|
|
193
|
-
new
|
|
194
|
-
|
|
201
|
+
items.push(
|
|
202
|
+
new GraphQlField(null, 'validation', {}, [
|
|
203
|
+
new GraphQlFragmentSpread('ValidationResult'),
|
|
204
|
+
]),
|
|
205
|
+
)
|
|
195
206
|
}
|
|
196
207
|
if (selection) {
|
|
197
208
|
items.push(new GraphQlField(null, 'node', {}, selection))
|
|
@@ -199,7 +210,6 @@ export class ContentQueryBuilder {
|
|
|
199
210
|
return items
|
|
200
211
|
}
|
|
201
212
|
|
|
202
|
-
|
|
203
213
|
private resolveSelection(
|
|
204
214
|
fields: EntitySelectionOrCallback,
|
|
205
215
|
context: ContentEntitySelectionContext<string>,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { MutationError, ValidationResult } from './types'
|
|
2
|
+
import { ContentMutation } from './nodes'
|
|
3
|
+
|
|
4
|
+
export class MutationFailedError<
|
|
5
|
+
Value extends {
|
|
6
|
+
readonly ok: false
|
|
7
|
+
readonly errorMessage: string
|
|
8
|
+
readonly errors: MutationError[]
|
|
9
|
+
readonly validation: ValidationResult
|
|
10
|
+
},
|
|
11
|
+
> extends Error {
|
|
12
|
+
constructor(
|
|
13
|
+
message: string,
|
|
14
|
+
public readonly request: ContentMutation<Value>,
|
|
15
|
+
public readonly result: Value,
|
|
16
|
+
) {
|
|
17
|
+
super(message)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -2,14 +2,11 @@ import { ContentClientInput, MutationResult, SchemaTypeLike, TransactionResult }
|
|
|
2
2
|
import { ContentMutation, ContentQuery, TypedEntitySelection, TypedEntitySelectionCallback } from './nodes'
|
|
3
3
|
import { MutationTransactionOptions } from './ContentQueryBuilder'
|
|
4
4
|
|
|
5
|
-
|
|
6
5
|
export type TypedContentEntitySelectionOrCallback<TSchema extends SchemaTypeLike, TEntityName extends keyof TSchema['entities'] & string, TValue> =
|
|
7
6
|
| TypedEntitySelection<TSchema, TEntityName, TSchema['entities'][TEntityName], TValue>
|
|
8
7
|
| TypedEntitySelectionCallback<TSchema, TEntityName, TSchema['entities'][TEntityName], TValue>
|
|
9
8
|
|
|
10
|
-
|
|
11
9
|
export interface TypedContentQueryBuilder<TSchema extends SchemaTypeLike> {
|
|
12
|
-
|
|
13
10
|
fragment<EntityName extends keyof TSchema['entities'] & string>(
|
|
14
11
|
name: EntityName,
|
|
15
12
|
): TypedEntitySelection<TSchema, EntityName, TSchema['entities'][EntityName], {}>
|
|
@@ -73,4 +70,3 @@ export interface TypedContentQueryBuilder<TSchema extends SchemaTypeLike> {
|
|
|
73
70
|
options?: MutationTransactionOptions,
|
|
74
71
|
): ContentMutation<TransactionResult<Values>>
|
|
75
72
|
}
|
|
76
|
-
|
|
@@ -14,8 +14,13 @@ export type ContentEntitySelectionContext<Name extends string> = {
|
|
|
14
14
|
export type ContentEntitySelectionCallback = (select: ContentEntitySelection) => ContentEntitySelection
|
|
15
15
|
|
|
16
16
|
export type EntitySelectionCommonInput<Alias extends string | null = string | null> = { as?: Alias }
|
|
17
|
-
export type EntitySelectionManyArgs<Alias extends string | null = string | null> =
|
|
18
|
-
|
|
17
|
+
export type EntitySelectionManyArgs<Alias extends string | null = string | null> =
|
|
18
|
+
& ContentClientInput.AnyListQueryInput
|
|
19
|
+
& EntitySelectionCommonInput<Alias>
|
|
20
|
+
& { totalCount?: boolean }
|
|
21
|
+
export type EntitySelectionManyByArgs<Alias extends string | null = string | null> =
|
|
22
|
+
& { by: Input.UniqueWhere; filter?: Input.Where }
|
|
23
|
+
& EntitySelectionCommonInput<Alias>
|
|
19
24
|
export type EntitySelectionOneArgs<Alias extends string | null = string | null> = { filter?: Input.Where } & EntitySelectionCommonInput<Alias>
|
|
20
25
|
export type EntitySelectionColumnArgs<Alias extends string | null = string | null> = EntitySelectionCommonInput<Alias>
|
|
21
26
|
|
|
@@ -27,13 +32,11 @@ export type EntitySelectionAnyArgs =
|
|
|
27
32
|
|
|
28
33
|
export type ContentEntitySelectionOrCallback = ContentEntitySelectionCallback | ContentEntitySelection
|
|
29
34
|
|
|
30
|
-
|
|
31
35
|
export type ContentTransformContext = {
|
|
32
36
|
rootValue: unknown
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
export class ContentEntitySelection {
|
|
36
|
-
|
|
37
40
|
/**
|
|
38
41
|
* @internal
|
|
39
42
|
*/
|
|
@@ -47,14 +50,17 @@ export class ContentEntitySelection {
|
|
|
47
50
|
) {
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
|
|
51
53
|
$(field: string, args?: EntitySelectionColumnArgs): ContentEntitySelection
|
|
52
54
|
$(field: string, args: EntitySelectionManyArgs, selection: ContentEntitySelectionOrCallback): ContentEntitySelection
|
|
53
55
|
$(field: string, args: EntitySelectionManyByArgs, selection: ContentEntitySelectionOrCallback): ContentEntitySelection
|
|
54
56
|
$(field: string, args: EntitySelectionOneArgs, selection: ContentEntitySelectionOrCallback): ContentEntitySelection
|
|
55
57
|
$(field: string, selection: ContentEntitySelectionOrCallback): ContentEntitySelection
|
|
56
58
|
|
|
57
|
-
$(
|
|
59
|
+
$(
|
|
60
|
+
field: string,
|
|
61
|
+
argsOrSelection?: EntitySelectionAnyArgs | ContentEntitySelectionOrCallback,
|
|
62
|
+
selectionIn?: ContentEntitySelectionOrCallback,
|
|
63
|
+
): ContentEntitySelection {
|
|
58
64
|
const [args, selection] = typeof argsOrSelection === 'function' || argsOrSelection instanceof ContentEntitySelection
|
|
59
65
|
? [{}, argsOrSelection]
|
|
60
66
|
: [argsOrSelection ?? {}, selectionIn]
|
|
@@ -99,6 +105,19 @@ export class ContentEntitySelection {
|
|
|
99
105
|
return new ContentEntitySelection(this.context, nodes)
|
|
100
106
|
}
|
|
101
107
|
|
|
108
|
+
omit(...fields: string[]): ContentEntitySelection {
|
|
109
|
+
return new ContentEntitySelection(
|
|
110
|
+
this.context,
|
|
111
|
+
this.selectionSet.filter(it => {
|
|
112
|
+
if (!(it instanceof GraphQlField)) {
|
|
113
|
+
return true
|
|
114
|
+
}
|
|
115
|
+
const alias = it.alias ?? it.name
|
|
116
|
+
return !fields.includes(alias)
|
|
117
|
+
}),
|
|
118
|
+
)
|
|
119
|
+
}
|
|
120
|
+
|
|
102
121
|
meta(field: string, flags: ('readable' | 'updatable')[]): ContentEntitySelection {
|
|
103
122
|
const metaField = this.selectionSet.find((it): it is GraphQlField => it instanceof GraphQlField && it.name === '_meta')
|
|
104
123
|
const selectionWithoutMeta = metaField ? this.selectionSet.filter(it => it !== metaField) : this.selectionSet
|
|
@@ -117,11 +136,14 @@ export class ContentEntitySelection {
|
|
|
117
136
|
])
|
|
118
137
|
}
|
|
119
138
|
|
|
120
|
-
|
|
121
139
|
transform(transform: (value: any, context: ContentTransformContext) => any): ContentEntitySelection {
|
|
122
|
-
return new ContentEntitySelection(
|
|
123
|
-
|
|
124
|
-
|
|
140
|
+
return new ContentEntitySelection(
|
|
141
|
+
this.context,
|
|
142
|
+
this.selectionSet,
|
|
143
|
+
!this.transformFn ? transform : (value, ctx) => {
|
|
144
|
+
return transform(this.transformFn!(value, ctx), ctx)
|
|
145
|
+
},
|
|
146
|
+
)
|
|
125
147
|
}
|
|
126
148
|
|
|
127
149
|
private _column(
|
|
@@ -142,14 +164,13 @@ export class ContentEntitySelection {
|
|
|
142
164
|
return this.withField(field)
|
|
143
165
|
}
|
|
144
166
|
|
|
145
|
-
|
|
146
167
|
private _many(
|
|
147
168
|
name: string,
|
|
148
169
|
args: EntitySelectionManyArgs,
|
|
149
170
|
fields:
|
|
150
171
|
| ContentEntitySelectionCallback
|
|
151
172
|
| ContentEntitySelection,
|
|
152
|
-
): ContentEntitySelection{
|
|
173
|
+
): ContentEntitySelection {
|
|
153
174
|
const alias = args.as ?? name
|
|
154
175
|
const fieldInfo = this.context.entity.fields[name]
|
|
155
176
|
if (!fieldInfo) {
|
|
@@ -166,20 +187,44 @@ export class ContentEntitySelection {
|
|
|
166
187
|
}
|
|
167
188
|
|
|
168
189
|
const entitySelection = typeof fields === 'function' ? fields(new ContentEntitySelection(newContext, [])) : fields
|
|
190
|
+
|
|
191
|
+
// Always use paginateRelation API (relay-like Connection format)
|
|
192
|
+
const paginateFieldName = `paginate${name.charAt(0).toUpperCase()}${name.slice(1)}`
|
|
193
|
+
const paginateSelectionSet: GraphQlSelectionSet = [
|
|
194
|
+
...(args.totalCount
|
|
195
|
+
? [
|
|
196
|
+
new GraphQlField(null, 'pageInfo', {}, [
|
|
197
|
+
new GraphQlField(null, 'totalCount'),
|
|
198
|
+
]),
|
|
199
|
+
]
|
|
200
|
+
: []),
|
|
201
|
+
new GraphQlField(null, 'edges', {}, [
|
|
202
|
+
new GraphQlField(null, 'node', {}, entitySelection.selectionSet),
|
|
203
|
+
]),
|
|
204
|
+
]
|
|
169
205
|
const newObjectField = new GraphQlField(
|
|
170
206
|
alias,
|
|
171
|
-
|
|
172
|
-
createListArgs(entity, args),
|
|
173
|
-
|
|
207
|
+
paginateFieldName,
|
|
208
|
+
createListArgs(entity, args, 'paginate'),
|
|
209
|
+
paginateSelectionSet,
|
|
174
210
|
)
|
|
175
211
|
const selectionWithField = this.withField(newObjectField)
|
|
212
|
+
const includeTotalCount = args.totalCount ?? false
|
|
176
213
|
const nestedTransform = entitySelection.transformFn
|
|
177
|
-
if (!nestedTransform) {
|
|
178
|
-
return selectionWithField
|
|
179
|
-
}
|
|
180
|
-
return this.withFieldTransform(alias, it => it.map(nestedTransform))
|
|
181
|
-
}
|
|
182
214
|
|
|
215
|
+
// Transform: unwrap Connection → flat array, optionally attach totalCount
|
|
216
|
+
return selectionWithField.withFieldTransform(alias, (connection, ctx) => {
|
|
217
|
+
const items = connection.edges.map((edge: any) => nestedTransform ? nestedTransform(edge.node, ctx) : edge.node)
|
|
218
|
+
if (includeTotalCount && connection.pageInfo) {
|
|
219
|
+
Object.defineProperty(items, 'totalCount', {
|
|
220
|
+
value: connection.pageInfo.totalCount,
|
|
221
|
+
enumerable: false,
|
|
222
|
+
writable: false,
|
|
223
|
+
})
|
|
224
|
+
}
|
|
225
|
+
return items
|
|
226
|
+
})
|
|
227
|
+
}
|
|
183
228
|
|
|
184
229
|
private _manyBy(
|
|
185
230
|
name: string,
|
|
@@ -229,7 +274,7 @@ export class ContentEntitySelection {
|
|
|
229
274
|
if (!nestedTransform) {
|
|
230
275
|
return selectionWithField
|
|
231
276
|
}
|
|
232
|
-
return
|
|
277
|
+
return selectionWithField.withFieldTransform(alias, (it, ctx) => it !== null ? nestedTransform(it, ctx) : null)
|
|
233
278
|
}
|
|
234
279
|
|
|
235
280
|
private _one(
|
|
@@ -273,10 +318,9 @@ export class ContentEntitySelection {
|
|
|
273
318
|
if (!nestedTransform) {
|
|
274
319
|
return selectionWithField
|
|
275
320
|
}
|
|
276
|
-
return
|
|
321
|
+
return selectionWithField.withFieldTransform(alias, (it, ctx) => it !== null ? nestedTransform(it, ctx) : null)
|
|
277
322
|
}
|
|
278
323
|
|
|
279
|
-
|
|
280
324
|
private withField(field: GraphQlField) {
|
|
281
325
|
return new ContentEntitySelection(this.context, [
|
|
282
326
|
...this.selectionSet,
|