@webiny/api-headless-cms 0.0.0-unstable.78f581c1d2 → 0.0.0-unstable.7f63ea0744

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 (353) hide show
  1. package/context.d.ts +5 -2
  2. package/context.js +53 -19
  3. package/context.js.map +1 -1
  4. package/crud/contentEntry/afterDelete.js +0 -5
  5. package/crud/contentEntry/afterDelete.js.map +1 -1
  6. package/crud/contentEntry/beforeCreate.js +0 -3
  7. package/crud/contentEntry/beforeCreate.js.map +1 -1
  8. package/crud/contentEntry/beforeUpdate.js +0 -3
  9. package/crud/contentEntry/beforeUpdate.js.map +1 -1
  10. package/crud/contentEntry/entryDataValidation.js +1 -40
  11. package/crud/contentEntry/entryDataValidation.js.map +1 -1
  12. package/crud/contentEntry/markLockedFields.js +6 -27
  13. package/crud/contentEntry/markLockedFields.js.map +1 -1
  14. package/crud/contentEntry/referenceFieldsMapping.js +12 -64
  15. package/crud/contentEntry/referenceFieldsMapping.js.map +1 -1
  16. package/crud/contentEntry/searchableFields.d.ts +9 -0
  17. package/crud/contentEntry/searchableFields.js +72 -0
  18. package/crud/contentEntry/searchableFields.js.map +1 -0
  19. package/crud/contentEntry.crud.js +120 -181
  20. package/crud/contentEntry.crud.js.map +1 -1
  21. package/crud/contentModel/afterCreate.js +0 -2
  22. package/crud/contentModel/afterCreate.js.map +1 -1
  23. package/crud/contentModel/afterCreateFrom.js +0 -2
  24. package/crud/contentModel/afterCreateFrom.js.map +1 -1
  25. package/crud/contentModel/afterDelete.js +0 -2
  26. package/crud/contentModel/afterDelete.js.map +1 -1
  27. package/crud/contentModel/afterUpdate.js +0 -2
  28. package/crud/contentModel/afterUpdate.js.map +1 -1
  29. package/crud/contentModel/beforeCreate.d.ts +2 -3
  30. package/crud/contentModel/beforeCreate.js +7 -36
  31. package/crud/contentModel/beforeCreate.js.map +1 -1
  32. package/crud/contentModel/beforeDelete.js +0 -10
  33. package/crud/contentModel/beforeDelete.js.map +1 -1
  34. package/crud/contentModel/beforeUpdate.d.ts +2 -4
  35. package/crud/contentModel/beforeUpdate.js +2 -7
  36. package/crud/contentModel/beforeUpdate.js.map +1 -1
  37. package/crud/contentModel/contentModelManagerFactory.js +0 -7
  38. package/crud/contentModel/contentModelManagerFactory.js.map +1 -1
  39. package/crud/contentModel/createFieldStorageId.js +4 -3
  40. package/crud/contentModel/createFieldStorageId.js.map +1 -1
  41. package/crud/contentModel/systemFields.js.map +1 -1
  42. package/crud/contentModel/validateLayout.js +0 -8
  43. package/crud/contentModel/validateLayout.js.map +1 -1
  44. package/crud/contentModel/validateModel.d.ts +3 -4
  45. package/crud/contentModel/validateModel.js +6 -11
  46. package/crud/contentModel/validateModel.js.map +1 -1
  47. package/crud/contentModel/validateModelFields.d.ts +3 -4
  48. package/crud/contentModel/validateModelFields.js +107 -97
  49. package/crud/contentModel/validateModelFields.js.map +1 -1
  50. package/crud/contentModel/validation.d.ts +477 -0
  51. package/crud/contentModel/validation.js +97 -0
  52. package/crud/contentModel/validation.js.map +1 -0
  53. package/crud/contentModel.crud.js +219 -269
  54. package/crud/contentModel.crud.js.map +1 -1
  55. package/crud/contentModelGroup/beforeCreate.js +0 -12
  56. package/crud/contentModelGroup/beforeCreate.js.map +1 -1
  57. package/crud/contentModelGroup/beforeDelete.js +0 -8
  58. package/crud/contentModelGroup/beforeDelete.js.map +1 -1
  59. package/crud/contentModelGroup/beforeUpdate.js +0 -5
  60. package/crud/contentModelGroup/beforeUpdate.js.map +1 -1
  61. package/crud/contentModelGroup/validation.d.ts +30 -0
  62. package/crud/contentModelGroup/validation.js +34 -0
  63. package/crud/contentModelGroup/validation.js.map +1 -0
  64. package/crud/contentModelGroup.crud.js +53 -95
  65. package/crud/contentModelGroup.crud.js.map +1 -1
  66. package/crud/settings.crud.js +0 -12
  67. package/crud/settings.crud.js.map +1 -1
  68. package/crud/system.crud.js +2 -37
  69. package/crud/system.crud.js.map +1 -1
  70. package/fieldConverters/CmsModelDefaultFieldConverterPlugin.js +0 -13
  71. package/fieldConverters/CmsModelDefaultFieldConverterPlugin.js.map +1 -1
  72. package/fieldConverters/CmsModelDynamicZoneFieldConverterPlugin.d.ts +11 -0
  73. package/fieldConverters/CmsModelDynamicZoneFieldConverterPlugin.js +203 -0
  74. package/fieldConverters/CmsModelDynamicZoneFieldConverterPlugin.js.map +1 -0
  75. package/fieldConverters/CmsModelObjectFieldConverterPlugin.js +0 -53
  76. package/fieldConverters/CmsModelObjectFieldConverterPlugin.js.map +1 -1
  77. package/fieldConverters/index.d.ts +2 -1
  78. package/fieldConverters/index.js +2 -5
  79. package/fieldConverters/index.js.map +1 -1
  80. package/graphql/buildSchemaPlugins.d.ts +8 -3
  81. package/graphql/buildSchemaPlugins.js +6 -14
  82. package/graphql/buildSchemaPlugins.js.map +1 -1
  83. package/graphql/createExecutableSchema.d.ts +7 -0
  84. package/graphql/createExecutableSchema.js +29 -0
  85. package/graphql/createExecutableSchema.js.map +1 -0
  86. package/graphql/generateSchema.d.ts +8 -0
  87. package/graphql/generateSchema.js +31 -0
  88. package/graphql/generateSchema.js.map +1 -0
  89. package/graphql/graphQLHandlerFactory.js +90 -74
  90. package/graphql/graphQLHandlerFactory.js.map +1 -1
  91. package/graphql/index.d.ts +1 -3
  92. package/graphql/index.js +2 -46
  93. package/graphql/index.js.map +1 -1
  94. package/graphql/schema/baseContentSchema.d.ts +6 -2
  95. package/graphql/schema/baseContentSchema.js +7 -13
  96. package/graphql/schema/baseContentSchema.js.map +1 -1
  97. package/graphql/schema/baseSchema.d.ts +3 -0
  98. package/graphql/schema/baseSchema.js +53 -0
  99. package/graphql/schema/baseSchema.js.map +1 -0
  100. package/graphql/schema/contentEntries.d.ts +6 -2
  101. package/graphql/schema/contentEntries.js +39 -65
  102. package/graphql/schema/contentEntries.js.map +1 -1
  103. package/graphql/schema/contentModelGroups.d.ts +6 -2
  104. package/graphql/schema/contentModelGroups.js +9 -22
  105. package/graphql/schema/contentModelGroups.js.map +1 -1
  106. package/graphql/schema/contentModels.d.ts +6 -2
  107. package/graphql/schema/contentModels.js +42 -25
  108. package/graphql/schema/contentModels.js.map +1 -1
  109. package/graphql/schema/createFieldResolvers.d.ts +1 -1
  110. package/graphql/schema/createFieldResolvers.js +20 -27
  111. package/graphql/schema/createFieldResolvers.js.map +1 -1
  112. package/graphql/schema/createManageResolvers.js +0 -26
  113. package/graphql/schema/createManageResolvers.js.map +1 -1
  114. package/graphql/schema/createManageSDL.d.ts +2 -0
  115. package/graphql/schema/createManageSDL.js +11 -20
  116. package/graphql/schema/createManageSDL.js.map +1 -1
  117. package/graphql/schema/createPreviewResolvers.js +0 -10
  118. package/graphql/schema/createPreviewResolvers.js.map +1 -1
  119. package/graphql/schema/createReadResolvers.js +5 -10
  120. package/graphql/schema/createReadResolvers.js.map +1 -1
  121. package/graphql/schema/createReadSDL.d.ts +2 -0
  122. package/graphql/schema/createReadSDL.js +11 -15
  123. package/graphql/schema/createReadSDL.js.map +1 -1
  124. package/graphql/schema/resolvers/commonFieldResolvers.js +0 -2
  125. package/graphql/schema/resolvers/commonFieldResolvers.js.map +1 -1
  126. package/graphql/schema/resolvers/manage/resolveCreate.js +0 -3
  127. package/graphql/schema/resolvers/manage/resolveCreate.js.map +1 -1
  128. package/graphql/schema/resolvers/manage/resolveCreateFrom.js +0 -3
  129. package/graphql/schema/resolvers/manage/resolveCreateFrom.js.map +1 -1
  130. package/graphql/schema/resolvers/manage/resolveDelete.js +0 -6
  131. package/graphql/schema/resolvers/manage/resolveDelete.js.map +1 -1
  132. package/graphql/schema/resolvers/manage/resolveGet.js +0 -16
  133. package/graphql/schema/resolvers/manage/resolveGet.js.map +1 -1
  134. package/graphql/schema/resolvers/manage/resolveGetByIds.js +0 -3
  135. package/graphql/schema/resolvers/manage/resolveGetByIds.js.map +1 -1
  136. package/graphql/schema/resolvers/manage/resolveGetRevisions.js +0 -3
  137. package/graphql/schema/resolvers/manage/resolveGetRevisions.js.map +1 -1
  138. package/graphql/schema/resolvers/manage/resolveList.js +0 -3
  139. package/graphql/schema/resolvers/manage/resolveList.js.map +1 -1
  140. package/graphql/schema/resolvers/manage/resolvePublish.js +0 -3
  141. package/graphql/schema/resolvers/manage/resolvePublish.js.map +1 -1
  142. package/graphql/schema/resolvers/manage/resolveRepublish.js +0 -3
  143. package/graphql/schema/resolvers/manage/resolveRepublish.js.map +1 -1
  144. package/graphql/schema/resolvers/manage/resolveUnpublish.js +0 -3
  145. package/graphql/schema/resolvers/manage/resolveUnpublish.js.map +1 -1
  146. package/graphql/schema/resolvers/manage/resolveUpdate.js +0 -3
  147. package/graphql/schema/resolvers/manage/resolveUpdate.js.map +1 -1
  148. package/graphql/schema/resolvers/preview/resolveGet.js +0 -8
  149. package/graphql/schema/resolvers/preview/resolveGet.js.map +1 -1
  150. package/graphql/schema/resolvers/preview/resolveList.js +0 -3
  151. package/graphql/schema/resolvers/preview/resolveList.js.map +1 -1
  152. package/graphql/schema/resolvers/read/resolveGet.js +0 -8
  153. package/graphql/schema/resolvers/read/resolveGet.js.map +1 -1
  154. package/graphql/schema/resolvers/read/resolveList.js +0 -3
  155. package/graphql/schema/resolvers/read/resolveList.js.map +1 -1
  156. package/graphql/schema/schemaPlugins.d.ts +8 -3
  157. package/graphql/schema/schemaPlugins.js +63 -65
  158. package/graphql/schema/schemaPlugins.js.map +1 -1
  159. package/graphql/system.js +69 -85
  160. package/graphql/system.js.map +1 -1
  161. package/graphqlFields/boolean.js +0 -12
  162. package/graphqlFields/boolean.js.map +1 -1
  163. package/graphqlFields/datetime.js +0 -17
  164. package/graphqlFields/datetime.js.map +1 -1
  165. package/graphqlFields/dynamicZone/dynamicZoneField.d.ts +2 -0
  166. package/graphqlFields/dynamicZone/dynamicZoneField.js +208 -0
  167. package/graphqlFields/dynamicZone/dynamicZoneField.js.map +1 -0
  168. package/graphqlFields/dynamicZone/dynamicZoneStorage.d.ts +3 -0
  169. package/graphqlFields/dynamicZone/dynamicZoneStorage.js +63 -0
  170. package/graphqlFields/dynamicZone/dynamicZoneStorage.js.map +1 -0
  171. package/graphqlFields/dynamicZone/index.d.ts +2 -0
  172. package/graphqlFields/dynamicZone/index.js +19 -0
  173. package/graphqlFields/dynamicZone/index.js.map +1 -0
  174. package/graphqlFields/file.js +0 -8
  175. package/graphqlFields/file.js.map +1 -1
  176. package/graphqlFields/helpers.js +0 -10
  177. package/graphqlFields/helpers.js.map +1 -1
  178. package/graphqlFields/index.d.ts +1 -1
  179. package/graphqlFields/index.js +2 -12
  180. package/graphqlFields/index.js.map +1 -1
  181. package/graphqlFields/longText.js +0 -10
  182. package/graphqlFields/longText.js.map +1 -1
  183. package/graphqlFields/number.js +4 -12
  184. package/graphqlFields/number.js.map +1 -1
  185. package/graphqlFields/object.js +112 -98
  186. package/graphqlFields/object.js.map +1 -1
  187. package/graphqlFields/ref.js +48 -96
  188. package/graphqlFields/ref.js.map +1 -1
  189. package/graphqlFields/richText.js +0 -9
  190. package/graphqlFields/richText.js.map +1 -1
  191. package/graphqlFields/text.js +0 -11
  192. package/graphqlFields/text.js.map +1 -1
  193. package/index.d.ts +3 -3
  194. package/index.js +3 -26
  195. package/index.js.map +1 -1
  196. package/modelManager/DefaultCmsModelManager.js +0 -16
  197. package/modelManager/DefaultCmsModelManager.js.map +1 -1
  198. package/modelManager/index.js +0 -4
  199. package/modelManager/index.js.map +1 -1
  200. package/package.json +28 -28
  201. package/parameters/context.js +0 -4
  202. package/parameters/context.js.map +1 -1
  203. package/parameters/header.js +0 -11
  204. package/parameters/header.js.map +1 -1
  205. package/parameters/index.js +0 -8
  206. package/parameters/index.js.map +1 -1
  207. package/parameters/manual.js +1 -8
  208. package/parameters/manual.js.map +1 -1
  209. package/parameters/path.js +0 -11
  210. package/parameters/path.js.map +1 -1
  211. package/plugins/CmsGraphQLSchemaPlugin.d.ts +5 -0
  212. package/plugins/CmsGraphQLSchemaPlugin.js +12 -0
  213. package/plugins/CmsGraphQLSchemaPlugin.js.map +1 -0
  214. package/plugins/CmsGraphQLSchemaSorterPlugin.d.ts +20 -0
  215. package/plugins/CmsGraphQLSchemaSorterPlugin.js +28 -0
  216. package/plugins/CmsGraphQLSchemaSorterPlugin.js.map +1 -0
  217. package/plugins/CmsGroupPlugin.js +0 -8
  218. package/plugins/CmsGroupPlugin.js.map +1 -1
  219. package/plugins/CmsModelFieldConverterPlugin.d.ts +2 -2
  220. package/plugins/CmsModelFieldConverterPlugin.js +0 -5
  221. package/plugins/CmsModelFieldConverterPlugin.js.map +1 -1
  222. package/plugins/CmsModelPlugin.js +2 -38
  223. package/plugins/CmsModelPlugin.js.map +1 -1
  224. package/plugins/CmsParametersPlugin.js +0 -7
  225. package/plugins/CmsParametersPlugin.js.map +1 -1
  226. package/plugins/StorageTransformPlugin.d.ts +11 -11
  227. package/plugins/StorageTransformPlugin.js +0 -9
  228. package/plugins/StorageTransformPlugin.js.map +1 -1
  229. package/plugins/index.d.ts +2 -0
  230. package/plugins/index.js +22 -10
  231. package/plugins/index.js.map +1 -1
  232. package/storage/default.js +0 -3
  233. package/storage/default.js.map +1 -1
  234. package/storage/object.js +4 -20
  235. package/storage/object.js.map +1 -1
  236. package/types.d.ts +241 -57
  237. package/types.js +62 -69
  238. package/types.js.map +1 -1
  239. package/upgrades/5.33.0/index.js +3 -26
  240. package/upgrades/5.33.0/index.js.map +1 -1
  241. package/upgrades/index.js +0 -3
  242. package/upgrades/index.js.map +1 -1
  243. package/utils/access.js +11 -25
  244. package/utils/access.js.map +1 -1
  245. package/utils/converters/Converter.js +0 -13
  246. package/utils/converters/Converter.js.map +1 -1
  247. package/utils/converters/ConverterCollection.js +14 -34
  248. package/utils/converters/ConverterCollection.js.map +1 -1
  249. package/utils/converters/valueKeyStorageConverter.js +0 -26
  250. package/utils/converters/valueKeyStorageConverter.js.map +1 -1
  251. package/utils/createTypeFromFields.d.ts +15 -0
  252. package/utils/createTypeFromFields.js +64 -0
  253. package/utils/createTypeFromFields.js.map +1 -0
  254. package/utils/createTypeName.js +2 -9
  255. package/utils/createTypeName.js.map +1 -1
  256. package/utils/entryStorage.js +22 -35
  257. package/utils/entryStorage.js.map +1 -1
  258. package/utils/filterAsync.js +0 -5
  259. package/utils/filterAsync.js.map +1 -1
  260. package/utils/getBaseFieldType.d.ts +4 -0
  261. package/utils/getBaseFieldType.js +10 -0
  262. package/utils/getBaseFieldType.js.map +1 -0
  263. package/utils/getEntryTitle.js +0 -9
  264. package/utils/getEntryTitle.js.map +1 -1
  265. package/utils/getSchemaFromFieldPlugins.d.ts +4 -7
  266. package/utils/getSchemaFromFieldPlugins.js +23 -19
  267. package/utils/getSchemaFromFieldPlugins.js.map +1 -1
  268. package/utils/ownership.js +0 -8
  269. package/utils/ownership.js.map +1 -1
  270. package/utils/permissions.js +8 -23
  271. package/utils/permissions.js.map +1 -1
  272. package/utils/pluralizedTypeName.js +0 -6
  273. package/utils/pluralizedTypeName.js.map +1 -1
  274. package/utils/renderFields.js +2 -9
  275. package/utils/renderFields.js.map +1 -1
  276. package/utils/renderGetFilterFields.js +6 -14
  277. package/utils/renderGetFilterFields.js.map +1 -1
  278. package/utils/renderInputFields.js +2 -9
  279. package/utils/renderInputFields.js.map +1 -1
  280. package/utils/renderListFilterFields.js +4 -10
  281. package/utils/renderListFilterFields.js.map +1 -1
  282. package/utils/renderSortEnum.d.ts +7 -4
  283. package/utils/renderSortEnum.js +21 -11
  284. package/utils/renderSortEnum.js.map +1 -1
  285. package/utils/toSlug.js +0 -4
  286. package/utils/toSlug.js.map +1 -1
  287. package/validators/dateGte.js +0 -7
  288. package/validators/dateGte.js.map +1 -1
  289. package/validators/dateLte.js +0 -7
  290. package/validators/dateLte.js.map +1 -1
  291. package/validators/dynamicZone.d.ts +2 -0
  292. package/validators/dynamicZone.js +20 -0
  293. package/validators/dynamicZone.js.map +1 -0
  294. package/validators/gte.js +0 -8
  295. package/validators/gte.js.map +1 -1
  296. package/validators/in.js +0 -8
  297. package/validators/in.js.map +1 -1
  298. package/validators/index.js +2 -16
  299. package/validators/index.js.map +1 -1
  300. package/validators/lte.js +0 -8
  301. package/validators/lte.js.map +1 -1
  302. package/validators/maxLength.js +0 -8
  303. package/validators/maxLength.js.map +1 -1
  304. package/validators/minLength.js +0 -8
  305. package/validators/minLength.js.map +1 -1
  306. package/validators/pattern.js +0 -9
  307. package/validators/pattern.js.map +1 -1
  308. package/validators/patternPlugins/email.js +0 -2
  309. package/validators/patternPlugins/email.js.map +1 -1
  310. package/validators/patternPlugins/index.js +0 -8
  311. package/validators/patternPlugins/index.js.map +1 -1
  312. package/validators/patternPlugins/lowerCase.js +0 -2
  313. package/validators/patternPlugins/lowerCase.js.map +1 -1
  314. package/validators/patternPlugins/lowerCaseSpace.js +0 -2
  315. package/validators/patternPlugins/lowerCaseSpace.js.map +1 -1
  316. package/validators/patternPlugins/upperCase.js +0 -2
  317. package/validators/patternPlugins/upperCase.js.map +1 -1
  318. package/validators/patternPlugins/upperCaseSpace.js +0 -2
  319. package/validators/patternPlugins/upperCaseSpace.js.map +1 -1
  320. package/validators/patternPlugins/url.js +0 -2
  321. package/validators/patternPlugins/url.js.map +1 -1
  322. package/validators/required.js +0 -5
  323. package/validators/required.js.map +1 -1
  324. package/validators/timeGte.js +0 -8
  325. package/validators/timeGte.js.map +1 -1
  326. package/validators/timeLte.js +0 -8
  327. package/validators/timeLte.js.map +1 -1
  328. package/validators/unique.js +0 -7
  329. package/validators/unique.js.map +1 -1
  330. package/crud/contentModel/createFieldModels.d.ts +0 -2
  331. package/crud/contentModel/createFieldModels.js +0 -26
  332. package/crud/contentModel/createFieldModels.js.map +0 -1
  333. package/crud/contentModel/fieldIdValidation.d.ts +0 -1
  334. package/crud/contentModel/fieldIdValidation.js +0 -25
  335. package/crud/contentModel/fieldIdValidation.js.map +0 -1
  336. package/crud/contentModel/idValidation.d.ts +0 -1
  337. package/crud/contentModel/idValidation.js +0 -22
  338. package/crud/contentModel/idValidation.js.map +0 -1
  339. package/crud/contentModel/models.d.ts +0 -4
  340. package/crud/contentModel/models.js +0 -180
  341. package/crud/contentModel/models.js.map +0 -1
  342. package/crud/index.d.ts +0 -6
  343. package/crud/index.js +0 -85
  344. package/crud/index.js.map +0 -1
  345. package/graphql/schema/resolvers/manage/resolveRequestChanges.d.ts +0 -7
  346. package/graphql/schema/resolvers/manage/resolveRequestChanges.js +0 -21
  347. package/graphql/schema/resolvers/manage/resolveRequestChanges.js.map +0 -1
  348. package/graphql/schema/resolvers/manage/resolveRequestReview.d.ts +0 -7
  349. package/graphql/schema/resolvers/manage/resolveRequestReview.js +0 -21
  350. package/graphql/schema/resolvers/manage/resolveRequestReview.js.map +0 -1
  351. package/utils/filterModelFields.d.ts +0 -16
  352. package/utils/filterModelFields.js +0 -77
  353. package/utils/filterModelFields.js.map +0 -1
