@webiny/api-headless-cms 5.24.0 → 5.25.0-beta.2

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 (187) hide show
  1. package/content/contextSetup.js.map +1 -0
  2. package/content/graphQLHandlerFactory.js +4 -0
  3. package/content/graphQLHandlerFactory.js.map +1 -0
  4. package/content/parameterPlugins.js.map +1 -0
  5. package/content/plugins/CmsGroupPlugin.js.map +1 -0
  6. package/content/plugins/CmsModelPlugin.js.map +1 -0
  7. package/content/plugins/CmsParametersPlugin.d.ts +1 -1
  8. package/content/plugins/CmsParametersPlugin.js.map +1 -0
  9. package/content/plugins/buildSchemaPlugins.js.map +1 -0
  10. package/content/plugins/crud/contentEntry/afterDelete.js +2 -1
  11. package/content/plugins/crud/contentEntry/afterDelete.js.map +1 -0
  12. package/content/plugins/crud/contentEntry/beforeCreate.js.map +1 -0
  13. package/content/plugins/crud/contentEntry/beforeUpdate.js.map +1 -0
  14. package/content/plugins/crud/contentEntry/entryDataValidation.d.ts +2 -2
  15. package/content/plugins/crud/contentEntry/entryDataValidation.js +2 -3
  16. package/content/plugins/crud/contentEntry/entryDataValidation.js.map +1 -0
  17. package/content/plugins/crud/contentEntry/markLockedFields.js +1 -1
  18. package/content/plugins/crud/contentEntry/markLockedFields.js.map +1 -0
  19. package/content/plugins/crud/contentEntry/referenceFieldsMapping.js +7 -3
  20. package/content/plugins/crud/contentEntry/referenceFieldsMapping.js.map +1 -0
  21. package/content/plugins/crud/contentEntry.crud.d.ts +2 -2
  22. package/content/plugins/crud/contentEntry.crud.js +24 -13
  23. package/content/plugins/crud/contentEntry.crud.js.map +1 -0
  24. package/content/plugins/crud/contentModel/afterCreate.js.map +1 -0
  25. package/content/plugins/crud/contentModel/afterDelete.js.map +1 -0
  26. package/content/plugins/crud/contentModel/afterUpdate.js.map +1 -0
  27. package/content/plugins/crud/contentModel/beforeCreate.d.ts +2 -2
  28. package/content/plugins/crud/contentModel/beforeCreate.js +1 -1
  29. package/content/plugins/crud/contentModel/beforeCreate.js.map +1 -0
  30. package/content/plugins/crud/contentModel/beforeDelete.js.map +1 -0
  31. package/content/plugins/crud/contentModel/beforeUpdate.js +12 -4
  32. package/content/plugins/crud/contentModel/beforeUpdate.js.map +1 -0
  33. package/content/plugins/crud/contentModel/contentModelManagerFactory.js.map +1 -0
  34. package/content/plugins/crud/contentModel/createFieldModels.js.map +1 -0
  35. package/content/plugins/crud/contentModel/idValidation.js.map +1 -0
  36. package/content/plugins/crud/contentModel/models.js.map +1 -0
  37. package/content/plugins/crud/contentModel/validateLayout.js.map +1 -0
  38. package/content/plugins/crud/contentModel.crud.d.ts +2 -2
  39. package/content/plugins/crud/contentModel.crud.js +2 -2
  40. package/content/plugins/crud/contentModel.crud.js.map +1 -0
  41. package/content/plugins/crud/contentModelGroup/beforeCreate.js.map +1 -0
  42. package/content/plugins/crud/contentModelGroup/beforeDelete.js.map +1 -0
  43. package/content/plugins/crud/contentModelGroup/beforeUpdate.js.map +1 -0
  44. package/content/plugins/crud/contentModelGroup.crud.d.ts +2 -2
  45. package/content/plugins/crud/contentModelGroup.crud.js.map +1 -0
  46. package/content/plugins/crud/index.d.ts +2 -2
  47. package/content/plugins/crud/index.js.map +1 -0
  48. package/content/plugins/graphqlFields/boolean.js +2 -6
  49. package/content/plugins/graphqlFields/boolean.js.map +1 -0
  50. package/content/plugins/graphqlFields/datetime.js +2 -2
  51. package/content/plugins/graphqlFields/datetime.js.map +1 -0
  52. package/content/plugins/graphqlFields/file.js +2 -6
  53. package/content/plugins/graphqlFields/file.js.map +1 -0
  54. package/content/plugins/graphqlFields/helpers.d.ts +6 -0
  55. package/content/plugins/graphqlFields/helpers.js +49 -0
  56. package/content/plugins/graphqlFields/helpers.js.map +1 -0
  57. package/content/plugins/graphqlFields/index.js.map +1 -0
  58. package/content/plugins/graphqlFields/longText.js +2 -6
  59. package/content/plugins/graphqlFields/longText.js.map +1 -0
  60. package/content/plugins/graphqlFields/number.js +2 -6
  61. package/content/plugins/graphqlFields/number.js.map +1 -0
  62. package/content/plugins/graphqlFields/object.js +11 -5
  63. package/content/plugins/graphqlFields/object.js.map +1 -0
  64. package/content/plugins/graphqlFields/ref.js +26 -13
  65. package/content/plugins/graphqlFields/ref.js.map +1 -0
  66. package/content/plugins/graphqlFields/richText.js +2 -6
  67. package/content/plugins/graphqlFields/richText.js.map +1 -0
  68. package/content/plugins/graphqlFields/text.js +2 -6
  69. package/content/plugins/graphqlFields/text.js.map +1 -0
  70. package/content/plugins/internalSecurity/InternalAuthenticationPlugin.js.map +1 -0
  71. package/content/plugins/internalSecurity/InternalAuthorizationPlugin.js.map +1 -0
  72. package/content/plugins/modelManager/DefaultCmsModelManager.js.map +1 -0
  73. package/content/plugins/modelManager/index.js.map +1 -0
  74. package/content/plugins/schema/baseSchema.js +1 -0
  75. package/content/plugins/schema/baseSchema.js.map +1 -0
  76. package/content/plugins/schema/contentEntries.js +12 -5
  77. package/content/plugins/schema/contentEntries.js.map +1 -0
  78. package/content/plugins/schema/contentModelGroups.js +1 -2
  79. package/content/plugins/schema/contentModelGroups.js.map +1 -0
  80. package/content/plugins/schema/contentModels.js +2 -3
  81. package/content/plugins/schema/contentModels.js.map +1 -0
  82. package/content/plugins/schema/createFieldResolvers.js.map +1 -0
  83. package/content/plugins/schema/createManageResolvers.js.map +1 -0
  84. package/content/plugins/schema/createManageSDL.js.map +1 -0
  85. package/content/plugins/schema/createPreviewResolvers.js.map +1 -0
  86. package/content/plugins/schema/createReadResolvers.js.map +1 -0
  87. package/content/plugins/schema/createReadSDL.js.map +1 -0
  88. package/content/plugins/schema/resolvers/commonFieldResolvers.d.ts +1 -1
  89. package/content/plugins/schema/resolvers/commonFieldResolvers.js.map +1 -0
  90. package/content/plugins/schema/resolvers/manage/resolveCreate.js.map +1 -0
  91. package/content/plugins/schema/resolvers/manage/resolveCreateFrom.js.map +1 -0
  92. package/content/plugins/schema/resolvers/manage/resolveDelete.js.map +1 -0
  93. package/content/plugins/schema/resolvers/manage/resolveGet.js.map +1 -0
  94. package/content/plugins/schema/resolvers/manage/resolveGetByIds.js.map +1 -0
  95. package/content/plugins/schema/resolvers/manage/resolveGetRevisions.js.map +1 -0
  96. package/content/plugins/schema/resolvers/manage/resolveList.js.map +1 -0
  97. package/content/plugins/schema/resolvers/manage/resolvePublish.js.map +1 -0
  98. package/content/plugins/schema/resolvers/manage/resolveRepublish.js.map +1 -0
  99. package/content/plugins/schema/resolvers/manage/resolveRequestChanges.js.map +1 -0
  100. package/content/plugins/schema/resolvers/manage/resolveRequestReview.js.map +1 -0
  101. package/content/plugins/schema/resolvers/manage/resolveUnpublish.js.map +1 -0
  102. package/content/plugins/schema/resolvers/manage/resolveUpdate.js.map +1 -0
  103. package/content/plugins/schema/resolvers/preview/resolveGet.js.map +1 -0
  104. package/content/plugins/schema/resolvers/preview/resolveList.js.map +1 -0
  105. package/content/plugins/schema/resolvers/read/resolveGet.js.map +1 -0
  106. package/content/plugins/schema/resolvers/read/resolveList.js.map +1 -0
  107. package/content/plugins/schema/schemaPlugins.js.map +1 -0
  108. package/content/plugins/storage/StorageTransformPlugin.js.map +1 -0
  109. package/content/plugins/storage/default.js.map +1 -0
  110. package/content/plugins/storage/object.js +6 -2
  111. package/content/plugins/storage/object.js.map +1 -0
  112. package/content/plugins/utils/createTypeName.js.map +1 -0
  113. package/content/plugins/utils/entryStorage.d.ts +2 -2
  114. package/content/plugins/utils/entryStorage.js +0 -4
  115. package/content/plugins/utils/entryStorage.js.map +1 -0
  116. package/content/plugins/utils/getEntryTitle.js +1 -1
  117. package/content/plugins/utils/getEntryTitle.js.map +1 -0
  118. package/content/plugins/utils/getSchemaFromFieldPlugins.js +8 -3
  119. package/content/plugins/utils/getSchemaFromFieldPlugins.js.map +1 -0
  120. package/content/plugins/utils/pluralizedTypeName.js.map +1 -0
  121. package/content/plugins/utils/renderFields.js.map +1 -0
  122. package/content/plugins/utils/renderGetFilterFields.js +5 -0
  123. package/content/plugins/utils/renderGetFilterFields.js.map +1 -0
  124. package/content/plugins/utils/renderInputFields.d.ts +1 -1
  125. package/content/plugins/utils/renderInputFields.js.map +1 -0
  126. package/content/plugins/utils/renderListFilterFields.js.map +1 -0
  127. package/content/plugins/utils/renderSortEnum.js.map +1 -0
  128. package/content/plugins/validators/dateGte.js +1 -1
  129. package/content/plugins/validators/dateGte.js.map +1 -0
  130. package/content/plugins/validators/dateLte.js +1 -1
  131. package/content/plugins/validators/dateLte.js.map +1 -0
  132. package/content/plugins/validators/gte.js +3 -1
  133. package/content/plugins/validators/gte.js.map +1 -0
  134. package/content/plugins/validators/in.js +3 -1
  135. package/content/plugins/validators/in.js.map +1 -0
  136. package/content/plugins/validators/index.js.map +1 -0
  137. package/content/plugins/validators/lte.js +3 -1
  138. package/content/plugins/validators/lte.js.map +1 -0
  139. package/content/plugins/validators/maxLength.js +3 -1
  140. package/content/plugins/validators/maxLength.js.map +1 -0
  141. package/content/plugins/validators/minLength.js +3 -1
  142. package/content/plugins/validators/minLength.js.map +1 -0
  143. package/content/plugins/validators/pattern.js +2 -2
  144. package/content/plugins/validators/pattern.js.map +1 -0
  145. package/content/plugins/validators/patternPlugins/email.js.map +1 -0
  146. package/content/plugins/validators/patternPlugins/index.js.map +1 -0
  147. package/content/plugins/validators/patternPlugins/lowerCase.js.map +1 -0
  148. package/content/plugins/validators/patternPlugins/lowerCaseSpace.js.map +1 -0
  149. package/content/plugins/validators/patternPlugins/upperCase.js.map +1 -0
  150. package/content/plugins/validators/patternPlugins/upperCaseSpace.js.map +1 -0
  151. package/content/plugins/validators/patternPlugins/url.js.map +1 -0
  152. package/content/plugins/validators/required.js.map +1 -0
  153. package/content/plugins/validators/timeGte.js +3 -1
  154. package/content/plugins/validators/timeGte.js.map +1 -0
  155. package/content/plugins/validators/timeLte.js +3 -1
  156. package/content/plugins/validators/timeLte.js.map +1 -0
  157. package/content/plugins/validators/unique.js +1 -0
  158. package/content/plugins/validators/unique.js.map +1 -0
  159. package/index.d.ts +3 -3
  160. package/index.js.map +1 -0
  161. package/migrateCMSPermissions.js.map +1 -0
  162. package/package.json +26 -26
  163. package/plugins/context.js +8 -3
  164. package/plugins/context.js.map +1 -0
  165. package/plugins/crud/index.d.ts +2 -2
  166. package/plugins/crud/index.js.map +1 -0
  167. package/plugins/crud/settings.crud.d.ts +2 -2
  168. package/plugins/crud/settings.crud.js.map +1 -0
  169. package/plugins/crud/system.crud.d.ts +3 -2
  170. package/plugins/crud/system.crud.js +2 -2
  171. package/plugins/crud/system.crud.js.map +1 -0
  172. package/plugins/graphql/system.d.ts +1 -1
  173. package/plugins/graphql/system.js.map +1 -0
  174. package/plugins/graphql.js +7 -0
  175. package/plugins/graphql.js.map +1 -0
  176. package/plugins/upgrades/index.js.map +1 -0
  177. package/plugins/upgrades/v5.5.0/helpers.js.map +1 -0
  178. package/plugins/upgrades/v5.5.0/index.js +1 -0
  179. package/plugins/upgrades/v5.5.0/index.js.map +1 -0
  180. package/transformers.js.map +1 -0
  181. package/types.d.ts +58 -28
  182. package/types.js +6 -0
  183. package/types.js.map +1 -0
  184. package/utils.d.ts +12 -14
  185. package/utils.js.map +1 -0
  186. package/content/plugins/graphqlFields/requiredField.d.ts +0 -2
  187. package/content/plugins/graphqlFields/requiredField.js +0 -24
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["system.crud.ts"],"names":["initialContentModelGroup","name","slug","description","icon","createSystemCrud","params","getTenant","storageOperations","context","getIdentity","onBeforeInstall","onAfterInstall","createReadAPIKey","crypto","randomBytes","Math","ceil","toString","getVersion","system","get","tenant","id","version","setVersion","original","create","update","onBeforeSystemInstall","onAfterSystemInstall","getSystemVersion","setSystemVersion","getReadAPIKey","readAPIKey","installSystem","identity","NotAuthorizedError","publish","cms","createGroup","ex","WebinyError","message","group","WEBINY_VERSION","upgradeSystem","upgradePlugins","plugins","byType","filter","pl","app","installedAppVersion","plugin","undefined","deployedVersion","upgradeToVersion","code","ErrorCode","UPGRADE_NOT_AVAILABLE","apply"],"mappings":"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","sourcesContent":["import crypto from \"crypto\";\nimport { NotAuthorizedError } from \"@webiny/api-security\";\nimport { ErrorCode, getApplicablePlugin } from \"@webiny/api-upgrade\";\nimport { UpgradePlugin } from \"@webiny/api-upgrade/types\";\nimport WebinyError from \"@webiny/error\";\nimport {\n AfterInstallTopicParams,\n BeforeInstallTopicParams,\n CmsContext,\n CmsSystem,\n CmsSystemContext,\n HeadlessCms,\n HeadlessCmsStorageOperations\n} from \"~/types\";\nimport { Tenant } from \"@webiny/api-tenancy/types\";\nimport { SecurityIdentity } from \"@webiny/api-security/types\";\nimport { createTopic } from \"@webiny/pubsub\";\n\nconst initialContentModelGroup = {\n name: \"Ungrouped\",\n slug: \"ungrouped\",\n description: \"A generic content model group\",\n icon: \"fas/star\"\n};\n\ninterface CreateSystemCrudParams {\n getTenant: () => Tenant;\n storageOperations: HeadlessCmsStorageOperations;\n context: CmsContext;\n getIdentity: () => SecurityIdentity;\n}\nexport const createSystemCrud = (params: CreateSystemCrudParams): CmsSystemContext => {\n const { getTenant, storageOperations, context, getIdentity } = params;\n\n const onBeforeInstall = createTopic<BeforeInstallTopicParams>();\n const onAfterInstall = createTopic<AfterInstallTopicParams>();\n\n const createReadAPIKey = () => {\n return crypto.randomBytes(Math.ceil(48 / 2)).toString(\"hex\");\n };\n\n const getVersion = async () => {\n if (!getTenant()) {\n return null;\n }\n\n const system = await storageOperations.system.get({\n tenant: getTenant().id\n });\n\n return system ? system.version || null : null;\n };\n\n const setVersion = async (version: string) => {\n const original = await storageOperations.system.get({\n tenant: getTenant().id\n });\n const system: CmsSystem = {\n ...(original || {}),\n version,\n tenant: getTenant().id\n };\n if (!original) {\n await storageOperations.system.create({\n system\n });\n return;\n }\n await storageOperations.system.update({\n original,\n system\n });\n };\n\n return {\n onBeforeSystemInstall: onBeforeInstall,\n onAfterSystemInstall: onAfterInstall,\n getSystemVersion: getVersion,\n setSystemVersion: setVersion,\n getReadAPIKey: async () => {\n const original = await storageOperations.system.get({\n tenant: getTenant().id\n });\n\n if (!original) {\n return null;\n }\n\n if (!original.readAPIKey) {\n const readAPIKey = createReadAPIKey();\n const system: CmsSystem = {\n ...original,\n readAPIKey\n };\n await storageOperations.system.update({\n original,\n system\n });\n return readAPIKey;\n }\n\n return original.readAPIKey;\n },\n installSystem: async (): Promise<void> => {\n const identity = getIdentity();\n if (!identity) {\n throw new NotAuthorizedError();\n }\n\n const version = await getVersion();\n if (version) {\n return;\n }\n /**\n * First trigger before install event.\n */\n await onBeforeInstall.publish({\n tenant: getTenant().id\n });\n\n /**\n * Add default content model group.\n */\n try {\n await context.cms.createGroup(initialContentModelGroup);\n } catch (ex) {\n throw new WebinyError(ex.message, \"CMS_INSTALLATION_CONTENT_MODEL_GROUP_ERROR\", {\n group: initialContentModelGroup\n });\n }\n\n const system: CmsSystem = {\n version: context.WEBINY_VERSION,\n readAPIKey: createReadAPIKey(),\n tenant: getTenant().id\n };\n /**\n * We need to create the system data.\n */\n await storageOperations.system.create({\n system\n });\n /**\n * And trigger after install event.\n */\n await onAfterInstall.publish({\n tenant: getTenant().id\n });\n },\n async upgradeSystem(this: HeadlessCms, version) {\n const identity = getIdentity();\n if (!identity) {\n throw new NotAuthorizedError();\n }\n\n const upgradePlugins = context.plugins\n .byType<UpgradePlugin>(\"api-upgrade\")\n .filter(pl => pl.app === \"headless-cms\");\n\n const installedAppVersion = await this.getSystemVersion();\n\n let plugin: UpgradePlugin | undefined = undefined;\n try {\n plugin = getApplicablePlugin({\n deployedVersion: context.WEBINY_VERSION,\n installedAppVersion,\n upgradePlugins,\n upgradeToVersion: version\n });\n } catch (ex) {\n /**\n * We just let the error disappear if is UPGRADE_NOT_AVAILABLE code\n * and rethrow if is not.\n * This is because we want upgrade to pass if there is no plugin available.\n */\n if (ex.code !== ErrorCode.UPGRADE_NOT_AVAILABLE) {\n throw ex;\n }\n }\n\n if (plugin) {\n await plugin.apply(context);\n }\n\n /**\n * Store new app version.\n */\n await setVersion(version);\n\n return true;\n }\n };\n};\n"]}
@@ -7,7 +7,7 @@ declare const _default: {
7
7
  typeDefs: string;
8
8
  resolvers: {
9
9
  CmsQuery: {
10
- version: (_: any, __: any, context: CmsContext) => Promise<string | ErrorResponse>;
10
+ version: (_: any, __: any, context: CmsContext) => Promise<string | ErrorResponse | null>;
11
11
  };
12
12
  CmsMutation: {
13
13
  install: (_: any, __: any, { cms }: CmsContext) => Promise<ErrorResponse | Response<boolean>>;
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["system.ts"],"names":["typeDefs","resolvers","CmsQuery","version","_","__","context","cms","getSystemVersion","e","ErrorResponse","CmsMutation","install","code","message","installSystem","Response","upgrade","args","upgradeSystem"],"mappings":";;;;;;;AAAA;;eAOe;AACXA,EAAAA,QAAQ;AAAE;AAAe;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAde;AAeXC,EAAAA,SAAS,EAAE;AACPC,IAAAA,QAAQ,EAAE;AACNC,MAAAA,OAAO,EAAE,OAAOC,CAAP,EAAeC,EAAf,EAAwBC,OAAxB,KAAgD;AACrD,YAAI;AACA,iBAAOA,OAAO,CAACC,GAAR,CAAYC,gBAAZ,EAAP;AACH,SAFD,CAEE,OAAOC,CAAP,EAAU;AACR,iBAAO,IAAIC,6BAAJ,CAAkBD,CAAlB,CAAP;AACH;AACJ;AAPK,KADH;AAUPE,IAAAA,WAAW,EAAE;AACTC,MAAAA,OAAO,EAAE,OAAOR,CAAP,EAAeC,EAAf,EAAwB;AAAEE,QAAAA;AAAF,OAAxB,KAAgD;AACrD,YAAI;AACA,gBAAMJ,OAAO,GAAG,MAAMI,GAAG,CAACC,gBAAJ,EAAtB;;AACA,cAAIL,OAAJ,EAAa;AACT,mBAAO,IAAIO,6BAAJ,CAAkB;AACrBG,cAAAA,IAAI,EAAE,wBADe;AAErBC,cAAAA,OAAO,EAAE;AAFY,aAAlB,CAAP;AAIH;;AAED,gBAAMP,GAAG,CAACQ,aAAJ,EAAN;AACA,iBAAO,IAAIC,wBAAJ,CAAa,IAAb,CAAP;AACH,SAXD,CAWE,OAAOP,CAAP,EAAU;AACR,iBAAO,IAAIC,6BAAJ,CAAkBD,CAAlB,CAAP;AACH;AACJ,OAhBQ;AAiBTQ,MAAAA,OAAO,EAAE,OAAOb,CAAP,EAAec,IAAf,EAA6C;AAAEX,QAAAA;AAAF,OAA7C,KAAqE;AAC1E,cAAM;AAAEJ,UAAAA;AAAF,YAAce,IAApB;;AACA,YAAI;AACA,gBAAMX,GAAG,CAACY,aAAJ,CAAkBhB,OAAlB,CAAN;AACA,iBAAO,IAAIa,wBAAJ,CAAa,IAAb,CAAP;AACH,SAHD,CAGE,OAAOP,CAAP,EAAU;AACR,iBAAO,IAAIC,6BAAJ,CAAkBD,CAAlB,CAAP;AACH;AACJ;AAzBQ;AAVN;AAfA,C","sourcesContent":["import { ErrorResponse, Response } from \"@webiny/handler-graphql\";\nimport { CmsContext } from \"~/types\";\n\ninterface CmsMutationUpgradeArgs {\n version: string;\n}\n\nexport default {\n typeDefs: /* GraphQL */ `\n extend type CmsQuery {\n # Get installed version\n version: String\n }\n\n extend type CmsMutation {\n # Install CMS\n install: CmsBooleanResponse\n\n # Upgrade CMS\n upgrade(version: String!): CmsBooleanResponse\n }\n `,\n resolvers: {\n CmsQuery: {\n version: async (_: any, __: any, context: CmsContext) => {\n try {\n return context.cms.getSystemVersion();\n } catch (e) {\n return new ErrorResponse(e);\n }\n }\n },\n CmsMutation: {\n install: async (_: any, __: any, { cms }: CmsContext) => {\n try {\n const version = await cms.getSystemVersion();\n if (version) {\n return new ErrorResponse({\n code: \"CMS_INSTALLATION_ERROR\",\n message: \"CMS is already installed.\"\n });\n }\n\n await cms.installSystem();\n return new Response(true);\n } catch (e) {\n return new ErrorResponse(e);\n }\n },\n upgrade: async (_: any, args: CmsMutationUpgradeArgs, { cms }: CmsContext) => {\n const { version } = args;\n try {\n await cms.upgradeSystem(version);\n return new Response(true);\n } catch (e) {\n return new ErrorResponse(e);\n }\n }\n }\n }\n};\n"]}
@@ -24,6 +24,7 @@ const createGraphQLPlugin = () => ({
24
24
  code: String
25
25
  message: String
26
26
  data: JSON
27
+ stack: String
27
28
  }
28
29
 
29
30
  type CmsCursors {
@@ -65,6 +66,12 @@ const createGraphQLPlugin = () => ({
65
66
 
66
67
  ${_system.default.typeDefs}
67
68
  `,
69
+
70
+ /**
71
+ * TS is complaining about emptyResolver not receiving any arguments.
72
+ * It is not required, so ignore.
73
+ */
74
+ // @ts-ignore
68
75
  resolvers: (0, _merge.default)({
69
76
  Query: {
70
77
  cms: emptyResolver
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["graphql.ts"],"names":["emptyResolver","createGraphQLPlugin","name","type","schema","typeDefs","system","resolvers","Query","cms","Mutation"],"mappings":";;;;;;;;;AACA;;AACA;;AAEA,MAAMA,aAAa,GAAG,OAAO,EAAP,CAAtB;;AAEO,MAAMC,mBAAmB,GAAG,OAA4B;AAC3DC,EAAAA,IAAI,EAAE,yBADqD;AAE3DC,EAAAA,IAAI,EAAE,gBAFqD;AAG3DC,EAAAA,MAAM,EAAE;AACJC,IAAAA,QAAQ;AAAE;AAAe;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAcC,gBAAOD,QAAS;AAC9B,SA/CY;;AAgDJ;AACR;AACA;AACA;AACQ;AACAE,IAAAA,SAAS,EAAE,oBACP;AACIC,MAAAA,KAAK,EAAE;AACHC,QAAAA,GAAG,EAAET;AADF,OADX;AAIIU,MAAAA,QAAQ,EAAE;AACND,QAAAA,GAAG,EAAET;AADC;AAJd,KADO,EASPM,gBAAOC,SATA;AArDP;AAHmD,CAA5B,CAA5B","sourcesContent":["import { GraphQLSchemaPlugin } from \"@webiny/handler-graphql/types\";\nimport merge from \"lodash/merge\";\nimport system from \"./graphql/system\";\n\nconst emptyResolver = () => ({});\n\nexport const createGraphQLPlugin = (): GraphQLSchemaPlugin => ({\n name: \"graphql-schema-headless\",\n type: \"graphql-schema\",\n schema: {\n typeDefs: /* GraphQL */ `\n type CmsError {\n code: String\n message: String\n data: JSON\n stack: String\n }\n\n type CmsCursors {\n next: String\n previous: String\n }\n\n type CmsListMeta {\n cursor: String\n hasMoreItems: Boolean\n totalCount: Int\n }\n\n type CmsDeleteResponse {\n data: Boolean\n error: CmsError\n }\n\n type CmsBooleanResponse {\n data: Boolean\n error: CmsError\n }\n\n extend type Query {\n cms: CmsQuery\n }\n\n extend type Mutation {\n cms: CmsMutation\n }\n\n type CmsQuery {\n _empty: String\n }\n\n type CmsMutation {\n _empty: String\n }\n\n ${system.typeDefs}\n `,\n /**\n * TS is complaining about emptyResolver not receiving any arguments.\n * It is not required, so ignore.\n */\n // @ts-ignore\n resolvers: merge(\n {\n Query: {\n cms: emptyResolver\n },\n Mutation: {\n cms: emptyResolver\n }\n },\n system.resolvers\n )\n }\n});\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["index.ts"],"names":["upgrade550"],"mappings":";;;;;;;;;AAAA;;eAEe,MAAM,CAACA,UAAD,C","sourcesContent":["import upgrade550 from \"./v5.5.0\";\n\nexport default () => [upgrade550];\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["helpers.ts"],"names":["isCmsContentPermission","permission","name","includes"],"mappings":";;;;;;;AAEO,MAAMA,sBAAsB,GAAIC,UAAD,IAClCA,UAAU,CAACC,IAAX,CAAgBC,QAAhB,CAAyB,MAAzB,KAAoC,CAACF,UAAU,CAACC,IAAX,CAAgBC,QAAhB,CAAyB,eAAzB,CADlC","sourcesContent":["type BasicPermission = { name: string; [key: string]: any };\n\nexport const isCmsContentPermission = (permission: BasicPermission) =>\n permission.name.includes(\"cms.\") && !permission.name.includes(\"cms.endpoint.\");\n"]}
@@ -123,6 +123,7 @@ const plugin = {
123
123
 
124
124
  console.log("Finish CMS permissions migration for API keys.");
125
125
  } catch (e) {
126
+ console.log("Upgrade v5.5.0");
126
127
  console.log(e);
127
128
  throw new _error.default("[API keys] CMS permissions migration failed!");
128
129
  }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["index.ts"],"names":["plugin","name","type","app","version","apply","context","console","log","security","tenancy","cms","tenant","getCurrentTenant","securityGroups","groups","listGroups","securityGroupsWithCmsPermission","filter","group","permissions","some","isCmsContentPermission","exists","length","i","securityGroup","slug","CmsContentPermissions","restPermissions","permission","newCMSContentPermissions","getModel","newPermissions","JSON","stringify","updateGroup","e","WebinyError","ApiKeys","apiKeys","listApiKeys","ApiKeysWithCmsPermission","key","apiKey","updateApiKey","id","description"],"mappings":";;;;;;;;;AAIA;;AAGA;;AACA;;AARA;AACA;AACA;AACA;AAOA,MAAMA,MAAiC,GAAG;AACtCC,EAAAA,IAAI,EAAE,uBADgC;AAEtCC,EAAAA,IAAI,EAAE,aAFgC;AAGtCC,EAAAA,GAAG,EAAE,cAHiC;AAItCC,EAAAA,OAAO,EAAE,OAJ6B;;AAKtC,QAAMC,KAAN,CAAYC,OAAZ,EAAqB;AACjBC,IAAAA,OAAO,CAACC,GAAR,CAAY,oCAAZ,EADiB,CAEjB;;AACA,QAAI;AACA,YAAM;AAAEC,QAAAA,QAAF;AAAYC,QAAAA,OAAZ;AAAqBC,QAAAA;AAArB,UAA6BL,OAAnC;AACA,YAAMM,MAAM,GAAGF,OAAO,CAACG,gBAAR,EAAf,CAFA,CAGA;AACA;;AACA,YAAMC,cAAc,GAAG,MAAML,QAAQ,CAACM,MAAT,CAAgBC,UAAhB,CAA2BJ,MAA3B,CAA7B;AACA,YAAMK,+BAA+B,GAAGH,cAAc,CAACI,MAAf,CAAsBC,KAAK,IAC/DA,KAAK,CAACC,WAAN,CAAkBC,IAAlB,CAAuBC,+BAAvB,CADoC,CAAxC;AAGA,YAAMC,MAAM,GAAGN,+BAA+B,CAACO,MAAhC,GAAyC,CAAxD;;AACA,UAAI,CAACD,MAAL,EAAa;AACThB,QAAAA,OAAO,CAACC,GAAR,CAAY,iDAAZ;AACA;AACH,OAbD,CAeA;;;AACA,WAAK,IAAIiB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGR,+BAA+B,CAACO,MAApD,EAA4DC,CAAC,EAA7D,EAAiE;AAC7D,cAAMC,aAAa,GAAGT,+BAA+B,CAACQ,CAAD,CAArD;AACAlB,QAAAA,OAAO,CAACC,GAAR,CAAa,kCAAiCkB,aAAa,CAACC,IAAK,EAAjE,EAF6D,CAG7D;;AACA,cAAMC,qBAAqB,GACvBF,aAAa,CAACN,WAAd,CAA0BF,MAA1B,CAAiCI,+BAAjC,CADJ;AAEA,cAAMO,eAAe,GAAGH,aAAa,CAACN,WAAd,CAA0BF,MAA1B,CACpBY,UAAU,IAAI,CAAC,qCAAuBA,UAAvB,CADK,CAAxB;;AAIA,YAAIF,qBAAqB,CAACJ,MAAtB,KAAiC,CAArC,EAAwC;AACpCjB,UAAAA,OAAO,CAACC,GAAR,CAAY,aAAZ;AACA;AACH,SAb4D,CAc7D;;;AACA,cAAMuB,wBAAwB,GAAG,MAAM,kDACnCH,qBADmC,EAEnCjB,GAAG,CAACqB,QAF+B,CAAvC;AAKA,cAAMC,cAAc,GAAG,CAAC,GAAGJ,eAAJ,EAAqB,GAAGE,wBAAxB,CAAvB;AACAxB,QAAAA,OAAO,CAACC,GAAR,CAAa,qCAAoCkB,aAAa,CAACC,IAAK,EAApE;AACApB,QAAAA,OAAO,CAACC,GAAR,CAAY,kBAAZ,EAAgC0B,IAAI,CAACC,SAAL,CAAeF,cAAf,EAA+B,IAA/B,EAAqC,CAArC,CAAhC,EAtB6D,CAuB7D;AACA;;AACA,cAAMxB,QAAQ,CAACM,MAAT,CAAgBqB,WAAhB,CAA4BxB,MAA5B,EAAoCc,aAAa,CAACC,IAAlD,EAAwD;AAC1DP,UAAAA,WAAW,EAAEa;AAD6C,SAAxD,CAAN;AAGH,OA5CD,CA8CA;;;AACA1B,MAAAA,OAAO,CAACC,GAAR,CAAY,yDAAZ;AACH,KAhDD,CAgDE,OAAO6B,CAAP,EAAU;AACR9B,MAAAA,OAAO,CAACC,GAAR,CAAY6B,CAAZ;AACA,YAAM,IAAIC,cAAJ,CAAgB,qDAAhB,CAAN;AACH,KAtDgB,CAwDjB;;;AACA,QAAI;AACA,YAAM;AAAE7B,QAAAA,QAAF;AAAYE,QAAAA;AAAZ,UAAoBL,OAA1B,CADA,CAEA;AACA;;AACA,YAAMiC,OAAO,GAAG,MAAM9B,QAAQ,CAAC+B,OAAT,CAAiBC,WAAjB,EAAtB;AACA,YAAMC,wBAAwB,GAAGH,OAAO,CAACrB,MAAR,CAAeyB,GAAG,IAC/CA,GAAG,CAACvB,WAAJ,CAAgBC,IAAhB,CAAqBC,+BAArB,CAD6B,CAAjC;AAGA,YAAMC,MAAM,GAAGmB,wBAAwB,CAAClB,MAAzB,GAAkC,CAAjD;;AACA,UAAI,CAACD,MAAL,EAAa;AACThB,QAAAA,OAAO,CAACC,GAAR,CAAY,0CAAZ;AACA;AACH,OAZD,CAcA;;;AACA,WAAK,IAAIiB,CAAC,GAAG,CAAb,EAAgBA,CAAC,GAAGiB,wBAAwB,CAAClB,MAA7C,EAAqDC,CAAC,EAAtD,EAA0D;AACtD,cAAMmB,MAAM,GAAGF,wBAAwB,CAACjB,CAAD,CAAvC;AACAlB,QAAAA,OAAO,CAACC,GAAR,CAAa,oCAAmCoC,MAAM,CAAC3C,IAAK,EAA5D,EAFsD,CAGtD;;AACA,cAAM2B,qBAAqB,GAAGgB,MAAM,CAACxB,WAAP,CAAmBF,MAAnB,CAA0BI,+BAA1B,CAA9B;AACA,cAAMO,eAAe,GAAGe,MAAM,CAACxB,WAAP,CAAmBF,MAAnB,CACpBY,UAAU,IAAI,CAAC,qCAAuBA,UAAvB,CADK,CAAxB;;AAIA,YAAIF,qBAAqB,CAACJ,MAAtB,KAAiC,CAArC,EAAwC;AACpCjB,UAAAA,OAAO,CAACC,GAAR,CAAY,aAAZ;AACA;AACH,SAZqD,CAatD;;;AACA,cAAMuB,wBAAwB,GAAG,MAAM,kDACnCH,qBADmC,EAEnCjB,GAAG,CAACqB,QAF+B,CAAvC;AAKA,cAAMC,cAAc,GAAG,CAAC,GAAGJ,eAAJ,EAAqB,GAAGE,wBAAxB,CAAvB;AACAxB,QAAAA,OAAO,CAACC,GAAR,CAAa,uCAAsCoC,MAAM,CAAC3C,IAAK,EAA/D;AACAM,QAAAA,OAAO,CAACC,GAAR,CAAY,kBAAZ,EAAgC0B,IAAI,CAACC,SAAL,CAAeF,cAAf,EAA+B,IAA/B,EAAqC,CAArC,CAAhC,EArBsD,CAsBtD;AACA;;AACA,cAAMxB,QAAQ,CAAC+B,OAAT,CAAiBK,YAAjB,CAA8BD,MAAM,CAACE,EAArC,EAAyC;AAC3C7C,UAAAA,IAAI,EAAE2C,MAAM,CAAC3C,IAD8B;AAE3C8C,UAAAA,WAAW,EAAEH,MAAM,CAACG,WAFuB;AAG3C3B,UAAAA,WAAW,EAAEa;AAH8B,SAAzC,CAAN;AAKH,OA5CD,CA8CA;;;AACA1B,MAAAA,OAAO,CAACC,GAAR,CAAY,gDAAZ;AACH,KAhDD,CAgDE,OAAO6B,CAAP,EAAU;AACR9B,MAAAA,OAAO,CAACC,GAAR,CAAY,gBAAZ;AACAD,MAAAA,OAAO,CAACC,GAAR,CAAY6B,CAAZ;AACA,YAAM,IAAIC,cAAJ,CAAgB,8CAAhB,CAAN;AACH;AACJ;;AAnHqC,CAA1C;eAsHetC,M","sourcesContent":["/**\n * Not used anymore so ignore.\n */\n// @ts-nocheck\nimport WebinyError from \"@webiny/error\";\nimport { UpgradePlugin } from \"@webiny/api-upgrade/types\";\nimport { CmsContext } from \"~/types\";\nimport { migrateCMSPermissions } from \"~/migrateCMSPermissions\";\nimport { isCmsContentPermission } from \"./helpers\";\n\nconst plugin: UpgradePlugin<CmsContext> = {\n name: \"api-upgrade-cms-5.5.0\",\n type: \"api-upgrade\",\n app: \"headless-cms\",\n version: \"5.5.0\",\n async apply(context) {\n console.log(\"Started CMS permissions migration.\");\n // Migrate \"Groups\"\n try {\n const { security, tenancy, cms } = context;\n const tenant = tenancy.getCurrentTenant();\n // Check if there is any \"SecurityGroup\" that contains \"cms\" permissions.\n // @ts-ignore Because we don't need a package dependency; this is a one-off operation.\n const securityGroups = await security.groups.listGroups(tenant);\n const securityGroupsWithCmsPermission = securityGroups.filter(group =>\n group.permissions.some(isCmsContentPermission)\n );\n const exists = securityGroupsWithCmsPermission.length > 0;\n if (!exists) {\n console.log(\"No Security groups with CMS permissions exists.\");\n return;\n }\n\n // For each such group, migrate permissions.\n for (let i = 0; i < securityGroupsWithCmsPermission.length; i++) {\n const securityGroup = securityGroupsWithCmsPermission[i];\n console.log(`Updating permission for group: ${securityGroup.slug}`);\n // Filter CMS content permissions.\n const CmsContentPermissions =\n securityGroup.permissions.filter(isCmsContentPermission);\n const restPermissions = securityGroup.permissions.filter(\n permission => !isCmsContentPermission(permission)\n );\n\n if (CmsContentPermissions.length === 0) {\n console.log(\"Skipping...\");\n continue;\n }\n // Migrate CMS permissions\n const newCMSContentPermissions = await migrateCMSPermissions(\n CmsContentPermissions,\n cms.getModel\n );\n\n const newPermissions = [...restPermissions, ...newCMSContentPermissions];\n console.log(`Saving new permissions for group: ${securityGroup.slug}`);\n console.log(\"newPermissions: \", JSON.stringify(newPermissions, null, 2));\n // Save group\n // @ts-ignore\n await security.groups.updateGroup(tenant, securityGroup.slug, {\n permissions: newPermissions\n });\n }\n\n // Indicate completion\n console.log(\"Finish CMS permissions migration for [Security groups].\");\n } catch (e) {\n console.log(e);\n throw new WebinyError(\"[Security groups] CMS permissions migration failed!\");\n }\n\n // Migrate \"API Keys\"\n try {\n const { security, cms } = context;\n // Check if there is any \"APIKey\" that contains \"cms\" permissions.\n // @ts-ignore\n const ApiKeys = await security.apiKeys.listApiKeys();\n const ApiKeysWithCmsPermission = ApiKeys.filter(key =>\n key.permissions.some(isCmsContentPermission)\n );\n const exists = ApiKeysWithCmsPermission.length > 0;\n if (!exists) {\n console.log(\"No API keys with CMS permissions exists.\");\n return;\n }\n\n // For each such API key, migrate permissions.\n for (let i = 0; i < ApiKeysWithCmsPermission.length; i++) {\n const apiKey = ApiKeysWithCmsPermission[i];\n console.log(`Updating permission for API key: ${apiKey.name}`);\n // Filter CMS content permissions.\n const CmsContentPermissions = apiKey.permissions.filter(isCmsContentPermission);\n const restPermissions = apiKey.permissions.filter(\n permission => !isCmsContentPermission(permission)\n );\n\n if (CmsContentPermissions.length === 0) {\n console.log(\"Skipping...\");\n continue;\n }\n // Migrate CMS permissions.\n const newCMSContentPermissions = await migrateCMSPermissions(\n CmsContentPermissions,\n cms.getModel\n );\n\n const newPermissions = [...restPermissions, ...newCMSContentPermissions];\n console.log(`Saving new permissions for API key: ${apiKey.name}`);\n console.log(\"newPermissions: \", JSON.stringify(newPermissions, null, 2));\n // Save API key\n // @ts-ignore\n await security.apiKeys.updateApiKey(apiKey.id, {\n name: apiKey.name,\n description: apiKey.description,\n permissions: newPermissions\n });\n }\n\n // Indicate completion\n console.log(\"Finish CMS permissions migration for API keys.\");\n } catch (e) {\n console.log(\"Upgrade v5.5.0\");\n console.log(e);\n throw new WebinyError(\"[API keys] CMS permissions migration failed!\");\n }\n }\n};\n\nexport default plugin;\n"]}
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["transformers.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;AAAA","sourcesContent":["import {\n entryFromStorageTransform,\n entryToStorageTransform,\n entryFieldFromStorageTransform\n} from \"./content/plugins/utils/entryStorage\";\n\nexport { entryToStorageTransform, entryFieldFromStorageTransform, entryFromStorageTransform };\n"]}
package/types.d.ts CHANGED
@@ -110,11 +110,11 @@ export interface CmsModelField {
110
110
  /**
111
111
  * Text below the field to clarify what is it meant to be in the field value
112
112
  */
113
- helpText?: string;
113
+ helpText?: string | null;
114
114
  /**
115
115
  * Text to be displayed in the field
116
116
  */
117
- placeholderText?: string;
117
+ placeholderText?: string | null;
118
118
  /**
119
119
  * Are predefined values enabled? And list of them
120
120
  */
@@ -149,9 +149,22 @@ export interface CmsModelField {
149
149
  */
150
150
  settings?: {
151
151
  /**
152
+ * Predefined values (text, number)
152
153
  * The default value for the field in case it is not predefined values field.
153
154
  */
154
155
  defaultValue?: string | number | null | undefined;
156
+ /**
157
+ * Object field.
158
+ */
159
+ fields?: CmsModelField[];
160
+ /**
161
+ * Ref field.
162
+ */
163
+ models?: Pick<CmsModel, "modelId">[];
164
+ /**
165
+ * Date field.
166
+ */
167
+ type?: string;
155
168
  /**
156
169
  * There are a lot of other settings that are possible to add so we keep the type opened.
157
170
  */
@@ -318,7 +331,7 @@ export interface CmsModel {
318
331
  /**
319
332
  * Description for the content model.
320
333
  */
321
- description?: string;
334
+ description?: string | null;
322
335
  /**
323
336
  * Date created
324
337
  */
@@ -380,7 +393,7 @@ interface CmsModelFieldToGraphQLCreateResolverParams {
380
393
  }
381
394
  export interface CmsModelFieldToGraphQLCreateResolver {
382
395
  (params: CmsModelFieldToGraphQLCreateResolverParams): GraphQLFieldResolver | {
383
- resolver: GraphQLFieldResolver;
396
+ resolver: GraphQLFieldResolver | null;
384
397
  typeResolvers: Resolvers<CmsContext>;
385
398
  } | false;
386
399
  }
@@ -595,7 +608,7 @@ export interface CmsModelFieldToGraphQLPlugin extends Plugin {
595
608
  model: CmsModel;
596
609
  field: CmsModelField;
597
610
  fieldTypePlugins: CmsFieldTypePlugins;
598
- }) => CmsModelFieldDefinition | string;
611
+ }) => CmsModelFieldDefinition | string | null;
599
612
  /**
600
613
  * Definition for field resolver.
601
614
  * By default it is simple return of the `instance.values[fieldId]` but if required, users can define their own.
@@ -662,7 +675,7 @@ export interface CreatedBy {
662
675
  /**
663
676
  * Full name of the user.
664
677
  */
665
- displayName: string;
678
+ displayName: string | null;
666
679
  /**
667
680
  * Type of the user (admin, user)
668
681
  */
@@ -713,9 +726,9 @@ export interface AfterInstallTopicParams {
713
726
  tenant: string;
714
727
  }
715
728
  export declare type CmsSystemContext = {
716
- getSystemVersion: () => Promise<string>;
729
+ getSystemVersion: () => Promise<string | null>;
717
730
  setSystemVersion: (version: string) => Promise<void>;
718
- getReadAPIKey(): Promise<string>;
731
+ getReadAPIKey(): Promise<string | null>;
719
732
  installSystem: () => Promise<void>;
720
733
  upgradeSystem: (version: string) => Promise<boolean>;
721
734
  /**
@@ -903,7 +916,12 @@ export interface CmsGroupContext {
903
916
  export interface CmsModelFieldValidation {
904
917
  name: string;
905
918
  message: string;
906
- settings?: Record<string, any>;
919
+ settings?: {
920
+ value?: string | number;
921
+ values?: string[];
922
+ preset?: string;
923
+ [key: string]: any;
924
+ };
907
925
  }
908
926
  /**
909
927
  * A GraphQL params.data parameter received when creating content model.
@@ -1366,6 +1384,15 @@ export interface CmsEntryListWhere {
1366
1384
  * @internal
1367
1385
  */
1368
1386
  latest?: boolean;
1387
+ /**
1388
+ * Search for exact locale.
1389
+ * This will most likely be populated, but leave it as optional.
1390
+ */
1391
+ locale?: string;
1392
+ /**
1393
+ * Exact tenant. No multi-tenancy search.
1394
+ */
1395
+ tenant: string;
1369
1396
  /**
1370
1397
  * Can be reference field or, actually, anything else.
1371
1398
  */
@@ -1398,7 +1425,7 @@ export interface CmsEntryListParams {
1398
1425
  where: CmsEntryListWhere;
1399
1426
  sort?: CmsEntryListSort;
1400
1427
  limit?: number;
1401
- after?: string;
1428
+ after?: string | null;
1402
1429
  }
1403
1430
  /**
1404
1431
  * Meta information for GraphQL output.
@@ -1410,7 +1437,7 @@ export interface CmsEntryMeta {
1410
1437
  /**
1411
1438
  * A cursor for pagination.
1412
1439
  */
1413
- cursor: string;
1440
+ cursor: string | null;
1414
1441
  /**
1415
1442
  * Is there more items to load?
1416
1443
  */
@@ -1552,7 +1579,7 @@ export interface CmsEntryContext {
1552
1579
  /**
1553
1580
  * Get a list of entries for a model by a given ID (revision).
1554
1581
  */
1555
- getEntriesByIds: (model: CmsModel, revisions: string[]) => Promise<CmsEntry[] | null>;
1582
+ getEntriesByIds: (model: CmsModel, revisions: string[]) => Promise<CmsEntry[]>;
1556
1583
  /**
1557
1584
  * Get the entry for a model by a given ID.
1558
1585
  */
@@ -1588,7 +1615,7 @@ export interface CmsEntryContext {
1588
1615
  /**
1589
1616
  * Update existing entry.
1590
1617
  */
1591
- updateEntry: (model: CmsModel, id: string, input?: UpdateCmsEntryInput) => Promise<CmsEntry>;
1618
+ updateEntry: (model: CmsModel, id: string, input: UpdateCmsEntryInput) => Promise<CmsEntry>;
1592
1619
  /**
1593
1620
  * Method that republishes entry with given identifier.
1594
1621
  * @internal
@@ -1671,15 +1698,22 @@ export declare type CmsEntryResolverFactory<TSource = any, TArgs = any, TContext
1671
1698
  */
1672
1699
  export interface CmsSettingsPermission extends SecurityPermission {
1673
1700
  }
1701
+ /**
1702
+ * A base security permission for CMS.
1703
+ *
1704
+ * @category SecurityPermission
1705
+ */
1706
+ export interface BaseCmsSecurityPermission extends SecurityPermission {
1707
+ own?: boolean;
1708
+ rwd: string | number;
1709
+ }
1674
1710
  /**
1675
1711
  * A security permission for content model.
1676
1712
  *
1677
1713
  * @category SecurityPermission
1678
1714
  * @category CmsModel
1679
1715
  */
1680
- export interface CmsModelPermission extends SecurityPermission {
1681
- own: boolean;
1682
- rwd: string;
1716
+ export interface CmsModelPermission extends BaseCmsSecurityPermission {
1683
1717
  /**
1684
1718
  * A object representing `key: model.modelId` values where key is locale code.
1685
1719
  */
@@ -1699,9 +1733,7 @@ export interface CmsModelPermission extends SecurityPermission {
1699
1733
  * @category SecurityPermission
1700
1734
  * @category CmsGroup
1701
1735
  */
1702
- export interface CmsGroupPermission extends SecurityPermission {
1703
- own: boolean;
1704
- rwd: string;
1736
+ export interface CmsGroupPermission extends BaseCmsSecurityPermission {
1705
1737
  /**
1706
1738
  * A object representing `key: group.id` values where key is locale code.
1707
1739
  */
@@ -1715,10 +1747,8 @@ export interface CmsGroupPermission extends SecurityPermission {
1715
1747
  * @category SecurityPermission
1716
1748
  * @category CmsEntry
1717
1749
  */
1718
- export interface CmsEntryPermission extends SecurityPermission {
1719
- own: boolean;
1720
- rwd: string;
1721
- pw: string;
1750
+ export interface CmsEntryPermission extends BaseCmsSecurityPermission {
1751
+ pw?: string;
1722
1752
  /**
1723
1753
  * A object representing `key: model.modelId` values where key is locale code.
1724
1754
  */
@@ -1846,7 +1876,7 @@ export interface CmsEntryStorageOperationsListParams {
1846
1876
  where: CmsEntryListWhere;
1847
1877
  sort?: CmsEntryListSort;
1848
1878
  limit?: number;
1849
- after?: string;
1879
+ after?: string | null;
1850
1880
  }
1851
1881
  export interface CmsEntryStorageOperationsCreateParams<T extends CmsStorageEntry = CmsStorageEntry> {
1852
1882
  /**
@@ -1874,11 +1904,11 @@ export interface CmsEntryStorageOperationsCreateRevisionFromParams<T extends Cms
1874
1904
  /**
1875
1905
  * Latest entry, used to calculate the new version.
1876
1906
  */
1877
- latestEntry: CmsEntry;
1907
+ latestEntry: CmsEntry | null;
1878
1908
  /**
1879
1909
  * Latest entry, used to calculate the new version, directly from storage, with transformations.
1880
1910
  */
1881
- latestStorageEntry: T;
1911
+ latestStorageEntry: T | null;
1882
1912
  /**
1883
1913
  * Real entry, with no transformations on it.
1884
1914
  */
@@ -1922,11 +1952,11 @@ export interface CmsEntryStorageOperationsDeleteRevisionParams<T extends CmsStor
1922
1952
  /**
1923
1953
  * Entry that was set as latest.
1924
1954
  */
1925
- entryToSetAsLatest?: CmsEntry;
1955
+ entryToSetAsLatest: CmsEntry | null;
1926
1956
  /**
1927
1957
  * Entry that was set as latest, directly from storage, with transformations.
1928
1958
  */
1929
- storageEntryToSetAsLatest?: T;
1959
+ storageEntryToSetAsLatest: T | null;
1930
1960
  }
1931
1961
  export interface CmsEntryStorageOperationsDeleteParams<T extends CmsStorageEntry = CmsStorageEntry> {
1932
1962
  /**
package/types.js CHANGED
@@ -334,6 +334,12 @@ exports.CONTENT_ENTRY_STATUS = void 0;
334
334
  */
335
335
  // eslint-disable-line
336
336
 
337
+ /**
338
+ * A base security permission for CMS.
339
+ *
340
+ * @category SecurityPermission
341
+ */
342
+
337
343
  /**
338
344
  * A security permission for content model.
339
345
  *
package/types.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["types.ts"],"names":["CONTENT_ENTRY_STATUS"],"mappings":";;;;;;;AAqDA;AACA;AACA;AACA;AACA;;AAqBA;AACA;AACA;AACA;AACA;;AAYA;AACA;AACA;AACA;AACA;;AASA;AACA;AACA;AACA;AACA;AACA;;AAmFA;AACA;AACA;;AAUA;AACA;AACA;AACA;AACA;AACA;;AAgCA;AACA;AACA;AACA;AACA;AACA;AACA;;AAqBA;AACA;AACA;AACA;AACA;AACA;AACA;;AAyBA;AACA;AACA;AACA;AACA;AACA;AACA;;AAiBA;AACA;AACA;AACA;AACA;AACA;;AA6EA;AACA;AACA;;AAoBA;AACA;AACA;AACA;AACA;;AAqNA;AACA;AACA;AACA;AACA;AACA;AACA;;AAoBA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;;AAqCA;AACA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;;AAgDA;AACA;AACA;AACA;AACA;AACA;;AASA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;AACA;;AAiCA;AACA;AACA;AACA;AACA;AACA;;AAYA;AACA;AACA;AACA;AACA;AACA;;AAoBA;AACA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAsDA;AACA;AACA;AACA;AACA;AACA;;AAoCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAkBA;AACA;AACA;AACA;AACA;AACA;;AA6EA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AA4EA;AACA;AACA;AACA;AACA;AACA;;AAuDA;AACA;AACA;AACA;AACA;;AAkBA;AACA;AACA;AACA;AACA;AACA;;AAwEA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;;AAiIA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;;AAqHA;AACA;AACA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;AACqE;;AAErE;AACA;AACA;AACA;AACA;;AAKA;AACA;AACA;AACA;AACA;AACA;;AAgBA;AACA;AACA;AACA;AACA;AACA;;AAUA;AACA;AACA;AACA;AACA;AACA;;AAgDA;AACA;AACA;AACA;AACA;;AAuDA;AACA;AACA;AACA;AACA;;AAwRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;IA2HYA,oB;;;WAAAA,oB;AAAAA,EAAAA,oB;AAAAA,EAAAA,oB;AAAAA,EAAAA,oB;AAAAA,EAAAA,oB;AAAAA,EAAAA,oB;GAAAA,oB,oCAAAA,oB","sourcesContent":["import { Plugin } from \"@webiny/plugins/types\";\nimport { I18NContext, I18NLocale } from \"@webiny/api-i18n/types\";\nimport { Context } from \"@webiny/handler/types\";\nimport { TenancyContext } from \"@webiny/api-tenancy/types\";\nimport {\n GraphQLFieldResolver,\n GraphQLSchemaDefinition,\n Resolvers\n} from \"@webiny/handler-graphql/types\";\nimport { I18NContentContext } from \"@webiny/api-i18n-content/types\";\nimport { SecurityPermission } from \"@webiny/api-security/types\";\nimport { HttpContext } from \"@webiny/handler-http/types\";\nimport { DbContext } from \"@webiny/handler-db/types\";\nimport { FileManagerContext } from \"@webiny/api-file-manager/types\";\nimport { UpgradePlugin } from \"@webiny/api-upgrade/types\";\nimport { Topic } from \"@webiny/pubsub/types\";\n\nexport type ApiEndpoint = \"manage\" | \"preview\" | \"read\";\nexport interface HeadlessCms\n extends CmsSettingsContext,\n CmsSystemContext,\n CmsGroupContext,\n CmsModelContext,\n CmsEntryContext {\n /**\n * API type\n */\n type: ApiEndpoint;\n /**\n * Requested locale\n */\n locale: string;\n /**\n * returns an instance of current locale\n */\n getLocale: () => I18NLocale;\n /**\n * Means this request is a READ API\n */\n READ: boolean;\n /**\n * Means this request is a MANAGE API\n */\n MANAGE: boolean;\n /**\n * Means this request is a PREVIEW API\n */\n PREVIEW: boolean;\n /**\n * The storage operations loaded for current context.\n */\n storageOperations: HeadlessCmsStorageOperations;\n}\n/**\n * @description This combines all contexts used in the CMS into a single one.\n *\n * @category Context\n */\nexport interface CmsContext\n extends Context,\n DbContext,\n HttpContext,\n I18NContext,\n FileManagerContext,\n I18NContentContext,\n TenancyContext {\n cms: HeadlessCms;\n}\n\ninterface CmsModelFieldPredefinedValuesValue {\n value: string;\n label: string;\n /**\n * Default selected predefined value.\n */\n selected?: boolean;\n}\n\n/**\n * Object containing content model field predefined options and values.\n *\n * @category CmsModelField\n */\nexport interface CmsModelFieldPredefinedValues {\n /**\n * Are predefined field values enabled?\n */\n enabled: boolean;\n /**\n * Predefined values array.\n */\n values: CmsModelFieldPredefinedValuesValue[];\n}\n\n/**\n * Object containing content model field renderer options.\n *\n * @category CmsModelField\n */\ninterface CmsModelFieldRenderer {\n /**\n * Name of the field renderer. Must have one in field renderer plugins.\n * Can be blank to let automatically determine the renderer.\n */\n name: string;\n}\n\n/**\n * A definition for content model field. This type exists on the app side as well.\n *\n * @category ModelField\n * @category Database model\n */\nexport interface CmsModelField {\n /**\n * A generated ID for the model field\n */\n id: string;\n /**\n * A type of the field\n */\n type: string;\n /**\n * A unique field ID for mapping values\n */\n fieldId: string;\n /**\n * A label for the field\n */\n label: string;\n /**\n * Text below the field to clarify what is it meant to be in the field value\n */\n helpText?: string | null;\n /**\n * Text to be displayed in the field\n */\n placeholderText?: string | null;\n /**\n * Are predefined values enabled? And list of them\n */\n predefinedValues?: CmsModelFieldPredefinedValues;\n /**\n * Field renderer. Blank if determined automatically.\n */\n renderer?: CmsModelFieldRenderer;\n /**\n * List of validations for the field\n *\n * @default []\n */\n validation?: CmsModelFieldValidation[];\n /**\n * List of validations for the list of values, when a field is set to accept a list of values.\n * These validations will be applied to the entire list, and `validation` (see above) will be applied\n * to each individual value in the list.\n *\n * @default []\n */\n listValidation?: CmsModelFieldValidation[];\n /**\n * Is this a multiple values field?\n *\n */\n multipleValues?: boolean;\n /**\n * Any user defined settings.\n *\n * @default {}\n */\n settings?: {\n /**\n * Predefined values (text, number)\n * The default value for the field in case it is not predefined values field.\n */\n defaultValue?: string | number | null | undefined;\n /**\n * Object field.\n */\n fields?: CmsModelField[];\n /**\n * Ref field.\n */\n models?: Pick<CmsModel, \"modelId\">[];\n /**\n * Date field.\n */\n type?: string;\n /**\n * There are a lot of other settings that are possible to add so we keep the type opened.\n */\n [key: string]: any;\n };\n}\n\n/**\n * A definition for dateTime field to show possible type of the field in settings.\n */\nexport interface CmsModelDateTimeField extends CmsModelField {\n /**\n * Settings object for the field. Contains type property.\n */\n settings: {\n type: \"time\" | \"date\" | \"dateTimeWithoutTimezone\" | \"dateTimeWithTimezone\";\n };\n}\n\n/**\n * Arguments for the field validator validate method.\n *\n * @category ModelField\n * @category FieldValidation\n */\nexport interface CmsModelFieldValidatorValidateParams<T = any> {\n /**\n * A value to be validated.\n */\n value: T;\n /**\n * Options from the CmsModelField validations.\n *\n * @see CmsModelField.validation\n * @see CmsModelField.listValidation\n */\n validator: CmsModelFieldValidation;\n /**\n * An instance of the current context.\n */\n context: CmsContext;\n /**\n * Field being validated.\n */\n field: CmsModelField;\n /**\n * An instance of the content model being validated.\n */\n model: CmsModel;\n /**\n * If entry is sent it means it is an update operation.\n * First usage is for the unique field value.\n */\n entry?: CmsEntry;\n}\n\n/**\n * Definition for the field validator.\n *\n * @category Plugin\n * @category ModelField\n * @category FieldValidation\n */\nexport interface CmsModelFieldValidatorPlugin extends Plugin {\n /**\n * A plugin type.\n */\n type: \"cms-model-field-validator\";\n /**\n * Actual validator definition.\n */\n validator: {\n /**\n * Name of the validator.\n */\n name: string;\n /**\n * Validation method.\n */\n validate(params: CmsModelFieldValidatorValidateParams): Promise<boolean>;\n };\n}\n\n/**\n * A pattern validator for the content entry field value.\n *\n * @category Plugin\n * @category ModelField\n * @category FieldValidation\n */\nexport interface CmsModelFieldPatternValidatorPlugin extends Plugin {\n /**\n * A plugin type\n */\n type: \"cms-model-field-validator-pattern\";\n /**\n * A pattern object for the validator.\n */\n pattern: {\n /**\n * name of the pattern.\n */\n name: string;\n /**\n * RegExp of the validator.\n */\n regex: string;\n /**\n * RegExp flags\n */\n flags: string;\n };\n}\n\n/**\n * Locked field in the content model\n *\n * @see CmsModel.lockedFields\n *\n * @category ModelField\n */\nexport interface LockedField {\n /**\n * Locked field ID - one used for mapping values.\n */\n fieldId: string;\n /**\n * Is the field multiple values field?\n */\n multipleValues: boolean;\n /**\n * Field type.\n */\n type: string;\n [key: string]: any;\n}\n\n/**\n * Cms Model defining an entry.\n *\n * @category Database model\n * @category CmsModel\n */\nexport interface CmsModel {\n /**\n * Name of the content model.\n */\n name: string;\n /**\n * Unique ID for the content model. Created from name if not defined by user.\n */\n modelId: string;\n /**\n * Locale this model belongs to.\n */\n locale: string;\n /**\n * Cms Group reference object.\n */\n group: {\n /**\n * Generated ID of the group\n */\n id: string;\n /**\n * Name of the group\n */\n name: string;\n };\n /**\n * Description for the content model.\n */\n description?: string | null;\n /**\n * Date created\n */\n createdOn?: Date;\n /**\n * Date saved. Changes on both save and create.\n */\n savedOn?: Date;\n /**\n * CreatedBy object wrapper. Contains id, name and type of the user.\n */\n createdBy?: CreatedBy;\n /**\n * List of fields defining entry values.\n */\n fields: CmsModelField[];\n /**\n * Admin UI field layout\n *\n * ```ts\n * layout: [\n * [field1id, field2id],\n * [field3id]\n * ]\n * ```\n */\n layout: string[][];\n /**\n * List of locked fields. Updated when entry is saved and a field has been used.\n */\n lockedFields?: LockedField[];\n /**\n * The field that is being displayed as entry title.\n * It is picked as first available text field. Or user can select own field.\n */\n titleFieldId: string;\n /**\n * The version of Webiny which this record was stored with.\n */\n webinyVersion: string;\n /**\n * Model tenant.\n */\n tenant: string;\n}\n\n/**\n * @category ModelField\n */\nexport interface CmsModelFieldDefinition {\n fields: string;\n typeDefs?: string;\n}\n\ninterface CmsModelFieldToGraphQLCreateResolverParams {\n models: CmsModel[];\n model: CmsModel;\n graphQLType: string;\n field: CmsModelField;\n createFieldResolvers: any;\n}\nexport interface CmsModelFieldToGraphQLCreateResolver {\n (params: CmsModelFieldToGraphQLCreateResolverParams):\n | GraphQLFieldResolver\n | { resolver: GraphQLFieldResolver | null; typeResolvers: Resolvers<CmsContext> }\n | false;\n}\n\n/**\n * @category Plugin\n * @category ModelField\n * @category GraphQL\n */\nexport interface CmsModelFieldToGraphQLPlugin extends Plugin {\n /**\n * A plugin type\n */\n type: \"cms-model-field-to-graphql\";\n /**\n * Field type name which must be exact as the one in `CmsEditorFieldTypePlugin` plugin.\n *\n * ```ts\n * fieldType: \"myField\"\n * ```\n */\n fieldType: string;\n /**\n * Is the field searchable via the GraphQL?\n *\n * ```ts\n * isSearchable: false\n * ```\n */\n isSearchable: boolean;\n /**\n * Is the field sortable via the GraphQL?\n *\n * ```ts\n * isSortable: true\n * ```\n */\n isSortable: boolean;\n /**\n * Read API methods.\n */\n read: {\n /**\n * Definition for get filtering for GraphQL.\n *\n * ```ts\n * read: {\n * createGetFilters({ field }) {\n * return `${field.fieldId}: MyField`;\n * }\n * }\n * ```\n */\n createGetFilters?(params: { model: CmsModel; field: CmsModelField }): string;\n /**\n * Definition for list filtering for GraphQL.\n *\n * ```ts\n * read: {\n * createListFilters({ field }) {\n * return `\n * ${field.fieldId}: MyType\n * ${field.fieldId}_not: MyType\n * ${field.fieldId}_in: [MyType]\n * ${field.fieldId}_not_in: [MyType]\n * `;\n * }\n * }\n * ```\n */\n createListFilters?(params: { model: CmsModel; field: CmsModelField }): string;\n /**\n * Definition of the field type for GraphQL - be aware if multiple values is selected.\n *\n * ```ts\n * read: {\n * createTypeField({ field }) {\n * if (field.multipleValues) {\n * return `${field.fieldId}: [MyFieldType]`;\n * }\n *\n * return `${field.fieldId}: MyField`;\n * }\n * }\n * ```\n */\n createTypeField(params: {\n model: CmsModel;\n field: CmsModelField;\n fieldTypePlugins: CmsFieldTypePlugins;\n }): CmsModelFieldDefinition | string | null;\n /**\n * Definition for field resolver.\n * By default it is simple return of the `instance.values[fieldId]` but if required, users can define their own.\n *\n * ```ts\n * read: {\n * createResolver({ field }) {\n * return instance => {\n * return instance.values[field.fieldId];\n * };\n * }\n * }\n * ```\n */\n createResolver?: CmsModelFieldToGraphQLCreateResolver;\n /**\n * Read API schema definitions for the field and resolvers for them.\n *\n * ```ts\n * read: {\n * createSchema() {\n * return {\n * typeDefs: `\n * myField {\n * id\n * date\n * }\n * `,\n * resolvers: {}\n * }\n * }\n * }\n * ```\n */\n createSchema?: (params: { models: CmsModel[] }) => GraphQLSchemaDefinition<CmsContext>;\n };\n manage: {\n /**\n * Definition for list filtering for GraphQL.\n *\n * ```ts\n * manage: {\n * createListFilters({ field }) {\n * return `\n * ${field.fieldId}: MyType\n * ${field.fieldId}_not: MyType\n * ${field.fieldId}_in: [MyType]\n * ${field.fieldId}_not_in: [MyType]\n * `;\n * }\n * }\n * ```\n */\n createListFilters?: (params: { model: CmsModel; field: CmsModelField }) => string;\n /**\n * Manage API schema definitions for the field and resolvers for them. Probably similar to `read.createSchema`.\n *\n * ```ts\n * createSchema() {\n * return {\n * typeDefs: `\n * myField {\n * id\n * date\n * }\n * `,\n * resolvers: {}\n * }\n * }\n * ```\n */\n createSchema?: (params: { models: CmsModel[] }) => GraphQLSchemaDefinition<CmsContext>;\n /**\n * Definition of the field type for GraphQL - be aware if multiple values is selected. Probably same as `read.createTypeField`.\n *\n * ```ts\n * manage: {\n * createTypeField({ field }) {\n * if (field.multipleValues) {\n * return field.fieldId + \": [MyType]\";\n * }\n *\n * return field.fieldId + \": MyType\";\n * }\n * }\n * ```\n */\n createTypeField: (params: {\n model: CmsModel;\n field: CmsModelField;\n fieldTypePlugins: CmsFieldTypePlugins;\n }) => CmsModelFieldDefinition | string | null;\n /**\n * Definition for input GraphQL field type.\n *\n * ```ts\n * manage: {\n * createInputField({ field }) {\n * if (field.multipleValues) {\n * return field.fieldId + \": [MyField]\";\n * }\n *\n * return field.fieldId + \": MyField\";\n * }\n * }\n * ```\n */\n createInputField: (params: {\n model: CmsModel;\n field: CmsModelField;\n fieldTypePlugins: CmsFieldTypePlugins;\n }) => CmsModelFieldDefinition | string | null;\n /**\n * Definition for field resolver.\n * By default it is simple return of the `instance.values[fieldId]` but if required, users can define their own.\n *\n * ```ts\n * manage: {\n * createResolver({ field }) {\n * return instance => {\n * return instance.values[field.fieldId];\n * };\n * }\n * }\n * ```\n */\n createResolver?: CmsModelFieldToGraphQLCreateResolver;\n };\n}\n\n/**\n * Check for content model locked field.\n * A custom plugin definable by the user.\n *\n * @category CmsModel\n * @category Plugin\n */\nexport interface CmsModelLockedFieldPlugin extends Plugin {\n /**\n * A plugin type\n */\n type: \"cms-model-locked-field\";\n /**\n * A unique identifier of the field type (text, number, json, myField, ...).\n */\n fieldType: string;\n /**\n * A method to check if field really is locked.\n */\n checkLockedField?: (params: { lockedField: LockedField; field: CmsModelField }) => void;\n /**\n * A method to get the locked field data.\n */\n getLockedFieldData?: (params: { field: CmsModelField }) => Record<string, any>;\n}\n\n/**\n * @category ModelField\n */\nexport interface CmsFieldTypePlugins {\n [key: string]: CmsModelFieldToGraphQLPlugin;\n}\n\n/**\n * A interface describing the reference to a user that created some data in the database.\n *\n * @category General\n */\nexport interface CreatedBy {\n /**\n * ID if the user.\n */\n id: string;\n /**\n * Full name of the user.\n */\n displayName: string | null;\n /**\n * Type of the user (admin, user)\n */\n type: string;\n}\n\n/**\n * Representation of settings database model.\n *\n * @category Database model\n */\nexport interface CmsSettings {\n /**\n * Last content model change. Used to cache GraphQL schema.\n */\n contentModelLastChange: Date;\n /**\n * Settings tenant.\n */\n tenant: string;\n /**\n * Settings locale.\n */\n locale: string;\n}\n\n/**\n * Settings CRUD in context.\n *\n * @category Context\n */\nexport interface CmsSettingsContext {\n /**\n * Gets settings model from the database.\n */\n getSettings: () => Promise<CmsSettings | null>;\n /**\n * Updates settings model with a new date.\n */\n updateModelLastChange: () => Promise<void>;\n /**\n * Get the datetime when content model last changed.\n */\n getModelLastChange: () => Promise<Date>;\n}\n\nexport interface BeforeInstallTopicParams {\n tenant: string;\n}\n\nexport interface AfterInstallTopicParams {\n tenant: string;\n}\n\nexport type CmsSystemContext = {\n getSystemVersion: () => Promise<string | null>;\n setSystemVersion: (version: string) => Promise<void>;\n getReadAPIKey(): Promise<string | null>;\n installSystem: () => Promise<void>;\n upgradeSystem: (version: string) => Promise<boolean>;\n /**\n * Events\n */\n onBeforeSystemInstall: Topic<BeforeInstallTopicParams>;\n onAfterSystemInstall: Topic<AfterInstallTopicParams>;\n};\n\n/**\n * A GraphQL params.data parameter received when creating content model group.\n *\n * @category CmsGroup\n * @category GraphQL params\n */\nexport interface CmsGroupCreateInput {\n name: string;\n slug?: string;\n description?: string;\n icon: string;\n}\n\n/**\n * A GraphQL params.data parameter received when updating content model group.\n *\n * @category CmsGroup\n * @category GraphQL params\n */\nexport interface CmsGroupUpdateInput {\n name?: string;\n slug?: string;\n description?: string;\n icon?: string;\n}\n\n/**\n * A representation of content model group in the database.\n *\n * @category CmsGroup\n * @category Database model\n */\nexport interface CmsGroup {\n /**\n * Generated ID.\n */\n id: string;\n /**\n * Name of the group.\n */\n name: string;\n /**\n * Slug for the group. Must be unique.\n */\n slug: string;\n /**\n * Locale this group belongs to.\n */\n locale: string;\n /**\n * Description for the group.\n */\n description?: string;\n /**\n * Icon for the group. In a form of \"ico/ico\".\n */\n icon?: string;\n /**\n * CreatedBy reference object.\n */\n createdBy?: CreatedBy;\n /**\n * Date group was created on.\n */\n createdOn?: string;\n /**\n * Date group was created or changed on.\n */\n savedOn?: string;\n /**\n * Which Webiny version was this record stored with.\n */\n webinyVersion: string;\n /**\n * Group tenant.\n */\n tenant: string;\n}\n\n/**\n * A data.where parameter received when listing content model groups.\n *\n * @category CmsGroup\n * @category GraphQL params\n */\nexport interface CmsGroupListParams {\n where: {\n tenant: string;\n locale: string;\n [key: string]: any;\n };\n}\n\n/**\n * @category CmsGroup\n * @category Topic\n */\nexport interface BeforeGroupCreateTopicParams {\n group: CmsGroup;\n}\n\n/**\n * @category CmsGroup\n * @category Topic\n */\nexport interface AfterGroupCreateTopicParams {\n group: CmsGroup;\n}\n\n/**\n * @category CmsGroup\n * @category Topic\n */\nexport interface BeforeGroupUpdateTopicParams {\n original: CmsGroup;\n group: CmsGroup;\n}\n\n/**\n * @category CmsGroup\n * @category Topic\n */\nexport interface AfterGroupUpdateTopicParams {\n original: CmsGroup;\n group: CmsGroup;\n}\n\n/**\n * @category CmsGroup\n * @category Topic\n */\nexport interface BeforeGroupDeleteTopicParams {\n group: CmsGroup;\n}\n\n/**\n * @category CmsGroup\n * @category Topic\n */\nexport interface AfterGroupDeleteTopicParams {\n group: CmsGroup;\n}\n\n/**\n * Cms Group in context.\n *\n * @category Context\n * @category CmsGroup\n */\nexport interface CmsGroupContext {\n /**\n * Gets content model group by given id.\n */\n getGroup: (id: string) => Promise<CmsGroup | null>;\n /**\n * List all content model groups. Filterable via params.\n */\n listGroups: (params?: CmsGroupListParams) => Promise<CmsGroup[]>;\n /**\n * Create a new content model group.\n */\n createGroup: (data: CmsGroupCreateInput) => Promise<CmsGroup>;\n /**\n * Update existing content model group.\n */\n updateGroup: (id: string, data: CmsGroupUpdateInput) => Promise<CmsGroup>;\n /**\n * Delete content model group by given id.\n */\n deleteGroup: (id: string) => Promise<boolean>;\n /**\n * Events.\n */\n onBeforeGroupCreate: Topic<BeforeGroupCreateTopicParams>;\n onAfterGroupCreate: Topic<AfterGroupCreateTopicParams>;\n onBeforeGroupUpdate: Topic<BeforeGroupUpdateTopicParams>;\n onAfterGroupUpdate: Topic<AfterGroupUpdateTopicParams>;\n onBeforeGroupDelete: Topic<BeforeGroupDeleteTopicParams>;\n onAfterGroupDelete: Topic<AfterGroupDeleteTopicParams>;\n}\n\n/**\n * Definition for content model field validator.\n *\n * @category ModelField\n * @category FieldValidation\n */\nexport interface CmsModelFieldValidation {\n name: string;\n message: string;\n settings?: {\n value?: string | number;\n values?: string[];\n preset?: string;\n [key: string]: any;\n };\n}\n\n/**\n * A GraphQL params.data parameter received when creating content model.\n *\n * @category GraphQL params\n * @category CmsModel\n */\nexport interface CmsModelCreateInput {\n /**\n * Name of the content model.\n */\n name: string;\n /**\n * Unique ID of the content model. Created from name if not sent by the user. Cannot be changed.\n */\n modelId?: string;\n /**\n * Description of the content model.\n */\n description?: string;\n /**\n * Group where to put the content model in.\n */\n group: string;\n}\n\n/**\n * A GraphQL params.data parameter received when creating content model from existing model.\n *\n * @category GraphQL params\n * @category CmsModel\n */\nexport interface CmsModelCreateFromInput extends CmsModelCreateInput {\n /**\n * Locale into which we want to clone the model into.\n */\n locale?: string;\n}\n\n/**\n * A definition for content model field received from the user.\n *\n * Input type for `CmsModelField`.\n * @see CmsModelField\n *\n * @category GraphQL params\n * @category ModelField\n */\nexport interface CmsModelFieldInput {\n /**\n * Generated ID.\n */\n id: string;\n /**\n * Type of the field. A plugin for the field must be defined.\n * @see CmsModelFieldToGraphQLPlugin\n */\n type: string;\n /**\n * A unique ID for the field. Values will be mapped via this value.\n * This field MUST be in range of \"a-zA-Z\".\n */\n fieldId: string;\n /**\n * Label for the field.\n */\n label: string;\n /**\n * Text to display below the field to help user what to write in the field.\n */\n helpText?: string;\n /**\n * Text to display in the field.\n */\n placeholderText?: string;\n /**\n * Are multiple values allowed?\n */\n multipleValues?: boolean;\n /**\n * Predefined values options for the field. Check the reference for more information.\n */\n predefinedValues?: CmsModelFieldPredefinedValues;\n /**\n * Renderer options for the field. Check the reference for more information.\n */\n renderer?: CmsModelFieldRenderer;\n /**\n * List of validations for the field.\n */\n validation?: CmsModelFieldValidation[];\n /**\n * @see CmsModelField.listValidation\n */\n listValidation: CmsModelFieldValidation[];\n /**\n * User defined settings.\n */\n settings?: Record<string, any>;\n}\n\n/**\n * A GraphQL params.data parameter received when updating content model.\n *\n * @category GraphQL params\n * @category CmsModel\n */\nexport interface CmsModelUpdateInput {\n /**\n * A new content model name.\n */\n name?: string;\n /**\n * A group we want to move the model to.\n */\n group?: string;\n /**\n * A new description of the content model.\n */\n description?: string;\n /**\n * A list of content model fields to define the entry values.\n */\n fields: CmsModelFieldInput[];\n /**\n * Admin UI field layout\n *\n * ```ts\n * layout: [\n * [field1id, field2id],\n * [field3id]\n * ]\n * ```\n */\n layout: string[][];\n /**\n * The field that is being displayed as entry title.\n * It is picked as first available text field. Or user can select own field.\n */\n titleFieldId?: string;\n}\n\n/**\n * A plugin to load a CmsModelManager.\n *\n * @see CmsModelManager\n *\n * @category Plugin\n * @category CmsModel\n * @category CmsEntry\n */\nexport interface ModelManagerPlugin extends Plugin {\n /**\n * A plugin type.\n */\n type: \"cms-content-model-manager\";\n /**\n * Specific model CmsModelManager loader. Can target exact modelId(s).\n * Be aware that if you define multiple plugins without `modelId`, last one will run.\n */\n modelId?: string[] | string;\n /**\n * Create a CmsModelManager for specific type - or new default one.\n * For reference in how is this plugin run check [contentModelManagerFactory](https://github.com/webiny/webiny-js/blob/f15676/packages/api-headless-cms/src/content/plugins/CRUD/contentModel/contentModelManagerFactory.ts)\n */\n create: (context: CmsContext, model: CmsModel) => Promise<CmsModelManager>;\n}\n\n/**\n * A content entry definition for and from the database.\n *\n * @category Database model\n * @category CmsEntry\n */\nexport interface CmsEntry {\n /**\n * A version of the webiny this entry was created with.\n * This can be used when upgrading the system so we know which entries to update.\n */\n webinyVersion: string;\n /**\n * Tenant id which is this entry for. Can be used in case of shared storage.\n */\n tenant: string;\n /**\n * Generated ID of the entry. It is shared across all the records in the database that represent a single entry.\n * So version 1, 2, ..., 2371 will have the same value in this field to link them together.\n */\n entryId: string;\n /**\n * Generated ID + version of the entry.\n */\n id: string;\n /**\n * CreatedBy object reference.\n */\n createdBy: CreatedBy;\n /**\n * OwnedBy object reference. Can be different from CreatedBy.\n */\n ownedBy: CreatedBy;\n /**\n * A string of Date.toISOString() type.\n * Populated on creation.\n */\n createdOn: string;\n /**\n * A string of Date.toISOString() type.\n * Populated every time entry is saved.\n */\n savedOn: string;\n /**\n * Model ID of the definition for the entry.\n * @see CmsModel\n */\n modelId: string;\n /**\n * A locale of the entry.\n * @see I18NLocale.code\n */\n locale: string;\n /**\n * A string of Date.toISOString() type - if published.\n * Populated when entry is published.\n */\n publishedOn?: string;\n /**\n * A revision version of the entry.\n */\n version: number;\n /**\n * Is the entry locked?\n */\n locked: boolean;\n /**\n * Status type of the entry.\n */\n status: CmsEntryStatus;\n /**\n * A mapped fieldId -> value object.\n *\n * @see CmsModelField\n */\n values: Record<string, any>;\n}\n\nexport interface CmsStorageEntry extends CmsEntry {\n [key: string]: any;\n}\n\n/**\n * A definition for content model manager to be used in the code.\n * The default one uses `CmsEntryContext` methods internally, but devs can change to what every they want.\n *\n * @see CmsEntryContext\n *\n * @category Context\n * @category CmsEntry\n * @category CmsModel\n */\nexport interface CmsModelManager {\n /**\n * List only published entries in the content model.\n */\n listPublished: (params: CmsEntryListParams) => Promise<[CmsEntry[], CmsEntryMeta]>;\n /**\n * List latest entries in the content model. Used for administration.\n */\n listLatest: (params: CmsEntryListParams) => Promise<[CmsEntry[], CmsEntryMeta]>;\n /**\n * Get a list of published entries by the ID list.\n */\n getPublishedByIds: (ids: string[]) => Promise<CmsEntry[]>;\n /**\n * Get a list of latest entries by the ID list.\n */\n getLatestByIds: (ids: string[]) => Promise<CmsEntry[]>;\n /**\n * Get an entry filtered by given params. Will always get one.\n */\n get: (id: string) => Promise<CmsEntry>;\n /**\n * Create a entry.\n */\n create: (data: CreateCmsEntryInput) => Promise<CmsEntry>;\n /**\n * Update a entry.\n */\n update: (id: string, data: UpdateCmsEntryInput) => Promise<CmsEntry>;\n /**\n * Delete a entry.\n */\n delete: (id: string) => Promise<void>;\n}\n\nexport interface BeforeModelCreateTopicParams {\n input: CmsModelCreateInput;\n model: CmsModel;\n}\nexport interface AfterModelCreateTopicParams {\n input: CmsModelCreateInput;\n model: CmsModel;\n}\nexport interface BeforeModelCreateFromTopicParams {\n input: CmsModelCreateInput;\n original: CmsModel;\n model: CmsModel;\n}\nexport interface AfterModelCreateFromTopicParams {\n input: CmsModelCreateInput;\n original: CmsModel;\n model: CmsModel;\n}\nexport interface BeforeModelUpdateTopicParams {\n input: CmsModelUpdateInput;\n original: CmsModel;\n model: CmsModel;\n}\nexport interface AfterModelUpdateTopicParams {\n input: CmsModelUpdateInput;\n original: CmsModel;\n model: CmsModel;\n}\nexport interface BeforeModelDeleteTopicParams {\n model: CmsModel;\n}\nexport interface AfterModelDeleteTopicParams {\n model: CmsModel;\n}\n\nexport interface CmsModelUpdateDirectParams {\n model: CmsModel;\n original: CmsModel;\n}\n\n/**\n * Cms Model in the context.\n *\n * @category Context\n * @category CmsModel\n */\nexport interface CmsModelContext {\n /**\n * Get a single content model.\n */\n getModel: (modelId: string) => Promise<CmsModel | null>;\n /**\n * Get all content models.\n */\n listModels: () => Promise<CmsModel[]>;\n /**\n * Create a content model.\n */\n createModel: (data: CmsModelCreateInput) => Promise<CmsModel>;\n /**\n * Create a content model from the given model - clone.\n */\n createModelFrom: (modelId: string, data: CmsModelCreateFromInput) => Promise<CmsModel>;\n /**\n * Update content model without data validation. Used internally.\n * @hidden\n */\n updateModelDirect: (params: CmsModelUpdateDirectParams) => Promise<CmsModel>;\n /**\n * Update content model.\n */\n updateModel: (modelId: string, data: CmsModelUpdateInput) => Promise<CmsModel>;\n /**\n * Delete content model. Should not allow deletion if there are entries connected to it.\n */\n deleteModel: (modelId: string) => Promise<void>;\n /**\n * Get a instance of CmsModelManager for given content modelId.\n *\n * @see CmsModelManager\n */\n getModelManager: (model: CmsModel | string) => Promise<CmsModelManager>;\n /**\n * Get all content model managers mapped by modelId.\n * @see CmsModelManager\n */\n getManagers: () => Map<string, CmsModelManager>;\n /**\n * Events.\n */\n onBeforeModelCreate: Topic<BeforeModelCreateTopicParams>;\n onAfterModelCreate: Topic<AfterModelCreateTopicParams>;\n onBeforeModelCreateFrom: Topic<BeforeModelCreateFromTopicParams>;\n onAfterModelCreateFrom: Topic<AfterModelCreateFromTopicParams>;\n onBeforeModelUpdate: Topic<BeforeModelUpdateTopicParams>;\n onAfterModelUpdate: Topic<AfterModelUpdateTopicParams>;\n onBeforeModelDelete: Topic<BeforeModelDeleteTopicParams>;\n onAfterModelDelete: Topic<AfterModelDeleteTopicParams>;\n}\n\n/**\n * Available statuses for content entry.\n *\n * @category CmsEntry\n */\ntype CmsEntryStatus =\n | \"published\"\n | \"unpublished\"\n | \"reviewRequested\"\n | \"changesRequested\"\n | \"draft\";\n\nexport interface CmsEntryListWhereRef {\n id?: string;\n id_in?: string[];\n id_not?: string;\n id_not_in?: string[];\n entryId?: string;\n entryId_not?: string;\n entryId_in?: string[];\n entryId_not_in?: string[];\n}\n/**\n * Entry listing where params.\n *\n * @category CmsEntry\n * @category GraphQL params\n */\nexport interface CmsEntryListWhere {\n /**\n * Fields.\n */\n id?: string;\n id_in?: string[];\n id_not?: string;\n id_not_in?: string[];\n /**\n * Generated ID without the version.\n */\n entryId?: string;\n entryId_not?: string;\n entryId_in?: string[];\n entryId_not_in?: string[];\n /**\n * Entry is owned by whom?\n *\n * Can be sent via the API or set internal if user can see only their own entries.\n */\n ownedBy?: string;\n ownedBy_not?: string;\n ownedBy_in?: string[];\n ownedBy_not_in?: string[];\n /**\n * Who created the entry?\n */\n createdBy?: string;\n createdBy_not?: string;\n createdBy_in?: string[];\n createdBy_not_in?: string[];\n /**\n * Version of the entry.\n *\n * It is not meant to be used via the API.\n * @internal\n */\n version?: number;\n version_lt?: number;\n version_gt?: number;\n /**\n * Each operations implementation MUST determine how to use this field.\n * In SQL it can be published field and in DynamoDB can be a secondary key.\n *\n * It is not meant to be used via the API.\n * @internal\n */\n published?: boolean;\n /**\n * Each operations implementation MUST determine how to use this field.\n * In SQL it can be published field and in DynamoDB can be a secondary key.\n *\n * It is not meant to be used via the API.\n * @internal\n */\n latest?: boolean;\n /**\n * Search for exact locale.\n * This will most likely be populated, but leave it as optional.\n */\n locale?: string;\n /**\n * Exact tenant. No multi-tenancy search.\n */\n tenant: string;\n /**\n * Can be reference field or, actually, anything else.\n */\n [key: string]: any | CmsEntryListWhereRef;\n}\n\n/**\n * Entry listing sort.\n *\n * @category CmsEntry\n * @category GraphQL params\n */\nexport type CmsEntryListSort = string[];\n\n/**\n * Get entry GraphQL resolver params.\n *\n * @category CmsEntry\n * @category GraphQL params\n */\nexport interface CmsEntryGetParams {\n where: CmsEntryListWhere;\n sort?: CmsEntryListSort;\n}\n\n/**\n * List entries GraphQL resolver params.\n *\n * @category CmsEntry\n * @category GraphQL params\n */\nexport interface CmsEntryListParams {\n where: CmsEntryListWhere;\n sort?: CmsEntryListSort;\n limit?: number;\n after?: string | null;\n}\n\n/**\n * Meta information for GraphQL output.\n *\n * @category CmsEntry\n * @category GraphQL output\n */\nexport interface CmsEntryMeta {\n /**\n * A cursor for pagination.\n */\n cursor: string | null;\n /**\n * Is there more items to load?\n */\n hasMoreItems: boolean;\n /**\n * Total count of the items in the storage.\n */\n totalCount: number;\n}\n\nexport interface BeforeEntryCreateTopicParams {\n input: CreateCmsEntryInput;\n entry: CmsEntry;\n model: CmsModel;\n}\nexport interface AfterEntryCreateTopicParams {\n input: CreateCmsEntryInput;\n entry: CmsEntry;\n model: CmsModel;\n storageEntry: CmsEntry;\n}\n\nexport interface BeforeEntryCreateRevisionTopicParams {\n input: CreateFromCmsEntryInput;\n entry: CmsEntry;\n original: CmsEntry;\n model: CmsModel;\n}\n\nexport interface AfterEntryCreateRevisionTopicParams {\n input: CreateFromCmsEntryInput;\n entry: CmsEntry;\n original: CmsEntry;\n model: CmsModel;\n storageEntry: CmsEntry;\n}\n\nexport interface BeforeEntryUpdateTopicParams {\n input: UpdateCmsEntryInput;\n original: CmsEntry;\n entry: CmsEntry;\n model: CmsModel;\n}\nexport interface AfterEntryUpdateTopicParams {\n input: UpdateCmsEntryInput;\n original: CmsEntry;\n entry: CmsEntry;\n model: CmsModel;\n storageEntry: CmsEntry;\n}\n\nexport interface BeforeEntryPublishTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n}\n\nexport interface AfterEntryPublishTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n storageEntry: CmsEntry;\n}\n\nexport interface BeforeEntryUnpublishTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n}\n\nexport interface AfterEntryUnpublishTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n storageEntry: CmsEntry;\n}\n\nexport interface BeforeEntryRequestChangesTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n}\n\nexport interface AfterEntryRequestChangesTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n storageEntry: CmsEntry;\n}\n\nexport interface BeforeEntryRequestReviewTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n}\n\nexport interface AfterEntryRequestReviewTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n storageEntry: CmsEntry;\n}\n\nexport interface BeforeEntryDeleteTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n}\nexport interface AfterEntryDeleteTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n}\n\nexport interface BeforeEntryDeleteRevisionTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n}\nexport interface AfterEntryDeleteRevisionTopicParams {\n entry: CmsEntry;\n model: CmsModel;\n}\n\nexport interface BeforeEntryGetTopicParams {\n model: CmsModel;\n where: CmsEntryListWhere;\n}\n\nexport interface BeforeEntryListTopicParams {\n where: CmsEntryListWhere;\n model: CmsModel;\n}\n\n/**\n * @category Context\n * @category CmsEntry\n */\nexport interface CreateCmsEntryInput {\n [key: string]: any;\n}\n\n/**\n * @category Context\n * @category CmsEntry\n */\nexport interface CreateFromCmsEntryInput {\n [key: string]: any;\n}\n\n/**\n * @category Context\n * @category CmsEntry\n */\nexport interface UpdateCmsEntryInput {\n [key: string]: any;\n}\n/**\n * Cms Entry CRUD methods in the context.\n *\n * @category Context\n * @category CmsEntry\n */\nexport interface CmsEntryContext {\n /**\n * Get a single content entry for a model.\n */\n getEntry: (model: CmsModel, params: CmsEntryGetParams) => Promise<CmsEntry | null>;\n /**\n * Get a list of entries for a model by a given ID (revision).\n */\n getEntriesByIds: (model: CmsModel, revisions: string[]) => Promise<CmsEntry[]>;\n /**\n * Get the entry for a model by a given ID.\n */\n getEntryById: (model: CmsModel, revision: string) => Promise<CmsEntry>;\n /**\n * List entries for a model. Internal method used by get, listLatest and listPublished.\n */\n listEntries: (\n model: CmsModel,\n params: CmsEntryListParams\n ) => Promise<[CmsEntry[], CmsEntryMeta]>;\n /**\n * Lists latest entries. Used for manage API.\n */\n listLatestEntries: (\n model: CmsModel,\n params?: CmsEntryListParams\n ) => Promise<[CmsEntry[], CmsEntryMeta]>;\n /**\n * List published entries. Used for read API.\n */\n listPublishedEntries: (\n model: CmsModel,\n params?: CmsEntryListParams\n ) => Promise<[CmsEntry[], CmsEntryMeta]>;\n /**\n * List published entries by IDs.\n */\n getPublishedEntriesByIds: (model: CmsModel, ids: string[]) => Promise<CmsEntry[]>;\n /**\n * List latest entries by IDs.\n */\n getLatestEntriesByIds: (model: CmsModel, ids: string[]) => Promise<CmsEntry[]>;\n /**\n * Create a new content entry.\n */\n createEntry: (model: CmsModel, input: CreateCmsEntryInput) => Promise<CmsEntry>;\n /**\n * Create a new entry from already existing entry.\n */\n createEntryRevisionFrom: (\n model: CmsModel,\n id: string,\n input: CreateFromCmsEntryInput\n ) => Promise<CmsEntry>;\n /**\n * Update existing entry.\n */\n updateEntry: (model: CmsModel, id: string, input: UpdateCmsEntryInput) => Promise<CmsEntry>;\n /**\n * Method that republishes entry with given identifier.\n * @internal\n */\n republishEntry: (model: CmsModel, id: string) => Promise<CmsEntry>;\n /**\n * Delete only a certain revision of the entry.\n */\n deleteEntryRevision: (model: CmsModel, id: string) => Promise<void>;\n /**\n * Delete entry with all its revisions.\n */\n deleteEntry: (model: CmsModel, id: string) => Promise<void>;\n /**\n * Publish entry.\n */\n publishEntry: (model: CmsModel, id: string) => Promise<CmsEntry>;\n /**\n * Unpublish entry.\n */\n unpublishEntry: (model: CmsModel, id: string) => Promise<CmsEntry>;\n /**\n * Request a review for the entry.\n */\n requestEntryReview: (model: CmsModel, id: string) => Promise<CmsEntry>;\n /**\n * Request changes for the entry.\n */\n requestEntryChanges: (model: CmsModel, id: string) => Promise<CmsEntry>;\n /**\n * Get all entry revisions.\n */\n getEntryRevisions: (model: CmsModel, id: string) => Promise<CmsEntry[]>;\n /**\n * Events.\n */\n onBeforeEntryCreate: Topic<BeforeEntryCreateTopicParams>;\n onAfterEntryCreate: Topic<AfterEntryCreateTopicParams>;\n onBeforeEntryCreateRevision: Topic<BeforeEntryCreateRevisionTopicParams>;\n onAfterEntryCreateRevision: Topic<AfterEntryCreateRevisionTopicParams>;\n onBeforeEntryUpdate: Topic<BeforeEntryUpdateTopicParams>;\n onAfterEntryUpdate: Topic<AfterEntryUpdateTopicParams>;\n onBeforeEntryDelete: Topic<BeforeEntryDeleteTopicParams>;\n onAfterEntryDelete: Topic<AfterEntryDeleteTopicParams>;\n onBeforeEntryDeleteRevision: Topic<BeforeEntryDeleteRevisionTopicParams>;\n onAfterEntryDeleteRevision: Topic<AfterEntryDeleteRevisionTopicParams>;\n onBeforeEntryPublish: Topic<BeforeEntryPublishTopicParams>;\n onAfterEntryPublish: Topic<AfterEntryPublishTopicParams>;\n onBeforeEntryUnpublish: Topic<BeforeEntryUnpublishTopicParams>;\n onAfterEntryUnpublish: Topic<AfterEntryUnpublishTopicParams>;\n onBeforeEntryRequestChanges: Topic<BeforeEntryRequestChangesTopicParams>;\n onAfterEntryRequestChanges: Topic<AfterEntryRequestChangesTopicParams>;\n onBeforeEntryRequestReview: Topic<BeforeEntryRequestReviewTopicParams>;\n onAfterEntryRequestReview: Topic<AfterEntryRequestReviewTopicParams>;\n onBeforeEntryGet: Topic<BeforeEntryGetTopicParams>;\n onBeforeEntryList: Topic<BeforeEntryListTopicParams>;\n}\n\n/**\n * Parameters for CmsEntryResolverFactory.\n *\n * @category GraphQL resolver\n * @category CmsEntry\n */\ninterface CmsEntryResolverFactoryParams {\n model: CmsModel;\n}\n\n/**\n * A type for EntryResolvers. Used when creating get, list, update, publish, ...etc.\n *\n * @category GraphQL resolver\n * @category CmsEntry\n */\nexport type CmsEntryResolverFactory<TSource = any, TArgs = any, TContext = CmsContext> = {\n (params: CmsEntryResolverFactoryParams): GraphQLFieldResolver<TSource, TArgs, TContext>;\n};\n\n/**\n * Settings security permission.\n *\n * @category SecurityPermission\n */\nexport interface CmsSettingsPermission extends SecurityPermission {} // eslint-disable-line\n\n/**\n * A base security permission for CMS.\n *\n * @category SecurityPermission\n */\nexport interface BaseCmsSecurityPermission extends SecurityPermission {\n own?: boolean;\n rwd: string | number;\n}\n/**\n * A security permission for content model.\n *\n * @category SecurityPermission\n * @category CmsModel\n */\nexport interface CmsModelPermission extends BaseCmsSecurityPermission {\n /**\n * A object representing `key: model.modelId` values where key is locale code.\n */\n models?: {\n [key: string]: string[];\n };\n /**\n * A object representing `key: group.id` values where key is locale code.\n */\n groups?: {\n [key: string]: string[];\n };\n}\n\n/**\n * The security permission for content model groups.\n *\n * @category SecurityPermission\n * @category CmsGroup\n */\nexport interface CmsGroupPermission extends BaseCmsSecurityPermission {\n /**\n * A object representing `key: group.id` values where key is locale code.\n */\n groups?: {\n [key: string]: string[];\n };\n}\n\n/**\n * The security permission for content entry.\n *\n * @category SecurityPermission\n * @category CmsEntry\n */\nexport interface CmsEntryPermission extends BaseCmsSecurityPermission {\n pw?: string;\n /**\n * A object representing `key: model.modelId` values where key is locale code.\n */\n models?: {\n [key: string]: string[];\n };\n /**\n * A object representing `key: group.id` values where key is locale code.\n */\n groups?: {\n [key: string]: string[];\n };\n}\n\nexport interface CmsGroupStorageOperationsGetParams {\n id: string;\n tenant: string;\n locale: string;\n}\n\nexport interface CmsGroupStorageOperationsListWhereParams {\n tenant: string;\n locale: string;\n [key: string]: any;\n}\nexport interface CmsGroupStorageOperationsListParams {\n where: CmsGroupStorageOperationsListWhereParams;\n sort?: string[];\n}\n\nexport interface CmsGroupStorageOperationsCreateParams {\n input: CmsGroupCreateInput;\n group: CmsGroup;\n}\n\nexport interface CmsGroupStorageOperationsUpdateParams {\n original: CmsGroup;\n group: CmsGroup;\n input: CmsGroupUpdateInput;\n}\n\nexport interface CmsGroupStorageOperationsDeleteParams {\n group: CmsGroup;\n}\n\n/**\n * Description of the CmsGroup CRUD operations.\n * If user wants to add another database to the application, this is how it is done.\n * This is just plain read, update, write, delete and list - no authentication or permission checks.\n */\nexport interface CmsGroupStorageOperations {\n /**\n * Gets content model group by given id.\n */\n get: (params: CmsGroupStorageOperationsGetParams) => Promise<CmsGroup | null>;\n /**\n * List all content model groups. Filterable via params.\n */\n list: (params: CmsGroupStorageOperationsListParams) => Promise<CmsGroup[]>;\n /**\n * Create a new content model group.\n */\n create: (params: CmsGroupStorageOperationsCreateParams) => Promise<CmsGroup>;\n /**\n * Update existing content model group.\n */\n update: (params: CmsGroupStorageOperationsUpdateParams) => Promise<CmsGroup>;\n /**\n * Delete the content model group.\n */\n delete: (params: CmsGroupStorageOperationsDeleteParams) => Promise<CmsGroup>;\n}\n\nexport interface CmsModelStorageOperationsGetParams {\n tenant: string;\n locale: string;\n modelId: string;\n}\n\nexport interface CmsModelStorageOperationsListWhereParams {\n tenant: string;\n locale: string;\n [key: string]: string;\n}\n\nexport interface CmsModelStorageOperationsListParams {\n where: CmsModelStorageOperationsListWhereParams;\n}\n\nexport interface CmsModelStorageOperationsCreateParams {\n input: CmsModelCreateInput;\n model: CmsModel;\n}\n\nexport interface CmsModelStorageOperationsUpdateParams {\n original: CmsModel;\n model: CmsModel;\n input: CmsModelUpdateInput;\n}\n\nexport interface CmsModelStorageOperationsDeleteParams {\n model: CmsModel;\n}\n\n/**\n * Description of the CmsModel storage operations.\n * If user wants to add another database to the application, this is how it is done.\n * This is just plain read, update, write, delete and list - no authentication or permission checks.\n */\nexport interface CmsModelStorageOperations {\n /**\n * Gets content model by given id.\n */\n get: (params: CmsModelStorageOperationsGetParams) => Promise<CmsModel | null>;\n /**\n * List all content models. Filterable via params.\n */\n list: (params: CmsModelStorageOperationsListParams) => Promise<CmsModel[]>;\n /**\n * Create a new content model.\n */\n create: (params: CmsModelStorageOperationsCreateParams) => Promise<CmsModel>;\n /**\n * Update existing content model.\n */\n update: (params: CmsModelStorageOperationsUpdateParams) => Promise<CmsModel>;\n /**\n * Delete the content model.\n */\n delete: (params: CmsModelStorageOperationsDeleteParams) => Promise<CmsModel>;\n}\n\nexport interface CmsEntryStorageOperationsGetParams {\n where: CmsEntryListWhere;\n sort?: CmsEntryListSort;\n limit?: number;\n}\n\nexport interface CmsEntryStorageOperationsListParams {\n where: CmsEntryListWhere;\n sort?: CmsEntryListSort;\n limit?: number;\n after?: string | null;\n}\n\nexport interface CmsEntryStorageOperationsCreateParams<\n T extends CmsStorageEntry = CmsStorageEntry\n> {\n /**\n * Input received from the user.\n */\n input: Record<string, any>;\n /**\n * Real entry, with no transformations on it.\n */\n entry: CmsEntry;\n /**\n * Entry prepared for the storage.\n */\n storageEntry: T;\n}\n\nexport interface CmsEntryStorageOperationsCreateRevisionFromParams<\n T extends CmsStorageEntry = CmsStorageEntry\n> {\n /**\n * The entry we are creating new one from.\n */\n originalEntry: CmsEntry;\n /**\n * The entry we are creating new one from, directly from storage, with transformations on it.\n */\n originalStorageEntry: T;\n /**\n * Latest entry, used to calculate the new version.\n */\n latestEntry: CmsEntry | null;\n /**\n * Latest entry, used to calculate the new version, directly from storage, with transformations.\n */\n latestStorageEntry: T | null;\n /**\n * Real entry, with no transformations on it.\n */\n entry: CmsEntry;\n /**\n * Entry prepared for the storage.\n */\n storageEntry: T;\n}\n\nexport interface CmsEntryStorageOperationsUpdateParams<\n T extends CmsStorageEntry = CmsStorageEntry\n> {\n /**\n * Input received from the user.\n */\n input: Record<string, any>;\n /**\n * Used to compare IDs, versions and passed into storage operations to be used if required.\n */\n originalEntry: CmsEntry;\n /**\n * Directly from storage, with transformations on it.\n */\n originalStorageEntry: T;\n /**\n * Real entry, with no transformations on it.\n */\n entry: CmsEntry;\n /**\n * Entry prepared for the storage.\n */\n storageEntry: T;\n}\n\nexport interface CmsEntryStorageOperationsDeleteRevisionParams<\n T extends CmsStorageEntry = CmsStorageEntry\n> {\n /**\n * Entry that was deleted.\n */\n entryToDelete: CmsEntry;\n /**\n * Entry that was deleted, directly from storage, with transformations.\n */\n storageEntryToDelete: T;\n /**\n * Entry that was set as latest.\n */\n entryToSetAsLatest: CmsEntry | null;\n /**\n * Entry that was set as latest, directly from storage, with transformations.\n */\n storageEntryToSetAsLatest: T | null;\n}\n\nexport interface CmsEntryStorageOperationsDeleteParams<\n T extends CmsStorageEntry = CmsStorageEntry\n> {\n /**\n * Entry that is going to be deleted.\n */\n entry: CmsEntry;\n /**\n * Entry that is going to be deleted, directly from storage.\n */\n storageEntry: T;\n}\n\nexport interface CmsEntryStorageOperationsPublishParams<\n T extends CmsStorageEntry = CmsStorageEntry\n> {\n /**\n * The entry record before it was published.\n */\n originalEntry: CmsEntry;\n /**\n * Directly from storage, with transformations on it.\n */\n originalStorageEntry: T;\n /**\n * The modified entry that is going to be saved as published.\n * Entry is in its original form.\n */\n entry: CmsEntry;\n /**\n * The modified entry and prepared for the storage.\n */\n storageEntry: T;\n}\n\nexport interface CmsEntryStorageOperationsUnpublishParams<\n T extends CmsStorageEntry = CmsStorageEntry\n> {\n /**\n * The entry record before it was unpublished.\n */\n originalEntry: CmsEntry;\n /**\n * The entry record before it was unpublished, with transformations on it.\n */\n originalStorageEntry: T;\n /**\n * The modified entry that is going to be saved as unpublished.\n */\n entry: CmsEntry;\n /**\n * The modified entry that is going to be saved as unpublished, with transformations on it.\n */\n storageEntry: T;\n}\n\nexport interface CmsEntryStorageOperationsRequestChangesParams<\n T extends CmsStorageEntry = CmsStorageEntry\n> {\n /**\n * Entry data updated with the required properties.\n */\n entry: CmsEntry;\n /**\n * Entry that is prepared for the storageOperations, with the transformations.\n */\n storageEntry: T;\n /**\n * Original entry from the storage.\n */\n originalEntry: CmsEntry;\n /**\n * Original entry to be updated, directly from storage, with the transformations.\n */\n originalStorageEntry: T;\n}\n\nexport interface CmsEntryStorageOperationsRequestReviewParams<\n T extends CmsStorageEntry = CmsStorageEntry\n> {\n /**\n * Entry that is prepared for the storageOperations.\n */\n entry: CmsEntry;\n /**\n * Entry that is prepared for the storageOperations, with the transformations.\n */\n storageEntry: T;\n /**\n * Original entry from the storage.\n */\n originalEntry: CmsEntry;\n /**\n * Original entry to be updated, directly from storage, with the transformations.\n */\n originalStorageEntry: T;\n}\n\nexport interface CmsEntryStorageOperationsGetByIdsParams {\n ids: readonly string[];\n}\n\nexport interface CmsEntryStorageOperationsGetLatestByIdsParams {\n ids: readonly string[];\n}\n\nexport interface CmsEntryStorageOperationsGetPublishedByIdsParams {\n ids: readonly string[];\n}\n\nexport interface CmsEntryStorageOperationsGetRevisionsParams {\n id: string;\n}\n\nexport interface CmsEntryStorageOperationsGetRevisionParams {\n id: string;\n}\n\nexport interface CmsEntryStorageOperationsGetPublishedRevisionParams {\n id: string;\n}\nexport interface CmsEntryStorageOperationsGetLatestRevisionParams {\n id: string;\n}\n\nexport interface CmsEntryStorageOperationsGetPreviousRevisionParams {\n entryId: string;\n version: number;\n}\n\nexport interface CmsEntryStorageOperationsListResponse<\n T extends CmsStorageEntry = CmsStorageEntry\n> {\n /**\n * Has more items to load with the current filtering?\n */\n hasMoreItems: boolean;\n /**\n * Items loaded with current filtering.\n */\n items: T[];\n /**\n * Pointer for where to start the new item set.\n */\n cursor: string | null;\n /**\n * Total amount of items with the current filter.\n */\n totalCount: number;\n}\n\n/**\n * Description of the CmsModel storage operations.\n * If user wants to add another database to the application, this is how it is done.\n * This is just plain read, update, write, delete and list - no authentication or permission checks.\n *\n *\n * @category StorageOperations\n * @category CmsEntry\n */\nexport interface CmsEntryStorageOperations<T extends CmsStorageEntry = CmsStorageEntry> {\n /**\n * Get all the entries of the ids.\n */\n getByIds: (model: CmsModel, params: CmsEntryStorageOperationsGetByIdsParams) => Promise<T[]>;\n /**\n * Get all the published entries of the ids.\n */\n getPublishedByIds: (\n model: CmsModel,\n params: CmsEntryStorageOperationsGetPublishedByIdsParams\n ) => Promise<T[]>;\n /**\n * Get all the latest entries of the ids.\n */\n getLatestByIds: (\n model: CmsModel,\n params: CmsEntryStorageOperationsGetLatestByIdsParams\n ) => Promise<T[]>;\n /**\n * Get all revisions of the given entry id.\n */\n getRevisions: (\n model: CmsModel,\n params: CmsEntryStorageOperationsGetRevisionsParams\n ) => Promise<T[]>;\n /**\n * Get all revisions of all of the given IDs.\n */\n // getAllRevisionsByIds: (\n // model: CmsModel,\n // params: CmsEntryStorageOperationsGetAllRevisionsParams\n // ) => Promise<T[]>;\n /**\n * Get the entry by the given revision id.\n */\n getRevisionById: (\n model: CmsModel,\n params: CmsEntryStorageOperationsGetRevisionParams\n ) => Promise<T | null>;\n /**\n * Get the published entry by given entryId.\n */\n getPublishedRevisionByEntryId: (\n model: CmsModel,\n params: CmsEntryStorageOperationsGetPublishedRevisionParams\n ) => Promise<T | null>;\n /**\n * Get the latest entry by given entryId.\n */\n getLatestRevisionByEntryId: (\n model: CmsModel,\n params: CmsEntryStorageOperationsGetLatestRevisionParams\n ) => Promise<T | null>;\n /**\n * Get the revision of the entry before given one.\n */\n getPreviousRevision: (\n model: CmsModel,\n params: CmsEntryStorageOperationsGetPreviousRevisionParams\n ) => Promise<T | null>;\n /**\n * Gets entry by given params.\n */\n get: (model: CmsModel, params: CmsEntryStorageOperationsGetParams) => Promise<T | null>;\n /**\n * List all entries. Filterable via params.\n */\n list: (\n model: CmsModel,\n params: CmsEntryStorageOperationsListParams\n ) => Promise<CmsEntryStorageOperationsListResponse<T>>;\n /**\n * Create a new entry.\n */\n create: (model: CmsModel, params: CmsEntryStorageOperationsCreateParams<T>) => Promise<T>;\n /**\n * Create a new entry from existing one.\n */\n createRevisionFrom: (\n model: CmsModel,\n params: CmsEntryStorageOperationsCreateRevisionFromParams<T>\n ) => Promise<T>;\n /**\n * Update existing entry.\n */\n update: (model: CmsModel, params: CmsEntryStorageOperationsUpdateParams<T>) => Promise<T>;\n /**\n * Delete the entry revision.\n */\n deleteRevision: (\n model: CmsModel,\n params: CmsEntryStorageOperationsDeleteRevisionParams<T>\n ) => Promise<void>;\n /**\n * Delete the entry.\n */\n delete: (model: CmsModel, params: CmsEntryStorageOperationsDeleteParams<T>) => Promise<void>;\n /**\n * Publish the entry.\n */\n publish: (model: CmsModel, params: CmsEntryStorageOperationsPublishParams<T>) => Promise<T>;\n /**\n * Unpublish the entry.\n */\n unpublish: (model: CmsModel, params: CmsEntryStorageOperationsUnpublishParams<T>) => Promise<T>;\n /**\n * Request changes the entry.\n */\n requestChanges: (\n model: CmsModel,\n params: CmsEntryStorageOperationsRequestChangesParams<T>\n ) => Promise<T>;\n /**\n * Request review the entry.\n */\n requestReview: (\n model: CmsModel,\n params: CmsEntryStorageOperationsRequestReviewParams<T>\n ) => Promise<CmsEntry>;\n}\n\nexport enum CONTENT_ENTRY_STATUS {\n DRAFT = \"draft\",\n PUBLISHED = \"published\",\n UNPUBLISHED = \"unpublished\",\n CHANGES_REQUESTED = \"changesRequested\",\n REVIEW_REQUESTED = \"reviewRequested\"\n}\n\nexport interface CmsSettingsStorageOperationsGetParams {\n locale: string;\n tenant: string;\n}\n\nexport interface CmsSettingsStorageOperationsCreateParams {\n settings: CmsSettings;\n}\n\nexport interface CmsSettingsStorageOperationsUpdateParams {\n original: CmsSettings;\n settings: CmsSettings;\n}\n\nexport interface CmsSettingsStorageOperations {\n /**\n * Get the settings from the storage.\n */\n get: (params: CmsSettingsStorageOperationsGetParams) => Promise<CmsSettings | null>;\n /**\n * Create settings in the storage.\n */\n create: (params: CmsSettingsStorageOperationsCreateParams) => Promise<CmsSettings>;\n /**\n * Update the settings in the storage.\n */\n update: (params: CmsSettingsStorageOperationsUpdateParams) => Promise<CmsSettings>;\n}\n\nexport interface CmsSystem {\n version?: string;\n readAPIKey?: string;\n /**\n * System tenant.\n */\n tenant: string;\n}\n\nexport interface CmsSystemStorageOperationsGetParams {\n tenant: string;\n}\n\nexport interface CmsSystemStorageOperationsCreateParams {\n system: CmsSystem;\n}\n\nexport interface CmsSystemStorageOperationsUpdateParams {\n system: CmsSystem;\n original: CmsSystem;\n}\n\nexport interface CmsSystemStorageOperations {\n /**\n * Get the system data.\n */\n get: (params: CmsSystemStorageOperationsGetParams) => Promise<CmsSystem | null>;\n /**\n * Create the system info in the storage.\n */\n create: (params: CmsSystemStorageOperationsCreateParams) => Promise<CmsSystem>;\n /**\n * Update the system info in the storage.\n */\n update: (params: CmsSystemStorageOperationsUpdateParams) => Promise<CmsSystem>;\n}\n\nexport interface HeadlessCmsStorageOperations {\n system: CmsSystemStorageOperations;\n settings: CmsSettingsStorageOperations;\n groups: CmsGroupStorageOperations;\n models: CmsModelStorageOperations;\n entries: CmsEntryStorageOperations;\n\n init?: (cms: HeadlessCms) => Promise<void>;\n /**\n * Plugins to be attached to the main context.\n */\n plugins?: Plugin[] | Plugin[][];\n /**\n * An upgrade to run if necessary.\n */\n upgrade?: UpgradePlugin | null;\n}\n"]}
package/utils.d.ts CHANGED
@@ -1,19 +1,16 @@
1
- import { SecurityPermission } from "@webiny/api-security/types";
2
- import { CmsModel, CmsContext, CreatedBy, CmsGroupPermission, CmsGroup } from "./types";
3
- export declare const hasRwd: (permission: SecurityPermission, rwd: string) => boolean;
4
- export declare const hasPw: (permission: SecurityPermission, pw: string) => boolean;
5
- export declare const checkPermissions: <TPermission extends SecurityPermission = SecurityPermission>(context: CmsContext, name: string, check?: {
6
- rwd?: string;
7
- pw?: string;
8
- }) => Promise<TPermission>;
9
- export declare const checkOwnership: (context: CmsContext, permission: SecurityPermission, record: {
1
+ import { CmsModel, CmsContext, CreatedBy, CmsGroupPermission, CmsGroup, CmsEntryPermission, BaseCmsSecurityPermission } from "./types";
2
+ export declare const hasRwd: (permission: BaseCmsSecurityPermission, rwd: string) => boolean;
3
+ export declare const hasPw: (permission: CmsEntryPermission, pw: string) => boolean;
4
+ export declare const checkPermissions: <TPermission extends BaseCmsSecurityPermission = BaseCmsSecurityPermission>(context: CmsContext, name: string, check?: {
5
+ rwd?: string | undefined;
6
+ pw?: string | undefined;
7
+ } | undefined) => Promise<TPermission>;
8
+ interface OwnableRecord {
10
9
  createdBy?: CreatedBy;
11
10
  ownedBy?: CreatedBy;
12
- }) => void;
13
- export declare const validateOwnership: (context: CmsContext, permission: SecurityPermission, record: {
14
- createdBy?: CreatedBy;
15
- ownedBy?: CreatedBy;
16
- }) => boolean;
11
+ }
12
+ export declare const checkOwnership: (context: CmsContext, permission: BaseCmsSecurityPermission, record: OwnableRecord) => void;
13
+ export declare const validateOwnership: (context: CmsContext, permission: BaseCmsSecurityPermission, record: OwnableRecord) => boolean;
17
14
  /**
18
15
  * model access is checking for both specific model or group access
19
16
  * if permission has specific models set as access pattern then groups will not matter (although both can be set)
@@ -23,3 +20,4 @@ export declare const validateModelAccess: (context: CmsContext, model: CmsModel)
23
20
  export declare const validateGroupAccess: (context: CmsContext, permission: CmsGroupPermission, group: CmsGroup) => boolean;
24
21
  export declare const toSlug: (text: string) => string;
25
22
  export declare const filterAsync: <T = Record<string, any>>(items: T[], predicate: (param: T) => Promise<boolean>) => Promise<T[]>;
23
+ export {};
package/utils.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["utils.ts"],"names":["hasRwd","permission","rwd","includes","hasPw","pw","isCustom","Object","keys","length","PW","r","c","p","u","RWD","w","d","checkPermissions","context","name","check","contentPermission","security","getPermission","NotAuthorizedError","data","reason","code","cms","getLocale","Array","isArray","locales","checkOwnership","record","own","identity","getIdentity","owner","id","creator","validateOwnership","checkModelAccess","model","validateModelAccess","modelId","modelGroupPermission","groups","modelPermission","models","locale","group","validateGroupAccess","toSlug","text","replacement","lower","remove","filterAsync","items","predicate","filteredItems","i","item","valid","push"],"mappings":"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","sourcesContent":["import slugify from \"slugify\";\nimport { NotAuthorizedError } from \"@webiny/api-security\";\n\nimport {\n CmsModelPermission,\n CmsModel,\n CmsContext,\n CreatedBy,\n CmsGroupPermission,\n CmsGroup,\n CmsEntryPermission,\n BaseCmsSecurityPermission\n} from \"~/types\";\n\nexport const hasRwd = (permission: BaseCmsSecurityPermission, rwd: string): boolean => {\n if (typeof permission.rwd !== \"string\") {\n return true;\n }\n\n return permission.rwd.includes(rwd);\n};\n\nexport const hasPw = (permission: CmsEntryPermission, pw: string): boolean => {\n const isCustom = Object.keys(permission).length > 1; // \"name\" key is always present\n\n if (!isCustom) {\n // Means it's a \"full-access\" permission.\n return true;\n }\n\n if (typeof permission.pw !== \"string\") {\n return false;\n }\n\n return permission.pw.includes(pw);\n};\n\nconst PW: Record<string, string> = {\n r: \"request review\",\n c: \"request change\",\n p: \"publish\",\n u: \"unpublish\"\n};\n\nconst RWD: Record<string, string> = {\n r: \"read\",\n w: \"write\",\n d: \"delete\"\n};\n\nexport const checkPermissions = async <\n TPermission extends BaseCmsSecurityPermission = BaseCmsSecurityPermission\n>(\n context: CmsContext,\n name: string,\n check?: { rwd?: string; pw?: string }\n): Promise<TPermission> => {\n // Check if user is allowed to edit content in current language\n const contentPermission: any = await context.security.getPermission(\"content.i18n\");\n\n if (!contentPermission) {\n throw new NotAuthorizedError({\n data: {\n reason: \"Missing access to content in any locale.\"\n }\n });\n }\n\n // We need to check this manually as CMS locale comes from the URL and not the default i18n app.\n const code = context.cms.getLocale().code;\n\n // IMPORTANT: If we have a `contentPermission`, and `locales` key is NOT SET - it means the user has access to all locales.\n // However, if the the `locales` IS SET - check that it contains the required locale.\n if (Array.isArray(contentPermission.locales) && !contentPermission.locales.includes(code)) {\n throw new NotAuthorizedError({\n data: {\n reason: `Not allowed to access content in \"${code}.\"`\n }\n });\n }\n\n const permission = await context.security.getPermission<TPermission>(name);\n\n if (!permission) {\n throw new NotAuthorizedError({\n data: {\n reason: `Missing permission \"${name}\".`\n }\n });\n }\n\n if (!check) {\n return permission;\n }\n\n if (check.rwd && !hasRwd(permission, check.rwd)) {\n throw new NotAuthorizedError({\n data: {\n reason: `Not allowed to perform \"${RWD[check.rwd]}\" on \"${name}\".`\n }\n });\n }\n\n // r = request review\n // c = request change\n // p = publish\n // u = unpublish\n if (check.pw && !hasPw(permission, check.pw)) {\n throw new NotAuthorizedError({\n data: {\n reason: `Not allowed to perform \"${PW[check.pw]}\" on \"${name}\".`\n }\n });\n }\n\n return permission;\n};\n\ninterface OwnableRecord {\n createdBy?: CreatedBy;\n ownedBy?: CreatedBy;\n}\n\nexport const checkOwnership = (\n context: CmsContext,\n permission: BaseCmsSecurityPermission,\n record: OwnableRecord\n): void => {\n if (!permission.own) {\n return;\n }\n\n const identity = context.security.getIdentity();\n const owner = identity && record[\"ownedBy\"] && record[\"ownedBy\"].id === identity.id;\n const creator = identity && record[\"createdBy\"] && record[\"createdBy\"].id === identity.id;\n\n if (!owner && !creator) {\n throw new NotAuthorizedError({\n data: {\n reason: `You are not the owner of the record.`\n }\n });\n }\n};\n\nexport const validateOwnership = (\n context: CmsContext,\n permission: BaseCmsSecurityPermission,\n record: OwnableRecord\n): boolean => {\n try {\n checkOwnership(context, permission, record);\n return true;\n } catch {\n return false;\n }\n};\n/**\n * model access is checking for both specific model or group access\n * if permission has specific models set as access pattern then groups will not matter (although both can be set)\n */\nexport const checkModelAccess = async (context: CmsContext, model: CmsModel): Promise<void> => {\n if (await validateModelAccess(context, model)) {\n return;\n }\n throw new NotAuthorizedError({\n data: {\n reason: `Not allowed to access model \"${model.modelId}\".`\n }\n });\n};\nexport const validateModelAccess = async (\n context: CmsContext,\n model: CmsModel\n): Promise<boolean> => {\n const modelGroupPermission: CmsGroupPermission = await checkPermissions(\n context,\n \"cms.contentModelGroup\",\n { rwd: \"r\" }\n );\n const { groups } = modelGroupPermission;\n\n const modelPermission: CmsModelPermission = await checkPermissions(\n context,\n \"cms.contentModel\",\n {\n rwd: \"r\"\n }\n );\n const { models } = modelPermission;\n // when no models or groups defined on permission\n // it means user has access to everything\n if (!models && !groups) {\n return true;\n }\n const locale = context.cms.getLocale().code;\n // Check whether the model is question belongs to \"content model groups\" for which user has permission.\n if (groups) {\n if (\n Array.isArray(groups[locale]) === false ||\n groups[locale].includes(model.group.id) === false\n ) {\n return false;\n }\n }\n // Check whether the model is question belongs to \"content models\" for which user has permission.\n if (models) {\n if (\n Array.isArray(models[locale]) === false ||\n models[locale].includes(model.modelId) === false\n ) {\n return false;\n }\n }\n\n return true;\n};\nexport const validateGroupAccess = (\n context: CmsContext,\n permission: CmsGroupPermission,\n group: CmsGroup\n): boolean => {\n const { groups } = permission;\n // when no groups defined on permission\n // it means user has access to everything\n if (!groups) {\n return true;\n }\n const locale = context.cms.getLocale().code;\n // when there is no locale in groups, it means that no access was given\n // this happens when access control was set but no models or groups were added\n if (Array.isArray(groups[locale]) === false || groups[locale].includes(group.id) === false) {\n return false;\n }\n return true;\n};\n\nexport const toSlug = (text: string): string => {\n return slugify(text, {\n replacement: \"-\",\n lower: true,\n remove: /[*#\\?<>_\\{\\}\\[\\]+~.()'\"!:;@]/g\n });\n};\n\nexport const filterAsync = async <T = Record<string, any>>(\n items: T[],\n predicate: (param: T) => Promise<boolean>\n): Promise<T[]> => {\n const filteredItems = [];\n\n for (let i = 0; i < items.length; i++) {\n const item = items[i];\n const valid = await predicate(item);\n if (valid) {\n filteredItems.push(item);\n }\n }\n\n return filteredItems;\n};\n"]}
@@ -1,2 +0,0 @@
1
- import { CmsModelField } from "../../../types";
2
- export declare const attachRequiredFieldValue: (def: string, field: CmsModelField) => string;