@webiny/api-headless-cms 6.6.0-alpha.0 → 6.6.0-alpha.1

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.
Files changed (139) hide show
  1. package/HeadlessCmsFeature.js +4 -1
  2. package/HeadlessCmsFeature.js.map +1 -1
  3. package/createCmsRoute.d.ts +13 -8
  4. package/createCmsRoute.js +14 -4
  5. package/createCmsRoute.js.map +1 -1
  6. package/crud/contentEntry/entryDataValidation.js +27 -0
  7. package/crud/contentEntry/entryDataValidation.js.map +1 -1
  8. package/crud/contentModel/defaultFields.js +3 -2
  9. package/crud/contentModel/defaultFields.js.map +1 -1
  10. package/domain/contentModel/schemas.d.ts +8 -6
  11. package/domain/contentModel/schemas.js +5 -3
  12. package/domain/contentModel/schemas.js.map +1 -1
  13. package/exports/api/cms/model.d.ts +4 -1
  14. package/exports/api/cms/model.js +2 -0
  15. package/features/ai/DescribeContentModelTool.d.ts +55 -0
  16. package/features/ai/DescribeContentModelTool.js +60 -0
  17. package/features/ai/DescribeContentModelTool.js.map +1 -0
  18. package/features/ai/ListContentModelsTool.d.ts +41 -0
  19. package/features/ai/ListContentModelsTool.js +44 -0
  20. package/features/ai/ListContentModelsTool.js.map +1 -0
  21. package/features/ai/QueryEntriesTool.d.ts +75 -0
  22. package/features/ai/QueryEntriesTool.js +90 -0
  23. package/features/ai/QueryEntriesTool.js.map +1 -0
  24. package/features/ai/feature.d.ts +8 -0
  25. package/features/ai/feature.js +15 -0
  26. package/features/ai/feature.js.map +1 -0
  27. package/features/ai/index.d.ts +4 -0
  28. package/features/ai/index.js +4 -0
  29. package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.d.ts +14 -0
  30. package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.js +32 -0
  31. package/features/contentModel/ComponentMapGenerator/ComponentMapGenerator.js.map +1 -0
  32. package/features/contentModel/ComponentMapGenerator/abstractions.d.ts +8 -0
  33. package/features/contentModel/ComponentMapGenerator/abstractions.js +5 -0
  34. package/features/contentModel/ComponentMapGenerator/abstractions.js.map +1 -0
  35. package/features/contentModel/ComponentMapGenerator/feature.d.ts +4 -0
  36. package/features/contentModel/ComponentMapGenerator/feature.js +11 -0
  37. package/features/contentModel/ComponentMapGenerator/feature.js.map +1 -0
  38. package/features/contentModel/ComponentMapGenerator/index.d.ts +2 -0
  39. package/features/contentModel/ComponentMapGenerator/index.js +2 -0
  40. package/features/contentModel/ContentModelFeature.js +4 -0
  41. package/features/contentModel/ContentModelFeature.js.map +1 -1
  42. package/features/contentModel/RefModelsGenerator/RefModelsGenerator.d.ts +19 -0
  43. package/features/contentModel/RefModelsGenerator/RefModelsGenerator.js +56 -0
  44. package/features/contentModel/RefModelsGenerator/RefModelsGenerator.js.map +1 -0
  45. package/features/contentModel/RefModelsGenerator/abstractions.d.ts +11 -0
  46. package/features/contentModel/RefModelsGenerator/abstractions.js +5 -0
  47. package/features/contentModel/RefModelsGenerator/abstractions.js.map +1 -0
  48. package/features/contentModel/RefModelsGenerator/feature.d.ts +4 -0
  49. package/features/contentModel/RefModelsGenerator/feature.js +11 -0
  50. package/features/contentModel/RefModelsGenerator/feature.js.map +1 -0
  51. package/features/contentModel/RefModelsGenerator/index.d.ts +2 -0
  52. package/features/contentModel/RefModelsGenerator/index.js +2 -0
  53. package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js +2 -0
  54. package/features/contentModel/ValuesSelectionGenerator/ValuesSelectionGenerator.js.map +1 -1
  55. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.d.ts +3 -1
  56. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.js +6 -4
  57. package/features/contentModelGroup/CreateGroup/CreateGroupRepository.js.map +1 -1
  58. package/features/graphql/feature.js +2 -0
  59. package/features/graphql/feature.js.map +1 -1
  60. package/features/graphql/fields/base/AssetToGraphQL.d.ts +26 -0
  61. package/features/graphql/fields/base/AssetToGraphQL.js +148 -0
  62. package/features/graphql/fields/base/AssetToGraphQL.js.map +1 -0
  63. package/features/graphql/fields/base/DynamicZoneToGraphQL.js +5 -1
  64. package/features/graphql/fields/base/DynamicZoneToGraphQL.js.map +1 -1
  65. package/features/graphql/fields/base/ObjectToGraphQL.js +2 -2
  66. package/features/graphql/fields/base/ObjectToGraphQL.js.map +1 -1
  67. package/features/modelBuilder/abstractions.d.ts +10 -0
  68. package/features/modelBuilder/abstractions.js.map +1 -1
  69. package/features/modelBuilder/feature.js +2 -0
  70. package/features/modelBuilder/feature.js.map +1 -1
  71. package/features/modelBuilder/fields/AssetFieldType.d.ts +20 -0
  72. package/features/modelBuilder/fields/AssetFieldType.js +46 -0
  73. package/features/modelBuilder/fields/AssetFieldType.js.map +1 -0
  74. package/features/modelBuilder/fields/BaseFieldBuilder.d.ts +3 -1
  75. package/features/modelBuilder/fields/BaseFieldBuilder.js +4 -0
  76. package/features/modelBuilder/fields/BaseFieldBuilder.js.map +1 -1
  77. package/features/modelBuilder/fields/DataFieldBuilder.d.ts +42 -0
  78. package/features/modelBuilder/fields/DataFieldBuilder.js +5 -1
  79. package/features/modelBuilder/fields/DataFieldBuilder.js.map +1 -1
  80. package/features/modelBuilder/fields/DynamicZoneFieldType.d.ts +1 -0
  81. package/features/modelBuilder/fields/DynamicZoneFieldType.js +10 -9
  82. package/features/modelBuilder/fields/DynamicZoneFieldType.js.map +1 -1
  83. package/features/modelBuilder/fields/UiAlertFieldType.js +2 -1
  84. package/features/modelBuilder/fields/UiAlertFieldType.js.map +1 -1
  85. package/features/modelBuilder/fields/UiSeparatorFieldType.js +2 -1
  86. package/features/modelBuilder/fields/UiSeparatorFieldType.js.map +1 -1
  87. package/features/modelBuilder/fields/UiTabsFieldType.d.ts +2 -1
  88. package/features/modelBuilder/fields/UiTabsFieldType.js +6 -3
  89. package/features/modelBuilder/fields/UiTabsFieldType.js.map +1 -1
  90. package/features/modelBuilder/fields/resolveAssetUrl.d.ts +35 -0
  91. package/features/modelBuilder/fields/resolveAssetUrl.js +26 -0
  92. package/features/modelBuilder/fields/resolveAssetUrl.js.map +1 -0
  93. package/features/modelBuilder/index.d.ts +1 -1
  94. package/features/modelBuilder/models/BaseModelBuilder.d.ts +3 -1
  95. package/features/modelBuilder/models/BaseModelBuilder.js +7 -0
  96. package/features/modelBuilder/models/BaseModelBuilder.js.map +1 -1
  97. package/features/modelBuilder/models/PrivateModelBuilder.js +2 -1
  98. package/features/modelBuilder/models/PrivateModelBuilder.js.map +1 -1
  99. package/features/modelBuilder/models/PublicModelBuilder.js +2 -1
  100. package/features/modelBuilder/models/PublicModelBuilder.js.map +1 -1
  101. package/features/sortMapper/SortMapper.js +2 -5
  102. package/features/sortMapper/SortMapper.js.map +1 -1
  103. package/features/whereMapper/WhereMapper.js +7 -5
  104. package/features/whereMapper/WhereMapper.js.map +1 -1
  105. package/graphql/schema/cms/getEntryResolver.js +3 -2
  106. package/graphql/schema/cms/getEntryResolver.js.map +1 -1
  107. package/graphql/schema/cms/getModelResolver.d.ts +35 -0
  108. package/graphql/schema/cms/getModelResolver.js +49 -0
  109. package/graphql/schema/cms/getModelResolver.js.map +1 -0
  110. package/graphql/schema/cms/helpers/buildFieldsSelection.js +9 -2
  111. package/graphql/schema/cms/helpers/buildFieldsSelection.js.map +1 -1
  112. package/graphql/schema/cms/helpers/expandFieldWildcards.d.ts +2 -0
  113. package/graphql/schema/cms/helpers/expandFieldWildcards.js +13 -0
  114. package/graphql/schema/cms/helpers/expandFieldWildcards.js.map +1 -0
  115. package/graphql/schema/cms/helpers/index.d.ts +1 -0
  116. package/graphql/schema/cms/helpers/index.js +1 -0
  117. package/graphql/schema/cms/helpers/transformWhereToNested.js +39 -17
  118. package/graphql/schema/cms/helpers/transformWhereToNested.js.map +1 -1
  119. package/graphql/schema/cms/helpers.d.ts +1 -0
  120. package/graphql/schema/cms/helpers.js +1 -0
  121. package/graphql/schema/cms/listEntriesResolver.js +3 -2
  122. package/graphql/schema/cms/listEntriesResolver.js.map +1 -1
  123. package/graphql/schema/cms/resolvers/getModel.d.ts +8 -0
  124. package/graphql/schema/cms/resolvers/getModel.js +18 -0
  125. package/graphql/schema/cms/resolvers/getModel.js.map +1 -0
  126. package/graphql/schema/cms/resolvers/index.d.ts +1 -0
  127. package/graphql/schema/cms/resolvers/index.js +1 -0
  128. package/graphql/schema/cms/typeDefs/query.js +1 -0
  129. package/graphql/schema/cms/typeDefs/query.js.map +1 -1
  130. package/graphql/schema/cms/typeDefs/responses.js +5 -0
  131. package/graphql/schema/cms/typeDefs/responses.js.map +1 -1
  132. package/graphql/schema/contentModels.js +31 -0
  133. package/graphql/schema/contentModels.js.map +1 -1
  134. package/package.json +21 -22
  135. package/plugins/CmsModelPlugin.js +2 -1
  136. package/plugins/CmsModelPlugin.js.map +1 -1
  137. package/types/fields/dynamicZoneField.d.ts +3 -2
  138. package/types/model.d.ts +6 -0
  139. package/types/modelField.d.ts +3 -1
