@strapi/content-releases 5.0.0-beta.1 → 5.0.0-beta.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{App-1LckaIGY.js → App-B5UOQWbt.js} +375 -368
- package/dist/_chunks/App-B5UOQWbt.js.map +1 -0
- package/dist/_chunks/{App-X01LBg5V.mjs → App-DcXlnXrr.mjs} +371 -363
- package/dist/_chunks/App-DcXlnXrr.mjs.map +1 -0
- package/dist/_chunks/{PurchaseContentReleases-YhAPgpG9.js → PurchaseContentReleases-Be3acS2L.js} +8 -7
- package/dist/_chunks/PurchaseContentReleases-Be3acS2L.js.map +1 -0
- package/dist/_chunks/{PurchaseContentReleases-Clm0iACO.mjs → PurchaseContentReleases-_MxP6-Dt.mjs} +9 -8
- package/dist/_chunks/PurchaseContentReleases-_MxP6-Dt.mjs.map +1 -0
- package/dist/_chunks/SettingsPage-ped5WZ6Q.js +40 -0
- package/dist/_chunks/SettingsPage-ped5WZ6Q.js.map +1 -0
- package/dist/_chunks/SettingsPage-w5dOMAtL.mjs +40 -0
- package/dist/_chunks/SettingsPage-w5dOMAtL.mjs.map +1 -0
- package/dist/_chunks/{en-faJDuv3q.js → en-aH5E5UNw.js} +12 -2
- package/dist/_chunks/en-aH5E5UNw.js.map +1 -0
- package/dist/_chunks/{en-RdapH-9X.mjs → en-ahPQUZv2.mjs} +12 -2
- package/dist/_chunks/en-ahPQUZv2.mjs.map +1 -0
- package/dist/_chunks/{index-cYWov2wa.js → index-BgID5UQ7.js} +549 -525
- package/dist/_chunks/index-BgID5UQ7.js.map +1 -0
- package/dist/_chunks/{index-OD9AlD-6.mjs → index-LUuvped4.mjs} +551 -525
- package/dist/_chunks/index-LUuvped4.mjs.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +2 -2
- package/dist/admin/src/components/ReleaseAction.d.ts +3 -0
- package/dist/admin/src/components/ReleaseActionMenu.d.ts +3 -3
- package/dist/admin/src/components/ReleaseActionModal.d.ts +24 -0
- package/dist/admin/src/components/ReleaseListCell.d.ts +0 -0
- package/dist/admin/src/components/ReleaseModal.d.ts +3 -2
- package/dist/admin/src/components/ReleasesPanel.d.ts +3 -0
- package/dist/admin/src/pages/SettingsPage.d.ts +1 -0
- package/dist/admin/src/services/release.d.ts +51 -313
- package/dist/admin/src/utils/api.d.ts +6 -0
- package/dist/server/index.js +824 -579
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +825 -580
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/src/bootstrap.d.ts +1 -1
- package/dist/server/src/bootstrap.d.ts.map +1 -1
- package/dist/server/src/constants.d.ts +11 -2
- package/dist/server/src/constants.d.ts.map +1 -1
- package/dist/server/src/content-types/index.d.ts +3 -5
- package/dist/server/src/content-types/index.d.ts.map +1 -1
- package/dist/server/src/content-types/release-action/index.d.ts +3 -5
- package/dist/server/src/content-types/release-action/index.d.ts.map +1 -1
- package/dist/server/src/content-types/release-action/schema.d.ts +3 -5
- package/dist/server/src/content-types/release-action/schema.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +6 -2
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/controllers/release-action.d.ts +0 -1
- package/dist/server/src/controllers/release-action.d.ts.map +1 -1
- package/dist/server/src/controllers/release.d.ts +7 -1
- package/dist/server/src/controllers/release.d.ts.map +1 -1
- package/dist/server/src/controllers/settings.d.ts +11 -0
- package/dist/server/src/controllers/settings.d.ts.map +1 -0
- package/dist/server/src/controllers/validation/release-action.d.ts +7 -1
- package/dist/server/src/controllers/validation/release-action.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/release.d.ts +1 -0
- package/dist/server/src/controllers/validation/release.d.ts.map +1 -1
- package/dist/server/src/controllers/validation/settings.d.ts +2 -0
- package/dist/server/src/controllers/validation/settings.d.ts.map +1 -0
- package/dist/server/src/destroy.d.ts +1 -1
- package/dist/server/src/destroy.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +73 -57
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/middlewares/documents.d.ts +6 -0
- package/dist/server/src/middlewares/documents.d.ts.map +1 -0
- package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts +9 -0
- package/dist/server/src/migrations/database/5.0.0-document-id-in-actions.d.ts.map +1 -0
- package/dist/server/src/migrations/index.d.ts.map +1 -1
- package/dist/server/src/register.d.ts +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/index.d.ts +16 -0
- package/dist/server/src/routes/index.d.ts.map +1 -1
- package/dist/server/src/routes/release-action.d.ts.map +1 -1
- package/dist/server/src/routes/release.d.ts.map +1 -1
- package/dist/server/src/routes/settings.d.ts +18 -0
- package/dist/server/src/routes/settings.d.ts.map +1 -0
- package/dist/server/src/services/index.d.ts +41 -41
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/services/release-action.d.ts +36 -0
- package/dist/server/src/services/release-action.d.ts.map +1 -0
- package/dist/server/src/services/release.d.ts +7 -42
- package/dist/server/src/services/release.d.ts.map +1 -1
- package/dist/server/src/services/scheduling.d.ts +1 -1
- package/dist/server/src/services/scheduling.d.ts.map +1 -1
- package/dist/server/src/services/settings.d.ts +13 -0
- package/dist/server/src/services/settings.d.ts.map +1 -0
- package/dist/server/src/services/validation.d.ts +2 -2
- package/dist/server/src/services/validation.d.ts.map +1 -1
- package/dist/server/src/utils/index.d.ts +33 -12
- package/dist/server/src/utils/index.d.ts.map +1 -1
- package/dist/shared/contracts/release-actions.d.ts +6 -5
- package/dist/shared/contracts/release-actions.d.ts.map +1 -1
- package/dist/shared/contracts/releases.d.ts +23 -6
- package/dist/shared/contracts/releases.d.ts.map +1 -1
- package/dist/shared/contracts/settings.d.ts +39 -0
- package/dist/shared/contracts/settings.d.ts.map +1 -0
- package/dist/shared/validation-schemas.d.ts +1 -0
- package/dist/shared/validation-schemas.d.ts.map +1 -1
- package/package.json +19 -18
- package/dist/_chunks/App-1LckaIGY.js.map +0 -1
- package/dist/_chunks/App-X01LBg5V.mjs.map +0 -1
- package/dist/_chunks/PurchaseContentReleases-Clm0iACO.mjs.map +0 -1
- package/dist/_chunks/PurchaseContentReleases-YhAPgpG9.js.map +0 -1
- package/dist/_chunks/en-RdapH-9X.mjs.map +0 -1
- package/dist/_chunks/en-faJDuv3q.js.map +0 -1
- package/dist/_chunks/index-OD9AlD-6.mjs.map +0 -1
- package/dist/_chunks/index-cYWov2wa.js.map +0 -1
- package/dist/admin/src/components/CMReleasesContainer.d.ts +0 -1
- package/dist/admin/src/services/axios.d.ts +0 -29
package/dist/server/index.js
CHANGED
|
@@ -71,24 +71,38 @@ const ACTIONS = [
|
|
|
71
71
|
displayName: "Add an entry to a release",
|
|
72
72
|
uid: "create-action",
|
|
73
73
|
pluginName: "content-releases"
|
|
74
|
+
},
|
|
75
|
+
// Settings
|
|
76
|
+
{
|
|
77
|
+
uid: "settings.read",
|
|
78
|
+
section: "settings",
|
|
79
|
+
displayName: "Read",
|
|
80
|
+
category: "content releases",
|
|
81
|
+
subCategory: "options",
|
|
82
|
+
pluginName: "content-releases"
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
uid: "settings.update",
|
|
86
|
+
section: "settings",
|
|
87
|
+
displayName: "Edit",
|
|
88
|
+
category: "content releases",
|
|
89
|
+
subCategory: "options",
|
|
90
|
+
pluginName: "content-releases"
|
|
74
91
|
}
|
|
75
92
|
];
|
|
76
93
|
const ALLOWED_WEBHOOK_EVENTS = {
|
|
77
94
|
RELEASES_PUBLISH: "releases.publish"
|
|
78
95
|
};
|
|
79
|
-
const getService = (name, { strapi: strapi2 }
|
|
96
|
+
const getService = (name, { strapi: strapi2 }) => {
|
|
80
97
|
return strapi2.plugin("content-releases").service(name);
|
|
81
98
|
};
|
|
82
|
-
const
|
|
99
|
+
const getDraftEntryValidStatus = async ({ contentType, documentId, locale }, { strapi: strapi2 }) => {
|
|
83
100
|
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
84
|
-
const populate = await populateBuilderService(
|
|
85
|
-
const entry = await strapi2
|
|
86
|
-
|
|
87
|
-
populate
|
|
88
|
-
});
|
|
89
|
-
return entry;
|
|
101
|
+
const populate = await populateBuilderService(contentType).populateDeep(Infinity).build();
|
|
102
|
+
const entry = await getEntry({ contentType, documentId, locale, populate }, { strapi: strapi2 });
|
|
103
|
+
return isEntryValid(contentType, entry, { strapi: strapi2 });
|
|
90
104
|
};
|
|
91
|
-
const
|
|
105
|
+
const isEntryValid = async (contentTypeUid, entry, { strapi: strapi2 }) => {
|
|
92
106
|
try {
|
|
93
107
|
await strapi2.entityValidator.validateEntityCreation(
|
|
94
108
|
strapi2.getModel(contentTypeUid),
|
|
@@ -102,6 +116,38 @@ const getEntryValidStatus = async (contentTypeUid, entry, { strapi: strapi2 } =
|
|
|
102
116
|
return false;
|
|
103
117
|
}
|
|
104
118
|
};
|
|
119
|
+
const getEntry = async ({
|
|
120
|
+
contentType,
|
|
121
|
+
documentId,
|
|
122
|
+
locale,
|
|
123
|
+
populate,
|
|
124
|
+
status = "draft"
|
|
125
|
+
}, { strapi: strapi2 }) => {
|
|
126
|
+
if (documentId) {
|
|
127
|
+
return strapi2.documents(contentType).findOne({ documentId, locale, populate, status });
|
|
128
|
+
}
|
|
129
|
+
return strapi2.documents(contentType).findFirst({ locale, populate, status });
|
|
130
|
+
};
|
|
131
|
+
const getEntryStatus = async (contentType, entry) => {
|
|
132
|
+
if (entry.publishedAt) {
|
|
133
|
+
return "published";
|
|
134
|
+
}
|
|
135
|
+
const publishedEntry = await strapi.documents(contentType).findOne({
|
|
136
|
+
documentId: entry.documentId,
|
|
137
|
+
locale: entry.locale,
|
|
138
|
+
status: "published",
|
|
139
|
+
fields: ["updatedAt"]
|
|
140
|
+
});
|
|
141
|
+
if (!publishedEntry) {
|
|
142
|
+
return "draft";
|
|
143
|
+
}
|
|
144
|
+
const entryUpdatedAt = new Date(entry.updatedAt).getTime();
|
|
145
|
+
const publishedEntryUpdatedAt = new Date(publishedEntry.updatedAt).getTime();
|
|
146
|
+
if (entryUpdatedAt > publishedEntryUpdatedAt) {
|
|
147
|
+
return "modified";
|
|
148
|
+
}
|
|
149
|
+
return "published";
|
|
150
|
+
};
|
|
105
151
|
async function deleteActionsOnDisableDraftAndPublish({
|
|
106
152
|
oldContentTypes,
|
|
107
153
|
contentTypes: contentTypes2
|
|
@@ -147,20 +193,22 @@ async function migrateIsValidAndStatusReleases() {
|
|
|
147
193
|
const notValidatedActions = actions.filter((action) => action.isEntryValid === null);
|
|
148
194
|
for (const action of notValidatedActions) {
|
|
149
195
|
if (action.entry) {
|
|
150
|
-
const
|
|
151
|
-
|
|
196
|
+
const isEntryValid2 = getDraftEntryValidStatus(
|
|
197
|
+
{
|
|
198
|
+
contentType: action.contentType,
|
|
199
|
+
documentId: action.entryDocumentId,
|
|
200
|
+
locale: action.locale
|
|
201
|
+
},
|
|
202
|
+
{ strapi }
|
|
203
|
+
);
|
|
204
|
+
await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
205
|
+
where: {
|
|
206
|
+
id: action.id
|
|
207
|
+
},
|
|
208
|
+
data: {
|
|
209
|
+
isEntryValid: isEntryValid2
|
|
210
|
+
}
|
|
152
211
|
});
|
|
153
|
-
if (populatedEntry) {
|
|
154
|
-
const isEntryValid = getEntryValidStatus(action.contentType, populatedEntry, { strapi });
|
|
155
|
-
await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
156
|
-
where: {
|
|
157
|
-
id: action.id
|
|
158
|
-
},
|
|
159
|
-
data: {
|
|
160
|
-
isEntryValid
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
212
|
}
|
|
165
213
|
}
|
|
166
214
|
return getService("release", { strapi }).updateReleaseStatus(release2.id);
|
|
@@ -204,24 +252,24 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
204
252
|
}
|
|
205
253
|
});
|
|
206
254
|
await utils.async.map(actions, async (action) => {
|
|
207
|
-
if (action.entry && action.release) {
|
|
208
|
-
const
|
|
209
|
-
|
|
255
|
+
if (action.entry && action.release && action.type === "publish") {
|
|
256
|
+
const isEntryValid2 = await getDraftEntryValidStatus(
|
|
257
|
+
{
|
|
258
|
+
contentType: contentTypeUID,
|
|
259
|
+
documentId: action.entryDocumentId,
|
|
260
|
+
locale: action.locale
|
|
261
|
+
},
|
|
262
|
+
{ strapi }
|
|
263
|
+
);
|
|
264
|
+
releasesAffected.add(action.release.id);
|
|
265
|
+
await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
266
|
+
where: {
|
|
267
|
+
id: action.id
|
|
268
|
+
},
|
|
269
|
+
data: {
|
|
270
|
+
isEntryValid: isEntryValid2
|
|
271
|
+
}
|
|
210
272
|
});
|
|
211
|
-
if (populatedEntry) {
|
|
212
|
-
const isEntryValid = await getEntryValidStatus(contentTypeUID, populatedEntry, {
|
|
213
|
-
strapi
|
|
214
|
-
});
|
|
215
|
-
releasesAffected.add(action.release.id);
|
|
216
|
-
await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
217
|
-
where: {
|
|
218
|
-
id: action.id
|
|
219
|
-
},
|
|
220
|
-
data: {
|
|
221
|
-
isEntryValid
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
273
|
}
|
|
226
274
|
});
|
|
227
275
|
}
|
|
@@ -236,13 +284,16 @@ async function disableContentTypeLocalized({ oldContentTypes, contentTypes: cont
|
|
|
236
284
|
if (!oldContentTypes) {
|
|
237
285
|
return;
|
|
238
286
|
}
|
|
287
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
288
|
+
if (!i18nPlugin) {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
239
291
|
for (const uid in contentTypes2) {
|
|
240
292
|
if (!oldContentTypes[uid]) {
|
|
241
293
|
continue;
|
|
242
294
|
}
|
|
243
295
|
const oldContentType = oldContentTypes[uid];
|
|
244
296
|
const contentType = contentTypes2[uid];
|
|
245
|
-
const i18nPlugin = strapi.plugin("i18n");
|
|
246
297
|
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
247
298
|
if (isLocalizedContentType(oldContentType) && !isLocalizedContentType(contentType)) {
|
|
248
299
|
await strapi.db.queryBuilder(RELEASE_ACTION_MODEL_UID).update({
|
|
@@ -255,13 +306,16 @@ async function enableContentTypeLocalized({ oldContentTypes, contentTypes: conte
|
|
|
255
306
|
if (!oldContentTypes) {
|
|
256
307
|
return;
|
|
257
308
|
}
|
|
309
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
310
|
+
if (!i18nPlugin) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
258
313
|
for (const uid in contentTypes2) {
|
|
259
314
|
if (!oldContentTypes[uid]) {
|
|
260
315
|
continue;
|
|
261
316
|
}
|
|
262
317
|
const oldContentType = oldContentTypes[uid];
|
|
263
318
|
const contentType = contentTypes2[uid];
|
|
264
|
-
const i18nPlugin = strapi.plugin("i18n");
|
|
265
319
|
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
266
320
|
const { getDefaultLocale } = i18nPlugin.service("locales");
|
|
267
321
|
if (!isLocalizedContentType(oldContentType) && isLocalizedContentType(contentType)) {
|
|
@@ -272,9 +326,38 @@ async function enableContentTypeLocalized({ oldContentTypes, contentTypes: conte
|
|
|
272
326
|
}
|
|
273
327
|
}
|
|
274
328
|
}
|
|
329
|
+
const addEntryDocumentToReleaseActions = {
|
|
330
|
+
name: "content-releases::5.0.0-add-entry-document-id-to-release-actions",
|
|
331
|
+
async up(trx, db) {
|
|
332
|
+
const hasPolymorphicColumn = await trx.schema.hasColumn("strapi_release_actions", "target_id");
|
|
333
|
+
if (hasPolymorphicColumn) {
|
|
334
|
+
const hasEntryDocumentIdColumn = await trx.schema.hasColumn(
|
|
335
|
+
"strapi_release_actions",
|
|
336
|
+
"entry_document_id"
|
|
337
|
+
);
|
|
338
|
+
if (!hasEntryDocumentIdColumn) {
|
|
339
|
+
await trx.schema.alterTable("strapi_release_actions", (table) => {
|
|
340
|
+
table.string("entry_document_id");
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
const releaseActions = await trx.select("*").from("strapi_release_actions");
|
|
344
|
+
utils.async.map(releaseActions, async (action) => {
|
|
345
|
+
const { target_type, target_id } = action;
|
|
346
|
+
const entry = await db.query(target_type).findOne({ where: { id: target_id } });
|
|
347
|
+
if (entry) {
|
|
348
|
+
await trx("strapi_release_actions").update({ entry_document_id: entry.documentId }).where("id", action.id);
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
},
|
|
353
|
+
async down() {
|
|
354
|
+
throw new Error("not implemented");
|
|
355
|
+
}
|
|
356
|
+
};
|
|
275
357
|
const register = async ({ strapi: strapi2 }) => {
|
|
276
358
|
if (strapi2.ee.features.isEnabled("cms-content-releases")) {
|
|
277
|
-
await strapi2.admin
|
|
359
|
+
await strapi2.service("admin::permission").actionProvider.registerMany(ACTIONS);
|
|
360
|
+
strapi2.db.migrations.providers.internal.register(addEntryDocumentToReleaseActions);
|
|
278
361
|
strapi2.hook("strapi::content-types.beforeSync").register(disableContentTypeLocalized).register(deleteActionsOnDisableDraftAndPublish);
|
|
279
362
|
strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType).register(enableContentTypeLocalized).register(revalidateChangedContentTypes).register(migrateIsValidAndStatusReleases);
|
|
280
363
|
}
|
|
@@ -284,6 +367,104 @@ const register = async ({ strapi: strapi2 }) => {
|
|
|
284
367
|
graphqlExtensionService.shadowCRUD(RELEASE_ACTION_MODEL_UID).disable();
|
|
285
368
|
}
|
|
286
369
|
};
|
|
370
|
+
const updateActionsStatusAndUpdateReleaseStatus = async (contentType, entry) => {
|
|
371
|
+
const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({
|
|
372
|
+
where: {
|
|
373
|
+
actions: {
|
|
374
|
+
contentType,
|
|
375
|
+
entryDocumentId: entry.documentId,
|
|
376
|
+
locale: entry.locale
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
});
|
|
380
|
+
const entryStatus = await isEntryValid(contentType, entry, { strapi });
|
|
381
|
+
await strapi.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
382
|
+
where: {
|
|
383
|
+
contentType,
|
|
384
|
+
entryDocumentId: entry.documentId,
|
|
385
|
+
locale: entry.locale
|
|
386
|
+
},
|
|
387
|
+
data: {
|
|
388
|
+
isEntryValid: entryStatus
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
for (const release2 of releases) {
|
|
392
|
+
getService("release", { strapi }).updateReleaseStatus(release2.id);
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
const deleteActionsAndUpdateReleaseStatus = async (params) => {
|
|
396
|
+
const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({
|
|
397
|
+
where: {
|
|
398
|
+
actions: params
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
|
402
|
+
where: params
|
|
403
|
+
});
|
|
404
|
+
for (const release2 of releases) {
|
|
405
|
+
getService("release", { strapi }).updateReleaseStatus(release2.id);
|
|
406
|
+
}
|
|
407
|
+
};
|
|
408
|
+
const deleteActionsOnDelete = async (ctx, next) => {
|
|
409
|
+
if (ctx.action !== "delete") {
|
|
410
|
+
return next();
|
|
411
|
+
}
|
|
412
|
+
if (!utils.contentTypes.hasDraftAndPublish(ctx.contentType)) {
|
|
413
|
+
return next();
|
|
414
|
+
}
|
|
415
|
+
const contentType = ctx.contentType.uid;
|
|
416
|
+
const { documentId, locale } = ctx.params;
|
|
417
|
+
const result = await next();
|
|
418
|
+
if (!result) {
|
|
419
|
+
return result;
|
|
420
|
+
}
|
|
421
|
+
try {
|
|
422
|
+
deleteActionsAndUpdateReleaseStatus({
|
|
423
|
+
contentType,
|
|
424
|
+
entryDocumentId: documentId,
|
|
425
|
+
...locale !== "*" && { locale }
|
|
426
|
+
});
|
|
427
|
+
} catch (error) {
|
|
428
|
+
strapi.log.error("Error while deleting release actions after delete", {
|
|
429
|
+
error
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
return result;
|
|
433
|
+
};
|
|
434
|
+
const updateActionsOnUpdate = async (ctx, next) => {
|
|
435
|
+
if (ctx.action !== "update") {
|
|
436
|
+
return next();
|
|
437
|
+
}
|
|
438
|
+
if (!utils.contentTypes.hasDraftAndPublish(ctx.contentType)) {
|
|
439
|
+
return next();
|
|
440
|
+
}
|
|
441
|
+
const contentType = ctx.contentType.uid;
|
|
442
|
+
const result = await next();
|
|
443
|
+
if (!result) {
|
|
444
|
+
return result;
|
|
445
|
+
}
|
|
446
|
+
try {
|
|
447
|
+
updateActionsStatusAndUpdateReleaseStatus(contentType, result);
|
|
448
|
+
} catch (error) {
|
|
449
|
+
strapi.log.error("Error while updating release actions after update", {
|
|
450
|
+
error
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
return result;
|
|
454
|
+
};
|
|
455
|
+
const deleteReleasesActionsAndUpdateReleaseStatus = async (params) => {
|
|
456
|
+
const releases = await strapi.db.query(RELEASE_MODEL_UID).findMany({
|
|
457
|
+
where: {
|
|
458
|
+
actions: params
|
|
459
|
+
}
|
|
460
|
+
});
|
|
461
|
+
await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
|
462
|
+
where: params
|
|
463
|
+
});
|
|
464
|
+
for (const release2 of releases) {
|
|
465
|
+
getService("release", { strapi }).updateReleaseStatus(release2.id);
|
|
466
|
+
}
|
|
467
|
+
};
|
|
287
468
|
const bootstrap = async ({ strapi: strapi2 }) => {
|
|
288
469
|
if (strapi2.ee.features.isEnabled("cms-content-releases")) {
|
|
289
470
|
const contentTypesWithDraftAndPublish = Object.keys(strapi2.contentTypes).filter(
|
|
@@ -291,115 +472,29 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
291
472
|
);
|
|
292
473
|
strapi2.db.lifecycles.subscribe({
|
|
293
474
|
models: contentTypesWithDraftAndPublish,
|
|
294
|
-
async afterDelete(event) {
|
|
295
|
-
try {
|
|
296
|
-
const { model, result } = event;
|
|
297
|
-
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
298
|
-
const { id } = result;
|
|
299
|
-
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
300
|
-
where: {
|
|
301
|
-
actions: {
|
|
302
|
-
target_type: model.uid,
|
|
303
|
-
target_id: id
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
});
|
|
307
|
-
await strapi2.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
|
308
|
-
where: {
|
|
309
|
-
target_type: model.uid,
|
|
310
|
-
target_id: id
|
|
311
|
-
}
|
|
312
|
-
});
|
|
313
|
-
for (const release2 of releases) {
|
|
314
|
-
getService("release", { strapi: strapi2 }).updateReleaseStatus(release2.id);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
} catch (error) {
|
|
318
|
-
strapi2.log.error("Error while deleting release actions after entry delete", { error });
|
|
319
|
-
}
|
|
320
|
-
},
|
|
321
|
-
/**
|
|
322
|
-
* deleteMany hook doesn't return the deleted entries ids
|
|
323
|
-
* so we need to fetch them before deleting the entries to save the ids on our state
|
|
324
|
-
*/
|
|
325
|
-
async beforeDeleteMany(event) {
|
|
326
|
-
const { model, params } = event;
|
|
327
|
-
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
328
|
-
const { where } = params;
|
|
329
|
-
const entriesToDelete = await strapi2.db.query(model.uid).findMany({ select: ["id"], where });
|
|
330
|
-
event.state.entriesToDelete = entriesToDelete;
|
|
331
|
-
}
|
|
332
|
-
},
|
|
333
475
|
/**
|
|
334
|
-
*
|
|
335
|
-
* We make this only after deleteMany is succesfully executed to avoid errors
|
|
476
|
+
* deleteMany is still used outside documents service, for example when deleting a locale
|
|
336
477
|
*/
|
|
337
478
|
async afterDeleteMany(event) {
|
|
338
479
|
try {
|
|
339
|
-
const
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
target_id: {
|
|
347
|
-
$in: entriesToDelete.map((entry) => entry.id)
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
});
|
|
352
|
-
await strapi2.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
|
353
|
-
where: {
|
|
354
|
-
target_type: model.uid,
|
|
355
|
-
target_id: {
|
|
356
|
-
$in: entriesToDelete.map((entry) => entry.id)
|
|
357
|
-
}
|
|
358
|
-
}
|
|
480
|
+
const model = strapi2.getModel(event.model.uid);
|
|
481
|
+
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
482
|
+
const { where } = event.params;
|
|
483
|
+
deleteReleasesActionsAndUpdateReleaseStatus({
|
|
484
|
+
contentType: model.uid,
|
|
485
|
+
locale: where.locale ?? null,
|
|
486
|
+
...where.documentId && { entryDocumentId: where.documentId }
|
|
359
487
|
});
|
|
360
|
-
for (const release2 of releases) {
|
|
361
|
-
getService("release", { strapi: strapi2 }).updateReleaseStatus(release2.id);
|
|
362
|
-
}
|
|
363
488
|
}
|
|
364
489
|
} catch (error) {
|
|
365
490
|
strapi2.log.error("Error while deleting release actions after entry deleteMany", {
|
|
366
491
|
error
|
|
367
492
|
});
|
|
368
493
|
}
|
|
369
|
-
},
|
|
370
|
-
async afterUpdate(event) {
|
|
371
|
-
try {
|
|
372
|
-
const { model, result } = event;
|
|
373
|
-
if (model.kind === "collectionType" && model.options?.draftAndPublish) {
|
|
374
|
-
const isEntryValid = await getEntryValidStatus(model.uid, result, {
|
|
375
|
-
strapi: strapi2
|
|
376
|
-
});
|
|
377
|
-
await strapi2.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
378
|
-
where: {
|
|
379
|
-
target_type: model.uid,
|
|
380
|
-
target_id: result.id
|
|
381
|
-
},
|
|
382
|
-
data: {
|
|
383
|
-
isEntryValid
|
|
384
|
-
}
|
|
385
|
-
});
|
|
386
|
-
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
387
|
-
where: {
|
|
388
|
-
actions: {
|
|
389
|
-
target_type: model.uid,
|
|
390
|
-
target_id: result.id
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
});
|
|
394
|
-
for (const release2 of releases) {
|
|
395
|
-
getService("release", { strapi: strapi2 }).updateReleaseStatus(release2.id);
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
} catch (error) {
|
|
399
|
-
strapi2.log.error("Error while updating release actions after entry update", { error });
|
|
400
|
-
}
|
|
401
494
|
}
|
|
402
495
|
});
|
|
496
|
+
strapi2.documents.use(deleteActionsOnDelete);
|
|
497
|
+
strapi2.documents.use(updateActionsOnUpdate);
|
|
403
498
|
getService("scheduling", { strapi: strapi2 }).syncFromDatabase().catch((err) => {
|
|
404
499
|
strapi2.log.error(
|
|
405
500
|
"Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling."
|
|
@@ -407,7 +502,7 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
407
502
|
throw err;
|
|
408
503
|
});
|
|
409
504
|
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
|
410
|
-
strapi2.webhookStore.addAllowedEvent(key, value);
|
|
505
|
+
strapi2.get("webhookStore").addAllowedEvent(key, value);
|
|
411
506
|
});
|
|
412
507
|
}
|
|
413
508
|
};
|
|
@@ -491,15 +586,13 @@ const schema = {
|
|
|
491
586
|
enum: ["publish", "unpublish"],
|
|
492
587
|
required: true
|
|
493
588
|
},
|
|
494
|
-
entry: {
|
|
495
|
-
type: "relation",
|
|
496
|
-
relation: "morphToOne",
|
|
497
|
-
configurable: false
|
|
498
|
-
},
|
|
499
589
|
contentType: {
|
|
500
590
|
type: "string",
|
|
501
591
|
required: true
|
|
502
592
|
},
|
|
593
|
+
entryDocumentId: {
|
|
594
|
+
type: "string"
|
|
595
|
+
},
|
|
503
596
|
locale: {
|
|
504
597
|
type: "string"
|
|
505
598
|
},
|
|
@@ -521,18 +614,6 @@ const contentTypes = {
|
|
|
521
614
|
release: release$1,
|
|
522
615
|
"release-action": releaseAction$1
|
|
523
616
|
};
|
|
524
|
-
const getGroupName = (queryValue) => {
|
|
525
|
-
switch (queryValue) {
|
|
526
|
-
case "contentType":
|
|
527
|
-
return "contentType.displayName";
|
|
528
|
-
case "action":
|
|
529
|
-
return "type";
|
|
530
|
-
case "locale":
|
|
531
|
-
return ___default.default.getOr("No locale", "locale.name");
|
|
532
|
-
default:
|
|
533
|
-
return "contentType.displayName";
|
|
534
|
-
}
|
|
535
|
-
};
|
|
536
617
|
const createReleaseService = ({ strapi: strapi2 }) => {
|
|
537
618
|
const dispatchWebhook = (event, { isPublished, release: release2, error }) => {
|
|
538
619
|
strapi2.eventHub.emit(event, {
|
|
@@ -541,93 +622,32 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
541
622
|
release: release2
|
|
542
623
|
});
|
|
543
624
|
};
|
|
544
|
-
const publishSingleTypeAction = async (uid, actionType, entryId) => {
|
|
545
|
-
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
546
|
-
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
547
|
-
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
548
|
-
const entry = await strapi2.entityService.findOne(uid, entryId, { populate });
|
|
549
|
-
try {
|
|
550
|
-
if (actionType === "publish") {
|
|
551
|
-
await entityManagerService.publish(entry, uid);
|
|
552
|
-
} else {
|
|
553
|
-
await entityManagerService.unpublish(entry, uid);
|
|
554
|
-
}
|
|
555
|
-
} catch (error) {
|
|
556
|
-
if (error instanceof utils.errors.ApplicationError && (error.message === "already.published" || error.message === "already.draft"))
|
|
557
|
-
;
|
|
558
|
-
else {
|
|
559
|
-
throw error;
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
};
|
|
563
|
-
const publishCollectionTypeAction = async (uid, entriesToPublishIds, entriestoUnpublishIds) => {
|
|
564
|
-
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
565
|
-
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
566
|
-
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
567
|
-
const entriesToPublish = await strapi2.entityService.findMany(uid, {
|
|
568
|
-
filters: {
|
|
569
|
-
id: {
|
|
570
|
-
$in: entriesToPublishIds
|
|
571
|
-
}
|
|
572
|
-
},
|
|
573
|
-
populate
|
|
574
|
-
});
|
|
575
|
-
const entriesToUnpublish = await strapi2.entityService.findMany(uid, {
|
|
576
|
-
filters: {
|
|
577
|
-
id: {
|
|
578
|
-
$in: entriestoUnpublishIds
|
|
579
|
-
}
|
|
580
|
-
},
|
|
581
|
-
populate
|
|
582
|
-
});
|
|
583
|
-
if (entriesToPublish.length > 0) {
|
|
584
|
-
await entityManagerService.publishMany(entriesToPublish, uid);
|
|
585
|
-
}
|
|
586
|
-
if (entriesToUnpublish.length > 0) {
|
|
587
|
-
await entityManagerService.unpublishMany(entriesToUnpublish, uid);
|
|
588
|
-
}
|
|
589
|
-
};
|
|
590
625
|
const getFormattedActions = async (releaseId) => {
|
|
591
626
|
const actions = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).findMany({
|
|
592
627
|
where: {
|
|
593
628
|
release: {
|
|
594
629
|
id: releaseId
|
|
595
630
|
}
|
|
596
|
-
},
|
|
597
|
-
populate: {
|
|
598
|
-
entry: {
|
|
599
|
-
fields: ["id"]
|
|
600
|
-
}
|
|
601
631
|
}
|
|
602
632
|
});
|
|
603
633
|
if (actions.length === 0) {
|
|
604
634
|
throw new utils.errors.ValidationError("No entries to publish");
|
|
605
635
|
}
|
|
606
|
-
const
|
|
607
|
-
const singleTypeActions = [];
|
|
636
|
+
const formattedActions = {};
|
|
608
637
|
for (const action of actions) {
|
|
609
638
|
const contentTypeUid = action.contentType;
|
|
610
|
-
if (
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
};
|
|
616
|
-
}
|
|
617
|
-
if (action.type === "publish") {
|
|
618
|
-
collectionTypeActions[contentTypeUid].entriesToPublishIds.push(action.entry.id);
|
|
619
|
-
} else {
|
|
620
|
-
collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
621
|
-
}
|
|
622
|
-
} else {
|
|
623
|
-
singleTypeActions.push({
|
|
624
|
-
uid: contentTypeUid,
|
|
625
|
-
action: action.type,
|
|
626
|
-
id: action.entry.id
|
|
627
|
-
});
|
|
639
|
+
if (!formattedActions[contentTypeUid]) {
|
|
640
|
+
formattedActions[contentTypeUid] = {
|
|
641
|
+
publish: [],
|
|
642
|
+
unpublish: []
|
|
643
|
+
};
|
|
628
644
|
}
|
|
645
|
+
formattedActions[contentTypeUid][action.type].push({
|
|
646
|
+
documentId: action.entryDocumentId,
|
|
647
|
+
locale: action.locale
|
|
648
|
+
});
|
|
629
649
|
}
|
|
630
|
-
return
|
|
650
|
+
return formattedActions;
|
|
631
651
|
};
|
|
632
652
|
return {
|
|
633
653
|
async create(releaseData, { user }) {
|
|
@@ -674,78 +694,10 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
674
694
|
}
|
|
675
695
|
});
|
|
676
696
|
},
|
|
677
|
-
|
|
678
|
-
const
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
target_type: contentTypeUid,
|
|
682
|
-
target_id: entryId
|
|
683
|
-
},
|
|
684
|
-
releasedAt: {
|
|
685
|
-
$null: true
|
|
686
|
-
}
|
|
687
|
-
},
|
|
688
|
-
populate: {
|
|
689
|
-
// Filter the action to get only the content type entry
|
|
690
|
-
actions: {
|
|
691
|
-
where: {
|
|
692
|
-
target_type: contentTypeUid,
|
|
693
|
-
target_id: entryId
|
|
694
|
-
}
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
});
|
|
698
|
-
return releases.map((release2) => {
|
|
699
|
-
if (release2.actions?.length) {
|
|
700
|
-
const [actionForEntry] = release2.actions;
|
|
701
|
-
delete release2.actions;
|
|
702
|
-
return {
|
|
703
|
-
...release2,
|
|
704
|
-
action: actionForEntry
|
|
705
|
-
};
|
|
706
|
-
}
|
|
707
|
-
return release2;
|
|
708
|
-
});
|
|
709
|
-
},
|
|
710
|
-
async findManyWithoutContentTypeEntryAttached(contentTypeUid, entryId) {
|
|
711
|
-
const releasesRelated = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
712
|
-
where: {
|
|
713
|
-
releasedAt: {
|
|
714
|
-
$null: true
|
|
715
|
-
},
|
|
716
|
-
actions: {
|
|
717
|
-
target_type: contentTypeUid,
|
|
718
|
-
target_id: entryId
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
});
|
|
722
|
-
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
723
|
-
where: {
|
|
724
|
-
$or: [
|
|
725
|
-
{
|
|
726
|
-
id: {
|
|
727
|
-
$notIn: releasesRelated.map((release2) => release2.id)
|
|
728
|
-
}
|
|
729
|
-
},
|
|
730
|
-
{
|
|
731
|
-
actions: null
|
|
732
|
-
}
|
|
733
|
-
],
|
|
734
|
-
releasedAt: {
|
|
735
|
-
$null: true
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
});
|
|
739
|
-
return releases.map((release2) => {
|
|
740
|
-
if (release2.actions?.length) {
|
|
741
|
-
const [actionForEntry] = release2.actions;
|
|
742
|
-
delete release2.actions;
|
|
743
|
-
return {
|
|
744
|
-
...release2,
|
|
745
|
-
action: actionForEntry
|
|
746
|
-
};
|
|
747
|
-
}
|
|
748
|
-
return release2;
|
|
697
|
+
findMany(query) {
|
|
698
|
+
const dbQuery = strapi2.get("query-params").transform(RELEASE_MODEL_UID, query ?? {});
|
|
699
|
+
return strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
700
|
+
...dbQuery
|
|
749
701
|
});
|
|
750
702
|
},
|
|
751
703
|
async update(id, releaseData, { user }) {
|
|
@@ -781,133 +733,6 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
781
733
|
strapi2.telemetry.send("didUpdateContentRelease");
|
|
782
734
|
return updatedRelease;
|
|
783
735
|
},
|
|
784
|
-
async createAction(releaseId, action) {
|
|
785
|
-
const { validateEntryContentType, validateUniqueEntry } = getService("release-validation", {
|
|
786
|
-
strapi: strapi2
|
|
787
|
-
});
|
|
788
|
-
await Promise.all([
|
|
789
|
-
validateEntryContentType(action.entry.contentType),
|
|
790
|
-
validateUniqueEntry(releaseId, action)
|
|
791
|
-
]);
|
|
792
|
-
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({ where: { id: releaseId } });
|
|
793
|
-
if (!release2) {
|
|
794
|
-
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
795
|
-
}
|
|
796
|
-
if (release2.releasedAt) {
|
|
797
|
-
throw new utils.errors.ValidationError("Release already published");
|
|
798
|
-
}
|
|
799
|
-
const { entry, type } = action;
|
|
800
|
-
const populatedEntry = await getPopulatedEntry(entry.contentType, entry.id, { strapi: strapi2 });
|
|
801
|
-
const isEntryValid = await getEntryValidStatus(entry.contentType, populatedEntry, { strapi: strapi2 });
|
|
802
|
-
const releaseAction2 = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).create({
|
|
803
|
-
data: {
|
|
804
|
-
type,
|
|
805
|
-
contentType: entry.contentType,
|
|
806
|
-
locale: entry.locale,
|
|
807
|
-
isEntryValid,
|
|
808
|
-
entry: {
|
|
809
|
-
id: entry.id,
|
|
810
|
-
__type: entry.contentType,
|
|
811
|
-
__pivot: { field: "entry" }
|
|
812
|
-
},
|
|
813
|
-
release: releaseId
|
|
814
|
-
},
|
|
815
|
-
populate: { release: { select: ["id"] }, entry: { select: ["id"] } }
|
|
816
|
-
});
|
|
817
|
-
this.updateReleaseStatus(releaseId);
|
|
818
|
-
return releaseAction2;
|
|
819
|
-
},
|
|
820
|
-
async findActions(releaseId, query) {
|
|
821
|
-
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
822
|
-
where: { id: releaseId },
|
|
823
|
-
select: ["id"]
|
|
824
|
-
});
|
|
825
|
-
if (!release2) {
|
|
826
|
-
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
827
|
-
}
|
|
828
|
-
const dbQuery = strapi2.get("query-params").transform(RELEASE_ACTION_MODEL_UID, query ?? {});
|
|
829
|
-
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).findPage({
|
|
830
|
-
...dbQuery,
|
|
831
|
-
populate: {
|
|
832
|
-
entry: {
|
|
833
|
-
populate: "*"
|
|
834
|
-
}
|
|
835
|
-
},
|
|
836
|
-
where: {
|
|
837
|
-
release: releaseId
|
|
838
|
-
}
|
|
839
|
-
});
|
|
840
|
-
},
|
|
841
|
-
async countActions(query) {
|
|
842
|
-
const dbQuery = strapi2.get("query-params").transform(RELEASE_ACTION_MODEL_UID, query ?? {});
|
|
843
|
-
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).count(dbQuery);
|
|
844
|
-
},
|
|
845
|
-
async groupActions(actions, groupBy) {
|
|
846
|
-
const contentTypeUids = actions.reduce((acc, action) => {
|
|
847
|
-
if (!acc.includes(action.contentType)) {
|
|
848
|
-
acc.push(action.contentType);
|
|
849
|
-
}
|
|
850
|
-
return acc;
|
|
851
|
-
}, []);
|
|
852
|
-
const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(
|
|
853
|
-
contentTypeUids
|
|
854
|
-
);
|
|
855
|
-
const allLocalesDictionary = await this.getLocalesDataForActions();
|
|
856
|
-
const formattedData = actions.map((action) => {
|
|
857
|
-
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
858
|
-
return {
|
|
859
|
-
...action,
|
|
860
|
-
locale: action.locale ? allLocalesDictionary[action.locale] : null,
|
|
861
|
-
contentType: {
|
|
862
|
-
displayName,
|
|
863
|
-
mainFieldValue: action.entry[mainField],
|
|
864
|
-
uid: action.contentType
|
|
865
|
-
}
|
|
866
|
-
};
|
|
867
|
-
});
|
|
868
|
-
const groupName = getGroupName(groupBy);
|
|
869
|
-
return ___default.default.groupBy(groupName)(formattedData);
|
|
870
|
-
},
|
|
871
|
-
async getLocalesDataForActions() {
|
|
872
|
-
if (!strapi2.plugin("i18n")) {
|
|
873
|
-
return {};
|
|
874
|
-
}
|
|
875
|
-
const allLocales = await strapi2.plugin("i18n").service("locales").find() || [];
|
|
876
|
-
return allLocales.reduce((acc, locale) => {
|
|
877
|
-
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
878
|
-
return acc;
|
|
879
|
-
}, {});
|
|
880
|
-
},
|
|
881
|
-
async getContentTypesDataForActions(contentTypesUids) {
|
|
882
|
-
const contentManagerContentTypeService = strapi2.plugin("content-manager").service("content-types");
|
|
883
|
-
const contentTypesData = {};
|
|
884
|
-
for (const contentTypeUid of contentTypesUids) {
|
|
885
|
-
const contentTypeConfig = await contentManagerContentTypeService.findConfiguration({
|
|
886
|
-
uid: contentTypeUid
|
|
887
|
-
});
|
|
888
|
-
contentTypesData[contentTypeUid] = {
|
|
889
|
-
mainField: contentTypeConfig.settings.mainField,
|
|
890
|
-
displayName: strapi2.getModel(contentTypeUid).info.displayName
|
|
891
|
-
};
|
|
892
|
-
}
|
|
893
|
-
return contentTypesData;
|
|
894
|
-
},
|
|
895
|
-
getContentTypeModelsFromActions(actions) {
|
|
896
|
-
const contentTypeUids = actions.reduce((acc, action) => {
|
|
897
|
-
if (!acc.includes(action.contentType)) {
|
|
898
|
-
acc.push(action.contentType);
|
|
899
|
-
}
|
|
900
|
-
return acc;
|
|
901
|
-
}, []);
|
|
902
|
-
const contentTypeModelsMap = contentTypeUids.reduce(
|
|
903
|
-
(acc, contentTypeUid) => {
|
|
904
|
-
acc[contentTypeUid] = strapi2.getModel(contentTypeUid);
|
|
905
|
-
return acc;
|
|
906
|
-
},
|
|
907
|
-
{}
|
|
908
|
-
);
|
|
909
|
-
return contentTypeModelsMap;
|
|
910
|
-
},
|
|
911
736
|
async getAllComponents() {
|
|
912
737
|
const contentManagerComponentsService = strapi2.plugin("content-manager").service("components");
|
|
913
738
|
const components = await contentManagerComponentsService.findAllComponents();
|
|
@@ -973,22 +798,19 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
973
798
|
}
|
|
974
799
|
try {
|
|
975
800
|
strapi2.log.info(`[Content Releases] Starting to publish release ${lockedRelease.name}`);
|
|
976
|
-
const
|
|
977
|
-
|
|
801
|
+
const formattedActions = await getFormattedActions(releaseId);
|
|
802
|
+
await strapi2.db.transaction(
|
|
803
|
+
async () => Promise.all(
|
|
804
|
+
Object.keys(formattedActions).map(async (contentTypeUid) => {
|
|
805
|
+
const contentType = contentTypeUid;
|
|
806
|
+
const { publish, unpublish } = formattedActions[contentType];
|
|
807
|
+
return Promise.all([
|
|
808
|
+
...publish.map((params) => strapi2.documents(contentType).publish(params)),
|
|
809
|
+
...unpublish.map((params) => strapi2.documents(contentType).unpublish(params))
|
|
810
|
+
]);
|
|
811
|
+
})
|
|
812
|
+
)
|
|
978
813
|
);
|
|
979
|
-
await strapi2.db.transaction(async () => {
|
|
980
|
-
for (const { uid, action, id } of singleTypeActions) {
|
|
981
|
-
await publishSingleTypeAction(uid, action, id);
|
|
982
|
-
}
|
|
983
|
-
for (const contentTypeUid of Object.keys(collectionTypeActions)) {
|
|
984
|
-
const uid = contentTypeUid;
|
|
985
|
-
await publishCollectionTypeAction(
|
|
986
|
-
uid,
|
|
987
|
-
collectionTypeActions[uid].entriesToPublishIds,
|
|
988
|
-
collectionTypeActions[uid].entriesToUnpublishIds
|
|
989
|
-
);
|
|
990
|
-
}
|
|
991
|
-
});
|
|
992
814
|
const release22 = await strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
993
815
|
where: {
|
|
994
816
|
id: releaseId
|
|
@@ -1018,13 +840,216 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
1018
840
|
};
|
|
1019
841
|
}
|
|
1020
842
|
});
|
|
1021
|
-
if (error instanceof Error) {
|
|
1022
|
-
throw error;
|
|
1023
|
-
}
|
|
1024
|
-
return release2;
|
|
843
|
+
if (error instanceof Error) {
|
|
844
|
+
throw error;
|
|
845
|
+
}
|
|
846
|
+
return release2;
|
|
847
|
+
},
|
|
848
|
+
async updateReleaseStatus(releaseId) {
|
|
849
|
+
const releaseActionService = getService("release-action", { strapi: strapi2 });
|
|
850
|
+
const [totalActions, invalidActions] = await Promise.all([
|
|
851
|
+
releaseActionService.countActions({
|
|
852
|
+
filters: {
|
|
853
|
+
release: releaseId
|
|
854
|
+
}
|
|
855
|
+
}),
|
|
856
|
+
releaseActionService.countActions({
|
|
857
|
+
filters: {
|
|
858
|
+
release: releaseId,
|
|
859
|
+
isEntryValid: false
|
|
860
|
+
}
|
|
861
|
+
})
|
|
862
|
+
]);
|
|
863
|
+
if (totalActions > 0) {
|
|
864
|
+
if (invalidActions > 0) {
|
|
865
|
+
return strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
866
|
+
where: {
|
|
867
|
+
id: releaseId
|
|
868
|
+
},
|
|
869
|
+
data: {
|
|
870
|
+
status: "blocked"
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
return strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
875
|
+
where: {
|
|
876
|
+
id: releaseId
|
|
877
|
+
},
|
|
878
|
+
data: {
|
|
879
|
+
status: "ready"
|
|
880
|
+
}
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
return strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
884
|
+
where: {
|
|
885
|
+
id: releaseId
|
|
886
|
+
},
|
|
887
|
+
data: {
|
|
888
|
+
status: "empty"
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
}
|
|
892
|
+
};
|
|
893
|
+
};
|
|
894
|
+
const getGroupName = (queryValue) => {
|
|
895
|
+
switch (queryValue) {
|
|
896
|
+
case "contentType":
|
|
897
|
+
return "contentType.displayName";
|
|
898
|
+
case "type":
|
|
899
|
+
return "type";
|
|
900
|
+
case "locale":
|
|
901
|
+
return ___default.default.getOr("No locale", "locale.name");
|
|
902
|
+
default:
|
|
903
|
+
return "contentType.displayName";
|
|
904
|
+
}
|
|
905
|
+
};
|
|
906
|
+
const createReleaseActionService = ({ strapi: strapi2 }) => {
|
|
907
|
+
const getLocalesDataForActions = async () => {
|
|
908
|
+
if (!strapi2.plugin("i18n")) {
|
|
909
|
+
return {};
|
|
910
|
+
}
|
|
911
|
+
const allLocales = await strapi2.plugin("i18n").service("locales").find() || [];
|
|
912
|
+
return allLocales.reduce((acc, locale) => {
|
|
913
|
+
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
914
|
+
return acc;
|
|
915
|
+
}, {});
|
|
916
|
+
};
|
|
917
|
+
const getContentTypesDataForActions = async (contentTypesUids) => {
|
|
918
|
+
const contentManagerContentTypeService = strapi2.plugin("content-manager").service("content-types");
|
|
919
|
+
const contentTypesData = {};
|
|
920
|
+
for (const contentTypeUid of contentTypesUids) {
|
|
921
|
+
const contentTypeConfig = await contentManagerContentTypeService.findConfiguration({
|
|
922
|
+
uid: contentTypeUid
|
|
923
|
+
});
|
|
924
|
+
contentTypesData[contentTypeUid] = {
|
|
925
|
+
mainField: contentTypeConfig.settings.mainField,
|
|
926
|
+
displayName: strapi2.getModel(contentTypeUid).info.displayName
|
|
927
|
+
};
|
|
928
|
+
}
|
|
929
|
+
return contentTypesData;
|
|
930
|
+
};
|
|
931
|
+
return {
|
|
932
|
+
async create(releaseId, action) {
|
|
933
|
+
const { validateEntryData, validateUniqueEntry } = getService("release-validation", {
|
|
934
|
+
strapi: strapi2
|
|
935
|
+
});
|
|
936
|
+
await Promise.all([
|
|
937
|
+
validateEntryData(action.contentType, action.entryDocumentId),
|
|
938
|
+
validateUniqueEntry(releaseId, action)
|
|
939
|
+
]);
|
|
940
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({ where: { id: releaseId } });
|
|
941
|
+
if (!release2) {
|
|
942
|
+
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
943
|
+
}
|
|
944
|
+
if (release2.releasedAt) {
|
|
945
|
+
throw new utils.errors.ValidationError("Release already published");
|
|
946
|
+
}
|
|
947
|
+
const actionStatus = action.type === "publish" ? await getDraftEntryValidStatus(
|
|
948
|
+
{
|
|
949
|
+
contentType: action.contentType,
|
|
950
|
+
documentId: action.entryDocumentId,
|
|
951
|
+
locale: action.locale
|
|
952
|
+
},
|
|
953
|
+
{
|
|
954
|
+
strapi: strapi2
|
|
955
|
+
}
|
|
956
|
+
) : true;
|
|
957
|
+
const releaseAction2 = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).create({
|
|
958
|
+
data: {
|
|
959
|
+
...action,
|
|
960
|
+
release: release2.id,
|
|
961
|
+
isEntryValid: actionStatus
|
|
962
|
+
},
|
|
963
|
+
populate: { release: { select: ["id"] } }
|
|
964
|
+
});
|
|
965
|
+
getService("release", { strapi: strapi2 }).updateReleaseStatus(release2.id);
|
|
966
|
+
return releaseAction2;
|
|
967
|
+
},
|
|
968
|
+
async findPage(releaseId, query) {
|
|
969
|
+
const release2 = await strapi2.db.query(RELEASE_MODEL_UID).findOne({
|
|
970
|
+
where: { id: releaseId },
|
|
971
|
+
select: ["id"]
|
|
972
|
+
});
|
|
973
|
+
if (!release2) {
|
|
974
|
+
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
975
|
+
}
|
|
976
|
+
const dbQuery = strapi2.get("query-params").transform(RELEASE_ACTION_MODEL_UID, query ?? {});
|
|
977
|
+
const { results: actions, pagination } = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).findPage({
|
|
978
|
+
...dbQuery,
|
|
979
|
+
where: {
|
|
980
|
+
release: releaseId
|
|
981
|
+
}
|
|
982
|
+
});
|
|
983
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
984
|
+
const actionsWithEntry = await utils.async.map(actions, async (action) => {
|
|
985
|
+
const populate = await populateBuilderService(action.contentType).populateDeep(Infinity).build();
|
|
986
|
+
const entry = await getEntry(
|
|
987
|
+
{
|
|
988
|
+
contentType: action.contentType,
|
|
989
|
+
documentId: action.entryDocumentId,
|
|
990
|
+
locale: action.locale,
|
|
991
|
+
populate,
|
|
992
|
+
status: action.type === "publish" ? "draft" : "published"
|
|
993
|
+
},
|
|
994
|
+
{ strapi: strapi2 }
|
|
995
|
+
);
|
|
996
|
+
return {
|
|
997
|
+
...action,
|
|
998
|
+
entry,
|
|
999
|
+
status: entry ? await getEntryStatus(action.contentType, entry) : null
|
|
1000
|
+
};
|
|
1001
|
+
});
|
|
1002
|
+
return {
|
|
1003
|
+
results: actionsWithEntry,
|
|
1004
|
+
pagination
|
|
1005
|
+
};
|
|
1006
|
+
},
|
|
1007
|
+
async groupActions(actions, groupBy) {
|
|
1008
|
+
const contentTypeUids = actions.reduce((acc, action) => {
|
|
1009
|
+
if (!acc.includes(action.contentType)) {
|
|
1010
|
+
acc.push(action.contentType);
|
|
1011
|
+
}
|
|
1012
|
+
return acc;
|
|
1013
|
+
}, []);
|
|
1014
|
+
const allReleaseContentTypesDictionary = await getContentTypesDataForActions(contentTypeUids);
|
|
1015
|
+
const allLocalesDictionary = await getLocalesDataForActions();
|
|
1016
|
+
const formattedData = actions.map((action) => {
|
|
1017
|
+
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
1018
|
+
return {
|
|
1019
|
+
...action,
|
|
1020
|
+
locale: action.locale ? allLocalesDictionary[action.locale] : null,
|
|
1021
|
+
contentType: {
|
|
1022
|
+
displayName,
|
|
1023
|
+
mainFieldValue: action.entry[mainField],
|
|
1024
|
+
uid: action.contentType
|
|
1025
|
+
}
|
|
1026
|
+
};
|
|
1027
|
+
});
|
|
1028
|
+
const groupName = getGroupName(groupBy);
|
|
1029
|
+
return ___default.default.groupBy(groupName)(formattedData);
|
|
1025
1030
|
},
|
|
1026
|
-
|
|
1027
|
-
const
|
|
1031
|
+
getContentTypeModelsFromActions(actions) {
|
|
1032
|
+
const contentTypeUids = actions.reduce((acc, action) => {
|
|
1033
|
+
if (!acc.includes(action.contentType)) {
|
|
1034
|
+
acc.push(action.contentType);
|
|
1035
|
+
}
|
|
1036
|
+
return acc;
|
|
1037
|
+
}, []);
|
|
1038
|
+
const contentTypeModelsMap = contentTypeUids.reduce(
|
|
1039
|
+
(acc, contentTypeUid) => {
|
|
1040
|
+
acc[contentTypeUid] = strapi2.getModel(contentTypeUid);
|
|
1041
|
+
return acc;
|
|
1042
|
+
},
|
|
1043
|
+
{}
|
|
1044
|
+
);
|
|
1045
|
+
return contentTypeModelsMap;
|
|
1046
|
+
},
|
|
1047
|
+
async countActions(query) {
|
|
1048
|
+
const dbQuery = strapi2.get("query-params").transform(RELEASE_ACTION_MODEL_UID, query ?? {});
|
|
1049
|
+
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).count(dbQuery);
|
|
1050
|
+
},
|
|
1051
|
+
async update(actionId, releaseId, update) {
|
|
1052
|
+
const action = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).findOne({
|
|
1028
1053
|
where: {
|
|
1029
1054
|
id: actionId,
|
|
1030
1055
|
release: {
|
|
@@ -1033,17 +1058,42 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
1033
1058
|
$null: true
|
|
1034
1059
|
}
|
|
1035
1060
|
}
|
|
1036
|
-
}
|
|
1037
|
-
data: update
|
|
1061
|
+
}
|
|
1038
1062
|
});
|
|
1039
|
-
if (!
|
|
1063
|
+
if (!action) {
|
|
1040
1064
|
throw new utils.errors.NotFoundError(
|
|
1041
1065
|
`Action with id ${actionId} not found in release with id ${releaseId} or it is already published`
|
|
1042
1066
|
);
|
|
1043
1067
|
}
|
|
1068
|
+
const actionStatus = update.type === "publish" ? getDraftEntryValidStatus(
|
|
1069
|
+
{
|
|
1070
|
+
contentType: action.contentType,
|
|
1071
|
+
documentId: action.entryDocumentId,
|
|
1072
|
+
locale: action.locale
|
|
1073
|
+
},
|
|
1074
|
+
{
|
|
1075
|
+
strapi: strapi2
|
|
1076
|
+
}
|
|
1077
|
+
) : true;
|
|
1078
|
+
const updatedAction = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
1079
|
+
where: {
|
|
1080
|
+
id: actionId,
|
|
1081
|
+
release: {
|
|
1082
|
+
id: releaseId,
|
|
1083
|
+
releasedAt: {
|
|
1084
|
+
$null: true
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
},
|
|
1088
|
+
data: {
|
|
1089
|
+
...update,
|
|
1090
|
+
isEntryValid: actionStatus
|
|
1091
|
+
}
|
|
1092
|
+
});
|
|
1093
|
+
getService("release", { strapi: strapi2 }).updateReleaseStatus(releaseId);
|
|
1044
1094
|
return updatedAction;
|
|
1045
1095
|
},
|
|
1046
|
-
async
|
|
1096
|
+
async delete(actionId, releaseId) {
|
|
1047
1097
|
const deletedAction = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).delete({
|
|
1048
1098
|
where: {
|
|
1049
1099
|
id: actionId,
|
|
@@ -1060,51 +1110,8 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
1060
1110
|
`Action with id ${actionId} not found in release with id ${releaseId} or it is already published`
|
|
1061
1111
|
);
|
|
1062
1112
|
}
|
|
1063
|
-
|
|
1113
|
+
getService("release", { strapi: strapi2 }).updateReleaseStatus(releaseId);
|
|
1064
1114
|
return deletedAction;
|
|
1065
|
-
},
|
|
1066
|
-
async updateReleaseStatus(releaseId) {
|
|
1067
|
-
const [totalActions, invalidActions] = await Promise.all([
|
|
1068
|
-
this.countActions({
|
|
1069
|
-
filters: {
|
|
1070
|
-
release: releaseId
|
|
1071
|
-
}
|
|
1072
|
-
}),
|
|
1073
|
-
this.countActions({
|
|
1074
|
-
filters: {
|
|
1075
|
-
release: releaseId,
|
|
1076
|
-
isEntryValid: false
|
|
1077
|
-
}
|
|
1078
|
-
})
|
|
1079
|
-
]);
|
|
1080
|
-
if (totalActions > 0) {
|
|
1081
|
-
if (invalidActions > 0) {
|
|
1082
|
-
return strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
1083
|
-
where: {
|
|
1084
|
-
id: releaseId
|
|
1085
|
-
},
|
|
1086
|
-
data: {
|
|
1087
|
-
status: "blocked"
|
|
1088
|
-
}
|
|
1089
|
-
});
|
|
1090
|
-
}
|
|
1091
|
-
return strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
1092
|
-
where: {
|
|
1093
|
-
id: releaseId
|
|
1094
|
-
},
|
|
1095
|
-
data: {
|
|
1096
|
-
status: "ready"
|
|
1097
|
-
}
|
|
1098
|
-
});
|
|
1099
|
-
}
|
|
1100
|
-
return strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
1101
|
-
where: {
|
|
1102
|
-
id: releaseId
|
|
1103
|
-
},
|
|
1104
|
-
data: {
|
|
1105
|
-
status: "empty"
|
|
1106
|
-
}
|
|
1107
|
-
});
|
|
1108
1115
|
}
|
|
1109
1116
|
};
|
|
1110
1117
|
};
|
|
@@ -1120,33 +1127,39 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1120
1127
|
where: {
|
|
1121
1128
|
id: releaseId
|
|
1122
1129
|
},
|
|
1123
|
-
populate: {
|
|
1130
|
+
populate: {
|
|
1131
|
+
actions: true
|
|
1132
|
+
}
|
|
1124
1133
|
});
|
|
1125
1134
|
if (!release2) {
|
|
1126
1135
|
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
1127
1136
|
}
|
|
1128
1137
|
const isEntryInRelease = release2.actions.some(
|
|
1129
|
-
(action) => Number(action.
|
|
1138
|
+
(action) => Number(action.entryDocumentId) === Number(releaseActionArgs.entryDocumentId) && action.contentType === releaseActionArgs.contentType && action.locale === releaseActionArgs.locale
|
|
1130
1139
|
);
|
|
1131
1140
|
if (isEntryInRelease) {
|
|
1132
1141
|
throw new AlreadyOnReleaseError(
|
|
1133
|
-
`Entry with
|
|
1142
|
+
`Entry with documentId ${releaseActionArgs.entryDocumentId} ${releaseActionArgs.locale ? `(${releaseActionArgs.locale})` : ""} and contentType ${releaseActionArgs.contentType} already exists in release with id ${releaseId}`
|
|
1134
1143
|
);
|
|
1135
1144
|
}
|
|
1136
1145
|
},
|
|
1137
|
-
|
|
1146
|
+
validateEntryData(contentTypeUid, entryDocumentId) {
|
|
1138
1147
|
const contentType = strapi2.contentType(contentTypeUid);
|
|
1139
1148
|
if (!contentType) {
|
|
1140
1149
|
throw new utils.errors.NotFoundError(`No content type found for uid ${contentTypeUid}`);
|
|
1141
1150
|
}
|
|
1142
|
-
if (!contentType
|
|
1151
|
+
if (!utils.contentTypes.hasDraftAndPublish(contentType)) {
|
|
1143
1152
|
throw new utils.errors.ValidationError(
|
|
1144
1153
|
`Content type with uid ${contentTypeUid} does not have draftAndPublish enabled`
|
|
1145
1154
|
);
|
|
1146
1155
|
}
|
|
1156
|
+
if (contentType.kind === "collectionType" && !entryDocumentId) {
|
|
1157
|
+
throw new utils.errors.ValidationError("Document id is required for collection type");
|
|
1158
|
+
}
|
|
1147
1159
|
},
|
|
1148
1160
|
async validatePendingReleasesLimit() {
|
|
1149
|
-
const
|
|
1161
|
+
const featureCfg = strapi2.ee.features.get("cms-content-releases");
|
|
1162
|
+
const maximumPendingReleases = typeof featureCfg === "object" && featureCfg?.options?.maximumReleases || 3;
|
|
1150
1163
|
const [, pendingReleasesCount] = await strapi2.db.query(RELEASE_MODEL_UID).findWithCount({
|
|
1151
1164
|
filters: {
|
|
1152
1165
|
releasedAt: {
|
|
@@ -1189,7 +1202,7 @@ const createSchedulingService = ({ strapi: strapi2 }) => {
|
|
|
1189
1202
|
}
|
|
1190
1203
|
const job = nodeSchedule.scheduleJob(scheduleDate, async () => {
|
|
1191
1204
|
try {
|
|
1192
|
-
await getService("release").publish(releaseId);
|
|
1205
|
+
await getService("release", { strapi: strapi2 }).publish(releaseId);
|
|
1193
1206
|
} catch (error) {
|
|
1194
1207
|
}
|
|
1195
1208
|
this.cancel(releaseId);
|
|
@@ -1231,10 +1244,33 @@ const createSchedulingService = ({ strapi: strapi2 }) => {
|
|
|
1231
1244
|
}
|
|
1232
1245
|
};
|
|
1233
1246
|
};
|
|
1247
|
+
const DEFAULT_SETTINGS = {
|
|
1248
|
+
defaultTimezone: null
|
|
1249
|
+
};
|
|
1250
|
+
const createSettingsService = ({ strapi: strapi2 }) => {
|
|
1251
|
+
const getStore = async () => strapi2.store({ type: "core", name: "content-releases" });
|
|
1252
|
+
return {
|
|
1253
|
+
async update({ settings: settings2 }) {
|
|
1254
|
+
const store = await getStore();
|
|
1255
|
+
store.set({ key: "settings", value: settings2 });
|
|
1256
|
+
return settings2;
|
|
1257
|
+
},
|
|
1258
|
+
async find() {
|
|
1259
|
+
const store = await getStore();
|
|
1260
|
+
const settings2 = await store.get({ key: "settings" });
|
|
1261
|
+
return {
|
|
1262
|
+
...DEFAULT_SETTINGS,
|
|
1263
|
+
...settings2 || {}
|
|
1264
|
+
};
|
|
1265
|
+
}
|
|
1266
|
+
};
|
|
1267
|
+
};
|
|
1234
1268
|
const services = {
|
|
1235
1269
|
release: createReleaseService,
|
|
1270
|
+
"release-action": createReleaseActionService,
|
|
1236
1271
|
"release-validation": createReleaseValidationService,
|
|
1237
|
-
scheduling: createSchedulingService
|
|
1272
|
+
scheduling: createSchedulingService,
|
|
1273
|
+
settings: createSettingsService
|
|
1238
1274
|
};
|
|
1239
1275
|
const RELEASE_SCHEMA = yup__namespace.object().shape({
|
|
1240
1276
|
name: yup__namespace.string().trim().required(),
|
|
@@ -1256,60 +1292,125 @@ const RELEASE_SCHEMA = yup__namespace.object().shape({
|
|
|
1256
1292
|
otherwise: yup__namespace.string().nullable()
|
|
1257
1293
|
})
|
|
1258
1294
|
}).required().noUnknown();
|
|
1295
|
+
const SETTINGS_SCHEMA = yup__namespace.object().shape({
|
|
1296
|
+
defaultTimezone: yup__namespace.string().nullable().default(null)
|
|
1297
|
+
}).required().noUnknown();
|
|
1298
|
+
const FIND_BY_DOCUMENT_ATTACHED_PARAMS_SCHEMA = utils.yup.object().shape({
|
|
1299
|
+
contentType: utils.yup.string().required(),
|
|
1300
|
+
entryDocumentId: utils.yup.string().nullable(),
|
|
1301
|
+
hasEntryAttached: utils.yup.string().nullable(),
|
|
1302
|
+
locale: utils.yup.string().nullable()
|
|
1303
|
+
}).required().noUnknown();
|
|
1259
1304
|
const validateRelease = utils.validateYupSchema(RELEASE_SCHEMA);
|
|
1305
|
+
const validatefindByDocumentAttachedParams = utils.validateYupSchema(
|
|
1306
|
+
FIND_BY_DOCUMENT_ATTACHED_PARAMS_SCHEMA
|
|
1307
|
+
);
|
|
1260
1308
|
const releaseController = {
|
|
1261
|
-
|
|
1262
|
-
|
|
1309
|
+
/**
|
|
1310
|
+
* Find releases based on documents attached or not to the release.
|
|
1311
|
+
* If `hasEntryAttached` is true, it will return all releases that have the entry attached.
|
|
1312
|
+
* If `hasEntryAttached` is false, it will return all releases that don't have the entry attached.
|
|
1313
|
+
*/
|
|
1314
|
+
async findByDocumentAttached(ctx) {
|
|
1315
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1263
1316
|
ability: ctx.state.userAbility,
|
|
1264
1317
|
model: RELEASE_MODEL_UID
|
|
1265
1318
|
});
|
|
1266
1319
|
await permissionsManager.validateQuery(ctx.query);
|
|
1267
1320
|
const releaseService = getService("release", { strapi });
|
|
1268
|
-
const
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
const
|
|
1274
|
-
|
|
1275
|
-
|
|
1321
|
+
const query = await permissionsManager.sanitizeQuery(ctx.query);
|
|
1322
|
+
await validatefindByDocumentAttachedParams(query);
|
|
1323
|
+
const { contentType, entryDocumentId, hasEntryAttached, locale } = query;
|
|
1324
|
+
const isEntryAttached = typeof hasEntryAttached === "string" ? Boolean(JSON.parse(hasEntryAttached)) : false;
|
|
1325
|
+
if (isEntryAttached) {
|
|
1326
|
+
const releases = await releaseService.findMany({
|
|
1327
|
+
where: {
|
|
1328
|
+
releasedAt: null,
|
|
1329
|
+
actions: {
|
|
1330
|
+
contentType,
|
|
1331
|
+
entryDocumentId: entryDocumentId ?? null,
|
|
1332
|
+
locale: locale ?? null
|
|
1333
|
+
}
|
|
1334
|
+
},
|
|
1335
|
+
populate: {
|
|
1336
|
+
actions: {
|
|
1337
|
+
fields: ["type"]
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
});
|
|
1341
|
+
ctx.body = { data: releases };
|
|
1276
1342
|
} else {
|
|
1277
|
-
const
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
const { actions, ...releaseData } = release2;
|
|
1281
|
-
return {
|
|
1282
|
-
...releaseData,
|
|
1343
|
+
const relatedReleases = await releaseService.findMany({
|
|
1344
|
+
where: {
|
|
1345
|
+
releasedAt: null,
|
|
1283
1346
|
actions: {
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1347
|
+
contentType,
|
|
1348
|
+
entryDocumentId: entryDocumentId ?? null,
|
|
1349
|
+
locale: locale ?? null
|
|
1287
1350
|
}
|
|
1288
|
-
}
|
|
1351
|
+
}
|
|
1289
1352
|
});
|
|
1290
|
-
const
|
|
1353
|
+
const releases = await releaseService.findMany({
|
|
1291
1354
|
where: {
|
|
1355
|
+
$or: [
|
|
1356
|
+
{
|
|
1357
|
+
id: {
|
|
1358
|
+
$notIn: relatedReleases.map((release2) => release2.id)
|
|
1359
|
+
}
|
|
1360
|
+
},
|
|
1361
|
+
{
|
|
1362
|
+
actions: null
|
|
1363
|
+
}
|
|
1364
|
+
],
|
|
1292
1365
|
releasedAt: null
|
|
1293
1366
|
}
|
|
1294
1367
|
});
|
|
1295
|
-
ctx.body = { data
|
|
1368
|
+
ctx.body = { data: releases };
|
|
1296
1369
|
}
|
|
1297
1370
|
},
|
|
1371
|
+
async findPage(ctx) {
|
|
1372
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1373
|
+
ability: ctx.state.userAbility,
|
|
1374
|
+
model: RELEASE_MODEL_UID
|
|
1375
|
+
});
|
|
1376
|
+
await permissionsManager.validateQuery(ctx.query);
|
|
1377
|
+
const releaseService = getService("release", { strapi });
|
|
1378
|
+
const query = await permissionsManager.sanitizeQuery(ctx.query);
|
|
1379
|
+
const { results, pagination } = await releaseService.findPage(query);
|
|
1380
|
+
const data = results.map((release2) => {
|
|
1381
|
+
const { actions, ...releaseData } = release2;
|
|
1382
|
+
return {
|
|
1383
|
+
...releaseData,
|
|
1384
|
+
actions: {
|
|
1385
|
+
meta: {
|
|
1386
|
+
count: actions.count
|
|
1387
|
+
}
|
|
1388
|
+
}
|
|
1389
|
+
};
|
|
1390
|
+
});
|
|
1391
|
+
const pendingReleasesCount = await strapi.db.query(RELEASE_MODEL_UID).count({
|
|
1392
|
+
where: {
|
|
1393
|
+
releasedAt: null
|
|
1394
|
+
}
|
|
1395
|
+
});
|
|
1396
|
+
ctx.body = { data, meta: { pagination, pendingReleasesCount } };
|
|
1397
|
+
},
|
|
1298
1398
|
async findOne(ctx) {
|
|
1299
1399
|
const id = ctx.params.id;
|
|
1300
1400
|
const releaseService = getService("release", { strapi });
|
|
1401
|
+
const releaseActionService = getService("release-action", { strapi });
|
|
1301
1402
|
const release2 = await releaseService.findOne(id, { populate: ["createdBy"] });
|
|
1302
1403
|
if (!release2) {
|
|
1303
1404
|
throw new utils.errors.NotFoundError(`Release not found for id: ${id}`);
|
|
1304
1405
|
}
|
|
1305
|
-
const count = await
|
|
1406
|
+
const count = await releaseActionService.countActions({
|
|
1306
1407
|
filters: {
|
|
1307
1408
|
release: id
|
|
1308
1409
|
}
|
|
1309
1410
|
});
|
|
1310
1411
|
const sanitizedRelease = {
|
|
1311
1412
|
...release2,
|
|
1312
|
-
createdBy: release2.createdBy ? strapi.admin
|
|
1413
|
+
createdBy: release2.createdBy ? strapi.service("admin::user").sanitizeUser(release2.createdBy) : null
|
|
1313
1414
|
};
|
|
1314
1415
|
const data = {
|
|
1315
1416
|
...sanitizedRelease,
|
|
@@ -1321,19 +1422,56 @@ const releaseController = {
|
|
|
1321
1422
|
};
|
|
1322
1423
|
ctx.body = { data };
|
|
1323
1424
|
},
|
|
1425
|
+
/* @TODO: Migrate to new api
|
|
1426
|
+
async mapEntriesToReleases(ctx: Koa.Context) {
|
|
1427
|
+
const { contentTypeUid, entriesIds } = ctx.query;
|
|
1428
|
+
|
|
1429
|
+
if (!contentTypeUid || !entriesIds) {
|
|
1430
|
+
throw new errors.ValidationError('Missing required query parameters');
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
const releaseService = getService('release', { strapi });
|
|
1434
|
+
|
|
1435
|
+
const releasesWithActions = await releaseService.findMany(
|
|
1436
|
+
contentTypeUid,
|
|
1437
|
+
entriesIds
|
|
1438
|
+
);
|
|
1439
|
+
|
|
1440
|
+
const mappedEntriesInReleases = releasesWithActions.reduce(
|
|
1441
|
+
// TODO: Fix for v5 removed mappedEntriedToRelease
|
|
1442
|
+
(acc: MapEntriesToReleases.Response['data'], release: Release) => {
|
|
1443
|
+
release.actions.forEach((action) => {
|
|
1444
|
+
if (!acc[action.entry.id]) {
|
|
1445
|
+
acc[action.entry.id] = [{ id: release.id, name: release.name }];
|
|
1446
|
+
} else {
|
|
1447
|
+
acc[action.entry.id].push({ id: release.id, name: release.name });
|
|
1448
|
+
}
|
|
1449
|
+
});
|
|
1450
|
+
|
|
1451
|
+
return acc;
|
|
1452
|
+
},
|
|
1453
|
+
// TODO: Fix for v5 removed mappedEntriedToRelease
|
|
1454
|
+
{} as MapEntriesToReleases.Response['data']
|
|
1455
|
+
);
|
|
1456
|
+
|
|
1457
|
+
ctx.body = {
|
|
1458
|
+
data: mappedEntriesInReleases,
|
|
1459
|
+
};
|
|
1460
|
+
},
|
|
1461
|
+
*/
|
|
1324
1462
|
async create(ctx) {
|
|
1325
1463
|
const user = ctx.state.user;
|
|
1326
1464
|
const releaseArgs = ctx.request.body;
|
|
1327
1465
|
await validateRelease(releaseArgs);
|
|
1328
1466
|
const releaseService = getService("release", { strapi });
|
|
1329
1467
|
const release2 = await releaseService.create(releaseArgs, { user });
|
|
1330
|
-
const permissionsManager = strapi.admin
|
|
1468
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1331
1469
|
ability: ctx.state.userAbility,
|
|
1332
1470
|
model: RELEASE_MODEL_UID
|
|
1333
1471
|
});
|
|
1334
|
-
ctx.
|
|
1472
|
+
ctx.created({
|
|
1335
1473
|
data: await permissionsManager.sanitizeOutput(release2)
|
|
1336
|
-
};
|
|
1474
|
+
});
|
|
1337
1475
|
},
|
|
1338
1476
|
async update(ctx) {
|
|
1339
1477
|
const user = ctx.state.user;
|
|
@@ -1342,7 +1480,7 @@ const releaseController = {
|
|
|
1342
1480
|
await validateRelease(releaseArgs);
|
|
1343
1481
|
const releaseService = getService("release", { strapi });
|
|
1344
1482
|
const release2 = await releaseService.update(id, releaseArgs, { user });
|
|
1345
|
-
const permissionsManager = strapi.admin
|
|
1483
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1346
1484
|
ability: ctx.state.userAbility,
|
|
1347
1485
|
model: RELEASE_MODEL_UID
|
|
1348
1486
|
});
|
|
@@ -1359,18 +1497,18 @@ const releaseController = {
|
|
|
1359
1497
|
};
|
|
1360
1498
|
},
|
|
1361
1499
|
async publish(ctx) {
|
|
1362
|
-
const user = ctx.state.user;
|
|
1363
1500
|
const id = ctx.params.id;
|
|
1364
1501
|
const releaseService = getService("release", { strapi });
|
|
1365
|
-
const
|
|
1502
|
+
const releaseActionService = getService("release-action", { strapi });
|
|
1503
|
+
const release2 = await releaseService.publish(id);
|
|
1366
1504
|
const [countPublishActions, countUnpublishActions] = await Promise.all([
|
|
1367
|
-
|
|
1505
|
+
releaseActionService.countActions({
|
|
1368
1506
|
filters: {
|
|
1369
1507
|
release: id,
|
|
1370
1508
|
type: "publish"
|
|
1371
1509
|
}
|
|
1372
1510
|
}),
|
|
1373
|
-
|
|
1511
|
+
releaseActionService.countActions({
|
|
1374
1512
|
filters: {
|
|
1375
1513
|
release: id,
|
|
1376
1514
|
type: "unpublish"
|
|
@@ -1388,42 +1526,47 @@ const releaseController = {
|
|
|
1388
1526
|
}
|
|
1389
1527
|
};
|
|
1390
1528
|
const RELEASE_ACTION_SCHEMA = utils.yup.object().shape({
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
}).required(),
|
|
1529
|
+
contentType: utils.yup.string().required(),
|
|
1530
|
+
entryDocumentId: utils.yup.strapiID(),
|
|
1531
|
+
locale: utils.yup.string(),
|
|
1395
1532
|
type: utils.yup.string().oneOf(["publish", "unpublish"]).required()
|
|
1396
1533
|
});
|
|
1397
1534
|
const RELEASE_ACTION_UPDATE_SCHEMA = utils.yup.object().shape({
|
|
1398
1535
|
type: utils.yup.string().oneOf(["publish", "unpublish"]).required()
|
|
1399
1536
|
});
|
|
1537
|
+
const FIND_MANY_ACTIONS_PARAMS = utils.yup.object().shape({
|
|
1538
|
+
groupBy: utils.yup.string().oneOf(["action", "contentType", "locale"])
|
|
1539
|
+
});
|
|
1400
1540
|
const validateReleaseAction = utils.validateYupSchema(RELEASE_ACTION_SCHEMA);
|
|
1401
1541
|
const validateReleaseActionUpdateSchema = utils.validateYupSchema(RELEASE_ACTION_UPDATE_SCHEMA);
|
|
1542
|
+
const validateFindManyActionsParams = utils.validateYupSchema(FIND_MANY_ACTIONS_PARAMS);
|
|
1402
1543
|
const releaseActionController = {
|
|
1403
1544
|
async create(ctx) {
|
|
1404
1545
|
const releaseId = ctx.params.releaseId;
|
|
1405
1546
|
const releaseActionArgs = ctx.request.body;
|
|
1406
1547
|
await validateReleaseAction(releaseActionArgs);
|
|
1407
|
-
const
|
|
1408
|
-
const releaseAction2 = await
|
|
1409
|
-
ctx.
|
|
1548
|
+
const releaseActionService = getService("release-action", { strapi });
|
|
1549
|
+
const releaseAction2 = await releaseActionService.create(releaseId, releaseActionArgs);
|
|
1550
|
+
ctx.created({
|
|
1410
1551
|
data: releaseAction2
|
|
1411
|
-
};
|
|
1552
|
+
});
|
|
1412
1553
|
},
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
const
|
|
1554
|
+
/*
|
|
1555
|
+
async createMany(ctx: Koa.Context) {
|
|
1556
|
+
const releaseId: CreateManyReleaseActions.Request['params']['releaseId'] = ctx.params.releaseId;
|
|
1557
|
+
const releaseActionsArgs = ctx.request.body as CreateManyReleaseActions.Request['body'];
|
|
1416
1558
|
await Promise.all(
|
|
1417
1559
|
releaseActionsArgs.map((releaseActionArgs) => validateReleaseAction(releaseActionArgs))
|
|
1418
1560
|
);
|
|
1419
|
-
const
|
|
1561
|
+
const releaseActionService = getService('release-action', { strapi });
|
|
1420
1562
|
const releaseActions = await strapi.db.transaction(async () => {
|
|
1421
|
-
const
|
|
1563
|
+
const releaseActions = await Promise.all(
|
|
1422
1564
|
releaseActionsArgs.map(async (releaseActionArgs) => {
|
|
1423
1565
|
try {
|
|
1424
|
-
const action = await
|
|
1566
|
+
const action = await releaseActionService.create(releaseId, releaseActionArgs);
|
|
1425
1567
|
return action;
|
|
1426
1568
|
} catch (error) {
|
|
1569
|
+
// If the entry is already in the release, we don't want to throw an error, so we catch and ignore it
|
|
1427
1570
|
if (error instanceof AlreadyOnReleaseError) {
|
|
1428
1571
|
return null;
|
|
1429
1572
|
}
|
|
@@ -1431,34 +1574,42 @@ const releaseActionController = {
|
|
|
1431
1574
|
}
|
|
1432
1575
|
})
|
|
1433
1576
|
);
|
|
1434
|
-
return
|
|
1577
|
+
return releaseActions;
|
|
1435
1578
|
});
|
|
1436
1579
|
const newReleaseActions = releaseActions.filter((action) => action !== null);
|
|
1437
|
-
ctx.
|
|
1580
|
+
ctx.created({
|
|
1438
1581
|
data: newReleaseActions,
|
|
1439
1582
|
meta: {
|
|
1440
1583
|
entriesAlreadyInRelease: releaseActions.length - newReleaseActions.length,
|
|
1441
|
-
totalEntries: releaseActions.length
|
|
1442
|
-
}
|
|
1443
|
-
};
|
|
1584
|
+
totalEntries: releaseActions.length,
|
|
1585
|
+
},
|
|
1586
|
+
});
|
|
1444
1587
|
},
|
|
1588
|
+
*/
|
|
1445
1589
|
async findMany(ctx) {
|
|
1446
1590
|
const releaseId = ctx.params.releaseId;
|
|
1447
|
-
const permissionsManager = strapi.admin
|
|
1591
|
+
const permissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1448
1592
|
ability: ctx.state.userAbility,
|
|
1449
1593
|
model: RELEASE_ACTION_MODEL_UID
|
|
1450
1594
|
});
|
|
1595
|
+
await validateFindManyActionsParams(ctx.query);
|
|
1596
|
+
if (ctx.query.groupBy) {
|
|
1597
|
+
if (!["action", "contentType", "locale"].includes(ctx.query.groupBy)) {
|
|
1598
|
+
ctx.badRequest("Invalid groupBy parameter");
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
ctx.query.sort = ctx.query.groupBy === "action" ? "type" : ctx.query.groupBy;
|
|
1602
|
+
delete ctx.query.groupBy;
|
|
1451
1603
|
const query = await permissionsManager.sanitizeQuery(ctx.query);
|
|
1452
|
-
const
|
|
1453
|
-
const { results, pagination } = await
|
|
1454
|
-
sort: query.groupBy === "action" ? "type" : query.groupBy,
|
|
1604
|
+
const releaseActionService = getService("release-action", { strapi });
|
|
1605
|
+
const { results, pagination } = await releaseActionService.findPage(releaseId, {
|
|
1455
1606
|
...query
|
|
1456
1607
|
});
|
|
1457
1608
|
const contentTypeOutputSanitizers = results.reduce((acc, action) => {
|
|
1458
1609
|
if (acc[action.contentType]) {
|
|
1459
1610
|
return acc;
|
|
1460
1611
|
}
|
|
1461
|
-
const contentTypePermissionsManager = strapi.admin
|
|
1612
|
+
const contentTypePermissionsManager = strapi.service("admin::permission").createPermissionsManager({
|
|
1462
1613
|
ability: ctx.state.userAbility,
|
|
1463
1614
|
model: action.contentType
|
|
1464
1615
|
});
|
|
@@ -1467,10 +1618,11 @@ const releaseActionController = {
|
|
|
1467
1618
|
}, {});
|
|
1468
1619
|
const sanitizedResults = await utils.async.map(results, async (action) => ({
|
|
1469
1620
|
...action,
|
|
1470
|
-
entry: await contentTypeOutputSanitizers[action.contentType](action.entry)
|
|
1621
|
+
entry: action.entry ? await contentTypeOutputSanitizers[action.contentType](action.entry) : {}
|
|
1471
1622
|
}));
|
|
1472
|
-
const groupedData = await
|
|
1473
|
-
const contentTypes2 =
|
|
1623
|
+
const groupedData = await releaseActionService.groupActions(sanitizedResults, query.sort);
|
|
1624
|
+
const contentTypes2 = releaseActionService.getContentTypeModelsFromActions(results);
|
|
1625
|
+
const releaseService = getService("release", { strapi });
|
|
1474
1626
|
const components = await releaseService.getAllComponents();
|
|
1475
1627
|
ctx.body = {
|
|
1476
1628
|
data: groupedData,
|
|
@@ -1486,8 +1638,8 @@ const releaseActionController = {
|
|
|
1486
1638
|
const releaseId = ctx.params.releaseId;
|
|
1487
1639
|
const releaseActionUpdateArgs = ctx.request.body;
|
|
1488
1640
|
await validateReleaseActionUpdateSchema(releaseActionUpdateArgs);
|
|
1489
|
-
const
|
|
1490
|
-
const updatedAction = await
|
|
1641
|
+
const releaseActionService = getService("release-action", { strapi });
|
|
1642
|
+
const updatedAction = await releaseActionService.update(
|
|
1491
1643
|
actionId,
|
|
1492
1644
|
releaseId,
|
|
1493
1645
|
releaseActionUpdateArgs
|
|
@@ -1499,17 +1651,70 @@ const releaseActionController = {
|
|
|
1499
1651
|
async delete(ctx) {
|
|
1500
1652
|
const actionId = ctx.params.actionId;
|
|
1501
1653
|
const releaseId = ctx.params.releaseId;
|
|
1502
|
-
const
|
|
1503
|
-
const deletedReleaseAction = await
|
|
1654
|
+
const releaseActionService = getService("release-action", { strapi });
|
|
1655
|
+
const deletedReleaseAction = await releaseActionService.delete(actionId, releaseId);
|
|
1504
1656
|
ctx.body = {
|
|
1505
1657
|
data: deletedReleaseAction
|
|
1506
1658
|
};
|
|
1507
1659
|
}
|
|
1508
1660
|
};
|
|
1509
|
-
const
|
|
1661
|
+
const validateSettings = utils.validateYupSchema(SETTINGS_SCHEMA);
|
|
1662
|
+
const settingsController = {
|
|
1663
|
+
async find(ctx) {
|
|
1664
|
+
const settingsService = getService("settings", { strapi });
|
|
1665
|
+
const settings2 = await settingsService.find();
|
|
1666
|
+
ctx.body = { data: settings2 };
|
|
1667
|
+
},
|
|
1668
|
+
async update(ctx) {
|
|
1669
|
+
const settingsBody = ctx.request.body;
|
|
1670
|
+
const settings2 = await validateSettings(settingsBody);
|
|
1671
|
+
const settingsService = getService("settings", { strapi });
|
|
1672
|
+
const updatedSettings = await settingsService.update({ settings: settings2 });
|
|
1673
|
+
ctx.body = { data: updatedSettings };
|
|
1674
|
+
}
|
|
1675
|
+
};
|
|
1676
|
+
const controllers = {
|
|
1677
|
+
release: releaseController,
|
|
1678
|
+
"release-action": releaseActionController,
|
|
1679
|
+
settings: settingsController
|
|
1680
|
+
};
|
|
1510
1681
|
const release = {
|
|
1511
1682
|
type: "admin",
|
|
1512
1683
|
routes: [
|
|
1684
|
+
/*
|
|
1685
|
+
{
|
|
1686
|
+
method: 'GET',
|
|
1687
|
+
path: '/mapEntriesToReleases',
|
|
1688
|
+
handler: 'release.mapEntriesToReleases',
|
|
1689
|
+
config: {
|
|
1690
|
+
policies: [
|
|
1691
|
+
'admin::isAuthenticatedAdmin',
|
|
1692
|
+
{
|
|
1693
|
+
name: 'admin::hasPermissions',
|
|
1694
|
+
config: {
|
|
1695
|
+
actions: ['plugin::content-releases.read'],
|
|
1696
|
+
},
|
|
1697
|
+
},
|
|
1698
|
+
],
|
|
1699
|
+
},
|
|
1700
|
+
},
|
|
1701
|
+
*/
|
|
1702
|
+
{
|
|
1703
|
+
method: "GET",
|
|
1704
|
+
path: "/getByDocumentAttached",
|
|
1705
|
+
handler: "release.findByDocumentAttached",
|
|
1706
|
+
config: {
|
|
1707
|
+
policies: [
|
|
1708
|
+
"admin::isAuthenticatedAdmin",
|
|
1709
|
+
{
|
|
1710
|
+
name: "admin::hasPermissions",
|
|
1711
|
+
config: {
|
|
1712
|
+
actions: ["plugin::content-releases.read"]
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
]
|
|
1716
|
+
}
|
|
1717
|
+
},
|
|
1513
1718
|
{
|
|
1514
1719
|
method: "POST",
|
|
1515
1720
|
path: "/",
|
|
@@ -1529,7 +1734,7 @@ const release = {
|
|
|
1529
1734
|
{
|
|
1530
1735
|
method: "GET",
|
|
1531
1736
|
path: "/",
|
|
1532
|
-
handler: "release.
|
|
1737
|
+
handler: "release.findPage",
|
|
1533
1738
|
config: {
|
|
1534
1739
|
policies: [
|
|
1535
1740
|
"admin::isAuthenticatedAdmin",
|
|
@@ -1627,22 +1832,24 @@ const releaseAction = {
|
|
|
1627
1832
|
]
|
|
1628
1833
|
}
|
|
1629
1834
|
},
|
|
1835
|
+
/*
|
|
1630
1836
|
{
|
|
1631
|
-
method:
|
|
1632
|
-
path:
|
|
1633
|
-
handler:
|
|
1837
|
+
method: 'POST',
|
|
1838
|
+
path: '/:releaseId/actions/bulk',
|
|
1839
|
+
handler: 'release-action.createMany',
|
|
1634
1840
|
config: {
|
|
1635
1841
|
policies: [
|
|
1636
|
-
|
|
1842
|
+
'admin::isAuthenticatedAdmin',
|
|
1637
1843
|
{
|
|
1638
|
-
name:
|
|
1844
|
+
name: 'admin::hasPermissions',
|
|
1639
1845
|
config: {
|
|
1640
|
-
actions: [
|
|
1641
|
-
}
|
|
1642
|
-
}
|
|
1643
|
-
]
|
|
1644
|
-
}
|
|
1846
|
+
actions: ['plugin::content-releases.create-action'],
|
|
1847
|
+
},
|
|
1848
|
+
},
|
|
1849
|
+
],
|
|
1850
|
+
},
|
|
1645
1851
|
},
|
|
1852
|
+
*/
|
|
1646
1853
|
{
|
|
1647
1854
|
method: "GET",
|
|
1648
1855
|
path: "/:releaseId/actions",
|
|
@@ -1693,7 +1900,45 @@ const releaseAction = {
|
|
|
1693
1900
|
}
|
|
1694
1901
|
]
|
|
1695
1902
|
};
|
|
1903
|
+
const settings = {
|
|
1904
|
+
type: "admin",
|
|
1905
|
+
routes: [
|
|
1906
|
+
{
|
|
1907
|
+
method: "GET",
|
|
1908
|
+
path: "/settings",
|
|
1909
|
+
handler: "settings.find",
|
|
1910
|
+
config: {
|
|
1911
|
+
policies: [
|
|
1912
|
+
"admin::isAuthenticatedAdmin",
|
|
1913
|
+
{
|
|
1914
|
+
name: "admin::hasPermissions",
|
|
1915
|
+
config: {
|
|
1916
|
+
actions: ["plugin::content-releases.settings.read"]
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
]
|
|
1920
|
+
}
|
|
1921
|
+
},
|
|
1922
|
+
{
|
|
1923
|
+
method: "PUT",
|
|
1924
|
+
path: "/settings",
|
|
1925
|
+
handler: "settings.update",
|
|
1926
|
+
config: {
|
|
1927
|
+
policies: [
|
|
1928
|
+
"admin::isAuthenticatedAdmin",
|
|
1929
|
+
{
|
|
1930
|
+
name: "admin::hasPermissions",
|
|
1931
|
+
config: {
|
|
1932
|
+
actions: ["plugin::content-releases.settings.update"]
|
|
1933
|
+
}
|
|
1934
|
+
}
|
|
1935
|
+
]
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
]
|
|
1939
|
+
};
|
|
1696
1940
|
const routes = {
|
|
1941
|
+
settings,
|
|
1697
1942
|
release,
|
|
1698
1943
|
"release-action": releaseAction
|
|
1699
1944
|
};
|