@strapi/content-releases 4.20.4 → 4.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/{App-6ugQxqYE.mjs → App-HVXzE3i3.mjs} +105 -113
- package/dist/_chunks/App-HVXzE3i3.mjs.map +1 -0
- package/dist/_chunks/{App-P1kyM3gT.js → App-l62gIUTX.js} +104 -112
- package/dist/_chunks/App-l62gIUTX.js.map +1 -0
- package/dist/_chunks/{en-WuuhP6Bn.mjs → en-RdapH-9X.mjs} +1 -2
- package/dist/_chunks/en-RdapH-9X.mjs.map +1 -0
- package/dist/_chunks/{en-gcJJ5htG.js → en-faJDuv3q.js} +1 -2
- package/dist/_chunks/en-faJDuv3q.js.map +1 -0
- package/dist/_chunks/{index-2xzbhaQP.js → index-ML_b3php.js} +9 -9
- package/dist/_chunks/index-ML_b3php.js.map +1 -0
- package/dist/_chunks/{index-_eBuegHN.mjs → index-Ys87ROOe.mjs} +9 -9
- package/dist/_chunks/index-Ys87ROOe.mjs.map +1 -0
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/server/index.js +264 -154
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +264 -154
- package/dist/server/index.mjs.map +1 -1
- package/package.json +11 -11
- package/dist/_chunks/App-6ugQxqYE.mjs.map +0 -1
- package/dist/_chunks/App-P1kyM3gT.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-2xzbhaQP.js.map +0 -1
- package/dist/_chunks/index-_eBuegHN.mjs.map +0 -1
package/dist/server/index.mjs
CHANGED
|
@@ -179,7 +179,7 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
179
179
|
}
|
|
180
180
|
});
|
|
181
181
|
await mapAsync(actions, async (action) => {
|
|
182
|
-
if (action.entry) {
|
|
182
|
+
if (action.entry && action.release) {
|
|
183
183
|
const populatedEntry = await getPopulatedEntry(contentTypeUID, action.entry.id, {
|
|
184
184
|
strapi
|
|
185
185
|
});
|
|
@@ -207,12 +207,57 @@ async function revalidateChangedContentTypes({ oldContentTypes, contentTypes: co
|
|
|
207
207
|
});
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
|
+
async function disableContentTypeLocalized({ oldContentTypes, contentTypes: contentTypes2 }) {
|
|
211
|
+
if (!oldContentTypes) {
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
for (const uid in contentTypes2) {
|
|
215
|
+
if (!oldContentTypes[uid]) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const oldContentType = oldContentTypes[uid];
|
|
219
|
+
const contentType = contentTypes2[uid];
|
|
220
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
221
|
+
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
222
|
+
if (isLocalizedContentType(oldContentType) && !isLocalizedContentType(contentType)) {
|
|
223
|
+
await strapi.db.queryBuilder(RELEASE_ACTION_MODEL_UID).update({
|
|
224
|
+
locale: null
|
|
225
|
+
}).where({ contentType: uid }).execute();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
async function enableContentTypeLocalized({ oldContentTypes, contentTypes: contentTypes2 }) {
|
|
230
|
+
if (!oldContentTypes) {
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
for (const uid in contentTypes2) {
|
|
234
|
+
if (!oldContentTypes[uid]) {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
const oldContentType = oldContentTypes[uid];
|
|
238
|
+
const contentType = contentTypes2[uid];
|
|
239
|
+
const i18nPlugin = strapi.plugin("i18n");
|
|
240
|
+
const { isLocalizedContentType } = i18nPlugin.service("content-types");
|
|
241
|
+
const { getDefaultLocale } = i18nPlugin.service("locales");
|
|
242
|
+
if (!isLocalizedContentType(oldContentType) && isLocalizedContentType(contentType)) {
|
|
243
|
+
const defaultLocale = await getDefaultLocale();
|
|
244
|
+
await strapi.db.queryBuilder(RELEASE_ACTION_MODEL_UID).update({
|
|
245
|
+
locale: defaultLocale
|
|
246
|
+
}).where({ contentType: uid }).execute();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
210
250
|
const { features: features$2 } = require("@strapi/strapi/dist/utils/ee");
|
|
211
251
|
const register = async ({ strapi: strapi2 }) => {
|
|
212
252
|
if (features$2.isEnabled("cms-content-releases")) {
|
|
213
253
|
await strapi2.admin.services.permission.actionProvider.registerMany(ACTIONS);
|
|
214
|
-
strapi2.hook("strapi::content-types.beforeSync").register(deleteActionsOnDisableDraftAndPublish);
|
|
215
|
-
strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType).register(revalidateChangedContentTypes).register(migrateIsValidAndStatusReleases);
|
|
254
|
+
strapi2.hook("strapi::content-types.beforeSync").register(deleteActionsOnDisableDraftAndPublish).register(disableContentTypeLocalized);
|
|
255
|
+
strapi2.hook("strapi::content-types.afterSync").register(deleteActionsOnDeleteContentType).register(enableContentTypeLocalized).register(revalidateChangedContentTypes).register(migrateIsValidAndStatusReleases);
|
|
256
|
+
}
|
|
257
|
+
if (strapi2.plugin("graphql")) {
|
|
258
|
+
const graphqlExtensionService = strapi2.plugin("graphql").service("extension");
|
|
259
|
+
graphqlExtensionService.shadowCRUD(RELEASE_MODEL_UID).disable();
|
|
260
|
+
graphqlExtensionService.shadowCRUD(RELEASE_ACTION_MODEL_UID).disable();
|
|
216
261
|
}
|
|
217
262
|
};
|
|
218
263
|
const { features: features$1 } = require("@strapi/strapi/dist/utils/ee");
|
|
@@ -338,27 +383,23 @@ const bootstrap = async ({ strapi: strapi2 }) => {
|
|
|
338
383
|
}
|
|
339
384
|
}
|
|
340
385
|
});
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
});
|
|
351
|
-
}
|
|
386
|
+
getService("scheduling", { strapi: strapi2 }).syncFromDatabase().catch((err) => {
|
|
387
|
+
strapi2.log.error(
|
|
388
|
+
"Error while syncing scheduled jobs from the database in the content-releases plugin. This could lead to errors in the releases scheduling."
|
|
389
|
+
);
|
|
390
|
+
throw err;
|
|
391
|
+
});
|
|
392
|
+
Object.entries(ALLOWED_WEBHOOK_EVENTS).forEach(([key, value]) => {
|
|
393
|
+
strapi2.webhookStore.addAllowedEvent(key, value);
|
|
394
|
+
});
|
|
352
395
|
}
|
|
353
396
|
};
|
|
354
397
|
const destroy = async ({ strapi: strapi2 }) => {
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
job.cancel();
|
|
361
|
-
}
|
|
398
|
+
const scheduledJobs = getService("scheduling", {
|
|
399
|
+
strapi: strapi2
|
|
400
|
+
}).getAll();
|
|
401
|
+
for (const [, job] of scheduledJobs) {
|
|
402
|
+
job.cancel();
|
|
362
403
|
}
|
|
363
404
|
};
|
|
364
405
|
const schema$1 = {
|
|
@@ -483,6 +524,94 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
483
524
|
release: release2
|
|
484
525
|
});
|
|
485
526
|
};
|
|
527
|
+
const publishSingleTypeAction = async (uid, actionType, entryId) => {
|
|
528
|
+
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
529
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
530
|
+
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
531
|
+
const entry = await strapi2.entityService.findOne(uid, entryId, { populate });
|
|
532
|
+
try {
|
|
533
|
+
if (actionType === "publish") {
|
|
534
|
+
await entityManagerService.publish(entry, uid);
|
|
535
|
+
} else {
|
|
536
|
+
await entityManagerService.unpublish(entry, uid);
|
|
537
|
+
}
|
|
538
|
+
} catch (error) {
|
|
539
|
+
if (error instanceof errors.ApplicationError && (error.message === "already.published" || error.message === "already.draft"))
|
|
540
|
+
;
|
|
541
|
+
else {
|
|
542
|
+
throw error;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
const publishCollectionTypeAction = async (uid, entriesToPublishIds, entriestoUnpublishIds) => {
|
|
547
|
+
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
548
|
+
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
549
|
+
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
550
|
+
const entriesToPublish = await strapi2.entityService.findMany(uid, {
|
|
551
|
+
filters: {
|
|
552
|
+
id: {
|
|
553
|
+
$in: entriesToPublishIds
|
|
554
|
+
}
|
|
555
|
+
},
|
|
556
|
+
populate
|
|
557
|
+
});
|
|
558
|
+
const entriesToUnpublish = await strapi2.entityService.findMany(uid, {
|
|
559
|
+
filters: {
|
|
560
|
+
id: {
|
|
561
|
+
$in: entriestoUnpublishIds
|
|
562
|
+
}
|
|
563
|
+
},
|
|
564
|
+
populate
|
|
565
|
+
});
|
|
566
|
+
if (entriesToPublish.length > 0) {
|
|
567
|
+
await entityManagerService.publishMany(entriesToPublish, uid);
|
|
568
|
+
}
|
|
569
|
+
if (entriesToUnpublish.length > 0) {
|
|
570
|
+
await entityManagerService.unpublishMany(entriesToUnpublish, uid);
|
|
571
|
+
}
|
|
572
|
+
};
|
|
573
|
+
const getFormattedActions = async (releaseId) => {
|
|
574
|
+
const actions = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).findMany({
|
|
575
|
+
where: {
|
|
576
|
+
release: {
|
|
577
|
+
id: releaseId
|
|
578
|
+
}
|
|
579
|
+
},
|
|
580
|
+
populate: {
|
|
581
|
+
entry: {
|
|
582
|
+
fields: ["id"]
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
if (actions.length === 0) {
|
|
587
|
+
throw new errors.ValidationError("No entries to publish");
|
|
588
|
+
}
|
|
589
|
+
const collectionTypeActions = {};
|
|
590
|
+
const singleTypeActions = [];
|
|
591
|
+
for (const action of actions) {
|
|
592
|
+
const contentTypeUid = action.contentType;
|
|
593
|
+
if (strapi2.contentTypes[contentTypeUid].kind === "collectionType") {
|
|
594
|
+
if (!collectionTypeActions[contentTypeUid]) {
|
|
595
|
+
collectionTypeActions[contentTypeUid] = {
|
|
596
|
+
entriesToPublishIds: [],
|
|
597
|
+
entriesToUnpublishIds: []
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
if (action.type === "publish") {
|
|
601
|
+
collectionTypeActions[contentTypeUid].entriesToPublishIds.push(action.entry.id);
|
|
602
|
+
} else {
|
|
603
|
+
collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
604
|
+
}
|
|
605
|
+
} else {
|
|
606
|
+
singleTypeActions.push({
|
|
607
|
+
uid: contentTypeUid,
|
|
608
|
+
action: action.type,
|
|
609
|
+
id: action.entry.id
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
return { collectionTypeActions, singleTypeActions };
|
|
614
|
+
};
|
|
486
615
|
return {
|
|
487
616
|
async create(releaseData, { user }) {
|
|
488
617
|
const releaseWithCreatorFields = await setCreatorFields({ user })(releaseData);
|
|
@@ -502,7 +631,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
502
631
|
status: "empty"
|
|
503
632
|
}
|
|
504
633
|
});
|
|
505
|
-
if (
|
|
634
|
+
if (releaseWithCreatorFields.scheduledAt) {
|
|
506
635
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
507
636
|
await schedulingService.set(release2.id, release2.scheduledAt);
|
|
508
637
|
}
|
|
@@ -627,13 +756,11 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
627
756
|
// @ts-expect-error see above
|
|
628
757
|
data: releaseWithCreatorFields
|
|
629
758
|
});
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
schedulingService.cancel(id);
|
|
636
|
-
}
|
|
759
|
+
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
760
|
+
if (releaseData.scheduledAt) {
|
|
761
|
+
await schedulingService.set(id, releaseData.scheduledAt);
|
|
762
|
+
} else if (release2.scheduledAt) {
|
|
763
|
+
schedulingService.cancel(id);
|
|
637
764
|
}
|
|
638
765
|
this.updateReleaseStatus(id);
|
|
639
766
|
strapi2.telemetry.send("didUpdateContentRelease");
|
|
@@ -799,7 +926,7 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
799
926
|
});
|
|
800
927
|
await strapi2.entityService.delete(RELEASE_MODEL_UID, releaseId);
|
|
801
928
|
});
|
|
802
|
-
if (
|
|
929
|
+
if (release2.scheduledAt) {
|
|
803
930
|
const schedulingService = getService("scheduling", { strapi: strapi2 });
|
|
804
931
|
await schedulingService.cancel(release2.id);
|
|
805
932
|
}
|
|
@@ -807,145 +934,71 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
807
934
|
return release2;
|
|
808
935
|
},
|
|
809
936
|
async publish(releaseId) {
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
actions: {
|
|
817
|
-
populate: {
|
|
818
|
-
entry: {
|
|
819
|
-
fields: ["id"]
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
);
|
|
826
|
-
if (!releaseWithPopulatedActionEntries) {
|
|
937
|
+
const {
|
|
938
|
+
release: release2,
|
|
939
|
+
error
|
|
940
|
+
} = await strapi2.db.transaction(async ({ trx }) => {
|
|
941
|
+
const lockedRelease = await strapi2.db?.queryBuilder(RELEASE_MODEL_UID).where({ id: releaseId }).select(["id", "name", "releasedAt", "status"]).first().transacting(trx).forUpdate().execute();
|
|
942
|
+
if (!lockedRelease) {
|
|
827
943
|
throw new errors.NotFoundError(`No release found for id ${releaseId}`);
|
|
828
944
|
}
|
|
829
|
-
if (
|
|
945
|
+
if (lockedRelease.releasedAt) {
|
|
830
946
|
throw new errors.ValidationError("Release already published");
|
|
831
947
|
}
|
|
832
|
-
if (
|
|
833
|
-
throw new errors.ValidationError("
|
|
948
|
+
if (lockedRelease.status === "failed") {
|
|
949
|
+
throw new errors.ValidationError("Release failed to publish");
|
|
834
950
|
}
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
entriesToUnpublishIds: []
|
|
844
|
-
};
|
|
845
|
-
}
|
|
846
|
-
if (action.type === "publish") {
|
|
847
|
-
collectionTypeActions[contentTypeUid].entriestoPublishIds.push(action.entry.id);
|
|
848
|
-
} else {
|
|
849
|
-
collectionTypeActions[contentTypeUid].entriesToUnpublishIds.push(action.entry.id);
|
|
850
|
-
}
|
|
851
|
-
} else {
|
|
852
|
-
singleTypeActions.push({
|
|
853
|
-
uid: contentTypeUid,
|
|
854
|
-
action: action.type,
|
|
855
|
-
id: action.entry.id
|
|
856
|
-
});
|
|
857
|
-
}
|
|
858
|
-
}
|
|
859
|
-
const entityManagerService = strapi2.plugin("content-manager").service("entity-manager");
|
|
860
|
-
const populateBuilderService = strapi2.plugin("content-manager").service("populate-builder");
|
|
861
|
-
await strapi2.db.transaction(async () => {
|
|
862
|
-
for (const { uid, action, id } of singleTypeActions) {
|
|
863
|
-
const populate = await populateBuilderService(uid).populateDeep(Infinity).build();
|
|
864
|
-
const entry = await strapi2.entityService.findOne(uid, id, { populate });
|
|
865
|
-
try {
|
|
866
|
-
if (action === "publish") {
|
|
867
|
-
await entityManagerService.publish(entry, uid);
|
|
868
|
-
} else {
|
|
869
|
-
await entityManagerService.unpublish(entry, uid);
|
|
870
|
-
}
|
|
871
|
-
} catch (error) {
|
|
872
|
-
if (error instanceof errors.ApplicationError && (error.message === "already.published" || error.message === "already.draft")) {
|
|
873
|
-
} else {
|
|
874
|
-
throw error;
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
for (const contentTypeUid of Object.keys(collectionTypeActions)) {
|
|
879
|
-
const populate = await populateBuilderService(contentTypeUid).populateDeep(Infinity).build();
|
|
880
|
-
const { entriestoPublishIds, entriesToUnpublishIds } = collectionTypeActions[contentTypeUid];
|
|
881
|
-
const entriesToPublish = await strapi2.entityService.findMany(
|
|
882
|
-
contentTypeUid,
|
|
883
|
-
{
|
|
884
|
-
filters: {
|
|
885
|
-
id: {
|
|
886
|
-
$in: entriestoPublishIds
|
|
887
|
-
}
|
|
888
|
-
},
|
|
889
|
-
populate
|
|
890
|
-
}
|
|
891
|
-
);
|
|
892
|
-
const entriesToUnpublish = await strapi2.entityService.findMany(
|
|
893
|
-
contentTypeUid,
|
|
894
|
-
{
|
|
895
|
-
filters: {
|
|
896
|
-
id: {
|
|
897
|
-
$in: entriesToUnpublishIds
|
|
898
|
-
}
|
|
899
|
-
},
|
|
900
|
-
populate
|
|
901
|
-
}
|
|
902
|
-
);
|
|
903
|
-
if (entriesToPublish.length > 0) {
|
|
904
|
-
await entityManagerService.publishMany(entriesToPublish, contentTypeUid);
|
|
951
|
+
try {
|
|
952
|
+
strapi2.log.info(`[Content Releases] Starting to publish release ${lockedRelease.name}`);
|
|
953
|
+
const { collectionTypeActions, singleTypeActions } = await getFormattedActions(
|
|
954
|
+
releaseId
|
|
955
|
+
);
|
|
956
|
+
await strapi2.db.transaction(async () => {
|
|
957
|
+
for (const { uid, action, id } of singleTypeActions) {
|
|
958
|
+
await publishSingleTypeAction(uid, action, id);
|
|
905
959
|
}
|
|
906
|
-
|
|
907
|
-
|
|
960
|
+
for (const contentTypeUid of Object.keys(collectionTypeActions)) {
|
|
961
|
+
const uid = contentTypeUid;
|
|
962
|
+
await publishCollectionTypeAction(
|
|
963
|
+
uid,
|
|
964
|
+
collectionTypeActions[uid].entriesToPublishIds,
|
|
965
|
+
collectionTypeActions[uid].entriesToUnpublishIds
|
|
966
|
+
);
|
|
908
967
|
}
|
|
909
|
-
}
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
releasedAt: /* @__PURE__ */ new Date()
|
|
918
|
-
},
|
|
919
|
-
populate: {
|
|
920
|
-
actions: {
|
|
921
|
-
// @ts-expect-error is not expecting count but it is working
|
|
922
|
-
count: true
|
|
968
|
+
});
|
|
969
|
+
const release22 = await strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
970
|
+
where: {
|
|
971
|
+
id: releaseId
|
|
972
|
+
},
|
|
973
|
+
data: {
|
|
974
|
+
status: "done",
|
|
975
|
+
releasedAt: /* @__PURE__ */ new Date()
|
|
923
976
|
}
|
|
924
|
-
}
|
|
925
|
-
});
|
|
926
|
-
if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
|
|
977
|
+
});
|
|
927
978
|
dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {
|
|
928
979
|
isPublished: true,
|
|
929
|
-
release:
|
|
980
|
+
release: release22
|
|
930
981
|
});
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
} catch (error) {
|
|
935
|
-
if (strapi2.features.future.isEnabled("contentReleasesScheduling")) {
|
|
982
|
+
strapi2.telemetry.send("didPublishContentRelease");
|
|
983
|
+
return { release: release22, error: null };
|
|
984
|
+
} catch (error2) {
|
|
936
985
|
dispatchWebhook(ALLOWED_WEBHOOK_EVENTS.RELEASES_PUBLISH, {
|
|
937
986
|
isPublished: false,
|
|
938
|
-
error
|
|
987
|
+
error: error2
|
|
939
988
|
});
|
|
940
|
-
|
|
941
|
-
strapi2.db.query(RELEASE_MODEL_UID).update({
|
|
942
|
-
where: { id: releaseId },
|
|
943
|
-
data: {
|
|
989
|
+
await strapi2.db?.queryBuilder(RELEASE_MODEL_UID).where({ id: releaseId }).update({
|
|
944
990
|
status: "failed"
|
|
945
|
-
}
|
|
946
|
-
|
|
991
|
+
}).transacting(trx).execute();
|
|
992
|
+
return {
|
|
993
|
+
release: null,
|
|
994
|
+
error: error2
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
});
|
|
998
|
+
if (error) {
|
|
947
999
|
throw error;
|
|
948
1000
|
}
|
|
1001
|
+
return release2;
|
|
949
1002
|
},
|
|
950
1003
|
async updateAction(actionId, releaseId, update) {
|
|
951
1004
|
const updatedAction = await strapi2.db.query(RELEASE_ACTION_MODEL_UID).update({
|
|
@@ -1032,6 +1085,12 @@ const createReleaseService = ({ strapi: strapi2 }) => {
|
|
|
1032
1085
|
}
|
|
1033
1086
|
};
|
|
1034
1087
|
};
|
|
1088
|
+
class AlreadyOnReleaseError extends errors.ApplicationError {
|
|
1089
|
+
constructor(message) {
|
|
1090
|
+
super(message);
|
|
1091
|
+
this.name = "AlreadyOnReleaseError";
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1035
1094
|
const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
1036
1095
|
async validateUniqueEntry(releaseId, releaseActionArgs) {
|
|
1037
1096
|
const release2 = await strapi2.entityService.findOne(RELEASE_MODEL_UID, releaseId, {
|
|
@@ -1044,7 +1103,7 @@ const createReleaseValidationService = ({ strapi: strapi2 }) => ({
|
|
|
1044
1103
|
(action) => Number(action.entry.id) === Number(releaseActionArgs.entry.id) && action.contentType === releaseActionArgs.entry.contentType
|
|
1045
1104
|
);
|
|
1046
1105
|
if (isEntryInRelease) {
|
|
1047
|
-
throw new
|
|
1106
|
+
throw new AlreadyOnReleaseError(
|
|
1048
1107
|
`Entry with id ${releaseActionArgs.entry.id} and contentType ${releaseActionArgs.entry.contentType} already exists in release with id ${releaseId}`
|
|
1049
1108
|
);
|
|
1050
1109
|
}
|
|
@@ -1152,7 +1211,7 @@ const createSchedulingService = ({ strapi: strapi2 }) => {
|
|
|
1152
1211
|
const services = {
|
|
1153
1212
|
release: createReleaseService,
|
|
1154
1213
|
"release-validation": createReleaseValidationService,
|
|
1155
|
-
|
|
1214
|
+
scheduling: createSchedulingService
|
|
1156
1215
|
};
|
|
1157
1216
|
const RELEASE_SCHEMA = yup.object().shape({
|
|
1158
1217
|
name: yup.string().trim().required(),
|
|
@@ -1328,6 +1387,38 @@ const releaseActionController = {
|
|
|
1328
1387
|
data: releaseAction2
|
|
1329
1388
|
};
|
|
1330
1389
|
},
|
|
1390
|
+
async createMany(ctx) {
|
|
1391
|
+
const releaseId = ctx.params.releaseId;
|
|
1392
|
+
const releaseActionsArgs = ctx.request.body;
|
|
1393
|
+
await Promise.all(
|
|
1394
|
+
releaseActionsArgs.map((releaseActionArgs) => validateReleaseAction(releaseActionArgs))
|
|
1395
|
+
);
|
|
1396
|
+
const releaseService = getService("release", { strapi });
|
|
1397
|
+
const releaseActions = await strapi.db.transaction(async () => {
|
|
1398
|
+
const releaseActions2 = await Promise.all(
|
|
1399
|
+
releaseActionsArgs.map(async (releaseActionArgs) => {
|
|
1400
|
+
try {
|
|
1401
|
+
const action = await releaseService.createAction(releaseId, releaseActionArgs);
|
|
1402
|
+
return action;
|
|
1403
|
+
} catch (error) {
|
|
1404
|
+
if (error instanceof AlreadyOnReleaseError) {
|
|
1405
|
+
return null;
|
|
1406
|
+
}
|
|
1407
|
+
throw error;
|
|
1408
|
+
}
|
|
1409
|
+
})
|
|
1410
|
+
);
|
|
1411
|
+
return releaseActions2;
|
|
1412
|
+
});
|
|
1413
|
+
const newReleaseActions = releaseActions.filter((action) => action !== null);
|
|
1414
|
+
ctx.body = {
|
|
1415
|
+
data: newReleaseActions,
|
|
1416
|
+
meta: {
|
|
1417
|
+
entriesAlreadyInRelease: releaseActions.length - newReleaseActions.length,
|
|
1418
|
+
totalEntries: releaseActions.length
|
|
1419
|
+
}
|
|
1420
|
+
};
|
|
1421
|
+
},
|
|
1331
1422
|
async findMany(ctx) {
|
|
1332
1423
|
const releaseId = ctx.params.releaseId;
|
|
1333
1424
|
const permissionsManager = strapi.admin.services.permission.createPermissionsManager({
|
|
@@ -1513,6 +1604,22 @@ const releaseAction = {
|
|
|
1513
1604
|
]
|
|
1514
1605
|
}
|
|
1515
1606
|
},
|
|
1607
|
+
{
|
|
1608
|
+
method: "POST",
|
|
1609
|
+
path: "/:releaseId/actions/bulk",
|
|
1610
|
+
handler: "release-action.createMany",
|
|
1611
|
+
config: {
|
|
1612
|
+
policies: [
|
|
1613
|
+
"admin::isAuthenticatedAdmin",
|
|
1614
|
+
{
|
|
1615
|
+
name: "admin::hasPermissions",
|
|
1616
|
+
config: {
|
|
1617
|
+
actions: ["plugin::content-releases.create-action"]
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
]
|
|
1621
|
+
}
|
|
1622
|
+
},
|
|
1516
1623
|
{
|
|
1517
1624
|
method: "GET",
|
|
1518
1625
|
path: "/:releaseId/actions",
|
|
@@ -1581,6 +1688,9 @@ const getPlugin = () => {
|
|
|
1581
1688
|
};
|
|
1582
1689
|
}
|
|
1583
1690
|
return {
|
|
1691
|
+
// Always return register, it handles its own feature check
|
|
1692
|
+
register,
|
|
1693
|
+
// Always return contentTypes to avoid losing data when the feature is disabled
|
|
1584
1694
|
contentTypes
|
|
1585
1695
|
};
|
|
1586
1696
|
};
|