mirror of
https://github.com/strapi/strapi.git
synced 2025-11-03 03:17:11 +00:00
chore: create updateEntry
This commit is contained in:
parent
5e5bcf8c8f
commit
2b548ef558
@ -137,11 +137,9 @@ describe('history-version service', () => {
|
||||
contentType: {
|
||||
uid: 'api::article.article',
|
||||
},
|
||||
args: [
|
||||
{
|
||||
locale: 'fr',
|
||||
},
|
||||
],
|
||||
params: {
|
||||
locale: 'fr',
|
||||
},
|
||||
};
|
||||
|
||||
const next = jest.fn((context) => ({ ...context, documentId: 'document-id' }));
|
||||
@ -154,7 +152,8 @@ describe('history-version service', () => {
|
||||
expect(next).toHaveBeenCalled();
|
||||
|
||||
// Ensure we're only storing the data we need in the database
|
||||
expect(mockFindOne).toHaveBeenLastCalledWith('document-id', {
|
||||
expect(mockFindOne).toHaveBeenLastCalledWith({
|
||||
documentId: 'document-id',
|
||||
locale: 'fr',
|
||||
populate: {
|
||||
component: {
|
||||
|
||||
@ -308,7 +308,7 @@ const createHistoryService = ({ strapi }: { strapi: Core.Strapi }) => {
|
||||
if ('documentId' in entry) {
|
||||
relatedEntry = await strapi
|
||||
.documents(attributeSchema.target)
|
||||
.findOne(entry.documentId, { locale: entry.locale || undefined });
|
||||
.findOne({ documentId: entry.documentId, locale: entry.locale || undefined });
|
||||
}
|
||||
// For media assets, only the id is available, double check that we have it
|
||||
} else if ('id' in entry) {
|
||||
|
||||
@ -105,7 +105,8 @@ describe('Default Service', () => {
|
||||
|
||||
expect(dbInstance.findOne).toHaveBeenCalledWith();
|
||||
|
||||
expect(documentService.update).toHaveBeenCalledWith(1, {
|
||||
expect(documentService.update).toHaveBeenCalledWith({
|
||||
documentId: 1,
|
||||
data: input,
|
||||
status: 'published',
|
||||
});
|
||||
@ -137,7 +138,7 @@ describe('Default Service', () => {
|
||||
|
||||
expect(dbInstance.findOne).toHaveBeenCalledWith();
|
||||
|
||||
expect(documentService.delete).toHaveBeenCalledWith(1, { status: 'published' });
|
||||
expect(documentService.delete).toHaveBeenCalledWith({ documentId: 1, status: 'published' });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -19,8 +19,6 @@ type ComponentBody = {
|
||||
[key: string]: ComponentValue | DynamicZoneValue;
|
||||
};
|
||||
|
||||
const isDialectMySQL = () => strapi.db?.dialect.client === 'mysql';
|
||||
|
||||
function omitComponentData(
|
||||
contentType: Struct.ContentTypeSchema,
|
||||
data: Modules.EntityService.Params.Data.Input<Struct.ContentTypeSchema['uid']>
|
||||
@ -83,11 +81,9 @@ const createComponents = async <
|
||||
}
|
||||
|
||||
// MySQL/MariaDB can cause deadlocks here if concurrency higher than 1
|
||||
const components = (await async.map(
|
||||
componentValue,
|
||||
(value: any) => createComponent(componentUID, value),
|
||||
{ concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }
|
||||
)) as RepeatableComponentValue;
|
||||
const components: RepeatableComponentValue = await async.map(componentValue, (value: any) =>
|
||||
createComponent(componentUID, value)
|
||||
);
|
||||
|
||||
componentBody[attributeName] = components.map(({ id }) => {
|
||||
return {
|
||||
@ -103,6 +99,7 @@ const createComponents = async <
|
||||
componentUID,
|
||||
componentValue as Modules.EntityService.Params.Data.Input<UID.Component>
|
||||
);
|
||||
|
||||
componentBody[attributeName] = {
|
||||
id: component.id,
|
||||
__pivot: {
|
||||
@ -140,8 +137,7 @@ const createComponents = async <
|
||||
// MySQL/MariaDB can cause deadlocks here if concurrency higher than 1
|
||||
componentBody[attributeName] = await async.map(
|
||||
dynamiczoneValues,
|
||||
createDynamicZoneComponents,
|
||||
{ concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }
|
||||
createDynamicZoneComponents
|
||||
);
|
||||
|
||||
continue;
|
||||
@ -200,11 +196,9 @@ const updateComponents = async <
|
||||
}
|
||||
|
||||
// MySQL/MariaDB can cause deadlocks here if concurrency higher than 1
|
||||
const components = (await async.map(
|
||||
componentValue,
|
||||
(value: any) => updateOrCreateComponent(componentUID, value),
|
||||
{ concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }
|
||||
)) as RepeatableComponentValue;
|
||||
const components: RepeatableComponentValue = await async.map(componentValue, (value: any) =>
|
||||
updateOrCreateComponent(componentUID, value)
|
||||
);
|
||||
|
||||
componentBody[attributeName] = components.filter(_.negate(_.isNil)).map(({ id }) => {
|
||||
return {
|
||||
@ -235,21 +229,17 @@ const updateComponents = async <
|
||||
}
|
||||
|
||||
// MySQL/MariaDB can cause deadlocks here if concurrency higher than 1
|
||||
componentBody[attributeName] = await async.map(
|
||||
dynamiczoneValues,
|
||||
async (value: any) => {
|
||||
const { id } = await updateOrCreateComponent(value.__component, value);
|
||||
componentBody[attributeName] = await async.map(dynamiczoneValues, async (value: any) => {
|
||||
const { id } = await updateOrCreateComponent(value.__component, value);
|
||||
|
||||
return {
|
||||
id,
|
||||
__component: value.__component,
|
||||
__pivot: {
|
||||
field: attributeName,
|
||||
},
|
||||
};
|
||||
},
|
||||
{ concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }
|
||||
);
|
||||
return {
|
||||
id,
|
||||
__component: value.__component,
|
||||
__pivot: {
|
||||
field: attributeName,
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -379,20 +369,14 @@ const deleteComponents = async <TUID extends UID.Schema, TEntity extends Data.En
|
||||
if (attribute.type === 'component') {
|
||||
const { component: componentUID } = attribute;
|
||||
// MySQL/MariaDB can cause deadlocks here if concurrency higher than 1
|
||||
await async.map(
|
||||
_.castArray(value),
|
||||
(subValue: any) => deleteComponent(componentUID, subValue),
|
||||
{
|
||||
concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity,
|
||||
}
|
||||
await async.map(_.castArray(value), (subValue: any) =>
|
||||
deleteComponent(componentUID, subValue)
|
||||
);
|
||||
} else {
|
||||
// delete dynamic zone components
|
||||
// MySQL/MariaDB can cause deadlocks here if concurrency higher than 1
|
||||
await async.map(
|
||||
_.castArray(value),
|
||||
(subValue: any) => deleteComponent(subValue.__component, subValue),
|
||||
{ concurrency: isDialectMySQL() && !strapi.db?.inTransaction() ? 1 : Infinity }
|
||||
await async.map(_.castArray(value), (subValue: any) =>
|
||||
deleteComponent(subValue.__component, subValue)
|
||||
);
|
||||
}
|
||||
|
||||
@ -469,8 +453,21 @@ const deleteComponent = async <TUID extends UID.Component>(
|
||||
await strapi.db.query(uid).delete({ where: { id: componentToDelete.id } });
|
||||
};
|
||||
|
||||
const assignComponentData = <TUID extends UID.ContentType>(
|
||||
data: Modules.EntityService.Params.Data.Input<TUID>,
|
||||
componentData: ComponentBody,
|
||||
{
|
||||
contentType,
|
||||
}: {
|
||||
contentType: Schema.ContentType<TUID>;
|
||||
}
|
||||
) => {
|
||||
return Object.assign(omitComponentData(contentType, data), componentData);
|
||||
};
|
||||
|
||||
export {
|
||||
omitComponentData,
|
||||
assignComponentData,
|
||||
getComponents,
|
||||
createComponents,
|
||||
updateComponents,
|
||||
|
||||
@ -29,11 +29,10 @@ const createEntriesService = (uid: UID.ContentType) => {
|
||||
|
||||
// Component handling
|
||||
const componentData = await components.createComponents(uid, validData);
|
||||
const contentTypeWithoutComponentData = components.omitComponentData(contentType, validData);
|
||||
const entryData = applyTransforms(
|
||||
Object.assign(contentTypeWithoutComponentData, componentData) as any,
|
||||
{ contentType }
|
||||
);
|
||||
const dataWithComponents = components.assignComponentData(validData, componentData, {
|
||||
contentType,
|
||||
});
|
||||
const entryData = applyTransforms(dataWithComponents, { contentType });
|
||||
|
||||
const doc = await strapi.db.query(uid).create({ ...query, data: entryData });
|
||||
|
||||
@ -48,9 +47,35 @@ const createEntriesService = (uid: UID.ContentType) => {
|
||||
await components.deleteComponents(uid, componentsToDelete as any, { loadComponents: false });
|
||||
}
|
||||
|
||||
async function updateEntry(entryToUpdate: any, params = {} as any) {
|
||||
const { data, ...restParams } = await transformParamsDocumentId(uid, params);
|
||||
const query = transformParamsToQuery(uid, pickSelectionParams(restParams) as any); // select / populate
|
||||
|
||||
const validData = await entityValidator.validateEntityUpdate(
|
||||
contentType,
|
||||
data,
|
||||
{
|
||||
isDraft: !params?.data?.publishedAt, // Always update the draft version
|
||||
locale: params?.locale,
|
||||
},
|
||||
entryToUpdate
|
||||
);
|
||||
// Component handling
|
||||
const componentData = await components.updateComponents(uid, entryToUpdate, validData as any);
|
||||
const dataWithComponents = components.assignComponentData(validData, componentData, {
|
||||
contentType,
|
||||
});
|
||||
const entryData = applyTransforms(dataWithComponents, { contentType });
|
||||
|
||||
return strapi.db
|
||||
.query(uid)
|
||||
.update({ ...query, where: { id: entryToUpdate.id }, data: entryData });
|
||||
}
|
||||
|
||||
return {
|
||||
create: createEntry,
|
||||
delete: deleteEntry,
|
||||
update: updateEntry,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -5,18 +5,15 @@ import { async, contentTypes as contentTypesUtils } from '@strapi/utils';
|
||||
import { wrapInTransaction, type RepositoryFactoryMethod } from './common';
|
||||
import * as DP from './draft-and-publish';
|
||||
import * as i18n from './internationalization';
|
||||
import { transformParamsDocumentId } from './transform/id-transform';
|
||||
|
||||
import * as components from './components';
|
||||
import { createEntriesService } from './entries';
|
||||
|
||||
import { createEntriesService } from './entries';
|
||||
import { pickSelectionParams } from './params';
|
||||
import { applyTransforms } from './attributes';
|
||||
import entityValidator from '../entity-validator';
|
||||
import { createDocumentId } from '../../utils/transform-content-types-to-models';
|
||||
import { getDeepPopulate } from './utils/populate';
|
||||
import { transformData } from './transform/data';
|
||||
import { transformParamsToQuery } from './transform/query';
|
||||
import { transformParamsDocumentId } from './transform/id-transform';
|
||||
|
||||
export const createContentTypeRepository: RepositoryFactoryMethod = (uid) => {
|
||||
const contentType = strapi.contentType(uid);
|
||||
@ -167,7 +164,6 @@ export const createContentTypeRepository: RepositoryFactoryMethod = (uid) => {
|
||||
const query = transformParamsToQuery(uid, pickSelectionParams(restParams || {}) as any);
|
||||
|
||||
// Validation
|
||||
const model = strapi.contentType(uid);
|
||||
// Find if document exists
|
||||
const entryToUpdate = await strapi.db
|
||||
.query(uid)
|
||||
@ -175,27 +171,7 @@ export const createContentTypeRepository: RepositoryFactoryMethod = (uid) => {
|
||||
|
||||
let updatedDraft = null;
|
||||
if (entryToUpdate) {
|
||||
const validData = await entityValidator.validateEntityUpdate(
|
||||
model,
|
||||
// @ts-expect-error we need type guard to assert that data has the valid type
|
||||
data,
|
||||
{
|
||||
isDraft: !queryParams?.data?.publishedAt, // Always update the draft version
|
||||
locale: queryParams?.locale,
|
||||
},
|
||||
entryToUpdate
|
||||
);
|
||||
|
||||
// Component handling
|
||||
const componentData = await updateComponents(entryToUpdate, validData as any);
|
||||
const entryData = applyTransforms(
|
||||
Object.assign(omitComponentData(validData), componentData as any),
|
||||
{ contentType: model }
|
||||
);
|
||||
|
||||
updatedDraft = await strapi.db
|
||||
.query(uid)
|
||||
.update({ ...query, where: { id: entryToUpdate.id }, data: entryData });
|
||||
updatedDraft = await entries.update(entryToUpdate, queryParams);
|
||||
}
|
||||
|
||||
if (!updatedDraft) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user