@directus/api 24.0.1 → 25.0.0

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 (85) hide show
  1. package/dist/app.js +10 -4
  2. package/dist/auth/drivers/oauth2.js +2 -3
  3. package/dist/auth/drivers/openid.js +2 -3
  4. package/dist/cache.d.ts +2 -2
  5. package/dist/cache.js +20 -7
  6. package/dist/controllers/assets.js +2 -2
  7. package/dist/controllers/metrics.d.ts +2 -0
  8. package/dist/controllers/metrics.js +33 -0
  9. package/dist/controllers/server.js +1 -1
  10. package/dist/database/helpers/number/dialects/mssql.d.ts +2 -2
  11. package/dist/database/helpers/number/dialects/mssql.js +3 -3
  12. package/dist/database/helpers/number/dialects/oracle.d.ts +2 -2
  13. package/dist/database/helpers/number/dialects/oracle.js +2 -2
  14. package/dist/database/helpers/number/dialects/sqlite.d.ts +2 -2
  15. package/dist/database/helpers/number/dialects/sqlite.js +2 -2
  16. package/dist/database/helpers/number/types.d.ts +2 -2
  17. package/dist/database/helpers/number/types.js +2 -2
  18. package/dist/database/index.js +3 -0
  19. package/dist/metrics/index.d.ts +1 -0
  20. package/dist/metrics/index.js +1 -0
  21. package/dist/metrics/lib/create-metrics.d.ts +15 -0
  22. package/dist/metrics/lib/create-metrics.js +239 -0
  23. package/dist/metrics/lib/use-metrics.d.ts +17 -0
  24. package/dist/metrics/lib/use-metrics.js +15 -0
  25. package/dist/metrics/types/metric.d.ts +1 -0
  26. package/dist/metrics/types/metric.js +1 -0
  27. package/dist/middleware/respond.js +7 -1
  28. package/dist/operations/condition/index.js +7 -2
  29. package/dist/schedules/metrics.d.ts +7 -0
  30. package/dist/schedules/metrics.js +44 -0
  31. package/dist/services/assets.d.ts +6 -1
  32. package/dist/services/assets.js +8 -6
  33. package/dist/services/fields.js +1 -1
  34. package/dist/services/graphql/errors/format.d.ts +6 -0
  35. package/dist/services/graphql/errors/format.js +14 -0
  36. package/dist/services/graphql/index.d.ts +5 -53
  37. package/dist/services/graphql/index.js +5 -2720
  38. package/dist/services/graphql/resolvers/mutation.d.ts +4 -0
  39. package/dist/services/graphql/resolvers/mutation.js +74 -0
  40. package/dist/services/graphql/resolvers/query.d.ts +8 -0
  41. package/dist/services/graphql/resolvers/query.js +87 -0
  42. package/dist/services/graphql/resolvers/system-admin.d.ts +5 -0
  43. package/dist/services/graphql/resolvers/system-admin.js +236 -0
  44. package/dist/services/graphql/resolvers/system-global.d.ts +7 -0
  45. package/dist/services/graphql/resolvers/system-global.js +435 -0
  46. package/dist/services/graphql/resolvers/system.d.ts +11 -0
  47. package/dist/services/graphql/resolvers/system.js +554 -0
  48. package/dist/services/graphql/schema/get-types.d.ts +12 -0
  49. package/dist/services/graphql/schema/get-types.js +223 -0
  50. package/dist/services/graphql/schema/index.d.ts +32 -0
  51. package/dist/services/graphql/schema/index.js +190 -0
  52. package/dist/services/graphql/schema/parse-args.d.ts +9 -0
  53. package/dist/services/graphql/schema/parse-args.js +35 -0
  54. package/dist/services/graphql/schema/parse-query.d.ts +7 -0
  55. package/dist/services/graphql/schema/parse-query.js +98 -0
  56. package/dist/services/graphql/schema/read.d.ts +12 -0
  57. package/dist/services/graphql/schema/read.js +653 -0
  58. package/dist/services/graphql/schema/write.d.ts +9 -0
  59. package/dist/services/graphql/schema/write.js +142 -0
  60. package/dist/services/graphql/subscription.d.ts +1 -1
  61. package/dist/services/graphql/subscription.js +7 -6
  62. package/dist/services/graphql/utils/aggrgate-query.d.ts +6 -0
  63. package/dist/services/graphql/utils/aggrgate-query.js +32 -0
  64. package/dist/services/graphql/utils/replace-fragments.d.ts +6 -0
  65. package/dist/services/graphql/utils/replace-fragments.js +21 -0
  66. package/dist/services/graphql/utils/replace-funcs.d.ts +5 -0
  67. package/dist/services/graphql/utils/replace-funcs.js +21 -0
  68. package/dist/services/graphql/utils/sanitize-gql-schema.d.ts +1 -1
  69. package/dist/services/graphql/utils/sanitize-gql-schema.js +5 -5
  70. package/dist/services/items.js +0 -2
  71. package/dist/services/meta.js +25 -84
  72. package/dist/services/users.d.ts +4 -0
  73. package/dist/services/users.js +23 -1
  74. package/dist/utils/apply-query.d.ts +1 -1
  75. package/dist/utils/apply-query.js +58 -21
  76. package/dist/utils/freeze-schema.d.ts +3 -0
  77. package/dist/utils/freeze-schema.js +31 -0
  78. package/dist/utils/get-accountability-for-token.js +1 -0
  79. package/dist/utils/get-milliseconds.js +1 -1
  80. package/dist/utils/get-schema.js +10 -5
  81. package/dist/utils/permissions-cachable.d.ts +8 -0
  82. package/dist/utils/permissions-cachable.js +38 -0
  83. package/dist/utils/sanitize-schema.d.ts +1 -1
  84. package/dist/websocket/messages.d.ts +6 -6
  85. package/package.json +22 -19
