Skip to content

Commit

Permalink
feat: introduce createCmsModelPlugin and createCmsGroupPlugin (#4089
Browse files Browse the repository at this point in the history
)
  • Loading branch information
adrians5j authored Apr 25, 2024
1 parent 59ebecf commit d68658b
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,7 @@ describe("content model plugins", () => {
fieldId: "something",
id: "something",
label: "Something",
storageId: "text@something",
storageId: "text@something!",
settings: {}
}
],
Expand All @@ -707,7 +707,7 @@ describe("content model plugins", () => {
}
expect(error).toBeInstanceOf(Error);
expect(error?.message).toEqual(
`Field's "storageId" of the field with "fieldId" something is not camel cased string in the content model "test".`
`Invalid storageId provided ("text@something!"). Only alphanumeric characters and "@" are allowed.`
);
});

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import lodashCamelCase from "lodash/camelCase";
import WebinyError from "@webiny/error";

// We allow "@" because that's we use it with the `createModelField` function.
const VALID_STORAGE_ID_REGEX = /^([@a-zA-Z-0-9]+)$/;

export const validateStorageId = (storageId: string) => {
if (!storageId.match(VALID_STORAGE_ID_REGEX)) {
const message = [
`Invalid storageId provided ("${storageId}").`,
'Only alphanumeric characters and "@" are allowed.'
].join(" ");

throw new WebinyError(message, "STORAGE_ID_NOT_ALPHANUMERIC_ERROR");
}

// We must do this because in the process of camel casing, Lodash removes the `@`
// character from the string. For example, if we received `text@productName`, we
// would be doing the `text@productName` vs. `textProductName` (camel cased) comparison.
storageId = storageId.replace("@", "");

if (storageId !== lodashCamelCase(storageId)) {
const message = [
`Invalid storageId provided ("${storageId}").`,
"Must be a camelCased string."
].join(" ");

throw new WebinyError(message, "STORAGE_ID_NOT_CAMEL_CASED_ERROR");
}
};
7 changes: 7 additions & 0 deletions packages/api-headless-cms/src/plugins/CmsGroupPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@ export class CmsGroupPlugin extends Plugin {
}
}

/**
* @deprecated Use `createCmsGroupPlugin` instead.
*/
export const createCmsGroup = (group: CmsGroup): CmsGroupPlugin => {
return new CmsGroupPlugin(group);
};

export const createCmsGroupPlugin = (group: CmsGroup): CmsGroupPlugin => {
return new CmsGroupPlugin(group);
};
39 changes: 21 additions & 18 deletions packages/api-headless-cms/src/plugins/CmsModelPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
CmsModelFieldSettings as BaseCmsModelFieldSettings
} from "~/types";
import { createFieldStorageId } from "~/crud/contentModel/createFieldStorageId";
import { validateStorageId } from "~/crud/contentModel/validateStorageId";

const createApiName = (name: string) => {
return upperFirst(camelCase(name));
Expand Down Expand Up @@ -232,24 +233,16 @@ export class CmsModelPlugin extends Plugin {
);
}

let storageId = input.storageId ? lodashCamelCase(input.storageId) : null;
/**
* If defined, storageId MUST be camel cased string - for backward compatibility.
*/
if (
storageId &&
(storageId.match(/^([a-zA-Z-0-9]+)$/) === null || storageId !== input.storageId)
) {
throw new WebinyError(
`Field's "storageId" of the field with "fieldId" ${input.fieldId} is not camel cased string in the content model "${model.modelId}".`,
"STORAGE_ID_NOT_CAMEL_CASED_ERROR",
{
model,
storageId,
field: input
}
);
} else if (!storageId) {
let storageId = input.storageId;
if (storageId) {
try {
validateStorageId(storageId);
} catch (e) {
throw WebinyError.from(e, {
data: { model, storageId, field: input }
});
}
} else {
storageId = createFieldStorageId(input);
}

Expand Down Expand Up @@ -333,13 +326,23 @@ export class CmsModelPlugin extends Plugin {
}
}

/**
* @deprecated Use `createCmsModelPlugin` instead.
*/
export const createCmsModel = (
model: CmsModelInput,
options?: CmsModelPluginOptions
): CmsModelPlugin => {
return new CmsModelPlugin(model, options);
};

export const createCmsModelPlugin = (
model: CmsModelInput,
options?: CmsModelPluginOptions
): CmsModelPlugin => {
return new CmsModelPlugin(model, options);
};

export const createPrivateModel = (
input: Omit<CmsPrivateModelFull, "group" | "isPrivate">
): CmsPrivateModelFull => {
Expand Down

0 comments on commit d68658b

Please sign in to comment.