mirror of
https://github.com/strapi/strapi.git
synced 2025-12-15 17:22:57 +00:00
chore(content-releases): remove future flags (#19245)
This commit is contained in:
parent
0d0b078513
commit
d172fb07e2
File diff suppressed because it is too large
Load Diff
@ -12,10 +12,7 @@ import type { Plugin } from '@strapi/types';
|
|||||||
const admin: Plugin.Config.AdminInput = {
|
const admin: Plugin.Config.AdminInput = {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
register(app: any) {
|
register(app: any) {
|
||||||
if (
|
if (window.strapi.features.isEnabled('cms-content-releases')) {
|
||||||
window.strapi.features.isEnabled('cms-content-releases') &&
|
|
||||||
window.strapi.future.isEnabled('contentReleases')
|
|
||||||
) {
|
|
||||||
app.addMenuLink({
|
app.addMenuLink({
|
||||||
to: `/plugins/${pluginId}`,
|
to: `/plugins/${pluginId}`,
|
||||||
icon: PaperPlane,
|
icon: PaperPlane,
|
||||||
|
|||||||
@ -23,9 +23,9 @@ describe('register', () => {
|
|||||||
addDestroyListenerCallback: jest.fn(),
|
addDestroyListenerCallback: jest.fn(),
|
||||||
})),
|
})),
|
||||||
})),
|
})),
|
||||||
eventHub: {
|
hook: jest.fn(() => ({
|
||||||
on: jest.fn(),
|
register: jest.fn(),
|
||||||
},
|
})),
|
||||||
admin: {
|
admin: {
|
||||||
services: {
|
services: {
|
||||||
permission: {
|
permission: {
|
||||||
|
|||||||
@ -1,23 +1,20 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
import type { LoadedStrapi, Entity as StrapiEntity } from '@strapi/types';
|
import type { LoadedStrapi, Entity as StrapiEntity } from '@strapi/types';
|
||||||
|
|
||||||
import { RELEASE_ACTION_MODEL_UID } from './constants';
|
import { RELEASE_ACTION_MODEL_UID } from './constants';
|
||||||
|
|
||||||
const { features } = require('@strapi/strapi/dist/utils/ee');
|
const { features } = require('@strapi/strapi/dist/utils/ee');
|
||||||
|
|
||||||
export const bootstrap = async ({ strapi }: { strapi: LoadedStrapi }) => {
|
export const bootstrap = async ({ strapi }: { strapi: LoadedStrapi }) => {
|
||||||
if (
|
if (features.isEnabled('cms-content-releases')) {
|
||||||
features.isEnabled('cms-content-releases') &&
|
// Clean up release-actions when an entry is deleted
|
||||||
strapi.features.future.isEnabled('contentReleases')
|
|
||||||
) {
|
|
||||||
strapi.db.lifecycles.subscribe({
|
strapi.db.lifecycles.subscribe({
|
||||||
afterDelete(event) {
|
afterDelete(event) {
|
||||||
// @ts-expect-error TODO: lifecycles types looks like are not 100% finished
|
// @ts-expect-error TODO: lifecycles types looks like are not 100% finished
|
||||||
const { model, result } = event;
|
const { model, result } = event;
|
||||||
|
|
||||||
// @ts-expect-error TODO: lifecycles types looks like are not 100% finished
|
// @ts-expect-error TODO: lifecycles types looks like are not 100% finished
|
||||||
if (model.kind === 'collectionType' && model.options.draftAndPublish) {
|
if (model.kind === 'collectionType' && model.options?.draftAndPublish) {
|
||||||
const { id } = result;
|
const { id } = result;
|
||||||
|
|
||||||
strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
||||||
where: {
|
where: {
|
||||||
target_type: model.uid,
|
target_type: model.uid,
|
||||||
@ -26,26 +23,21 @@ export const bootstrap = async ({ strapi }: { strapi: LoadedStrapi }) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* deleteMany hook doesn't return the deleted entries ids
|
* deleteMany hook doesn't return the deleted entries ids
|
||||||
* so we need to fetch them before deleting the entries to save the ids on our state
|
* so we need to fetch them before deleting the entries to save the ids on our state
|
||||||
*/
|
*/
|
||||||
async beforeDeleteMany(event) {
|
async beforeDeleteMany(event) {
|
||||||
const { model, params } = event;
|
const { model, params } = event;
|
||||||
|
|
||||||
// @ts-expect-error TODO: lifecycles types looks like are not 100% finished
|
// @ts-expect-error TODO: lifecycles types looks like are not 100% finished
|
||||||
if (model.kind === 'collectionType' && model.options.draftAndPublish) {
|
if (model.kind === 'collectionType' && model.options?.draftAndPublish) {
|
||||||
const { where } = params;
|
const { where } = params;
|
||||||
|
|
||||||
const entriesToDelete = await strapi.db
|
const entriesToDelete = await strapi.db
|
||||||
.query(model.uid)
|
.query(model.uid)
|
||||||
.findMany({ select: ['id'], where });
|
.findMany({ select: ['id'], where });
|
||||||
|
|
||||||
event.state.entriesToDelete = entriesToDelete;
|
event.state.entriesToDelete = entriesToDelete;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We delete the release actions related to deleted entries
|
* We delete the release actions related to deleted entries
|
||||||
* We make this only after deleteMany is succesfully executed to avoid errors
|
* We make this only after deleteMany is succesfully executed to avoid errors
|
||||||
@ -53,7 +45,6 @@ export const bootstrap = async ({ strapi }: { strapi: LoadedStrapi }) => {
|
|||||||
async afterDeleteMany(event) {
|
async afterDeleteMany(event) {
|
||||||
const { model, state } = event;
|
const { model, state } = event;
|
||||||
const entriesToDelete = state.entriesToDelete;
|
const entriesToDelete = state.entriesToDelete;
|
||||||
|
|
||||||
if (entriesToDelete) {
|
if (entriesToDelete) {
|
||||||
await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
await strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
||||||
where: {
|
where: {
|
||||||
|
|||||||
@ -5,15 +5,11 @@ import { contentTypes } from './content-types';
|
|||||||
import { services } from './services';
|
import { services } from './services';
|
||||||
import { controllers } from './controllers';
|
import { controllers } from './controllers';
|
||||||
import { routes } from './routes';
|
import { routes } from './routes';
|
||||||
import { getService } from './utils';
|
|
||||||
|
|
||||||
const { features } = require('@strapi/strapi/dist/utils/ee');
|
const { features } = require('@strapi/strapi/dist/utils/ee');
|
||||||
|
|
||||||
const getPlugin = () => {
|
const getPlugin = () => {
|
||||||
if (
|
if (features.isEnabled('cms-content-releases')) {
|
||||||
features.isEnabled('cms-content-releases') &&
|
|
||||||
strapi.features.future.isEnabled('contentReleases')
|
|
||||||
) {
|
|
||||||
return {
|
return {
|
||||||
register,
|
register,
|
||||||
bootstrap,
|
bootstrap,
|
||||||
@ -21,14 +17,6 @@ const getPlugin = () => {
|
|||||||
services,
|
services,
|
||||||
controllers,
|
controllers,
|
||||||
routes,
|
routes,
|
||||||
destroy() {
|
|
||||||
if (
|
|
||||||
features.isEnabled('cms-content-releases') &&
|
|
||||||
strapi.features.future.isEnabled('contentReleases')
|
|
||||||
) {
|
|
||||||
getService('event-manager').destroyAllListeners();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,53 @@
|
|||||||
|
import type { Schema } from '@strapi/types';
|
||||||
|
import { contentTypes as contentTypesUtils, mapAsync } from '@strapi/utils';
|
||||||
|
|
||||||
|
import { difference, keys } from 'lodash';
|
||||||
|
import { RELEASE_ACTION_MODEL_UID } from '../constants';
|
||||||
|
|
||||||
|
interface Input {
|
||||||
|
oldContentTypes: Record<string, Schema.ContentType>;
|
||||||
|
contentTypes: Record<string, Schema.ContentType>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteActionsOnDisableDraftAndPublish({
|
||||||
|
oldContentTypes,
|
||||||
|
contentTypes,
|
||||||
|
}: Input) {
|
||||||
|
if (!oldContentTypes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const uid in contentTypes) {
|
||||||
|
if (!oldContentTypes[uid]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldContentType = oldContentTypes[uid];
|
||||||
|
const contentType = contentTypes[uid];
|
||||||
|
|
||||||
|
if (
|
||||||
|
contentTypesUtils.hasDraftAndPublish(oldContentType) &&
|
||||||
|
!contentTypesUtils.hasDraftAndPublish(contentType)
|
||||||
|
) {
|
||||||
|
await strapi.db
|
||||||
|
?.queryBuilder(RELEASE_ACTION_MODEL_UID)
|
||||||
|
.delete()
|
||||||
|
.where({ contentType: uid })
|
||||||
|
.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function deleteActionsOnDeleteContentType({ oldContentTypes, contentTypes }: Input) {
|
||||||
|
const deletedContentTypes = difference(keys(oldContentTypes), keys(contentTypes)) ?? [];
|
||||||
|
|
||||||
|
if (deletedContentTypes.length) {
|
||||||
|
await mapAsync(deletedContentTypes, async (deletedContentTypeUID: unknown) => {
|
||||||
|
return strapi.db
|
||||||
|
?.queryBuilder(RELEASE_ACTION_MODEL_UID)
|
||||||
|
.delete()
|
||||||
|
.where({ contentType: deletedContentTypeUID })
|
||||||
|
.execute();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,37 +1,16 @@
|
|||||||
/* eslint-disable @typescript-eslint/no-var-requires */
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
||||||
import type { LoadedStrapi } from '@strapi/types';
|
import type { LoadedStrapi } from '@strapi/types';
|
||||||
import { ACTIONS } from './constants';
|
|
||||||
|
|
||||||
import { getService } from './utils';
|
import { ACTIONS } from './constants';
|
||||||
|
import { deleteActionsOnDeleteContentType, deleteActionsOnDisableDraftAndPublish } from './migrations';
|
||||||
|
|
||||||
const { features } = require('@strapi/strapi/dist/utils/ee');
|
const { features } = require('@strapi/strapi/dist/utils/ee');
|
||||||
|
|
||||||
export const register = async ({ strapi }: { strapi: LoadedStrapi }) => {
|
export const register = async ({ strapi }: { strapi: LoadedStrapi }) => {
|
||||||
if (
|
if (features.isEnabled('cms-content-releases')) {
|
||||||
features.isEnabled('cms-content-releases') &&
|
|
||||||
strapi.features.future.isEnabled('contentReleases')
|
|
||||||
) {
|
|
||||||
await strapi.admin.services.permission.actionProvider.registerMany(ACTIONS);
|
await strapi.admin.services.permission.actionProvider.registerMany(ACTIONS);
|
||||||
|
|
||||||
const releaseActionService = getService('release-action', { strapi });
|
strapi.hook('strapi::content-types.beforeSync').register(deleteActionsOnDisableDraftAndPublish);
|
||||||
const eventManager = getService('event-manager', { strapi });
|
strapi.hook('strapi::content-types.afterSync').register(deleteActionsOnDeleteContentType);
|
||||||
// Clean up release-actions when draft and publish is disabled
|
|
||||||
const destroyContentTypeUpdateListener = strapi.eventHub.on(
|
|
||||||
'content-type.update',
|
|
||||||
async ({ contentType }) => {
|
|
||||||
if (contentType.schema.options.draftAndPublish === false) {
|
|
||||||
await releaseActionService.deleteManyForContentType(contentType.uid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
eventManager.addDestroyListenerCallback(destroyContentTypeUpdateListener);
|
|
||||||
// Clean up release-actions when a content-type is deleted
|
|
||||||
const destroyContentTypeDeleteListener = strapi.eventHub.on(
|
|
||||||
'content-type.delete',
|
|
||||||
async ({ contentType }) => {
|
|
||||||
await releaseActionService.deleteManyForContentType(contentType.uid);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
eventManager.addDestroyListenerCallback(destroyContentTypeDeleteListener);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
import createReleaseActionService from '../release-action';
|
|
||||||
|
|
||||||
describe('Release Action service', () => {
|
|
||||||
it('deletes all release actions given a content type uid', async () => {
|
|
||||||
const strapiMock = {
|
|
||||||
db: {
|
|
||||||
query: jest.fn().mockReturnValue({
|
|
||||||
deleteMany: jest.fn(),
|
|
||||||
}),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// @ts-expect-error Ignore missing properties
|
|
||||||
const releaseActionService = createReleaseActionService({ strapi: strapiMock });
|
|
||||||
await releaseActionService.deleteManyForContentType('api::test.test');
|
|
||||||
|
|
||||||
expect(strapiMock.db.query().deleteMany).toHaveBeenCalledWith({
|
|
||||||
where: {
|
|
||||||
target_type: 'api::test.test',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
interface ReleaseEventServiceState {
|
|
||||||
destroyListenerCallbacks: (() => void)[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const createEventManagerService = () => {
|
|
||||||
const state: ReleaseEventServiceState = {
|
|
||||||
destroyListenerCallbacks: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
addDestroyListenerCallback(destroyListenerCallback: () => void) {
|
|
||||||
state.destroyListenerCallbacks.push(destroyListenerCallback);
|
|
||||||
},
|
|
||||||
|
|
||||||
destroyAllListeners() {
|
|
||||||
if (!state.destroyListenerCallbacks.length) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
state.destroyListenerCallbacks.forEach((destroyListenerCallback) => {
|
|
||||||
destroyListenerCallback();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export default createEventManagerService;
|
|
||||||
@ -1,11 +1,7 @@
|
|||||||
import releaseAction from './release-action';
|
|
||||||
import release from './release';
|
import release from './release';
|
||||||
import releaseValidation from './validation';
|
import releaseValidation from './validation';
|
||||||
import eventManager from './event-manager';
|
|
||||||
|
|
||||||
export const services = {
|
export const services = {
|
||||||
release,
|
release,
|
||||||
'release-action': releaseAction,
|
|
||||||
'release-validation': releaseValidation,
|
'release-validation': releaseValidation,
|
||||||
'event-manager': eventManager,
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,15 +0,0 @@
|
|||||||
import type { LoadedStrapi } from '@strapi/types';
|
|
||||||
import { RELEASE_ACTION_MODEL_UID } from '../constants';
|
|
||||||
import type { ReleaseAction } from '../../../shared/contracts/release-actions';
|
|
||||||
|
|
||||||
const createReleaseActionService = ({ strapi }: { strapi: LoadedStrapi }) => ({
|
|
||||||
async deleteManyForContentType(contentTypeUid: ReleaseAction['contentType']) {
|
|
||||||
return strapi.db.query(RELEASE_ACTION_MODEL_UID).deleteMany({
|
|
||||||
where: {
|
|
||||||
target_type: contentTypeUid,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default createReleaseActionService;
|
|
||||||
@ -26,7 +26,7 @@ import type {
|
|||||||
import type { Entity, UserInfo } from '../../../shared/types';
|
import type { Entity, UserInfo } from '../../../shared/types';
|
||||||
import { getService } from '../utils';
|
import { getService } from '../utils';
|
||||||
|
|
||||||
interface Locale extends Entity {
|
export interface Locale extends Entity {
|
||||||
name: string;
|
name: string;
|
||||||
code: string;
|
code: string;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user