@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.
- package/dist/app.js +10 -4
- package/dist/auth/drivers/oauth2.js +2 -3
- package/dist/auth/drivers/openid.js +2 -3
- package/dist/cache.d.ts +2 -2
- package/dist/cache.js +20 -7
- package/dist/controllers/assets.js +2 -2
- package/dist/controllers/metrics.d.ts +2 -0
- package/dist/controllers/metrics.js +33 -0
- package/dist/controllers/server.js +1 -1
- package/dist/database/helpers/number/dialects/mssql.d.ts +2 -2
- package/dist/database/helpers/number/dialects/mssql.js +3 -3
- package/dist/database/helpers/number/dialects/oracle.d.ts +2 -2
- package/dist/database/helpers/number/dialects/oracle.js +2 -2
- package/dist/database/helpers/number/dialects/sqlite.d.ts +2 -2
- package/dist/database/helpers/number/dialects/sqlite.js +2 -2
- package/dist/database/helpers/number/types.d.ts +2 -2
- package/dist/database/helpers/number/types.js +2 -2
- package/dist/database/index.js +3 -0
- package/dist/metrics/index.d.ts +1 -0
- package/dist/metrics/index.js +1 -0
- package/dist/metrics/lib/create-metrics.d.ts +15 -0
- package/dist/metrics/lib/create-metrics.js +239 -0
- package/dist/metrics/lib/use-metrics.d.ts +17 -0
- package/dist/metrics/lib/use-metrics.js +15 -0
- package/dist/metrics/types/metric.d.ts +1 -0
- package/dist/metrics/types/metric.js +1 -0
- package/dist/middleware/respond.js +7 -1
- package/dist/operations/condition/index.js +7 -2
- package/dist/schedules/metrics.d.ts +7 -0
- package/dist/schedules/metrics.js +44 -0
- package/dist/services/assets.d.ts +6 -1
- package/dist/services/assets.js +8 -6
- package/dist/services/fields.js +1 -1
- package/dist/services/graphql/errors/format.d.ts +6 -0
- package/dist/services/graphql/errors/format.js +14 -0
- package/dist/services/graphql/index.d.ts +5 -53
- package/dist/services/graphql/index.js +5 -2720
- package/dist/services/graphql/resolvers/mutation.d.ts +4 -0
- package/dist/services/graphql/resolvers/mutation.js +74 -0
- package/dist/services/graphql/resolvers/query.d.ts +8 -0
- package/dist/services/graphql/resolvers/query.js +87 -0
- package/dist/services/graphql/resolvers/system-admin.d.ts +5 -0
- package/dist/services/graphql/resolvers/system-admin.js +236 -0
- package/dist/services/graphql/resolvers/system-global.d.ts +7 -0
- package/dist/services/graphql/resolvers/system-global.js +435 -0
- package/dist/services/graphql/resolvers/system.d.ts +11 -0
- package/dist/services/graphql/resolvers/system.js +554 -0
- package/dist/services/graphql/schema/get-types.d.ts +12 -0
- package/dist/services/graphql/schema/get-types.js +223 -0
- package/dist/services/graphql/schema/index.d.ts +32 -0
- package/dist/services/graphql/schema/index.js +190 -0
- package/dist/services/graphql/schema/parse-args.d.ts +9 -0
- package/dist/services/graphql/schema/parse-args.js +35 -0
- package/dist/services/graphql/schema/parse-query.d.ts +7 -0
- package/dist/services/graphql/schema/parse-query.js +98 -0
- package/dist/services/graphql/schema/read.d.ts +12 -0
- package/dist/services/graphql/schema/read.js +653 -0
- package/dist/services/graphql/schema/write.d.ts +9 -0
- package/dist/services/graphql/schema/write.js +142 -0
- package/dist/services/graphql/subscription.d.ts +1 -1
- package/dist/services/graphql/subscription.js +7 -6
- package/dist/services/graphql/utils/aggrgate-query.d.ts +6 -0
- package/dist/services/graphql/utils/aggrgate-query.js +32 -0
- package/dist/services/graphql/utils/replace-fragments.d.ts +6 -0
- package/dist/services/graphql/utils/replace-fragments.js +21 -0
- package/dist/services/graphql/utils/replace-funcs.d.ts +5 -0
- package/dist/services/graphql/utils/replace-funcs.js +21 -0
- package/dist/services/graphql/utils/sanitize-gql-schema.d.ts +1 -1
- package/dist/services/graphql/utils/sanitize-gql-schema.js +5 -5
- package/dist/services/items.js +0 -2
- package/dist/services/meta.js +25 -84
- package/dist/services/users.d.ts +4 -0
- package/dist/services/users.js +23 -1
- package/dist/utils/apply-query.d.ts +1 -1
- package/dist/utils/apply-query.js +58 -21
- package/dist/utils/freeze-schema.d.ts +3 -0
- package/dist/utils/freeze-schema.js +31 -0
- package/dist/utils/get-accountability-for-token.js +1 -0
- package/dist/utils/get-milliseconds.js +1 -1
- package/dist/utils/get-schema.js +10 -5
- package/dist/utils/permissions-cachable.d.ts +8 -0
- package/dist/utils/permissions-cachable.js +38 -0
- package/dist/utils/sanitize-schema.d.ts +1 -1
- package/dist/websocket/messages.d.ts +6 -6
- package/package.json +22 -19
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Item } from '@directus/types';
|
|
2
|
+
import type { GraphQLResolveInfo } from 'graphql';
|
|
3
|
+
import type { GraphQLService } from '../index.js';
|
|
4
|
+
export declare function resolveMutation(gql: GraphQLService, args: Record<string, any>, info: GraphQLResolveInfo): Promise<Partial<Item> | boolean | undefined>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { getService } from '../../../utils/get-service.js';
|
|
2
|
+
import { formatError } from '../errors/format.js';
|
|
3
|
+
import { replaceFragmentsInSelections } from '../utils/replace-fragments.js';
|
|
4
|
+
import { getQuery } from '../schema/parse-query.js';
|
|
5
|
+
export async function resolveMutation(gql, args, info) {
|
|
6
|
+
const action = info.fieldName.split('_')[0];
|
|
7
|
+
let collection = info.fieldName.substring(action.length + 1);
|
|
8
|
+
if (gql.scope === 'system')
|
|
9
|
+
collection = `directus_${collection}`;
|
|
10
|
+
const selections = replaceFragmentsInSelections(info.fieldNodes[0]?.selectionSet?.selections, info.fragments);
|
|
11
|
+
const query = getQuery(args, selections || [], info.variableValues, gql.accountability);
|
|
12
|
+
const singleton = collection.endsWith('_batch') === false &&
|
|
13
|
+
collection.endsWith('_items') === false &&
|
|
14
|
+
collection.endsWith('_item') === false &&
|
|
15
|
+
collection in gql.schema.collections;
|
|
16
|
+
const single = collection.endsWith('_items') === false && collection.endsWith('_batch') === false;
|
|
17
|
+
const batchUpdate = action === 'update' && collection.endsWith('_batch');
|
|
18
|
+
if (collection.endsWith('_batch'))
|
|
19
|
+
collection = collection.slice(0, -6);
|
|
20
|
+
if (collection.endsWith('_items'))
|
|
21
|
+
collection = collection.slice(0, -6);
|
|
22
|
+
if (collection.endsWith('_item'))
|
|
23
|
+
collection = collection.slice(0, -5);
|
|
24
|
+
if (singleton && action === 'update') {
|
|
25
|
+
return await gql.upsertSingleton(collection, args['data'], query);
|
|
26
|
+
}
|
|
27
|
+
const service = getService(collection, {
|
|
28
|
+
knex: gql.knex,
|
|
29
|
+
accountability: gql.accountability,
|
|
30
|
+
schema: gql.schema,
|
|
31
|
+
});
|
|
32
|
+
const hasQuery = (query.fields || []).length > 0;
|
|
33
|
+
try {
|
|
34
|
+
if (single) {
|
|
35
|
+
if (action === 'create') {
|
|
36
|
+
const key = await service.createOne(args['data']);
|
|
37
|
+
return hasQuery ? await service.readOne(key, query) : true;
|
|
38
|
+
}
|
|
39
|
+
if (action === 'update') {
|
|
40
|
+
const key = await service.updateOne(args['id'], args['data']);
|
|
41
|
+
return hasQuery ? await service.readOne(key, query) : true;
|
|
42
|
+
}
|
|
43
|
+
if (action === 'delete') {
|
|
44
|
+
await service.deleteOne(args['id']);
|
|
45
|
+
return { id: args['id'] };
|
|
46
|
+
}
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
if (action === 'create') {
|
|
51
|
+
const keys = await service.createMany(args['data']);
|
|
52
|
+
return hasQuery ? await service.readMany(keys, query) : true;
|
|
53
|
+
}
|
|
54
|
+
if (action === 'update') {
|
|
55
|
+
const keys = [];
|
|
56
|
+
if (batchUpdate) {
|
|
57
|
+
keys.push(...(await service.updateBatch(args['data'])));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
keys.push(...(await service.updateMany(args['ids'], args['data'])));
|
|
61
|
+
}
|
|
62
|
+
return hasQuery ? await service.readMany(keys, query) : true;
|
|
63
|
+
}
|
|
64
|
+
if (action === 'delete') {
|
|
65
|
+
const keys = await service.deleteMany(args['ids']);
|
|
66
|
+
return { ids: keys };
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
return formatError(err);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Item } from '@directus/types';
|
|
2
|
+
import type { GraphQLResolveInfo } from 'graphql';
|
|
3
|
+
import type { GraphQLService } from '../index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Generic resolver that's used for every "regular" items/system query. Converts the incoming GraphQL AST / fragments into
|
|
6
|
+
* Directus' query structure which is then executed by the services.
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveQuery(gql: GraphQLService, info: GraphQLResolveInfo): Promise<Partial<Item> | null>;
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { parseFilterFunctionPath } from '@directus/utils';
|
|
2
|
+
import { omit } from 'lodash-es';
|
|
3
|
+
import { mergeVersionsRaw, mergeVersionsRecursive } from '../../../utils/merge-version-data.js';
|
|
4
|
+
import { VersionsService } from '../../versions.js';
|
|
5
|
+
import { getAggregateQuery } from '../utils/aggrgate-query.js';
|
|
6
|
+
import { replaceFragmentsInSelections } from '../utils/replace-fragments.js';
|
|
7
|
+
import { parseArgs } from '../schema/parse-args.js';
|
|
8
|
+
import { getQuery } from '../schema/parse-query.js';
|
|
9
|
+
/**
|
|
10
|
+
* Generic resolver that's used for every "regular" items/system query. Converts the incoming GraphQL AST / fragments into
|
|
11
|
+
* Directus' query structure which is then executed by the services.
|
|
12
|
+
*/
|
|
13
|
+
export async function resolveQuery(gql, info) {
|
|
14
|
+
let collection = info.fieldName;
|
|
15
|
+
if (gql.scope === 'system')
|
|
16
|
+
collection = `directus_${collection}`;
|
|
17
|
+
const selections = replaceFragmentsInSelections(info.fieldNodes[0]?.selectionSet?.selections, info.fragments);
|
|
18
|
+
if (!selections)
|
|
19
|
+
return null;
|
|
20
|
+
const args = parseArgs(info.fieldNodes[0].arguments || [], info.variableValues);
|
|
21
|
+
let query;
|
|
22
|
+
let versionRaw = false;
|
|
23
|
+
const isAggregate = collection.endsWith('_aggregated') && collection in gql.schema.collections === false;
|
|
24
|
+
if (isAggregate) {
|
|
25
|
+
query = getAggregateQuery(args, selections, gql.accountability);
|
|
26
|
+
collection = collection.slice(0, -11);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
query = getQuery(args, selections, info.variableValues, gql.accountability);
|
|
30
|
+
if (collection.endsWith('_by_id') && collection in gql.schema.collections === false) {
|
|
31
|
+
collection = collection.slice(0, -6);
|
|
32
|
+
}
|
|
33
|
+
if (collection.endsWith('_by_version') && collection in gql.schema.collections === false) {
|
|
34
|
+
collection = collection.slice(0, -11);
|
|
35
|
+
versionRaw = true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (args['id']) {
|
|
39
|
+
query.filter = {
|
|
40
|
+
_and: [
|
|
41
|
+
query.filter || {},
|
|
42
|
+
{
|
|
43
|
+
[gql.schema.collections[collection].primary]: {
|
|
44
|
+
_eq: args['id'],
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
query.limit = 1;
|
|
50
|
+
}
|
|
51
|
+
// Transform count(a.b.c) into a.b.count(c)
|
|
52
|
+
if (query.fields?.length) {
|
|
53
|
+
for (let fieldIndex = 0; fieldIndex < query.fields.length; fieldIndex++) {
|
|
54
|
+
query.fields[fieldIndex] = parseFilterFunctionPath(query.fields[fieldIndex]);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
const result = await gql.read(collection, query);
|
|
58
|
+
if (args['version']) {
|
|
59
|
+
const versionsService = new VersionsService({ accountability: gql.accountability, schema: gql.schema });
|
|
60
|
+
const saves = await versionsService.getVersionSaves(args['version'], collection, args['id']);
|
|
61
|
+
if (saves) {
|
|
62
|
+
if (gql.schema.collections[collection].singleton) {
|
|
63
|
+
return versionRaw
|
|
64
|
+
? mergeVersionsRaw(result, saves)
|
|
65
|
+
: mergeVersionsRecursive(result, saves, collection, gql.schema);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
if (result?.[0] === undefined)
|
|
69
|
+
return null;
|
|
70
|
+
return versionRaw
|
|
71
|
+
? mergeVersionsRaw(result[0], saves)
|
|
72
|
+
: mergeVersionsRecursive(result[0], saves, collection, gql.schema);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (args['id']) {
|
|
77
|
+
return result?.[0] || null;
|
|
78
|
+
}
|
|
79
|
+
if (query.group) {
|
|
80
|
+
// for every entry in result add a group field based on query.group;
|
|
81
|
+
const aggregateKeys = Object.keys(query.aggregate ?? {});
|
|
82
|
+
result['map']((field) => {
|
|
83
|
+
field['group'] = omit(field, aggregateKeys);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SchemaComposer } from 'graphql-compose';
|
|
2
|
+
import type { GraphQLParams } from '../../../types/index.js';
|
|
3
|
+
import { GraphQLService } from '../index.js';
|
|
4
|
+
import type { BaseTypeComposers } from './system.js';
|
|
5
|
+
export declare function resolveSystemAdmin(gql: GraphQLService, schemaComposer: SchemaComposer<GraphQLParams['contextValue']>, { Collection, Field, Relation, Extension }: BaseTypeComposers): void;
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import { GraphQLBoolean, GraphQLID, GraphQLList, GraphQLNonNull, GraphQLString } from 'graphql';
|
|
2
|
+
import { SchemaComposer, toInputObjectType } from 'graphql-compose';
|
|
3
|
+
import { CollectionsService } from '../../collections.js';
|
|
4
|
+
import { ExtensionsService } from '../../extensions.js';
|
|
5
|
+
import { FieldsService } from '../../fields.js';
|
|
6
|
+
import { RelationsService } from '../../relations.js';
|
|
7
|
+
import { GraphQLService } from '../index.js';
|
|
8
|
+
export function resolveSystemAdmin(gql, schemaComposer, { Collection, Field, Relation, Extension }) {
|
|
9
|
+
if (gql.accountability?.admin === true) {
|
|
10
|
+
schemaComposer.Mutation.addFields({
|
|
11
|
+
create_collections_item: {
|
|
12
|
+
type: Collection,
|
|
13
|
+
args: {
|
|
14
|
+
data: toInputObjectType(Collection.clone('create_directus_collections'), {
|
|
15
|
+
postfix: '_input',
|
|
16
|
+
}).addFields({
|
|
17
|
+
fields: [
|
|
18
|
+
toInputObjectType(Field.clone('create_directus_collections_fields'), { postfix: '_input' }).NonNull,
|
|
19
|
+
],
|
|
20
|
+
}).NonNull,
|
|
21
|
+
},
|
|
22
|
+
resolve: async (_, args) => {
|
|
23
|
+
const collectionsService = new CollectionsService({
|
|
24
|
+
accountability: gql.accountability,
|
|
25
|
+
schema: gql.schema,
|
|
26
|
+
});
|
|
27
|
+
const collectionKey = await collectionsService.createOne(args['data']);
|
|
28
|
+
return await collectionsService.readOne(collectionKey);
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
update_collections_item: {
|
|
32
|
+
type: Collection,
|
|
33
|
+
args: {
|
|
34
|
+
collection: new GraphQLNonNull(GraphQLString),
|
|
35
|
+
data: toInputObjectType(Collection.clone('update_directus_collections'), {
|
|
36
|
+
postfix: '_input',
|
|
37
|
+
}).removeField(['collection', 'schema']).NonNull,
|
|
38
|
+
},
|
|
39
|
+
resolve: async (_, args) => {
|
|
40
|
+
const collectionsService = new CollectionsService({
|
|
41
|
+
accountability: gql.accountability,
|
|
42
|
+
schema: gql.schema,
|
|
43
|
+
});
|
|
44
|
+
const collectionKey = await collectionsService.updateOne(args['collection'], args['data']);
|
|
45
|
+
return await collectionsService.readOne(collectionKey);
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
delete_collections_item: {
|
|
49
|
+
type: schemaComposer.createObjectTC({
|
|
50
|
+
name: 'delete_collection',
|
|
51
|
+
fields: {
|
|
52
|
+
collection: GraphQLString,
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
args: {
|
|
56
|
+
collection: new GraphQLNonNull(GraphQLString),
|
|
57
|
+
},
|
|
58
|
+
resolve: async (_, args) => {
|
|
59
|
+
const collectionsService = new CollectionsService({
|
|
60
|
+
accountability: gql.accountability,
|
|
61
|
+
schema: gql.schema,
|
|
62
|
+
});
|
|
63
|
+
await collectionsService.deleteOne(args['collection']);
|
|
64
|
+
return { collection: args['collection'] };
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
schemaComposer.Mutation.addFields({
|
|
69
|
+
create_fields_item: {
|
|
70
|
+
type: Field,
|
|
71
|
+
args: {
|
|
72
|
+
collection: new GraphQLNonNull(GraphQLString),
|
|
73
|
+
data: toInputObjectType(Field.clone('create_directus_fields'), { postfix: '_input' }).NonNull,
|
|
74
|
+
},
|
|
75
|
+
resolve: async (_, args) => {
|
|
76
|
+
const service = new FieldsService({
|
|
77
|
+
accountability: gql.accountability,
|
|
78
|
+
schema: gql.schema,
|
|
79
|
+
});
|
|
80
|
+
await service.createField(args['collection'], args['data']);
|
|
81
|
+
return await service.readOne(args['collection'], args['data'].field);
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
update_fields_item: {
|
|
85
|
+
type: Field,
|
|
86
|
+
args: {
|
|
87
|
+
collection: new GraphQLNonNull(GraphQLString),
|
|
88
|
+
field: new GraphQLNonNull(GraphQLString),
|
|
89
|
+
data: toInputObjectType(Field.clone('update_directus_fields'), { postfix: '_input' }).NonNull,
|
|
90
|
+
},
|
|
91
|
+
resolve: async (_, args) => {
|
|
92
|
+
const service = new FieldsService({
|
|
93
|
+
accountability: gql.accountability,
|
|
94
|
+
schema: gql.schema,
|
|
95
|
+
});
|
|
96
|
+
await service.updateField(args['collection'], {
|
|
97
|
+
...args['data'],
|
|
98
|
+
field: args['field'],
|
|
99
|
+
});
|
|
100
|
+
return await service.readOne(args['collection'], args['data'].field);
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
delete_fields_item: {
|
|
104
|
+
type: schemaComposer.createObjectTC({
|
|
105
|
+
name: 'delete_field',
|
|
106
|
+
fields: {
|
|
107
|
+
collection: GraphQLString,
|
|
108
|
+
field: GraphQLString,
|
|
109
|
+
},
|
|
110
|
+
}),
|
|
111
|
+
args: {
|
|
112
|
+
collection: new GraphQLNonNull(GraphQLString),
|
|
113
|
+
field: new GraphQLNonNull(GraphQLString),
|
|
114
|
+
},
|
|
115
|
+
resolve: async (_, args) => {
|
|
116
|
+
const service = new FieldsService({
|
|
117
|
+
accountability: gql.accountability,
|
|
118
|
+
schema: gql.schema,
|
|
119
|
+
});
|
|
120
|
+
await service.deleteField(args['collection'], args['field']);
|
|
121
|
+
const { collection, field } = args;
|
|
122
|
+
return { collection, field };
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
schemaComposer.Mutation.addFields({
|
|
127
|
+
create_relations_item: {
|
|
128
|
+
type: Relation,
|
|
129
|
+
args: {
|
|
130
|
+
data: toInputObjectType(Relation.clone('create_directus_relations'), { postfix: '_input' }).NonNull,
|
|
131
|
+
},
|
|
132
|
+
resolve: async (_, args) => {
|
|
133
|
+
const relationsService = new RelationsService({
|
|
134
|
+
accountability: gql.accountability,
|
|
135
|
+
schema: gql.schema,
|
|
136
|
+
});
|
|
137
|
+
await relationsService.createOne(args['data']);
|
|
138
|
+
return await relationsService.readOne(args['data'].collection, args['data'].field);
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
update_relations_item: {
|
|
142
|
+
type: Relation,
|
|
143
|
+
args: {
|
|
144
|
+
collection: new GraphQLNonNull(GraphQLString),
|
|
145
|
+
field: new GraphQLNonNull(GraphQLString),
|
|
146
|
+
data: toInputObjectType(Relation.clone('update_directus_relations'), { postfix: '_input' }).NonNull,
|
|
147
|
+
},
|
|
148
|
+
resolve: async (_, args) => {
|
|
149
|
+
const relationsService = new RelationsService({
|
|
150
|
+
accountability: gql.accountability,
|
|
151
|
+
schema: gql.schema,
|
|
152
|
+
});
|
|
153
|
+
await relationsService.updateOne(args['collection'], args['field'], args['data']);
|
|
154
|
+
return await relationsService.readOne(args['data'].collection, args['data'].field);
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
delete_relations_item: {
|
|
158
|
+
type: schemaComposer.createObjectTC({
|
|
159
|
+
name: 'delete_relation',
|
|
160
|
+
fields: {
|
|
161
|
+
collection: GraphQLString,
|
|
162
|
+
field: GraphQLString,
|
|
163
|
+
},
|
|
164
|
+
}),
|
|
165
|
+
args: {
|
|
166
|
+
collection: new GraphQLNonNull(GraphQLString),
|
|
167
|
+
field: new GraphQLNonNull(GraphQLString),
|
|
168
|
+
},
|
|
169
|
+
resolve: async (_, args) => {
|
|
170
|
+
const relationsService = new RelationsService({
|
|
171
|
+
accountability: gql.accountability,
|
|
172
|
+
schema: gql.schema,
|
|
173
|
+
});
|
|
174
|
+
await relationsService.deleteOne(args['collection'], args['field']);
|
|
175
|
+
return { collection: args['collection'], field: args['field'] };
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
Extension.addFields({
|
|
180
|
+
bundle: GraphQLString,
|
|
181
|
+
name: new GraphQLNonNull(GraphQLString),
|
|
182
|
+
schema: schemaComposer.createObjectTC({
|
|
183
|
+
name: 'directus_extensions_schema',
|
|
184
|
+
fields: {
|
|
185
|
+
type: GraphQLString,
|
|
186
|
+
local: GraphQLBoolean,
|
|
187
|
+
},
|
|
188
|
+
}),
|
|
189
|
+
meta: schemaComposer.createObjectTC({
|
|
190
|
+
name: 'directus_extensions_meta',
|
|
191
|
+
fields: {
|
|
192
|
+
enabled: GraphQLBoolean,
|
|
193
|
+
},
|
|
194
|
+
}),
|
|
195
|
+
});
|
|
196
|
+
schemaComposer.Query.addFields({
|
|
197
|
+
extensions: {
|
|
198
|
+
type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(Extension.getType()))),
|
|
199
|
+
resolve: async () => {
|
|
200
|
+
const service = new ExtensionsService({
|
|
201
|
+
accountability: gql.accountability,
|
|
202
|
+
schema: gql.schema,
|
|
203
|
+
});
|
|
204
|
+
return await service.readAll();
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
schemaComposer.Mutation.addFields({
|
|
209
|
+
update_extensions_item: {
|
|
210
|
+
type: Extension,
|
|
211
|
+
args: {
|
|
212
|
+
id: GraphQLID,
|
|
213
|
+
data: toInputObjectType(schemaComposer.createObjectTC({
|
|
214
|
+
name: 'update_directus_extensions_input',
|
|
215
|
+
fields: {
|
|
216
|
+
meta: schemaComposer.createObjectTC({
|
|
217
|
+
name: 'update_directus_extensions_input_meta',
|
|
218
|
+
fields: {
|
|
219
|
+
enabled: GraphQLBoolean,
|
|
220
|
+
},
|
|
221
|
+
}),
|
|
222
|
+
},
|
|
223
|
+
})),
|
|
224
|
+
},
|
|
225
|
+
resolve: async (_, args) => {
|
|
226
|
+
const extensionsService = new ExtensionsService({
|
|
227
|
+
accountability: gql.accountability,
|
|
228
|
+
schema: gql.schema,
|
|
229
|
+
});
|
|
230
|
+
await extensionsService.updateOne(args['id'], args['data']);
|
|
231
|
+
return await extensionsService.readOne(args['id']);
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SchemaComposer } from 'graphql-compose';
|
|
2
|
+
import type { GraphQLParams } from '../../../types/index.js';
|
|
3
|
+
import { GraphQLService } from '../index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Globally available mutations
|
|
6
|
+
*/
|
|
7
|
+
export declare function globalResolvers(gql: GraphQLService, schemaComposer: SchemaComposer<GraphQLParams['contextValue']>): void;
|