@strapi/content-type-builder 5.54.0 → 5.55.0

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 (208) hide show
  1. package/dist/admin/components/AIChat/hooks/useAIFetch.js +6 -2
  2. package/dist/admin/components/AIChat/hooks/useAIFetch.js.map +1 -1
  3. package/dist/admin/components/AIChat/hooks/useAIFetch.mjs +7 -3
  4. package/dist/admin/components/AIChat/hooks/useAIFetch.mjs.map +1 -1
  5. package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.js +20 -0
  6. package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.js.map +1 -0
  7. package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.mjs +18 -0
  8. package/dist/admin/components/AIChat/hooks/usePrefetchAIToken.mjs.map +1 -0
  9. package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.js +83 -59
  10. package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.js.map +1 -1
  11. package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.mjs +86 -62
  12. package/dist/admin/components/ContentTypeBuilderNav/ContentTypeBuilderNav.mjs.map +1 -1
  13. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.js +112 -0
  14. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.js.map +1 -0
  15. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.mjs +110 -0
  16. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.mjs.map +1 -0
  17. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.js +159 -0
  18. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.js.map +1 -0
  19. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.mjs +157 -0
  20. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.mjs.map +1 -0
  21. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.js +311 -0
  22. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.js.map +1 -0
  23. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.mjs +309 -0
  24. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.mjs.map +1 -0
  25. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.js +379 -0
  26. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.js.map +1 -0
  27. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.mjs +376 -0
  28. package/dist/admin/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.mjs.map +1 -0
  29. package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.js +172 -0
  30. package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.js.map +1 -0
  31. package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.mjs +166 -0
  32. package/dist/admin/components/ContentTypeBuilderNav/hooks/useContentTypeBuilderMenu.mjs.map +1 -0
  33. package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.js +62 -0
  34. package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.js.map +1 -0
  35. package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.mjs +60 -0
  36. package/dist/admin/components/ContentTypeBuilderNav/hooks/useFolderActions.mjs.map +1 -0
  37. package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.js +145 -0
  38. package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.js.map +1 -0
  39. package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.mjs +143 -0
  40. package/dist/admin/components/ContentTypeBuilderNav/hooks/useSortableTree.mjs.map +1 -0
  41. package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.js +176 -0
  42. package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.js.map +1 -0
  43. package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.mjs +169 -0
  44. package/dist/admin/components/ContentTypeBuilderNav/lib/buildFolderTree.mjs.map +1 -0
  45. package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.js +277 -0
  46. package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.js.map +1 -0
  47. package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.mjs +273 -0
  48. package/dist/admin/components/ContentTypeBuilderNav/lib/dropProjection.mjs.map +1 -0
  49. package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.js +62 -0
  50. package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.js.map +1 -0
  51. package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.mjs +58 -0
  52. package/dist/admin/components/ContentTypeBuilderNav/lib/flatModel.mjs.map +1 -0
  53. package/dist/admin/components/DataManager/DataManagerContext.js.map +1 -1
  54. package/dist/admin/components/DataManager/DataManagerContext.mjs.map +1 -1
  55. package/dist/admin/components/DataManager/DataManagerProvider.js +70 -8
  56. package/dist/admin/components/DataManager/DataManagerProvider.js.map +1 -1
  57. package/dist/admin/components/DataManager/DataManagerProvider.mjs +70 -8
  58. package/dist/admin/components/DataManager/DataManagerProvider.mjs.map +1 -1
  59. package/dist/admin/components/DataManager/reducer.js +411 -33
  60. package/dist/admin/components/DataManager/reducer.js.map +1 -1
  61. package/dist/admin/components/DataManager/reducer.mjs +411 -33
  62. package/dist/admin/components/DataManager/reducer.mjs.map +1 -1
  63. package/dist/admin/components/DataManager/utils/cleanData.js +11 -2
  64. package/dist/admin/components/DataManager/utils/cleanData.js.map +1 -1
  65. package/dist/admin/components/DataManager/utils/cleanData.mjs +11 -2
  66. package/dist/admin/components/DataManager/utils/cleanData.mjs.map +1 -1
  67. package/dist/admin/components/DataManager/utils/contentStructure.js +150 -0
  68. package/dist/admin/components/DataManager/utils/contentStructure.js.map +1 -0
  69. package/dist/admin/components/DataManager/utils/contentStructure.mjs +133 -0
  70. package/dist/admin/components/DataManager/utils/contentStructure.mjs.map +1 -0
  71. package/dist/admin/components/FolderSelect.js +200 -0
  72. package/dist/admin/components/FolderSelect.js.map +1 -0
  73. package/dist/admin/components/FolderSelect.mjs +198 -0
  74. package/dist/admin/components/FolderSelect.mjs.map +1 -0
  75. package/dist/admin/components/FormModal/FormModal.js +23 -2
  76. package/dist/admin/components/FormModal/FormModal.js.map +1 -1
  77. package/dist/admin/components/FormModal/FormModal.mjs +23 -2
  78. package/dist/admin/components/FormModal/FormModal.mjs.map +1 -1
  79. package/dist/admin/components/FormModal/contentType/contentTypeForm.js +15 -18
  80. package/dist/admin/components/FormModal/contentType/contentTypeForm.js.map +1 -1
  81. package/dist/admin/components/FormModal/contentType/contentTypeForm.mjs +15 -18
  82. package/dist/admin/components/FormModal/contentType/contentTypeForm.mjs.map +1 -1
  83. package/dist/admin/components/FormModal/reducer.js +6 -0
  84. package/dist/admin/components/FormModal/reducer.js.map +1 -1
  85. package/dist/admin/components/FormModal/reducer.mjs +6 -0
  86. package/dist/admin/components/FormModal/reducer.mjs.map +1 -1
  87. package/dist/admin/pages/App/index.js +2 -5
  88. package/dist/admin/pages/App/index.js.map +1 -1
  89. package/dist/admin/pages/App/index.mjs +2 -5
  90. package/dist/admin/pages/App/index.mjs.map +1 -1
  91. package/dist/admin/src/components/AIChat/hooks/usePrefetchAIToken.d.ts +1 -0
  92. package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/DeleteFolderDialog.d.ts +16 -0
  93. package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/FolderNameField.d.ts +12 -0
  94. package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/FolderNavSection.d.ts +14 -0
  95. package/dist/admin/src/components/ContentTypeBuilderNav/components/FolderNav/SortableTreeRow.d.ts +38 -0
  96. package/dist/admin/src/components/ContentTypeBuilderNav/{useContentTypeBuilderMenu.d.ts → hooks/useContentTypeBuilderMenu.d.ts} +17 -7
  97. package/dist/admin/src/components/ContentTypeBuilderNav/hooks/useFolderActions.d.ts +42 -0
  98. package/dist/admin/src/components/ContentTypeBuilderNav/hooks/useSortableTree.d.ts +53 -0
  99. package/dist/admin/src/components/ContentTypeBuilderNav/lib/buildFolderTree.d.ts +42 -0
  100. package/dist/admin/src/components/ContentTypeBuilderNav/lib/dropProjection.d.ts +58 -0
  101. package/dist/admin/src/components/ContentTypeBuilderNav/lib/flatModel.d.ts +18 -0
  102. package/dist/admin/src/components/DataManager/DataManagerContext.d.ts +41 -0
  103. package/dist/admin/src/components/DataManager/reducer.d.ts +105 -1
  104. package/dist/admin/src/components/DataManager/utils/cleanData.d.ts +5 -1
  105. package/dist/admin/src/components/DataManager/utils/contentStructure.d.ts +68 -0
  106. package/dist/admin/src/components/FolderSelect.d.ts +18 -0
  107. package/dist/admin/src/components/FormModal/contentType/contentTypeForm.d.ts +0 -21
  108. package/dist/admin/src/components/FormModal/forms/forms.d.ts +0 -10
  109. package/dist/admin/src/components/FormModal/reducer.d.ts +7 -0
  110. package/dist/admin/src/utils/folderTelemetry.d.ts +5 -0
  111. package/dist/admin/translations/en.json.js +23 -0
  112. package/dist/admin/translations/en.json.js.map +1 -1
  113. package/dist/admin/translations/en.json.mjs +23 -0
  114. package/dist/admin/translations/en.json.mjs.map +1 -1
  115. package/dist/admin/utils/folderTelemetry.js +19 -0
  116. package/dist/admin/utils/folderTelemetry.js.map +1 -0
  117. package/dist/admin/utils/folderTelemetry.mjs +16 -0
  118. package/dist/admin/utils/folderTelemetry.mjs.map +1 -0
  119. package/dist/server/controllers/schema.js +1 -1
  120. package/dist/server/controllers/schema.js.map +1 -1
  121. package/dist/server/controllers/schema.mjs +1 -1
  122. package/dist/server/controllers/schema.mjs.map +1 -1
  123. package/dist/server/controllers/validation/common.js +3 -0
  124. package/dist/server/controllers/validation/common.js.map +1 -1
  125. package/dist/server/controllers/validation/common.mjs +3 -1
  126. package/dist/server/controllers/validation/common.mjs.map +1 -1
  127. package/dist/server/controllers/validation/content-structure.js +177 -0
  128. package/dist/server/controllers/validation/content-structure.js.map +1 -0
  129. package/dist/server/controllers/validation/content-structure.mjs +173 -0
  130. package/dist/server/controllers/validation/content-structure.mjs.map +1 -0
  131. package/dist/server/controllers/validation/schema.js +3 -1
  132. package/dist/server/controllers/validation/schema.js.map +1 -1
  133. package/dist/server/controllers/validation/schema.mjs +3 -1
  134. package/dist/server/controllers/validation/schema.mjs.map +1 -1
  135. package/dist/server/register.js +1 -1
  136. package/dist/server/register.js.map +1 -1
  137. package/dist/server/register.mjs +1 -1
  138. package/dist/server/register.mjs.map +1 -1
  139. package/dist/server/routes/content-api.js +4 -4
  140. package/dist/server/routes/content-api.js.map +1 -1
  141. package/dist/server/routes/content-api.mjs +4 -4
  142. package/dist/server/routes/content-api.mjs.map +1 -1
  143. package/dist/server/services/api-handler.js +37 -4
  144. package/dist/server/services/api-handler.js.map +1 -1
  145. package/dist/server/services/api-handler.mjs +36 -5
  146. package/dist/server/services/api-handler.mjs.map +1 -1
  147. package/dist/server/services/content-structure.js +174 -0
  148. package/dist/server/services/content-structure.js.map +1 -0
  149. package/dist/server/services/content-structure.mjs +172 -0
  150. package/dist/server/services/content-structure.mjs.map +1 -0
  151. package/dist/server/services/content-types.js +196 -44
  152. package/dist/server/services/content-types.js.map +1 -1
  153. package/dist/server/services/content-types.mjs +195 -45
  154. package/dist/server/services/content-types.mjs.map +1 -1
  155. package/dist/server/services/index.js +3 -1
  156. package/dist/server/services/index.js.map +1 -1
  157. package/dist/server/services/index.mjs +3 -1
  158. package/dist/server/services/index.mjs.map +1 -1
  159. package/dist/server/services/schema-builder/index.js +4 -2
  160. package/dist/server/services/schema-builder/index.js.map +1 -1
  161. package/dist/server/services/schema-builder/index.mjs +4 -2
  162. package/dist/server/services/schema-builder/index.mjs.map +1 -1
  163. package/dist/server/services/schema-builder/schema-handler.js +16 -16
  164. package/dist/server/services/schema-builder/schema-handler.js.map +1 -1
  165. package/dist/server/services/schema-builder/schema-handler.mjs +16 -16
  166. package/dist/server/services/schema-builder/schema-handler.mjs.map +1 -1
  167. package/dist/server/services/schema-mutation.js +46 -0
  168. package/dist/server/services/schema-mutation.js.map +1 -0
  169. package/dist/server/services/schema-mutation.mjs +43 -0
  170. package/dist/server/services/schema-mutation.mjs.map +1 -0
  171. package/dist/server/services/schema.js +134 -79
  172. package/dist/server/services/schema.js.map +1 -1
  173. package/dist/server/services/schema.mjs +135 -80
  174. package/dist/server/services/schema.mjs.map +1 -1
  175. package/dist/server/src/controllers/schema.d.ts.map +1 -1
  176. package/dist/server/src/controllers/validation/common.d.ts +1 -0
  177. package/dist/server/src/controllers/validation/common.d.ts.map +1 -1
  178. package/dist/server/src/controllers/validation/content-structure.d.ts +56 -0
  179. package/dist/server/src/controllers/validation/content-structure.d.ts.map +1 -0
  180. package/dist/server/src/controllers/validation/schema.d.ts +35 -0
  181. package/dist/server/src/controllers/validation/schema.d.ts.map +1 -1
  182. package/dist/server/src/index.d.ts +3 -0
  183. package/dist/server/src/index.d.ts.map +1 -1
  184. package/dist/server/src/routes/content-api.d.ts.map +1 -1
  185. package/dist/server/src/services/api-handler.d.ts +13 -1
  186. package/dist/server/src/services/api-handler.d.ts.map +1 -1
  187. package/dist/server/src/services/content-structure.d.ts +37 -0
  188. package/dist/server/src/services/content-structure.d.ts.map +1 -0
  189. package/dist/server/src/services/content-types.d.ts +4 -0
  190. package/dist/server/src/services/content-types.d.ts.map +1 -1
  191. package/dist/server/src/services/index.d.ts +4 -0
  192. package/dist/server/src/services/index.d.ts.map +1 -1
  193. package/dist/server/src/services/schema-builder/index.d.ts +3 -1
  194. package/dist/server/src/services/schema-builder/index.d.ts.map +1 -1
  195. package/dist/server/src/services/schema-builder/schema-handler.d.ts.map +1 -1
  196. package/dist/server/src/services/schema-mutation.d.ts +26 -0
  197. package/dist/server/src/services/schema-mutation.d.ts.map +1 -0
  198. package/dist/server/src/services/schema.d.ts +1 -0
  199. package/dist/server/src/services/schema.d.ts.map +1 -1
  200. package/dist/server/src/utils/index.d.ts +2 -0
  201. package/dist/server/src/utils/index.d.ts.map +1 -1
  202. package/dist/server/utils/index.js.map +1 -1
  203. package/dist/server/utils/index.mjs.map +1 -1
  204. package/package.json +6 -6
  205. package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.js +0 -157
  206. package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.js.map +0 -1
  207. package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.mjs +0 -151
  208. package/dist/admin/components/ContentTypeBuilderNav/useContentTypeBuilderMenu.mjs.map +0 -1
