@contember/client-content 2.1.0-alpha.3 → 2.1.0-alpha.30

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 (46) hide show
  1. package/dist/development/src/ContentClient.cjs +12 -0
  2. package/dist/development/src/ContentClient.cjs.map +1 -1
  3. package/dist/development/src/ContentClient.js +12 -0
  4. package/dist/development/src/ContentClient.js.map +1 -1
  5. package/dist/development/src/MutationFailedError.cjs +11 -0
  6. package/dist/development/src/MutationFailedError.cjs.map +1 -0
  7. package/dist/development/src/MutationFailedError.js +11 -0
  8. package/dist/development/src/MutationFailedError.js.map +1 -0
  9. package/dist/development/src/nodes/ContentEntitySelection.cjs +15 -3
  10. package/dist/development/src/nodes/ContentEntitySelection.cjs.map +1 -1
  11. package/dist/development/src/nodes/ContentEntitySelection.js +15 -3
  12. package/dist/development/src/nodes/ContentEntitySelection.js.map +1 -1
  13. package/dist/production/src/ContentClient.cjs +12 -0
  14. package/dist/production/src/ContentClient.cjs.map +1 -1
  15. package/dist/production/src/ContentClient.js +12 -0
  16. package/dist/production/src/ContentClient.js.map +1 -1
  17. package/dist/production/src/MutationFailedError.cjs +11 -0
  18. package/dist/production/src/MutationFailedError.cjs.map +1 -0
  19. package/dist/production/src/MutationFailedError.js +11 -0
  20. package/dist/production/src/MutationFailedError.js.map +1 -0
  21. package/dist/production/src/nodes/ContentEntitySelection.cjs +15 -3
  22. package/dist/production/src/nodes/ContentEntitySelection.cjs.map +1 -1
  23. package/dist/production/src/nodes/ContentEntitySelection.js +15 -3
  24. package/dist/production/src/nodes/ContentEntitySelection.js.map +1 -1
  25. package/dist/types/ContentClient.d.ts +10 -0
  26. package/dist/types/ContentClient.d.ts.map +1 -1
  27. package/dist/types/MutationFailedError.d.ts +13 -0
  28. package/dist/types/MutationFailedError.d.ts.map +1 -0
  29. package/dist/types/nodes/ContentEntitySelection.d.ts +1 -0
  30. package/dist/types/nodes/ContentEntitySelection.d.ts.map +1 -1
  31. package/dist/types/nodes/TypedEntitySelection.d.ts +1 -0
  32. package/dist/types/nodes/TypedEntitySelection.d.ts.map +1 -1
  33. package/dist/types/tsconfig.tsbuildinfo +1 -1
  34. package/dist/types/types/Result.d.ts +30 -9
  35. package/dist/types/types/Result.d.ts.map +1 -1
  36. package/package.json +5 -5
  37. package/src/ContentClient.ts +20 -0
  38. package/src/MutationFailedError.ts +17 -0
  39. package/src/nodes/ContentEntitySelection.ts +16 -3
  40. package/src/nodes/TypedEntitySelection.ts +4 -0
  41. package/src/types/Result.ts +41 -9
  42. package/tests/cases/unit/__snapshots__/mutation.test.ts.snap +198 -0
  43. package/tests/cases/unit/__snapshots__/query.test.ts.snap +133 -0
  44. package/tests/cases/unit/mutation.test.ts +49 -0
  45. package/tests/cases/unit/query.test.ts +30 -0
  46. package/tests/cases/unit/types.test.ts +6 -0
@@ -99,6 +99,19 @@ export class ContentEntitySelection {
99
99
  return new ContentEntitySelection(this.context, nodes)
100
100
  }
101
101
 