@@ -1,25 +1,22 @@
1
1
  "use strict";
2
2
 
3
3
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
-
5
4
  Object.defineProperty(exports, "__esModule", {
6
5
  value: true
7
6
  });
8
7
  exports.validateModelFields = void 0;
9
-
10
8
  var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
11
-
12
9
  var _error = _interopRequireDefault(require("@webiny/error"));
13
-
14
10
  var _createManageSDL = require("../../graphql/schema/createManageSDL");
15
-
16
11
  var _graphqlTag = _interopRequireDefault(require("graphql-tag"));
17
-
18
12
  var _createFieldStorageId = require("./createFieldStorageId");
19
-
13
+ var _getBaseFieldType = require("../../utils/getBaseFieldType");
14
+ var _plugins = require("../../plugins");
15
+ var _buildSchemaPlugins = require("../../graphql/buildSchemaPlugins");
16
+ var _createExecutableSchema = require("../../graphql/createExecutableSchema");
17
+ var _handlerGraphql = require("@webiny/handler-graphql");
20
18
  const defaultTitleFieldId = "id";
21
19
  const allowedTitleFieldTypes = ["text", "number"];
22
-
23
20
  const getContentModelTitleFieldId = (fields, titleFieldId) => {
24
21
  /**
25
22
  * If there are no fields defined, we will return the default field
@@ -32,11 +29,9 @@ const getContentModelTitleFieldId = (fields, titleFieldId) => {
32
29
  * we will take first text field that has no multiple values enabled
33
30
  * or if initial titleFieldId is the default one also try to find first available text field
34
31
  */
35
-
36
-
37
32
  if (!titleFieldId || titleFieldId === defaultTitleFieldId) {
38
33
  const titleField = fields.find(field => {
39
- return field.type === "text" && !field.multipleValues;
34
+ return (0, _getBaseFieldType.getBaseFieldType)(field) === "text" && !field.multipleValues;
40
35
  });
41
36
  return (titleField === null || titleField === void 0 ? void 0 : titleField.fieldId) || defaultTitleFieldId;
42
37
  }
@@ -45,17 +40,13 @@ const getContentModelTitleFieldId = (fields, titleFieldId) => {
45
40
  * for correct type
46
41
  * and that it is not multiple values field
47
42
  */
48
-
49
-
50
43
  const target = fields.find(f => f.fieldId === titleFieldId);
51
-
52
44
  if (!target) {
53
45
  throw new _error.default(`Field selected for the title field does not exist in the model.`, "VALIDATION_ERROR", {
54
46
  fieldId: titleFieldId,
55
47
  fields
56
48
  });
57
49
  }
58
-
59
50
  if (allowedTitleFieldTypes.includes(target.type) === false) {
60
51
  throw new _error.default(`Only ${allowedTitleFieldTypes.join(", ")} and id fields can be used as an entry title.`, "ENTRY_TITLE_FIELD_TYPE", {
61
52
  storageId: target.storageId,
@@ -63,7 +54,6 @@ const getContentModelTitleFieldId = (fields, titleFieldId) => {
63
54
  type: target.type
64
55
  });
65
56
  }
66
-
67
57
  if (target.multipleValues) {
68
58
  throw new _error.default(`Fields that accept multiple values cannot be used as the entry title.`, "ENTRY_TITLE_FIELD_TYPE", {
69
59
  storageId: target.storageId,
@@ -71,18 +61,15 @@ const getContentModelTitleFieldId = (fields, titleFieldId) => {
71
61
  type: target.type
72
62
  });
73
63
  }
74
-
75
64
  return target.fieldId;
76
65
  };
77
-
78
66
  const extractInvalidField = (model, err) => {
79
67
  var _err$source;
80
-
81
68
  const sdl = ((_err$source = err.source) === null || _err$source === void 0 ? void 0 : _err$source.body) || "";
69
+
82
70
  /**
83
71
  * Find the invalid type
84
72
  */
85
-
86
73
  const {
87
74
  line: lineNumber
88
75
  } = err.locations ? err.locations[0] : {
@@ -91,33 +78,25 @@ const extractInvalidField = (model, err) => {
91
78
  const sdlLines = sdl.split("\n");
92
79
  let sdlLine;
93
80
  let gqlType;
94
-
95
81
  for (let i = lineNumber; i > 0; i--) {
96
82
  if (sdlLine && sdlLine.includes("type ")) {
97
83
  gqlType = sdlLine.match(/type\s+(.*?)\s+{/);
98
84
  break;
99
85
  }
100
-
101
86
  sdlLine = sdlLines[i];
102
87
  }
103
-
104
88
  let invalidField = undefined;
105
-
106
89
  if (Array.isArray(gqlType)) {
107
90
  const fieldRegex = new RegExp(`([^\\s+].*?):\\s+\\[?${gqlType[1]}!?\\]?`);
108
91
  const matched = sdl.match(fieldRegex);
109
-
110
92
  if (matched) {
111
93
  invalidField = matched[1];
112
94
  }
113
95
  }
114
-
115
96
  let message = `See more details in the browser console.`;
116
-
117
97
  if (invalidField) {
118
98
  message = `Please review the definition of "${invalidField}" field.`;
119
99
  }
120
-
121
100
  return {
122
101
  data: {
123
102
  modelId: model.modelId,
@@ -128,7 +107,22 @@ const extractInvalidField = (model, err) => {
128
107
  message: [`Model "${model.modelId}" was not saved!`, message].join("\n")
129
108
  };
130
109
  };
131
-
110
+ const createValidateChildFields = plugins => {
111
+ return ({
112
+ fields,
113
+ originalFields
114
+ }) => {
115
+ if (fields.length === 0 && originalFields.length === 0) {
116
+ return;
117
+ }
118
+ validateFields({
119
+ fields,
120
+ originalFields,
121
+ plugins,
122
+ lockedFields: []
123
+ });
124
+ };
125
+ };
132
126
  const validateFields = params => {
133
127
  const {
134
128
  plugins,
@@ -136,23 +130,27 @@ const validateFields = params => {
136
130
  originalFields,
137
131
  lockedFields
138
132
  } = params;
133
+ const idList = [];
139
134
  const fieldIdList = [];
140
135
  const storageIdList = [];
141
-
142
136
  for (const field of fields) {
143
- var _field$settings, _originalField$settin;
144
-
145
- const plugin = plugins.find(item => item.fieldType === field.type);
146
-
137
+ const baseType = (0, _getBaseFieldType.getBaseFieldType)(field);
138
+ const plugin = plugins.find(plugin => plugin.fieldType === baseType);
147
139
  if (!plugin) {
148
- throw new Error(`Cannot update content model because of the unknown "${field.type}" field.`);
140
+ throw new Error(`Cannot update content model because of the unknown "${baseType}" field.`);
149
141
  }
150
-
142
+ /**
143
+ * Check the field's id against existing ones.
144
+ * There cannot be two fields with the same id.
145
+ */
146
+ if (idList.includes(field.id)) {
147
+ throw new _error.default(`Cannot update content model because field "${field.storageId || field.fieldId}" has id "${field.id}", which is already used.`);
148
+ }
149
+ idList.push(field.id);
151
150
  const originalField = originalFields.find(f => f.id === field.id);
152
151
  /**
153
152
  * Field MUST have an fieldId defined.
154
153
  */
155
-
156
154
  if (!field.fieldId) {
157
155
  throw new _error.default(`Field does not have an "fieldId" defined.`, "MISSING_FIELD_ID", {
158
156
  field
@@ -171,12 +169,9 @@ const validateFields = params => {
171
169
  * https://discuss.elastic.co/t/special-characters-in-field-names/10658/3
172
170
  * https://discuss.elastic.co/t/illegal-characters-in-elasticsearch-field-names/17196/2
173
171
  */
174
-
175
-
176
172
  const isLocked = lockedFields.some(lockedField => {
177
- return lockedField.fieldId === field.storageId;
173
+ return lockedField.fieldId === field.storageId || lockedField.fieldId === field.fieldId;
178
174
  });
179
-
180
175
  if (!field.storageId) {
181
176
  /**
182
177
  * In case field is locked, we must set the storageId to the fieldId value.
@@ -205,75 +200,82 @@ const validateFields = params => {
205
200
  * Check the field's fieldId against existing ones.
206
201
  * There cannot be two fields with the same fieldId - outside world identifier.
207
202
  */
208
-
209
-
210
203
  if (fieldIdList.includes(field.fieldId)) {
211
204
  throw new _error.default(`Cannot update content model because field "${field.storageId}" has fieldId "${field.fieldId}", which is already used.`);
212
205
  }
213
-
214
206
  fieldIdList.push(field.fieldId);
215
207
  /**
216
208
  * Check the field's storageId against the existing ones.
217
209
  * There cannot be two fields with the same storageId.
218
210
  */
219
-
220
211
  if (storageIdList.includes(field.storageId)) {
221
212
  throw new _error.default(`Cannot update content model because field "${field.label}" has storageId "${field.storageId}", which is already used.`);
222
213
  }
223
-
224
214
  storageIdList.push(field.storageId);
225
215
  /**
226
- * TODO maybe make this part pluginable?
227
- * We need to check the object field child fields.
228
- * It must be recursive.
216
+ * There might be some plugins which allow child fields.
217
+ * We use this method to validate them as well.
229
218
  */
230
-
231
- if (field.type !== "object") {
232
- continue;
233
- }
234
-
235
- const childFields = ((_field$settings = field.settings) === null || _field$settings === void 0 ? void 0 : _field$settings.fields) || [];
236
- const originalChildFields = (originalField === null || originalField === void 0 ? void 0 : (_originalField$settin = originalField.settings) === null || _originalField$settin === void 0 ? void 0 : _originalField$settin.fields) || [];
237
- /**
238
- * No point in going further if there are no child fields.
239
- * Code will break if child fields were removed but used in the entries.
240
- */
241
-
242
- if (childFields.length === 0) {
219
+ if (!plugin.validateChildFields) {
243
220
  continue;
244
221
  }
245
-
246
- validateFields({
247
- fields: childFields,
248
- originalFields: originalChildFields,
249
- plugins,
250
- lockedFields: []
222
+ const validateChildFields = createValidateChildFields(plugins);
223
+ plugin.validateChildFields({
224
+ field,
225
+ originalField,
226
+ validate: validateChildFields
251
227
  });
252
228
  }
253
229
  };
254
-
255
- const validateModelFields = params => {
230
+ const createGraphQLSchema = async params => {
231
+ const {
232
+ context,
233
+ model
234
+ } = params;
235
+ const modelPlugins = await (0, _buildSchemaPlugins.buildSchemaPlugins)({
236
+ context,
237
+ models: [model]
238
+ });
239
+ const plugins = context.plugins.byType(_handlerGraphql.GraphQLSchemaPlugin.type);
240
+ plugins.push(...modelPlugins);
241
+ return (0, _createExecutableSchema.createExecutableSchema)({
242
+ plugins
243
+ });
244
+ };
245
+ const extractErrorObject = error => {
246
+ return ["message", "code", "data", "stack"].reduce((output, key) => {
247
+ if (!error[key]) {
248
+ return output;
249
+ }
250
+ output[key] = error[key];
251
+ return output;
252
+ }, {});
253
+ };
254
+ const validateModelFields = async params => {
256
255
  const {
257
256
  model,
258
257
  original,
259
- plugins
258
+ context
260
259
  } = params;
261
260
  const {
262
261
  titleFieldId
263
262
  } = model;
263
+ const {
264
+ plugins
265
+ } = context;
266
+
264
267
  /**
265
268
  * There should be fields/locked fields in either model or data to be updated.
266
269
  */
267
-
268
270
  const {
269
271
  fields = [],
270
272
  lockedFields = []
271
273
  } = model;
274
+
272
275
  /**
273
276
  * Let's inspect the fields of the received content model. We prevent saving of a content model if it
274
277
  * contains a field for which a "cms-model-field-to-graphql" plugin does not exist on the backend.
275
278
  */
276
-
277
279
  const fieldTypePlugins = plugins.byType("cms-model-field-to-graphql");
278
280
  validateFields({
279
281
  fields,
@@ -281,8 +283,8 @@ const validateModelFields = params => {
281
283
  lockedFields,
282
284
  plugins: fieldTypePlugins
283
285
  });
284
-
285
286
  if (fields.length) {
287
+ const sorterPlugins = plugins.byType(_plugins.CmsGraphQLSchemaSorterPlugin.type);
286
288
  /**
287
289
  * Make sure that this model can be safely converted to a GraphQL SDL
288
290
  */
@@ -290,64 +292,73 @@ const validateModelFields = params => {
290
292
  model,
291
293
  fieldTypePlugins: fieldTypePlugins.reduce((acc, pl) => (0, _objectSpread2.default)((0, _objectSpread2.default)({}, acc), {}, {
292
294
  [pl.fieldType]: pl
293
- }), {})
295
+ }), {}),
296
+ sorterPlugins
294
297
  });
295
-
296
298
  try {
297
299
  (0, _graphqlTag.default)(schema);
298
300
  } catch (err) {
299
301
  throw new _error.default(extractInvalidField(model, err));
300
302
  }
303
+ /**
304
+ *
305
+ */
306
+ try {
307
+ await createGraphQLSchema({
308
+ context,
309
+ model
310
+ });
311
+ } catch (err) {
312
+ throw new _error.default({
313
+ message: "Cannot generate GraphQL schema when testing with the given model. Please check the response for more details.",
314
+ code: "GRAPHQL_SCHEMA_ERROR",
315
+ data: {
316
+ modelId: model.modelId,
317
+ error: extractErrorObject(err)
318
+ }
319
+ });
320
+ }
301
321
  }
302
-
303
322
  model.titleFieldId = getContentModelTitleFieldId(fields, titleFieldId);
304
323
  const cmsLockedFieldPlugins = plugins.byType("cms-model-locked-field");
324
+
305
325
  /**
306
326
  * We must not allow removal or changes in fields that are already in use in content entries.
307
327
  * Locked fields still have fieldId (should be storageId) because of the old existing locked fields in the models.
308
328
  */
309
-
310
329
  for (const lockedField of lockedFields) {
311
330
  const existingField = fields.find(item => item.storageId === lockedField.fieldId);
331
+
312
332
  /**
313
333
  * Starting with 5.33.0 fields can be deleted.
314
334
  * Our UI gives a warning upon locked field deletion, but if user is managing fields through API directly - we cannot do anything.
315
335
  */
316
-
317
336
  if (!existingField) {
318
- continue; // throw new WebinyError(
319
- // `Cannot remove the field "${lockedField.fieldId}" because it's already in use in created content.`,
320
- // "ENTRY_FIELD_USED",
321
- // {
322
- // lockedField,
323
- // fields
324
- // }
325
- // );
337
+ continue;
326
338
  }
327
-
328
339
  if (lockedField.multipleValues !== existingField.multipleValues) {
329
340
  throw new _error.default(`Cannot change "multipleValues" for the "${lockedField.fieldId}" field because it's already in use in created content.`, "ENTRY_FIELD_USED", {
341
+ reason: `"multipleValues" changed`,
330
342
  field: existingField
331
343
  });
332
344
  }
333
-
334
- if (lockedField.type !== existingField.type) {
345
+ const fieldType = (0, _getBaseFieldType.getBaseFieldType)(existingField);
346
+ if (lockedField.type !== fieldType) {
335
347
  throw new _error.default(`Cannot change field type for the "${lockedField.fieldId}" field because it's already in use in created content.`, "ENTRY_FIELD_USED", {
336
- field: existingField
348
+ reason: `"type" changed`,
349
+ lockedFieldType: lockedField.type,
350
+ existingFieldType: fieldType
337
351
  });
338
352
  }
353
+
339
354
  /**
340
355
  * Check `lockedField` invariant for specific field
341
356
  */
342
-
343
-
344
- const lockedFieldsByType = cmsLockedFieldPlugins.filter(pl => pl.fieldType === lockedField.type);
345
-
357
+ const lockedFieldsByType = cmsLockedFieldPlugins.filter(pl => pl.fieldType === (0, _getBaseFieldType.getBaseFieldType)(lockedField));
346
358
  for (const plugin of lockedFieldsByType) {
347
359
  if (typeof plugin.checkLockedField !== "function") {
348
360
  continue;
349
361
  }
350
-
351
362
  plugin.checkLockedField({
352
363
  lockedField,
353
364
  field: existingField
@@ -355,5 +366,4 @@ const validateModelFields = params => {
355
366
  }
356
367
  }
357
368
  };
358
-
359
369
  exports.validateModelFields = validateModelFields;
@@ -1 +1 @@
1
- {"version":3,"names":["defaultTitleFieldId","allowedTitleFieldTypes","getContentModelTitleFieldId","fields","titleFieldId","length","titleField","find","field","type","multipleValues","fieldId","target","f","WebinyError","includes","join","storageId","extractInvalidField","model","err","sdl","source","body","line","lineNumber","locations","sdlLines","split","sdlLine","gqlType","i","match","invalidField","undefined","Array","isArray","fieldRegex","RegExp","matched","message","data","modelId","code","validateFields","params","plugins","originalFields","lockedFields","fieldIdList","storageIdList","plugin","item","fieldType","Error","originalField","id","isLocked","some","lockedField","createFieldStorageId","push","label","childFields","settings","originalChildFields","validateModelFields","original","fieldTypePlugins","byType","schema","createManageSDL","reduce","acc","pl","gql","cmsLockedFieldPlugins","existingField","lockedFieldsByType","filter","checkLockedField"],"sources":["validateModelFields.ts"],"sourcesContent":["import {\n CmsModel,\n CmsModelField,\n CmsModelFieldToGraphQLPlugin,\n CmsModelLockedFieldPlugin,\n LockedField\n} from \"~/types\";\nimport WebinyError from \"@webiny/error\";\nimport { createManageSDL } from \"~/graphql/schema/createManageSDL\";\nimport gql from \"graphql-tag\";\nimport { PluginsContainer } from \"@webiny/plugins\";\nimport { createFieldStorageId } from \"./createFieldStorageId\";\nimport { GraphQLError } from \"graphql\";\n\nconst defaultTitleFieldId = \"id\";\n\nconst allowedTitleFieldTypes = [\"text\", \"number\"];\n\nconst getContentModelTitleFieldId = (fields: CmsModelField[], titleFieldId?: string): string => {\n /**\n * If there are no fields defined, we will return the default field\n */\n if (fields.length === 0) {\n return defaultTitleFieldId;\n }\n /**\n * if there is no title field defined either in input data or existing content model data\n * we will take first text field that has no multiple values enabled\n * or if initial titleFieldId is the default one also try to find first available text field\n */\n if (!titleFieldId || titleFieldId === defaultTitleFieldId) {\n const titleField = fields.find(field => {\n return field.type === \"text\" && !field.multipleValues;\n });\n return titleField?.fieldId || defaultTitleFieldId;\n }\n /**\n * check existing titleFieldId for existence in the model\n * for correct type\n * and that it is not multiple values field\n */\n const target = fields.find(f => f.fieldId === titleFieldId);\n if (!target) {\n throw new WebinyError(\n `Field selected for the title field does not exist in the model.`,\n \"VALIDATION_ERROR\",\n {\n fieldId: titleFieldId,\n fields\n }\n );\n }\n\n if (allowedTitleFieldTypes.includes(target.type) === false) {\n throw new WebinyError(\n `Only ${allowedTitleFieldTypes.join(\n \", \"\n )} and id fields can be used as an entry title.`,\n \"ENTRY_TITLE_FIELD_TYPE\",\n {\n storageId: target.storageId,\n fieldId: target.fieldId,\n type: target.type\n }\n );\n }\n\n if (target.multipleValues) {\n throw new WebinyError(\n `Fields that accept multiple values cannot be used as the entry title.`,\n \"ENTRY_TITLE_FIELD_TYPE\",\n {\n storageId: target.storageId,\n fieldId: target.fieldId,\n type: target.type\n }\n );\n }\n\n return target.fieldId;\n};\n\nconst extractInvalidField = (model: CmsModel, err: GraphQLError) => {\n const sdl = err.source?.body || \"\";\n\n /**\n * Find the invalid type\n */\n const { line: lineNumber } = err.locations\n ? err.locations[0]\n : {\n line: 0\n };\n const sdlLines = sdl.split(\"\\n\");\n let sdlLine;\n let gqlType;\n for (let i = lineNumber; i > 0; i--) {\n if (sdlLine && sdlLine.includes(\"type \")) {\n gqlType = sdlLine.match(/type\\s+(.*?)\\s+{/);\n break;\n }\n\n sdlLine = sdlLines[i];\n }\n\n let invalidField: string | undefined = undefined;\n if (Array.isArray(gqlType)) {\n const fieldRegex = new RegExp(`([^\\\\s+].*?):\\\\s+\\\\[?${gqlType[1]}!?\\\\]?`);\n\n const matched = sdl.match(fieldRegex);\n if (matched) {\n invalidField = matched[1];\n }\n }\n\n let message = `See more details in the browser console.`;\n if (invalidField) {\n message = `Please review the definition of \"${invalidField}\" field.`;\n }\n\n return {\n data: {\n modelId: model.modelId,\n sdl,\n invalidField\n },\n code: \"INVALID_MODEL_DEFINITION\",\n message: [`Model \"${model.modelId}\" was not saved!`, message].join(\"\\n\")\n };\n};\n\ninterface ValidateFieldsParams {\n plugins: CmsModelFieldToGraphQLPlugin[];\n fields: CmsModelField[];\n originalFields: CmsModelField[];\n lockedFields: LockedField[];\n}\nconst validateFields = (params: ValidateFieldsParams) => {\n const { plugins, fields, originalFields, lockedFields } = params;\n\n const fieldIdList: string[] = [];\n\n const storageIdList: string[] = [];\n\n for (const field of fields) {\n const plugin = plugins.find(item => item.fieldType === field.type);\n if (!plugin) {\n throw new Error(\n `Cannot update content model because of the unknown \"${field.type}\" field.`\n );\n }\n const originalField = originalFields.find(f => f.id === field.id);\n /**\n * Field MUST have an fieldId defined.\n */\n if (!field.fieldId) {\n throw new WebinyError(`Field does not have an \"fieldId\" defined.`, \"MISSING_FIELD_ID\", {\n field\n });\n }\n /**\n * If storageId does not match a certain pattern, add that pattern, but only if field is not locked (used) already.\n * This is to avoid errors in the already installed systems.\n *\n * Why are we using the @?\n *\n * It is not part of special characters for the query syntax in the Lucene.\n *\n * Relevant links:\n * https://lucene.apache.org/core/3_4_0/queryparsersyntax.html\n * https://discuss.elastic.co/t/special-characters-in-field-names/10658/3\n * https://discuss.elastic.co/t/illegal-characters-in-elasticsearch-field-names/17196/2\n */\n const isLocked = lockedFields.some(lockedField => {\n return lockedField.fieldId === field.storageId;\n });\n if (!field.storageId) {\n /**\n * In case field is locked, we must set the storageId to the fieldId value.\n * This should not happen, because we upgrade all the fields in 5.33.0, but let's have a check just in case of some upgrade miss.\n */\n //\n if (isLocked) {\n field.storageId = field.fieldId;\n }\n /**\n * When having original field, just set the storageId to value from the originalField\n */\n //\n else if (originalField) {\n field.storageId = originalField.storageId;\n }\n /**\n * The last case is when no original field and not locked - so this is a completely new field.\n */\n //\n else {\n field.storageId = createFieldStorageId(field);\n }\n }\n /**\n * Check the field's fieldId against existing ones.\n * There cannot be two fields with the same fieldId - outside world identifier.\n */\n if (fieldIdList.includes(field.fieldId)) {\n throw new WebinyError(\n `Cannot update content model because field \"${field.storageId}\" has fieldId \"${field.fieldId}\", which is already used.`\n );\n }\n fieldIdList.push(field.fieldId);\n /**\n * Check the field's storageId against the existing ones.\n * There cannot be two fields with the same storageId.\n */\n if (storageIdList.includes(field.storageId)) {\n throw new WebinyError(\n `Cannot update content model because field \"${field.label}\" has storageId \"${field.storageId}\", which is already used.`\n );\n }\n storageIdList.push(field.storageId);\n /**\n * TODO maybe make this part pluginable?\n * We need to check the object field child fields.\n * It must be recursive.\n */\n if (field.type !== \"object\") {\n continue;\n }\n const childFields = field.settings?.fields || [];\n const originalChildFields = originalField?.settings?.fields || [];\n /**\n * No point in going further if there are no child fields.\n * Code will break if child fields were removed but used in the entries.\n */\n if (childFields.length === 0) {\n continue;\n }\n validateFields({\n fields: childFields,\n originalFields: originalChildFields,\n plugins,\n lockedFields: []\n });\n }\n};\n\ninterface ValidateModelFieldsParams {\n model: CmsModel;\n original?: CmsModel;\n plugins: PluginsContainer;\n}\nexport const validateModelFields = (params: ValidateModelFieldsParams) => {\n const { model, original, plugins } = params;\n const { titleFieldId } = model;\n\n /**\n * There should be fields/locked fields in either model or data to be updated.\n */\n const { fields = [], lockedFields = [] } = model;\n\n /**\n * Let's inspect the fields of the received content model. We prevent saving of a content model if it\n * contains a field for which a \"cms-model-field-to-graphql\" plugin does not exist on the backend.\n */\n const fieldTypePlugins = plugins.byType<CmsModelFieldToGraphQLPlugin>(\n \"cms-model-field-to-graphql\"\n );\n\n validateFields({\n fields,\n originalFields: original?.fields || [],\n lockedFields,\n plugins: fieldTypePlugins\n });\n\n if (fields.length) {\n /**\n * Make sure that this model can be safely converted to a GraphQL SDL\n */\n const schema = createManageSDL({\n model,\n fieldTypePlugins: fieldTypePlugins.reduce(\n (acc, pl) => ({ ...acc, [pl.fieldType]: pl }),\n {}\n )\n });\n\n try {\n gql(schema);\n } catch (err) {\n throw new WebinyError(extractInvalidField(model, err));\n }\n }\n\n model.titleFieldId = getContentModelTitleFieldId(fields, titleFieldId);\n\n const cmsLockedFieldPlugins =\n plugins.byType<CmsModelLockedFieldPlugin>(\"cms-model-locked-field\");\n\n /**\n * We must not allow removal or changes in fields that are already in use in content entries.\n * Locked fields still have fieldId (should be storageId) because of the old existing locked fields in the models.\n */\n for (const lockedField of lockedFields) {\n const existingField = fields.find(item => item.storageId === lockedField.fieldId);\n\n /**\n * Starting with 5.33.0 fields can be deleted.\n * Our UI gives a warning upon locked field deletion, but if user is managing fields through API directly - we cannot do anything.\n */\n if (!existingField) {\n continue;\n // throw new WebinyError(\n // `Cannot remove the field \"${lockedField.fieldId}\" because it's already in use in created content.`,\n // \"ENTRY_FIELD_USED\",\n // {\n // lockedField,\n // fields\n // }\n // );\n }\n\n if (lockedField.multipleValues !== existingField.multipleValues) {\n throw new WebinyError(\n `Cannot change \"multipleValues\" for the \"${lockedField.fieldId}\" field because it's already in use in created content.`,\n \"ENTRY_FIELD_USED\",\n {\n field: existingField\n }\n );\n }\n\n if (lockedField.type !== existingField.type) {\n throw new WebinyError(\n `Cannot change field type for the \"${lockedField.fieldId}\" field because it's already in use in created content.`,\n \"ENTRY_FIELD_USED\",\n {\n field: existingField\n }\n );\n }\n\n /**\n * Check `lockedField` invariant for specific field\n */\n const lockedFieldsByType = cmsLockedFieldPlugins.filter(\n pl => pl.fieldType === lockedField.type\n );\n for (const plugin of lockedFieldsByType) {\n if (typeof plugin.checkLockedField !== \"function\") {\n continue;\n }\n plugin.checkLockedField({\n lockedField,\n field: existingField\n });\n }\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"names":["defaultTitleFieldId","allowedTitleFieldTypes","getContentModelTitleFieldId","fields","titleFieldId","length","titleField","find","field","getBaseFieldType","multipleValues","fieldId","target","f","WebinyError","includes","type","join","storageId","extractInvalidField","model","err","sdl","source","body","line","lineNumber","locations","sdlLines","split","sdlLine","gqlType","i","match","invalidField","undefined","Array","isArray","fieldRegex","RegExp","matched","message","data","modelId","code","createValidateChildFields","plugins","originalFields","validateFields","lockedFields","params","idList","fieldIdList","storageIdList","baseType","plugin","fieldType","Error","id","push","originalField","isLocked","some","lockedField","createFieldStorageId","label","validateChildFields","validate","createGraphQLSchema","context","modelPlugins","buildSchemaPlugins","models","byType","GraphQLSchemaPlugin","createExecutableSchema","extractErrorObject","error","reduce","output","key","validateModelFields","original","fieldTypePlugins","sorterPlugins","CmsGraphQLSchemaSorterPlugin","schema","createManageSDL","acc","pl","gql","cmsLockedFieldPlugins","existingField","item","reason","lockedFieldType","existingFieldType","lockedFieldsByType","filter","checkLockedField"],"sources":["validateModelFields.ts"],"sourcesContent":["import {\n CmsContext,\n CmsModel,\n CmsModelField,\n CmsModelFieldToGraphQLPlugin,\n CmsModelFieldToGraphQLPluginValidateChildFieldsValidate,\n CmsModelLockedFieldPlugin,\n LockedField\n} from \"~/types\";\nimport WebinyError from \"@webiny/error\";\nimport { createManageSDL } from \"~/graphql/schema/createManageSDL\";\nimport gql from \"graphql-tag\";\nimport { createFieldStorageId } from \"./createFieldStorageId\";\nimport { GraphQLError } from \"graphql\";\nimport { getBaseFieldType } from \"~/utils/getBaseFieldType\";\nimport { CmsGraphQLSchemaSorterPlugin } from \"~/plugins\";\nimport { buildSchemaPlugins } from \"~/graphql/buildSchemaPlugins\";\nimport { createExecutableSchema } from \"~/graphql/createExecutableSchema\";\nimport { GraphQLSchemaPlugin } from \"@webiny/handler-graphql\";\n\nconst defaultTitleFieldId = \"id\";\n\nconst allowedTitleFieldTypes = [\"text\", \"number\"];\n\nconst getContentModelTitleFieldId = (fields: CmsModelField[], titleFieldId?: string): string => {\n /**\n * If there are no fields defined, we will return the default field\n */\n if (fields.length === 0) {\n return defaultTitleFieldId;\n }\n /**\n * if there is no title field defined either in input data or existing content model data\n * we will take first text field that has no multiple values enabled\n * or if initial titleFieldId is the default one also try to find first available text field\n */\n if (!titleFieldId || titleFieldId === defaultTitleFieldId) {\n const titleField = fields.find(field => {\n return getBaseFieldType(field) === \"text\" && !field.multipleValues;\n });\n return titleField?.fieldId || defaultTitleFieldId;\n }\n /**\n * check existing titleFieldId for existence in the model\n * for correct type\n * and that it is not multiple values field\n */\n const target = fields.find(f => f.fieldId === titleFieldId);\n if (!target) {\n throw new WebinyError(\n `Field selected for the title field does not exist in the model.`,\n \"VALIDATION_ERROR\",\n {\n fieldId: titleFieldId,\n fields\n }\n );\n }\n\n if (allowedTitleFieldTypes.includes(target.type) === false) {\n throw new WebinyError(\n `Only ${allowedTitleFieldTypes.join(\n \", \"\n )} and id fields can be used as an entry title.`,\n \"ENTRY_TITLE_FIELD_TYPE\",\n {\n storageId: target.storageId,\n fieldId: target.fieldId,\n type: target.type\n }\n );\n }\n\n if (target.multipleValues) {\n throw new WebinyError(\n `Fields that accept multiple values cannot be used as the entry title.`,\n \"ENTRY_TITLE_FIELD_TYPE\",\n {\n storageId: target.storageId,\n fieldId: target.fieldId,\n type: target.type\n }\n );\n }\n\n return target.fieldId;\n};\n\nconst extractInvalidField = (model: CmsModel, err: GraphQLError) => {\n const sdl = err.source?.body || \"\";\n\n /**\n * Find the invalid type\n */\n const { line: lineNumber } = err.locations\n ? err.locations[0]\n : {\n line: 0\n };\n const sdlLines = sdl.split(\"\\n\");\n let sdlLine;\n let gqlType;\n for (let i = lineNumber; i > 0; i--) {\n if (sdlLine && sdlLine.includes(\"type \")) {\n gqlType = sdlLine.match(/type\\s+(.*?)\\s+{/);\n break;\n }\n\n sdlLine = sdlLines[i];\n }\n\n let invalidField: string | undefined = undefined;\n if (Array.isArray(gqlType)) {\n const fieldRegex = new RegExp(`([^\\\\s+].*?):\\\\s+\\\\[?${gqlType[1]}!?\\\\]?`);\n\n const matched = sdl.match(fieldRegex);\n if (matched) {\n invalidField = matched[1];\n }\n }\n\n let message = `See more details in the browser console.`;\n if (invalidField) {\n message = `Please review the definition of \"${invalidField}\" field.`;\n }\n\n return {\n data: {\n modelId: model.modelId,\n sdl,\n invalidField\n },\n code: \"INVALID_MODEL_DEFINITION\",\n message: [`Model \"${model.modelId}\" was not saved!`, message].join(\"\\n\")\n };\n};\n\nconst createValidateChildFields = (\n plugins: CmsModelFieldToGraphQLPlugin[]\n): CmsModelFieldToGraphQLPluginValidateChildFieldsValidate => {\n return ({ fields, originalFields }) => {\n if (fields.length === 0 && originalFields.length === 0) {\n return;\n }\n validateFields({\n fields,\n originalFields,\n plugins,\n lockedFields: []\n });\n };\n};\n\ninterface ValidateFieldsParams {\n plugins: CmsModelFieldToGraphQLPlugin[];\n fields: CmsModelField[];\n originalFields: CmsModelField[];\n lockedFields: LockedField[];\n}\nconst validateFields = (params: ValidateFieldsParams) => {\n const { plugins, fields, originalFields, lockedFields } = params;\n\n const idList: string[] = [];\n const fieldIdList: string[] = [];\n const storageIdList: string[] = [];\n\n for (const field of fields) {\n const baseType = getBaseFieldType(field);\n const plugin = plugins.find(plugin => plugin.fieldType === baseType);\n\n if (!plugin) {\n throw new Error(\n `Cannot update content model because of the unknown \"${baseType}\" field.`\n );\n }\n /**\n * Check the field's id against existing ones.\n * There cannot be two fields with the same id.\n */\n if (idList.includes(field.id)) {\n throw new WebinyError(\n `Cannot update content model because field \"${\n field.storageId || field.fieldId\n }\" has id \"${field.id}\", which is already used.`\n );\n }\n idList.push(field.id);\n\n const originalField = originalFields.find(f => f.id === field.id);\n /**\n * Field MUST have an fieldId defined.\n */\n if (!field.fieldId) {\n throw new WebinyError(`Field does not have an \"fieldId\" defined.`, \"MISSING_FIELD_ID\", {\n field\n });\n }\n /**\n * If storageId does not match a certain pattern, add that pattern, but only if field is not locked (used) already.\n * This is to avoid errors in the already installed systems.\n *\n * Why are we using the @?\n *\n * It is not part of special characters for the query syntax in the Lucene.\n *\n * Relevant links:\n * https://lucene.apache.org/core/3_4_0/queryparsersyntax.html\n * https://discuss.elastic.co/t/special-characters-in-field-names/10658/3\n * https://discuss.elastic.co/t/illegal-characters-in-elasticsearch-field-names/17196/2\n */\n const isLocked = lockedFields.some(lockedField => {\n return lockedField.fieldId === field.storageId || lockedField.fieldId === field.fieldId;\n });\n if (!field.storageId) {\n /**\n * In case field is locked, we must set the storageId to the fieldId value.\n * This should not happen, because we upgrade all the fields in 5.33.0, but let's have a check just in case of some upgrade miss.\n */\n //\n if (isLocked) {\n field.storageId = field.fieldId;\n }\n /**\n * When having original field, just set the storageId to value from the originalField\n */\n //\n else if (originalField) {\n field.storageId = originalField.storageId;\n }\n /**\n * The last case is when no original field and not locked - so this is a completely new field.\n */\n //\n else {\n field.storageId = createFieldStorageId(field);\n }\n }\n /**\n * Check the field's fieldId against existing ones.\n * There cannot be two fields with the same fieldId - outside world identifier.\n */\n if (fieldIdList.includes(field.fieldId)) {\n throw new WebinyError(\n `Cannot update content model because field \"${field.storageId}\" has fieldId \"${field.fieldId}\", which is already used.`\n );\n }\n fieldIdList.push(field.fieldId);\n /**\n * Check the field's storageId against the existing ones.\n * There cannot be two fields with the same storageId.\n */\n if (storageIdList.includes(field.storageId)) {\n throw new WebinyError(\n `Cannot update content model because field \"${field.label}\" has storageId \"${field.storageId}\", which is already used.`\n );\n }\n storageIdList.push(field.storageId);\n /**\n * There might be some plugins which allow child fields.\n * We use this method to validate them as well.\n */\n if (!plugin.validateChildFields) {\n continue;\n }\n const validateChildFields = createValidateChildFields(plugins);\n plugin.validateChildFields({\n field,\n originalField,\n validate: validateChildFields\n });\n }\n};\ninterface CreateGraphQLSchemaParams {\n context: CmsContext;\n model: CmsModel;\n}\nconst createGraphQLSchema = async (params: CreateGraphQLSchemaParams): Promise<any> => {\n const { context, model } = params;\n\n const modelPlugins = await buildSchemaPlugins({\n context,\n models: [model]\n });\n\n const plugins = context.plugins.byType<GraphQLSchemaPlugin<CmsContext>>(\n GraphQLSchemaPlugin.type\n );\n plugins.push(...modelPlugins);\n\n return createExecutableSchema({\n plugins\n });\n};\n\nconst extractErrorObject = (error: any) => {\n return [\"message\", \"code\", \"data\", \"stack\"].reduce<Record<string, any>>((output, key) => {\n if (!error[key]) {\n return output;\n }\n output[key] = error[key];\n return output;\n }, {});\n};\n\ninterface ValidateModelFieldsParams {\n model: CmsModel;\n original?: CmsModel;\n context: CmsContext;\n}\nexport const validateModelFields = async (params: ValidateModelFieldsParams): Promise<void> => {\n const { model, original, context } = params;\n const { titleFieldId } = model;\n const { plugins } = context;\n\n /**\n * There should be fields/locked fields in either model or data to be updated.\n */\n const { fields = [], lockedFields = [] } = model;\n\n /**\n * Let's inspect the fields of the received content model. We prevent saving of a content model if it\n * contains a field for which a \"cms-model-field-to-graphql\" plugin does not exist on the backend.\n */\n const fieldTypePlugins = plugins.byType<CmsModelFieldToGraphQLPlugin>(\n \"cms-model-field-to-graphql\"\n );\n\n validateFields({\n fields,\n originalFields: original?.fields || [],\n lockedFields,\n plugins: fieldTypePlugins\n });\n\n if (fields.length) {\n const sorterPlugins = plugins.byType<CmsGraphQLSchemaSorterPlugin>(\n CmsGraphQLSchemaSorterPlugin.type\n );\n /**\n * Make sure that this model can be safely converted to a GraphQL SDL\n */\n const schema = createManageSDL({\n model,\n fieldTypePlugins: fieldTypePlugins.reduce(\n (acc, pl) => ({ ...acc, [pl.fieldType]: pl }),\n {}\n ),\n sorterPlugins\n });\n\n try {\n gql(schema);\n } catch (err) {\n throw new WebinyError(extractInvalidField(model, err));\n }\n /**\n *\n */\n try {\n await createGraphQLSchema({\n context,\n model\n });\n } catch (err) {\n throw new WebinyError({\n message:\n \"Cannot generate GraphQL schema when testing with the given model. Please check the response for more details.\",\n code: \"GRAPHQL_SCHEMA_ERROR\",\n data: {\n modelId: model.modelId,\n error: extractErrorObject(err)\n }\n });\n }\n }\n\n model.titleFieldId = getContentModelTitleFieldId(fields, titleFieldId);\n\n const cmsLockedFieldPlugins =\n plugins.byType<CmsModelLockedFieldPlugin>(\"cms-model-locked-field\");\n\n /**\n * We must not allow removal or changes in fields that are already in use in content entries.\n * Locked fields still have fieldId (should be storageId) because of the old existing locked fields in the models.\n */\n for (const lockedField of lockedFields) {\n const existingField = fields.find(item => item.storageId === lockedField.fieldId);\n\n /**\n * Starting with 5.33.0 fields can be deleted.\n * Our UI gives a warning upon locked field deletion, but if user is managing fields through API directly - we cannot do anything.\n */\n if (!existingField) {\n continue;\n }\n\n if (lockedField.multipleValues !== existingField.multipleValues) {\n throw new WebinyError(\n `Cannot change \"multipleValues\" for the \"${lockedField.fieldId}\" field because it's already in use in created content.`,\n \"ENTRY_FIELD_USED\",\n {\n reason: `\"multipleValues\" changed`,\n field: existingField\n }\n );\n }\n\n const fieldType = getBaseFieldType(existingField);\n if (lockedField.type !== fieldType) {\n throw new WebinyError(\n `Cannot change field type for the \"${lockedField.fieldId}\" field because it's already in use in created content.`,\n \"ENTRY_FIELD_USED\",\n {\n reason: `\"type\" changed`,\n lockedFieldType: lockedField.type,\n existingFieldType: fieldType\n }\n );\n }\n\n /**\n * Check `lockedField` invariant for specific field\n */\n const lockedFieldsByType = cmsLockedFieldPlugins.filter(\n pl => pl.fieldType === getBaseFieldType(lockedField)\n );\n for (const plugin of lockedFieldsByType) {\n if (typeof plugin.checkLockedField !== \"function\") {\n continue;\n }\n plugin.checkLockedField({\n lockedField,\n field: existingField\n });\n }\n }\n};\n"],"mappings":"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"}