@strapi/content-releases 0.0.0-experimental.f7b9b47085e387e97f990d8695971b51d7f7149a → 0.0.0-next.37dd1e3ff22e1635b69683abadd444912ae0dbff
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-f2cafd81.js → App-5PRKHpa2.js} +207 -112
- package/dist/_chunks/App-5PRKHpa2.js.map +1 -0
- package/dist/_chunks/{App-a4843fda.mjs → App-J4jrthEu.mjs} +210 -115
- package/dist/_chunks/App-J4jrthEu.mjs.map +1 -0
- package/dist/_chunks/{en-13576ce2.js → en-haKSQIo8.js} +13 -4
- package/dist/_chunks/en-haKSQIo8.js.map +1 -0
- package/dist/_chunks/{en-e98d8b57.mjs → en-ngTk74JV.mjs} +13 -4
- package/dist/_chunks/en-ngTk74JV.mjs.map +1 -0
- package/dist/_chunks/{index-66d129ac.js → index-PEkKIRyJ.js} +33 -22
- package/dist/_chunks/index-PEkKIRyJ.js.map +1 -0
- package/dist/_chunks/{index-937f8179.mjs → index-_Zsj8MUA.mjs} +36 -25
- package/dist/_chunks/index-_Zsj8MUA.mjs.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +2 -2
- package/dist/server/index.js +205 -56
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +203 -56
- package/dist/server/index.mjs.map +1 -1
- package/package.json +9 -8
- package/dist/_chunks/App-a4843fda.mjs.map +0 -1
- package/dist/_chunks/App-f2cafd81.js.map +0 -1
- package/dist/_chunks/en-13576ce2.js.map +0 -1
- package/dist/_chunks/en-e98d8b57.mjs.map +0 -1
- package/dist/_chunks/index-66d129ac.js.map +0 -1
- package/dist/_chunks/index-937f8179.mjs.map +0 -1
package/dist/server/index.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { setCreatorFields, errors, validateYupSchema, yup as yup$1 } from "@strapi/utils";
|
|
2
|
+
import _ from "lodash/fp";
|
|
2
3
|
import * as yup from "yup";
|
|
3
4
|
const RELEASE_MODEL_UID = "plugin::content-releases.release";
|
|
4
5
|
const RELEASE_ACTION_MODEL_UID = "plugin::content-releases.release-action";
|
|
@@ -46,10 +47,80 @@ const ACTIONS = [
|
|
|
46
47
|
pluginName: "content-releases"
|
|
47
48
|
}
|
|
48
49
|
];
|
|
49
|
-
const {
|
|
50
|
+
const getService = (name, { strapi: strapi2 } = { strapi: global.strapi }) => {
|
|
51
|
+
return strapi2.plugin("content-releases").service(name);
|
|
52
|
+
};
|
|
53
|
+
const { features: features$2 } = require("@strapi/strapi/dist/utils/ee");
|
|
50
54
|
const register = async ({ strapi: strapi2 }) => {
|
|
51
|
-
if (features$
|
|
55
|
+
if (features$2.isEnabled("cms-content-releases") && strapi2.features.future.isEnabled("contentReleases")) {
|
|
52
56
|
await strapi2.admin.services.permission.actionProvider.registerMany(ACTIONS);
|
|
57
|
+
const releaseActionService = getService("release-action", { strapi: strapi2 });
|
|
58
|
+
const eventManager = getService("event-manager", { strapi: strapi2 });
|
|
59
|
+
const destroyContentTypeUpdateListener = strapi2.eventHub.on(
|
|
60
|
+
"content-type.update",
|
|
61
|
+
async ({ contentType }) => {
|
|
62
|
+
if (contentType.schema.options.draftAndPublish === false) {
|
|
63
|
+
await releaseActionService.deleteManyForContentType(contentType.uid);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
);
|
|
67
|
+
eventManager.addDestroyListenerCallback(destroyContentTypeUpdateListener);
|
|
68
|
+
const destroyContentTypeDeleteListener = strapi2.eventHub.on(
|
|
69
|
+
"content-type.delete",
|
|
70
|
+
async ({ contentType }) => {
|
|
71
|
+
await releaseActionService.deleteManyForContentType(contentType.uid);
|
|
72
|
+
}
|
|
73
|
+
);
|
|
74
|
+
eventManager.addDestroyListenerCallback(destroyContentTypeDeleteListener);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const { features: features$1 } = require("@strapi/strapi/dist/utils/ee");
|
|
78
|
+
const bootstrap = async ({ strapi: strapi2 }) => {
|
|
79
|
+
if (features$1.isEnabled("cms-content-releases") && strapi2.features.future.isEnabled("contentReleases")) {
|
|
80
|
+
strapi2.db.lifecycles.subscribe({
|
|
81
|
+
afterDelete(event) {
|
|
82
|
+
const { model, result } = event;
|
|
83
|
+
if (model.kind === "collectionType" && model.options.draftAndPublish) {
|
|
84
|
+
const { id } = result;
|
|
85
|
+
strapi2.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
|
86
|
+
where: {
|
|
87
|
+
target_type: model.uid,
|
|
88
|
+
target_id: id
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
/**
|
|
94
|
+
* deleteMany hook doesn't return the deleted entries ids
|
|
95
|
+
* so we need to fetch them before deleting the entries to save the ids on our state
|
|
96
|
+
*/
|
|
97
|
+
async beforeDeleteMany(event) {
|
|
98
|
+
const { model, params } = event;
|
|
99
|
+
if (model.kind === "collectionType" && model.options.draftAndPublish) {
|
|
100
|
+
const { where } = params;
|
|
101
|
+
const entriesToDelete = await strapi2.db.query(model.uid).findMany({ select: ["id"], where });
|
|
102
|
+
event.state.entriesToDelete = entriesToDelete;
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
/**
|
|
106
|
+
* We delete the release actions related to deleted entries
|
|
107
|
+
* We make this only after deleteMany is succesfully executed to avoid errors
|
|
108
|
+
*/
|
|
109
|
+
async afterDeleteMany(event) {
|
|
110
|
+
const { model, state } = event;
|
|
111
|
+
const entriesToDelete = state.entriesToDelete;
|
|
112
|
+
if (entriesToDelete) {
|
|
113
|
+
await strapi2.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
|
114
|
+
where: {
|
|
115
|
+
target_type: model.uid,
|
|
116
|
+
target_id: {
|
|
117
|
+
$in: entriesToDelete.map((entry) => entry.id)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
53
124
|
}
|
|
54
125
|
};
|
|
55
126
|
const schema$1 = {
|
|
@@ -122,6 +193,9 @@ const schema = {
|
|
|
122
193
|
type: "string",
|
|
123
194
|
required: true
|
|
124
195
|
},
|
|
196
|
+
locale: {
|
|
197
|
+
type: "string"
|
|
198
|
+
},
|
|
125
199
|
release: {
|
|
126
200
|
type: "relation",
|
|
127
201
|
relation: "manyToOne",
|
|
@@ -137,8 +211,26 @@ const contentTypes = {
|
|
|
137
211
|
release: release$1,
|
|
138
212
|
"release-action": releaseAction$1
|
|
139
213
|
};
|
|
140
|
-
const
|
|
141
|
-
|
|
214
|
+
const createReleaseActionService = ({ strapi: strapi2 }) => ({
|
|
215
|
+
async deleteManyForContentType(contentTypeUid) {
|
|
216
|
+
return strapi2.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
|
217
|
+
where: {
|
|
218
|
+
target_type: contentTypeUid
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
const getGroupName = (queryValue) => {
|
|
224
|
+
switch (queryValue) {
|
|
225
|
+
case "contentType":
|
|
226
|
+
return "entry.contentType.displayName";
|
|
227
|
+
case "action":
|
|
228
|
+
return "type";
|
|
229
|
+
case "locale":
|
|
230
|
+
return _.getOr("No locale", "entry.locale.name");
|
|
231
|
+
default:
|
|
232
|
+
return "entry.contentType.displayName";
|
|
233
|
+
}
|
|
142
234
|
};
|
|
143
235
|
const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
144
236
|
async create(releaseData, { user }) {
|
|
@@ -224,19 +316,23 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
224
316
|
});
|
|
225
317
|
},
|
|
226
318
|
async update(id, releaseData, { user }) {
|
|
227
|
-
const
|
|
228
|
-
const release2 = await strapi2.entityService.
|
|
319
|
+
const releaseWithCreatorFields = await setCreatorFields({ user, isEdition: true })(releaseData);
|
|
320
|
+
const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, id);
|
|
321
|
+
if (!release2) {
|
|
322
|
+
throw new errors.NotFoundError(`No release found for id ${id}`);
|
|
323
|
+
}
|
|
324
|
+
if (release2.releasedAt) {
|
|
325
|
+
throw new errors.ValidationError("Release already published");
|
|
326
|
+
}
|
|
327
|
+
const updatedRelease = await strapi2.entityService.update(RELEASE_MODEL_UID, id, {
|
|
229
328
|
/*
|
|
230
329
|
* The type returned from the entity service: Partial<Input<"plugin::content-releases.release">>
|
|
231
330
|
* is not compatible with the type we are passing here: UpdateRelease.Request['body']
|
|
232
331
|
*/
|
|
233
332
|
// @ts-expect-error see above
|
|
234
|
-
data:
|
|
333
|
+
data: releaseWithCreatorFields
|
|
235
334
|
});
|
|
236
|
-
|
|
237
|
-
throw new errors.NotFoundError(`No release found for id ${id}`);
|
|
238
|
-
}
|
|
239
|
-
return release2;
|
|
335
|
+
return updatedRelease;
|
|
240
336
|
},
|
|
241
337
|
async createAction(releaseId, action) {
|
|
242
338
|
const { validateEntryContentType, validateUniqueEntry } = getService("release-validation", {
|
|
@@ -246,11 +342,19 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
246
342
|
validateEntryContentType(action.entry.contentType),
|
|
247
343
|
validateUniqueEntry(releaseId, action)
|
|
248
344
|
]);
|
|
345
|
+
const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, releaseId);
|
|
346
|
+
if (!release2) {
|
|
347
|
+
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
348
|
+
}
|
|
349
|
+
if (release2.releasedAt) {
|
|
350
|
+
throw new errors.ValidationError("Release already published");
|
|
351
|
+
}
|
|
249
352
|
const { entry, type } = action;
|
|
250
353
|
return strapi2.entityService.create(RELEASE_ACTION_MODEL_UID, {
|
|
251
354
|
data: {
|
|
252
355
|
type,
|
|
253
356
|
contentType: entry.contentType,
|
|
357
|
+
locale: entry.locale,
|
|
254
358
|
entry: {
|
|
255
359
|
id: entry.id,
|
|
256
360
|
__type: entry.contentType,
|
|
@@ -262,8 +366,10 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
262
366
|
});
|
|
263
367
|
},
|
|
264
368
|
async findActions(releaseId, query) {
|
|
265
|
-
const
|
|
266
|
-
|
|
369
|
+
const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
|
|
370
|
+
fields: ["id"]
|
|
371
|
+
});
|
|
372
|
+
if (!release2) {
|
|
267
373
|
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
268
374
|
}
|
|
269
375
|
return strapi2.entityService.findPage(RELEASE_ACTION_MODEL_UID, {
|
|
@@ -279,18 +385,40 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
279
385
|
async countActions(query) {
|
|
280
386
|
return strapi2.entityService.count(RELEASE_ACTION_MODEL_UID, query);
|
|
281
387
|
},
|
|
282
|
-
async
|
|
283
|
-
const
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
388
|
+
async groupActions(actions, groupBy) {
|
|
389
|
+
const contentTypeUids = actions.reduce((acc, action) => {
|
|
390
|
+
if (!acc.includes(action.contentType)) {
|
|
391
|
+
acc.push(action.contentType);
|
|
392
|
+
}
|
|
393
|
+
return acc;
|
|
394
|
+
}, []);
|
|
395
|
+
const allReleaseContentTypesDictionary = await this.getContentTypesDataForActions(
|
|
396
|
+
contentTypeUids
|
|
397
|
+
);
|
|
398
|
+
const allLocales = await strapi2.plugin("i18n").service("locales").find();
|
|
399
|
+
const allLocalesDictionary = allLocales.reduce((acc, locale) => {
|
|
400
|
+
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
401
|
+
return acc;
|
|
402
|
+
}, {});
|
|
403
|
+
const formattedData = actions.map((action) => {
|
|
404
|
+
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
405
|
+
return {
|
|
406
|
+
...action,
|
|
407
|
+
entry: {
|
|
408
|
+
id: action.entry.id,
|
|
409
|
+
contentType: {
|
|
410
|
+
displayName,
|
|
411
|
+
mainFieldValue: action.entry[mainField]
|
|
412
|
+
},
|
|
413
|
+
locale: action.locale ? allLocalesDictionary[action.locale] : null,
|
|
414
|
+
status: action.entry.publishedAt ? "published" : "draft"
|
|
287
415
|
}
|
|
288
|
-
|
|
289
|
-
})
|
|
290
|
-
|
|
416
|
+
};
|
|
417
|
+
});
|
|
418
|
+
const groupName = getGroupName(groupBy);
|
|
419
|
+
return _.groupBy(groupName)(formattedData);
|
|
291
420
|
},
|
|
292
|
-
async getContentTypesDataForActions(
|
|
293
|
-
const contentTypesUids = await this.getAllContentTypeUids(releaseId);
|
|
421
|
+
async getContentTypesDataForActions(contentTypesUids) {
|
|
294
422
|
const contentManagerContentTypeService = strapi2.plugin("content-manager").service("content-types");
|
|
295
423
|
const contentTypesData = {};
|
|
296
424
|
for (const contentTypeUid of contentTypesUids) {
|
|
@@ -395,13 +523,18 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
395
523
|
const updatedAction = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
396
524
|
where: {
|
|
397
525
|
id: actionId,
|
|
398
|
-
release:
|
|
526
|
+
release: {
|
|
527
|
+
id: releaseId,
|
|
528
|
+
releasedAt: {
|
|
529
|
+
$null: true
|
|
530
|
+
}
|
|
531
|
+
}
|
|
399
532
|
},
|
|
400
533
|
data: update
|
|
401
534
|
});
|
|
402
535
|
if (!updatedAction) {
|
|
403
536
|
throw new errors.NotFoundError(
|
|
404
|
-
`Action with id ${actionId} not found in release with id ${releaseId}`
|
|
537
|
+
`Action with id ${actionId} not found in release with id ${releaseId} or it is already published`
|
|
405
538
|
);
|
|
406
539
|
}
|
|
407
540
|
return updatedAction;
|
|
@@ -410,12 +543,17 @@ const createReleaseService = ({ strapi: strapi2 }) => ({
|
|
|
410
543
|
const deletedAction = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).delete({
|
|
411
544
|
where: {
|
|
412
545
|
id: actionId,
|
|
413
|
-
release:
|
|
546
|
+
release: {
|
|
547
|
+
id: releaseId,
|
|
548
|
+
releasedAt: {
|
|
549
|
+
$null: true
|
|
550
|
+
}
|
|
551
|
+
}
|
|
414
552
|
}
|
|
415
553
|
});
|
|
416
554
|
if (!deletedAction) {
|
|
417
555
|
throw new errors.NotFoundError(
|
|
418
|
-
`Action with id ${actionId} not found in release with id ${releaseId}`
|
|
556
|
+
`Action with id ${actionId} not found in release with id ${releaseId} or it is already published`
|
|
419
557
|
);
|
|
420
558
|
}
|
|
421
559
|
return deletedAction;
|
|
@@ -450,7 +588,30 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
450
588
|
}
|
|
451
589
|
}
|
|
452
590
|
});
|
|
453
|
-
const
|
|
591
|
+
const createEventManagerService = () => {
|
|
592
|
+
const state = {
|
|
593
|
+
destroyListenerCallbacks: []
|
|
594
|
+
};
|
|
595
|
+
return {
|
|
596
|
+
addDestroyListenerCallback(destroyListenerCallback) {
|
|
597
|
+
state.destroyListenerCallbacks.push(destroyListenerCallback);
|
|
598
|
+
},
|
|
599
|
+
destroyAllListeners() {
|
|
600
|
+
if (!state.destroyListenerCallbacks.length) {
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
state.destroyListenerCallbacks.forEach((destroyListenerCallback) => {
|
|
604
|
+
destroyListenerCallback();
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
};
|
|
609
|
+
const services = {
|
|
610
|
+
release: createReleaseService,
|
|
611
|
+
"release-action": createReleaseActionService,
|
|
612
|
+
"release-validation": createReleaseValidationService,
|
|
613
|
+
"event-manager": createEventManagerService
|
|
614
|
+
};
|
|
454
615
|
const RELEASE_SCHEMA = yup.object().shape({
|
|
455
616
|
name: yup.string().trim().required()
|
|
456
617
|
}).required().noUnknown();
|
|
@@ -595,31 +756,13 @@ const releaseActionController = {
|
|
|
595
756
|
});
|
|
596
757
|
const query = await permissionsManager.sanitizeQuery(ctx.query);
|
|
597
758
|
const releaseService = getService("release", { strapi });
|
|
598
|
-
const { results, pagination } = await releaseService.findActions(releaseId,
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
);
|
|
602
|
-
const allLocales = await strapi.plugin("i18n").service("locales").find();
|
|
603
|
-
const allLocalesDictionary = allLocales.reduce((acc, locale) => {
|
|
604
|
-
acc[locale.code] = { name: locale.name, code: locale.code };
|
|
605
|
-
return acc;
|
|
606
|
-
}, {});
|
|
607
|
-
const data = results.map((action) => {
|
|
608
|
-
const { mainField, displayName } = allReleaseContentTypesDictionary[action.contentType];
|
|
609
|
-
return {
|
|
610
|
-
...action,
|
|
611
|
-
entry: {
|
|
612
|
-
id: action.entry.id,
|
|
613
|
-
contentType: {
|
|
614
|
-
displayName,
|
|
615
|
-
mainFieldValue: action.entry[mainField]
|
|
616
|
-
},
|
|
617
|
-
locale: allLocalesDictionary[action.entry.locale]
|
|
618
|
-
}
|
|
619
|
-
};
|
|
759
|
+
const { results, pagination } = await releaseService.findActions(releaseId, {
|
|
760
|
+
sort: query.groupBy === "action" ? "type" : query.groupBy,
|
|
761
|
+
...query
|
|
620
762
|
});
|
|
763
|
+
const groupedData = await releaseService.groupActions(results, query.groupBy);
|
|
621
764
|
ctx.body = {
|
|
622
|
-
data,
|
|
765
|
+
data: groupedData,
|
|
623
766
|
meta: {
|
|
624
767
|
pagination
|
|
625
768
|
}
|
|
@@ -643,10 +786,8 @@ const releaseActionController = {
|
|
|
643
786
|
async delete(ctx) {
|
|
644
787
|
const actionId = ctx.params.actionId;
|
|
645
788
|
const releaseId = ctx.params.releaseId;
|
|
646
|
-
const
|
|
647
|
-
|
|
648
|
-
releaseId
|
|
649
|
-
);
|
|
789
|
+
const releaseService = getService("release", { strapi });
|
|
790
|
+
const deletedReleaseAction = await releaseService.deleteAction(actionId, releaseId);
|
|
650
791
|
ctx.body = {
|
|
651
792
|
data: deletedReleaseAction
|
|
652
793
|
};
|
|
@@ -832,10 +973,16 @@ const getPlugin = () => {
|
|
|
832
973
|
if (features.isEnabled("cms-content-releases") && strapi.features.future.isEnabled("contentReleases")) {
|
|
833
974
|
return {
|
|
834
975
|
register,
|
|
976
|
+
bootstrap,
|
|
835
977
|
contentTypes,
|
|
836
978
|
services,
|
|
837
979
|
controllers,
|
|
838
|
-
routes
|
|
980
|
+
routes,
|
|
981
|
+
destroy() {
|
|
982
|
+
if (features.isEnabled("cms-content-releases") && strapi.features.future.isEnabled("contentReleases")) {
|
|
983
|
+
getService("event-manager").destroyAllListeners();
|
|
984
|
+
}
|
|
985
|
+
}
|
|
839
986
|
};
|
|
840
987
|
}
|
|
841
988
|
return {
|