@directus/api
Version:
Directus is a real-time API and App dashboard for managing SQL database content
266 lines (264 loc) • 8.99 kB
JavaScript
import { RelationsService } from "../../relations.js";
import { ExtensionsService } from "../../extensions.js";
import { FieldsService, systemFieldUpdateSchema } from "../../fields.js";
import { getCollectionType } from "./get-collection-type.js";
import { getFieldType } from "./get-field-type.js";
import { getRelationType } from "./get-relation-type.js";
import "../index.js";
import { CollectionsService } from "../../collections.js";
import { InvalidPayloadError } from "@directus/errors";
import { isSystemField } from "@directus/system-data";
import { GraphQLBoolean, GraphQLID, GraphQLList, GraphQLNonNull, GraphQLString } from "graphql";
import { SchemaComposer, toInputObjectType } from "graphql-compose";
//#region src/services/graphql/resolvers/system-admin.ts
function resolveSystemAdmin(gql, schema, schemaComposer) {
if (!gql.accountability?.admin) return;
const Collection = getCollectionType(schemaComposer, schema, "write");
const Field = getFieldType(schemaComposer, schema, "write");
const Relation = getRelationType(schemaComposer, schema, "write");
schemaComposer.Mutation.addFields({
create_collections_item: {
type: Collection,
args: {
data: toInputObjectType(Collection, { postfix: "_input" }).addFields({ fields: [toInputObjectType(Field, { postfix: "_input" }).NonNull] }).NonNull,
concurrentIndexCreation: {
type: GraphQLBoolean,
defaultValue: false
}
},
resolve: async (_, args) => {
const collectionsService = new CollectionsService({
accountability: gql.accountability,
schema: gql.schema
});
const collectionKey = await collectionsService.createOne(args["data"], { attemptConcurrentIndex: Boolean(args["concurrentIndexCreation"]) });
return await collectionsService.readOne(collectionKey);
}
},
update_collections_item: {
type: Collection,
args: {
collection: new GraphQLNonNull(GraphQLString),
data: toInputObjectType(Collection, { postfix: "_input" }).removeField(["collection", "schema"]).NonNull
},
resolve: async (_, args) => {
const collectionsService = new CollectionsService({
accountability: gql.accountability,
schema: gql.schema
});
const collectionKey = await collectionsService.updateOne(args["collection"], args["data"]);
return await collectionsService.readOne(collectionKey);
}
},
delete_collections_item: {
type: schemaComposer.createObjectTC({
name: "delete_collection",
fields: { collection: GraphQLString }
}),
args: { collection: new GraphQLNonNull(GraphQLString) },
resolve: async (_, args) => {
await new CollectionsService({
accountability: gql.accountability,
schema: gql.schema
}).deleteOne(args["collection"]);
return { collection: args["collection"] };
}
}
});
schemaComposer.Mutation.addFields({
create_fields_item: {
type: Field,
args: {
collection: new GraphQLNonNull(GraphQLString),
data: toInputObjectType(Field, { postfix: "_input" }).NonNull,
concurrentIndexCreation: {
type: GraphQLBoolean,
defaultValue: false
}
},
resolve: async (_, args) => {
const service = new FieldsService({
accountability: gql.accountability,
schema: gql.schema
});
await service.createField(args["collection"], args["data"], void 0, { attemptConcurrentIndex: Boolean(args["concurrentIndexCreation"]) });
return await service.readOne(args["collection"], args["data"].field);
}
},
update_fields_item: {
type: Field,
args: {
collection: new GraphQLNonNull(GraphQLString),
field: new GraphQLNonNull(GraphQLString),
data: toInputObjectType(Field, { postfix: "_input" }).NonNull,
concurrentIndexCreation: {
type: GraphQLBoolean,
defaultValue: false
}
},
resolve: async (_, args) => {
const service = new FieldsService({
accountability: gql.accountability,
schema: gql.schema
});
if (isSystemField(args["collection"], args["field"])) {
if (!systemFieldUpdateSchema.safeParse(args["data"]).success) throw new InvalidPayloadError({ reason: "Only \"schema.is_indexed\" may be modified for system fields" });
}
await service.updateField(args["collection"], {
...args["data"],
field: args["field"]
}, { attemptConcurrentIndex: Boolean(args["concurrentIndexCreation"]) });
return await service.readOne(args["collection"], args["field"]);
}
},
update_fields_items: {
type: Field,
args: {
collection: new GraphQLNonNull(GraphQLString),
data: [toInputObjectType(Field, { postfix: "_input" }).NonNull],
concurrentIndexCreation: {
type: GraphQLBoolean,
defaultValue: false
}
},
resolve: async (_, args) => {
const service = new FieldsService({
accountability: gql.accountability,
schema: gql.schema
});
for (const fieldData of args["data"]) if (isSystemField(args["collection"], fieldData["field"])) {
if (!systemFieldUpdateSchema.safeParse(fieldData).success) throw new InvalidPayloadError({ reason: "Only \"schema.is_indexed\" may be modified for system fields" });
}
await service.updateFields(args["collection"], args["data"], { attemptConcurrentIndex: Boolean(args["concurrentIndexCreation"]) });
return await service.readOne(args["collection"], args["field"]);
}
},
delete_fields_item: {
type: schemaComposer.createObjectTC({
name: "delete_field",
fields: {
collection: GraphQLString,
field: GraphQLString
}
}),
args: {
collection: new GraphQLNonNull(GraphQLString),
field: new GraphQLNonNull(GraphQLString)
},
resolve: async (_, args) => {
await new FieldsService({
accountability: gql.accountability,
schema: gql.schema
}).deleteField(args["collection"], args["field"]);
const { collection, field } = args;
return {
collection,
field
};
}
}
});
schemaComposer.Mutation.addFields({
create_relations_item: {
type: Relation,
args: { data: toInputObjectType(Relation, { postfix: "_input" }).NonNull },
resolve: async (_, args) => {
const relationsService = new RelationsService({
accountability: gql.accountability,
schema: gql.schema
});
await relationsService.createOne(args["data"]);
return await relationsService.readOne(args["data"].collection, args["data"].field);
}
},
update_relations_item: {
type: Relation,
args: {
collection: new GraphQLNonNull(GraphQLString),
field: new GraphQLNonNull(GraphQLString),
data: toInputObjectType(Relation, { postfix: "_input" }).NonNull
},
resolve: async (_, args) => {
const relationsService = new RelationsService({
accountability: gql.accountability,
schema: gql.schema
});
await relationsService.updateOne(args["collection"], args["field"], args["data"]);
return await relationsService.readOne(args["data"].collection, args["data"].field);
}
},
delete_relations_item: {
type: schemaComposer.createObjectTC({
name: "delete_relation",
fields: {
collection: GraphQLString,
field: GraphQLString
}
}),
args: {
collection: new GraphQLNonNull(GraphQLString),
field: new GraphQLNonNull(GraphQLString)
},
resolve: async (_, args) => {
await new RelationsService({
accountability: gql.accountability,
schema: gql.schema
}).deleteOne(args["collection"], args["field"]);
return {
collection: args["collection"],
field: args["field"]
};
}
}
});
const Extension = schemaComposer.createObjectTC({
name: "directus_extensions",
fields: {
bundle: GraphQLString,
name: new GraphQLNonNull(GraphQLString),
schema: schemaComposer.createObjectTC({
name: "directus_extensions_schema",
fields: {
type: GraphQLString,
local: GraphQLBoolean
}
}),
meta: schemaComposer.createObjectTC({
name: "directus_extensions_meta",
fields: { enabled: GraphQLBoolean }
})
}
});
schemaComposer.Query.addFields({ extensions: {
type: new GraphQLNonNull(new GraphQLList(new GraphQLNonNull(Extension.getType()))),
resolve: async () => {
return await new ExtensionsService({
accountability: gql.accountability,
schema: gql.schema
}).readAll();
}
} });
schemaComposer.Mutation.addFields({ update_extensions_item: {
type: Extension,
args: {
id: GraphQLID,
data: toInputObjectType(schemaComposer.createObjectTC({
name: "update_directus_extensions_input",
fields: { meta: schemaComposer.createObjectTC({
name: "update_directus_extensions_input_meta",
fields: { enabled: GraphQLBoolean }
}) }
}))
},
resolve: async (_, args) => {
const extensionsService = new ExtensionsService({
accountability: gql.accountability,
schema: gql.schema
});
await extensionsService.updateOne(args["id"], args["data"]);
return await extensionsService.readOne(args["id"]);
}
} });
}
//#endregion
export { resolveSystemAdmin };