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