Skip to content

Commit

Permalink
feat(api-headless-cms): add getExecutableSchema utility
Browse files Browse the repository at this point in the history
  • Loading branch information
Pavel910 committed Apr 25, 2024
1 parent cf397c5 commit a7220b5
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ErrorResponse, Response } from "@webiny/handler-graphql";
import { CmsGraphQLSchemaPlugin } from "~/index";
import { createCmsGraphQLSchemaPlugin } from "~/index";
import { ACO_TEST_MODEL_ID } from "./model";
import { CmsContext } from "~/types";

const createUpdateLocationGraphQlPlugin = () => {
const plugin = new CmsGraphQLSchemaPlugin({
const plugin = createCmsGraphQLSchemaPlugin<CmsContext>({
typeDefs: /* GraphQL */ `
type UpdateTestAcoModelLocationResponse {
data: TestAcoModel
Expand Down
45 changes: 44 additions & 1 deletion packages/api-headless-cms/src/context.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { CmsContext, HeadlessCmsStorageOperations } from "~/types";
import { ApiEndpoint, CmsContext, HeadlessCmsStorageOperations } from "~/types";
import WebinyError from "@webiny/error";
import { ContextPlugin } from "@webiny/api";
import { GraphQLRequestBody } from "@webiny/handler-graphql/types";
import { processRequestBody } from "@webiny/handler-graphql";
import { CmsParametersPlugin, CmsParametersPluginResponse } from "~/plugins/CmsParametersPlugin";
import { AccessControl } from "~/crud/AccessControl/AccessControl";
import { createSystemCrud } from "~/crud/system.crud";
Expand All @@ -11,6 +13,7 @@ import { StorageOperationsCmsModelPlugin } from "~/plugins";
import { createCmsModelFieldConvertersAttachFactory } from "~/utils/converters/valueKeyStorageConverter";
import { createExportCrud } from "~/export";
import { createImportCrud } from "~/export/crud/importing";
import { getSchema } from "~/graphql/getSchema";

const getParameters = async (context: CmsContext): Promise<CmsParametersPluginResponse> => {
const plugins = context.plugins.byType<CmsParametersPlugin>(CmsParametersPlugin.type);
Expand Down Expand Up @@ -58,6 +61,45 @@ export const createContextPlugin = ({ storageOperations }: CrudParams) => {
return context.tenancy.getCurrentTenant();
};

const setSchemaType = (type: ApiEndpoint | null) => {
if (!type) {
return;
}

context.cms.type = type;

switch (type) {
case "read":
context.cms.READ = true;
break;
case "preview":
context.cms.PREVIEW = true;
break;
default:
context.cms.MANAGE = true;
}
};

async function getExecutableSchema(type: ApiEndpoint) {
const originalType = context.cms.type;
setSchemaType(type);

const schema = await context.security.withoutAuthorization(() => {
return getSchema({
context,
getTenant,
getLocale,
type
});
});

setSchemaType(originalType);

return async <TData, TExtensions>(input: GraphQLRequestBody | GraphQLRequestBody[]) => {
return processRequestBody<TData, TExtensions>(input, schema, context);
};
}

context.plugins.register(
new StorageOperationsCmsModelPlugin(
createCmsModelFieldConvertersAttachFactory(context.plugins)
Expand Down Expand Up @@ -89,6 +131,7 @@ export const createContextPlugin = ({ storageOperations }: CrudParams) => {
MANAGE: type === "manage",
storageOperations,
accessControl,
getExecutableSchema,
...createSystemCrud({
context,
getTenant,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { GraphQLSchemaPlugin } from "@webiny/handler-graphql";
import { GraphQLSchemaPlugin, GraphQLSchemaPluginConfig } from "@webiny/handler-graphql";
import { Context } from "@webiny/api/types";
import { CmsContext } from "~/types";

export class CmsGraphQLSchemaPlugin<T = CmsContext> extends GraphQLSchemaPlugin<T> {
public static override type = "cms.graphql.schema";
}

export const createCmsGraphQLSchemaPlugin = <TContext = Context>(
params: GraphQLSchemaPluginConfig<TContext>
) => {
return new CmsGraphQLSchemaPlugin<TContext>(params);
};
12 changes: 11 additions & 1 deletion packages/api-headless-cms/src/types/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Plugin } from "@webiny/plugins/types";
import { I18NContext, I18NLocale } from "@webiny/api-i18n/types";
import { Context } from "@webiny/api/types";
import { GraphQLFieldResolver, Resolvers } from "@webiny/handler-graphql/types";
import { GraphQLFieldResolver, GraphQLRequestBody, Resolvers } from "@webiny/handler-graphql/types";
import { processRequestBody } from "@webiny/handler-graphql";
import { SecurityPermission } from "@webiny/api-security/types";
import { DbContext } from "@webiny/handler-db/types";
import { Topic } from "@webiny/pubsub/types";
Expand Down Expand Up @@ -62,8 +63,17 @@ export interface HeadlessCms
*/
export: HeadlessCmsExport;
importing: HeadlessCmsImport;
getExecutableSchema: GetExecutableSchema;
}

export type GetExecutableSchema = (
type: ApiEndpoint
) => Promise<
<TData = Record<string, any>, TExtensions = Record<string, any>>(
input: GraphQLRequestBody | GraphQLRequestBody[]
) => ReturnType<typeof processRequestBody<TData, TExtensions>>
>;

/**
* @description This combines all contexts used in the CMS into a single one.
*
Expand Down

0 comments on commit a7220b5

Please sign in to comment.