@@ -1 +1 @@
1
- {"version":3,"file":"plugins/CmsModelPlugin.js","sources":["../../src/plugins/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 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 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 extends Omit<\n CmsPrivateModel,\n \"fields\" | \"createdBy\" | \"createdOn\" | \"savedOn\"\n> {\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"],"names":["createApiName","name","upperFirst","camelCase","createPluralApiName","pluralize","CmsModelPlugin","Plugin","contentModel","options","input","isPrivate","singularApiName","pluralApiName","modelPlugin","model","inputFields","WebinyError","fields","storageIdList","fieldIdList","fieldId","lodashCamelCase","storageId","validateStorageId","e","createFieldStorageId","settings","childFields","field","countFieldInLayout","layout","total","row","cell","Array","tab","createModelPlugin","createPrivateModelPlugin"],"mappings":";;;;;;;AAcA,MAAMA,gBAAgB,CAACC,OACZC,WAAWC,UAAUF;AAGhC,MAAMG,sBAAsB,CAACH,OAClBI,UAAUL,cAAcC;AA6E5B,MAAMK,uBAAuBC;;aACA,IAAI,GAAW;;IAK/C,YAAYC,YAA2B,EAAEC,OAA+B,CAAE;QACtE,KAAK;QACL,IAAI,CAAC,OAAO,GAAGA,WAAW,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,UAAU,CAACD;IACxC;IAEQ,WAAWE,KAAoB,EAAuB;QAC1D,MAAMC,YAAYD,MAAM,SAAS,IAAI;QAErC,MAAME,kBAAkBF,MAAM,eAAe,GACvCV,cAAcU,MAAM,eAAe,IACnCV,cAAcU,MAAM,IAAI;QAE9B,MAAMG,gBAAgBH,MAAM,aAAa,GACnCV,cAAcU,MAAM,aAAa,IACjCN,oBAAoBM,MAAM,IAAI;QAEpC,MAAMI,cAAmC;YACrC,OAAOJ,MAAM,KAAK,IAAI;YACtB,aAAa;YACb,QAAQ,EAAE;YACV,UAAU;YACVC;YACA,MAAM;YACN,QAAQ,EAAE;YACV,SAASD,MAAM,OAAO;YACtB,MAAMA,MAAM,IAAI;YAChBG;YACAD;YACA,cAAc;QAClB;QAEA,IAAIF,MAAM,UAAU,EAAE;YAIlB,OAAOA,KAAK,CAAC,aAAa;YAE1B,OAAO;gBACH,GAAGI,WAAW;gBACd,GAAGJ,KAAK;gBAER,QAAQA,MAAM,MAAM;gBACpBG;gBACAD;YACJ;QACJ;QAEA,MAAMG,QAA6B;YAC/B,GAAGD,WAAW;YACd,GAAGJ,KAAK;YACRG;YACAD;YACA,QAAQ,IAAI,CAAC,WAAW,CAACF,OAAOA,MAAM,MAAM;QAChD;QACA,IAAI,CAAC,cAAc,CAACK;QACpB,OAAOA;IACX;IAEQ,YACJA,KAAoB,EACpBC,WAAiC,EACd;QACnB,IAAIA,AAAuB,MAAvBA,YAAY,MAAM,EAClB,MAAM,IAAIC,MACN,CAAC,sCAAsC,EAAEF,MAAM,OAAO,CAAC,EAAE,CAAC,EAC1D,kBACA;YACIA;QACJ;QAGR,MAAMG,SAA8B,EAAE;QACtC,MAAMC,gBAA0B,EAAE;QAClC,MAAMC,cAAwB,EAAE;QAChC,KAAK,MAAMV,SAASM,YAAa;YAI7B,IAAI,CAAEN,AAAAA,CAAAA,MAAM,OAAO,IAAI,EAAC,EAAG,IAAI,IAC3B,MAAM,IAAIO,MACN,CAAC,0DAA0D,EAAEF,MAAM,OAAO,CAAC,EAAE,CAAC,EAC9E,kBACA;gBACIA;gBACA,OAAOL;YACX;YAGR,MAAMW,UAAUC,UAAgBZ,MAAM,OAAO;YAI7C,IAAIW,AAA4B,SAA5BA,QAAQ,KAAK,CAAC,WACd,MAAM,IAAIJ,MACN,CAAC,uEAAuE,EAAEF,MAAM,OAAO,CAAC,+BAA+B,CAAC,EACxH,wBACA;gBACIA;gBACA,OAAOL;YACX;YAMR,IAAIW,YAAYX,MAAM,OAAO,EACzB,MAAM,IAAIO,MACN,CAAC,qEAAqE,EAAEF,MAAM,OAAO,CAAC,EAAE,CAAC,EACzF,wBACA;gBACIA;gBACA,OAAOL;YACX;YAMR,IAAIU,YAAY,QAAQ,CAACC,UACrB,MAAM,IAAIJ,MACN,CAAC,uBAAuB,EAAEP,MAAM,EAAE,CAAC,sCAAsC,EAAEK,MAAM,OAAO,CAAC,EAAE,CAAC,EAC5F,6BACA;gBACIA;gBACA,OAAOL;YACX;YAIR,IAAIa,YAAYb,MAAM,SAAS;YAC/B,IAAIa,WACA,IAAI;gBACAC,kBAAkBD;YACtB,EAAE,OAAOE,GAAG;gBACR,MAAMR,MAAAA,IAAgB,CAACQ,GAAG;oBACtB,MAAM;wBAAEV;wBAAOQ;wBAAW,OAAOb;oBAAM;gBAC3C;YACJ;iBAEAa,YAAYG,qBAAqBhB;YAMrC,IAAIS,cAAc,QAAQ,CAACI,YACvB,MAAM,IAAIN,MACN,CAAC,wDAAwD,EAAEF,MAAM,OAAO,CAAC,EAAE,CAAC,EAC5E,oBACA;gBACIA;gBACA,OAAOL;YACX;YAQR,IAAIiB,WAAsCjB,MAAM,QAAQ;YAExD,MAAMkB,cAAcD,UAAU,UAAU,EAAE;YAC1C,IAAIjB,AAAe,aAAfA,MAAM,IAAI,IAAiBkB,YAAY,MAAM,GAAG,GAChDD,WAAW;gBACP,GAAIA,YAAY,CAAC,CAAC;gBAClB,QAAQ,IAAI,CAAC,WAAW,CAACZ,OAAOa;YACpC;YAGJ,MAAMC,QAA2B;gBAC7B,GAAGnB,KAAK;gBACRiB;gBACAJ;YACJ;YAIAL,OAAO,IAAI,CAACW;YACZV,cAAc,IAAI,CAACU,MAAM,SAAS;YAClCT,YAAY,IAAI,CAACS,MAAM,OAAO;QAClC;QACA,OAAOX;IACX;IAEQ,eAAeH,KAA0B,EAAQ;QAIrD,IAAI,AAAgC,UAAhC,IAAI,CAAC,OAAO,CAAC,cAAc,EAC3B;QAGJ,MAAMe,qBAAqB,CAACT,SAAiBU;YACzC,IAAIC,QAAQ;YACZ,KAAK,MAAMC,OAAOF,OACd,KAAK,MAAMG,QAAQD,IACf,IAAI,AAAgB,YAAhB,OAAOC,MACP;gBAAA,IAAIA,SAASb,SACTW;YACJ,OACG,IAAIE,QAAQ,AAAgB,YAAhB,OAAOA,QAAqBC,MAAM,OAAO,CAACD,KAAK,IAAI,GAClE;gBAAA,KAAK,MAAME,OAAOF,KAAK,IAAI,CACvB,IAAIC,MAAM,OAAO,CAACC,IAAI,MAAM,GACxBJ,SAASF,mBAAmBT,SAASe,IAAI,MAAM;YAEvD;YAIZ,OAAOJ;QACX;QAEA,KAAK,MAAMH,SAASd,MAAM,MAAM,CAAE;YAC9B,MAAMiB,QAAQF,mBAAmBD,MAAM,EAAE,EAAEd,MAAM,MAAM;YACvD,IAAIiB,AAAU,MAAVA;gBAEG,IAAIA,QAAQ,GACf,MAAM,IAAIf,MACN,CAAC,OAAO,EAAEY,MAAM,EAAE,CAAC,kCAAkC,CAAC,EACtD,6BACA;oBACId;oBACAc;gBACJ;gBAGR,MAAM,IAAIZ,MACN,CAAC,eAAe,EAAEY,MAAM,EAAE,CAAC,YAAY,CAAC,EACxC,2BACA;oBACId;oBACAc;gBACJ;;QAER;IACJ;AACJ;AAMO,MAAMQ,oBAAoB,CAC7BtB,OACAN,UAEO,IAAIH,eAAeS,OAAON;AAO9B,MAAM6B,2BAA2B,CACpC5B,QAEO2B,kBACH;QACI,eAAe;QACf,YAAY;QACZ,WAAW;QACX,OAAO;QACP,GAAG3B,KAAK;IACZ,GACA;QACI,gBAAgB;IACpB"}
1
+ {"version":3,"file":"plugins/CmsModelPlugin.js","sources":["../../src/plugins/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 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 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 extends Omit<\n CmsPrivateModel,\n \"fields\" | \"createdBy\" | \"createdOn\" | \"savedOn\"\n> {\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 settings: {}\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"],"names":["createApiName","name","upperFirst","camelCase","createPluralApiName","pluralize","CmsModelPlugin","Plugin","contentModel","options","input","isPrivate","singularApiName","pluralApiName","modelPlugin","model","inputFields","WebinyError","fields","storageIdList","fieldIdList","fieldId","lodashCamelCase","storageId","validateStorageId","e","createFieldStorageId","settings","childFields","field","countFieldInLayout","layout","total","row","cell","Array","tab","createModelPlugin","createPrivateModelPlugin"],"mappings":";;;;;;;AAcA,MAAMA,gBAAgB,CAACC,OACZC,WAAWC,UAAUF;AAGhC,MAAMG,sBAAsB,CAACH,OAClBI,UAAUL,cAAcC;AA6E5B,MAAMK,uBAAuBC;;aACA,IAAI,GAAW;;IAK/C,YAAYC,YAA2B,EAAEC,OAA+B,CAAE;QACtE,KAAK;QACL,IAAI,CAAC,OAAO,GAAGA,WAAW,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,UAAU,CAACD;IACxC;IAEQ,WAAWE,KAAoB,EAAuB;QAC1D,MAAMC,YAAYD,MAAM,SAAS,IAAI;QAErC,MAAME,kBAAkBF,MAAM,eAAe,GACvCV,cAAcU,MAAM,eAAe,IACnCV,cAAcU,MAAM,IAAI;QAE9B,MAAMG,gBAAgBH,MAAM,aAAa,GACnCV,cAAcU,MAAM,aAAa,IACjCN,oBAAoBM,MAAM,IAAI;QAEpC,MAAMI,cAAmC;YACrC,OAAOJ,MAAM,KAAK,IAAI;YACtB,aAAa;YACb,QAAQ,EAAE;YACV,UAAU;YACVC;YACA,MAAM;YACN,QAAQ,EAAE;YACV,SAASD,MAAM,OAAO;YACtB,MAAMA,MAAM,IAAI;YAChBG;YACAD;YACA,cAAc;YACd,UAAU,CAAC;QACf;QAEA,IAAIF,MAAM,UAAU,EAAE;YAIlB,OAAOA,KAAK,CAAC,aAAa;YAE1B,OAAO;gBACH,GAAGI,WAAW;gBACd,GAAGJ,KAAK;gBAER,QAAQA,MAAM,MAAM;gBACpBG;gBACAD;YACJ;QACJ;QAEA,MAAMG,QAA6B;YAC/B,GAAGD,WAAW;YACd,GAAGJ,KAAK;YACRG;YACAD;YACA,QAAQ,IAAI,CAAC,WAAW,CAACF,OAAOA,MAAM,MAAM;QAChD;QACA,IAAI,CAAC,cAAc,CAACK;QACpB,OAAOA;IACX;IAEQ,YACJA,KAAoB,EACpBC,WAAiC,EACd;QACnB,IAAIA,AAAuB,MAAvBA,YAAY,MAAM,EAClB,MAAM,IAAIC,MACN,CAAC,sCAAsC,EAAEF,MAAM,OAAO,CAAC,EAAE,CAAC,EAC1D,kBACA;YACIA;QACJ;QAGR,MAAMG,SAA8B,EAAE;QACtC,MAAMC,gBAA0B,EAAE;QAClC,MAAMC,cAAwB,EAAE;QAChC,KAAK,MAAMV,SAASM,YAAa;YAI7B,IAAI,CAAEN,AAAAA,CAAAA,MAAM,OAAO,IAAI,EAAC,EAAG,IAAI,IAC3B,MAAM,IAAIO,MACN,CAAC,0DAA0D,EAAEF,MAAM,OAAO,CAAC,EAAE,CAAC,EAC9E,kBACA;gBACIA;gBACA,OAAOL;YACX;YAGR,MAAMW,UAAUC,UAAgBZ,MAAM,OAAO;YAI7C,IAAIW,AAA4B,SAA5BA,QAAQ,KAAK,CAAC,WACd,MAAM,IAAIJ,MACN,CAAC,uEAAuE,EAAEF,MAAM,OAAO,CAAC,+BAA+B,CAAC,EACxH,wBACA;gBACIA;gBACA,OAAOL;YACX;YAMR,IAAIW,YAAYX,MAAM,OAAO,EACzB,MAAM,IAAIO,MACN,CAAC,qEAAqE,EAAEF,MAAM,OAAO,CAAC,EAAE,CAAC,EACzF,wBACA;gBACIA;gBACA,OAAOL;YACX;YAMR,IAAIU,YAAY,QAAQ,CAACC,UACrB,MAAM,IAAIJ,MACN,CAAC,uBAAuB,EAAEP,MAAM,EAAE,CAAC,sCAAsC,EAAEK,MAAM,OAAO,CAAC,EAAE,CAAC,EAC5F,6BACA;gBACIA;gBACA,OAAOL;YACX;YAIR,IAAIa,YAAYb,MAAM,SAAS;YAC/B,IAAIa,WACA,IAAI;gBACAC,kBAAkBD;YACtB,EAAE,OAAOE,GAAG;gBACR,MAAMR,MAAAA,IAAgB,CAACQ,GAAG;oBACtB,MAAM;wBAAEV;wBAAOQ;wBAAW,OAAOb;oBAAM;gBAC3C;YACJ;iBAEAa,YAAYG,qBAAqBhB;YAMrC,IAAIS,cAAc,QAAQ,CAACI,YACvB,MAAM,IAAIN,MACN,CAAC,wDAAwD,EAAEF,MAAM,OAAO,CAAC,EAAE,CAAC,EAC5E,oBACA;gBACIA;gBACA,OAAOL;YACX;YAQR,IAAIiB,WAAsCjB,MAAM,QAAQ;YAExD,MAAMkB,cAAcD,UAAU,UAAU,EAAE;YAC1C,IAAIjB,AAAe,aAAfA,MAAM,IAAI,IAAiBkB,YAAY,MAAM,GAAG,GAChDD,WAAW;gBACP,GAAIA,YAAY,CAAC,CAAC;gBAClB,QAAQ,IAAI,CAAC,WAAW,CAACZ,OAAOa;YACpC;YAGJ,MAAMC,QAA2B;gBAC7B,GAAGnB,KAAK;gBACRiB;gBACAJ;YACJ;YAIAL,OAAO,IAAI,CAACW;YACZV,cAAc,IAAI,CAACU,MAAM,SAAS;YAClCT,YAAY,IAAI,CAACS,MAAM,OAAO;QAClC;QACA,OAAOX;IACX;IAEQ,eAAeH,KAA0B,EAAQ;QAIrD,IAAI,AAAgC,UAAhC,IAAI,CAAC,OAAO,CAAC,cAAc,EAC3B;QAGJ,MAAMe,qBAAqB,CAACT,SAAiBU;YACzC,IAAIC,QAAQ;YACZ,KAAK,MAAMC,OAAOF,OACd,KAAK,MAAMG,QAAQD,IACf,IAAI,AAAgB,YAAhB,OAAOC,MACP;gBAAA,IAAIA,SAASb,SACTW;YACJ,OACG,IAAIE,QAAQ,AAAgB,YAAhB,OAAOA,QAAqBC,MAAM,OAAO,CAACD,KAAK,IAAI,GAClE;gBAAA,KAAK,MAAME,OAAOF,KAAK,IAAI,CACvB,IAAIC,MAAM,OAAO,CAACC,IAAI,MAAM,GACxBJ,SAASF,mBAAmBT,SAASe,IAAI,MAAM;YAEvD;YAIZ,OAAOJ;QACX;QAEA,KAAK,MAAMH,SAASd,MAAM,MAAM,CAAE;YAC9B,MAAMiB,QAAQF,mBAAmBD,MAAM,EAAE,EAAEd,MAAM,MAAM;YACvD,IAAIiB,AAAU,MAAVA;gBAEG,IAAIA,QAAQ,GACf,MAAM,IAAIf,MACN,CAAC,OAAO,EAAEY,MAAM,EAAE,CAAC,kCAAkC,CAAC,EACtD,6BACA;oBACId;oBACAc;gBACJ;gBAGR,MAAM,IAAIZ,MACN,CAAC,eAAe,EAAEY,MAAM,EAAE,CAAC,YAAY,CAAC,EACxC,2BACA;oBACId;oBACAc;gBACJ;;QAER;IACJ;AACJ;AAMO,MAAMQ,oBAAoB,CAC7BtB,OACAN,UAEO,IAAIH,eAAeS,OAAON;AAO9B,MAAM6B,2BAA2B,CACpC5B,QAEO2B,kBACH;QACI,eAAe;QACf,YAAY;QACZ,WAAW;QACX,OAAO;QACP,GAAG3B,KAAK;IACZ,GACA;QACI,gBAAgB;IACpB"}
@@ -1,5 +1,5 @@
1
1
  import type { CmsModelField, CmsModelFieldValidation } from "../modelField.js";