@@ -0,0 +1,653 @@
1
+ import { GraphQLBoolean, GraphQLFloat, GraphQLID, GraphQLInt, GraphQLList, GraphQLNonNull, GraphQLString, } from 'graphql';
2
+ import { GraphQLJSON, InputTypeComposer, ObjectTypeComposer } from 'graphql-compose';
3
+ import { getGraphQLType } from '../../../utils/get-graphql-type.js';
4
+ import { GraphQLService } from '../index.js';
5
+ import { resolveQuery } from '../resolvers/query.js';
6
+ import { createSubscriptionGenerator } from '../subscription.js';
7
+ import { GraphQLBigInt } from '../types/bigint.js';
8
+ import { GraphQLDate } from '../types/date.js';
9
+ import { GraphQLGeoJSON } from '../types/geojson.js';
10
+ import { GraphQLHash } from '../types/hash.js';
11
+ import { GraphQLStringOrFloat } from '../types/string-or-float.js';
12
+ import { SYSTEM_DENY_LIST } from './index.js';
13
+ import { getTypes } from './get-types.js';
14
+ /**
15
+ * Create readable types and attach resolvers for each. Also prepares full filter argument structures
16
+ */
17
+ export function getReadableTypes(gql, schemaComposer, schema, inconsistentFields) {
18
+ const { CollectionTypes: ReadCollectionTypes, VersionTypes: VersionCollectionTypes } = getTypes(schemaComposer, gql.scope, schema, inconsistentFields, 'read');
19
+ const ReadableCollectionFilterTypes = {};
20
+ const AggregatedFunctions = {};
21
+ const AggregatedFields = {};
22
+ const AggregateMethods = {};
23
+ const StringFilterOperators = schemaComposer.createInputTC({
24
+ name: 'string_filter_operators',
25
+ fields: {
26
+ _eq: {
27
+ type: GraphQLString,
28
+ },
29
+ _neq: {
30
+ type: GraphQLString,
31
+ },
32
+ _contains: {
33
+ type: GraphQLString,
34
+ },
35
+ _icontains: {
36
+ type: GraphQLString,
37
+ },
38
+ _ncontains: {
39
+ type: GraphQLString,
40
+ },
41
+ _starts_with: {
42
+ type: GraphQLString,
43
+ },
44
+ _nstarts_with: {
45
+ type: GraphQLString,
46
+ },
47
+ _istarts_with: {
48
+ type: GraphQLString,
49
+ },
50
+ _nistarts_with: {
51
+ type: GraphQLString,
52
+ },
53
+ _ends_with: {
54
+ type: GraphQLString,
55
+ },
56
+ _nends_with: {
57
+ type: GraphQLString,
58
+ },
59
+ _iends_with: {
60
+ type: GraphQLString,
61
+ },
62
+ _niends_with: {
63
+ type: GraphQLString,
64
+ },
65
+ _in: {
66
+ type: new GraphQLList(GraphQLString),
67
+ },
68
+ _nin: {
69
+ type: new GraphQLList(GraphQLString),
70
+ },
71
+ _null: {
72
+ type: GraphQLBoolean,
73
+ },
74
+ _nnull: {
75
+ type: GraphQLBoolean,
76
+ },
77
+ _empty: {
78
+ type: GraphQLBoolean,
79
+ },
80
+ _nempty: {
81
+ type: GraphQLBoolean,
82
+ },
83
+ },
84
+ });
85
+ const BooleanFilterOperators = schemaComposer.createInputTC({
86
+ name: 'boolean_filter_operators',
87
+ fields: {
88
+ _eq: {
89
+ type: GraphQLBoolean,
90
+ },
91
+ _neq: {
92
+ type: GraphQLBoolean,
93
+ },
94
+ _null: {
95
+ type: GraphQLBoolean,
96
+ },
97
+ _nnull: {
98
+ type: GraphQLBoolean,
99
+ },
100
+ },
101
+ });
102
+ const DateFilterOperators = schemaComposer.createInputTC({
103
+ name: 'date_filter_operators',
104
+ fields: {
105
+ _eq: {
106
+ type: GraphQLString,
107
+ },
108
+ _neq: {
109
+ type: GraphQLString,
110
+ },
111
+ _gt: {
112
+ type: GraphQLString,
113
+ },
114
+ _gte: {
115
+ type: GraphQLString,
116
+ },
117
+ _lt: {
118
+ type: GraphQLString,
119
+ },
120
+ _lte: {
121
+ type: GraphQLString,
122
+ },
123
+ _null: {
124
+ type: GraphQLBoolean,
125
+ },
126
+ _nnull: {
127
+ type: GraphQLBoolean,
128
+ },
129
+ _in: {
130
+ type: new GraphQLList(GraphQLString),
131
+ },
132
+ _nin: {
133
+ type: new GraphQLList(GraphQLString),
134
+ },
135
+ _between: {
136
+ type: new GraphQLList(GraphQLStringOrFloat),
137
+ },
138
+ _nbetween: {
139
+ type: new GraphQLList(GraphQLStringOrFloat),
140
+ },
141
+ },
142
+ });
143
+ // Uses StringOrFloat rather than Float to support api dynamic variables (like `$NOW`)
144
+ const NumberFilterOperators = schemaComposer.createInputTC({
145
+ name: 'number_filter_operators',
146
+ fields: {
147
+ _eq: {
148
+ type: GraphQLStringOrFloat,
149
+ },
150
+ _neq: {
151
+ type: GraphQLStringOrFloat,
152
+ },
153
+ _in: {
154
+ type: new GraphQLList(GraphQLStringOrFloat),
155
+ },
156
+ _nin: {
157
+ type: new GraphQLList(GraphQLStringOrFloat),
158
+ },
159
+ _gt: {
160
+ type: GraphQLStringOrFloat,
161
+ },
162
+ _gte: {
163
+ type: GraphQLStringOrFloat,
164
+ },
165
+ _lt: {
166
+ type: GraphQLStringOrFloat,
167
+ },
168
+ _lte: {
169
+ type: GraphQLStringOrFloat,
170
+ },
171
+ _null: {
172
+ type: GraphQLBoolean,
173
+ },
174
+ _nnull: {
175
+ type: GraphQLBoolean,
176
+ },
177
+ _between: {
178
+ type: new GraphQLList(GraphQLStringOrFloat),
179
+ },
180
+ _nbetween: {
181
+ type: new GraphQLList(GraphQLStringOrFloat),
182
+ },
183
+ },
184
+ });
185
+ const BigIntFilterOperators = schemaComposer.createInputTC({
186
+ name: 'big_int_filter_operators',
187
+ fields: {
188
+ _eq: {
189
+ type: GraphQLBigInt,
190
+ },
191
+ _neq: {
192
+ type: GraphQLBigInt,
193
+ },
194
+ _in: {
195
+ type: new GraphQLList(GraphQLBigInt),
196
+ },
197
+ _nin: {
198
+ type: new GraphQLList(GraphQLBigInt),
199
+ },
200
+ _gt: {
201
+ type: GraphQLBigInt,
202
+ },
203
+ _gte: {
204
+ type: GraphQLBigInt,
205
+ },
206
+ _lt: {
207
+ type: GraphQLBigInt,
208
+ },
209
+ _lte: {
210
+ type: GraphQLBigInt,
211
+ },
212
+ _null: {
213
+ type: GraphQLBoolean,
214
+ },
215
+ _nnull: {
216
+ type: GraphQLBoolean,
217
+ },
218
+ _between: {
219
+ type: new GraphQLList(GraphQLBigInt),
220
+ },
221
+ _nbetween: {
222
+ type: new GraphQLList(GraphQLBigInt),
223
+ },
224
+ },
225
+ });
226
+ const GeometryFilterOperators = schemaComposer.createInputTC({
227
+ name: 'geometry_filter_operators',
228
+ fields: {
229
+ _eq: {
230
+ type: GraphQLGeoJSON,
231
+ },
232
+ _neq: {
233
+ type: GraphQLGeoJSON,
234
+ },
235
+ _intersects: {
236
+ type: GraphQLGeoJSON,
237
+ },
238
+ _nintersects: {
239
+ type: GraphQLGeoJSON,
240
+ },
241
+ _intersects_bbox: {
242
+ type: GraphQLGeoJSON,
243
+ },
244
+ _nintersects_bbox: {
245
+ type: GraphQLGeoJSON,
246
+ },
247
+ _null: {
248
+ type: GraphQLBoolean,
249
+ },
250
+ _nnull: {
251
+ type: GraphQLBoolean,
252
+ },
253
+ },
254
+ });
255
+ const HashFilterOperators = schemaComposer.createInputTC({
256
+ name: 'hash_filter_operators',
257
+ fields: {
258
+ _null: {
259
+ type: GraphQLBoolean,
260
+ },
261
+ _nnull: {
262
+ type: GraphQLBoolean,
263
+ },
264
+ _empty: {
265
+ type: GraphQLBoolean,
266
+ },
267
+ _nempty: {
268
+ type: GraphQLBoolean,
269
+ },
270
+ },
271
+ });
272
+ const CountFunctionFilterOperators = schemaComposer.createInputTC({
273
+ name: 'count_function_filter_operators',
274
+ fields: {
275
+ count: {
276
+ type: NumberFilterOperators,
277
+ },
278
+ },
279
+ });
280
+ const DateFunctionFilterOperators = schemaComposer.createInputTC({
281
+ name: 'date_function_filter_operators',
282
+ fields: {
283
+ year: {
284
+ type: NumberFilterOperators,
285
+ },
286
+ month: {
287
+ type: NumberFilterOperators,
288
+ },
289
+ week: {
290
+ type: NumberFilterOperators,
291
+ },
292
+ day: {
293
+ type: NumberFilterOperators,
294
+ },
295
+ weekday: {
296
+ type: NumberFilterOperators,
297
+ },
298
+ },
299
+ });
300
+ const TimeFunctionFilterOperators = schemaComposer.createInputTC({
301
+ name: 'time_function_filter_operators',
302
+ fields: {
303
+ hour: {
304
+ type: NumberFilterOperators,
305
+ },
306
+ minute: {
307
+ type: NumberFilterOperators,
308
+ },
309
+ second: {
310
+ type: NumberFilterOperators,
311
+ },
312
+ },
313
+ });
314
+ const DateTimeFunctionFilterOperators = schemaComposer.createInputTC({
315
+ name: 'datetime_function_filter_operators',
316
+ fields: {
317
+ ...DateFunctionFilterOperators.getFields(),
318
+ ...TimeFunctionFilterOperators.getFields(),
319
+ },
320
+ });
321
+ const subscriptionEventType = schemaComposer.createEnumTC({
322
+ name: 'EventEnum',
323
+ values: {
324
+ create: { value: 'create' },
325
+ update: { value: 'update' },
326
+ delete: { value: 'delete' },
327
+ },
328
+ });
329
+ for (const collection of Object.values(schema.read.collections)) {
330
+ if (Object.keys(collection.fields).length === 0)
331
+ continue;
332
+ if (SYSTEM_DENY_LIST.includes(collection.collection))
333
+ continue;
334
+ ReadableCollectionFilterTypes[collection.collection] = schemaComposer.createInputTC({
335
+ name: `${collection.collection}_filter`,
336
+ fields: Object.values(collection.fields).reduce((acc, field) => {
337
+ const graphqlType = getGraphQLType(field.type, field.special);
338
+ let filterOperatorType;
339
+ switch (graphqlType) {
340
+ case GraphQLBoolean:
341
+ filterOperatorType = BooleanFilterOperators;
342
+ break;
343
+ case GraphQLBigInt:
344
+ filterOperatorType = BigIntFilterOperators;
345
+ break;
346
+ case GraphQLInt:
347
+ case GraphQLFloat:
348
+ filterOperatorType = NumberFilterOperators;
349
+ break;
350
+ case GraphQLDate:
351
+ filterOperatorType = DateFilterOperators;
352
+ break;
353
+ case GraphQLGeoJSON:
354
+ filterOperatorType = GeometryFilterOperators;
355
+ break;
356
+ case GraphQLHash:
357
+ filterOperatorType = HashFilterOperators;
358
+ break;
359
+ default:
360
+ filterOperatorType = StringFilterOperators;
361
+ }
362
+ acc[field.field] = filterOperatorType;
363
+ if (field.type === 'date') {
364
+ acc[`${field.field}_func`] = {
365
+ type: DateFunctionFilterOperators,
366
+ };
367
+ }
368
+ if (field.type === 'time') {
369
+ acc[`${field.field}_func`] = {
370
+ type: TimeFunctionFilterOperators,
371
+ };
372
+ }
373
+ if (field.type === 'dateTime' || field.type === 'timestamp') {
374
+ acc[`${field.field}_func`] = {
375
+ type: DateTimeFunctionFilterOperators,
376
+ };
377
+ }
378
+ if (field.type === 'json' || field.type === 'alias') {
379
+ acc[`${field.field}_func`] = {
380
+ type: CountFunctionFilterOperators,
381
+ };
382
+ }
383
+ return acc;
384
+ }, {}),
385
+ });
386
+ ReadableCollectionFilterTypes[collection.collection].addFields({
387
+ _and: [ReadableCollectionFilterTypes[collection.collection]],
388
+ _or: [ReadableCollectionFilterTypes[collection.collection]],
389
+ });
390
+ AggregatedFields[collection.collection] = schemaComposer.createObjectTC({
391
+ name: `${collection.collection}_aggregated_fields`,
392
+ fields: Object.values(collection.fields).reduce((acc, field) => {
393
+ const graphqlType = getGraphQLType(field.type, field.special);
394
+ switch (graphqlType) {
395
+ case GraphQLBigInt:
396
+ case GraphQLInt:
397
+ case GraphQLFloat:
398
+ acc[field.field] = {
399
+ type: GraphQLFloat,
400
+ description: field.note,
401
+ };
402
+ break;
403
+ default:
404
+ break;
405
+ }
406
+ return acc;
407
+ }, {}),
408
+ });
409
+ const countType = schemaComposer.createObjectTC({
410
+ name: `${collection.collection}_aggregated_count`,
411
+ fields: Object.values(collection.fields).reduce((acc, field) => {
412
+ acc[field.field] = {
413
+ type: GraphQLInt,
414
+ description: field.note,
415
+ };
416
+ return acc;
417
+ }, {}),
418
+ });
419
+ AggregateMethods[collection.collection] = {
420
+ group: {
421
+ name: 'group',
422
+ type: GraphQLJSON,
423
+ },
424
+ countAll: {
425
+ name: 'countAll',
426
+ type: GraphQLInt,
427
+ },
428
+ count: {
429
+ name: 'count',
430
+ type: countType,
431
+ },
432
+ countDistinct: {
433
+ name: 'countDistinct',
434
+ type: countType,
435
+ },
436
+ };
437
+ const hasNumericAggregates = Object.values(collection.fields).some((field) => {
438
+ const graphqlType = getGraphQLType(field.type, field.special);
439
+ if (graphqlType === GraphQLInt || graphqlType === GraphQLFloat) {
440
+ return true;
441
+ }
442
+ return false;
443
+ });
444
+ if (hasNumericAggregates) {
445
+ Object.assign(AggregateMethods[collection.collection], {
446
+ avg: {
447
+ name: 'avg',
448
+ type: AggregatedFields[collection.collection],
449
+ },
450
+ sum: {
451
+ name: 'sum',
452
+ type: AggregatedFields[collection.collection],
453
+ },
454
+ avgDistinct: {
455
+ name: 'avgDistinct',
456
+ type: AggregatedFields[collection.collection],
457
+ },
458
+ sumDistinct: {
459
+ name: 'sumDistinct',
460
+ type: AggregatedFields[collection.collection],
461
+ },
462
+ min: {
463
+ name: 'min',
464
+ type: AggregatedFields[collection.collection],
465
+ },
466
+ max: {
467
+ name: 'max',
468
+ type: AggregatedFields[collection.collection],
469
+ },
470
+ });
471
+ }
472
+ AggregatedFunctions[collection.collection] = schemaComposer.createObjectTC({
473
+ name: `${collection.collection}_aggregated`,
474
+ fields: AggregateMethods[collection.collection],
475
+ });
476
+ const resolver = {
477
+ name: collection.collection,
478
+ type: collection.singleton
479
+ ? ReadCollectionTypes[collection.collection]
480
+ : new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(ReadCollectionTypes[collection.collection].getType()))),
481
+ resolve: async ({ info, context }) => {
482
+ const result = await resolveQuery(gql, info);
483
+ context['data'] = result;
484
+ return result;
485
+ },
486
+ };
487
+ if (collection.singleton === false) {
488
+ resolver.args = {
489
+ filter: ReadableCollectionFilterTypes[collection.collection],
490
+ sort: {
491
+ type: new GraphQLList(GraphQLString),
492
+ },
493
+ limit: {
494
+ type: GraphQLInt,
495
+ },
496
+ offset: {
497
+ type: GraphQLInt,
498
+ },
499
+ page: {
500
+ type: GraphQLInt,
501
+ },
502
+ search: {
503
+ type: GraphQLString,
504
+ },
505
+ };
506
+ }
507
+ else {
508
+ resolver.args = {
509
+ version: GraphQLString,
510
+ };
511
+ }
512
+ ReadCollectionTypes[collection.collection].addResolver(resolver);
513
+ ReadCollectionTypes[collection.collection].addResolver({
514
+ name: `${collection.collection}_aggregated`,
515
+ type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(AggregatedFunctions[collection.collection].getType()))),
516
+ args: {
517
+ groupBy: new GraphQLList(GraphQLString),
518
+ filter: ReadableCollectionFilterTypes[collection.collection],
519
+ limit: {
520
+ type: GraphQLInt,
521
+ },
522
+ offset: {
523
+ type: GraphQLInt,
524
+ },
525
+ page: {
526
+ type: GraphQLInt,
527
+ },
528
+ search: {
529
+ type: GraphQLString,
530
+ },
531
+ sort: {
532
+ type: new GraphQLList(GraphQLString),
533
+ },
534
+ },
535
+ resolve: async ({ info, context }) => {
536
+ const result = await resolveQuery(gql, info);
537
+ context['data'] = result;
538
+ return result;
539
+ },
540
+ });
541
+ if (collection.singleton === false) {
542
+ ReadCollectionTypes[collection.collection].addResolver({
543
+ name: `${collection.collection}_by_id`,
544
+ type: ReadCollectionTypes[collection.collection],
545
+ args: {
546
+ id: new GraphQLNonNull(GraphQLID),
547
+ version: GraphQLString,
548
+ },
549
+ resolve: async ({ info, context }) => {
550
+ const result = await resolveQuery(gql, info);
551
+ context['data'] = result;
552
+ return result;
553
+ },
554
+ });
555
+ }
556
+ if (gql.scope === 'items') {
557
+ VersionCollectionTypes[collection.collection].addResolver({
558
+ name: `${collection.collection}_by_version`,
559
+ type: VersionCollectionTypes[collection.collection],
560
+ args: collection.singleton
561
+ ? { version: new GraphQLNonNull(GraphQLString) }
562
+ : {
563
+ version: new GraphQLNonNull(GraphQLString),
564
+ id: new GraphQLNonNull(GraphQLID),
565
+ },
566
+ resolve: async ({ info, context }) => {
567
+ const result = await resolveQuery(gql, info);
568
+ context['data'] = result;
569
+ return result;
570
+ },
571
+ });
572
+ }
573
+ const eventName = `${collection.collection}_mutated`;
574
+ if (collection.collection in ReadCollectionTypes) {
575
+ const subscriptionType = schemaComposer.createObjectTC({
576
+ name: eventName,
577
+ fields: {
578
+ key: new GraphQLNonNull(GraphQLID),
579
+ event: subscriptionEventType,
580
+ data: ReadCollectionTypes[collection.collection],
581
+ },
582
+ });
583
+ schemaComposer.Subscription.addFields({
584
+ [eventName]: {
585
+ type: subscriptionType,
586
+ args: {
587
+ event: subscriptionEventType,
588
+ },
589
+ subscribe: createSubscriptionGenerator(gql, eventName),
590
+ },
591
+ });
592
+ }
593
+ }
594
+ for (const relation of schema.read.relations) {
595
+ if (relation.related_collection) {
596
+ if (SYSTEM_DENY_LIST.includes(relation.related_collection))
597
+ continue;
598
+ ReadableCollectionFilterTypes[relation.collection]?.addFields({
599
+ [relation.field]: ReadableCollectionFilterTypes[relation.related_collection],
600
+ });
601
+ ReadCollectionTypes[relation.collection]?.addFieldArgs(relation.field, {
602
+ filter: ReadableCollectionFilterTypes[relation.related_collection],
603
+ sort: {
604
+ type: new GraphQLList(GraphQLString),
605
+ },
606
+ limit: {
607
+ type: GraphQLInt,
608
+ },
609
+ offset: {
610
+ type: GraphQLInt,
611
+ },
612
+ page: {
613
+ type: GraphQLInt,
614
+ },
615
+ search: {
616
+ type: GraphQLString,
617
+ },
618
+ });
619
+ if (relation.meta?.one_field) {
620
+ ReadableCollectionFilterTypes[relation.related_collection]?.addFields({
621
+ [relation.meta.one_field]: ReadableCollectionFilterTypes[relation.collection],
622
+ });
623
+ ReadCollectionTypes[relation.related_collection]?.addFieldArgs(relation.meta.one_field, {
624
+ filter: ReadableCollectionFilterTypes[relation.collection],
625
+ sort: {
626
+ type: new GraphQLList(GraphQLString),
627
+ },
628
+ limit: {
629
+ type: GraphQLInt,
630
+ },
631
+ offset: {
632
+ type: GraphQLInt,
633
+ },
634
+ page: {
635
+ type: GraphQLInt,
636
+ },
637
+ search: {
638
+ type: GraphQLString,
639
+ },
640
+ });
641
+ }
642
+ }
643
+ else if (relation.meta?.one_allowed_collections) {
644
+ ReadableCollectionFilterTypes[relation.collection]?.removeField('item');
645
+ for (const collection of relation.meta.one_allowed_collections) {
646
+ ReadableCollectionFilterTypes[relation.collection]?.addFields({
647
+ [`item__${collection}`]: ReadableCollectionFilterTypes[collection],
648
+ });
649
+ }
650
+ }
651
+ }
652
+ return { ReadCollectionTypes, VersionCollectionTypes, ReadableCollectionFilterTypes };
653
+ }
@@ -0,0 +1,9 @@
1
+ import type { SchemaComposer } from 'graphql-compose';
2
+ import { ObjectTypeComposer } from 'graphql-compose';
3
+ import { GraphQLService } from '../index.js';
4
+ import { type InconsistentFields, type Schema } from './index.js';
5
+ export declare function getWritableTypes(gql: GraphQLService, schemaComposer: SchemaComposer, schema: Schema, inconsistentFields: InconsistentFields, ReadCollectionTypes: Record<string, ObjectTypeComposer<any, any>>): {
6
+ CreateCollectionTypes: Record<string, ObjectTypeComposer<any, any>>;
7
+ UpdateCollectionTypes: Record<string, ObjectTypeComposer<any, any>>;
8
+ DeleteCollectionTypes: Record<string, ObjectTypeComposer<any, any>>;
9
+ };