Skip to content

Commit

Permalink
fix(api-file-manager): cms fields graphql definitions (#3519)
Browse files Browse the repository at this point in the history
  • Loading branch information
brunozoric committed Sep 13, 2023
1 parent d6a2253 commit 77a9474
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 5 deletions.
114 changes: 114 additions & 0 deletions packages/api-file-manager/__tests__/file.extensions.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import useGqlHandler from "~tests/utils/useGqlHandler";
import { createFileModelModifier } from "~/modelModifier/CmsModelModifier";
import { fileAData } from "./mocks/files";

describe("File Model Extensions", () => {
const { listFiles, createFile } = useGqlHandler({
plugins: [
// Add custom fields that will be assigned to the `extensions` object field.
createFileModelModifier(({ modifier }) => {
modifier.addField({
id: "carMake",
fieldId: "carMake",
label: "Car Make",
type: "text"
});

modifier.addField({
id: "year",
fieldId: "year",
label: "Year of manufacturing",
type: "number"
});
modifier.addField({
id: "aDateTime",
fieldId: "aDateTime",
type: "datetime",
label: "A date time field",
renderer: {
name: "date-time-input"
},
settings: {
type: "dateTimeWithoutTimezone",
defaultSetValue: "current"
}
});
modifier.addField({
id: "article",
fieldId: "article",
label: "Article",
type: "ref",
renderer: {
name: "ref-advanced-single"
},
settings: {
models: [
{
modelId: "article"
}
]
}
});
})
]
});

it("should add custom fields to `extensions` object field", async () => {
const extensions = {
carMake: "Honda",
year: 2018,
aDateTime: "2020-01-01T00:00:00.000Z",
article: {
modelId: "article",
id: "abcdefg#0001"
}
};
const fields = ["extensions { carMake year aDateTime article { id modelId } }"];

const [createAResponse] = await createFile(
{
data: {
...fileAData,
extensions
}
},
fields
);
expect(createAResponse).toEqual({
data: {
fileManager: {
createFile: {
data: {
...fileAData,
extensions
},
error: null
}
}
}
});

const [listResponse] = await listFiles({}, fields);

expect(listResponse).toEqual({
data: {
fileManager: {
listFiles: {
data: [
{
...fileAData,
extensions
}
],
meta: {
totalCount: 1,
hasMoreItems: false,
cursor: null
},
error: null
}
}
}
});
});
});
16 changes: 16 additions & 0 deletions packages/api-file-manager/__tests__/fileSchema.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ describe("File Model Modifier test", () => {
label: "Year of manufacturing",
type: "number"
});
modifier.addField({
id: "article",
fieldId: "article",
label: "Article",
type: "ref",
renderer: {
name: "ref-advanced-single"
},
settings: {
models: [
{
modelId: "article"
}
]
}
});
})
]
});
Expand Down
4 changes: 4 additions & 0 deletions packages/api-file-manager/__tests__/mocks/file.sdl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export default /* GraphQL */ `
type FmFile_Extensions {
carMake: String
year: Number
article: RefField
}
input FmFile_ExtensionsWhereInput {
Expand All @@ -88,6 +89,8 @@ export default /* GraphQL */ `
year_between: [Number!]
# there must be two numbers sent in the array
year_not_between: [Number!]
article: RefFieldWhereInput
}
type FmFile {
Expand Down Expand Up @@ -121,6 +124,7 @@ export default /* GraphQL */ `
input FmFile_ExtensionsInput {
carMake: String
year: Number
article: RefFieldInput
}
input FmFileCreateInput {
Expand Down
17 changes: 16 additions & 1 deletion packages/api-file-manager/src/graphql/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { CmsModel } from "@webiny/api-headless-cms/types";
import { createFieldTypePluginRecords } from "@webiny/api-headless-cms/graphql/schema/createFieldTypePluginRecords";
import { createFilesSchema } from "~/graphql/filesSchema";
import { isInstallationPending } from "~/cmsFileStorage/isInstallationPending";
import { createGraphQLSchemaPluginFromFieldPlugins } from "@webiny/api-headless-cms/utils/getSchemaFromFieldPlugins";
import { GraphQLSchemaPlugin } from "@webiny/handler-graphql";

export const createGraphQLSchemaPlugin = () => {
return [
Expand All @@ -20,14 +22,27 @@ export const createGraphQLSchemaPlugin = () => {
const fileModel = (await context.cms.getModel("fmFile")) as CmsModel;
const models = await context.cms.listModels();
const fieldPlugins = createFieldTypePluginRecords(context.plugins);
/**
* We need to register all plugins for all the CMS fields.
*/
const plugins = createGraphQLSchemaPluginFromFieldPlugins({
models,
type: "manage",
fieldTypePlugins: fieldPlugins,
createPlugin: ({ schema, type, fieldType }) => {
const plugin = new GraphQLSchemaPlugin(schema);
plugin.name = `fm.graphql.schema.${type}.field.${fieldType}`;
return plugin;
}
});

const graphQlPlugin = createFilesSchema({
model: fileModel,
models,
plugins: fieldPlugins
});

context.plugins.register(graphQlPlugin);
context.plugins.register([...plugins, graphQlPlugin]);
});
})
];
Expand Down
32 changes: 28 additions & 4 deletions packages/api-headless-cms/src/utils/getSchemaFromFieldPlugins.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,38 @@
import { CmsModel, CmsFieldTypePlugins, ApiEndpoint } from "~/types";
import { ApiEndpoint, CmsContext, CmsFieldTypePlugins, CmsModel } from "~/types";
import { CmsGraphQLSchemaPlugin } from "~/plugins";
import { GraphQLSchemaPlugin } from "@webiny/handler-graphql";
import { GraphQLSchemaDefinition } from "@webiny/handler-graphql/types";

const TYPE_MAP: Record<string, "manage" | "read"> = {
preview: "read",
read: "read",
manage: "manage"
};

interface CreatePluginCallableParams {
schema: GraphQLSchemaDefinition<CmsContext>;
type: "manage" | "preview" | "read";
fieldType: string;
}

interface CreatePluginCallable {
(params: CreatePluginCallableParams): GraphQLSchemaPlugin<CmsContext>;
}

const defaultCreatePlugin: CreatePluginCallable = ({ schema, type, fieldType }) => {
const plugin = new CmsGraphQLSchemaPlugin(schema);
plugin.name = `headless-cms.graphql.schema.${type}.field.${fieldType}`;
return plugin;
};

interface Params {
models: CmsModel[];
fieldTypePlugins: CmsFieldTypePlugins;
type: ApiEndpoint;
createPlugin?: CreatePluginCallable;
}
export const createGraphQLSchemaPluginFromFieldPlugins = (params: Params) => {
const { models, fieldTypePlugins, type } = params;
const { models, fieldTypePlugins, type, createPlugin = defaultCreatePlugin } = params;

const plugins: CmsGraphQLSchemaPlugin[] = [];
for (const key in fieldTypePlugins) {
Expand All @@ -28,8 +47,13 @@ export const createGraphQLSchemaPluginFromFieldPlugins = (params: Params) => {
}
const schema = createSchema({ models });

const plugin = new CmsGraphQLSchemaPlugin(schema);
plugin.name = `headless-cms.graphql.schema.${type}.field.${fieldTypePlugin.fieldType}`;
// const plugin = new CmsGraphQLSchemaPlugin(schema);
// plugin.name = `headless-cms.graphql.schema.${type}.field.${fieldTypePlugin.fieldType}`;
const plugin = createPlugin({
schema,
type,
fieldType: fieldTypePlugin.fieldType
});
plugins.push(plugin);
}
return plugins;
Expand Down

0 comments on commit 77a9474

Please sign in to comment.