@strapi/content-releases 0.0.0-next.a9d79bec775daaf0da4e506b2aebafdb4ca95b06 → 0.0.0-next.ac2b9fdba5ef59eb22c4e387ac1c5a13dd219f29
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/LICENSE +17 -1
- package/dist/_chunks/{App-p8aKBitd.js → App-dLXY5ei3.js} +138 -131
- package/dist/_chunks/App-dLXY5ei3.js.map +1 -0
- package/dist/_chunks/{App-bpzO2Ljh.mjs → App-jrh58sXY.mjs} +141 -134
- package/dist/_chunks/App-jrh58sXY.mjs.map +1 -0
- package/dist/_chunks/{PurchaseContentReleases-Clm0iACO.mjs → PurchaseContentReleases-3tRbmbY3.mjs} +2 -2
- package/dist/_chunks/PurchaseContentReleases-3tRbmbY3.mjs.map +1 -0
- package/dist/_chunks/{PurchaseContentReleases-YhAPgpG9.js → PurchaseContentReleases-bpIYXOfu.js} +2 -2
- package/dist/_chunks/PurchaseContentReleases-bpIYXOfu.js.map +1 -0
- package/dist/_chunks/{en-gcJJ5htG.js → en-HrREghh3.js} +11 -3
- package/dist/_chunks/en-HrREghh3.js.map +1 -0
- package/dist/_chunks/{en-WuuhP6Bn.mjs → en-ltT1TlKQ.mjs} +11 -3
- package/dist/_chunks/en-ltT1TlKQ.mjs.map +1 -0
- package/dist/_chunks/{index-fP3qoWZ4.js → index-CVO0Rqdm.js} +320 -18
- package/dist/_chunks/index-CVO0Rqdm.js.map +1 -0
- package/dist/_chunks/{index-AECgcaDa.mjs → index-PiOGBETy.mjs} +325 -23
- package/dist/_chunks/index-PiOGBETy.mjs.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +291 -160
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +291 -160
- package/dist/server/index.mjs.map +1 -1
- package/package.json +15 -14
- package/dist/_chunks/App-bpzO2Ljh.mjs.map +0 -1
- package/dist/_chunks/App-p8aKBitd.js.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-WuuhP6Bn.mjs.map +0 -1
- package/dist/_chunks/en-gcJJ5htG.js.map +0 -1
- package/dist/_chunks/index-AECgcaDa.mjs.map +0 -1
- package/dist/_chunks/index-fP3qoWZ4.js.map +0 -1
package/dist/server/index.js
CHANGED
|
@@ -235,13 +235,16 @@ async function disableContentTypeLocalized({ oldContentTypes, contentTypes: cont
|
|
|
235
235
|
if (!oldContentTypes) {
|
|
236
236
|
return;
|
|
237
237
|
}
|
|
238
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
239
|
+
if (!i18nPlugin) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
238
242
|
for (const uid in contentTypes2) {
|
|
239
243
|
if (!oldContentTypes[uid]) {
|
|
240
244
|
continue;
|
|
241
245
|
}
|
|
242
246
|
const oldContentType = oldContentTypes[uid];
|
|
243
247
|
const contentType = contentTypes2[uid];
|
|
244
|
-
const i18nPlugin = strapi.plugin("i18n");
|
|
245
248
|
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
246
249
|
if (isLocalizedContentType(oldContentType) && !isLocalizedContentType(contentType)) {
|
|
247
250
|
await strapi.db.queryBuilder(RELEASE_ACTION_MODEL_UID).update({
|
|
@@ -254,13 +257,16 @@ async function enableContentTypeLocalized({ oldContentTypes, contentTypes: conte
|
|
|
254
257
|
if (!oldContentTypes) {
|
|
255
258
|
return;
|
|
256
259
|
}
|
|
260
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
261
|
+
if (!i18nPlugin) {
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
257
264
|
for (const uid in contentTypes2) {
|
|
258
265
|
if (!oldContentTypes[uid]) {
|
|
259
266
|
continue;
|
|
260
267
|
}
|
|
261
268
|
const oldContentType = oldContentTypes[uid];
|
|
262
269
|
const contentType = contentTypes2[uid];
|
|
263
|
-
const i18nPlugin = strapi.plugin("i18n");
|
|
264
270
|
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
265
271
|
const { getDefaultLocale } = i18nPlugin.service("locales");
|
|
266
272
|
if (!isLocalizedContentType(oldContentType) && isLocalizedContentType(contentType)) {
|
|
@@ -407,27 +413,23 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
407
413
|
}
|
|
408
414
|
}
|
|
409
415
|
});
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
});
|
|
420
|
-
}
|
|
416
|
+
getService("scheduling", { strapi: strapi2 }).syncFromDatabase().catch((err) => {
|
|
417
|
+
strapi2.log.error(
|
|
418
|
+
"Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling."
|
|
419
|
+
);
|
|
420
|
+
throw err;
|
|
421
|
+
});
|
|
422
|
+
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
|
423
|
+
strapi2.webhookStore.addAllowedEvent(key, value);
|
|
424
|
+
});
|
|
421
425
|
}
|
|
422
426
|
};
|
|
423
427
|
const destroy = async ({ strapi: strapi2 }) => {
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
job.cancel();
|
|
430
|
-
}
|
|
428
|
+
const scheduledJobs = getService("scheduling", {
|
|
429
|
+
strapi: strapi2
|
|
430
|
+
}).getAll();
|
|
431
|
+
for (const [, job] of scheduledJobs) {
|
|
432
|
+
job.cancel();
|
|
431
433
|
}
|
|
432
434
|
};
|
|
433
435
|
const schema$1 = {
|
|
@@ -552,6 +554,94 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
552
554
|
release: release2
|
|
553
555
|
});
|
|
554
556
|
};
|
|
557
|
+
const publishSingleTypeAction = async (uid, actionType, entryId) => {
|
|
558
|
+
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
559
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
560
|
+
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
561
|
+
const entry = await strapi2.entityService.findOne(uid, entryId, { populate });
|
|
562
|
+
try {
|
|
563
|
+
if (actionType === "publish") {
|
|
564
|
+
await entityManagerService.publish(entry, uid);
|
|
565
|
+
} else {
|
|
566
|
+
await entityManagerService.unpublish(entry, uid);
|
|
567
|
+
}
|
|
568
|
+
} catch (error) {
|
|
569
|
+
if (error instanceof utils.errors.ApplicationError && (error.message === "already.published" || error.message === "already.draft"))
|
|
570
|
+
;
|
|
571
|
+
else {
|
|
572
|
+
throw error;
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
};
|
|
576
|
+
const publishCollectionTypeAction = async (uid, entriesToPublishIds, entriestoUnpublishIds) => {
|
|
577
|
+
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
578
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
579
|
+
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
580
|
+
const entriesToPublish = await strapi2.entityService.findMany(uid, {
|
|
581
|
+
filters: {
|
|
582
|
+
id: {
|
|
583
|
+
$in: entriesToPublishIds
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
populate
|
|
587
|
+
});
|
|
588
|
+
const entriesToUnpublish = await strapi2.entityService.findMany(uid, {
|
|
589
|
+
filters: {
|
|
590
|
+
id: {
|
|
591
|
+
$in: entriestoUnpublishIds
|
|
592
|
+
}
|
|
593
|
+
},
|
|
594
|
+
populate
|
|
595
|
+
});
|
|
596
|
+
if (entriesToPublish.length > 0) {
|
|
597
|
+
await entityManagerService.publishMany(entriesToPublish, uid);
|
|
598
|
+
}
|
|
599
|
+
if (entriesToUnpublish.length > 0) {
|
|
600
|
+
await entityManagerService.unpublishMany(entriesToUnpublish, uid);
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
const getFormattedActions = async (releaseId) => {
|
|
604
|
+
const actions = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).findMany({
|
|
605
|
+
where: {
|
|
606
|
+
release: {
|
|
607
|
+
id: releaseId
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
populate: {
|
|
611
|
+
entry: {
|
|
612
|
+
fields: ["id"]
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
});
|
|
616
|
+
if (actions.length === 0) {
|
|
617
|
+
throw new utils.errors.ValidationError("No entries to publish");
|
|
618
|
+
}
|
|
619
|
+
const collectionTypeActions = {};
|
|
620
|
+
const singleTypeActions = [];
|
|
621
|
+
for (const action of actions) {
|
|
622
|
+
const contentTypeUid = action.contentType;
|
|
623
|
+
if (strapi2.contentTypes[contentTypeUid].kind === "collectionType") {
|
|
624
|
+
if (!collectionTypeActions[contentTypeUid]) {
|
|
625
|
+
collectionTypeActions[contentTypeUid] = {
|
|
626
|
+
entriesToPublishIds: [],
|
|
627
|
+
entriesToUnpublishIds: []
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
if (action.type === "publish") {
|
|
631
|
+
collectionTypeActions[contentTypeUid].entriesToPublishIds.push(action.entry.id);
|
|
632
|
+
} else {
|
|
633
|
+
collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
634
|
+
}
|
|
635
|
+
} else {
|
|
636
|
+
singleTypeActions.push({
|
|
637
|
+
uid: contentTypeUid,
|
|
638
|
+
action: action.type,
|
|
639
|
+
id: action.entry.id
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
return { collectionTypeActions, singleTypeActions };
|
|
644
|
+
};
|
|
555
645
|
return {
|
|
556
646
|
async create(releaseData, { user }) {
|
|
557
647
|
const releaseWithCreatorFields = await utils.setCreatorFields({ user })(releaseData);
|
|
@@ -571,7 +661,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
571
661
|
status: "empty"
|
|
572
662
|
}
|
|
573
663
|
});
|
|
574
|
-
if (
|
|
664
|
+
if (releaseWithCreatorFields.scheduledAt) {
|
|
575
665
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
576
666
|
await schedulingService.set(release2.id, release2.scheduledAt);
|
|
577
667
|
}
|
|
@@ -595,12 +685,18 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
595
685
|
}
|
|
596
686
|
});
|
|
597
687
|
},
|
|
598
|
-
async findManyWithContentTypeEntryAttached(contentTypeUid,
|
|
688
|
+
async findManyWithContentTypeEntryAttached(contentTypeUid, entriesIds) {
|
|
689
|
+
let entries = entriesIds;
|
|
690
|
+
if (!Array.isArray(entriesIds)) {
|
|
691
|
+
entries = [entriesIds];
|
|
692
|
+
}
|
|
599
693
|
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
600
694
|
where: {
|
|
601
695
|
actions: {
|
|
602
696
|
target_type: contentTypeUid,
|
|
603
|
-
target_id:
|
|
697
|
+
target_id: {
|
|
698
|
+
$in: entries
|
|
699
|
+
}
|
|
604
700
|
},
|
|
605
701
|
releasedAt: {
|
|
606
702
|
$null: true
|
|
@@ -611,18 +707,25 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
611
707
|
actions: {
|
|
612
708
|
where: {
|
|
613
709
|
target_type: contentTypeUid,
|
|
614
|
-
target_id:
|
|
710
|
+
target_id: {
|
|
711
|
+
$in: entries
|
|
712
|
+
}
|
|
713
|
+
},
|
|
714
|
+
populate: {
|
|
715
|
+
entry: {
|
|
716
|
+
select: ["id"]
|
|
717
|
+
}
|
|
615
718
|
}
|
|
616
719
|
}
|
|
617
720
|
}
|
|
618
721
|
});
|
|
619
722
|
return releases.map((release2) => {
|
|
620
723
|
if (release2.actions?.length) {
|
|
621
|
-
const
|
|
724
|
+
const actionsForEntry = release2.actions;
|
|
622
725
|
delete release2.actions;
|
|
623
726
|
return {
|
|
624
727
|
...release2,
|
|
625
|
-
|
|
728
|
+
actions: actionsForEntry
|
|
626
729
|
};
|
|
627
730
|
}
|
|
628
731
|
return release2;
|
|
@@ -696,19 +799,17 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
696
799
|
// @ts-expect-error see above
|
|
697
800
|
data: releaseWithCreatorFields
|
|
698
801
|
});
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
schedulingService.cancel(id);
|
|
705
|
-
}
|
|
802
|
+
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
803
|
+
if (releaseData.scheduledAt) {
|
|
804
|
+
await schedulingService.set(id, releaseData.scheduledAt);
|
|
805
|
+
} else if (release2.scheduledAt) {
|
|
806
|
+
schedulingService.cancel(id);
|
|
706
807
|
}
|
|
707
808
|
this.updateReleaseStatus(id);
|
|
708
809
|
strapi2.telemetry.send("didUpdateContentRelease");
|
|
709
810
|
return updatedRelease;
|
|
710
811
|
},
|
|
711
|
-
async createAction(releaseId, action) {
|
|
812
|
+
async createAction(releaseId, action, { disableUpdateReleaseStatus = false } = {}) {
|
|
712
813
|
const { validateEntryContentType, validateUniqueEntry } = getService("release-validation", {
|
|
713
814
|
strapi: strapi2
|
|
714
815
|
});
|
|
@@ -741,7 +842,9 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
741
842
|
},
|
|
742
843
|
populate: { release: { fields: ["id"] }, entry: { fields: ["id"] } }
|
|
743
844
|
});
|
|
744
|
-
|
|
845
|
+
if (!disableUpdateReleaseStatus) {
|
|
846
|
+
this.updateReleaseStatus(releaseId);
|
|
847
|
+
}
|
|
745
848
|
return releaseAction2;
|
|
746
849
|
},
|
|
747
850
|
async findActions(releaseId, query) {
|
|
@@ -868,7 +971,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
868
971
|
});
|
|
869
972
|
await strapi2.entityService.delete(RELEASE_MODEL_UID, releaseId);
|
|
870
973
|
});
|
|
871
|
-
if (
|
|
974
|
+
if (release2.scheduledAt) {
|
|
872
975
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
873
976
|
await schedulingService.cancel(release2.id);
|
|
874
977
|
}
|
|
@@ -876,145 +979,71 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
876
979
|
return release2;
|
|
877
980
|
},
|
|
878
981
|
async publish(releaseId) {
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
actions: {
|
|
886
|
-
populate: {
|
|
887
|
-
entry: {
|
|
888
|
-
fields: ["id"]
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
);
|
|
895
|
-
if (!releaseWithPopulatedActionEntries) {
|
|
982
|
+
const {
|
|
983
|
+
release: release2,
|
|
984
|
+
error
|
|
985
|
+
} = await strapi2.db.transaction(async ({ trx }) => {
|
|
986
|
+
const lockedRelease = await strapi2.db?.queryBuilder(RELEASE_MODEL_UID).where({ id: releaseId }).select(["id", "name", "releasedAt", "status"]).first().transacting(trx).forUpdate().execute();
|
|
987
|
+
if (!lockedRelease) {
|
|
896
988
|
throw new utils.errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
897
989
|
}
|
|
898
|
-
if (
|
|
990
|
+
if (lockedRelease.releasedAt) {
|
|
899
991
|
throw new utils.errors.ValidationError("Release already published");
|
|
900
992
|
}
|
|
901
|
-
if (
|
|
902
|
-
throw new utils.errors.ValidationError("
|
|
993
|
+
if (lockedRelease.status === "failed") {
|
|
994
|
+
throw new utils.errors.ValidationError("Release failed to publish");
|
|
903
995
|
}
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
entriesToUnpublishIds: []
|
|
913
|
-
};
|
|
914
|
-
}
|
|
915
|
-
if (action.type === "publish") {
|
|
916
|
-
collectionTypeActions[contentTypeUid].entriestoPublishIds.push(action.entry.id);
|
|
917
|
-
} else {
|
|
918
|
-
collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
919
|
-
}
|
|
920
|
-
} else {
|
|
921
|
-
singleTypeActions.push({
|
|
922
|
-
uid: contentTypeUid,
|
|
923
|
-
action: action.type,
|
|
924
|
-
id: action.entry.id
|
|
925
|
-
});
|
|
926
|
-
}
|
|
927
|
-
}
|
|
928
|
-
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
929
|
-
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
930
|
-
await strapi2.db.transaction(async () => {
|
|
931
|
-
for (const { uid, action, id } of singleTypeActions) {
|
|
932
|
-
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
933
|
-
const entry = await strapi2.entityService.findOne(uid, id, { populate });
|
|
934
|
-
try {
|
|
935
|
-
if (action === "publish") {
|
|
936
|
-
await entityManagerService.publish(entry, uid);
|
|
937
|
-
} else {
|
|
938
|
-
await entityManagerService.unpublish(entry, uid);
|
|
939
|
-
}
|
|
940
|
-
} catch (error) {
|
|
941
|
-
if (error instanceof utils.errors.ApplicationError && (error.message === "already.published" || error.message === "already.draft")) {
|
|
942
|
-
} else {
|
|
943
|
-
throw error;
|
|
944
|
-
}
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
for (const contentTypeUid of Object.keys(collectionTypeActions)) {
|
|
948
|
-
const populate = await populateBuilderService(contentTypeUid).populateDeep(Infinity).build();
|
|
949
|
-
const { entriestoPublishIds, entriesToUnpublishIds } = collectionTypeActions[contentTypeUid];
|
|
950
|
-
const entriesToPublish = await strapi2.entityService.findMany(
|
|
951
|
-
contentTypeUid,
|
|
952
|
-
{
|
|
953
|
-
filters: {
|
|
954
|
-
id: {
|
|
955
|
-
$in: entriestoPublishIds
|
|
956
|
-
}
|
|
957
|
-
},
|
|
958
|
-
populate
|
|
959
|
-
}
|
|
960
|
-
);
|
|
961
|
-
const entriesToUnpublish = await strapi2.entityService.findMany(
|
|
962
|
-
contentTypeUid,
|
|
963
|
-
{
|
|
964
|
-
filters: {
|
|
965
|
-
id: {
|
|
966
|
-
$in: entriesToUnpublishIds
|
|
967
|
-
}
|
|
968
|
-
},
|
|
969
|
-
populate
|
|
970
|
-
}
|
|
971
|
-
);
|
|
972
|
-
if (entriesToPublish.length > 0) {
|
|
973
|
-
await entityManagerService.publishMany(entriesToPublish, contentTypeUid);
|
|
996
|
+
try {
|
|
997
|
+
strapi2.log.info(`[Content Releases] Starting to publish release ${lockedRelease.name}`);
|
|
998
|
+
const { collectionTypeActions, singleTypeActions } = await getFormattedActions(
|
|
999
|
+
releaseId
|
|
1000
|
+
);
|
|
1001
|
+
await strapi2.db.transaction(async () => {
|
|
1002
|
+
for (const { uid, action, id } of singleTypeActions) {
|
|
1003
|
+
await publishSingleTypeAction(uid, action, id);
|
|
974
1004
|
}
|
|
975
|
-
|
|
976
|
-
|
|
1005
|
+
for (const contentTypeUid of Object.keys(collectionTypeActions)) {
|
|
1006
|
+
const uid = contentTypeUid;
|
|
1007
|
+
await publishCollectionTypeAction(
|
|
1008
|
+
uid,
|
|
1009
|
+
collectionTypeActions[uid].entriesToPublishIds,
|
|
1010
|
+
collectionTypeActions[uid].entriesToUnpublishIds
|
|
1011
|
+
);
|
|
977
1012
|
}
|
|
978
|
-
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
releasedAt: /* @__PURE__ */ new Date()
|
|
987
|
-
},
|
|
988
|
-
populate: {
|
|
989
|
-
actions: {
|
|
990
|
-
// @ts-expect-error is not expecting count but it is working
|
|
991
|
-
count: true
|
|
1013
|
+
});
|
|
1014
|
+
const release22 = await strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
1015
|
+
where: {
|
|
1016
|
+
id: releaseId
|
|
1017
|
+
},
|
|
1018
|
+
data: {
|
|
1019
|
+
status: "done",
|
|
1020
|
+
releasedAt: /* @__PURE__ */ new Date()
|
|
992
1021
|
}
|
|
993
|
-
}
|
|
994
|
-
});
|
|
995
|
-
if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
|
|
1022
|
+
});
|
|
996
1023
|
dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {
|
|
997
1024
|
isPublished: true,
|
|
998
|
-
release:
|
|
1025
|
+
release: release22
|
|
999
1026
|
});
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
} catch (error) {
|
|
1004
|
-
if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
|
|
1027
|
+
strapi2.telemetry.send("didPublishContentRelease");
|
|
1028
|
+
return { release: release22, error: null };
|
|
1029
|
+
} catch (error2) {
|
|
1005
1030
|
dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {
|
|
1006
1031
|
isPublished: false,
|
|
1007
|
-
error
|
|
1032
|
+
error: error2
|
|
1008
1033
|
});
|
|
1009
|
-
|
|
1010
|
-
strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
1011
|
-
where: { id: releaseId },
|
|
1012
|
-
data: {
|
|
1034
|
+
await strapi2.db?.queryBuilder(RELEASE_MODEL_UID).where({ id: releaseId }).update({
|
|
1013
1035
|
status: "failed"
|
|
1014
|
-
}
|
|
1015
|
-
|
|
1036
|
+
}).transacting(trx).execute();
|
|
1037
|
+
return {
|
|
1038
|
+
release: null,
|
|
1039
|
+
error: error2
|
|
1040
|
+
};
|
|
1041
|
+
}
|
|
1042
|
+
});
|
|
1043
|
+
if (error) {
|
|
1016
1044
|
throw error;
|
|
1017
1045
|
}
|
|
1046
|
+
return release2;
|
|
1018
1047
|
},
|
|
1019
1048
|
async updateAction(actionId, releaseId, update) {
|
|
1020
1049
|
const updatedAction = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
@@ -1101,6 +1130,12 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
1101
1130
|
}
|
|
1102
1131
|
};
|
|
1103
1132
|
};
|
|
1133
|
+
class AlreadyOnReleaseError extends utils.errors.ApplicationError {
|
|
1134
|
+
constructor(message) {
|
|
1135
|
+
super(message);
|
|
1136
|
+
this.name = "AlreadyOnReleaseError";
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1104
1139
|
const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
1105
1140
|
async validateUniqueEntry(releaseId, releaseActionArgs) {
|
|
1106
1141
|
const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
|
|
@@ -1113,7 +1148,7 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1113
1148
|
(action) => Number(action.entry.id) === Number(releaseActionArgs.entry.id) && action.contentType === releaseActionArgs.entry.contentType
|
|
1114
1149
|
);
|
|
1115
1150
|
if (isEntryInRelease) {
|
|
1116
|
-
throw new
|
|
1151
|
+
throw new AlreadyOnReleaseError(
|
|
1117
1152
|
`Entry with id ${releaseActionArgs.entry.id} and contentType ${releaseActionArgs.entry.contentType} already exists in release with id ${releaseId}`
|
|
1118
1153
|
);
|
|
1119
1154
|
}
|
|
@@ -1221,7 +1256,7 @@ const createSchedulingService = ({ strapi: strapi2 }) => {
|
|
|
1221
1256
|
const services = {
|
|
1222
1257
|
release: createReleaseService,
|
|
1223
1258
|
"release-validation": createReleaseValidationService,
|
|
1224
|
-
|
|
1259
|
+
scheduling: createSchedulingService
|
|
1225
1260
|
};
|
|
1226
1261
|
const RELEASE_SCHEMA = yup__namespace.object().shape({
|
|
1227
1262
|
name: yup__namespace.string().trim().required(),
|
|
@@ -1308,6 +1343,33 @@ const releaseController = {
|
|
|
1308
1343
|
};
|
|
1309
1344
|
ctx.body = { data };
|
|
1310
1345
|
},
|
|
1346
|
+
async mapEntriesToReleases(ctx) {
|
|
1347
|
+
const { contentTypeUid, entriesIds } = ctx.query;
|
|
1348
|
+
if (!contentTypeUid || !entriesIds) {
|
|
1349
|
+
throw new utils.errors.ValidationError("Missing required query parameters");
|
|
1350
|
+
}
|
|
1351
|
+
const releaseService = getService("release", { strapi });
|
|
1352
|
+
const releasesWithActions = await releaseService.findManyWithContentTypeEntryAttached(
|
|
1353
|
+
contentTypeUid,
|
|
1354
|
+
entriesIds
|
|
1355
|
+
);
|
|
1356
|
+
const mappedEntriesInReleases = releasesWithActions.reduce(
|
|
1357
|
+
(acc, release2) => {
|
|
1358
|
+
release2.actions.forEach((action) => {
|
|
1359
|
+
if (!acc[action.entry.id]) {
|
|
1360
|
+
acc[action.entry.id] = [{ id: release2.id, name: release2.name }];
|
|
1361
|
+
} else {
|
|
1362
|
+
acc[action.entry.id].push({ id: release2.id, name: release2.name });
|
|
1363
|
+
}
|
|
1364
|
+
});
|
|
1365
|
+
return acc;
|
|
1366
|
+
},
|
|
1367
|
+
{}
|
|
1368
|
+
);
|
|
1369
|
+
ctx.body = {
|
|
1370
|
+
data: mappedEntriesInReleases
|
|
1371
|
+
};
|
|
1372
|
+
},
|
|
1311
1373
|
async create(ctx) {
|
|
1312
1374
|
const user = ctx.state.user;
|
|
1313
1375
|
const releaseArgs = ctx.request.body;
|
|
@@ -1397,6 +1459,43 @@ const releaseActionController = {
|
|
|
1397
1459
|
data: releaseAction2
|
|
1398
1460
|
};
|
|
1399
1461
|
},
|
|
1462
|
+
async createMany(ctx) {
|
|
1463
|
+
const releaseId = ctx.params.releaseId;
|
|
1464
|
+
const releaseActionsArgs = ctx.request.body;
|
|
1465
|
+
await Promise.all(
|
|
1466
|
+
releaseActionsArgs.map((releaseActionArgs) => validateReleaseAction(releaseActionArgs))
|
|
1467
|
+
);
|
|
1468
|
+
const releaseService = getService("release", { strapi });
|
|
1469
|
+
const releaseActions = await strapi.db.transaction(async () => {
|
|
1470
|
+
const releaseActions2 = await Promise.all(
|
|
1471
|
+
releaseActionsArgs.map(async (releaseActionArgs) => {
|
|
1472
|
+
try {
|
|
1473
|
+
const action = await releaseService.createAction(releaseId, releaseActionArgs, {
|
|
1474
|
+
disableUpdateReleaseStatus: true
|
|
1475
|
+
});
|
|
1476
|
+
return action;
|
|
1477
|
+
} catch (error) {
|
|
1478
|
+
if (error instanceof AlreadyOnReleaseError) {
|
|
1479
|
+
return null;
|
|
1480
|
+
}
|
|
1481
|
+
throw error;
|
|
1482
|
+
}
|
|
1483
|
+
})
|
|
1484
|
+
);
|
|
1485
|
+
return releaseActions2;
|
|
1486
|
+
});
|
|
1487
|
+
const newReleaseActions = releaseActions.filter((action) => action !== null);
|
|
1488
|
+
if (newReleaseActions.length > 0) {
|
|
1489
|
+
releaseService.updateReleaseStatus(releaseId);
|
|
1490
|
+
}
|
|
1491
|
+
ctx.body = {
|
|
1492
|
+
data: newReleaseActions,
|
|
1493
|
+
meta: {
|
|
1494
|
+
entriesAlreadyInRelease: releaseActions.length - newReleaseActions.length,
|
|
1495
|
+
totalEntries: releaseActions.length
|
|
1496
|
+
}
|
|
1497
|
+
};
|
|
1498
|
+
},
|
|
1400
1499
|
async findMany(ctx) {
|
|
1401
1500
|
const releaseId = ctx.params.releaseId;
|
|
1402
1501
|
const permissionsManager = strapi.admin.services.permission.createPermissionsManager({
|
|
@@ -1465,6 +1564,22 @@ const controllers = { release: releaseController, "release-action": releaseActio
|
|
|
1465
1564
|
const release = {
|
|
1466
1565
|
type: "admin",
|
|
1467
1566
|
routes: [
|
|
1567
|
+
{
|
|
1568
|
+
method: "GET",
|
|
1569
|
+
path: "/mapEntriesToReleases",
|
|
1570
|
+
handler: "release.mapEntriesToReleases",
|
|
1571
|
+
config: {
|
|
1572
|
+
policies: [
|
|
1573
|
+
"admin::isAuthenticatedAdmin",
|
|
1574
|
+
{
|
|
1575
|
+
name: "admin::hasPermissions",
|
|
1576
|
+
config: {
|
|
1577
|
+
actions: ["plugin::content-releases.read"]
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
]
|
|
1581
|
+
}
|
|
1582
|
+
},
|
|
1468
1583
|
{
|
|
1469
1584
|
method: "POST",
|
|
1470
1585
|
path: "/",
|
|
@@ -1582,6 +1697,22 @@ const releaseAction = {
|
|
|
1582
1697
|
]
|
|
1583
1698
|
}
|
|
1584
1699
|
},
|
|
1700
|
+
{
|
|
1701
|
+
method: "POST",
|
|
1702
|
+
path: "/:releaseId/actions/bulk",
|
|
1703
|
+
handler: "release-action.createMany",
|
|
1704
|
+
config: {
|
|
1705
|
+
policies: [
|
|
1706
|
+
"admin::isAuthenticatedAdmin",
|
|
1707
|
+
{
|
|
1708
|
+
name: "admin::hasPermissions",
|
|
1709
|
+
config: {
|
|
1710
|
+
actions: ["plugin::content-releases.create-action"]
|
|
1711
|
+
}
|
|
1712
|
+
}
|
|
1713
|
+
]
|
|
1714
|
+
}
|
|
1715
|
+
},
|
|
1585
1716
|
{
|
|
1586
1717
|
method: "GET",
|
|
1587
1718
|
path: "/:releaseId/actions",
|