2
- import type { CmsIcon } from "../../types/index.js";
2
+ import type { CmsIcon, CmsModelLayoutCell } from "../../types/index.js";
3
3
  export interface CmsDynamicZoneTemplate {
4
4
  id: string;
5
5
  name: string;
@@ -7,9 +7,10 @@ export interface CmsDynamicZoneTemplate {
7
7
  description: string;
8
8
  icon?: CmsIcon;
9
9
  fields: CmsModelField[];
10
- layout: string[][];
10
+ layout: CmsModelLayoutCell[][];
11
11
  validation: CmsModelFieldValidation[];
12
12
  tags?: string[];
13
+ componentName?: string;
13
14
  }
14
15
  /**
15
16
  * A definition for dynamic-zone field to show possible type of the field in settings.
package/types/model.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { CmsIdentity } from "./identity.js";
2
2
  import type { CmsModelField, CmsModelFieldInput, FieldRule } from "./modelField.js";
3
3
  import type { CmsIcon } from "../types/types.js";
4
+ import type { IModelSettings } from "../features/modelBuilder/abstractions.js";
4
5
  export interface CmsTabLayoutTab {
5
6
  id: string;
6
7
  label: string;
@@ -140,6 +141,10 @@ export interface CmsModel {
140
141
  * Is this model created via plugin?
141
142
  */
142
143
  isPlugin?: boolean;
144
+ /**
145
+ * Arbitrary model-level settings (e.g., feature flags).
146
+ */
147
+ settings?: IModelSettings | null;
143
148
  }