@@ -4,7 +4,9 @@ var _ = require('lodash');
4
4
  var fp = require('lodash/fp');
5
5
  var utils = require('@strapi/utils');
6
6
  var attributes = require('../utils/attributes.js');
7
+ var index$1 = require('../utils/index.js');
7
8
  var index = require('./schema-builder/index.js');
9
+ var schemaMutation = require('./schema-mutation.js');
8
10
  var constants = require('./constants.js');
9
11
 
10
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -12,6 +14,17 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
14
  var ___default = /*#__PURE__*/_interopDefault(_);
13
15
 
14
16
  const { ApplicationError } = utils.errors;
17
+ const isCTBOwnedApplicationContentType = (uid)=>uid.startsWith('api::');
18
+ const assertCTBOwnedApplicationContentType = (uid)=>{
19
+ if (!isCTBOwnedApplicationContentType(uid)) {
20
+ throw new ApplicationError(`Content type "${uid}" is not managed by CTB and cannot be deleted`);
21
+ }
22
+ };
23
+ const pruneFolderReferences = (uids)=>{
24
+ return index$1.getService('content-structure').commitFromUpdate({
25
+ deletedUids: new Set(uids)
26
+ });
27
+ };
15
28
  const isContentTypeVisible = (model)=>fp.getOr(true, 'pluginOptions.content-type-builder.visible', model) === true;
