@webiny/api-headless-cms 6.0.0-rc.2 → 6.0.0-rc.4
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/crud/contentEntry/searchableFields.js +6 -2
- package/crud/contentEntry/searchableFields.js.map +1 -1
- package/crud/contentModel/validation.d.ts +9 -9
- package/crud/contentModel/validation.js +3 -3
- package/crud/contentModel/validation.js.map +1 -1
- package/domain/contentModel/errors.d.ts +1 -1
- package/domain/contentModel/errors.js.map +1 -1
- package/domain/contentModel/schemas.d.ts +126 -8
- package/domain/contentModel/schemas.js +12 -13
- package/domain/contentModel/schemas.js.map +1 -1
- package/export/graphql/index.js +1 -1
- package/export/graphql/index.js.map +1 -1
- package/features/contentEntry/GetUniqueFieldValues/GetUniqueFieldValuesUseCase.d.ts +2 -2
- package/features/contentEntry/GetUniqueFieldValues/GetUniqueFieldValuesUseCase.js +3 -4
- package/features/contentEntry/GetUniqueFieldValues/GetUniqueFieldValuesUseCase.js.map +1 -1
- package/features/contentModel/CreateModel/CreateModelRepository.js +4 -1
- package/features/contentModel/CreateModel/CreateModelRepository.js.map +1 -1
- package/features/contentModel/CreateModelFrom/CreateModelFromRepository.js +12 -3
- package/features/contentModel/CreateModelFrom/CreateModelFromRepository.js.map +1 -1
- package/features/contentModel/UpdateModel/UpdateModelRepository.js +8 -2
- package/features/contentModel/UpdateModel/UpdateModelRepository.js.map +1 -1
- package/features/contentModel/UpdateModel/UpdateModelUseCase.js +4 -1
- package/features/contentModel/UpdateModel/UpdateModelUseCase.js.map +1 -1
- package/features/modelBuilder/feature.js +2 -2
- package/features/modelBuilder/feature.js.map +1 -1
- package/features/modelBuilder/fields/BaseFieldBuilder.d.ts +36 -0
- package/features/modelBuilder/fields/BaseFieldBuilder.js +41 -0
- package/features/modelBuilder/fields/BaseFieldBuilder.js.map +1 -0
- package/features/modelBuilder/fields/DataFieldBuilder.d.ts +228 -0
- package/features/modelBuilder/fields/DataFieldBuilder.js +219 -0
- package/features/modelBuilder/fields/DataFieldBuilder.js.map +1 -0
- package/features/modelBuilder/fields/DynamicZoneFieldType.d.ts +2 -2
- package/features/modelBuilder/fields/DynamicZoneFieldType.js +6 -3
- package/features/modelBuilder/fields/DynamicZoneFieldType.js.map +1 -1
- package/features/modelBuilder/fields/FieldBuilder.d.ts +5 -228
- package/features/modelBuilder/fields/FieldBuilder.js +3 -231
- package/features/modelBuilder/fields/FieldBuilder.js.map +1 -1
- package/features/modelBuilder/fields/LayoutFieldBuilder.d.ts +7 -0
- package/features/modelBuilder/fields/LayoutFieldBuilder.js +9 -0
- package/features/modelBuilder/fields/LayoutFieldBuilder.js.map +1 -0
- package/features/modelBuilder/fields/ObjectFieldType.d.ts +4 -3
- package/features/modelBuilder/fields/ObjectFieldType.js +19 -4
- package/features/modelBuilder/fields/ObjectFieldType.js.map +1 -1
- package/features/modelBuilder/fields/UiAlertFieldType.d.ts +8 -4
- package/features/modelBuilder/fields/UiAlertFieldType.js +23 -6
- package/features/modelBuilder/fields/UiAlertFieldType.js.map +1 -1
- package/features/modelBuilder/fields/UiSeparatorFieldType.d.ts +6 -4
- package/features/modelBuilder/fields/UiSeparatorFieldType.js +18 -4
- package/features/modelBuilder/fields/UiSeparatorFieldType.js.map +1 -1
- package/features/modelBuilder/fields/UiTabsFieldType.d.ts +28 -0
- package/features/modelBuilder/fields/UiTabsFieldType.js +75 -0
- package/features/modelBuilder/fields/UiTabsFieldType.js.map +1 -0
- package/features/modelBuilder/fields/abstractions.d.ts +2 -2
- package/features/modelBuilder/fields/abstractions.js.map +1 -1
- package/features/modelBuilder/index.d.ts +2 -0
- package/features/modelBuilder/index.js +2 -0
- package/features/modelBuilder/index.js.map +1 -1
- package/features/modelBuilder/models/BaseModelBuilder.d.ts +8 -3
- package/features/modelBuilder/models/BaseModelBuilder.js +19 -0
- package/features/modelBuilder/models/BaseModelBuilder.js.map +1 -1
- package/features/modelBuilder/models/PrivateModelBuilder.js +4 -2
- package/features/modelBuilder/models/PrivateModelBuilder.js.map +1 -1
- package/features/modelBuilder/models/PublicModelBuilder.js +16 -11
- package/features/modelBuilder/models/PublicModelBuilder.js.map +1 -1
- package/graphql/schema/cms/helpers/index.d.ts +1 -0
- package/graphql/schema/cms/helpers/index.js +1 -0
- package/graphql/schema/cms/helpers/index.js.map +1 -1
- package/graphql/schema/cms/helpers/transformWhereToNested.d.ts +17 -0
- package/graphql/schema/cms/helpers/transformWhereToNested.js +54 -0
- package/graphql/schema/cms/helpers/transformWhereToNested.js.map +1 -0
- package/graphql/schema/cms/helpers.d.ts +1 -0
- package/graphql/schema/cms/helpers.js +1 -0
- package/graphql/schema/cms/helpers.js.map +1 -1
- package/graphql/schema/cms/listEntriesResolver.js +6 -2
- package/graphql/schema/cms/listEntriesResolver.js.map +1 -1
- package/graphql/schema/contentModels.js +21 -3
- package/graphql/schema/contentModels.js.map +1 -1
- package/graphqlFields/index.js +1 -2
- package/graphqlFields/index.js.map +1 -1
- package/package.json +20 -20
- package/plugins/CmsModelPlugin.js +19 -4
- package/plugins/CmsModelPlugin.js.map +1 -1
- package/types/fields/objectField.d.ts +2 -0
- package/types/fields/objectField.js.map +1 -1
- package/types/model.d.ts +32 -3
- package/types/model.js.map +1 -1
- package/types/modelField.d.ts +19 -3
- package/types/modelField.js.map +1 -1
- package/utils/createModelField.js +4 -2
- package/utils/createModelField.js.map +1 -1
- package/features/modelBuilder/fields/UiFieldType.d.ts +0 -18
- package/features/modelBuilder/fields/UiFieldType.js +0 -25
- package/features/modelBuilder/fields/UiFieldType.js.map +0 -1
- package/graphqlFields/ui.d.ts +0 -2
- package/graphqlFields/ui.js +0 -32
- package/graphqlFields/ui.js.map +0 -1
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transforms a flat where object with dot-notation keys into a nested object.
|
|
3
|
+
* Keys without dots are passed through unchanged.
|
|
4
|
+
* Handles logical operators (AND, OR) recursively.
|
|
5
|
+
*
|
|
6
|
+
* @param where - Where clause object potentially containing dot-notation keys
|
|
7
|
+
* @returns Nested where object compatible with the GraphQL ListWhereInput type
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* transformWhereToNested({ "values.name": "Keyboard", id: "abc" })
|
|
11
|
+
* // Returns: { values: { name: "Keyboard" }, id: "abc" }
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* transformWhereToNested({ "values.price_gt": 100, "values.name_contains": "board" })
|
|
15
|
+
* // Returns: { values: { price_gt: 100, name_contains: "board" } }
|
|
16
|
+
*/
|
|
17
|
+
export const transformWhereToNested = where => {
|
|
18
|
+
if (!where) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
const result = {};
|
|
22
|
+
for (const [key, value] of Object.entries(where)) {
|
|
23
|
+
// Handle logical operators recursively.
|
|
24
|
+
if (key === "AND" || key === "OR") {
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
result[key] = value.map(item => transformWhereToNested(item));
|
|
27
|
+
} else {
|
|
28
|
+
result[key] = value;
|
|
29
|
+
}
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const dotIndex = key.indexOf(".");
|
|
33
|
+
if (dotIndex === -1) {
|
|
34
|
+
// No dot — pass through unchanged.
|
|
35
|
+
result[key] = value;
|
|
36
|
+
} else {
|
|
37
|
+
// Dot-notation key — expand into nested object.
|
|
38
|
+
const head = key.slice(0, dotIndex);
|
|
39
|
+
const tail = key.slice(dotIndex + 1);
|
|
40
|
+
if (result[head] === undefined) {
|
|
41
|
+
result[head] = {};
|
|
42
|
+
}
|
|
43
|
+
const nested = result[head];
|
|
44
|
+
// Recursively expand in case of multiple levels of nesting.
|
|
45
|
+
const expanded = transformWhereToNested({
|
|
46
|
+
[tail]: value
|
|
47
|
+
});
|
|
48
|
+
Object.assign(nested, expanded);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=transformWhereToNested.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["transformWhereToNested","where","undefined","result","key","value","Object","entries","Array","isArray","map","item","dotIndex","indexOf","head","slice","tail","nested","expanded","assign"],"sources":["transformWhereToNested.ts"],"sourcesContent":["/**\n * Transforms a flat where object with dot-notation keys into a nested object.\n * Keys without dots are passed through unchanged.\n * Handles logical operators (AND, OR) recursively.\n *\n * @param where - Where clause object potentially containing dot-notation keys\n * @returns Nested where object compatible with the GraphQL ListWhereInput type\n *\n * @example\n * transformWhereToNested({ \"values.name\": \"Keyboard\", id: \"abc\" })\n * // Returns: { values: { name: \"Keyboard\" }, id: \"abc\" }\n *\n * @example\n * transformWhereToNested({ \"values.price_gt\": 100, \"values.name_contains\": \"board\" })\n * // Returns: { values: { price_gt: 100, name_contains: \"board\" } }\n */\nexport const transformWhereToNested = (\n where?: Record<string, unknown>\n): Record<string, unknown> | undefined => {\n if (!where) {\n return undefined;\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(where)) {\n // Handle logical operators recursively.\n if (key === \"AND\" || key === \"OR\") {\n if (Array.isArray(value)) {\n result[key] = value.map(item =>\n transformWhereToNested(item as Record<string, unknown>)\n );\n } else {\n result[key] = value;\n }\n continue;\n }\n\n const dotIndex = key.indexOf(\".\");\n if (dotIndex === -1) {\n // No dot — pass through unchanged.\n result[key] = value;\n } else {\n // Dot-notation key — expand into nested object.\n const head = key.slice(0, dotIndex);\n const tail = key.slice(dotIndex + 1);\n\n if (result[head] === undefined) {\n result[head] = {};\n }\n\n const nested = result[head] as Record<string, unknown>;\n // Recursively expand in case of multiple levels of nesting.\n const expanded = transformWhereToNested({ [tail]: value }) as Record<string, unknown>;\n Object.assign(nested, expanded);\n }\n }\n\n return result;\n};\n"],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,sBAAsB,GAC/BC,KAA+B,IACO;EACtC,IAAI,CAACA,KAAK,EAAE;IACR,OAAOC,SAAS;EACpB;EAEA,MAAMC,MAA+B,GAAG,CAAC,CAAC;EAE1C,KAAK,MAAM,CAACC,GAAG,EAAEC,KAAK,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACN,KAAK,CAAC,EAAE;IAC9C;IACA,IAAIG,GAAG,KAAK,KAAK,IAAIA,GAAG,KAAK,IAAI,EAAE;MAC/B,IAAII,KAAK,CAACC,OAAO,CAACJ,KAAK,CAAC,EAAE;QACtBF,MAAM,CAACC,GAAG,CAAC,GAAGC,KAAK,CAACK,GAAG,CAACC,IAAI,IACxBX,sBAAsB,CAACW,IAA+B,CAC1D,CAAC;MACL,CAAC,MAAM;QACHR,MAAM,CAACC,GAAG,CAAC,GAAGC,KAAK;MACvB;MACA;IACJ;IAEA,MAAMO,QAAQ,GAAGR,GAAG,CAACS,OAAO,CAAC,GAAG,CAAC;IACjC,IAAID,QAAQ,KAAK,CAAC,CAAC,EAAE;MACjB;MACAT,MAAM,CAACC,GAAG,CAAC,GAAGC,KAAK;IACvB,CAAC,MAAM;MACH;MACA,MAAMS,IAAI,GAAGV,GAAG,CAACW,KAAK,CAAC,CAAC,EAAEH,QAAQ,CAAC;MACnC,MAAMI,IAAI,GAAGZ,GAAG,CAACW,KAAK,CAACH,QAAQ,GAAG,CAAC,CAAC;MAEpC,IAAIT,MAAM,CAACW,IAAI,CAAC,KAAKZ,SAAS,EAAE;QAC5BC,MAAM,CAACW,IAAI,CAAC,GAAG,CAAC,CAAC;MACrB;MAEA,MAAMG,MAAM,GAAGd,MAAM,CAACW,IAAI,CAA4B;MACtD;MACA,MAAMI,QAAQ,GAAGlB,sBAAsB,CAAC;QAAE,CAACgB,IAAI,GAAGX;MAAM,CAAC,CAA4B;MACrFC,MAAM,CAACa,MAAM,CAACF,MAAM,EAAEC,QAAQ,CAAC;IACnC;EACJ;EAEA,OAAOf,MAAM;AACjB,CAAC","ignoreList":[]}
|
|
@@ -2,3 +2,4 @@ export { getErrorMessage } from "./helpers/getErrorMessage.js";
|
|
|
2
2
|
export { getModel } from "./helpers/getModel.js";
|
|
3
3
|
export { transformSortToArray } from "./helpers/transformSortToArray.js";
|
|
4
4
|
export { buildFieldsSelection } from "./helpers/buildFieldsSelection.js";
|
|
5
|
+
export { transformWhereToNested } from "./helpers/transformWhereToNested.js";
|
|
@@ -2,5 +2,6 @@ export { getErrorMessage } from "./helpers/getErrorMessage.js";
|
|
|
2
2
|
export { getModel } from "./helpers/getModel.js";
|
|
3
3
|
export { transformSortToArray } from "./helpers/transformSortToArray.js";
|
|
4
4
|
export { buildFieldsSelection } from "./helpers/buildFieldsSelection.js";
|
|
5
|
+
export { transformWhereToNested } from "./helpers/transformWhereToNested.js";
|
|
5
6
|
|
|
6
7
|
//# sourceMappingURL=helpers.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["getErrorMessage","getModel","transformSortToArray","buildFieldsSelection"],"sources":["helpers.ts"],"sourcesContent":["export { getErrorMessage } from \"./helpers/getErrorMessage.js\";\nexport { getModel } from \"./helpers/getModel.js\";\nexport { transformSortToArray } from \"./helpers/transformSortToArray.js\";\nexport { buildFieldsSelection } from \"./helpers/buildFieldsSelection.js\";\n"],"mappings":"AAAA,SAASA,eAAe;AACxB,SAASC,QAAQ;AACjB,SAASC,oBAAoB;AAC7B,SAASC,oBAAoB","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["getErrorMessage","getModel","transformSortToArray","buildFieldsSelection","transformWhereToNested"],"sources":["helpers.ts"],"sourcesContent":["export { getErrorMessage } from \"./helpers/getErrorMessage.js\";\nexport { getModel } from \"./helpers/getModel.js\";\nexport { transformSortToArray } from \"./helpers/transformSortToArray.js\";\nexport { buildFieldsSelection } from \"./helpers/buildFieldsSelection.js\";\nexport { transformWhereToNested } from \"./helpers/transformWhereToNested.js\";\n"],"mappings":"AAAA,SAASA,eAAe;AACxB,SAASC,QAAQ;AACjB,SAASC,oBAAoB;AAC7B,SAASC,oBAAoB;AAC7B,SAASC,sBAAsB","ignoreList":[]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getModel, getErrorMessage, buildFieldsSelection, transformSortToArray } from "./helpers.js";
|
|
1
|
+
import { getModel, getErrorMessage, buildFieldsSelection, transformSortToArray, transformWhereToNested } from "./helpers.js";
|
|
2
2
|
export const createListEntriesResolver = () => {
|
|
3
3
|
return async ({
|
|
4
4
|
args,
|
|
@@ -25,6 +25,10 @@ export const createListEntriesResolver = () => {
|
|
|
25
25
|
// Transform sort to array format expected by the underlying GraphQL schema.
|
|
26
26
|
// Handles both object format {createdOn: "desc"} and array format ["createdOn_DESC"].
|
|
27
27
|
const transformedSort = transformSortToArray(sort);
|
|
28
|
+
|
|
29
|
+
// Transform dot-notation where keys (e.g. "values.name") into nested objects
|
|
30
|
+
// (e.g. { values: { name: ... } }) so they match the typed ListWhereInput.
|
|
31
|
+
const transformedWhere = transformWhereToNested(where);
|
|
28
32
|
const query = /* GraphQL */`
|
|
29
33
|
query List${model.pluralApiName}(
|
|
30
34
|
$where: ${model.singularApiName}ListWhereInput
|
|
@@ -57,7 +61,7 @@ export const createListEntriesResolver = () => {
|
|
|
57
61
|
const result = await executeSchema({
|
|
58
62
|
query,
|
|
59
63
|
variables: {
|
|
60
|
-
where,
|
|
64
|
+
where: transformedWhere,
|
|
61
65
|
sort: transformedSort,
|
|
62
66
|
limit,
|
|
63
67
|
after
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["getModel","getErrorMessage","buildFieldsSelection","transformSortToArray","createListEntriesResolver","args","context","modelId","where","sort","limit","after","fields","preview","model","apiType","executeSchema","cms","getExecutableSchema","fieldsSelection","transformedSort","query","pluralApiName","singularApiName","result","variables","operationName","data","meta","cursor","hasMoreItems","totalCount","error","message","code"],"sources":["listEntriesResolver.ts"],"sourcesContent":["import type { CmsContext } from \"~/types/index.js\";\nimport type { ApiEndpoint } from \"~/types/index.js\";\nimport type { ExecutionResult } from \"graphql\";\nimport {\n getModel,\n getErrorMessage,\n buildFieldsSelection,\n transformSortToArray\n} from \"./helpers.js\";\n\nexport interface ListEntriesArgs {\n modelId: string;\n where?: Record<string, unknown>;\n sort?: Record<string, unknown> | string[];\n limit?: number;\n after?: string;\n fields: string[];\n preview?: boolean;\n}\n\nexport const createListEntriesResolver = () => {\n return async ({ args, context }: { args: ListEntriesArgs; context: CmsContext }) => {\n const { modelId, where, sort, limit, after, fields, preview = false } = args;\n\n try {\n const model = await getModel(context, modelId);\n\n // Determine which API to use based on the preview flag.\n // preview=true -> preview API, preview=false -> read API\n const apiType: ApiEndpoint = preview ? \"preview\" : \"read\";\n const executeSchema = await context.cms.getExecutableSchema(apiType);\n\n const fieldsSelection = buildFieldsSelection(fields);\n\n // Transform sort to array format expected by the underlying GraphQL schema.\n // Handles both object format {createdOn: \"desc\"} and array format [\"createdOn_DESC\"].\n const transformedSort = transformSortToArray(sort);\n\n const query = /* GraphQL */ `\n query List${model.pluralApiName}(\n $where: ${model.singularApiName}ListWhereInput\n $sort: [${model.singularApiName}ListSorter!]\n $limit: Int\n $after: String\n ) {\n list${model.pluralApiName}(\n where: $where\n sort: $sort\n limit: $limit\n after: $after\n ) {\n data {\n ${fieldsSelection}\n }\n meta {\n cursor\n hasMoreItems\n totalCount\n }\n error {\n message\n code\n data\n }\n }\n }\n `;\n\n const result = (await executeSchema({\n query,\n variables: { where, sort: transformedSort, limit, after }\n })) as ExecutionResult;\n\n const operationName = `list${model.pluralApiName}`;\n return (\n result.data?.[operationName] || {\n data: [],\n meta: { cursor: null, hasMoreItems: false, totalCount: 0 },\n error: null\n }\n );\n } catch (error) {\n return {\n data: [],\n meta: { cursor: null, hasMoreItems: false, totalCount: 0 },\n error: {\n message: getErrorMessage(error, \"Failed to list entries\"),\n code: \"LIST_ENTRIES_ERROR\"\n }\n };\n }\n };\n};\n"],"mappings":"AAGA,SACIA,QAAQ,EACRC,eAAe,EACfC,oBAAoB,EACpBC,oBAAoB;
|
|
1
|
+
{"version":3,"names":["getModel","getErrorMessage","buildFieldsSelection","transformSortToArray","transformWhereToNested","createListEntriesResolver","args","context","modelId","where","sort","limit","after","fields","preview","model","apiType","executeSchema","cms","getExecutableSchema","fieldsSelection","transformedSort","transformedWhere","query","pluralApiName","singularApiName","result","variables","operationName","data","meta","cursor","hasMoreItems","totalCount","error","message","code"],"sources":["listEntriesResolver.ts"],"sourcesContent":["import type { CmsContext } from \"~/types/index.js\";\nimport type { ApiEndpoint } from \"~/types/index.js\";\nimport type { ExecutionResult } from \"graphql\";\nimport {\n getModel,\n getErrorMessage,\n buildFieldsSelection,\n transformSortToArray,\n transformWhereToNested\n} from \"./helpers.js\";\n\nexport interface ListEntriesArgs {\n modelId: string;\n where?: Record<string, unknown>;\n sort?: Record<string, unknown> | string[];\n limit?: number;\n after?: string;\n fields: string[];\n preview?: boolean;\n}\n\nexport const createListEntriesResolver = () => {\n return async ({ args, context }: { args: ListEntriesArgs; context: CmsContext }) => {\n const { modelId, where, sort, limit, after, fields, preview = false } = args;\n\n try {\n const model = await getModel(context, modelId);\n\n // Determine which API to use based on the preview flag.\n // preview=true -> preview API, preview=false -> read API\n const apiType: ApiEndpoint = preview ? \"preview\" : \"read\";\n const executeSchema = await context.cms.getExecutableSchema(apiType);\n\n const fieldsSelection = buildFieldsSelection(fields);\n\n // Transform sort to array format expected by the underlying GraphQL schema.\n // Handles both object format {createdOn: \"desc\"} and array format [\"createdOn_DESC\"].\n const transformedSort = transformSortToArray(sort);\n\n // Transform dot-notation where keys (e.g. \"values.name\") into nested objects\n // (e.g. { values: { name: ... } }) so they match the typed ListWhereInput.\n const transformedWhere = transformWhereToNested(where);\n\n const query = /* GraphQL */ `\n query List${model.pluralApiName}(\n $where: ${model.singularApiName}ListWhereInput\n $sort: [${model.singularApiName}ListSorter!]\n $limit: Int\n $after: String\n ) {\n list${model.pluralApiName}(\n where: $where\n sort: $sort\n limit: $limit\n after: $after\n ) {\n data {\n ${fieldsSelection}\n }\n meta {\n cursor\n hasMoreItems\n totalCount\n }\n error {\n message\n code\n data\n }\n }\n }\n `;\n\n const result = (await executeSchema({\n query,\n variables: { where: transformedWhere, sort: transformedSort, limit, after }\n })) as ExecutionResult;\n\n const operationName = `list${model.pluralApiName}`;\n return (\n result.data?.[operationName] || {\n data: [],\n meta: { cursor: null, hasMoreItems: false, totalCount: 0 },\n error: null\n }\n );\n } catch (error) {\n return {\n data: [],\n meta: { cursor: null, hasMoreItems: false, totalCount: 0 },\n error: {\n message: getErrorMessage(error, \"Failed to list entries\"),\n code: \"LIST_ENTRIES_ERROR\"\n }\n };\n }\n };\n};\n"],"mappings":"AAGA,SACIA,QAAQ,EACRC,eAAe,EACfC,oBAAoB,EACpBC,oBAAoB,EACpBC,sBAAsB;AAa1B,OAAO,MAAMC,yBAAyB,GAAGA,CAAA,KAAM;EAC3C,OAAO,OAAO;IAAEC,IAAI;IAAEC;EAAwD,CAAC,KAAK;IAChF,MAAM;MAAEC,OAAO;MAAEC,KAAK;MAAEC,IAAI;MAAEC,KAAK;MAAEC,KAAK;MAAEC,MAAM;MAAEC,OAAO,GAAG;IAAM,CAAC,GAAGR,IAAI;IAE5E,IAAI;MACA,MAAMS,KAAK,GAAG,MAAMf,QAAQ,CAACO,OAAO,EAAEC,OAAO,CAAC;;MAE9C;MACA;MACA,MAAMQ,OAAoB,GAAGF,OAAO,GAAG,SAAS,GAAG,MAAM;MACzD,MAAMG,aAAa,GAAG,MAAMV,OAAO,CAACW,GAAG,CAACC,mBAAmB,CAACH,OAAO,CAAC;MAEpE,MAAMI,eAAe,GAAGlB,oBAAoB,CAACW,MAAM,CAAC;;MAEpD;MACA;MACA,MAAMQ,eAAe,GAAGlB,oBAAoB,CAACO,IAAI,CAAC;;MAElD;MACA;MACA,MAAMY,gBAAgB,GAAGlB,sBAAsB,CAACK,KAAK,CAAC;MAEtD,MAAMc,KAAK,GAAG,aAAc;AACxC,4BAA4BR,KAAK,CAACS,aAAa;AAC/C,8BAA8BT,KAAK,CAACU,eAAe;AACnD,8BAA8BV,KAAK,CAACU,eAAe;AACnD;AACA;AACA;AACA,0BAA0BV,KAAK,CAACS,aAAa;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8BJ,eAAe;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;MAED,MAAMM,MAAM,GAAI,MAAMT,aAAa,CAAC;QAChCM,KAAK;QACLI,SAAS,EAAE;UAAElB,KAAK,EAAEa,gBAAgB;UAAEZ,IAAI,EAAEW,eAAe;UAAEV,KAAK;UAAEC;QAAM;MAC9E,CAAC,CAAqB;MAEtB,MAAMgB,aAAa,GAAG,OAAOb,KAAK,CAACS,aAAa,EAAE;MAClD,OACIE,MAAM,CAACG,IAAI,GAAGD,aAAa,CAAC,IAAI;QAC5BC,IAAI,EAAE,EAAE;QACRC,IAAI,EAAE;UAAEC,MAAM,EAAE,IAAI;UAAEC,YAAY,EAAE,KAAK;UAAEC,UAAU,EAAE;QAAE,CAAC;QAC1DC,KAAK,EAAE;MACX,CAAC;IAET,CAAC,CAAC,OAAOA,KAAK,EAAE;MACZ,OAAO;QACHL,IAAI,EAAE,EAAE;QACRC,IAAI,EAAE;UAAEC,MAAM,EAAE,IAAI;UAAEC,YAAY,EAAE,KAAK;UAAEC,UAAU,EAAE;QAAE,CAAC;QAC1DC,KAAK,EAAE;UACHC,OAAO,EAAElC,eAAe,CAACiC,KAAK,EAAE,wBAAwB,CAAC;UACzDE,IAAI,EAAE;QACV;MACJ,CAAC;IACL;EACJ,CAAC;AACL,CAAC","ignoreList":[]}
|
|
@@ -121,6 +121,14 @@ export const createModelsSchema = ({
|
|
|
121
121
|
settings: JSON
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
input CmsFieldRuleInput {
|
|
125
|
+
type: String!
|
|
126
|
+
target: String!
|
|
127
|
+
operator: String!
|
|
128
|
+
value: JSON
|
|
129
|
+
action: String!
|
|
130
|
+
}
|
|
131
|
+
|
|
124
132
|
input CmsContentModelFieldInput {
|
|
125
133
|
id: ID!
|
|
126
134
|
label: String!
|
|
@@ -140,6 +148,7 @@ export const createModelsSchema = ({
|
|
|
140
148
|
validation: [CmsFieldValidationInput]
|
|
141
149
|
listValidation: [CmsFieldValidationInput]
|
|
142
150
|
settings: JSON
|
|
151
|
+
rules: [CmsFieldRuleInput!]
|
|
143
152
|
}
|
|
144
153
|
|
|
145
154
|
input CmsContentModelCreateInput {
|
|
@@ -151,7 +160,7 @@ export const createModelsSchema = ({
|
|
|
151
160
|
icon: Icon
|
|
152
161
|
singleEntry: Boolean
|
|
153
162
|
description: String
|
|
154
|
-
layout:
|
|
163
|
+
layout: JSON
|
|
155
164
|
fields: [CmsContentModelFieldInput!]
|
|
156
165
|
titleFieldId: String
|
|
157
166
|
descriptionFieldId: String
|
|
@@ -177,7 +186,7 @@ export const createModelsSchema = ({
|
|
|
177
186
|
group: String
|
|
178
187
|
icon: Icon
|
|
179
188
|
description: String
|
|
180
|
-
layout:
|
|
189
|
+
layout: JSON!
|
|
181
190
|
fields: [CmsContentModelFieldInput!]!
|
|
182
191
|
titleFieldId: String
|
|
183
192
|
descriptionFieldId: String
|
|
@@ -226,6 +235,14 @@ export const createModelsSchema = ({
|
|
|
226
235
|
values: [CmsPredefinedValue]
|
|
227
236
|
}
|
|
228
237
|
|
|
238
|
+
type CmsFieldRule {
|
|
239
|
+
type: String!
|
|
240
|
+
target: String!
|
|
241
|
+
operator: String!
|
|
242
|
+
value: JSON
|
|
243
|
+
action: String!
|
|
244
|
+
}
|
|
245
|
+
|
|
229
246
|
type CmsContentModelField {
|
|
230
247
|
id: ID!
|
|
231
248
|
# auto-generated value
|
|
@@ -245,6 +262,7 @@ export const createModelsSchema = ({
|
|
|
245
262
|
validation: [CmsFieldValidation!]
|
|
246
263
|
listValidation: [CmsFieldValidation!]
|
|
247
264
|
settings: JSON
|
|
265
|
+
rules: [CmsFieldRule!]
|
|
248
266
|
}
|
|
249
267
|
|
|
250
268
|
type CmsContentModel {
|
|
@@ -259,7 +277,7 @@ export const createModelsSchema = ({
|
|
|
259
277
|
savedOn: DateTime
|
|
260
278
|
createdBy: CmsIdentity
|
|
261
279
|
fields: [CmsContentModelField!]!
|
|
262
|
-
layout:
|
|
280
|
+
layout: JSON!
|
|
263
281
|
titleFieldId: String
|
|
264
282
|
descriptionFieldId: String
|
|
265
283
|
imageFieldId: String
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["ErrorResponse","NotFoundError","Response","createCmsGraphQLSchemaPlugin","createModelsSchema","context","resolvers","Query","getContentModel","_","args","model","cms","getModel","modelId","e","listContentModels","models","listModels","includePrivate","includePlugins","CmsContentModelField","renderer","field","settings","tags","Array","isArray","CmsContentModel","hasType","find","tag","startsWith","plugin","isPlugin","manageSchema","MANAGE","createContentModel","createModel","data","createContentModelFrom","createModelFrom","updateContentModel","updateModel","deleteContentModel","deleteModel","typeDefs","name","type"],"sources":["contentModels.ts"],"sourcesContent":["import { ErrorResponse, NotFoundError, Response } from \"@webiny/handler-graphql\";\nimport type { CmsContext, CmsModel } from \"~/types/index.js\";\nimport type { Resolvers } from \"@webiny/handler-graphql/types.js\";\nimport type { ICmsGraphQLSchemaPlugin } from \"~/plugins/index.js\";\nimport { createCmsGraphQLSchemaPlugin } from \"~/plugins/index.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\n\nexport interface CreateModelsSchemaParams {\n context: CmsContext;\n}\n\nexport const createModelsSchema = ({\n context\n}: CreateModelsSchemaParams): ICmsGraphQLSchemaPlugin => {\n const resolvers: Resolvers<CmsContext> = {\n Query: {\n getContentModel: async (_: unknown, args: GenericRecord, context) => {\n try {\n const model = await context.cms.getModel(args.modelId);\n\n if (!model) {\n throw new NotFoundError(`Content model \"${args.modelId}\" was not found!`);\n }\n\n return new Response(model);\n } catch (e) {\n return new ErrorResponse(e);\n }\n },\n listContentModels: async (_: unknown, args: GenericRecord, context: CmsContext) => {\n try {\n const models = await context.cms.listModels({\n includePrivate: false,\n includePlugins: args?.includePlugins === false ? false : true\n });\n return new Response(models);\n } catch (e) {\n return new ErrorResponse(e);\n }\n }\n },\n CmsContentModelField: {\n renderer: field => {\n // Make sure `settings` is an object.\n if (field.renderer) {\n // We're using `||` here, because we want to use the fallback value for both `undefined` and `null`.\n return { ...field.renderer, settings: field.renderer.settings || {} };\n }\n\n return field.renderer;\n },\n tags(field) {\n // Make sure `tags` are always returned as an array.\n return Array.isArray(field.tags) ? field.tags : [];\n }\n },\n CmsContentModel: {\n tags(model: CmsModel) {\n // Make sure `tags` always contain a `type` tag, to differentiate between models.\n const hasType = (model.tags || []).find(tag => tag.startsWith(\"type:\"));\n\n return hasType ? model.tags : [\"type:model\", ...(model.tags || [])];\n },\n plugin: (model: CmsModel) => {\n return model.isPlugin ?? false;\n }\n }\n };\n\n let manageSchema = \"\";\n if (context.cms.MANAGE) {\n resolvers[\"Mutation\"] = {\n createContentModel: async (_: unknown, args: any, context) => {\n try {\n const model = await context.cms.createModel(args.data);\n return new Response(model);\n } catch (e) {\n return new ErrorResponse(e);\n }\n },\n createContentModelFrom: async (_: unknown, args: any, context) => {\n try {\n const model = await context.cms.createModelFrom(args.modelId, args.data);\n return new Response(model);\n } catch (e) {\n return new ErrorResponse(e);\n }\n },\n updateContentModel: async (_: unknown, args: any, context) => {\n const { modelId, data } = args;\n try {\n const model = await context.cms.updateModel(modelId, data);\n return new Response(model);\n } catch (e) {\n return new ErrorResponse(e);\n }\n },\n deleteContentModel: async (_: unknown, args: any, context) => {\n const { modelId } = args;\n try {\n await context.cms.deleteModel(modelId);\n return new Response(true);\n } catch (e) {\n return new ErrorResponse(e);\n }\n }\n };\n\n manageSchema = /* GraphQL */ `\n input CmsPredefinedValueInput {\n label: String!\n value: String!\n selected: Boolean\n }\n\n input CmsPredefinedValuesInput {\n enabled: Boolean\n values: [CmsPredefinedValueInput]\n }\n input CmsFieldRendererInput {\n name: String\n settings: JSON\n }\n\n input CmsFieldValidationInput {\n name: String!\n message: String\n settings: JSON\n }\n\n input CmsContentModelFieldInput {\n id: ID!\n label: String!\n help: String\n description: String\n note: String\n placeholder: String\n # we never use user input - this is here to the GraphQL does not break when posting from our UI\n # used for debugging purposes\n storageId: String\n fieldId: String!\n type: String!\n tags: [String!]\n list: Boolean\n predefinedValues: CmsPredefinedValuesInput\n renderer: CmsFieldRendererInput\n validation: [CmsFieldValidationInput]\n listValidation: [CmsFieldValidationInput]\n settings: JSON\n }\n\n input CmsContentModelCreateInput {\n name: String!\n singularApiName: String!\n pluralApiName: String!\n modelId: String\n group: String!\n icon: Icon\n singleEntry: Boolean\n description: String\n layout: [[ID!]!]\n fields: [CmsContentModelFieldInput!]\n titleFieldId: String\n descriptionFieldId: String\n imageFieldId: String\n tags: [String!]\n defaultFields: Boolean\n }\n\n input CmsContentModelCreateFromInput {\n name: String!\n singularApiName: String!\n pluralApiName: String!\n modelId: String\n group: String!\n icon: Icon\n description: String\n }\n\n input CmsContentModelUpdateInput {\n name: String\n singularApiName: String\n pluralApiName: String\n group: String\n icon: Icon\n description: String\n layout: [[ID!]!]!\n fields: [CmsContentModelFieldInput!]!\n titleFieldId: String\n descriptionFieldId: String\n imageFieldId: String\n tags: [String!]\n }\n\n extend type Mutation {\n createContentModel(data: CmsContentModelCreateInput!): CmsContentModelResponse\n\n createContentModelFrom(\n modelId: ID!\n data: CmsContentModelCreateFromInput!\n ): CmsContentModelResponse\n\n updateContentModel(\n modelId: ID!\n data: CmsContentModelUpdateInput!\n ): CmsContentModelResponse\n\n deleteContentModel(modelId: ID!): CmsDeleteResponse\n }\n `;\n }\n\n const plugin = createCmsGraphQLSchemaPlugin({\n typeDefs: /* GraphQL */ `\n type CmsFieldValidation {\n name: String!\n message: String\n settings: JSON\n }\n\n type CmsFieldRenderer {\n name: String\n settings: JSON\n }\n\n type CmsPredefinedValue {\n label: String\n value: String\n selected: Boolean\n }\n\n type CmsPredefinedValues {\n enabled: Boolean\n values: [CmsPredefinedValue]\n }\n\n type CmsContentModelField {\n id: ID!\n # auto-generated value\n # used for debugging purposes\n storageId: String\n fieldId: String!\n label: String!\n help: String\n description: String\n note: String\n placeholder: String\n type: String!\n tags: [String!]!\n list: Boolean\n predefinedValues: CmsPredefinedValues\n renderer: CmsFieldRenderer\n validation: [CmsFieldValidation!]\n listValidation: [CmsFieldValidation!]\n settings: JSON\n }\n\n type CmsContentModel {\n name: String!\n singularApiName: String!\n pluralApiName: String!\n modelId: String!\n description: String\n group: String!\n icon: Icon\n createdOn: DateTime\n savedOn: DateTime\n createdBy: CmsIdentity\n fields: [CmsContentModelField!]!\n layout: [[String!]!]!\n titleFieldId: String\n descriptionFieldId: String\n imageFieldId: String\n tags: [String!]!\n tenant: String!\n # Returns true if the content model is registered via a plugin.\n plugin: Boolean!\n }\n\n type CmsContentModelResponse {\n data: CmsContentModel\n error: CmsError\n }\n\n type CmsContentModelListResponse {\n data: [CmsContentModel]\n meta: CmsListMeta\n error: CmsError\n }\n\n extend type Query {\n getContentModel(modelId: ID!, where: JSON, sort: String): CmsContentModelResponse\n\n listContentModels(includePlugins: Boolean = true): CmsContentModelListResponse\n }\n\n ${manageSchema}\n `,\n resolvers\n });\n plugin.name = `headless-cms.graphql.schema.${context.cms.type}.content-models`;\n return plugin;\n};\n"],"mappings":"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MAAM;UAAES,OAAO;UAAEyB;QAAK,CAAC,GAAG7B,IAAI;QAC9B,IAAI;UACA,MAAMC,KAAK,GAAG,MAAMN,OAAO,CAACO,GAAG,CAAC+B,WAAW,CAAC7B,OAAO,EAAEyB,IAAI,CAAC;UAC1D,OAAO,IAAIrC,QAAQ,CAACS,KAAK,CAAC;QAC9B,CAAC,CAAC,OAAOI,CAAC,EAAE;UACR,OAAO,IAAIf,aAAa,CAACe,CAAC,CAAC;QAC/B;MACJ,CAAC;MACD6B,kBAAkB,EAAE,MAAAA,CAAOnC,CAAU,EAAEC,IAAS,EAAEL,OAAO,KAAK;QAC1D,MAAM;UAAES;QAAQ,CAAC,GAAGJ,IAAI;QACxB,IAAI;UACA,MAAML,OAAO,CAACO,GAAG,CAACiC,WAAW,CAAC/B,OAAO,CAAC;UACtC,OAAO,IAAIZ,QAAQ,CAAC,IAAI,CAAC;QAC7B,CAAC,CAAC,OAAOa,CAAC,EAAE;UACR,OAAO,IAAIf,aAAa,CAACe,CAAC,CAAC;QAC/B;MACJ;IACJ,CAAC;IAEDoB,YAAY,GAAG,aAAc;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;EACL;EAEA,MAAMF,MAAM,GAAG9B,4BAA4B,CAAC;IACxC2C,QAAQ,EAAE,aAAc;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAcX,YAAY;AAC1B,SAAS;IACD7B;EACJ,CAAC,CAAC;EACF2B,MAAM,CAACc,IAAI,GAAG,+BAA+B1C,OAAO,CAACO,GAAG,CAACoC,IAAI,iBAAiB;EAC9E,OAAOf,MAAM;AACjB,CAAC","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["ErrorResponse","NotFoundError","Response","createCmsGraphQLSchemaPlugin","createModelsSchema","context","resolvers","Query","getContentModel","_","args","model","cms","getModel","modelId","e","listContentModels","models","listModels","includePrivate","includePlugins","CmsContentModelField","renderer","field","settings","tags","Array","isArray","CmsContentModel","hasType","find","tag","startsWith","plugin","isPlugin","manageSchema","MANAGE","createContentModel","createModel","data","createContentModelFrom","createModelFrom","updateContentModel","updateModel","deleteContentModel","deleteModel","typeDefs","name","type"],"sources":["contentModels.ts"],"sourcesContent":["import { ErrorResponse, NotFoundError, Response } from \"@webiny/handler-graphql\";\nimport type { CmsContext, CmsModel } from \"~/types/index.js\";\nimport type { Resolvers } from \"@webiny/handler-graphql/types.js\";\nimport type { ICmsGraphQLSchemaPlugin } from \"~/plugins/index.js\";\nimport { createCmsGraphQLSchemaPlugin } from \"~/plugins/index.js\";\nimport type { GenericRecord } from \"@webiny/api/types.js\";\n\nexport interface CreateModelsSchemaParams {\n context: CmsContext;\n}\n\nexport const createModelsSchema = ({\n context\n}: CreateModelsSchemaParams): ICmsGraphQLSchemaPlugin => {\n const resolvers: Resolvers<CmsContext> = {\n Query: {\n getContentModel: async (_: unknown, args: GenericRecord, context) => {\n try {\n const model = await context.cms.getModel(args.modelId);\n\n if (!model) {\n throw new NotFoundError(`Content model \"${args.modelId}\" was not found!`);\n }\n\n return new Response(model);\n } catch (e) {\n return new ErrorResponse(e);\n }\n },\n listContentModels: async (_: unknown, args: GenericRecord, context: CmsContext) => {\n try {\n const models = await context.cms.listModels({\n includePrivate: false,\n includePlugins: args?.includePlugins === false ? false : true\n });\n return new Response(models);\n } catch (e) {\n return new ErrorResponse(e);\n }\n }\n },\n CmsContentModelField: {\n renderer: field => {\n // Make sure `settings` is an object.\n if (field.renderer) {\n // We're using `||` here, because we want to use the fallback value for both `undefined` and `null`.\n return { ...field.renderer, settings: field.renderer.settings || {} };\n }\n\n return field.renderer;\n },\n tags(field) {\n // Make sure `tags` are always returned as an array.\n return Array.isArray(field.tags) ? field.tags : [];\n }\n },\n CmsContentModel: {\n tags(model: CmsModel) {\n // Make sure `tags` always contain a `type` tag, to differentiate between models.\n const hasType = (model.tags || []).find(tag => tag.startsWith(\"type:\"));\n\n return hasType ? model.tags : [\"type:model\", ...(model.tags || [])];\n },\n plugin: (model: CmsModel) => {\n return model.isPlugin ?? false;\n }\n }\n };\n\n let manageSchema = \"\";\n if (context.cms.MANAGE) {\n resolvers[\"Mutation\"] = {\n createContentModel: async (_: unknown, args: any, context) => {\n try {\n const model = await context.cms.createModel(args.data);\n return new Response(model);\n } catch (e) {\n return new ErrorResponse(e);\n }\n },\n createContentModelFrom: async (_: unknown, args: any, context) => {\n try {\n const model = await context.cms.createModelFrom(args.modelId, args.data);\n return new Response(model);\n } catch (e) {\n return new ErrorResponse(e);\n }\n },\n updateContentModel: async (_: unknown, args: any, context) => {\n const { modelId, data } = args;\n try {\n const model = await context.cms.updateModel(modelId, data);\n return new Response(model);\n } catch (e) {\n return new ErrorResponse(e);\n }\n },\n deleteContentModel: async (_: unknown, args: any, context) => {\n const { modelId } = args;\n try {\n await context.cms.deleteModel(modelId);\n return new Response(true);\n } catch (e) {\n return new ErrorResponse(e);\n }\n }\n };\n\n manageSchema = /* GraphQL */ `\n input CmsPredefinedValueInput {\n label: String!\n value: String!\n selected: Boolean\n }\n\n input CmsPredefinedValuesInput {\n enabled: Boolean\n values: [CmsPredefinedValueInput]\n }\n input CmsFieldRendererInput {\n name: String\n settings: JSON\n }\n\n input CmsFieldValidationInput {\n name: String!\n message: String\n settings: JSON\n }\n\n input CmsFieldRuleInput {\n type: String!\n target: String!\n operator: String!\n value: JSON\n action: String!\n }\n\n input CmsContentModelFieldInput {\n id: ID!\n label: String!\n help: String\n description: String\n note: String\n placeholder: String\n # we never use user input - this is here to the GraphQL does not break when posting from our UI\n # used for debugging purposes\n storageId: String\n fieldId: String!\n type: String!\n tags: [String!]\n list: Boolean\n predefinedValues: CmsPredefinedValuesInput\n renderer: CmsFieldRendererInput\n validation: [CmsFieldValidationInput]\n listValidation: [CmsFieldValidationInput]\n settings: JSON\n rules: [CmsFieldRuleInput!]\n }\n\n input CmsContentModelCreateInput {\n name: String!\n singularApiName: String!\n pluralApiName: String!\n modelId: String\n group: String!\n icon: Icon\n singleEntry: Boolean\n description: String\n layout: JSON\n fields: [CmsContentModelFieldInput!]\n titleFieldId: String\n descriptionFieldId: String\n imageFieldId: String\n tags: [String!]\n defaultFields: Boolean\n }\n\n input CmsContentModelCreateFromInput {\n name: String!\n singularApiName: String!\n pluralApiName: String!\n modelId: String\n group: String!\n icon: Icon\n description: String\n }\n\n input CmsContentModelUpdateInput {\n name: String\n singularApiName: String\n pluralApiName: String\n group: String\n icon: Icon\n description: String\n layout: JSON!\n fields: [CmsContentModelFieldInput!]!\n titleFieldId: String\n descriptionFieldId: String\n imageFieldId: String\n tags: [String!]\n }\n\n extend type Mutation {\n createContentModel(data: CmsContentModelCreateInput!): CmsContentModelResponse\n\n createContentModelFrom(\n modelId: ID!\n data: CmsContentModelCreateFromInput!\n ): CmsContentModelResponse\n\n updateContentModel(\n modelId: ID!\n data: CmsContentModelUpdateInput!\n ): CmsContentModelResponse\n\n deleteContentModel(modelId: ID!): CmsDeleteResponse\n }\n `;\n }\n\n const plugin = createCmsGraphQLSchemaPlugin({\n typeDefs: /* GraphQL */ `\n type CmsFieldValidation {\n name: String!\n message: String\n settings: JSON\n }\n\n type CmsFieldRenderer {\n name: String\n settings: JSON\n }\n\n type CmsPredefinedValue {\n label: String\n value: String\n selected: Boolean\n }\n\n type CmsPredefinedValues {\n enabled: Boolean\n values: [CmsPredefinedValue]\n }\n\n type CmsFieldRule {\n type: String!\n target: String!\n operator: String!\n value: JSON\n action: String!\n }\n\n type CmsContentModelField {\n id: ID!\n # auto-generated value\n # used for debugging purposes\n storageId: String\n fieldId: String!\n label: String!\n help: String\n description: String\n note: String\n placeholder: String\n type: String!\n tags: [String!]!\n list: Boolean\n predefinedValues: CmsPredefinedValues\n renderer: CmsFieldRenderer\n validation: [CmsFieldValidation!]\n listValidation: [CmsFieldValidation!]\n settings: JSON\n rules: [CmsFieldRule!]\n }\n\n type CmsContentModel {\n name: String!\n singularApiName: String!\n pluralApiName: String!\n modelId: String!\n description: String\n group: String!\n icon: Icon\n createdOn: DateTime\n savedOn: DateTime\n createdBy: CmsIdentity\n fields: [CmsContentModelField!]!\n layout: JSON!\n titleFieldId: String\n descriptionFieldId: String\n imageFieldId: String\n tags: [String!]!\n tenant: String!\n # Returns true if the content model is registered via a plugin.\n plugin: Boolean!\n }\n\n type CmsContentModelResponse {\n data: CmsContentModel\n error: CmsError\n }\n\n type CmsContentModelListResponse {\n data: [CmsContentModel]\n meta: CmsListMeta\n error: CmsError\n }\n\n extend type Query {\n getContentModel(modelId: ID!, where: JSON, sort: String): CmsContentModelResponse\n\n listContentModels(includePlugins: Boolean = true): CmsContentModelListResponse\n }\n\n ${manageSchema}\n `,\n resolvers\n });\n plugin.name = `headless-cms.graphql.schema.${context.cms.type}.content-models`;\n return plugin;\n};\n"],"mappings":"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MAAM;UAAES,OAAO;UAAEyB;QAAK,CAAC,GAAG7B,IAAI;QAC9B,IAAI;UACA,MAAMC,KAAK,GAAG,MAAMN,OAAO,CAACO,GAAG,CAAC+B,WAAW,CAAC7B,OAAO,EAAEyB,IAAI,CAAC;UAC1D,OAAO,IAAIrC,QAAQ,CAACS,KAAK,CAAC;QAC9B,CAAC,CAAC,OAAOI,CAAC,EAAE;UACR,OAAO,IAAIf,aAAa,CAACe,CAAC,CAAC;QAC/B;MACJ,CAAC;MACD6B,kBAAkB,EAAE,MAAAA,CAAOnC,CAAU,EAAEC,IAAS,EAAEL,OAAO,KAAK;QAC1D,MAAM;UAAES;QAAQ,CAAC,GAAGJ,IAAI;QACxB,IAAI;UACA,MAAML,OAAO,CAACO,GAAG,CAACiC,WAAW,CAAC/B,OAAO,CAAC;UACtC,OAAO,IAAIZ,QAAQ,CAAC,IAAI,CAAC;QAC7B,CAAC,CAAC,OAAOa,CAAC,EAAE;UACR,OAAO,IAAIf,aAAa,CAACe,CAAC,CAAC;QAC/B;MACJ;IACJ,CAAC;IAEDoB,YAAY,GAAG,aAAc;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;EACL;EAEA,MAAMF,MAAM,GAAG9B,4BAA4B,CAAC;IACxC2C,QAAQ,EAAE,aAAc;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAcX,YAAY;AAC1B,SAAS;IACD7B;EACJ,CAAC,CAAC;EACF2B,MAAM,CAACc,IAAI,GAAG,+BAA+B1C,OAAO,CAACO,GAAG,CAACoC,IAAI,iBAAiB;EAC9E,OAAOf,MAAM;AACjB,CAAC","ignoreList":[]}
|
package/graphqlFields/index.js
CHANGED
|
@@ -10,7 +10,6 @@ import { createObjectField } from "./object.js";
|
|
|
10
10
|
import { createDynamicZoneField } from "./dynamicZone/index.js";
|
|
11
11
|
import { createJsonField } from "./json.js";
|
|
12
12
|
import { createSearchableJsonField } from "./searchableJson.js";
|
|
13
|
-
|
|
14
|
-
export const createGraphQLFields = () => [createTextField(), createRefField(), createNumberField(), createDateTimeField(), createBooleanField(), createLongTextField(), createRichTextField(), createJsonField(), createSearchableJsonField(), createFileField(), createObjectField(), createDynamicZoneField(), createUiField()];
|
|
13
|
+
export const createGraphQLFields = () => [createTextField(), createRefField(), createNumberField(), createDateTimeField(), createBooleanField(), createLongTextField(), createRichTextField(), createJsonField(), createSearchableJsonField(), createFileField(), createObjectField(), createDynamicZoneField()];
|
|
15
14
|
|
|
16
15
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createTextField","createLongTextField","createRefField","createNumberField","createBooleanField","createDateTimeField","createRichTextField","createFileField","createObjectField","createDynamicZoneField","createJsonField","createSearchableJsonField","
|
|
1
|
+
{"version":3,"names":["createTextField","createLongTextField","createRefField","createNumberField","createBooleanField","createDateTimeField","createRichTextField","createFileField","createObjectField","createDynamicZoneField","createJsonField","createSearchableJsonField","createGraphQLFields"],"sources":["index.ts"],"sourcesContent":["import { createTextField } from \"./text.js\";\nimport { createLongTextField } from \"./longText.js\";\nimport { createRefField } from \"./ref.js\";\nimport { createNumberField } from \"./number.js\";\nimport { createBooleanField } from \"./boolean.js\";\nimport { createDateTimeField } from \"./datetime.js\";\nimport { createRichTextField } from \"./richText.js\";\nimport { createFileField } from \"./file.js\";\nimport { createObjectField } from \"./object.js\";\nimport { createDynamicZoneField } from \"./dynamicZone/index.js\";\nimport type { CmsModelFieldToGraphQLPlugin } from \"~/types/index.js\";\nimport { createJsonField } from \"./json.js\";\nimport { createSearchableJsonField } from \"./searchableJson.js\";\n\nexport const createGraphQLFields = (): CmsModelFieldToGraphQLPlugin<any>[] => [\n createTextField(),\n createRefField(),\n createNumberField(),\n createDateTimeField(),\n createBooleanField(),\n createLongTextField(),\n createRichTextField(),\n createJsonField(),\n createSearchableJsonField(),\n createFileField(),\n createObjectField(),\n createDynamicZoneField()\n];\n"],"mappings":"AAAA,SAASA,eAAe;AACxB,SAASC,mBAAmB;AAC5B,SAASC,cAAc;AACvB,SAASC,iBAAiB;AAC1B,SAASC,kBAAkB;AAC3B,SAASC,mBAAmB;AAC5B,SAASC,mBAAmB;AAC5B,SAASC,eAAe;AACxB,SAASC,iBAAiB;AAC1B,SAASC,sBAAsB;AAE/B,SAASC,eAAe;AACxB,SAASC,yBAAyB;AAElC,OAAO,MAAMC,mBAAmB,GAAGA,CAAA,KAA2C,CAC1EZ,eAAe,CAAC,CAAC,EACjBE,cAAc,CAAC,CAAC,EAChBC,iBAAiB,CAAC,CAAC,EACnBE,mBAAmB,CAAC,CAAC,EACrBD,kBAAkB,CAAC,CAAC,EACpBH,mBAAmB,CAAC,CAAC,EACrBK,mBAAmB,CAAC,CAAC,EACrBI,eAAe,CAAC,CAAC,EACjBC,yBAAyB,CAAC,CAAC,EAC3BJ,eAAe,CAAC,CAAC,EACjBC,iBAAiB,CAAC,CAAC,EACnBC,sBAAsB,CAAC,CAAC,CAC3B","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/api-headless-cms",
|
|
3
|
-
"version": "6.0.0-rc.
|
|
3
|
+
"version": "6.0.0-rc.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"keywords": [
|
|
@@ -22,19 +22,19 @@
|
|
|
22
22
|
"@babel/code-frame": "7.29.0",
|
|
23
23
|
"@graphql-tools/merge": "9.1.7",
|
|
24
24
|
"@graphql-tools/schema": "10.0.31",
|
|
25
|
-
"@webiny/api": "6.0.0-rc.
|
|
26
|
-
"@webiny/api-core": "6.0.0-rc.
|
|
25
|
+
"@webiny/api": "6.0.0-rc.4",
|
|
26
|
+
"@webiny/api-core": "6.0.0-rc.4",
|
|
27
27
|
"@webiny/di": "0.2.3",
|
|
28
|
-
"@webiny/error": "6.0.0-rc.
|
|
29
|
-
"@webiny/feature": "6.0.0-rc.
|
|
30
|
-
"@webiny/handler": "6.0.0-rc.
|
|
31
|
-
"@webiny/handler-aws": "6.0.0-rc.
|
|
32
|
-
"@webiny/handler-db": "6.0.0-rc.
|
|
33
|
-
"@webiny/handler-graphql": "6.0.0-rc.
|
|
34
|
-
"@webiny/plugins": "6.0.0-rc.
|
|
35
|
-
"@webiny/project": "6.0.0-rc.
|
|
36
|
-
"@webiny/utils": "6.0.0-rc.
|
|
37
|
-
"@webiny/validation": "6.0.0-rc.
|
|
28
|
+
"@webiny/error": "6.0.0-rc.4",
|
|
29
|
+
"@webiny/feature": "6.0.0-rc.4",
|
|
30
|
+
"@webiny/handler": "6.0.0-rc.4",
|
|
31
|
+
"@webiny/handler-aws": "6.0.0-rc.4",
|
|
32
|
+
"@webiny/handler-db": "6.0.0-rc.4",
|
|
33
|
+
"@webiny/handler-graphql": "6.0.0-rc.4",
|
|
34
|
+
"@webiny/plugins": "6.0.0-rc.4",
|
|
35
|
+
"@webiny/project": "6.0.0-rc.4",
|
|
36
|
+
"@webiny/utils": "6.0.0-rc.4",
|
|
37
|
+
"@webiny/validation": "6.0.0-rc.4",
|
|
38
38
|
"dot-prop-immutable": "2.1.1",
|
|
39
39
|
"graphql": "16.13.0",
|
|
40
40
|
"graphql-tag": "2.12.6",
|
|
@@ -48,13 +48,13 @@
|
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@types/babel__code-frame": "7.27.0",
|
|
50
50
|
"@types/pluralize": "0.0.33",
|
|
51
|
-
"@webiny/aws-sdk": "6.0.0-rc.
|
|
52
|
-
"@webiny/build-tools": "6.0.0-rc.
|
|
53
|
-
"@webiny/db-dynamodb": "6.0.0-rc.
|
|
51
|
+
"@webiny/aws-sdk": "6.0.0-rc.4",
|
|
52
|
+
"@webiny/build-tools": "6.0.0-rc.4",
|
|
53
|
+
"@webiny/db-dynamodb": "6.0.0-rc.4",
|
|
54
54
|
"@webiny/handler-db": "0.0.0",
|
|
55
|
-
"@webiny/project-utils": "6.0.0-rc.
|
|
56
|
-
"@webiny/sdk": "6.0.0-rc.
|
|
57
|
-
"@webiny/wcp": "6.0.0-rc.
|
|
55
|
+
"@webiny/project-utils": "6.0.0-rc.4",
|
|
56
|
+
"@webiny/sdk": "6.0.0-rc.4",
|
|
57
|
+
"@webiny/wcp": "6.0.0-rc.4",
|
|
58
58
|
"apollo-graphql": "0.9.7",
|
|
59
59
|
"graphql": "16.13.0",
|
|
60
60
|
"prettier": "3.6.2",
|
|
@@ -67,5 +67,5 @@
|
|
|
67
67
|
"access": "public",
|
|
68
68
|
"directory": "dist"
|
|
69
69
|
},
|
|
70
|
-
"gitHead": "
|
|
70
|
+
"gitHead": "e2758ee1cfa3b9a7152e9bb995a90ccabd33266f"
|
|
71
71
|
}
|
|
@@ -168,12 +168,27 @@ export class CmsModelPlugin extends Plugin {
|
|
|
168
168
|
if (this.options.validateLayout === false) {
|
|
169
169
|
return;
|
|
170
170
|
}
|
|
171
|
-
|
|
171
|
+
const countFieldInLayout = (fieldId, layout) => {
|
|
172
172
|
let total = 0;
|
|
173
|
-
for (const row of
|
|
174
|
-
|
|
175
|
-
|
|
173
|
+
for (const row of layout) {
|
|
174
|
+
for (const cell of row) {
|
|
175
|
+
if (typeof cell === "string") {
|
|
176
|
+
if (cell === fieldId) {
|
|
177
|
+
total++;
|
|
178
|
+
}
|
|
179
|
+
} else if (cell && typeof cell === "object" && Array.isArray(cell.tabs)) {
|
|
180
|
+
for (const tab of cell.tabs) {
|
|
181
|
+
if (Array.isArray(tab.layout)) {
|
|
182
|
+
total += countFieldInLayout(fieldId, tab.layout);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
176
187
|
}
|
|
188
|
+
return total;
|
|
189
|
+
};
|
|
190
|
+
for (const field of model.fields) {
|
|
191
|
+
const total = countFieldInLayout(field.id, model.layout);
|
|
177
192
|
if (total === 1) {
|
|
178
193
|
continue;
|
|
179
194
|
} else if (total > 1) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["WebinyError","lodashCamelCase","camelCase","upperFirst","pluralize","Plugin","createFieldStorageId","validateStorageId","createApiName","name","createPluralApiName","CmsModelPlugin","type","constructor","contentModel","options","buildModel","input","isPrivate","singularApiName","pluralApiName","modelPlugin","group","description","fields","isPlugin","icon","layout","modelId","titleFieldId","noValidate","model","buildFields","validateLayout","inputFields","length","storageIdList","fieldIdList","fieldId","trim","field","match","includes","id","storageId","e","from","data","settings","childFields","push","total","row","count","filter","cell","createModelPlugin","createPrivateModelPlugin","authorization"],"sources":["CmsModelPlugin.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\nimport lodashCamelCase from \"lodash/camelCase.js\";\nimport camelCase from \"lodash/camelCase.js\";\nimport upperFirst from \"lodash/upperFirst.js\";\nimport pluralize from \"pluralize\";\nimport { Plugin } from \"@webiny/plugins\";\nimport type {\n CmsModel as CmsModelBase,\n CmsModelField as CmsModelFieldBase,\n CmsModelFieldSettings as BaseCmsModelFieldSettings\n} from \"~/types/index.js\";\nimport { createFieldStorageId } from \"~/crud/contentModel/createFieldStorageId.js\";\nimport { validateStorageId } from \"~/crud/contentModel/validateStorageId.js\";\n\nconst createApiName = (name: string) => {\n return upperFirst(camelCase(name));\n};\n\nconst createPluralApiName = (name: string) => {\n return pluralize(createApiName(name));\n};\n\ninterface CmsModelFieldSettings extends Omit<BaseCmsModelFieldSettings, \"fields\"> {\n /**\n * Object field has child fields.\n */\n fields?: CmsModelFieldInput[];\n}\n\ninterface CmsModelFieldInput extends Omit<CmsModelFieldBase, \"storageId\" | \"settings\"> {\n /**\n * If defined, it must be camelCased string.\n * This is for backwards compatibility - before fields had storageId.\n *\n * This should only be populated in old model fields.\n * New ones must have this empty.\n */\n storageId?: string;\n /**\n * We must have a possibility to have a nested field defined without the storageId.\n */\n settings?: CmsModelFieldSettings;\n}\n\nexport interface CmsApiModel\n extends Omit<\n CmsModelPluginModel,\n \"isPrivate\" | \"fields\" | \"singularApiName\" | \"pluralApiName\" | \"isPlugin\"\n > {\n isPrivate?: never;\n noValidate?: boolean;\n singularApiName?: string;\n pluralApiName?: string;\n fields: CmsModelFieldInput[];\n}\n\nexport interface CmsApiModelFull extends Omit<CmsApiModel, \"fields\"> {\n fields: CmsModelFieldBase[];\n}\n\ninterface CmsPrivateModel\n extends Omit<\n CmsModelPluginModel,\n | \"isPrivate\"\n | \"singularApiName\"\n | \"pluralApiName\"\n | \"fields\"\n | \"isPlugin\"\n | \"layout\"\n | \"icon\"\n | \"titleFieldId\"\n | \"description\"\n > {\n noValidate?: boolean;\n titleFieldId?: string;\n singularApiName?: never;\n pluralApiName?: never;\n isPrivate: true;\n fields: CmsModelFieldInput[];\n}\n\nexport interface CmsPrivateModelFull\n extends Omit<CmsPrivateModel, \"fields\" | \"createdBy\" | \"createdOn\" | \"savedOn\"> {\n fields: CmsModelFieldBase[];\n}\n\nexport type CmsModelInput = CmsApiModel | CmsPrivateModel | CmsApiModelFull | CmsPrivateModelFull;\n\nexport interface CmsModelPluginModel extends Omit<CmsModelBase, \"tenant\"> {\n tenant?: string;\n}\n\ninterface CmsModelPluginOptions {\n validateLayout?: boolean;\n}\n\nexport class CmsModelPlugin extends Plugin {\n public static override readonly type: string = \"cms-content-model\";\n public readonly contentModel: CmsModelPluginModel;\n\n private readonly options: CmsModelPluginOptions;\n\n constructor(contentModel: CmsModelInput, options?: CmsModelPluginOptions) {\n super();\n this.options = options || {};\n this.contentModel = this.buildModel(contentModel);\n }\n\n private buildModel(input: CmsModelInput): CmsModelPluginModel {\n const isPrivate = input.isPrivate ?? false;\n\n const singularApiName = input.singularApiName\n ? createApiName(input.singularApiName)\n : createApiName(input.name);\n\n const pluralApiName = input.pluralApiName\n ? createApiName(input.pluralApiName)\n : createPluralApiName(input.name);\n\n const modelPlugin: CmsModelPluginModel = {\n group: input.group ?? \"ungrouped\",\n description: \"\",\n fields: [],\n isPlugin: true,\n isPrivate,\n icon: null,\n layout: [],\n modelId: input.modelId,\n name: input.name,\n pluralApiName,\n singularApiName,\n titleFieldId: \"id\"\n };\n\n if (input.noValidate) {\n /**\n * We can safely ignore this error, because we are sure noValidate is not a model field.\n */\n delete input[\"noValidate\"];\n\n return {\n ...modelPlugin,\n ...input,\n // Since `noValidate` is set, we trust the input, and cast to `CmsModelFieldBase`.\n fields: input.fields as CmsModelFieldBase[],\n pluralApiName,\n singularApiName\n };\n }\n\n const model: CmsModelPluginModel = {\n ...modelPlugin,\n ...input,\n pluralApiName,\n singularApiName,\n fields: this.buildFields(input, input.fields)\n };\n this.validateLayout(model);\n return model;\n }\n\n private buildFields(\n model: CmsModelInput,\n inputFields: CmsModelFieldInput[]\n ): CmsModelFieldBase[] {\n if (inputFields.length === 0) {\n throw new WebinyError(\n `Missing fields for the defined model \"${model.modelId}\".`,\n \"MISSING_FIELDS\",\n {\n model\n }\n );\n }\n const fields: CmsModelFieldBase[] = [];\n const storageIdList: string[] = [];\n const fieldIdList: string[] = [];\n for (const input of inputFields) {\n /**\n * Field must contain an fieldId. It is required in the graphql, but lets check it just in case\n */\n if (!(input.fieldId || \"\").trim()) {\n throw new WebinyError(\n `Field's \"storageId\" is not defined for the content model \"${model.modelId}\".`,\n \"FIELD_ID_ERROR\",\n {\n model,\n field: input\n }\n );\n }\n const fieldId = lodashCamelCase(input.fieldId);\n /**\n * FieldID must be in correct pattern.\n */\n if (fieldId.match(/^[0-9]/) !== null) {\n throw new WebinyError(\n `Field's \"fieldId\" does not match correct pattern in the content model \"${model.modelId}\" - cannot start with a number.`,\n \"FIELD_FIELD_ID_ERROR\",\n {\n model,\n field: input\n }\n );\n }\n /**\n * FieldID also must be camelCased.\n */\n if (fieldId !== input.fieldId) {\n throw new WebinyError(\n `Field's \"fieldId\" must be a camel cased string in the content model \"${model.modelId}\".`,\n \"FIELD_FIELD_ID_ERROR\",\n {\n model,\n field: input\n }\n );\n }\n /**\n * ... and fieldId must be unique.\n */\n if (fieldIdList.includes(fieldId)) {\n throw new WebinyError(\n `Field's \"fieldId\" (id: ${input.id}) is not unique in the content model \"${model.modelId}\".`,\n \"FIELD_ID_NOT_UNIQUE_ERROR\",\n {\n model,\n field: input\n }\n );\n }\n\n let storageId = input.storageId;\n if (storageId) {\n try {\n validateStorageId(storageId);\n } catch (e) {\n throw WebinyError.from(e, {\n data: { model, storageId, field: input }\n });\n }\n } else {\n storageId = createFieldStorageId(input);\n }\n\n /**\n * Fields storageId must be unique.\n */\n if (storageIdList.includes(storageId)) {\n throw new WebinyError(\n `Field's \"storageId\" is not unique in the content model \"${model.modelId}\".`,\n \"STORAGE_ID_ERROR\",\n {\n model,\n field: input\n }\n );\n }\n\n /**\n * We can safely ignore error because we are going through the fields and making sure each has storageId.\n */\n // @ts-expect-error\n let settings: BaseCmsModelFieldSettings = input.settings;\n\n const childFields = settings?.fields || [];\n if (input.type === \"object\" && childFields.length > 0) {\n settings = {\n ...(settings || {}),\n fields: this.buildFields(model, childFields)\n };\n }\n\n const field: CmsModelFieldBase = {\n ...input,\n settings,\n storageId\n };\n /**\n * Add all relevant data to arrays.\n */\n fields.push(field);\n storageIdList.push(field.storageId);\n fieldIdList.push(field.fieldId);\n }\n return fields;\n }\n\n private validateLayout(model: CmsModelPluginModel): void {\n /**\n * Only skip validation if option.validateLayout was set as false, explicitly.\n */\n if (this.options.validateLayout === false) {\n return;\n }\n for (const field of model.fields) {\n let total = 0;\n for (const row of model.layout) {\n const count = row.filter(cell => cell === field.id).length;\n total = total + count;\n }\n if (total === 1) {\n continue;\n } else if (total > 1) {\n throw new WebinyError(\n `Field \"${field.id}\" is in more than one layout cell.`,\n \"DUPLICATE_FIELD_IN_LAYOUT\",\n {\n model,\n field\n }\n );\n }\n throw new WebinyError(\n `Missing field \"${field.id}\" in layout.`,\n \"MISSING_FIELD_IN_LAYOUT\",\n {\n model,\n field\n }\n );\n }\n }\n}\n\n/**\n * IMPORTANT! This function should NOT be used outside the `api-headless-cms` package!\n * @internal\n */\nexport const createModelPlugin = (\n model: CmsModelInput,\n options?: CmsModelPluginOptions\n): CmsModelPlugin => {\n return new CmsModelPlugin(model, options);\n};\n\n/**\n * IMPORTANT! This function should NOT be used outside the `api-headless-cms` package!\n * @internal\n */\nexport const createPrivateModelPlugin = (\n input: Omit<CmsPrivateModelFull, \"group\" | \"isPrivate\">\n): CmsModelPlugin => {\n return createModelPlugin(\n {\n authorization: false,\n noValidate: true,\n isPrivate: true,\n group: \"private\",\n ...input\n },\n {\n validateLayout: false\n }\n );\n};\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["WebinyError","lodashCamelCase","camelCase","upperFirst","pluralize","Plugin","createFieldStorageId","validateStorageId","createApiName","name","createPluralApiName","CmsModelPlugin","type","constructor","contentModel","options","buildModel","input","isPrivate","singularApiName","pluralApiName","modelPlugin","group","description","fields","isPlugin","icon","layout","modelId","titleFieldId","noValidate","model","buildFields","validateLayout","inputFields","length","storageIdList","fieldIdList","fieldId","trim","field","match","includes","id","storageId","e","from","data","settings","childFields","push","countFieldInLayout","total","row","cell","Array","isArray","tabs","tab","createModelPlugin","createPrivateModelPlugin","authorization"],"sources":["CmsModelPlugin.ts"],"sourcesContent":["import WebinyError from \"@webiny/error\";\nimport lodashCamelCase from \"lodash/camelCase.js\";\nimport camelCase from \"lodash/camelCase.js\";\nimport upperFirst from \"lodash/upperFirst.js\";\nimport pluralize from \"pluralize\";\nimport { Plugin } from \"@webiny/plugins\";\nimport type {\n CmsModel as CmsModelBase,\n CmsModelField as CmsModelFieldBase,\n CmsModelFieldSettings as BaseCmsModelFieldSettings\n} from \"~/types/index.js\";\nimport { createFieldStorageId } from \"~/crud/contentModel/createFieldStorageId.js\";\nimport { validateStorageId } from \"~/crud/contentModel/validateStorageId.js\";\n\nconst createApiName = (name: string) => {\n return upperFirst(camelCase(name));\n};\n\nconst createPluralApiName = (name: string) => {\n return pluralize(createApiName(name));\n};\n\ninterface CmsModelFieldSettings extends Omit<BaseCmsModelFieldSettings, \"fields\"> {\n /**\n * Object field has child fields.\n */\n fields?: CmsModelFieldInput[];\n}\n\ninterface CmsModelFieldInput extends Omit<CmsModelFieldBase, \"storageId\" | \"settings\"> {\n /**\n * If defined, it must be camelCased string.\n * This is for backwards compatibility - before fields had storageId.\n *\n * This should only be populated in old model fields.\n * New ones must have this empty.\n */\n storageId?: string;\n /**\n * We must have a possibility to have a nested field defined without the storageId.\n */\n settings?: CmsModelFieldSettings;\n}\n\nexport interface CmsApiModel\n extends Omit<\n CmsModelPluginModel,\n \"isPrivate\" | \"fields\" | \"singularApiName\" | \"pluralApiName\" | \"isPlugin\"\n > {\n isPrivate?: never;\n noValidate?: boolean;\n singularApiName?: string;\n pluralApiName?: string;\n fields: CmsModelFieldInput[];\n}\n\nexport interface CmsApiModelFull extends Omit<CmsApiModel, \"fields\"> {\n fields: CmsModelFieldBase[];\n}\n\ninterface CmsPrivateModel\n extends Omit<\n CmsModelPluginModel,\n | \"isPrivate\"\n | \"singularApiName\"\n | \"pluralApiName\"\n | \"fields\"\n | \"isPlugin\"\n | \"layout\"\n | \"icon\"\n | \"titleFieldId\"\n | \"description\"\n > {\n noValidate?: boolean;\n titleFieldId?: string;\n singularApiName?: never;\n pluralApiName?: never;\n isPrivate: true;\n fields: CmsModelFieldInput[];\n}\n\nexport interface CmsPrivateModelFull\n extends Omit<CmsPrivateModel, \"fields\" | \"createdBy\" | \"createdOn\" | \"savedOn\"> {\n fields: CmsModelFieldBase[];\n}\n\nexport type CmsModelInput = CmsApiModel | CmsPrivateModel | CmsApiModelFull | CmsPrivateModelFull;\n\nexport interface CmsModelPluginModel extends Omit<CmsModelBase, \"tenant\"> {\n tenant?: string;\n}\n\ninterface CmsModelPluginOptions {\n validateLayout?: boolean;\n}\n\nexport class CmsModelPlugin extends Plugin {\n public static override readonly type: string = \"cms-content-model\";\n public readonly contentModel: CmsModelPluginModel;\n\n private readonly options: CmsModelPluginOptions;\n\n constructor(contentModel: CmsModelInput, options?: CmsModelPluginOptions) {\n super();\n this.options = options || {};\n this.contentModel = this.buildModel(contentModel);\n }\n\n private buildModel(input: CmsModelInput): CmsModelPluginModel {\n const isPrivate = input.isPrivate ?? false;\n\n const singularApiName = input.singularApiName\n ? createApiName(input.singularApiName)\n : createApiName(input.name);\n\n const pluralApiName = input.pluralApiName\n ? createApiName(input.pluralApiName)\n : createPluralApiName(input.name);\n\n const modelPlugin: CmsModelPluginModel = {\n group: input.group ?? \"ungrouped\",\n description: \"\",\n fields: [],\n isPlugin: true,\n isPrivate,\n icon: null,\n layout: [],\n modelId: input.modelId,\n name: input.name,\n pluralApiName,\n singularApiName,\n titleFieldId: \"id\"\n };\n\n if (input.noValidate) {\n /**\n * We can safely ignore this error, because we are sure noValidate is not a model field.\n */\n delete input[\"noValidate\"];\n\n return {\n ...modelPlugin,\n ...input,\n // Since `noValidate` is set, we trust the input, and cast to `CmsModelFieldBase`.\n fields: input.fields as CmsModelFieldBase[],\n pluralApiName,\n singularApiName\n };\n }\n\n const model: CmsModelPluginModel = {\n ...modelPlugin,\n ...input,\n pluralApiName,\n singularApiName,\n fields: this.buildFields(input, input.fields)\n };\n this.validateLayout(model);\n return model;\n }\n\n private buildFields(\n model: CmsModelInput,\n inputFields: CmsModelFieldInput[]\n ): CmsModelFieldBase[] {\n if (inputFields.length === 0) {\n throw new WebinyError(\n `Missing fields for the defined model \"${model.modelId}\".`,\n \"MISSING_FIELDS\",\n {\n model\n }\n );\n }\n const fields: CmsModelFieldBase[] = [];\n const storageIdList: string[] = [];\n const fieldIdList: string[] = [];\n for (const input of inputFields) {\n /**\n * Field must contain an fieldId. It is required in the graphql, but lets check it just in case\n */\n if (!(input.fieldId || \"\").trim()) {\n throw new WebinyError(\n `Field's \"storageId\" is not defined for the content model \"${model.modelId}\".`,\n \"FIELD_ID_ERROR\",\n {\n model,\n field: input\n }\n );\n }\n const fieldId = lodashCamelCase(input.fieldId);\n /**\n * FieldID must be in correct pattern.\n */\n if (fieldId.match(/^[0-9]/) !== null) {\n throw new WebinyError(\n `Field's \"fieldId\" does not match correct pattern in the content model \"${model.modelId}\" - cannot start with a number.`,\n \"FIELD_FIELD_ID_ERROR\",\n {\n model,\n field: input\n }\n );\n }\n /**\n * FieldID also must be camelCased.\n */\n if (fieldId !== input.fieldId) {\n throw new WebinyError(\n `Field's \"fieldId\" must be a camel cased string in the content model \"${model.modelId}\".`,\n \"FIELD_FIELD_ID_ERROR\",\n {\n model,\n field: input\n }\n );\n }\n /**\n * ... and fieldId must be unique.\n */\n if (fieldIdList.includes(fieldId)) {\n throw new WebinyError(\n `Field's \"fieldId\" (id: ${input.id}) is not unique in the content model \"${model.modelId}\".`,\n \"FIELD_ID_NOT_UNIQUE_ERROR\",\n {\n model,\n field: input\n }\n );\n }\n\n let storageId = input.storageId;\n if (storageId) {\n try {\n validateStorageId(storageId);\n } catch (e) {\n throw WebinyError.from(e, {\n data: { model, storageId, field: input }\n });\n }\n } else {\n storageId = createFieldStorageId(input);\n }\n\n /**\n * Fields storageId must be unique.\n */\n if (storageIdList.includes(storageId)) {\n throw new WebinyError(\n `Field's \"storageId\" is not unique in the content model \"${model.modelId}\".`,\n \"STORAGE_ID_ERROR\",\n {\n model,\n field: input\n }\n );\n }\n\n /**\n * We can safely ignore error because we are going through the fields and making sure each has storageId.\n */\n // @ts-expect-error\n let settings: BaseCmsModelFieldSettings = input.settings;\n\n const childFields = settings?.fields || [];\n if (input.type === \"object\" && childFields.length > 0) {\n settings = {\n ...(settings || {}),\n fields: this.buildFields(model, childFields)\n };\n }\n\n const field: CmsModelFieldBase = {\n ...input,\n settings,\n storageId\n };\n /**\n * Add all relevant data to arrays.\n */\n fields.push(field);\n storageIdList.push(field.storageId);\n fieldIdList.push(field.fieldId);\n }\n return fields;\n }\n\n private validateLayout(model: CmsModelPluginModel): void {\n /**\n * Only skip validation if option.validateLayout was set as false, explicitly.\n */\n if (this.options.validateLayout === false) {\n return;\n }\n\n const countFieldInLayout = (fieldId: string, layout: any[][]): number => {\n let total = 0;\n for (const row of layout) {\n for (const cell of row) {\n if (typeof cell === \"string\") {\n if (cell === fieldId) {\n total++;\n }\n } else if (cell && typeof cell === \"object\" && Array.isArray(cell.tabs)) {\n for (const tab of cell.tabs) {\n if (Array.isArray(tab.layout)) {\n total += countFieldInLayout(fieldId, tab.layout);\n }\n }\n }\n }\n }\n return total;\n };\n\n for (const field of model.fields) {\n const total = countFieldInLayout(field.id, model.layout);\n if (total === 1) {\n continue;\n } else if (total > 1) {\n throw new WebinyError(\n `Field \"${field.id}\" is in more than one layout cell.`,\n \"DUPLICATE_FIELD_IN_LAYOUT\",\n {\n model,\n field\n }\n );\n }\n throw new WebinyError(\n `Missing field \"${field.id}\" in layout.`,\n \"MISSING_FIELD_IN_LAYOUT\",\n {\n model,\n field\n }\n );\n }\n }\n}\n\n/**\n * IMPORTANT! This function should NOT be used outside the `api-headless-cms` package!\n * @internal\n */\nexport const createModelPlugin = (\n model: CmsModelInput,\n options?: CmsModelPluginOptions\n): CmsModelPlugin => {\n return new CmsModelPlugin(model, options);\n};\n\n/**\n * IMPORTANT! This function should NOT be used outside the `api-headless-cms` package!\n * @internal\n */\nexport const createPrivateModelPlugin = (\n input: Omit<CmsPrivateModelFull, \"group\" | \"isPrivate\">\n): CmsModelPlugin => {\n return createModelPlugin(\n {\n authorization: false,\n noValidate: true,\n isPrivate: true,\n group: \"private\",\n ...input\n },\n {\n validateLayout: false\n }\n );\n};\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { CmsModelField } from "../modelField.js";
|
|
2
|
+
import type { CmsModelLayout } from "../../types/index.js";
|
|
2
3
|
/**
|
|
3
4
|
* A definition for object field to show possible type of the field in settings.
|
|
4
5
|
*/
|
|
@@ -8,6 +9,7 @@ export interface CmsModelObjectField extends CmsModelField {
|
|
|
8
9
|
*/
|
|
9
10
|
settings: {
|
|
10
11
|
fields: CmsModelField[];
|
|
12
|
+
layout?: CmsModelLayout;
|
|
11
13
|
parents?: string[];
|
|
12
14
|
};
|
|
13
15
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["objectField.ts"],"sourcesContent":["import type { CmsModelField } from \"../modelField.js\";\n\n/**\n * A definition for object field to show possible type of the field in settings.\n */\nexport interface CmsModelObjectField extends CmsModelField {\n /**\n * Settings object for the field. Contains `templates` property.\n */\n settings: {\n fields: CmsModelField[];\n parents?: string[];\n };\n}\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sources":["objectField.ts"],"sourcesContent":["import type { CmsModelField } from \"../modelField.js\";\nimport type { CmsModelLayout } from \"~/types/index.js\";\n\n/**\n * A definition for object field to show possible type of the field in settings.\n */\nexport interface CmsModelObjectField extends CmsModelField {\n /**\n * Settings object for the field. Contains `templates` property.\n */\n settings: {\n fields: CmsModelField[];\n layout?: CmsModelLayout;\n parents?: string[];\n };\n}\n"],"mappings":"","ignoreList":[]}
|
package/types/model.d.ts
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
1
|
import type { CmsIdentity } from "./identity.js";
|
|
2
|
-
import type { CmsModelField, CmsModelFieldInput } from "./modelField.js";
|
|
2
|
+
import type { CmsModelField, CmsModelFieldInput, FieldRule } from "./modelField.js";
|
|
3
3
|
import type { CmsIcon } from "../types/types.js";
|
|
4
|
+
export interface CmsTabLayoutTab {
|
|
5
|
+
id: string;
|
|
6
|
+
label: string;
|
|
7
|
+
icon?: CmsIcon | null;
|
|
8
|
+
layout: CmsModelLayout;
|
|
9
|
+
rules?: FieldRule[];
|
|
10
|
+
}
|
|
11
|
+
export interface CmsTabLayoutDescriptor {
|
|
12
|
+
type: "tabs";
|
|
13
|
+
label: string;
|
|
14
|
+
description?: string | null;
|
|
15
|
+
help?: string | null;
|
|
16
|
+
tabs: CmsTabLayoutTab[];
|
|
17
|
+
rules?: FieldRule[];
|
|
18
|
+
}
|
|
19
|
+
export interface CmsSeparatorLayoutDescriptor {
|
|
20
|
+
type: "separator";
|
|
21
|
+
label: string;
|
|
22
|
+
description: string | null | undefined;
|
|
23
|
+
rules?: FieldRule[];
|
|
24
|
+
}
|
|
25
|
+
export interface CmsAlertLayoutDescriptor {
|
|
26
|
+
type: "alert";
|
|
27
|
+
label: string;
|
|
28
|
+
alertType: "info" | "success" | "warning" | "danger";
|
|
29
|
+
rules?: FieldRule[];
|
|
30
|
+
}
|
|
31
|
+
export type CmsModelLayoutCell = string | CmsTabLayoutDescriptor | CmsSeparatorLayoutDescriptor | CmsAlertLayoutDescriptor;
|
|
32
|
+
export type CmsModelLayout = CmsModelLayoutCell[][];
|
|
4
33
|
/**
|
|
5
34
|
* Base CMS Model. Should not be exported and used outside of this package.
|
|
6
35
|
*
|
|
@@ -76,7 +105,7 @@ export interface CmsModel {
|
|
|
76
105
|
* ]
|
|
77
106
|
* ```
|
|
78
107
|
*/
|
|
79
|
-
layout:
|
|
108
|
+
layout: CmsModelLayout;
|
|
80
109
|
/**
|
|
81
110
|
* Models can be tagged to give them contextual meaning.
|
|
82
111
|
*/
|
|
@@ -161,7 +190,7 @@ export interface CmsModelCreateInput {
|
|
|
161
190
|
* ]
|
|
162
191
|
* ```
|
|
163
192
|
*/
|
|
164
|
-
layout?:
|
|
193
|
+
layout?: CmsModelLayout;
|
|
165
194
|
/**
|
|
166
195
|
* Models can be tagged to give them contextual meaning.
|
|
167
196
|
*/
|
package/types/model.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sources":["model.ts"],"sourcesContent":["import type { CmsIdentity } from \"./identity.js\";\nimport type { CmsModelField, CmsModelFieldInput } from \"./modelField.js\";\nimport type { CmsIcon } from \"~/types/types.js\";\n\n/**\n * Base CMS Model. Should not be exported and used outside of this package.\n *\n * @category Database model\n * @category CmsModel\n */\nexport interface CmsModel {\n /**\n * Name of the content model.\n */\n name: string;\n /**\n * Unique ID for the content model. Created from name if not defined by user.\n */\n modelId: string;\n /**\n * Name of the content model in singular form to be used in the API.\n * example:\n * - Article\n * - Fruit\n * - Vegetable\n * - Car\n */\n singularApiName: string;\n /**\n * Name of the content model in plural form to be used in the API.\n * example:\n * - Articles\n * - Fruits\n * - Vegetables\n * - Cars\n */\n pluralApiName: string;\n /**\n * Model tenant.\n */\n tenant: string;\n /**\n * Model group slug.\n */\n group: string;\n /**\n * Icon for the content model.\n */\n icon: CmsIcon | null;\n /**\n * Description for the content model.\n */\n description: string | null;\n /**\n * Date created\n */\n createdOn?: string;\n /**\n * Date saved. Changes on both save and create.\n */\n savedOn?: string;\n /**\n * CreatedBy object wrapper. Contains id, name and type of the user.\n */\n createdBy?: CmsIdentity;\n /**\n * List of fields defining entry values.\n */\n fields: CmsModelField[];\n /**\n * Admin UI field layout\n *\n * ```ts\n * layout: [\n * [field1id, field2id],\n * [field3id]\n * ]\n * ```\n */\n layout:
|
|
1
|
+
{"version":3,"names":[],"sources":["model.ts"],"sourcesContent":["import type { CmsIdentity } from \"./identity.js\";\nimport type { CmsModelField, CmsModelFieldInput, FieldRule } from \"./modelField.js\";\nimport type { CmsIcon } from \"~/types/types.js\";\n\nexport interface CmsTabLayoutTab {\n id: string;\n label: string;\n icon?: CmsIcon | null;\n layout: CmsModelLayout;\n rules?: FieldRule[];\n}\n\nexport interface CmsTabLayoutDescriptor {\n type: \"tabs\";\n label: string;\n description?: string | null;\n help?: string | null;\n tabs: CmsTabLayoutTab[];\n rules?: FieldRule[];\n}\n\nexport interface CmsSeparatorLayoutDescriptor {\n type: \"separator\";\n label: string;\n description: string | null | undefined;\n rules?: FieldRule[];\n}\n\nexport interface CmsAlertLayoutDescriptor {\n type: \"alert\";\n label: string;\n alertType: \"info\" | \"success\" | \"warning\" | \"danger\";\n rules?: FieldRule[];\n}\n\nexport type CmsModelLayoutCell =\n | string\n | CmsTabLayoutDescriptor\n | CmsSeparatorLayoutDescriptor\n | CmsAlertLayoutDescriptor;\nexport type CmsModelLayout = CmsModelLayoutCell[][];\n\n/**\n * Base CMS Model. Should not be exported and used outside of this package.\n *\n * @category Database model\n * @category CmsModel\n */\nexport interface CmsModel {\n /**\n * Name of the content model.\n */\n name: string;\n /**\n * Unique ID for the content model. Created from name if not defined by user.\n */\n modelId: string;\n /**\n * Name of the content model in singular form to be used in the API.\n * example:\n * - Article\n * - Fruit\n * - Vegetable\n * - Car\n */\n singularApiName: string;\n /**\n * Name of the content model in plural form to be used in the API.\n * example:\n * - Articles\n * - Fruits\n * - Vegetables\n * - Cars\n */\n pluralApiName: string;\n /**\n * Model tenant.\n */\n tenant: string;\n /**\n * Model group slug.\n */\n group: string;\n /**\n * Icon for the content model.\n */\n icon: CmsIcon | null;\n /**\n * Description for the content model.\n */\n description: string | null;\n /**\n * Date created\n */\n createdOn?: string;\n /**\n * Date saved. Changes on both save and create.\n */\n savedOn?: string;\n /**\n * CreatedBy object wrapper. Contains id, name and type of the user.\n */\n createdBy?: CmsIdentity;\n /**\n * List of fields defining entry values.\n */\n fields: CmsModelField[];\n /**\n * Admin UI field layout\n *\n * ```ts\n * layout: [\n * [field1id, field2id],\n * [field3id]\n * ]\n * ```\n */\n layout: CmsModelLayout;\n /**\n * Models can be tagged to give them contextual meaning.\n */\n tags?: string[];\n /**\n * The field that is used as an entry title.\n * If not specified by the user, the system tries to assign the first available `text` field.\n */\n titleFieldId: string;\n /**\n * The field that is used as an entry description.\n * If not set by the user, the system will try to assign the first available `long-text` field.\n */\n descriptionFieldId?: string | null;\n /**\n * The field that is used as an entry image.\n * If not set by the user, the system will try to assign a `file` field which has `imagesOnly` enabled.\n */\n imageFieldId?: string | null;\n\n /**\n * Is model private?\n * This is meant to be used for some internal models - will not be visible in the schema.\n * Only available for the plugin constructed models.\n */\n isPrivate?: boolean;\n\n /**\n * Does this model require authorization to be performed?\n * Only available for models created via plugins.\n */\n authorization?: boolean | CmsModelAuthorization;\n\n /**\n * Is this model created via plugin?\n */\n isPlugin?: boolean;\n}\n\nexport interface CmsModelAuthorization {\n permissions: boolean;\n\n [key: string]: any;\n}\n\n/**\n * A GraphQL `params.data` parameter received when creating content model.\n *\n * @category GraphQL params\n * @category CmsModel\n */\nexport interface CmsModelCreateInput {\n /**\n * Name of the content model.\n */\n name: string;\n /**\n * Singular name of the content model to be used in the API.\n */\n singularApiName: string;\n /**\n * Plural name of the content model to be used in the API.\n */\n pluralApiName: string;\n /**\n * Unique ID of the content model. Created from name if not sent by the user. Cannot be changed.\n */\n modelId?: string;\n /**\n * Description of the content model.\n */\n description?: string | null;\n /**\n * Group where to put the content model in.\n */\n group: string;\n /**\n * A list of content model fields to define the entry values.\n */\n fields?: CmsModelFieldInput[];\n /**\n * Admin UI field layout\n *\n * ```ts\n * layout: [\n * [field1id, field2id],\n * [field3id]\n * ]\n * ```\n */\n layout?: CmsModelLayout;\n /**\n * Models can be tagged to give them contextual meaning.\n */\n tags?: string[];\n /**\n * Fields fieldId which are picked to represent the CMS entry.\n */\n titleFieldId?: string | null;\n descriptionFieldId?: string | null;\n imageFieldId?: string | null;\n icon?: CmsIcon | null;\n}\n\n/**\n * A GraphQL `params.data` parameter received when creating content model from existing model.\n *\n * @category GraphQL params\n * @category CmsModel\n */\nexport interface CmsModelCreateFromInput extends CmsModelCreateInput {}\n"],"mappings":"","ignoreList":[]}
|