@kyro-cms/core 0.9.7 → 0.9.8
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/dist/{WebhookService-BKszZlG0.d.cts → WebhookService-Dj8pJ3sp.d.cts} +1 -1
- package/dist/{WebhookService-Ccf1j-IN.d.ts → WebhookService-DpRB940h.d.ts} +1 -1
- package/dist/api-handler-graphql.cjs +11 -11
- package/dist/api-handler-graphql.js +7 -7
- package/dist/api-handler-trpc.cjs +9 -9
- package/dist/api-handler-trpc.js +7 -7
- package/dist/api-handler.cjs +10 -10
- package/dist/api-handler.js +7 -7
- package/dist/{base-CIuXkrH4.d.cts → base-BjyoF6da.d.cts} +2 -2
- package/dist/{base-fFo4lqER.d.ts → base-C2YR8lWt.d.ts} +2 -2
- package/dist/{chunk-QVJNSAQL.cjs → chunk-2CBCU5ML.cjs} +47 -41
- package/dist/chunk-2CBCU5ML.cjs.map +1 -0
- package/dist/{chunk-NZEUU7QB.js → chunk-2GXALYKV.js} +2 -2
- package/dist/chunk-2GXALYKV.js.map +1 -0
- package/dist/{chunk-3UK5XBVJ.js → chunk-2Z7YAJBS.js} +10 -9
- package/dist/chunk-2Z7YAJBS.js.map +1 -0
- package/dist/{chunk-QX3WNQ7V.js → chunk-65DSXNQL.js} +4 -4
- package/dist/{chunk-QX3WNQ7V.js.map → chunk-65DSXNQL.js.map} +1 -1
- package/dist/{chunk-PONTBXR5.js → chunk-6DURKQ6W.js} +370 -140
- package/dist/chunk-6DURKQ6W.js.map +1 -0
- package/dist/{chunk-AX2TZRQJ.js → chunk-EQTMBMDR.js} +3 -3
- package/dist/{chunk-AX2TZRQJ.js.map → chunk-EQTMBMDR.js.map} +1 -1
- package/dist/{chunk-E5UJBLQ7.js → chunk-FIAMXNTH.js} +2 -2
- package/dist/chunk-FIAMXNTH.js.map +1 -0
- package/dist/{chunk-VLK5SJRI.js → chunk-HA4MGAZJ.js} +28 -22
- package/dist/chunk-HA4MGAZJ.js.map +1 -0
- package/dist/{chunk-FKKQUMXR.cjs → chunk-KGJRJ7CU.cjs} +2 -2
- package/dist/chunk-KGJRJ7CU.cjs.map +1 -0
- package/dist/{chunk-FSKONGCX.cjs → chunk-OJ2AM75W.cjs} +2 -2
- package/dist/chunk-OJ2AM75W.cjs.map +1 -0
- package/dist/{chunk-DRVOUQMT.cjs → chunk-OVZO4KB6.cjs} +45 -79
- package/dist/chunk-OVZO4KB6.cjs.map +1 -0
- package/dist/{chunk-RRKCIAPU.cjs → chunk-PF642V5O.cjs} +372 -140
- package/dist/chunk-PF642V5O.cjs.map +1 -0
- package/dist/{chunk-OZ3CCTTA.cjs → chunk-PJ7F4TCC.cjs} +5 -5
- package/dist/{chunk-OZ3CCTTA.cjs.map → chunk-PJ7F4TCC.cjs.map} +1 -1
- package/dist/{chunk-HVCUIII2.cjs → chunk-W3GT55TY.cjs} +13 -13
- package/dist/{chunk-HVCUIII2.cjs.map → chunk-W3GT55TY.cjs.map} +1 -1
- package/dist/{chunk-QFLB4EIJ.cjs → chunk-Z7OH3MWT.cjs} +10 -9
- package/dist/chunk-Z7OH3MWT.cjs.map +1 -0
- package/dist/{chunk-CMXVTUYV.js → chunk-ZFHTJ2YX.js} +29 -63
- package/dist/chunk-ZFHTJ2YX.js.map +1 -0
- package/dist/client.cjs +3 -3
- package/dist/client.d.cts +2 -2
- package/dist/client.d.ts +2 -2
- package/dist/client.js +1 -1
- package/dist/drizzle/index.d.cts +3 -3
- package/dist/drizzle/index.d.ts +3 -3
- package/dist/fields/index.cjs +21 -21
- package/dist/fields/index.d.cts +1 -1
- package/dist/fields/index.d.ts +1 -1
- package/dist/fields/index.js +1 -1
- package/dist/graphql/index.cjs +13 -5
- package/dist/graphql/index.d.cts +34 -12
- package/dist/graphql/index.d.ts +34 -12
- package/dist/graphql/index.js +2 -2
- package/dist/{index-BKta3cBH.d.cts → index-DHbywDs-.d.cts} +2 -2
- package/dist/{index-ClOqnkTO.d.ts → index-jLs0zlft.d.ts} +2 -2
- package/dist/index.cjs +90 -90
- package/dist/index.d.cts +9 -9
- package/dist/index.d.ts +9 -9
- package/dist/index.js +8 -8
- package/dist/mongodb/index.d.cts +3 -3
- package/dist/mongodb/index.d.ts +3 -3
- package/dist/rest/index.cjs +5 -5
- package/dist/rest/index.d.cts +4 -4
- package/dist/rest/index.d.ts +4 -4
- package/dist/rest/index.js +3 -3
- package/dist/templates/index.d.cts +2 -2
- package/dist/templates/index.d.ts +2 -2
- package/dist/trpc/index.cjs +12 -12
- package/dist/trpc/index.d.cts +3 -3
- package/dist/trpc/index.d.ts +3 -3
- package/dist/trpc/index.js +3 -3
- package/dist/{types-Dgzlftb7.d.ts → types-BzH3_rtP.d.ts} +7 -7
- package/dist/{types-Ds0tCA3L.d.cts → types-CY_iNunL.d.cts} +7 -7
- package/dist/{types-DeSApf9T.d.ts → types-C_rVxU2T.d.cts} +4 -4
- package/dist/{types-DeSApf9T.d.cts → types-C_rVxU2T.d.ts} +4 -4
- package/package.json +2 -1
- package/dist/chunk-3UK5XBVJ.js.map +0 -1
- package/dist/chunk-CMXVTUYV.js.map +0 -1
- package/dist/chunk-DRVOUQMT.cjs.map +0 -1
- package/dist/chunk-E5UJBLQ7.js.map +0 -1
- package/dist/chunk-FKKQUMXR.cjs.map +0 -1
- package/dist/chunk-FSKONGCX.cjs.map +0 -1
- package/dist/chunk-NZEUU7QB.js.map +0 -1
- package/dist/chunk-PONTBXR5.js.map +0 -1
- package/dist/chunk-QFLB4EIJ.cjs.map +0 -1
- package/dist/chunk-QVJNSAQL.cjs.map +0 -1
- package/dist/chunk-RRKCIAPU.cjs.map +0 -1
- package/dist/chunk-VLK5SJRI.js.map +0 -1
|
@@ -1,7 +1,22 @@
|
|
|
1
|
-
import { checkCollectionAccess, checkGlobalAccess } from './chunk-
|
|
2
|
-
import { GraphQLObjectType, GraphQLString, GraphQLInputObjectType, GraphQLBoolean, GraphQLInt, GraphQLList,
|
|
1
|
+
import { checkCollectionAccess, checkGlobalAccess } from './chunk-2GXALYKV.js';
|
|
2
|
+
import { GraphQLError, GraphQLObjectType, GraphQLString, GraphQLNonNull, GraphQLInputObjectType, GraphQLBoolean, GraphQLInt, GraphQLList, GraphQLDirective, DirectiveLocation, printSchema, GraphQLSchema, GraphQLUnionType, GraphQLFloat, GraphQLEnumType } from 'graphql';
|
|
3
3
|
export { printSchema } from 'graphql';
|
|
4
4
|
|
|
5
|
+
function toPascalCase(slug) {
|
|
6
|
+
return slug.split(/[-_]/).map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("");
|
|
7
|
+
}
|
|
8
|
+
function toCamelCase(slug) {
|
|
9
|
+
const p = toPascalCase(slug);
|
|
10
|
+
return p.charAt(0).toLowerCase() + p.slice(1);
|
|
11
|
+
}
|
|
12
|
+
function toPascalSingular(slug) {
|
|
13
|
+
const p = toPascalCase(slug);
|
|
14
|
+
if (p.endsWith("s") && p.length > 1) return p.slice(0, -1);
|
|
15
|
+
return p;
|
|
16
|
+
}
|
|
17
|
+
function toCamelSingular(slug) {
|
|
18
|
+
return toCamelCase(slug).endsWith("s") && slug.length > 1 ? toCamelCase(slug).slice(0, -1) : toCamelCase(slug);
|
|
19
|
+
}
|
|
5
20
|
var RelationLoader = class {
|
|
6
21
|
db;
|
|
7
22
|
tenantID;
|
|
@@ -68,6 +83,24 @@ function gqlError(message, code) {
|
|
|
68
83
|
err.extensions = { code };
|
|
69
84
|
return err;
|
|
70
85
|
}
|
|
86
|
+
function depthLimit(maxDepth) {
|
|
87
|
+
return (validationContext) => {
|
|
88
|
+
let depth = 0;
|
|
89
|
+
return {
|
|
90
|
+
Field() {
|
|
91
|
+
depth++;
|
|
92
|
+
if (depth > maxDepth) {
|
|
93
|
+
validationContext.reportError(
|
|
94
|
+
new GraphQLError(`Query exceeds max depth of ${maxDepth}`)
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
leaveField() {
|
|
99
|
+
depth--;
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
}
|
|
71
104
|
async function checkAccess(config, operation, context) {
|
|
72
105
|
const result = await checkCollectionAccess(config, operation, context);
|
|
73
106
|
if (!result.allowed) {
|
|
@@ -81,7 +114,7 @@ async function checkGqlGlobalAccess(config, operation, context) {
|
|
|
81
114
|
throw gqlError(result.error || "Access denied", "FORBIDDEN");
|
|
82
115
|
}
|
|
83
116
|
}
|
|
84
|
-
function fieldToGraphQLType(field, registry, collectionTypes, isInputType = false
|
|
117
|
+
function fieldToGraphQLType(field, registry, collectionTypes, isInputType = false) {
|
|
85
118
|
switch (field.type) {
|
|
86
119
|
case "text":
|
|
87
120
|
case "email":
|
|
@@ -119,9 +152,8 @@ function fieldToGraphQLType(field, registry, collectionTypes, isInputType = fals
|
|
|
119
152
|
}
|
|
120
153
|
const relatedCollection = registry.getCollection(field.relationTo);
|
|
121
154
|
if (relatedCollection) {
|
|
122
|
-
const refName = `${field.relationTo.replace(/-/g, "_")}_ref`;
|
|
123
155
|
const refType = new GraphQLObjectType({
|
|
124
|
-
name:
|
|
156
|
+
name: toPascalSingular(field.relationTo),
|
|
125
157
|
fields: () => ({
|
|
126
158
|
id: { type: GraphQLString },
|
|
127
159
|
...buildFieldsFromCollection(relatedCollection, registry, collectionTypes)
|
|
@@ -138,21 +170,35 @@ function fieldToGraphQLType(field, registry, collectionTypes, isInputType = fals
|
|
|
138
170
|
}
|
|
139
171
|
return field.hasMany ? new GraphQLList(GraphQLString) : GraphQLString;
|
|
140
172
|
case "array": {
|
|
141
|
-
if (isInputType)
|
|
173
|
+
if (isInputType) {
|
|
174
|
+
const arrFields2 = field.fields;
|
|
175
|
+
if (arrFields2 && arrFields2.length > 0) {
|
|
176
|
+
const arrTypeName = `${field.name?.replace(/-/g, "_") || "array"}_input_item`;
|
|
177
|
+
return new GraphQLList(fieldsToGraphQLInputObjectType(arrTypeName, arrFields2, registry));
|
|
178
|
+
}
|
|
179
|
+
return new GraphQLList(GraphQLString);
|
|
180
|
+
}
|
|
142
181
|
const arrFields = field.fields;
|
|
143
182
|
if (arrFields && arrFields.length > 0) {
|
|
144
183
|
const arrTypeName = `${field.name?.replace(/-/g, "_") || "array"}_item`;
|
|
145
|
-
const itemType = fieldsToGraphQLObjectType(arrTypeName, arrFields, registry, collectionTypes
|
|
184
|
+
const itemType = fieldsToGraphQLObjectType(arrTypeName, arrFields, registry, collectionTypes);
|
|
146
185
|
return new GraphQLList(itemType);
|
|
147
186
|
}
|
|
148
187
|
return new GraphQLList(GraphQLString);
|
|
149
188
|
}
|
|
150
189
|
case "group": {
|
|
151
|
-
if (isInputType)
|
|
190
|
+
if (isInputType) {
|
|
191
|
+
const groupFields2 = field.fields;
|
|
192
|
+
if (groupFields2 && groupFields2.length > 0) {
|
|
193
|
+
const groupTypeName = `${field.name?.replace(/-/g, "_") || "group"}_input_group`;
|
|
194
|
+
return fieldsToGraphQLInputObjectType(groupTypeName, groupFields2, registry);
|
|
195
|
+
}
|
|
196
|
+
return GraphQLString;
|
|
197
|
+
}
|
|
152
198
|
const groupFields = field.fields;
|
|
153
199
|
if (groupFields && groupFields.length > 0) {
|
|
154
200
|
const groupTypeName = `${field.name?.replace(/-/g, "_") || "group"}_group`;
|
|
155
|
-
return fieldsToGraphQLObjectType(groupTypeName, groupFields, registry, collectionTypes
|
|
201
|
+
return fieldsToGraphQLObjectType(groupTypeName, groupFields, registry, collectionTypes);
|
|
156
202
|
}
|
|
157
203
|
return GraphQLString;
|
|
158
204
|
}
|
|
@@ -162,7 +208,7 @@ function fieldToGraphQLType(field, registry, collectionTypes, isInputType = fals
|
|
|
162
208
|
if (blocks && blocks.length > 0) {
|
|
163
209
|
const blockTypes = [];
|
|
164
210
|
for (const block of blocks) {
|
|
165
|
-
const blockTypeName = `
|
|
211
|
+
const blockTypeName = `Block${toPascalCase(block.slug)}`;
|
|
166
212
|
const bType = new GraphQLObjectType({
|
|
167
213
|
name: blockTypeName,
|
|
168
214
|
fields: () => {
|
|
@@ -173,7 +219,7 @@ function fieldToGraphQLType(field, registry, collectionTypes, isInputType = fals
|
|
|
173
219
|
if (block.fields) {
|
|
174
220
|
for (const bf of block.fields) {
|
|
175
221
|
if (!bf.name) continue;
|
|
176
|
-
const bfConfig = buildFieldConfig(bf, registry, collectionTypes
|
|
222
|
+
const bfConfig = buildFieldConfig(bf, registry, collectionTypes);
|
|
177
223
|
if (bfConfig) out[bf.name] = bfConfig;
|
|
178
224
|
}
|
|
179
225
|
}
|
|
@@ -188,7 +234,7 @@ function fieldToGraphQLType(field, registry, collectionTypes, isInputType = fals
|
|
|
188
234
|
name: unionName,
|
|
189
235
|
types: blockTypes,
|
|
190
236
|
resolveType(value) {
|
|
191
|
-
const blockName = `
|
|
237
|
+
const blockName = `Block${value?.blockType ? toPascalCase(value.blockType) : ""}`;
|
|
192
238
|
const blockType = blockTypes.find(
|
|
193
239
|
(bt) => bt.name === blockName
|
|
194
240
|
);
|
|
@@ -207,11 +253,11 @@ function fieldToGraphQLType(field, registry, collectionTypes, isInputType = fals
|
|
|
207
253
|
return GraphQLString;
|
|
208
254
|
}
|
|
209
255
|
}
|
|
210
|
-
function buildFieldsFromCollection(config, registry, collectionTypes
|
|
256
|
+
function buildFieldsFromCollection(config, registry, collectionTypes) {
|
|
211
257
|
const fields = {};
|
|
212
258
|
for (const field of config.fields) {
|
|
213
259
|
if (field.name && field.admin?.hidden !== true) {
|
|
214
|
-
const fc = buildFieldConfig(field, registry, collectionTypes
|
|
260
|
+
const fc = buildFieldConfig(field, registry, collectionTypes);
|
|
215
261
|
if (fc) fields[field.name] = fc;
|
|
216
262
|
}
|
|
217
263
|
}
|
|
@@ -231,7 +277,7 @@ function buildSortEnum(config) {
|
|
|
231
277
|
}
|
|
232
278
|
}
|
|
233
279
|
return new GraphQLEnumType({
|
|
234
|
-
name: `${config.slug
|
|
280
|
+
name: `${toPascalSingular(config.slug)}Sort`,
|
|
235
281
|
values: sortFields
|
|
236
282
|
});
|
|
237
283
|
}
|
|
@@ -329,7 +375,7 @@ function buildCollectionFilterType(config, namePrefix) {
|
|
|
329
375
|
}
|
|
330
376
|
}
|
|
331
377
|
return new GraphQLInputObjectType({
|
|
332
|
-
name: `${namePrefix}
|
|
378
|
+
name: `${namePrefix}Filter`,
|
|
333
379
|
fields
|
|
334
380
|
});
|
|
335
381
|
}
|
|
@@ -342,7 +388,42 @@ function translateFilter(filter) {
|
|
|
342
388
|
}
|
|
343
389
|
return result;
|
|
344
390
|
}
|
|
345
|
-
function
|
|
391
|
+
function fieldsToGraphQLInputObjectType(name, fields, registry) {
|
|
392
|
+
return new GraphQLInputObjectType({
|
|
393
|
+
name,
|
|
394
|
+
fields: () => {
|
|
395
|
+
const out = {};
|
|
396
|
+
for (const field of fields) {
|
|
397
|
+
if (!field.name) continue;
|
|
398
|
+
if (field.type === "row" || field.type === "collapsible") {
|
|
399
|
+
const subFields = field.fields;
|
|
400
|
+
if (subFields) {
|
|
401
|
+
for (const sf of subFields) {
|
|
402
|
+
if (!sf.name) continue;
|
|
403
|
+
out[sf.name] = { type: fieldToGraphQLType(sf, registry, void 0, true) };
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
} else if (field.type === "tabs") {
|
|
407
|
+
const tabs = field.tabs;
|
|
408
|
+
if (tabs) {
|
|
409
|
+
for (const tab of tabs) {
|
|
410
|
+
if (tab.fields) {
|
|
411
|
+
for (const sf of tab.fields) {
|
|
412
|
+
if (!sf.name) continue;
|
|
413
|
+
out[sf.name] = { type: fieldToGraphQLType(sf, registry, void 0, true) };
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
} else {
|
|
419
|
+
out[field.name] = { type: fieldToGraphQLType(field, registry, void 0, true) };
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return out;
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
function fieldsToGraphQLObjectType(name, fields, registry, collectionTypes) {
|
|
346
427
|
return new GraphQLObjectType({
|
|
347
428
|
name,
|
|
348
429
|
fields: () => {
|
|
@@ -354,7 +435,7 @@ function fieldsToGraphQLObjectType(name, fields, registry, collectionTypes, load
|
|
|
354
435
|
if (subFields) {
|
|
355
436
|
for (const sf of subFields) {
|
|
356
437
|
if (!sf.name) continue;
|
|
357
|
-
const fc = buildFieldConfig(sf, registry, collectionTypes
|
|
438
|
+
const fc = buildFieldConfig(sf, registry, collectionTypes);
|
|
358
439
|
if (fc) out[sf.name] = fc;
|
|
359
440
|
}
|
|
360
441
|
}
|
|
@@ -365,14 +446,14 @@ function fieldsToGraphQLObjectType(name, fields, registry, collectionTypes, load
|
|
|
365
446
|
if (tab.fields) {
|
|
366
447
|
for (const sf of tab.fields) {
|
|
367
448
|
if (!sf.name) continue;
|
|
368
|
-
const fc = buildFieldConfig(sf, registry, collectionTypes
|
|
449
|
+
const fc = buildFieldConfig(sf, registry, collectionTypes);
|
|
369
450
|
if (fc) out[sf.name] = fc;
|
|
370
451
|
}
|
|
371
452
|
}
|
|
372
453
|
}
|
|
373
454
|
}
|
|
374
455
|
} else {
|
|
375
|
-
const fc = buildFieldConfig(field, registry, collectionTypes
|
|
456
|
+
const fc = buildFieldConfig(field, registry, collectionTypes);
|
|
376
457
|
if (fc) out[field.name] = fc;
|
|
377
458
|
}
|
|
378
459
|
}
|
|
@@ -380,14 +461,17 @@ function fieldsToGraphQLObjectType(name, fields, registry, collectionTypes, load
|
|
|
380
461
|
}
|
|
381
462
|
});
|
|
382
463
|
}
|
|
383
|
-
function buildFieldConfig(field, registry, collectionTypes
|
|
464
|
+
function buildFieldConfig(field, registry, collectionTypes) {
|
|
384
465
|
if (!field.name) return null;
|
|
466
|
+
const deprecationReason = field.deprecated || void 0;
|
|
385
467
|
if (field.type === "relationship" && !field.hasMany) {
|
|
386
|
-
const gqlType = fieldToGraphQLType(field, registry, collectionTypes, false
|
|
468
|
+
const gqlType = fieldToGraphQLType(field, registry, collectionTypes, false);
|
|
387
469
|
return {
|
|
388
470
|
type: field.required ? new GraphQLNonNull(gqlType) : gqlType,
|
|
389
471
|
description: field.admin?.description || field.label,
|
|
390
|
-
|
|
472
|
+
deprecationReason,
|
|
473
|
+
resolve: (source, args, ctx) => {
|
|
474
|
+
const loader = ctx?.relationLoader;
|
|
391
475
|
const relField = field;
|
|
392
476
|
const id = source?.[relField.name];
|
|
393
477
|
if (!id) return null;
|
|
@@ -401,11 +485,13 @@ function buildFieldConfig(field, registry, collectionTypes, loader) {
|
|
|
401
485
|
};
|
|
402
486
|
}
|
|
403
487
|
if (field.type === "relationship" && field.hasMany) {
|
|
404
|
-
const gqlType = fieldToGraphQLType(field, registry, collectionTypes, false
|
|
488
|
+
const gqlType = fieldToGraphQLType(field, registry, collectionTypes, false);
|
|
405
489
|
return {
|
|
406
490
|
type: gqlType,
|
|
407
491
|
description: field.admin?.description || field.label,
|
|
408
|
-
|
|
492
|
+
deprecationReason,
|
|
493
|
+
resolve: (source, args, ctx) => {
|
|
494
|
+
const loader = ctx?.relationLoader;
|
|
409
495
|
const relField = field;
|
|
410
496
|
const ids = source?.[relField.name] || [];
|
|
411
497
|
if (!ids.length) return [];
|
|
@@ -426,27 +512,27 @@ function buildFieldConfig(field, registry, collectionTypes, loader) {
|
|
|
426
512
|
};
|
|
427
513
|
}
|
|
428
514
|
return {
|
|
429
|
-
type: field.required ? new GraphQLNonNull(fieldToGraphQLType(field, registry, collectionTypes, false
|
|
430
|
-
description: field.admin?.description || field.label
|
|
515
|
+
type: field.required ? new GraphQLNonNull(fieldToGraphQLType(field, registry, collectionTypes, false)) : fieldToGraphQLType(field, registry, collectionTypes, false),
|
|
516
|
+
description: field.admin?.description || field.label,
|
|
517
|
+
deprecationReason
|
|
431
518
|
};
|
|
432
519
|
}
|
|
433
520
|
function buildGraphQLSchema(options) {
|
|
434
|
-
const { registry, db,
|
|
521
|
+
const { registry, db, settings } = options;
|
|
435
522
|
const apiAccess = settings?.access?.apiAccess;
|
|
436
523
|
if (apiAccess?.graphqlEnabled === false) {
|
|
437
524
|
throw new Error("GraphQL API is disabled");
|
|
438
525
|
}
|
|
439
526
|
const collections = registry.getCollections();
|
|
440
527
|
const globals = registry.getGlobals();
|
|
441
|
-
const relationLoader = new RelationLoader({ db, tenantID, user });
|
|
442
528
|
const collectionTypes = {};
|
|
443
529
|
const collectionInputTypes = {};
|
|
444
530
|
for (const collection of collections) {
|
|
445
531
|
collectionTypes[collection.slug] = new GraphQLObjectType({
|
|
446
|
-
name:
|
|
532
|
+
name: toPascalSingular(collection.slug),
|
|
447
533
|
fields: () => ({
|
|
448
|
-
id: { type: GraphQLString },
|
|
449
|
-
...buildFieldsFromCollection(collection, registry, collectionTypes
|
|
534
|
+
id: { type: new GraphQLNonNull(GraphQLString) },
|
|
535
|
+
...buildFieldsFromCollection(collection, registry, collectionTypes),
|
|
450
536
|
...collection.timestamps ? {
|
|
451
537
|
createdAt: { type: GraphQLString },
|
|
452
538
|
updatedAt: { type: GraphQLString }
|
|
@@ -465,7 +551,7 @@ function buildGraphQLSchema(options) {
|
|
|
465
551
|
}
|
|
466
552
|
}
|
|
467
553
|
collectionInputTypes[collection.slug] = new GraphQLInputObjectType({
|
|
468
|
-
name: `${collection.slug
|
|
554
|
+
name: `${toPascalSingular(collection.slug)}Input`,
|
|
469
555
|
fields: () => inputFields
|
|
470
556
|
});
|
|
471
557
|
}
|
|
@@ -473,19 +559,18 @@ function buildGraphQLSchema(options) {
|
|
|
473
559
|
const globalInputTypes = {};
|
|
474
560
|
for (const global of globals) {
|
|
475
561
|
globalTypes[global.slug] = new GraphQLObjectType({
|
|
476
|
-
name:
|
|
562
|
+
name: toPascalCase(global.slug),
|
|
477
563
|
fields: () => ({
|
|
478
564
|
id: { type: GraphQLString },
|
|
479
565
|
...buildFieldsFromCollection(
|
|
480
566
|
{ slug: global.slug, fields: global.fields },
|
|
481
567
|
registry,
|
|
482
|
-
collectionTypes
|
|
483
|
-
relationLoader
|
|
568
|
+
collectionTypes
|
|
484
569
|
)
|
|
485
570
|
})
|
|
486
571
|
});
|
|
487
572
|
globalInputTypes[global.slug] = new GraphQLInputObjectType({
|
|
488
|
-
name: `${global.slug
|
|
573
|
+
name: `${toPascalCase(global.slug)}Input`,
|
|
489
574
|
fields: () => {
|
|
490
575
|
const inputFields = {};
|
|
491
576
|
for (const field of global.fields) {
|
|
@@ -499,15 +584,24 @@ function buildGraphQLSchema(options) {
|
|
|
499
584
|
}
|
|
500
585
|
});
|
|
501
586
|
}
|
|
587
|
+
const pageInfoType = new GraphQLObjectType({
|
|
588
|
+
name: "PageInfo",
|
|
589
|
+
fields: {
|
|
590
|
+
hasNextPage: { type: new GraphQLNonNull(GraphQLBoolean) },
|
|
591
|
+
hasPreviousPage: { type: new GraphQLNonNull(GraphQLBoolean) },
|
|
592
|
+
startCursor: { type: GraphQLString },
|
|
593
|
+
endCursor: { type: GraphQLString }
|
|
594
|
+
}
|
|
595
|
+
});
|
|
502
596
|
const queryFields = {};
|
|
503
597
|
for (const collection of collections) {
|
|
504
598
|
const type = collectionTypes[collection.slug];
|
|
505
599
|
if (!type) continue;
|
|
506
|
-
const filterType = buildCollectionFilterType(collection, collection.slug
|
|
600
|
+
const filterType = buildCollectionFilterType(collection, toPascalSingular(collection.slug));
|
|
507
601
|
const sortEnum = buildSortEnum(collection);
|
|
508
|
-
queryFields[
|
|
602
|
+
queryFields[toCamelCase(collection.slug)] = {
|
|
509
603
|
type: new GraphQLObjectType({
|
|
510
|
-
name: `${collection.slug
|
|
604
|
+
name: `${toPascalSingular(collection.slug)}FindResult`,
|
|
511
605
|
fields: {
|
|
512
606
|
docs: { type: new GraphQLList(type) },
|
|
513
607
|
totalDocs: { type: GraphQLInt },
|
|
@@ -525,14 +619,15 @@ function buildGraphQLSchema(options) {
|
|
|
525
619
|
draft: { type: GraphQLBoolean }
|
|
526
620
|
},
|
|
527
621
|
resolve: async (_, args, ctx) => {
|
|
622
|
+
const { user: ctxUser, req: ctxReq, tenantID: ctxTenant, apiKey: ctxApiKey, db: ctxDb, relationLoader: ctxLoader } = ctx;
|
|
528
623
|
const extraWhere = await checkAccess(collection, "read", {
|
|
529
|
-
user,
|
|
530
|
-
req,
|
|
531
|
-
tenantID,
|
|
532
|
-
apiKey
|
|
624
|
+
user: ctxUser,
|
|
625
|
+
req: ctxReq,
|
|
626
|
+
tenantID: ctxTenant,
|
|
627
|
+
apiKey: ctxApiKey
|
|
533
628
|
});
|
|
534
|
-
if (
|
|
535
|
-
|
|
629
|
+
if (ctxTenant) {
|
|
630
|
+
ctxDb.setTenantContext({ tenantId: ctxTenant, userId: ctxUser?.id ?? "", role: ctxUser?.role, isSuperAdmin: ctxUser?.role === "super_admin" });
|
|
536
631
|
}
|
|
537
632
|
let where = {};
|
|
538
633
|
if (args.where) {
|
|
@@ -548,51 +643,52 @@ function buildGraphQLSchema(options) {
|
|
|
548
643
|
if (extraWhere) {
|
|
549
644
|
where = { ...where, ...extraWhere };
|
|
550
645
|
}
|
|
551
|
-
const isDraft = args.draft ?? !!
|
|
552
|
-
return RelationLoader.withBatch(
|
|
553
|
-
return
|
|
646
|
+
const isDraft = args.draft ?? !!ctxUser;
|
|
647
|
+
return RelationLoader.withBatch(ctxLoader, async () => {
|
|
648
|
+
return ctxDb.find({
|
|
554
649
|
collection: collection.slug,
|
|
555
650
|
where,
|
|
556
651
|
sort: args.sort,
|
|
557
652
|
limit: args.limit || 10,
|
|
558
653
|
page: args.page || 1,
|
|
559
|
-
tenantID,
|
|
654
|
+
tenantID: ctxTenant,
|
|
560
655
|
draft: isDraft
|
|
561
656
|
});
|
|
562
657
|
});
|
|
563
658
|
}
|
|
564
659
|
};
|
|
565
|
-
queryFields[
|
|
660
|
+
queryFields[toCamelSingular(collection.slug)] = {
|
|
566
661
|
type,
|
|
567
662
|
args: {
|
|
568
663
|
id: { type: new GraphQLNonNull(GraphQLString) },
|
|
569
664
|
draft: { type: GraphQLBoolean }
|
|
570
665
|
},
|
|
571
666
|
resolve: async (_, args, ctx) => {
|
|
667
|
+
const { user: ctxUser, req: ctxReq, tenantID: ctxTenant, apiKey: ctxApiKey, db: ctxDb, relationLoader: ctxLoader } = ctx;
|
|
572
668
|
await checkAccess(collection, "read", {
|
|
573
|
-
user,
|
|
574
|
-
req,
|
|
575
|
-
tenantID,
|
|
576
|
-
apiKey
|
|
669
|
+
user: ctxUser,
|
|
670
|
+
req: ctxReq,
|
|
671
|
+
tenantID: ctxTenant,
|
|
672
|
+
apiKey: ctxApiKey
|
|
577
673
|
});
|
|
578
|
-
if (
|
|
579
|
-
|
|
674
|
+
if (ctxTenant) {
|
|
675
|
+
ctxDb.setTenantContext({ tenantId: ctxTenant, userId: ctxUser?.id ?? "", role: ctxUser?.role, isSuperAdmin: ctxUser?.role === "super_admin" });
|
|
580
676
|
}
|
|
581
|
-
const isDraft = args.draft ?? !!
|
|
582
|
-
return RelationLoader.withBatch(
|
|
583
|
-
const doc = await
|
|
677
|
+
const isDraft = args.draft ?? !!ctxUser;
|
|
678
|
+
return RelationLoader.withBatch(ctxLoader, async () => {
|
|
679
|
+
const doc = await ctxDb.findByID({
|
|
584
680
|
collection: collection.slug,
|
|
585
681
|
id: args.id,
|
|
586
|
-
tenantID,
|
|
682
|
+
tenantID: ctxTenant,
|
|
587
683
|
draft: isDraft
|
|
588
684
|
});
|
|
589
685
|
return doc;
|
|
590
686
|
});
|
|
591
687
|
}
|
|
592
688
|
};
|
|
593
|
-
queryFields[
|
|
689
|
+
queryFields[`count${toPascalSingular(collection.slug)}s`] = {
|
|
594
690
|
type: new GraphQLObjectType({
|
|
595
|
-
name: `${collection.slug
|
|
691
|
+
name: `${toPascalSingular(collection.slug)}Count`,
|
|
596
692
|
fields: {
|
|
597
693
|
totalDocs: { type: GraphQLInt }
|
|
598
694
|
}
|
|
@@ -601,11 +697,12 @@ function buildGraphQLSchema(options) {
|
|
|
601
697
|
where: { type: GraphQLString }
|
|
602
698
|
},
|
|
603
699
|
resolve: async (_, args, ctx) => {
|
|
700
|
+
const { user: ctxUser, req: ctxReq, tenantID: ctxTenant, apiKey: ctxApiKey, db: ctxDb } = ctx;
|
|
604
701
|
await checkAccess(collection, "read", {
|
|
605
|
-
user,
|
|
606
|
-
req,
|
|
607
|
-
tenantID,
|
|
608
|
-
apiKey
|
|
702
|
+
user: ctxUser,
|
|
703
|
+
req: ctxReq,
|
|
704
|
+
tenantID: ctxTenant,
|
|
705
|
+
apiKey: ctxApiKey
|
|
609
706
|
});
|
|
610
707
|
let where = {};
|
|
611
708
|
if (args.where) {
|
|
@@ -618,33 +715,129 @@ function buildGraphQLSchema(options) {
|
|
|
618
715
|
where = translateFilter(args.where);
|
|
619
716
|
}
|
|
620
717
|
}
|
|
621
|
-
const count = await
|
|
718
|
+
const count = await ctxDb.count({
|
|
622
719
|
collection: collection.slug,
|
|
623
720
|
where,
|
|
624
|
-
tenantID
|
|
721
|
+
tenantID: ctxTenant
|
|
625
722
|
});
|
|
626
723
|
return { totalDocs: count };
|
|
627
724
|
}
|
|
628
725
|
};
|
|
726
|
+
const edgeType = new GraphQLObjectType({
|
|
727
|
+
name: `${toPascalSingular(collection.slug)}Edge`,
|
|
728
|
+
fields: {
|
|
729
|
+
node: { type },
|
|
730
|
+
cursor: { type: new GraphQLNonNull(GraphQLString) }
|
|
731
|
+
}
|
|
732
|
+
});
|
|
733
|
+
const connectionType = new GraphQLObjectType({
|
|
734
|
+
name: `${toPascalSingular(collection.slug)}Connection`,
|
|
735
|
+
fields: {
|
|
736
|
+
edges: { type: new GraphQLList(edgeType) },
|
|
737
|
+
pageInfo: { type: new GraphQLNonNull(pageInfoType) },
|
|
738
|
+
totalCount: { type: GraphQLInt }
|
|
739
|
+
}
|
|
740
|
+
});
|
|
741
|
+
queryFields[`${toCamelCase(collection.slug)}Connection`] = {
|
|
742
|
+
type: connectionType,
|
|
743
|
+
args: {
|
|
744
|
+
first: { type: GraphQLInt },
|
|
745
|
+
after: { type: GraphQLString },
|
|
746
|
+
last: { type: GraphQLInt },
|
|
747
|
+
before: { type: GraphQLString },
|
|
748
|
+
where: { type: filterType },
|
|
749
|
+
sort: { type: sortEnum || GraphQLString },
|
|
750
|
+
draft: { type: GraphQLBoolean }
|
|
751
|
+
},
|
|
752
|
+
resolve: async (_, args, ctx) => {
|
|
753
|
+
const { user: ctxUser, req: ctxReq, tenantID: ctxTenant, apiKey: ctxApiKey, db: ctxDb, relationLoader: ctxLoader } = ctx;
|
|
754
|
+
const extraWhere = await checkAccess(collection, "read", {
|
|
755
|
+
user: ctxUser,
|
|
756
|
+
req: ctxReq,
|
|
757
|
+
tenantID: ctxTenant,
|
|
758
|
+
apiKey: ctxApiKey
|
|
759
|
+
});
|
|
760
|
+
if (ctxTenant) {
|
|
761
|
+
ctxDb.setTenantContext({ tenantId: ctxTenant, userId: ctxUser?.id ?? "", role: ctxUser?.role, isSuperAdmin: ctxUser?.role === "super_admin" });
|
|
762
|
+
}
|
|
763
|
+
let where = {};
|
|
764
|
+
if (args.where) {
|
|
765
|
+
if (typeof args.where === "string") {
|
|
766
|
+
try {
|
|
767
|
+
where = JSON.parse(args.where);
|
|
768
|
+
} catch {
|
|
769
|
+
}
|
|
770
|
+
} else {
|
|
771
|
+
where = translateFilter(args.where);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
if (extraWhere) where = { ...where, ...extraWhere };
|
|
775
|
+
const isDraft = args.draft ?? !!ctxUser;
|
|
776
|
+
return RelationLoader.withBatch(ctxLoader, async () => {
|
|
777
|
+
let page = 1;
|
|
778
|
+
let limit = args.first || args.last || 10;
|
|
779
|
+
if (args.after) {
|
|
780
|
+
try {
|
|
781
|
+
const afterIdx = parseInt(Buffer.from(args.after, "base64").toString("utf-8"), 10);
|
|
782
|
+
if (!isNaN(afterIdx)) page = Math.floor(afterIdx / limit) + 1;
|
|
783
|
+
} catch {
|
|
784
|
+
}
|
|
785
|
+
} else if (args.before) {
|
|
786
|
+
try {
|
|
787
|
+
const beforeIdx = parseInt(Buffer.from(args.before, "base64").toString("utf-8"), 10);
|
|
788
|
+
if (!isNaN(beforeIdx)) page = Math.max(1, Math.floor(beforeIdx / limit));
|
|
789
|
+
} catch {
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
const result = await ctxDb.find({
|
|
793
|
+
collection: collection.slug,
|
|
794
|
+
where,
|
|
795
|
+
sort: args.sort,
|
|
796
|
+
limit,
|
|
797
|
+
page,
|
|
798
|
+
tenantID: ctxTenant,
|
|
799
|
+
draft: isDraft
|
|
800
|
+
});
|
|
801
|
+
const edges = (result.docs || []).map((doc, idx) => {
|
|
802
|
+
const cursorIdx = (page - 1) * limit + idx;
|
|
803
|
+
return {
|
|
804
|
+
node: doc,
|
|
805
|
+
cursor: Buffer.from(String(cursorIdx)).toString("base64")
|
|
806
|
+
};
|
|
807
|
+
});
|
|
808
|
+
return {
|
|
809
|
+
edges,
|
|
810
|
+
pageInfo: {
|
|
811
|
+
hasNextPage: result.hasNextPage || false,
|
|
812
|
+
hasPreviousPage: result.hasPrevPage || false,
|
|
813
|
+
startCursor: edges.length > 0 ? edges[0].cursor : null,
|
|
814
|
+
endCursor: edges.length > 0 ? edges[edges.length - 1].cursor : null
|
|
815
|
+
},
|
|
816
|
+
totalCount: result.totalDocs
|
|
817
|
+
};
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
};
|
|
629
821
|
}
|
|
630
822
|
for (const global of globals) {
|
|
631
823
|
const type = globalTypes[global.slug];
|
|
632
824
|
if (!type) continue;
|
|
633
|
-
queryFields[
|
|
825
|
+
queryFields[toCamelCase(global.slug)] = {
|
|
634
826
|
type,
|
|
635
|
-
resolve: async () => {
|
|
827
|
+
resolve: async (_, args, ctx) => {
|
|
828
|
+
const { user: ctxUser, req: ctxReq, tenantID: ctxTenant, db: ctxDb } = ctx;
|
|
636
829
|
await checkGqlGlobalAccess(global, "read", {
|
|
637
|
-
user,
|
|
638
|
-
req,
|
|
639
|
-
tenantID
|
|
830
|
+
user: ctxUser,
|
|
831
|
+
req: ctxReq,
|
|
832
|
+
tenantID: ctxTenant
|
|
640
833
|
});
|
|
641
|
-
if (
|
|
642
|
-
|
|
834
|
+
if (ctxTenant) {
|
|
835
|
+
ctxDb.setTenantContext({ tenantId: ctxTenant, userId: ctxUser?.id ?? "", role: ctxUser?.role, isSuperAdmin: ctxUser?.role === "super_admin" });
|
|
643
836
|
}
|
|
644
|
-
return
|
|
837
|
+
return ctxDb.findOne({
|
|
645
838
|
collection: `_globals_${global.slug}`,
|
|
646
839
|
where: {},
|
|
647
|
-
tenantID
|
|
840
|
+
tenantID: ctxTenant
|
|
648
841
|
});
|
|
649
842
|
}
|
|
650
843
|
};
|
|
@@ -658,9 +851,9 @@ function buildGraphQLSchema(options) {
|
|
|
658
851
|
const type = collectionTypes[collection.slug];
|
|
659
852
|
const inputType = collectionInputTypes[collection.slug];
|
|
660
853
|
if (!type || !inputType) continue;
|
|
661
|
-
mutationFields[
|
|
854
|
+
mutationFields[`create${toPascalSingular(collection.slug)}`] = {
|
|
662
855
|
type: new GraphQLObjectType({
|
|
663
|
-
name: `${collection.slug
|
|
856
|
+
name: `${toPascalSingular(collection.slug)}CreateResult`,
|
|
664
857
|
fields: {
|
|
665
858
|
doc: { type },
|
|
666
859
|
message: { type: GraphQLString }
|
|
@@ -671,28 +864,38 @@ function buildGraphQLSchema(options) {
|
|
|
671
864
|
draft: { type: GraphQLBoolean }
|
|
672
865
|
},
|
|
673
866
|
resolve: async (_, args, ctx) => {
|
|
867
|
+
const { user: ctxUser, req: ctxReq, tenantID: ctxTenant, apiKey: ctxApiKey, db: ctxDb, registry: ctxRegistry } = ctx;
|
|
674
868
|
await checkAccess(collection, "create", {
|
|
675
|
-
user,
|
|
676
|
-
req,
|
|
677
|
-
tenantID,
|
|
678
|
-
apiKey
|
|
869
|
+
user: ctxUser,
|
|
870
|
+
req: ctxReq,
|
|
871
|
+
tenantID: ctxTenant,
|
|
872
|
+
apiKey: ctxApiKey
|
|
679
873
|
});
|
|
680
|
-
if (
|
|
681
|
-
|
|
874
|
+
if (ctxTenant) {
|
|
875
|
+
ctxDb.setTenantContext({ tenantId: ctxTenant, userId: ctxUser?.id ?? "", role: ctxUser?.role, isSuperAdmin: ctxUser?.role === "super_admin" });
|
|
682
876
|
}
|
|
683
|
-
const
|
|
684
|
-
|
|
685
|
-
|
|
877
|
+
const createSchema = ctxRegistry.getCreateZodSchema(collection.slug);
|
|
878
|
+
let validated;
|
|
879
|
+
try {
|
|
880
|
+
validated = createSchema.parse(args.data);
|
|
881
|
+
} catch (err) {
|
|
882
|
+
if (err?.issues) {
|
|
883
|
+
const msg = err.issues.map((i) => `${i.path?.join(".")}: ${i.message}`).join("; ");
|
|
884
|
+
throw gqlError(msg, "BAD_USER_INPUT");
|
|
885
|
+
}
|
|
886
|
+
throw err;
|
|
887
|
+
}
|
|
888
|
+
const doc = await ctxDb.create({
|
|
686
889
|
collection: collection.slug,
|
|
687
890
|
data: validated,
|
|
688
|
-
tenantID
|
|
891
|
+
tenantID: ctxTenant
|
|
689
892
|
});
|
|
690
893
|
return { doc, message: "Created successfully" };
|
|
691
894
|
}
|
|
692
895
|
};
|
|
693
|
-
mutationFields[
|
|
896
|
+
mutationFields[`update${toPascalSingular(collection.slug)}`] = {
|
|
694
897
|
type: new GraphQLObjectType({
|
|
695
|
-
name: `${collection.slug
|
|
898
|
+
name: `${toPascalSingular(collection.slug)}UpdateResult`,
|
|
696
899
|
fields: {
|
|
697
900
|
doc: { type },
|
|
698
901
|
message: { type: GraphQLString }
|
|
@@ -705,20 +908,21 @@ function buildGraphQLSchema(options) {
|
|
|
705
908
|
draft: { type: GraphQLBoolean }
|
|
706
909
|
},
|
|
707
910
|
resolve: async (_, args, ctx) => {
|
|
911
|
+
const { user: ctxUser, req: ctxReq, tenantID: ctxTenant, apiKey: ctxApiKey, db: ctxDb, registry: ctxRegistry } = ctx;
|
|
708
912
|
await checkAccess(collection, "update", {
|
|
709
|
-
user,
|
|
710
|
-
req,
|
|
711
|
-
tenantID,
|
|
712
|
-
apiKey
|
|
913
|
+
user: ctxUser,
|
|
914
|
+
req: ctxReq,
|
|
915
|
+
tenantID: ctxTenant,
|
|
916
|
+
apiKey: ctxApiKey
|
|
713
917
|
});
|
|
714
|
-
if (
|
|
715
|
-
|
|
918
|
+
if (ctxTenant) {
|
|
919
|
+
ctxDb.setTenantContext({ tenantId: ctxTenant, userId: ctxUser?.id ?? "", role: ctxUser?.role, isSuperAdmin: ctxUser?.role === "super_admin" });
|
|
716
920
|
}
|
|
717
921
|
if (args.baseUpdatedAt) {
|
|
718
|
-
const originalDoc = await
|
|
922
|
+
const originalDoc = await ctxDb.findByID({
|
|
719
923
|
collection: collection.slug,
|
|
720
924
|
id: args.id,
|
|
721
|
-
tenantID,
|
|
925
|
+
tenantID: ctxTenant,
|
|
722
926
|
draft: true
|
|
723
927
|
});
|
|
724
928
|
if (originalDoc && originalDoc.updatedAt && args.baseUpdatedAt !== originalDoc.updatedAt) {
|
|
@@ -728,20 +932,29 @@ function buildGraphQLSchema(options) {
|
|
|
728
932
|
);
|
|
729
933
|
}
|
|
730
934
|
}
|
|
731
|
-
const
|
|
732
|
-
|
|
733
|
-
|
|
935
|
+
const updateSchema = ctxRegistry.getUpdateZodSchema(collection.slug);
|
|
936
|
+
let validated;
|
|
937
|
+
try {
|
|
938
|
+
validated = updateSchema.parse(args.data);
|
|
939
|
+
} catch (err) {
|
|
940
|
+
if (err?.issues) {
|
|
941
|
+
const msg = err.issues.map((i) => `${i.path?.join(".")}: ${i.message}`).join("; ");
|
|
942
|
+
throw gqlError(msg, "BAD_USER_INPUT");
|
|
943
|
+
}
|
|
944
|
+
throw err;
|
|
945
|
+
}
|
|
946
|
+
const doc = await ctxDb.update({
|
|
734
947
|
collection: collection.slug,
|
|
735
948
|
id: args.id,
|
|
736
949
|
data: validated,
|
|
737
|
-
tenantID
|
|
950
|
+
tenantID: ctxTenant
|
|
738
951
|
});
|
|
739
952
|
return { doc, message: "Updated successfully" };
|
|
740
953
|
}
|
|
741
954
|
};
|
|
742
|
-
mutationFields[
|
|
955
|
+
mutationFields[`delete${toPascalSingular(collection.slug)}`] = {
|
|
743
956
|
type: new GraphQLObjectType({
|
|
744
|
-
name: `${collection.slug
|
|
957
|
+
name: `${toPascalSingular(collection.slug)}DeleteResult`,
|
|
745
958
|
fields: {
|
|
746
959
|
doc: { type },
|
|
747
960
|
message: { type: GraphQLString }
|
|
@@ -751,19 +964,20 @@ function buildGraphQLSchema(options) {
|
|
|
751
964
|
id: { type: new GraphQLNonNull(GraphQLString) }
|
|
752
965
|
},
|
|
753
966
|
resolve: async (_, args, ctx) => {
|
|
967
|
+
const { user: ctxUser, req: ctxReq, tenantID: ctxTenant, apiKey: ctxApiKey, db: ctxDb } = ctx;
|
|
754
968
|
await checkAccess(collection, "delete", {
|
|
755
|
-
user,
|
|
756
|
-
req,
|
|
757
|
-
tenantID,
|
|
758
|
-
apiKey
|
|
969
|
+
user: ctxUser,
|
|
970
|
+
req: ctxReq,
|
|
971
|
+
tenantID: ctxTenant,
|
|
972
|
+
apiKey: ctxApiKey
|
|
759
973
|
});
|
|
760
|
-
if (
|
|
761
|
-
|
|
974
|
+
if (ctxTenant) {
|
|
975
|
+
ctxDb.setTenantContext({ tenantId: ctxTenant, userId: ctxUser?.id ?? "", role: ctxUser?.role, isSuperAdmin: ctxUser?.role === "super_admin" });
|
|
762
976
|
}
|
|
763
|
-
const doc = await
|
|
977
|
+
const doc = await ctxDb.delete({
|
|
764
978
|
collection: collection.slug,
|
|
765
979
|
id: args.id,
|
|
766
|
-
tenantID
|
|
980
|
+
tenantID: ctxTenant
|
|
767
981
|
});
|
|
768
982
|
return { doc, message: "Deleted successfully" };
|
|
769
983
|
}
|
|
@@ -772,9 +986,9 @@ function buildGraphQLSchema(options) {
|
|
|
772
986
|
for (const global of globals) {
|
|
773
987
|
const inputType = globalInputTypes[global.slug];
|
|
774
988
|
if (!inputType) continue;
|
|
775
|
-
mutationFields[
|
|
989
|
+
mutationFields[`update${toPascalCase(global.slug)}`] = {
|
|
776
990
|
type: new GraphQLObjectType({
|
|
777
|
-
name: `${global.slug
|
|
991
|
+
name: `${toPascalCase(global.slug)}UpdateResult`,
|
|
778
992
|
fields: {
|
|
779
993
|
doc: { type: globalTypes[global.slug] || GraphQLString },
|
|
780
994
|
message: { type: GraphQLString }
|
|
@@ -784,32 +998,33 @@ function buildGraphQLSchema(options) {
|
|
|
784
998
|
data: { type: new GraphQLNonNull(inputType) }
|
|
785
999
|
},
|
|
786
1000
|
resolve: async (_, args, ctx) => {
|
|
1001
|
+
const { user: ctxUser, req: ctxReq, tenantID: ctxTenant, db: ctxDb } = ctx;
|
|
787
1002
|
await checkGqlGlobalAccess(global, "update", {
|
|
788
|
-
user,
|
|
789
|
-
req,
|
|
790
|
-
tenantID
|
|
1003
|
+
user: ctxUser,
|
|
1004
|
+
req: ctxReq,
|
|
1005
|
+
tenantID: ctxTenant
|
|
791
1006
|
});
|
|
792
|
-
if (
|
|
793
|
-
|
|
1007
|
+
if (ctxTenant) {
|
|
1008
|
+
ctxDb.setTenantContext({ tenantId: ctxTenant, userId: ctxUser?.id ?? "", role: ctxUser?.role, isSuperAdmin: ctxUser?.role === "super_admin" });
|
|
794
1009
|
}
|
|
795
|
-
const doc = await
|
|
1010
|
+
const doc = await ctxDb.findOne({
|
|
796
1011
|
collection: `_globals_${global.slug}`,
|
|
797
1012
|
where: {},
|
|
798
|
-
tenantID
|
|
1013
|
+
tenantID: ctxTenant
|
|
799
1014
|
});
|
|
800
1015
|
let result;
|
|
801
1016
|
if (doc) {
|
|
802
|
-
result = await
|
|
1017
|
+
result = await ctxDb.update({
|
|
803
1018
|
collection: `_globals_${global.slug}`,
|
|
804
1019
|
id: doc.id,
|
|
805
1020
|
data: args.data,
|
|
806
|
-
tenantID
|
|
1021
|
+
tenantID: ctxTenant
|
|
807
1022
|
});
|
|
808
1023
|
} else {
|
|
809
|
-
result = await
|
|
1024
|
+
result = await ctxDb.create({
|
|
810
1025
|
collection: `_globals_${global.slug}`,
|
|
811
1026
|
data: args.data,
|
|
812
|
-
tenantID
|
|
1027
|
+
tenantID: ctxTenant
|
|
813
1028
|
});
|
|
814
1029
|
}
|
|
815
1030
|
return { doc: result, message: "Updated successfully" };
|
|
@@ -820,23 +1035,38 @@ function buildGraphQLSchema(options) {
|
|
|
820
1035
|
name: "Mutation",
|
|
821
1036
|
fields: mutationFields
|
|
822
1037
|
});
|
|
1038
|
+
const keyDirective = new GraphQLDirective({
|
|
1039
|
+
name: "key",
|
|
1040
|
+
locations: [DirectiveLocation.OBJECT, DirectiveLocation.INTERFACE],
|
|
1041
|
+
args: {
|
|
1042
|
+
fields: { type: new GraphQLNonNull(GraphQLString) }
|
|
1043
|
+
}
|
|
1044
|
+
});
|
|
1045
|
+
const serviceSdl = printSchema(new GraphQLSchema({
|
|
1046
|
+
query: new GraphQLObjectType({ name: "Query", fields: { ...queryFields } }),
|
|
1047
|
+
mutation: Mutation,
|
|
1048
|
+
directives: [keyDirective]
|
|
1049
|
+
}));
|
|
1050
|
+
queryFields._service = {
|
|
1051
|
+
type: new GraphQLObjectType({
|
|
1052
|
+
name: "_Service",
|
|
1053
|
+
fields: {
|
|
1054
|
+
sdl: { type: GraphQLString }
|
|
1055
|
+
}
|
|
1056
|
+
}),
|
|
1057
|
+
resolve: () => ({ sdl: serviceSdl })
|
|
1058
|
+
};
|
|
823
1059
|
return new GraphQLSchema({
|
|
824
1060
|
query: Query,
|
|
825
|
-
mutation: Mutation
|
|
1061
|
+
mutation: Mutation,
|
|
1062
|
+
directives: [keyDirective]
|
|
826
1063
|
});
|
|
827
1064
|
}
|
|
828
|
-
function createGraphQLSchema(registry, db
|
|
829
|
-
const schema = buildGraphQLSchema({
|
|
830
|
-
registry,
|
|
831
|
-
db,
|
|
832
|
-
user: options?.user,
|
|
833
|
-
req: options?.req,
|
|
834
|
-
tenantID: options?.tenantID,
|
|
835
|
-
apiKey: options?.apiKey
|
|
836
|
-
});
|
|
1065
|
+
function createGraphQLSchema(registry, db) {
|
|
1066
|
+
const schema = buildGraphQLSchema({ registry, db });
|
|
837
1067
|
return Object.assign(schema, { sdl: printSchema(schema) });
|
|
838
1068
|
}
|
|
839
1069
|
|
|
840
|
-
export { buildGraphQLSchema, createGraphQLSchema };
|
|
841
|
-
//# sourceMappingURL=chunk-
|
|
842
|
-
//# sourceMappingURL=chunk-
|
|
1070
|
+
export { RelationLoader, buildGraphQLSchema, createGraphQLSchema, depthLimit };
|
|
1071
|
+
//# sourceMappingURL=chunk-6DURKQ6W.js.map
|
|
1072
|
+
//# sourceMappingURL=chunk-6DURKQ6W.js.map
|