144
149
  export interface StorageCmsModelFields {
145
150
  compression: string;
@@ -209,6 +214,7 @@ export interface CmsModelCreateInput {
209
214
  descriptionFieldId?: string | null;
210
215
  imageFieldId?: string | null;
211
216
  icon?: CmsIcon | null;
217
+ settings?: IModelSettings | null;
212
218
  }
213
219
  /**
214
220
  * A GraphQL `params.data` parameter received when creating content model from existing model.
@@ -1,9 +1,10 @@
1
1
  import type { CmsModel, CmsModelLayout } from "./model.js";
2
2
  import type { GenericRecord } from "@webiny/api/types.js";
3
3
  import type { CmsDynamicZoneTemplate } from "../types/fields/dynamicZoneField.js";
4
+ import type { IModelSettings } from "../features/modelBuilder/abstractions.js";
4
5
  export type FieldRuleAction = "hide" | "disable" | string;
5
6
  export interface FieldRule {
6
- type: "accessControl" | "entryValue";
7
+ type: "accessControl" | "condition";
7
8
  target: string;
8
9
  operator: string;
9
10
  value: string | number | boolean | null;
@@ -242,6 +243,7 @@ export interface CmsModelUpdateInput {
242
243
  titleFieldId?: string | null;
243
244
  descriptionFieldId?: string | null;
244
245
  imageFieldId?: string | null;
246
+ settings?: IModelSettings | null;
245
247
  }
246
248
  /**
247
249
  * Object containing content model field renderer options.