@strapi/content-releases 0.0.0-next.836f74517f9a428a4798ed889c3f05057ec6beb1 → 0.0.0-next.8b561475428ed29d8c7ca70ec2e96f051220ebaf
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-pNsURCL_.js → App-dLXY5ei3.js} +146 -138
- package/dist/_chunks/App-dLXY5ei3.js.map +1 -0
- package/dist/_chunks/{App-fcvNs2Qb.mjs → App-jrh58sXY.mjs} +150 -142
- 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-gzTuOXiK.js → index-CVO0Rqdm.js} +320 -18
- package/dist/_chunks/index-CVO0Rqdm.js.map +1 -0
- package/dist/_chunks/{index-pxhi8wsT.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 +290 -158
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +290 -158
- package/dist/server/index.mjs.map +1 -1
- package/package.json +12 -12
- package/dist/_chunks/App-fcvNs2Qb.mjs.map +0 -1
- package/dist/_chunks/App-pNsURCL_.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-gzTuOXiK.js.map +0 -1
- package/dist/_chunks/index-pxhi8wsT.mjs.map +0 -1
package/dist/server/index.mjs
CHANGED
|
@@ -211,13 +211,16 @@ async function disableContentTypeLocalized({ oldContentTypes, contentTypes: cont
|
|
|
211
211
|
if (!oldContentTypes) {
|
|
212
212
|
return;
|
|
213
213
|
}
|
|
214
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
215
|
+
if (!i18nPlugin) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
214
218
|
for (const uid in contentTypes2) {
|
|
215
219
|
if (!oldContentTypes[uid]) {
|
|
216
220
|
continue;
|
|
217
221
|
}
|
|
218
222
|
const oldContentType = oldContentTypes[uid];
|
|
219
223
|
const contentType = contentTypes2[uid];
|
|
220
|
-
const i18nPlugin = strapi.plugin("i18n");
|
|
221
224
|
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
222
225
|
if (isLocalizedContentType(oldContentType) && !isLocalizedContentType(contentType)) {
|
|
223
226
|
await strapi.db.queryBuilder(RELEASE_ACTION_MODEL_UID).update({
|
|
@@ -230,13 +233,16 @@ async function enableContentTypeLocalized({ oldContentTypes, contentTypes: conte
|
|
|
230
233
|
if (!oldContentTypes) {
|
|
231
234
|
return;
|
|
232
235
|
}
|
|
236
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
237
|
+
if (!i18nPlugin) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
233
240
|
for (const uid in contentTypes2) {
|
|
234
241
|
if (!oldContentTypes[uid]) {
|
|
235
242
|
continue;
|
|
236
243
|
}
|
|
237
244
|
const oldContentType = oldContentTypes[uid];
|
|
238
245
|
const contentType = contentTypes2[uid];
|
|
239
|
-
const i18nPlugin = strapi.plugin("i18n");
|
|
240
246
|
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
241
247
|
const { getDefaultLocale } = i18nPlugin.service("locales");
|
|
242
248
|
if (!isLocalizedContentType(oldContentType) && isLocalizedContentType(contentType)) {
|
|
@@ -254,6 +260,11 @@ const register = async ({ strapi: strapi2 }) => {
|
|
|
254
260
|
strapi2.hook("strapi::content-types.beforeSync").register(deleteActionsOnDisableDraftAndPublish).register(disableContentTypeLocalized);
|
|
255
261
|
strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType).register(enableContentTypeLocalized).register(revalidateChangedContentTypes).register(migrateIsValidAndStatusReleases);
|
|
256
262
|
}
|
|
263
|
+
if (strapi2.plugin("graphql")) {
|
|
264
|
+
const graphqlExtensionService = strapi2.plugin("graphql").service("extension");
|
|
265
|
+
graphqlExtensionService.shadowCRUD(RELEASE_MODEL_UID).disable();
|
|
266
|
+
graphqlExtensionService.shadowCRUD(RELEASE_ACTION_MODEL_UID).disable();
|
|
267
|
+
}
|
|
257
268
|
};
|
|
258
269
|
const { features: features$1 } = require("@strapi/strapi/dist/utils/ee");
|
|
259
270
|
const bootstrap = async ({ strapi: strapi2 }) => {
|
|
@@ -378,27 +389,23 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
378
389
|
}
|
|
379
390
|
}
|
|
380
391
|
});
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
+
getService("scheduling", { strapi: strapi2 }).syncFromDatabase().catch((err) => {
|
|
393
|
+
strapi2.log.error(
|
|
394
|
+
"Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling."
|
|
395
|
+
);
|
|
396
|
+
throw err;
|
|
397
|
+
});
|
|
398
|
+
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
|
399
|
+
strapi2.webhookStore.addAllowedEvent(key, value);
|
|
400
|
+
});
|
|
392
401
|
}
|
|
393
402
|
};
|
|
394
403
|
const destroy = async ({ strapi: strapi2 }) => {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
job.cancel();
|
|
401
|
-
}
|
|
404
|
+
const scheduledJobs = getService("scheduling", {
|
|
405
|
+
strapi: strapi2
|
|
406
|
+
}).getAll();
|
|
407
|
+
for (const [, job] of scheduledJobs) {
|
|
408
|
+
job.cancel();
|
|
402
409
|
}
|
|
403
410
|
};
|
|
404
411
|
const schema$1 = {
|
|
@@ -523,6 +530,94 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
523
530
|
release: release2
|
|
524
531
|
});
|
|
525
532
|
};
|
|
533
|
+
const publishSingleTypeAction = async (uid, actionType, entryId) => {
|
|
534
|
+
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
535
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
536
|
+
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
537
|
+
const entry = await strapi2.entityService.findOne(uid, entryId, { populate });
|
|
538
|
+
try {
|
|
539
|
+
if (actionType === "publish") {
|
|
540
|
+
await entityManagerService.publish(entry, uid);
|
|
541
|
+
} else {
|
|
542
|
+
await entityManagerService.unpublish(entry, uid);
|
|
543
|
+
}
|
|
544
|
+
} catch (error) {
|
|
545
|
+
if (error instanceof errors.ApplicationError && (error.message === "already.published" || error.message === "already.draft"))
|
|
546
|
+
;
|
|
547
|
+
else {
|
|
548
|
+
throw error;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
const publishCollectionTypeAction = async (uid, entriesToPublishIds, entriestoUnpublishIds) => {
|
|
553
|
+
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
554
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
555
|
+
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
556
|
+
const entriesToPublish = await strapi2.entityService.findMany(uid, {
|
|
557
|
+
filters: {
|
|
558
|
+
id: {
|
|
559
|
+
$in: entriesToPublishIds
|
|
560
|
+
}
|
|
561
|
+
},
|
|
562
|
+
populate
|
|
563
|
+
});
|
|
564
|
+
const entriesToUnpublish = await strapi2.entityService.findMany(uid, {
|
|
565
|
+
filters: {
|
|
566
|
+
id: {
|
|
567
|
+
$in: entriestoUnpublishIds
|
|
568
|
+
}
|
|
569
|
+
},
|
|
570
|
+
populate
|
|
571
|
+
});
|
|
572
|
+
if (entriesToPublish.length > 0) {
|
|
573
|
+
await entityManagerService.publishMany(entriesToPublish, uid);
|
|
574
|
+
}
|
|
575
|
+
if (entriesToUnpublish.length > 0) {
|
|
576
|
+
await entityManagerService.unpublishMany(entriesToUnpublish, uid);
|
|
577
|
+
}
|
|
578
|
+
};
|
|
579
|
+
const getFormattedActions = async (releaseId) => {
|
|
580
|
+
const actions = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).findMany({
|
|
581
|
+
where: {
|
|
582
|
+
release: {
|
|
583
|
+
id: releaseId
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
populate: {
|
|
587
|
+
entry: {
|
|
588
|
+
fields: ["id"]
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
});
|
|
592
|
+
if (actions.length === 0) {
|
|
593
|
+
throw new errors.ValidationError("No entries to publish");
|
|
594
|
+
}
|
|
595
|
+
const collectionTypeActions = {};
|
|
596
|
+
const singleTypeActions = [];
|
|
597
|
+
for (const action of actions) {
|
|
598
|
+
const contentTypeUid = action.contentType;
|
|
599
|
+
if (strapi2.contentTypes[contentTypeUid].kind === "collectionType") {
|
|
600
|
+
if (!collectionTypeActions[contentTypeUid]) {
|
|
601
|
+
collectionTypeActions[contentTypeUid] = {
|
|
602
|
+
entriesToPublishIds: [],
|
|
603
|
+
entriesToUnpublishIds: []
|
|
604
|
+
};
|
|
605
|
+
}
|
|
606
|
+
if (action.type === "publish") {
|
|
607
|
+
collectionTypeActions[contentTypeUid].entriesToPublishIds.push(action.entry.id);
|
|
608
|
+
} else {
|
|
609
|
+
collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
610
|
+
}
|
|
611
|
+
} else {
|
|
612
|
+
singleTypeActions.push({
|
|
613
|
+
uid: contentTypeUid,
|
|
614
|
+
action: action.type,
|
|
615
|
+
id: action.entry.id
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
return { collectionTypeActions, singleTypeActions };
|
|
620
|
+
};
|
|
526
621
|
return {
|
|
527
622
|
async create(releaseData, { user }) {
|
|
528
623
|
const releaseWithCreatorFields = await setCreatorFields({ user })(releaseData);
|
|
@@ -542,7 +637,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
542
637
|
status: "empty"
|
|
543
638
|
}
|
|
544
639
|
});
|
|
545
|
-
if (
|
|
640
|
+
if (releaseWithCreatorFields.scheduledAt) {
|
|
546
641
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
547
642
|
await schedulingService.set(release2.id, release2.scheduledAt);
|
|
548
643
|
}
|
|
@@ -566,12 +661,18 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
566
661
|
}
|
|
567
662
|
});
|
|
568
663
|
},
|
|
569
|
-
async findManyWithContentTypeEntryAttached(contentTypeUid,
|
|
664
|
+
async findManyWithContentTypeEntryAttached(contentTypeUid, entriesIds) {
|
|
665
|
+
let entries = entriesIds;
|
|
666
|
+
if (!Array.isArray(entriesIds)) {
|
|
667
|
+
entries = [entriesIds];
|
|
668
|
+
}
|
|
570
669
|
const releases = await strapi2.db.query(RELEASE_MODEL_UID).findMany({
|
|
571
670
|
where: {
|
|
572
671
|
actions: {
|
|
573
672
|
target_type: contentTypeUid,
|
|
574
|
-
target_id:
|
|
673
|
+
target_id: {
|
|
674
|
+
$in: entries
|
|
675
|
+
}
|
|
575
676
|
},
|
|
576
677
|
releasedAt: {
|
|
577
678
|
$null: true
|
|
@@ -582,18 +683,25 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
582
683
|
actions: {
|
|
583
684
|
where: {
|
|
584
685
|
target_type: contentTypeUid,
|
|
585
|
-
target_id:
|
|
686
|
+
target_id: {
|
|
687
|
+
$in: entries
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
populate: {
|
|
691
|
+
entry: {
|
|
692
|
+
select: ["id"]
|
|
693
|
+
}
|
|
586
694
|
}
|
|
587
695
|
}
|
|
588
696
|
}
|
|
589
697
|
});
|
|
590
698
|
return releases.map((release2) => {
|
|
591
699
|
if (release2.actions?.length) {
|
|
592
|
-
const
|
|
700
|
+
const actionsForEntry = release2.actions;
|
|
593
701
|
delete release2.actions;
|
|
594
702
|
return {
|
|
595
703
|
...release2,
|
|
596
|
-
|
|
704
|
+
actions: actionsForEntry
|
|
597
705
|
};
|
|
598
706
|
}
|
|
599
707
|
return release2;
|
|
@@ -667,13 +775,11 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
667
775
|
// @ts-expect-error see above
|
|
668
776
|
data: releaseWithCreatorFields
|
|
669
777
|
});
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
schedulingService.cancel(id);
|
|
676
|
-
}
|
|
778
|
+
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
779
|
+
if (releaseData.scheduledAt) {
|
|
780
|
+
await schedulingService.set(id, releaseData.scheduledAt);
|
|
781
|
+
} else if (release2.scheduledAt) {
|
|
782
|
+
schedulingService.cancel(id);
|
|
677
783
|
}
|
|
678
784
|
this.updateReleaseStatus(id);
|
|
679
785
|
strapi2.telemetry.send("didUpdateContentRelease");
|
|
@@ -839,7 +945,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
839
945
|
});
|
|
840
946
|
await strapi2.entityService.delete(RELEASE_MODEL_UID, releaseId);
|
|
841
947
|
});
|
|
842
|
-
if (
|
|
948
|
+
if (release2.scheduledAt) {
|
|
843
949
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
844
950
|
await schedulingService.cancel(release2.id);
|
|
845
951
|
}
|
|
@@ -847,145 +953,71 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
847
953
|
return release2;
|
|
848
954
|
},
|
|
849
955
|
async publish(releaseId) {
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
actions: {
|
|
857
|
-
populate: {
|
|
858
|
-
entry: {
|
|
859
|
-
fields: ["id"]
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
);
|
|
866
|
-
if (!releaseWithPopulatedActionEntries) {
|
|
956
|
+
const {
|
|
957
|
+
release: release2,
|
|
958
|
+
error
|
|
959
|
+
} = await strapi2.db.transaction(async ({ trx }) => {
|
|
960
|
+
const lockedRelease = await strapi2.db?.queryBuilder(RELEASE_MODEL_UID).where({ id: releaseId }).select(["id", "name", "releasedAt", "status"]).first().transacting(trx).forUpdate().execute();
|
|
961
|
+
if (!lockedRelease) {
|
|
867
962
|
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
868
963
|
}
|
|
869
|
-
if (
|
|
964
|
+
if (lockedRelease.releasedAt) {
|
|
870
965
|
throw new errors.ValidationError("Release already published");
|
|
871
966
|
}
|
|
872
|
-
if (
|
|
873
|
-
throw new errors.ValidationError("
|
|
874
|
-
}
|
|
875
|
-
const collectionTypeActions = {};
|
|
876
|
-
const singleTypeActions = [];
|
|
877
|
-
for (const action of releaseWithPopulatedActionEntries.actions) {
|
|
878
|
-
const contentTypeUid = action.contentType;
|
|
879
|
-
if (strapi2.contentTypes[contentTypeUid].kind === "collectionType") {
|
|
880
|
-
if (!collectionTypeActions[contentTypeUid]) {
|
|
881
|
-
collectionTypeActions[contentTypeUid] = {
|
|
882
|
-
entriestoPublishIds: [],
|
|
883
|
-
entriesToUnpublishIds: []
|
|
884
|
-
};
|
|
885
|
-
}
|
|
886
|
-
if (action.type === "publish") {
|
|
887
|
-
collectionTypeActions[contentTypeUid].entriestoPublishIds.push(action.entry.id);
|
|
888
|
-
} else {
|
|
889
|
-
collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
890
|
-
}
|
|
891
|
-
} else {
|
|
892
|
-
singleTypeActions.push({
|
|
893
|
-
uid: contentTypeUid,
|
|
894
|
-
action: action.type,
|
|
895
|
-
id: action.entry.id
|
|
896
|
-
});
|
|
897
|
-
}
|
|
967
|
+
if (lockedRelease.status === "failed") {
|
|
968
|
+
throw new errors.ValidationError("Release failed to publish");
|
|
898
969
|
}
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
await entityManagerService.publish(entry, uid);
|
|
908
|
-
} else {
|
|
909
|
-
await entityManagerService.unpublish(entry, uid);
|
|
910
|
-
}
|
|
911
|
-
} catch (error) {
|
|
912
|
-
if (error instanceof errors.ApplicationError && (error.message === "already.published" || error.message === "already.draft")) {
|
|
913
|
-
} else {
|
|
914
|
-
throw error;
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
for (const contentTypeUid of Object.keys(collectionTypeActions)) {
|
|
919
|
-
const populate = await populateBuilderService(contentTypeUid).populateDeep(Infinity).build();
|
|
920
|
-
const { entriestoPublishIds, entriesToUnpublishIds } = collectionTypeActions[contentTypeUid];
|
|
921
|
-
const entriesToPublish = await strapi2.entityService.findMany(
|
|
922
|
-
contentTypeUid,
|
|
923
|
-
{
|
|
924
|
-
filters: {
|
|
925
|
-
id: {
|
|
926
|
-
$in: entriestoPublishIds
|
|
927
|
-
}
|
|
928
|
-
},
|
|
929
|
-
populate
|
|
930
|
-
}
|
|
931
|
-
);
|
|
932
|
-
const entriesToUnpublish = await strapi2.entityService.findMany(
|
|
933
|
-
contentTypeUid,
|
|
934
|
-
{
|
|
935
|
-
filters: {
|
|
936
|
-
id: {
|
|
937
|
-
$in: entriesToUnpublishIds
|
|
938
|
-
}
|
|
939
|
-
},
|
|
940
|
-
populate
|
|
941
|
-
}
|
|
942
|
-
);
|
|
943
|
-
if (entriesToPublish.length > 0) {
|
|
944
|
-
await entityManagerService.publishMany(entriesToPublish, contentTypeUid);
|
|
970
|
+
try {
|
|
971
|
+
strapi2.log.info(`[Content Releases] Starting to publish release ${lockedRelease.name}`);
|
|
972
|
+
const { collectionTypeActions, singleTypeActions } = await getFormattedActions(
|
|
973
|
+
releaseId
|
|
974
|
+
);
|
|
975
|
+
await strapi2.db.transaction(async () => {
|
|
976
|
+
for (const { uid, action, id } of singleTypeActions) {
|
|
977
|
+
await publishSingleTypeAction(uid, action, id);
|
|
945
978
|
}
|
|
946
|
-
|
|
947
|
-
|
|
979
|
+
for (const contentTypeUid of Object.keys(collectionTypeActions)) {
|
|
980
|
+
const uid = contentTypeUid;
|
|
981
|
+
await publishCollectionTypeAction(
|
|
982
|
+
uid,
|
|
983
|
+
collectionTypeActions[uid].entriesToPublishIds,
|
|
984
|
+
collectionTypeActions[uid].entriesToUnpublishIds
|
|
985
|
+
);
|
|
948
986
|
}
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
releasedAt: /* @__PURE__ */ new Date()
|
|
958
|
-
},
|
|
959
|
-
populate: {
|
|
960
|
-
actions: {
|
|
961
|
-
// @ts-expect-error is not expecting count but it is working
|
|
962
|
-
count: true
|
|
987
|
+
});
|
|
988
|
+
const release22 = await strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
989
|
+
where: {
|
|
990
|
+
id: releaseId
|
|
991
|
+
},
|
|
992
|
+
data: {
|
|
993
|
+
status: "done",
|
|
994
|
+
releasedAt: /* @__PURE__ */ new Date()
|
|
963
995
|
}
|
|
964
|
-
}
|
|
965
|
-
});
|
|
966
|
-
if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
|
|
996
|
+
});
|
|
967
997
|
dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {
|
|
968
998
|
isPublished: true,
|
|
969
|
-
release:
|
|
999
|
+
release: release22
|
|
970
1000
|
});
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
} catch (error) {
|
|
975
|
-
if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
|
|
1001
|
+
strapi2.telemetry.send("didPublishContentRelease");
|
|
1002
|
+
return { release: release22, error: null };
|
|
1003
|
+
} catch (error2) {
|
|
976
1004
|
dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {
|
|
977
1005
|
isPublished: false,
|
|
978
|
-
error
|
|
1006
|
+
error: error2
|
|
979
1007
|
});
|
|
980
|
-
|
|
981
|
-
strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
982
|
-
where: { id: releaseId },
|
|
983
|
-
data: {
|
|
1008
|
+
await strapi2.db?.queryBuilder(RELEASE_MODEL_UID).where({ id: releaseId }).update({
|
|
984
1009
|
status: "failed"
|
|
985
|
-
}
|
|
986
|
-
|
|
1010
|
+
}).transacting(trx).execute();
|
|
1011
|
+
return {
|
|
1012
|
+
release: null,
|
|
1013
|
+
error: error2
|
|
1014
|
+
};
|
|
1015
|
+
}
|
|
1016
|
+
});
|
|
1017
|
+
if (error) {
|
|
987
1018
|
throw error;
|
|
988
1019
|
}
|
|
1020
|
+
return release2;
|
|
989
1021
|
},
|
|
990
1022
|
async updateAction(actionId, releaseId, update) {
|
|
991
1023
|
const updatedAction = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
@@ -1072,6 +1104,12 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
1072
1104
|
}
|
|
1073
1105
|
};
|
|
1074
1106
|
};
|
|
1107
|
+
class AlreadyOnReleaseError extends errors.ApplicationError {
|
|
1108
|
+
constructor(message) {
|
|
1109
|
+
super(message);
|
|
1110
|
+
this.name = "AlreadyOnReleaseError";
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1075
1113
|
const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
1076
1114
|
async validateUniqueEntry(releaseId, releaseActionArgs) {
|
|
1077
1115
|
const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
|
|
@@ -1084,7 +1122,7 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1084
1122
|
(action) => Number(action.entry.id) === Number(releaseActionArgs.entry.id) && action.contentType === releaseActionArgs.entry.contentType
|
|
1085
1123
|
);
|
|
1086
1124
|
if (isEntryInRelease) {
|
|
1087
|
-
throw new
|
|
1125
|
+
throw new AlreadyOnReleaseError(
|
|
1088
1126
|
`Entry with id ${releaseActionArgs.entry.id} and contentType ${releaseActionArgs.entry.contentType} already exists in release with id ${releaseId}`
|
|
1089
1127
|
);
|
|
1090
1128
|
}
|
|
@@ -1192,7 +1230,7 @@ const createSchedulingService = ({ strapi: strapi2 }) => {
|
|
|
1192
1230
|
const services = {
|
|
1193
1231
|
release: createReleaseService,
|
|
1194
1232
|
"release-validation": createReleaseValidationService,
|
|
1195
|
-
|
|
1233
|
+
scheduling: createSchedulingService
|
|
1196
1234
|
};
|
|
1197
1235
|
const RELEASE_SCHEMA = yup.object().shape({
|
|
1198
1236
|
name: yup.string().trim().required(),
|
|
@@ -1279,6 +1317,33 @@ const releaseController = {
|
|
|
1279
1317
|
};
|
|
1280
1318
|
ctx.body = { data };
|
|
1281
1319
|
},
|
|
1320
|
+
async mapEntriesToReleases(ctx) {
|
|
1321
|
+
const { contentTypeUid, entriesIds } = ctx.query;
|
|
1322
|
+
if (!contentTypeUid || !entriesIds) {
|
|
1323
|
+
throw new errors.ValidationError("Missing required query parameters");
|
|
1324
|
+
}
|
|
1325
|
+
const releaseService = getService("release", { strapi });
|
|
1326
|
+
const releasesWithActions = await releaseService.findManyWithContentTypeEntryAttached(
|
|
1327
|
+
contentTypeUid,
|
|
1328
|
+
entriesIds
|
|
1329
|
+
);
|
|
1330
|
+
const mappedEntriesInReleases = releasesWithActions.reduce(
|
|
1331
|
+
(acc, release2) => {
|
|
1332
|
+
release2.actions.forEach((action) => {
|
|
1333
|
+
if (!acc[action.entry.id]) {
|
|
1334
|
+
acc[action.entry.id] = [{ id: release2.id, name: release2.name }];
|
|
1335
|
+
} else {
|
|
1336
|
+
acc[action.entry.id].push({ id: release2.id, name: release2.name });
|
|
1337
|
+
}
|
|
1338
|
+
});
|
|
1339
|
+
return acc;
|
|
1340
|
+
},
|
|
1341
|
+
{}
|
|
1342
|
+
);
|
|
1343
|
+
ctx.body = {
|
|
1344
|
+
data: mappedEntriesInReleases
|
|
1345
|
+
};
|
|
1346
|
+
},
|
|
1282
1347
|
async create(ctx) {
|
|
1283
1348
|
const user = ctx.state.user;
|
|
1284
1349
|
const releaseArgs = ctx.request.body;
|
|
@@ -1368,6 +1433,38 @@ const releaseActionController = {
|
|
|
1368
1433
|
data: releaseAction2
|
|
1369
1434
|
};
|
|
1370
1435
|
},
|
|
1436
|
+
async createMany(ctx) {
|
|
1437
|
+
const releaseId = ctx.params.releaseId;
|
|
1438
|
+
const releaseActionsArgs = ctx.request.body;
|
|
1439
|
+
await Promise.all(
|
|
1440
|
+
releaseActionsArgs.map((releaseActionArgs) => validateReleaseAction(releaseActionArgs))
|
|
1441
|
+
);
|
|
1442
|
+
const releaseService = getService("release", { strapi });
|
|
1443
|
+
const releaseActions = await strapi.db.transaction(async () => {
|
|
1444
|
+
const releaseActions2 = await Promise.all(
|
|
1445
|
+
releaseActionsArgs.map(async (releaseActionArgs) => {
|
|
1446
|
+
try {
|
|
1447
|
+
const action = await releaseService.createAction(releaseId, releaseActionArgs);
|
|
1448
|
+
return action;
|
|
1449
|
+
} catch (error) {
|
|
1450
|
+
if (error instanceof AlreadyOnReleaseError) {
|
|
1451
|
+
return null;
|
|
1452
|
+
}
|
|
1453
|
+
throw error;
|
|
1454
|
+
}
|
|
1455
|
+
})
|
|
1456
|
+
);
|
|
1457
|
+
return releaseActions2;
|
|
1458
|
+
});
|
|
1459
|
+
const newReleaseActions = releaseActions.filter((action) => action !== null);
|
|
1460
|
+
ctx.body = {
|
|
1461
|
+
data: newReleaseActions,
|
|
1462
|
+
meta: {
|
|
1463
|
+
entriesAlreadyInRelease: releaseActions.length - newReleaseActions.length,
|
|
1464
|
+
totalEntries: releaseActions.length
|
|
1465
|
+
}
|
|
1466
|
+
};
|
|
1467
|
+
},
|
|
1371
1468
|
async findMany(ctx) {
|
|
1372
1469
|
const releaseId = ctx.params.releaseId;
|
|
1373
1470
|
const permissionsManager = strapi.admin.services.permission.createPermissionsManager({
|
|
@@ -1436,6 +1533,22 @@ const controllers = { release: releaseController, "release-action": releaseActio
|
|
|
1436
1533
|
const release = {
|
|
1437
1534
|
type: "admin",
|
|
1438
1535
|
routes: [
|
|
1536
|
+
{
|
|
1537
|
+
method: "GET",
|
|
1538
|
+
path: "/mapEntriesToReleases",
|
|
1539
|
+
handler: "release.mapEntriesToReleases",
|
|
1540
|
+
config: {
|
|
1541
|
+
policies: [
|
|
1542
|
+
"admin::isAuthenticatedAdmin",
|
|
1543
|
+
{
|
|
1544
|
+
name: "admin::hasPermissions",
|
|
1545
|
+
config: {
|
|
1546
|
+
actions: ["plugin::content-releases.read"]
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
]
|
|
1550
|
+
}
|
|
1551
|
+
},
|
|
1439
1552
|
{
|
|
1440
1553
|
method: "POST",
|
|
1441
1554
|
path: "/",
|
|
@@ -1553,6 +1666,22 @@ const releaseAction = {
|
|
|
1553
1666
|
]
|
|
1554
1667
|
}
|
|
1555
1668
|
},
|
|
1669
|
+
{
|
|
1670
|
+
method: "POST",
|
|
1671
|
+
path: "/:releaseId/actions/bulk",
|
|
1672
|
+
handler: "release-action.createMany",
|
|
1673
|
+
config: {
|
|
1674
|
+
policies: [
|
|
1675
|
+
"admin::isAuthenticatedAdmin",
|
|
1676
|
+
{
|
|
1677
|
+
name: "admin::hasPermissions",
|
|
1678
|
+
config: {
|
|
1679
|
+
actions: ["plugin::content-releases.create-action"]
|
|
1680
|
+
}
|
|
1681
|
+
}
|
|
1682
|
+
]
|
|
1683
|
+
}
|
|
1684
|
+
},
|
|
1556
1685
|
{
|
|
1557
1686
|
method: "GET",
|
|
1558
1687
|
path: "/:releaseId/actions",
|
|
@@ -1621,6 +1750,9 @@ const getPlugin = () => {
|
|
|
1621
1750
|
};
|
|
1622
1751
|
}
|
|
1623
1752
|
return {
|
|
1753
|
+
// Always return register, it handles its own feature check
|
|
1754
|
+
register,
|
|
1755
|
+
// Always return contentTypes to avoid losing data when the feature is disabled
|
|
1624
1756
|
contentTypes
|
|
1625
1757
|
};
|
|
1626
1758
|
};
|