102
+ omit(...fields: string[]): ContentEntitySelection {
103
+ return new ContentEntitySelection(
104
+ this.context,
105
+ this.selectionSet.filter(it => {
106
+ if (!(it instanceof GraphQlField)) {
107
+ return true
108
+ }
109
+ const alias = it.alias ?? it.name
110
+ return !fields.includes(alias)
111
+ }),
112
+ )
113
+ }
114
+
102
115
  meta(field: string, flags: ('readable' | 'updatable')[]): ContentEntitySelection {
103
116
  const metaField = this.selectionSet.find((it): it is GraphQlField => it instanceof GraphQlField && it.name === '_meta')
104
117
  const selectionWithoutMeta = metaField ? this.selectionSet.filter(it => it !== metaField) : this.selectionSet
@@ -177,7 +190,7 @@ export class ContentEntitySelection {
177
190
  if (!nestedTransform) {
178
191
  return selectionWithField
179
192
  }
180
- return this.withFieldTransform(alias, it => it.map(nestedTransform))
193
+ return selectionWithField.withFieldTransform(alias, it => it.map(nestedTransform))
181
194
  }
182
195
 
183
196
 
@@ -229,7 +242,7 @@ export class ContentEntitySelection {
229
242
  if (!nestedTransform) {
230
243
  return selectionWithField
231
244
  }
232
- return this.withFieldTransform(alias, (it, ctx) => it !== null ? nestedTransform(it, ctx) : null)
245
+ return selectionWithField.withFieldTransform(alias, (it, ctx) => it !== null ? nestedTransform(it, ctx) : null)
233
246
  }
234
247
 
235
248
  private _one(
@@ -273,7 +286,7 @@ export class ContentEntitySelection {
273
286
  if (!nestedTransform) {
274
287
  return selectionWithField
275
288
  }
276
- return this.withFieldTransform(alias, (it, ctx) => it !== null ? nestedTransform(it, ctx) : null)
289
+ return selectionWithField.withFieldTransform(alias, (it, ctx) => it !== null ? nestedTransform(it, ctx) : null)
277
290
  }
278
291
 
279
292
 
@@ -26,6 +26,10 @@ export interface TypedEntitySelection<TSchema extends SchemaTypeLike, TEntityNam
26
26
  [key in TAlias extends null ? TKey : TAlias]: TypedEntitySelectionResult<TEntity, TKey, TNestedValue>
27
27
  }>
28
28
 
29
+ omit<TField extends keyof TValue>(
30
+ ...fields: TField[]
31
+ ): TypedEntitySelection<TSchema, TEntityName, TEntity, Omit<TValue, TField>>
32
+
29
33
 
30
34
  meta<
31
35
  TField extends (keyof TEntity['columns'] | keyof TEntity['hasMany'] | keyof TEntity['hasOne'])
@@ -1,26 +1,58 @@
1
1
  import { Result } from '@contember/schema'
2
2
 
3
- export type TransactionResult<V> = {
4
- readonly ok: boolean
5
- readonly errorMessage: string | null
3
+ export type TransactionOkResult<V> = {
4
+ readonly ok: true
5
+ readonly errorMessage: null
6
+ readonly errors: []
7
+ readonly validation: ValidationOkResult
8
+ readonly data: V
9
+ }
10
+ export type TransactionFailResult<V> = {
11
+ readonly ok: false
12
+ readonly errorMessage: string
6
13
  readonly errors: MutationError[]
7
14
  readonly validation: ValidationResult
8
15
  readonly data: V
9
16
  }
10
17
 
11
- export type MutationResult<Value = unknown> = {
18
+ export type TransactionResult<V> =
19
+ | TransactionOkResult<V>
20
+ | TransactionFailResult<V>
21
+
22
+ export type MutationOkResult<Value = unknown> = {
23
+ readonly ok: true
24
+ readonly errorMessage: null
25
+ readonly errors: []
26
+ readonly node: Value | null // still may be null
27
+ readonly validation: ValidationOkResult
28
+ }
29
+
30
+ export type MutationFailResult = {
12
31
  readonly ok: boolean
13
- readonly errorMessage: string | null
32
+ readonly errorMessage: string
14
33
  readonly errors: MutationError[]
15
- readonly node: Value | null
16
- readonly validation?: ValidationResult
34
+ readonly node: null
35
+ readonly validation: ValidationResult
17
36
  }
18
37
 
19
- export type ValidationResult = {
20
- readonly valid: boolean
38
+ export type MutationResult<Value = unknown> =
39
+ | MutationOkResult<Value>
40
+ | MutationFailResult
41
+
42
+ export type ValidationOkResult = {
43
+ readonly valid: true
44
+ readonly errors: []
45
+ }
46
+
47
+ export type ValidationFailResult = {
48
+ readonly valid: false
21
49
  readonly errors: ValidationError[]
22
50
  }
23
51
 
52
+ export type ValidationResult =
53
+ | ValidationOkResult
54
+ | ValidationFailResult
55
+
24
56
  export type ValidationError = {
25
57
  readonly path: Path
26
58
  readonly message: { text: string }
@@ -1196,3 +1196,201 @@ exports[`mutations in trx create trx 2`] = `
1196
1196
  "MutationTransactionOptions_0": {},
1197
1197
  }
1198
1198
  `;
1199
+
1200
+ exports[`mutations without trx mutate or fail 1`] = `
1201
+ "mutation($MutationTransactionOptions_0: MutationTransactionOptions, $AuthorCreateInput_1: AuthorCreateInput!) {
1202
+ mut: transaction(options: $MutationTransactionOptions_0) {
1203
+ ok
1204
+ errorMessage
1205
+ errors {
1206
+ ... MutationError
1207
+ }
1208
+ validation {
1209
+ ... ValidationResult
1210
+ }
1211
+ mut: createAuthor(data: $AuthorCreateInput_1) {
1212
+ ok
1213
+ errorMessage
1214
+ errors {
1215
+ ... MutationError
1216
+ }
1217
+ validation {
1218
+ ... ValidationResult
1219
+ }
1220
+ }
1221
+ }
1222
+ }
1223
+ fragment MutationError on _MutationError {
1224
+ paths {
1225
+ ... on _FieldPathFragment {
1226
+ field
1227
+ }
1228
+ ... on _IndexPathFragment {
1229
+ index
1230
+ alias
1231
+ }
1232
+ }
1233
+ message
1234
+ type
1235
+ }
1236
+ fragment ValidationResult on _ValidationResult {
1237
+ valid
1238
+ errors {
1239
+ path {
1240
+ ... on _FieldPathFragment {
1241
+ field
1242
+ }
1243
+ ... on _IndexPathFragment {
1244
+ index
1245
+ alias
1246
+ }
1247
+ }
1248
+ message {
1249
+ text
1250
+ }
1251
+ }
1252
+ }
1253
+ "
1254
+ `;
1255
+
1256
+ exports[`mutations without trx mutate or fail 2`] = `
1257
+ {
1258
+ "AuthorCreateInput_1": {
1259
+ "email": "xx@localhost",
1260
+ "name": "John",
1261
+ },
1262
+ "MutationTransactionOptions_0": {},
1263
+ }
1264
+ `;
1265
+
1266
+ exports[`mutations without trx mutate or fail - fail 1`] = `
1267
+ "mutation($MutationTransactionOptions_0: MutationTransactionOptions, $AuthorCreateInput_1: AuthorCreateInput!) {
1268
+ mut: transaction(options: $MutationTransactionOptions_0) {
1269
+ ok
1270
+ errorMessage
1271
+ errors {
1272
+ ... MutationError
1273
+ }
1274
+ validation {
1275
+ ... ValidationResult
1276
+ }
1277
+ mut: createAuthor(data: $AuthorCreateInput_1) {
1278
+ ok
1279
+ errorMessage
1280
+ errors {
1281
+ ... MutationError
1282
+ }
1283
+ validation {
1284
+ ... ValidationResult
1285
+ }
1286
+ }
1287
+ }
1288
+ }
1289
+ fragment MutationError on _MutationError {
1290
+ paths {
1291
+ ... on _FieldPathFragment {
1292
+ field
1293
+ }
1294
+ ... on _IndexPathFragment {
1295
+ index
1296
+ alias
1297
+ }
1298
+ }
1299
+ message
1300
+ type
1301
+ }
1302
+ fragment ValidationResult on _ValidationResult {
1303
+ valid
1304
+ errors {
1305
+ path {
1306
+ ... on _FieldPathFragment {
1307
+ field
1308
+ }
1309
+ ... on _IndexPathFragment {
1310
+ index
1311
+ alias
1312
+ }
1313
+ }
1314
+ message {
1315
+ text
1316
+ }
1317
+ }
1318
+ }
1319
+ "
1320
+ `;
1321
+
1322
+ exports[`mutations without trx mutate or fail - fail 2`] = `
1323
+ {
1324
+ "AuthorCreateInput_1": {
1325
+ "email": "xx@localhost",
1326
+ "name": "John",
1327
+ },
1328
+ "MutationTransactionOptions_0": {},
1329
+ }
1330
+ `;
1331
+
1332
+ exports[`mutations without trx mutate or fail - ok 1`] = `
1333
+ "mutation($MutationTransactionOptions_0: MutationTransactionOptions, $AuthorCreateInput_1: AuthorCreateInput!) {
1334
+ mut: transaction(options: $MutationTransactionOptions_0) {
1335
+ ok
1336
+ errorMessage
1337
+ errors {
1338
+ ... MutationError
1339
+ }
1340
+ validation {
1341
+ ... ValidationResult
1342
+ }
1343
+ mut: createAuthor(data: $AuthorCreateInput_1) {
1344
+ ok
1345
+ errorMessage
1346
+ errors {
1347
+ ... MutationError
1348
+ }
1349
+ validation {
1350
+ ... ValidationResult
1351
+ }
1352
+ }
1353
+ }
1354
+ }
1355
+ fragment MutationError on _MutationError {
1356
+ paths {
1357
+ ... on _FieldPathFragment {
1358
+ field
1359
+ }
1360
+ ... on _IndexPathFragment {
1361
+ index
1362
+ alias
1363
+ }
1364
+ }
1365
+ message
1366
+ type
1367
+ }
1368
+ fragment ValidationResult on _ValidationResult {
1369
+ valid
1370
+ errors {
1371
+ path {
1372
+ ... on _FieldPathFragment {
1373
+ field
1374
+ }
1375
+ ... on _IndexPathFragment {
1376
+ index
1377
+ alias
1378
+ }
1379
+ }
1380
+ message {
1381
+ text
1382
+ }
1383
+ }
1384
+ }
1385
+ "
1386
+ `;
1387
+
1388
+ exports[`mutations without trx mutate or fail - ok 2`] = `
1389
+ {
1390
+ "AuthorCreateInput_1": {
1391
+ "email": "xx@localhost",
1392
+ "name": "John",
1393
+ },
1394
+ "MutationTransactionOptions_0": {},
1395
+ }
1396
+ `;
@@ -100,3 +100,136 @@ exports[`queries get by id 1`] = `
100
100
  }
101
101
  "
102
102
  `;
103
+
104
+ exports[`queries nested has-many transform 1`] = `
105
+ [
106
+ {
107
+ "query":
108
+ "query($AuthorUniqueWhere_0: AuthorUniqueWhere!) {
109
+ author: getAuthor(by: $AuthorUniqueWhere_0) {
110
+ id
111
+ name
112
+ email
113
+ posts {
114
+ id
115
+ publishedAt
116
+ }
117
+ }
118
+ }
119
+ "
120
+ ,
121
+ "variables": {
122
+ "AuthorUniqueWhere_0": {
123
+ "id": "123",
124
+ },
125
+ },
126
+ },
127
+ ]
128
+ `;
129
+
130
+ exports[`queries top level list transform 1`] = `
131
+ [
132
+ {
133
+ "query":
134
+ "query {
135
+ authors: listAuthor {
136
+ id
137
+ name
138
+ email
139
+ }
140
+ }
141
+ "
142
+ ,
143
+ "variables": {},
144
+ },
145
+ ]
146
+ `;
147
+
148
+ exports[`queries top level get transform 1`] = `
149
+ [
150
+ {
151
+ "query":
152
+ "query($AuthorUniqueWhere_0: AuthorUniqueWhere!) {
153
+ author: getAuthor(by: $AuthorUniqueWhere_0) {
154
+ id
155
+ name
156
+ email
157
+ }
158
+ }
159
+ "
160
+ ,
161
+ "variables": {
162
+ "AuthorUniqueWhere_0": {
163
+ "id": "123",
164
+ },
165
+ },
166
+ },
167
+ ]
168
+ `;
169
+
170
+ exports[`queries nested has-one transform 1`] = `
171
+ [
172
+ {
173
+ "query":
174
+ "query($PostUniqueWhere_0: PostUniqueWhere!) {
175
+ post: getPost(by: $PostUniqueWhere_0) {
176
+ id
177
+ publishedAt
178
+ author {
179
+ id
180
+ name
181
+ email
182
+ }
183
+ }
184
+ }
185
+ "
186
+ ,
187
+ "variables": {
188
+ "PostUniqueWhere_0": {
189
+ "id": "123",
190
+ },
191
+ },
192
+ },
193
+ ]
194
+ `;
195
+
196
+ exports[`queries nested has-many-by transform 1`] = `
197
+ [
198
+ {
199
+ "query":
200
+ "query($PostUniqueWhere_0: PostUniqueWhere!, $PostLocalesByLocaleUniqueWhere_1: PostLocalesByLocaleUniqueWhere!) {
201
+ post: getPost(by: $PostUniqueWhere_0) {
202
+ id
203
+ publishedAt
204
+ localesByLocale(by: $PostLocalesByLocaleUniqueWhere_1) {
205
+ id
206
+ title
207
+ content
208
+ }
209
+ }
210
+ }
211
+ "
212
+ ,
213
+ "variables": {
214
+ "PostLocalesByLocaleUniqueWhere_1": {
215
+ "locale": {
216
+ "code": "en",
217
+ },
218
+ },
219
+ "PostUniqueWhere_0": {
220
+ "id": "123",
221
+ },
222
+ },
223
+ },
224
+ ]
225
+ `;
226
+
227
+ exports[`queries omit 1`] = `
228
+ "query {
229
+ authors: listAuthor {
230
+ id
231
+ name
232
+ }
233
+ }
234
+ "
235
+ `;
@@ -1,6 +1,7 @@
1
1
  import { describe, expect, test } from 'bun:test'
2
2
  import { createClient } from '../../lib'
3
3
  import { queryBuilder } from '../../client'
4
+ import { expectTypeOf } from 'expect-type'
4
5
 
5
6
  const qb = queryBuilder
6
7
  describe('mutations in trx', () => {
@@ -518,4 +519,52 @@ describe('mutations without trx', () => {
518
519
  expect(calls[0].variables).toMatchSnapshot()
519
520
  })
520
521
 
522
+ test('mutate or fail - fail', async () => {
523
+ const [client, calls] = createClient({
524
+ mut: {
525
+ ok: false,
526
+ errorMessage: 'some error',
527
+ mut: {
528
+ ok: false,
529
+ },
530
+ },
531
+ })
532
+ const createAuthor = qb.transaction(qb.create('Author', {
533
+ data: {
534
+ name: 'John',
535
+ email: 'xx@localhost',
536
+ },
537
+ }))
538
+ expect(() => client.mutateOrThrow(createAuthor)).toThrow('some error')
539
+ expect(calls).toHaveLength(1)
540
+ expect(calls[0].query).toMatchSnapshot()
541
+ expect(calls[0].variables).toMatchSnapshot()
542
+ })
543
+
544
+
545
+ test('mutate or fail - ok', async () => {
546
+ const [client, calls] = createClient({
547
+ mut: {
548
+ ok: true,
549
+ errorMessage: null,
550
+ mut: {
551
+ ok: true,
552
+ },
553
+ },
554
+ })
555
+ const createAuthor = qb.transaction(qb.create('Author', {
556
+ data: {
557
+ name: 'John',
558
+ email: 'xx@localhost',
559
+ },
560
+ }))
561
+ const result = await client.mutateOrThrow(createAuthor)
562
+ expect(result.ok).toBe(true)
563
+ const ok = result.ok
564
+ expectTypeOf(ok).toEqualTypeOf<true>()
565
+
566
+ expect(calls).toHaveLength(1)
567
+ expect(calls[0].query).toMatchSnapshot()
568
+ expect(calls[0].variables).toMatchSnapshot()
569
+ })
521
570
  })
@@ -255,6 +255,7 @@ describe('queries', () => {
255
255
  ],
256
256
  })
257
257
  expect(calls).toHaveLength(1)
258
+ expect(calls).toMatchSnapshot()
258
259
  })
259
260
 
260
261
  test('top level get transform', async () => {
@@ -281,6 +282,7 @@ describe('queries', () => {
281
282
  },
282
283
  })
283
284
  expect(calls).toHaveLength(1)
285
+ expect(calls).toMatchSnapshot()
284
286
  })
285
287
 
286
288
 
@@ -325,6 +327,7 @@ describe('queries', () => {
325
327
  },
326
328
  })