16
29
  const getRestrictRelationsTo = (contentType)=>{
17
30
  const { uid } = contentType;
@@ -53,12 +66,36 @@ const getRestrictRelationsTo = (contentType)=>{
53
66
  const createContentTypes = async (contentTypes)=>{
54
67
  const builder = index();
55
68
  const createdContentTypes = [];
56
- for (const contentType of contentTypes){
57
- createdContentTypes.push(await createContentType(contentType, {
58
- defaultBuilder: builder
59
- }));
69
+ const generatedApiNames = [];
70
+ let schemaAlreadyRolledBack = false;
71
+ try {
72
+ for (const contentType of contentTypes){
73
+ createdContentTypes.push(await createContentType(contentType, {
74
+ defaultBuilder: builder,
75
+ generatedApiNames,
76
+ deferEvent: true
77
+ }));
78
+ }
79
+ const schemaFilesWritten = await builder.writeFiles();
80
+ if (!schemaFilesWritten) {
81
+ schemaAlreadyRolledBack = true;
82
+ throw new ApplicationError('Invalid schema edition');
83
+ }
84
+ } catch (error) {
85
+ const apiHandler = strapi.plugin('content-type-builder').service('api-handler');
86
+ await schemaMutation.rollbackSchemaMutation({
87
+ builder,
88
+ apiHandler,
89
+ generatedApiNames,
90
+ schemaAlreadyRolledBack
91
+ });
92
+ throw error;
93
+ }
94
+ for (const contentType of createdContentTypes){
95
+ strapi.eventHub.emit('content-type.create', {
96
+ contentType
97
+ });
60
98
  }
61
- await builder.writeFiles();
62
99
  return createdContentTypes;
63
100
  };
64
101
  /**
@@ -85,19 +122,43 @@ const createContentTypes = async (contentTypes)=>{
85
122
  }
86
123
  return builder.editComponent(options);
87
124
  });
88
- // generate api skeleton
89
- await generateAPI({
90
- displayName: contentType.displayName || contentType.info.displayName,
91
- singularName: contentType.singularName,
92
- pluralName: contentType.pluralName,
93
- kind: contentType.kind
94
- });
95
- if (!options.defaultBuilder) {
96
- await builder.writeFiles();
125
+ const generatedApiNames = options.generatedApiNames ?? [];
126
+ let schemaAlreadyRolledBack = false;
127
+ try {
128
+ // Generate before writing the schema so a successful mutation retains the existing layout.
129
+ if (!contentType.plugin) {
130
+ generatedApiNames.push(contentType.singularName);
131
+ await generateAPI({
132
+ displayName: contentType.displayName || contentType.info.displayName,
133
+ singularName: contentType.singularName,
134
+ pluralName: contentType.pluralName,
135
+ kind: contentType.kind
136
+ });
137
+ }
138
+ if (!options.defaultBuilder) {
139
+ const schemaFilesWritten = await builder.writeFiles();
140
+ if (!schemaFilesWritten) {
141
+ schemaAlreadyRolledBack = true;
142
+ throw new ApplicationError('Invalid schema edition');
143
+ }
144
+ }
145
+ } catch (error) {
146
+ if (!options.defaultBuilder) {
147
+ const apiHandler = strapi.plugin('content-type-builder').service('api-handler');
148
+ await schemaMutation.rollbackSchemaMutation({
149
+ builder,
150
+ apiHandler,
151
+ generatedApiNames,
152
+ schemaAlreadyRolledBack
153
+ });
154
+ }
155
+ throw error;
156
+ }
157
+ if (!options.deferEvent) {
158
+ strapi.eventHub.emit('content-type.create', {
159
+ contentType: newContentType
160
+ });
97
161
  }
98
- strapi.eventHub.emit('content-type.create', {
99
- contentType: newContentType
100
- });
101
162
  return newContentType;
102
163
  };
103
164
  /**
@@ -123,6 +184,7 @@ const createContentTypes = async (contentTypes)=>{
123
184
  */ const editContentType = async (uid, { contentType, components = [] })=>{
124
185
  const builder = index();
125
186
  const previousSchema = builder.contentTypes.get(uid).schema;
187
+ const isPluginContentType = Boolean(builder.contentTypes.get(uid).plugin);
126
188
  const previousKind = previousSchema.kind;
127
189
  const newKind = contentType.kind || previousKind;
128
190
  // Restore non-visible attributes from previous schema
@@ -153,21 +215,48 @@ const createContentTypes = async (contentTypes)=>{
153
215
  return builder.editComponent(replaceTmpUIDs(component));
154
216
  });
155
217
  if (newKind !== previousKind) {
218
+ let schemaAlreadyRolledBack = false;
156
219
  const apiHandler = strapi.plugin('content-type-builder').service('api-handler');
157
220
  await apiHandler.backup(uid);
158
221
  try {
159
- await apiHandler.clear(uid);
160
- // generate new api skeleton
161
- await generateAPI({
162
- displayName: updatedContentType.schema.info.displayName,
163
- singularName: updatedContentType.schema.info.singularName,
164
- pluralName: updatedContentType.schema.info.pluralName,
165
- kind: updatedContentType.schema.kind
222
+ await apiHandler.clear(uid, {
223
+ preserveBackup: true
166
224
  });
167
- await builder.writeFiles();
225
+ if (!isPluginContentType) {
226
+ // generate new api skeleton
227
+ await generateAPI({
228
+ displayName: updatedContentType.schema.info.displayName,
229
+ singularName: updatedContentType.schema.info.singularName,
230
+ pluralName: updatedContentType.schema.info.pluralName,
231
+ kind: updatedContentType.schema.kind
232
+ });
233
+ }
234
+ const schemaFilesWritten = await builder.writeFiles();
235
+ if (!schemaFilesWritten) {
236
+ schemaAlreadyRolledBack = true;
237
+ throw new ApplicationError('Invalid schema edition');
238
+ }
239
+ await pruneFolderReferences([
240
+ uid
241
+ ]);
168
242
  } catch (error) {
243
+ await schemaMutation.rollbackSchemaMutation({
244
+ builder,
245
+ apiHandler,
246
+ backedUpApiUids: [
247
+ uid
248
+ ],
249
+ schemaAlreadyRolledBack
250
+ });
251
+ throw error;
252
+ }
253
+ for (const error of (await schemaMutation.finalizeSchemaMutation({
254
+ apiHandler,
255
+ backedUpApiUids: [
256
+ uid
257
+ ]
258
+ }))){
169
259
  strapi.log.error(error);
170
- await apiHandler.rollback(uid);
171
260
  }
172
261
  return updatedContentType;
173
262
  }
@@ -178,43 +267,105 @@ const createContentTypes = async (contentTypes)=>{
178
267
  return updatedContentType;
179
268
  };
180
269
  const deleteContentTypes = async (uids)=>{
270
+ uids.forEach(assertCTBOwnedApplicationContentType);
181
271
  const builder = index();
182
272
  const apiHandler = strapi.plugin('content-type-builder').service('api-handler');
183
- for (const uid of uids){
184
- await deleteContentType(uid, builder);
185
- }
186
- await builder.writeFiles();
187
- for (const uid of uids){
188
- try {
189
- await apiHandler.clear(uid);
190
- } catch (error) {
191
- strapi.log.error(error);
192
- await apiHandler.rollback(uid);
273
+ const deletedContentTypes = [];
274
+ const backedUpApiUids = [];
275
+ let schemaAlreadyRolledBack = false;
276
+ try {
277
+ for (const uid of uids){
278
+ await apiHandler.backup(uid);
279
+ backedUpApiUids.push(uid);
280
+ deletedContentTypes.push(builder.deleteContentType(uid));
281
+ }
282
+ const schemaFilesWritten = await builder.writeFiles();
283
+ if (!schemaFilesWritten) {
284
+ schemaAlreadyRolledBack = true;
285
+ throw new ApplicationError('Invalid schema edition');
286
+ }
287
+ for (const uid of uids){
288
+ await apiHandler.clear(uid, {
289
+ preserveBackup: true
290
+ });
193
291
  }
292
+ await pruneFolderReferences(uids);
293
+ } catch (error) {
294
+ await schemaMutation.rollbackSchemaMutation({
295
+ builder,
296
+ apiHandler,
297
+ backedUpApiUids,
298
+ schemaAlreadyRolledBack
299
+ });
300
+ throw error;
301
+ }
302
+ for (const error of (await schemaMutation.finalizeSchemaMutation({
303
+ apiHandler,
304
+ backedUpApiUids
305
+ }))){
306
+ strapi.log.error(error);
307
+ }
308
+ for (const contentType of deletedContentTypes){
309
+ strapi.eventHub.emit('content-type.delete', {
310
+ contentType
311
+ });
194
312
  }
195
313
  };
196
314
  /**
197
315
  * Deletes a content type and the api files related to it
198
316
  */ const deleteContentType = async (uid, defaultBuilder = undefined)=>{
317
+ assertCTBOwnedApplicationContentType(uid);
199
318
  const builder = defaultBuilder || index();
200
319
  // make a backup
201
320
  const apiHandler = strapi.plugin('content-type-builder').service('api-handler');
202
321
  await apiHandler.backup(uid);
203
- const contentType = builder.deleteContentType(uid);
322
+ let contentType;
323
+ let schemaAlreadyRolledBack = false;
204
324
  if (!defaultBuilder) {
205
325
  try {
206
- await builder.writeFiles();
207
- await apiHandler.clear(uid);
208
- } catch {
209
- await apiHandler.rollback(uid);
326
+ contentType = builder.deleteContentType(uid);
327
+ const schemaFilesWritten = await builder.writeFiles();
328
+ if (!schemaFilesWritten) {
329
+ schemaAlreadyRolledBack = true;
330
+ throw new ApplicationError('Invalid schema edition');
331
+ }
332
+ await apiHandler.clear(uid, {
333
+ preserveBackup: true
334
+ });
335
+ await pruneFolderReferences([
336
+ uid
337
+ ]);
338
+ } catch (error) {
339
+ await schemaMutation.rollbackSchemaMutation({
340
+ builder,
341
+ apiHandler,
342
+ backedUpApiUids: [
343
+ uid
344
+ ],
345
+ schemaAlreadyRolledBack
346
+ });
347
+ throw error;
210
348
  }
349
+ for (const error of (await schemaMutation.finalizeSchemaMutation({
350
+ apiHandler,
351
+ backedUpApiUids: [
352
+ uid
353
+ ]
354
+ }))){
355
+ strapi.log.error(error);
356
+ }
357
+ } else {
358
+ contentType = builder.deleteContentType(uid);
359
+ }
360
+ if (!defaultBuilder) {
361
+ strapi.eventHub.emit('content-type.delete', {
362
+ contentType
363
+ });
211
364
  }
212
- strapi.eventHub.emit('content-type.delete', {
213
- contentType
214
- });
215
365
  return contentType;
216
366
  };
217
367
 
368
+ exports.assertCTBOwnedApplicationContentType = assertCTBOwnedApplicationContentType;
218
369
  exports.createContentType = createContentType;
219
370
  exports.createContentTypes = createContentTypes;
220
371
  exports.deleteContentType = deleteContentType;
@@ -223,5 +374,6 @@ exports.editContentType = editContentType;
223
374
  exports.formatContentType = formatContentType;
224
375
  exports.generateAPI = generateAPI;
225
376
  exports.getRestrictRelationsTo = getRestrictRelationsTo;
377
+ exports.isCTBOwnedApplicationContentType = isCTBOwnedApplicationContentType;
226
378
  exports.isContentTypeVisible = isContentTypeVisible;
227
379
  //# sourceMappingURL=content-types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"content-types.js","sources":["../../../server/src/services/content-types.ts"],"sourcesContent":["import _ from 'lodash';\nimport { getOr } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils, errors } from '@strapi/utils';\nimport type { UID, Struct } from '@strapi/types';\nimport { formatAttributes, replaceTemporaryUIDs } from '../utils/attributes';\nimport createBuilder from './schema-builder';\nimport { coreUids, pluginsUids } from './constants';\n\nconst { ApplicationError } = errors;\n\nexport const isContentTypeVisible = (model: Struct.ContentTypeSchema) =>\n getOr(true, 'pluginOptions.content-type-builder.visible', model) === true;\n\nexport const getRestrictRelationsTo = (contentType: Struct.ContentTypeSchema) => {\n const { uid } = contentType;\n if (uid === coreUids.STRAPI_USER) {\n // TODO: replace with an obj { relation: 'x', bidirectional: true|false }\n return ['oneWay', 'manyWay'];\n }\n\n if (\n uid.startsWith(coreUids.PREFIX) ||\n uid === pluginsUids.UPLOAD_FILE ||\n !isContentTypeVisible(contentType)\n ) {\n return [];\n }\n\n return null;\n};\n\n/**\n * Format a contentType info to be used by the front-end\n */\nexport const formatContentType = (contentType: any) => {\n const { uid, kind, modelName, plugin, collectionName, info } = contentType;\n\n return {\n uid,\n plugin,\n apiID: modelName,\n schema: {\n ...contentTypesUtils.getOptions(contentType),\n displayName: info.displayName,\n singularName: info.singularName,\n pluralName: info.pluralName,\n description: _.get(info, 'description', ''),\n pluginOptions: contentType.pluginOptions,\n kind: kind || 'collectionType',\n collectionName,\n attributes: formatAttributes(contentType),\n visible: isContentTypeVisible(contentType),\n restrictRelationsTo: getRestrictRelationsTo(contentType),\n },\n };\n};\n\nexport const createContentTypes = async (contentTypes: any[]) => {\n const builder = createBuilder();\n const createdContentTypes: any[] = [];\n\n for (const contentType of contentTypes) {\n createdContentTypes.push(await createContentType(contentType, { defaultBuilder: builder }));\n }\n\n await builder.writeFiles();\n\n return createdContentTypes;\n};\n\ntype CreateContentTypeOptions = {\n defaultBuilder?: any; // TODO\n};\n\n/**\n * Creates a content type and handle the nested components sent with it\n */\nexport const createContentType = async (\n { contentType, components }: any,\n options: CreateContentTypeOptions = {}\n) => {\n const builder = options.defaultBuilder || createBuilder();\n const uidMap = builder.createNewComponentUIDMap(components || []);\n\n const replaceTmpUIDs = replaceTemporaryUIDs(uidMap);\n\n const newContentType = builder.createContentType(replaceTmpUIDs(contentType));\n\n // allow components to target the new contentType\n const targetContentType = (infos: any) => {\n Object.keys(infos.attributes).forEach((key) => {\n const { target } = infos.attributes[key];\n if (target === '__contentType__') {\n infos.attributes[key].target = newContentType.uid;\n }\n });\n\n return infos;\n };\n\n components?.forEach((component: any) => {\n const options = replaceTmpUIDs(targetContentType(component));\n\n if (!_.has(component, 'uid')) {\n return builder.createComponent(options);\n }\n\n return builder.editComponent(options);\n });\n\n // generate api skeleton\n await generateAPI({\n displayName: contentType!.displayName || contentType!.info.displayName,\n singularName: contentType!.singularName,\n pluralName: contentType!.pluralName,\n kind: contentType!.kind,\n });\n\n if (!options.defaultBuilder) {\n await builder.writeFiles();\n }\n\n strapi.eventHub.emit('content-type.create', { contentType: newContentType });\n\n return newContentType;\n};\n\n/**\n * Generate an API skeleton\n */\nexport const generateAPI = ({\n singularName,\n kind = 'collectionType',\n pluralName,\n displayName,\n}: any) => {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const strapiGenerators = require('@strapi/generators');\n return strapiGenerators.generate(\n 'content-type',\n {\n kind,\n singularName,\n id: singularName,\n pluralName,\n displayName,\n destination: 'new',\n bootstrapApi: true,\n attributes: [],\n },\n { dir: strapi.dirs.app.root }\n );\n};\n\n/**\n * Edits a contentType and handle the nested contentTypes sent with it\n */\nexport const editContentType = async (\n uid: UID.ContentType,\n { contentType, components = [] }: any\n) => {\n const builder = createBuilder();\n\n const previousSchema = builder.contentTypes.get(uid).schema;\n const previousKind = previousSchema.kind;\n const newKind = contentType.kind || previousKind;\n\n // Restore non-visible attributes from previous schema\n const previousAttributes = previousSchema.attributes;\n const prevNonVisibleAttributes = contentTypesUtils\n .getNonVisibleAttributes(previousSchema)\n .reduce((acc, key) => {\n if (key in previousAttributes) {\n acc[key] = previousAttributes[key];\n }\n\n return acc;\n }, {} as any);\n contentType.attributes = _.merge(prevNonVisibleAttributes, contentType.attributes);\n\n if (newKind !== previousKind && newKind === 'singleType') {\n const entryCount = await strapi.db.query(uid).count();\n if (entryCount > 1) {\n throw new ApplicationError(\n 'You cannot convert a collectionType to a singleType when having multiple entries in DB'\n );\n }\n }\n\n const uidMap = builder.createNewComponentUIDMap(components);\n const replaceTmpUIDs = replaceTemporaryUIDs(uidMap);\n\n const updatedContentType = builder.editContentType({\n uid,\n ...replaceTmpUIDs(contentType),\n });\n\n components.forEach((component: any) => {\n if (!_.has(component, 'uid')) {\n return builder.createComponent(replaceTmpUIDs(component));\n }\n\n return builder.editComponent(replaceTmpUIDs(component));\n });\n\n if (newKind !== previousKind) {\n const apiHandler = strapi.plugin('content-type-builder').service('api-handler');\n await apiHandler.backup(uid);\n\n try {\n await apiHandler.clear(uid);\n\n // generate new api skeleton\n await generateAPI({\n displayName: updatedContentType.schema.info.displayName,\n singularName: updatedContentType.schema.info.singularName,\n pluralName: updatedContentType.schema.info.pluralName,\n kind: updatedContentType.schema.kind,\n });\n\n await builder.writeFiles();\n } catch (error) {\n strapi.log.error(error);\n await apiHandler.rollback(uid);\n }\n\n return updatedContentType;\n }\n\n await builder.writeFiles();\n\n strapi.eventHub.emit('content-type.update', { contentType: updatedContentType });\n\n return updatedContentType;\n};\n\nexport const deleteContentTypes = async (uids: UID.ContentType[]) => {\n const builder = createBuilder();\n const apiHandler = strapi.plugin('content-type-builder').service('api-handler');\n\n for (const uid of uids) {\n await deleteContentType(uid, builder);\n }\n\n await builder.writeFiles();\n for (const uid of uids) {\n try {\n await apiHandler.clear(uid);\n } catch (error) {\n strapi.log.error(error);\n await apiHandler.rollback(uid);\n }\n }\n};\n\n/**\n * Deletes a content type and the api files related to it\n */\nexport const deleteContentType = async (uid: UID.ContentType, defaultBuilder: any = undefined) => {\n const builder = defaultBuilder || createBuilder();\n // make a backup\n const apiHandler = strapi.plugin('content-type-builder').service('api-handler');\n await apiHandler.backup(uid);\n\n const contentType = builder.deleteContentType(uid);\n\n if (!defaultBuilder) {\n try {\n await builder.writeFiles();\n await apiHandler.clear(uid);\n } catch {\n await apiHandler.rollback(uid);\n }\n }\n\n strapi.eventHub.emit('content-type.delete', { contentType });\n\n return contentType;\n};\n"],"names":["ApplicationError","errors","isContentTypeVisible","model","getOr","getRestrictRelationsTo","contentType","uid","coreUids","STRAPI_USER","startsWith","PREFIX","pluginsUids","UPLOAD_FILE","formatContentType","kind","modelName","plugin","collectionName","info","apiID","schema","contentTypesUtils","getOptions","displayName","singularName","pluralName","description","_","get","pluginOptions","attributes","formatAttributes","visible","restrictRelationsTo","createContentTypes","contentTypes","builder","createBuilder","createdContentTypes","push","createContentType","defaultBuilder","writeFiles","components","options","uidMap","createNewComponentUIDMap","replaceTmpUIDs","replaceTemporaryUIDs","newContentType","targetContentType","infos","Object","keys","forEach","key","target","component","has","createComponent","editComponent","generateAPI","strapi","eventHub","emit","strapiGenerators","require","generate","id","destination","bootstrapApi","dir","dirs","app","root","editContentType","previousSchema","previousKind","newKind","previousAttributes","prevNonVisibleAttributes","getNonVisibleAttributes","reduce","acc","merge","entryCount","db","query","count","updatedContentType","apiHandler","service","backup","clear","error","log","rollback","deleteContentTypes","uids","deleteContentType","undefined"],"mappings":"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"}
1
+ {"version":3,"file":"content-types.js","sources":["../../../server/src/services/content-types.ts"],"sourcesContent":["import _ from 'lodash';\nimport { getOr } from 'lodash/fp';\nimport { contentTypes as contentTypesUtils, errors } from '@strapi/utils';\nimport type { UID, Struct } from '@strapi/types';\nimport { formatAttributes, replaceTemporaryUIDs } from '../utils/attributes';\nimport { getService } from '../utils';\nimport createBuilder from './schema-builder';\nimport { finalizeSchemaMutation, rollbackSchemaMutation } from './schema-mutation';\nimport { coreUids, pluginsUids } from './constants';\n\nconst { ApplicationError } = errors;\n\nexport const isCTBOwnedApplicationContentType = (uid: UID.ContentType): boolean =>\n uid.startsWith('api::');\n\nexport const assertCTBOwnedApplicationContentType = (uid: UID.ContentType): void => {\n if (!isCTBOwnedApplicationContentType(uid)) {\n throw new ApplicationError(`Content type \"${uid}\" is not managed by CTB and cannot be deleted`);\n }\n};\n\nconst pruneFolderReferences = (uids: UID.ContentType[]) => {\n return getService('content-structure').commitFromUpdate({ deletedUids: new Set(uids) });\n};\n\nexport const isContentTypeVisible = (model: Struct.ContentTypeSchema) =>\n getOr(true, 'pluginOptions.content-type-builder.visible', model) === true;\n\nexport const getRestrictRelationsTo = (contentType: Struct.ContentTypeSchema) => {\n const { uid } = contentType;\n if (uid === coreUids.STRAPI_USER) {\n // TODO: replace with an obj { relation: 'x', bidirectional: true|false }\n return ['oneWay', 'manyWay'];\n }\n\n if (\n uid.startsWith(coreUids.PREFIX) ||\n uid === pluginsUids.UPLOAD_FILE ||\n !isContentTypeVisible(contentType)\n ) {\n return [];\n }\n\n return null;\n};\n\n/**\n * Format a contentType info to be used by the front-end\n */\nexport const formatContentType = (contentType: any) => {\n const { uid, kind, modelName, plugin, collectionName, info } = contentType;\n\n return {\n uid,\n plugin,\n apiID: modelName,\n schema: {\n ...contentTypesUtils.getOptions(contentType),\n displayName: info.displayName,\n singularName: info.singularName,\n pluralName: info.pluralName,\n description: _.get(info, 'description', ''),\n pluginOptions: contentType.pluginOptions,\n kind: kind || 'collectionType',\n collectionName,\n attributes: formatAttributes(contentType),\n visible: isContentTypeVisible(contentType),\n restrictRelationsTo: getRestrictRelationsTo(contentType),\n },\n };\n};\n\nexport const createContentTypes = async (contentTypes: any[]) => {\n const builder = createBuilder();\n const createdContentTypes: any[] = [];\n const generatedApiNames: string[] = [];\n let schemaAlreadyRolledBack = false;\n\n try {\n for (const contentType of contentTypes) {\n createdContentTypes.push(\n await createContentType(contentType, {\n defaultBuilder: builder,\n generatedApiNames,\n deferEvent: true,\n })\n );\n }\n\n const schemaFilesWritten = await builder.writeFiles();\n if (!schemaFilesWritten) {\n schemaAlreadyRolledBack = true;\n throw new ApplicationError('Invalid schema edition');\n }\n } catch (error) {\n const apiHandler = strapi\n .plugin('content-type-builder')\n .service('api-handler') as typeof import('./api-handler');\n await rollbackSchemaMutation({\n builder,\n apiHandler,\n generatedApiNames,\n schemaAlreadyRolledBack,\n });\n\n throw error;\n }\n\n for (const contentType of createdContentTypes) {\n strapi.eventHub.emit('content-type.create', { contentType });\n }\n\n return createdContentTypes;\n};\n\ntype CreateContentTypeOptions = {\n defaultBuilder?: any; // TODO\n generatedApiNames?: string[];\n deferEvent?: boolean;\n};\n\n/**\n * Creates a content type and handle the nested components sent with it\n */\nexport const createContentType = async (\n { contentType, components }: any,\n options: CreateContentTypeOptions = {}\n) => {\n const builder = options.defaultBuilder || createBuilder();\n const uidMap = builder.createNewComponentUIDMap(components || []);\n\n const replaceTmpUIDs = replaceTemporaryUIDs(uidMap);\n\n const newContentType = builder.createContentType(replaceTmpUIDs(contentType));\n\n // allow components to target the new contentType\n const targetContentType = (infos: any) => {\n Object.keys(infos.attributes).forEach((key) => {\n const { target } = infos.attributes[key];\n if (target === '__contentType__') {\n infos.attributes[key].target = newContentType.uid;\n }\n });\n\n return infos;\n };\n\n components?.forEach((component: any) => {\n const options = replaceTmpUIDs(targetContentType(component));\n\n if (!_.has(component, 'uid')) {\n return builder.createComponent(options);\n }\n\n return builder.editComponent(options);\n });\n\n const generatedApiNames = options.generatedApiNames ?? [];\n let schemaAlreadyRolledBack = false;\n\n try {\n // Generate before writing the schema so a successful mutation retains the existing layout.\n if (!contentType.plugin) {\n generatedApiNames.push(contentType.singularName);\n\n await generateAPI({\n displayName: contentType!.displayName || contentType!.info.displayName,\n singularName: contentType!.singularName,\n pluralName: contentType!.pluralName,\n kind: contentType!.kind,\n });\n }\n\n if (!options.defaultBuilder) {\n const schemaFilesWritten = await builder.writeFiles();\n if (!schemaFilesWritten) {\n schemaAlreadyRolledBack = true;\n throw new ApplicationError('Invalid schema edition');\n }\n }\n } catch (error) {\n if (!options.defaultBuilder) {\n const apiHandler = strapi\n .plugin('content-type-builder')\n .service('api-handler') as typeof import('./api-handler');\n await rollbackSchemaMutation({\n builder,\n apiHandler,\n generatedApiNames,\n schemaAlreadyRolledBack,\n });\n }\n\n throw error;\n }\n\n if (!options.deferEvent) {\n strapi.eventHub.emit('content-type.create', { contentType: newContentType });\n }\n\n return newContentType;\n};\n\n/**\n * Generate an API skeleton\n */\nexport const generateAPI = ({\n singularName,\n kind = 'collectionType',\n pluralName,\n displayName,\n}: any) => {\n // eslint-disable-next-line @typescript-eslint/no-var-requires\n const strapiGenerators = require('@strapi/generators');\n return strapiGenerators.generate(\n 'content-type',\n {\n kind,\n singularName,\n id: singularName,\n pluralName,\n displayName,\n destination: 'new',\n bootstrapApi: true,\n attributes: [],\n },\n { dir: strapi.dirs.app.root }\n );\n};\n\n/**\n * Edits a contentType and handle the nested contentTypes sent with it\n */\nexport const editContentType = async (\n uid: UID.ContentType,\n { contentType, components = [] }: any\n) => {\n const builder = createBuilder();\n\n const previousSchema = builder.contentTypes.get(uid).schema;\n const isPluginContentType = Boolean(builder.contentTypes.get(uid).plugin);\n const previousKind = previousSchema.kind;\n const newKind = contentType.kind || previousKind;\n\n // Restore non-visible attributes from previous schema\n const previousAttributes = previousSchema.attributes;\n const prevNonVisibleAttributes = contentTypesUtils\n .getNonVisibleAttributes(previousSchema)\n .reduce((acc, key) => {\n if (key in previousAttributes) {\n acc[key] = previousAttributes[key];\n }\n\n return acc;\n }, {} as any);\n contentType.attributes = _.merge(prevNonVisibleAttributes, contentType.attributes);\n\n if (newKind !== previousKind && newKind === 'singleType') {\n const entryCount = await strapi.db.query(uid).count();\n if (entryCount > 1) {\n throw new ApplicationError(\n 'You cannot convert a collectionType to a singleType when having multiple entries in DB'\n );\n }\n }\n\n const uidMap = builder.createNewComponentUIDMap(components);\n const replaceTmpUIDs = replaceTemporaryUIDs(uidMap);\n\n const updatedContentType = builder.editContentType({\n uid,\n ...replaceTmpUIDs(contentType),\n });\n\n components.forEach((component: any) => {\n if (!_.has(component, 'uid')) {\n return builder.createComponent(replaceTmpUIDs(component));\n }\n\n return builder.editComponent(replaceTmpUIDs(component));\n });\n\n if (newKind !== previousKind) {\n let schemaAlreadyRolledBack = false;\n const apiHandler = strapi\n .plugin('content-type-builder')\n .service('api-handler') as typeof import('./api-handler');\n await apiHandler.backup(uid);\n\n try {\n await apiHandler.clear(uid, { preserveBackup: true });\n\n if (!isPluginContentType) {\n // generate new api skeleton\n await generateAPI({\n displayName: updatedContentType.schema.info.displayName,\n singularName: updatedContentType.schema.info.singularName,\n pluralName: updatedContentType.schema.info.pluralName,\n kind: updatedContentType.schema.kind,\n });\n }\n\n const schemaFilesWritten = await builder.writeFiles();\n if (!schemaFilesWritten) {\n schemaAlreadyRolledBack = true;\n throw new ApplicationError('Invalid schema edition');\n }\n await pruneFolderReferences([uid]);\n } catch (error) {\n await rollbackSchemaMutation({\n builder,\n apiHandler,\n backedUpApiUids: [uid],\n schemaAlreadyRolledBack,\n });\n\n throw error;\n }\n\n for (const error of await finalizeSchemaMutation({ apiHandler, backedUpApiUids: [uid] })) {\n strapi.log.error(error);\n }\n\n return updatedContentType;\n }\n\n await builder.writeFiles();\n\n strapi.eventHub.emit('content-type.update', { contentType: updatedContentType });\n\n return updatedContentType;\n};\n\nexport const deleteContentTypes = async (uids: UID.ContentType[]) => {\n uids.forEach(assertCTBOwnedApplicationContentType);\n\n const builder = createBuilder();\n const apiHandler = strapi\n .plugin('content-type-builder')\n .service('api-handler') as typeof import('./api-handler');\n\n const deletedContentTypes: any[] = [];\n const backedUpApiUids: UID.ContentType[] = [];\n let schemaAlreadyRolledBack = false;\n\n try {\n for (const uid of uids) {\n await apiHandler.backup(uid);\n backedUpApiUids.push(uid);\n deletedContentTypes.push(builder.deleteContentType(uid));\n }\n\n const schemaFilesWritten = await builder.writeFiles();\n if (!schemaFilesWritten) {\n schemaAlreadyRolledBack = true;\n throw new ApplicationError('Invalid schema edition');\n }\n\n for (const uid of uids) {\n await apiHandler.clear(uid, { preserveBackup: true });\n }\n\n await pruneFolderReferences(uids);\n } catch (error) {\n await rollbackSchemaMutation({\n builder,\n apiHandler,\n backedUpApiUids,\n schemaAlreadyRolledBack,\n });\n\n throw error;\n }\n\n for (const error of await finalizeSchemaMutation({ apiHandler, backedUpApiUids })) {\n strapi.log.error(error);\n }\n\n for (const contentType of deletedContentTypes) {\n strapi.eventHub.emit('content-type.delete', { contentType });\n }\n};\n\n/**\n * Deletes a content type and the api files related to it\n */\nexport const deleteContentType = async (uid: UID.ContentType, defaultBuilder: any = undefined) => {\n assertCTBOwnedApplicationContentType(uid);\n\n const builder = defaultBuilder || createBuilder();\n // make a backup\n const apiHandler = strapi\n .plugin('content-type-builder')\n .service('api-handler') as typeof import('./api-handler');\n await apiHandler.backup(uid);\n\n let contentType;\n let schemaAlreadyRolledBack = false;\n\n if (!defaultBuilder) {\n try {\n contentType = builder.deleteContentType(uid);\n const schemaFilesWritten = await builder.writeFiles();\n if (!schemaFilesWritten) {\n schemaAlreadyRolledBack = true;\n throw new ApplicationError('Invalid schema edition');\n }\n await apiHandler.clear(uid, { preserveBackup: true });\n await pruneFolderReferences([uid]);\n } catch (error) {\n await rollbackSchemaMutation({\n builder,\n apiHandler,\n backedUpApiUids: [uid],\n schemaAlreadyRolledBack,\n });\n\n throw error;\n }\n\n for (const error of await finalizeSchemaMutation({ apiHandler, backedUpApiUids: [uid] })) {\n strapi.log.error(error);\n }\n } else {\n contentType = builder.deleteContentType(uid);\n }\n\n if (!defaultBuilder) {\n strapi.eventHub.emit('content-type.delete', { contentType });\n }\n\n return contentType;\n};\n"],"names":["ApplicationError","errors","isCTBOwnedApplicationContentType","uid","startsWith","assertCTBOwnedApplicationContentType","pruneFolderReferences","uids","getService","commitFromUpdate","deletedUids","Set","isContentTypeVisible","model","getOr","getRestrictRelationsTo","contentType","coreUids","STRAPI_USER","PREFIX","pluginsUids","UPLOAD_FILE","formatContentType","kind","modelName","plugin","collectionName","info","apiID","schema","contentTypesUtils","getOptions","displayName","singularName","pluralName","description","_","get","pluginOptions","attributes","formatAttributes","visible","restrictRelationsTo","createContentTypes","contentTypes","builder","createBuilder","createdContentTypes","generatedApiNames","schemaAlreadyRolledBack","push","createContentType","defaultBuilder","deferEvent","schemaFilesWritten","writeFiles","error","apiHandler","strapi","service","rollbackSchemaMutation","eventHub","emit","components","options","uidMap","createNewComponentUIDMap","replaceTmpUIDs","replaceTemporaryUIDs","newContentType","targetContentType","infos","Object","keys","forEach","key","target","component","has","createComponent","editComponent","generateAPI","strapiGenerators","require","generate","id","destination","bootstrapApi","dir","dirs","app","root","editContentType","previousSchema","isPluginContentType","Boolean","previousKind","newKind","previousAttributes","prevNonVisibleAttributes","getNonVisibleAttributes","reduce","acc","merge","entryCount","db","query","count","updatedContentType","backup","clear","preserveBackup","backedUpApiUids","finalizeSchemaMutation","log","deleteContentTypes","deletedContentTypes","deleteContentType","undefined"],"mappings":";;;;;;;;;;;;;;;AAUA,MAAM,EAAEA,gBAAgB,EAAE,GAAGC,YAAAA;MAEhBC,gCAAAA,GAAmC,CAACC,MAC/CA,GAAAA,CAAIC,UAAU,CAAC,OAAA;AAEV,MAAMC,uCAAuC,CAACF,GAAAA,GAAAA;IACnD,IAAI,CAACD,iCAAiCC,GAAAA,CAAAA,EAAM;AAC1C,QAAA,MAAM,IAAIH,gBAAAA,CAAiB,CAAC,cAAc,EAAEG,GAAAA,CAAI,6CAA6C,CAAC,CAAA;AAChG,IAAA;AACF;AAEA,MAAMG,wBAAwB,CAACC,IAAAA,GAAAA;IAC7B,OAAOC,kBAAAA,CAAW,mBAAA,CAAA,CAAqBC,gBAAgB,CAAC;AAAEC,QAAAA,WAAAA,EAAa,IAAIC,GAAAA,CAAIJ,IAAAA;AAAM,KAAA,CAAA;AACvF,CAAA;AAEO,MAAMK,uBAAuB,CAACC,KAAAA,GACnCC,SAAM,IAAA,EAAM,4CAAA,EAA8CD,WAAW;AAEhE,MAAME,yBAAyB,CAACC,WAAAA,GAAAA;IACrC,MAAM,EAAEb,GAAG,EAAE,GAAGa,WAAAA;IAChB,IAAIb,GAAAA,KAAQc,kBAAAA,CAASC,WAAW,EAAE;;QAEhC,OAAO;AAAC,YAAA,QAAA;AAAU,YAAA;AAAU,SAAA;AAC9B,IAAA;AAEA,IAAA,IACEf,GAAAA,CAAIC,UAAU,CAACa,kBAAAA,CAASE,MAAM,CAAA,IAC9BhB,GAAAA,KAAQiB,qBAAAA,CAAYC,WAAW,IAC/B,CAACT,oBAAAA,CAAqBI,WAAAA,CAAAA,EACtB;AACA,QAAA,OAAO,EAAE;AACX,IAAA;IAEA,OAAO,IAAA;AACT;AAEA;;IAGO,MAAMM,iBAAAA,GAAoB,CAACN,WAAAA,GAAAA;AAChC,IAAA,MAAM,EAAEb,GAAG,EAAEoB,IAAI,EAAEC,SAAS,EAAEC,MAAM,EAAEC,cAAc,EAAEC,IAAI,EAAE,GAAGX,WAAAA;IAE/D,OAAO;AACLb,QAAAA,GAAAA;AACAsB,QAAAA,MAAAA;QACAG,KAAAA,EAAOJ,SAAAA;QACPK,MAAAA,EAAQ;YACN,GAAGC,kBAAAA,CAAkBC,UAAU,CAACf,WAAAA,CAAY;AAC5CgB,YAAAA,WAAAA,EAAaL,KAAKK,WAAW;AAC7BC,YAAAA,YAAAA,EAAcN,KAAKM,YAAY;AAC/BC,YAAAA,UAAAA,EAAYP,KAAKO,UAAU;AAC3BC,YAAAA,WAAAA,EAAaC,kBAAAA,CAAEC,GAAG,CAACV,IAAAA,EAAM,aAAA,EAAe,EAAA,CAAA;AACxCW,YAAAA,aAAAA,EAAetB,YAAYsB,aAAa;AACxCf,YAAAA,IAAAA,EAAMA,IAAAA,IAAQ,gBAAA;AACdG,YAAAA,cAAAA;AACAa,YAAAA,UAAAA,EAAYC,2BAAAA,CAAiBxB,WAAAA,CAAAA;AAC7ByB,YAAAA,OAAAA,EAAS7B,oBAAAA,CAAqBI,WAAAA,CAAAA;AAC9B0B,YAAAA,mBAAAA,EAAqB3B,sBAAAA,CAAuBC,WAAAA;AAC9C;AACF,KAAA;AACF;AAEO,MAAM2B,qBAAqB,OAAOC,YAAAA,GAAAA;AACvC,IAAA,MAAMC,OAAAA,GAAUC,KAAAA,EAAAA;AAChB,IAAA,MAAMC,sBAA6B,EAAE;AACrC,IAAA,MAAMC,oBAA8B,EAAE;AACtC,IAAA,IAAIC,uBAAAA,GAA0B,KAAA;IAE9B,IAAI;QACF,KAAK,MAAMjC,eAAe4B,YAAAA,CAAc;AACtCG,YAAAA,mBAAAA,CAAoBG,IAAI,CACtB,MAAMC,iBAAAA,CAAkBnC,WAAAA,EAAa;gBACnCoC,cAAAA,EAAgBP,OAAAA;AAChBG,gBAAAA,iBAAAA;gBACAK,UAAAA,EAAY;AACd,aAAA,CAAA,CAAA;AAEJ,QAAA;QAEA,MAAMC,kBAAAA,GAAqB,MAAMT,OAAAA,CAAQU,UAAU,EAAA;AACnD,QAAA,IAAI,CAACD,kBAAAA,EAAoB;YACvBL,uBAAAA,GAA0B,IAAA;AAC1B,YAAA,MAAM,IAAIjD,gBAAAA,CAAiB,wBAAA,CAAA;AAC7B,QAAA;AACF,IAAA,CAAA,CAAE,OAAOwD,KAAAA,EAAO;AACd,QAAA,MAAMC,aAAaC,MAAAA,CAChBjC,MAAM,CAAC,sBAAA,CAAA,CACPkC,OAAO,CAAC,aAAA,CAAA;AACX,QAAA,MAAMC,qCAAAA,CAAuB;AAC3Bf,YAAAA,OAAAA;AACAY,YAAAA,UAAAA;AACAT,YAAAA,iBAAAA;AACAC,YAAAA;AACF,SAAA,CAAA;QAEA,MAAMO,KAAAA;AACR,IAAA;IAEA,KAAK,MAAMxC,eAAe+B,mBAAAA,CAAqB;AAC7CW,QAAAA,MAAAA,CAAOG,QAAQ,CAACC,IAAI,CAAC,qBAAA,EAAuB;AAAE9C,YAAAA;AAAY,SAAA,CAAA;AAC5D,IAAA;IAEA,OAAO+B,mBAAAA;AACT;AAQA;;AAEC,IACM,MAAMI,iBAAAA,GAAoB,OAC/B,EAAEnC,WAAW,EAAE+C,UAAU,EAAO,EAChCC,OAAAA,GAAoC,EAAE,GAAA;IAEtC,MAAMnB,OAAAA,GAAUmB,OAAAA,CAAQZ,cAAc,IAAIN,KAAAA,EAAAA;AAC1C,IAAA,MAAMmB,MAAAA,GAASpB,OAAAA,CAAQqB,wBAAwB,CAACH,cAAc,EAAE,CAAA;AAEhE,IAAA,MAAMI,iBAAiBC,+BAAAA,CAAqBH,MAAAA,CAAAA;AAE5C,IAAA,MAAMI,cAAAA,GAAiBxB,OAAAA,CAAQM,iBAAiB,CAACgB,cAAAA,CAAenD,WAAAA,CAAAA,CAAAA;;AAGhE,IAAA,MAAMsD,oBAAoB,CAACC,KAAAA,GAAAA;AACzBC,QAAAA,MAAAA,CAAOC,IAAI,CAACF,KAAAA,CAAMhC,UAAU,CAAA,CAAEmC,OAAO,CAAC,CAACC,GAAAA,GAAAA;AACrC,YAAA,MAAM,EAAEC,MAAM,EAAE,GAAGL,KAAAA,CAAMhC,UAAU,CAACoC,GAAAA,CAAI;AACxC,YAAA,IAAIC,WAAW,iBAAA,EAAmB;AAChCL,gBAAAA,KAAAA,CAAMhC,UAAU,CAACoC,GAAAA,CAAI,CAACC,MAAM,GAAGP,eAAelE,GAAG;AACnD,YAAA;AACF,QAAA,CAAA,CAAA;QAEA,OAAOoE,KAAAA;AACT,IAAA,CAAA;AAEAR,IAAAA,UAAAA,EAAYW,QAAQ,CAACG,SAAAA,GAAAA;QACnB,MAAMb,OAAAA,GAAUG,eAAeG,iBAAAA,CAAkBO,SAAAA,CAAAA,CAAAA;AAEjD,QAAA,IAAI,CAACzC,kBAAAA,CAAE0C,GAAG,CAACD,WAAW,KAAA,CAAA,EAAQ;YAC5B,OAAOhC,OAAAA,CAAQkC,eAAe,CAACf,OAAAA,CAAAA;AACjC,QAAA;QAEA,OAAOnB,OAAAA,CAAQmC,aAAa,CAAChB,OAAAA,CAAAA;AAC/B,IAAA,CAAA,CAAA;AAEA,IAAA,MAAMhB,iBAAAA,GAAoBgB,OAAAA,CAAQhB,iBAAiB,IAAI,EAAE;AACzD,IAAA,IAAIC,uBAAAA,GAA0B,KAAA;IAE9B,IAAI;;QAEF,IAAI,CAACjC,WAAAA,CAAYS,MAAM,EAAE;YACvBuB,iBAAAA,CAAkBE,IAAI,CAAClC,WAAAA,CAAYiB,YAAY,CAAA;AAE/C,YAAA,MAAMgD,WAAAA,CAAY;AAChBjD,gBAAAA,WAAAA,EAAahB,YAAagB,WAAW,IAAIhB,WAAAA,CAAaW,IAAI,CAACK,WAAW;AACtEC,gBAAAA,YAAAA,EAAcjB,YAAaiB,YAAY;AACvCC,gBAAAA,UAAAA,EAAYlB,YAAakB,UAAU;AACnCX,gBAAAA,IAAAA,EAAMP,YAAaO;AACrB,aAAA,CAAA;AACF,QAAA;QAEA,IAAI,CAACyC,OAAAA,CAAQZ,cAAc,EAAE;YAC3B,MAAME,kBAAAA,GAAqB,MAAMT,OAAAA,CAAQU,UAAU,EAAA;AACnD,YAAA,IAAI,CAACD,kBAAAA,EAAoB;gBACvBL,uBAAAA,GAA0B,IAAA;AAC1B,gBAAA,MAAM,IAAIjD,gBAAAA,CAAiB,wBAAA,CAAA;AAC7B,YAAA;AACF,QAAA;AACF,IAAA,CAAA,CAAE,OAAOwD,KAAAA,EAAO;QACd,IAAI,CAACQ,OAAAA,CAAQZ,cAAc,EAAE;AAC3B,YAAA,MAAMK,aAAaC,MAAAA,CAChBjC,MAAM,CAAC,sBAAA,CAAA,CACPkC,OAAO,CAAC,aAAA,CAAA;AACX,YAAA,MAAMC,qCAAAA,CAAuB;AAC3Bf,gBAAAA,OAAAA;AACAY,gBAAAA,UAAAA;AACAT,gBAAAA,iBAAAA;AACAC,gBAAAA;AACF,aAAA,CAAA;AACF,QAAA;QAEA,MAAMO,KAAAA;AACR,IAAA;IAEA,IAAI,CAACQ,OAAAA,CAAQX,UAAU,EAAE;AACvBK,QAAAA,MAAAA,CAAOG,QAAQ,CAACC,IAAI,CAAC,qBAAA,EAAuB;YAAE9C,WAAAA,EAAaqD;AAAe,SAAA,CAAA;AAC5E,IAAA;IAEA,OAAOA,cAAAA;AACT;AAEA;;AAEC,IACM,MAAMY,WAAAA,GAAc,CAAC,EAC1BhD,YAAY,EACZV,IAAAA,GAAO,gBAAgB,EACvBW,UAAU,EACVF,WAAW,EACP,GAAA;;AAEJ,IAAA,MAAMkD,mBAAmBC,OAAAA,CAAQ,oBAAA,CAAA;IACjC,OAAOD,gBAAAA,CAAiBE,QAAQ,CAC9B,cAAA,EACA;AACE7D,QAAAA,IAAAA;AACAU,QAAAA,YAAAA;QACAoD,EAAAA,EAAIpD,YAAAA;AACJC,QAAAA,UAAAA;AACAF,QAAAA,WAAAA;QACAsD,WAAAA,EAAa,KAAA;QACbC,YAAAA,EAAc,IAAA;AACdhD,QAAAA,UAAAA,EAAY;KACd,EACA;AAAEiD,QAAAA,GAAAA,EAAK9B,MAAAA,CAAO+B,IAAI,CAACC,GAAG,CAACC;AAAK,KAAA,CAAA;AAEhC;AAEA;;IAGO,MAAMC,eAAAA,GAAkB,OAC7BzF,GAAAA,EACA,EAAEa,WAAW,EAAE+C,UAAAA,GAAa,EAAE,EAAO,GAAA;AAErC,IAAA,MAAMlB,OAAAA,GAAUC,KAAAA,EAAAA;AAEhB,IAAA,MAAM+C,iBAAiBhD,OAAAA,CAAQD,YAAY,CAACP,GAAG,CAAClC,KAAK0B,MAAM;IAC3D,MAAMiE,mBAAAA,GAAsBC,QAAQlD,OAAAA,CAAQD,YAAY,CAACP,GAAG,CAAClC,KAAKsB,MAAM,CAAA;IACxE,MAAMuE,YAAAA,GAAeH,eAAetE,IAAI;IACxC,MAAM0E,OAAAA,GAAUjF,WAAAA,CAAYO,IAAI,IAAIyE,YAAAA;;IAGpC,MAAME,kBAAAA,GAAqBL,eAAetD,UAAU;IACpD,MAAM4D,wBAAAA,GAA2BrE,mBAC9BsE,uBAAuB,CAACP,gBACxBQ,MAAM,CAAC,CAACC,GAAAA,EAAK3B,GAAAA,GAAAA;AACZ,QAAA,IAAIA,OAAOuB,kBAAAA,EAAoB;AAC7BI,YAAAA,GAAG,CAAC3B,GAAAA,CAAI,GAAGuB,kBAAkB,CAACvB,GAAAA,CAAI;AACpC,QAAA;QAEA,OAAO2B,GAAAA;AACT,IAAA,CAAA,EAAG,EAAC,CAAA;AACNtF,IAAAA,WAAAA,CAAYuB,UAAU,GAAGH,kBAAAA,CAAEmE,KAAK,CAACJ,wBAAAA,EAA0BnF,YAAYuB,UAAU,CAAA;IAEjF,IAAI0D,OAAAA,KAAYD,YAAAA,IAAgBC,OAAAA,KAAY,YAAA,EAAc;QACxD,MAAMO,UAAAA,GAAa,MAAM9C,MAAAA,CAAO+C,EAAE,CAACC,KAAK,CAACvG,KAAKwG,KAAK,EAAA;AACnD,QAAA,IAAIH,aAAa,CAAA,EAAG;AAClB,YAAA,MAAM,IAAIxG,gBAAAA,CACR,wFAAA,CAAA;AAEJ,QAAA;AACF,IAAA;IAEA,MAAMiE,MAAAA,GAASpB,OAAAA,CAAQqB,wBAAwB,CAACH,UAAAA,CAAAA;AAChD,IAAA,MAAMI,iBAAiBC,+BAAAA,CAAqBH,MAAAA,CAAAA;IAE5C,MAAM2C,kBAAAA,GAAqB/D,OAAAA,CAAQ+C,eAAe,CAAC;AACjDzF,QAAAA,GAAAA;AACA,QAAA,GAAGgE,eAAenD,WAAAA;AACpB,KAAA,CAAA;IAEA+C,UAAAA,CAAWW,OAAO,CAAC,CAACG,SAAAA,GAAAA;AAClB,QAAA,IAAI,CAACzC,kBAAAA,CAAE0C,GAAG,CAACD,WAAW,KAAA,CAAA,EAAQ;YAC5B,OAAOhC,OAAAA,CAAQkC,eAAe,CAACZ,cAAAA,CAAeU,SAAAA,CAAAA,CAAAA;AAChD,QAAA;QAEA,OAAOhC,OAAAA,CAAQmC,aAAa,CAACb,cAAAA,CAAeU,SAAAA,CAAAA,CAAAA;AAC9C,IAAA,CAAA,CAAA;AAEA,IAAA,IAAIoB,YAAYD,YAAAA,EAAc;AAC5B,QAAA,IAAI/C,uBAAAA,GAA0B,KAAA;AAC9B,QAAA,MAAMQ,aAAaC,MAAAA,CAChBjC,MAAM,CAAC,sBAAA,CAAA,CACPkC,OAAO,CAAC,aAAA,CAAA;QACX,MAAMF,UAAAA,CAAWoD,MAAM,CAAC1G,GAAAA,CAAAA;QAExB,IAAI;YACF,MAAMsD,UAAAA,CAAWqD,KAAK,CAAC3G,GAAAA,EAAK;gBAAE4G,cAAAA,EAAgB;AAAK,aAAA,CAAA;AAEnD,YAAA,IAAI,CAACjB,mBAAAA,EAAqB;;AAExB,gBAAA,MAAMb,WAAAA,CAAY;AAChBjD,oBAAAA,WAAAA,EAAa4E,kBAAAA,CAAmB/E,MAAM,CAACF,IAAI,CAACK,WAAW;AACvDC,oBAAAA,YAAAA,EAAc2E,kBAAAA,CAAmB/E,MAAM,CAACF,IAAI,CAACM,YAAY;AACzDC,oBAAAA,UAAAA,EAAY0E,kBAAAA,CAAmB/E,MAAM,CAACF,IAAI,CAACO,UAAU;oBACrDX,IAAAA,EAAMqF,kBAAAA,CAAmB/E,MAAM,CAACN;AAClC,iBAAA,CAAA;AACF,YAAA;YAEA,MAAM+B,kBAAAA,GAAqB,MAAMT,OAAAA,CAAQU,UAAU,EAAA;AACnD,YAAA,IAAI,CAACD,kBAAAA,EAAoB;gBACvBL,uBAAAA,GAA0B,IAAA;AAC1B,gBAAA,MAAM,IAAIjD,gBAAAA,CAAiB,wBAAA,CAAA;AAC7B,YAAA;AACA,YAAA,MAAMM,qBAAAA,CAAsB;AAACH,gBAAAA;AAAI,aAAA,CAAA;AACnC,QAAA,CAAA,CAAE,OAAOqD,KAAAA,EAAO;AACd,YAAA,MAAMI,qCAAAA,CAAuB;AAC3Bf,gBAAAA,OAAAA;AACAY,gBAAAA,UAAAA;gBACAuD,eAAAA,EAAiB;AAAC7G,oBAAAA;AAAI,iBAAA;AACtB8C,gBAAAA;AACF,aAAA,CAAA;YAEA,MAAMO,KAAAA;AACR,QAAA;AAEA,QAAA,KAAK,MAAMA,KAAAA,KAAS,MAAMyD,qCAAAA,CAAuB;AAAExD,YAAAA,UAAAA;YAAYuD,eAAAA,EAAiB;AAAC7G,gBAAAA;AAAI;AAAC,SAAA,CAAC,EAAG;YACxFuD,MAAAA,CAAOwD,GAAG,CAAC1D,KAAK,CAACA,KAAAA,CAAAA;AACnB,QAAA;QAEA,OAAOoD,kBAAAA;AACT,IAAA;AAEA,IAAA,MAAM/D,QAAQU,UAAU,EAAA;AAExBG,IAAAA,MAAAA,CAAOG,QAAQ,CAACC,IAAI,CAAC,qBAAA,EAAuB;QAAE9C,WAAAA,EAAa4F;AAAmB,KAAA,CAAA;IAE9E,OAAOA,kBAAAA;AACT;AAEO,MAAMO,qBAAqB,OAAO5G,IAAAA,GAAAA;AACvCA,IAAAA,IAAAA,CAAKmE,OAAO,CAACrE,oCAAAA,CAAAA;AAEb,IAAA,MAAMwC,OAAAA,GAAUC,KAAAA,EAAAA;AAChB,IAAA,MAAMW,aAAaC,MAAAA,CAChBjC,MAAM,CAAC,sBAAA,CAAA,CACPkC,OAAO,CAAC,aAAA,CAAA;AAEX,IAAA,MAAMyD,sBAA6B,EAAE;AACrC,IAAA,MAAMJ,kBAAqC,EAAE;AAC7C,IAAA,IAAI/D,uBAAAA,GAA0B,KAAA;IAE9B,IAAI;QACF,KAAK,MAAM9C,OAAOI,IAAAA,CAAM;YACtB,MAAMkD,UAAAA,CAAWoD,MAAM,CAAC1G,GAAAA,CAAAA;AACxB6G,YAAAA,eAAAA,CAAgB9D,IAAI,CAAC/C,GAAAA,CAAAA;AACrBiH,YAAAA,mBAAAA,CAAoBlE,IAAI,CAACL,OAAAA,CAAQwE,iBAAiB,CAAClH,GAAAA,CAAAA,CAAAA;AACrD,QAAA;QAEA,MAAMmD,kBAAAA,GAAqB,MAAMT,OAAAA,CAAQU,UAAU,EAAA;AACnD,QAAA,IAAI,CAACD,kBAAAA,EAAoB;YACvBL,uBAAAA,GAA0B,IAAA;AAC1B,YAAA,MAAM,IAAIjD,gBAAAA,CAAiB,wBAAA,CAAA;AAC7B,QAAA;QAEA,KAAK,MAAMG,OAAOI,IAAAA,CAAM;YACtB,MAAMkD,UAAAA,CAAWqD,KAAK,CAAC3G,GAAAA,EAAK;gBAAE4G,cAAAA,EAAgB;AAAK,aAAA,CAAA;AACrD,QAAA;AAEA,QAAA,MAAMzG,qBAAAA,CAAsBC,IAAAA,CAAAA;AAC9B,IAAA,CAAA,CAAE,OAAOiD,KAAAA,EAAO;AACd,QAAA,MAAMI,qCAAAA,CAAuB;AAC3Bf,YAAAA,OAAAA;AACAY,YAAAA,UAAAA;AACAuD,YAAAA,eAAAA;AACA/D,YAAAA;AACF,SAAA,CAAA;QAEA,MAAMO,KAAAA;AACR,IAAA;AAEA,IAAA,KAAK,MAAMA,KAAAA,KAAS,MAAMyD,qCAAAA,CAAuB;AAAExD,QAAAA,UAAAA;AAAYuD,QAAAA;AAAgB,KAAA,CAAC,EAAG;QACjFtD,MAAAA,CAAOwD,GAAG,CAAC1D,KAAK,CAACA,KAAAA,CAAAA;AACnB,IAAA;IAEA,KAAK,MAAMxC,eAAeoG,mBAAAA,CAAqB;AAC7C1D,QAAAA,MAAAA,CAAOG,QAAQ,CAACC,IAAI,CAAC,qBAAA,EAAuB;AAAE9C,YAAAA;AAAY,SAAA,CAAA;AAC5D,IAAA;AACF;AAEA;;AAEC,IACM,MAAMqG,iBAAAA,GAAoB,OAAOlH,GAAAA,EAAsBiD,iBAAsBkE,SAAS,GAAA;IAC3FjH,oCAAAA,CAAqCF,GAAAA,CAAAA;AAErC,IAAA,MAAM0C,UAAUO,cAAAA,IAAkBN,KAAAA,EAAAA;;AAElC,IAAA,MAAMW,aAAaC,MAAAA,CAChBjC,MAAM,CAAC,sBAAA,CAAA,CACPkC,OAAO,CAAC,aAAA,CAAA;IACX,MAAMF,UAAAA,CAAWoD,MAAM,CAAC1G,GAAAA,CAAAA;IAExB,IAAIa,WAAAA;AACJ,IAAA,IAAIiC,uBAAAA,GAA0B,KAAA;AAE9B,IAAA,IAAI,CAACG,cAAAA,EAAgB;QACnB,IAAI;YACFpC,WAAAA,GAAc6B,OAAAA,CAAQwE,iBAAiB,CAAClH,GAAAA,CAAAA;YACxC,MAAMmD,kBAAAA,GAAqB,MAAMT,OAAAA,CAAQU,UAAU,EAAA;AACnD,YAAA,IAAI,CAACD,kBAAAA,EAAoB;gBACvBL,uBAAAA,GAA0B,IAAA;AAC1B,gBAAA,MAAM,IAAIjD,gBAAAA,CAAiB,wBAAA,CAAA;AAC7B,YAAA;YACA,MAAMyD,UAAAA,CAAWqD,KAAK,CAAC3G,GAAAA,EAAK;gBAAE4G,cAAAA,EAAgB;AAAK,aAAA,CAAA;AACnD,YAAA,MAAMzG,qBAAAA,CAAsB;AAACH,gBAAAA;AAAI,aAAA,CAAA;AACnC,QAAA,CAAA,CAAE,OAAOqD,KAAAA,EAAO;AACd,YAAA,MAAMI,qCAAAA,CAAuB;AAC3Bf,gBAAAA,OAAAA;AACAY,gBAAAA,UAAAA;gBACAuD,eAAAA,EAAiB;AAAC7G,oBAAAA;AAAI,iBAAA;AACtB8C,gBAAAA;AACF,aAAA,CAAA;YAEA,MAAMO,KAAAA;AACR,QAAA;AAEA,QAAA,KAAK,MAAMA,KAAAA,KAAS,MAAMyD,qCAAAA,CAAuB;AAAExD,YAAAA,UAAAA;YAAYuD,eAAAA,EAAiB;AAAC7G,gBAAAA;AAAI;AAAC,SAAA,CAAC,EAAG;YACxFuD,MAAAA,CAAOwD,GAAG,CAAC1D,KAAK,CAACA,KAAAA,CAAAA;AACnB,QAAA;IACF,CAAA,MAAO;QACLxC,WAAAA,GAAc6B,OAAAA,CAAQwE,iBAAiB,CAAClH,GAAAA,CAAAA;AAC1C,IAAA;AAEA,IAAA,IAAI,CAACiD,cAAAA,EAAgB;AACnBM,QAAAA,MAAAA,CAAOG,QAAQ,CAACC,IAAI,CAAC,qBAAA,EAAuB;AAAE9C,YAAAA;AAAY,SAAA,CAAA;AAC5D,IAAA;IAEA,OAAOA,WAAAA;AACT;;;;;;;;;;;;;;"}