327
329
  expect(calls).toHaveLength(1)
330
+ expect(calls).toMatchSnapshot()
328
331
  })
329
332
 
330
333
 
@@ -362,6 +365,7 @@ describe('queries', () => {
362
365
  },
363
366
  },
364
367
  })
368
+ expect(calls).toMatchSnapshot()
365
369
  })
366
370
 
367
371
 
@@ -392,6 +396,7 @@ describe('queries', () => {
392
396
  },
393
397
  },
394
398
  })
399
+ expect(calls).toMatchSnapshot()
395
400
  })
396
401
 
397
402
  test('multiple transforms', async () => {
@@ -447,4 +452,29 @@ describe('queries', () => {
447
452
  expect(calls).toHaveLength(1)
448
453
  })
449
454
 
455
+ test('omit', async () => {
456
+ const [client, calls] = createClient({
457
+ authors: [
458
+ {
459
+ id: '1',
460
+ name: 'John',
461
+ },
462
+ ],
463
+ })
464
+ const result = await client.query({
465
+ authors: qb.list('Author', {}, it => it.$$().omit('email').$('posts', {}, it => it.$$()).omit('posts')),
466
+ })
467
+ expect(result).toStrictEqual({
468
+ authors: [
469
+ {
470
+ id: '1',
471
+ name: 'John',
472
+ },
473
+ ],
474
+ })
475
+ expect(calls).toHaveLength(1)
476
+ expect(calls[0].query).toMatchSnapshot()
477
+ expect(calls[0].variables).toStrictEqual({})
478
+ })
479
+
450
480
  })
@@ -142,4 +142,10 @@ describe('ts types', () => {
142
142
  )
143
143
  }).toThrow('Field Post.lorem does not exist.')
144
144
  })
145
+
146
+ test('omit', async () => {
147
+ const fragment = qb.fragment('Post', it => it.$$().omit('publishedAt'))
148
+ type fragmentType = FragmentType<typeof fragment>
149
+ expectTypeOf<fragmentType>().toEqualTypeOf<{ id: string }>()
150
+ })
145
151
  })