@directus/api
Version:
Directus is a real-time API and App dashboard for managing SQL database content
97 lines (96 loc) • 3.83 kB
JavaScript
import { ForbiddenError } from '@directus/errors';
import { transaction } from '../transaction.js';
import { deepMapWithSchema } from './deep-map-with-schema.js';
import { splitRecursive } from './split-recursive.js';
export async function handleVersion(self, key, queryWithKey, opts) {
const { VersionsService } = await import('../../services/versions.js');
const { ItemsService } = await import('../../services/items.js');
if (queryWithKey.versionRaw) {
const originalData = await self.readByQuery(queryWithKey, opts);
if (originalData.length === 0) {
throw new ForbiddenError();
}
const versionsService = new VersionsService({
schema: self.schema,
accountability: self.accountability,
knex: self.knex,
});
const version = await versionsService.getVersionSave(queryWithKey.version, self.collection, key);
return Object.assign(originalData[0], version?.delta);
}
let result;
const versionsService = new VersionsService({
schema: self.schema,
accountability: self.accountability,
knex: self.knex,
});
const createdIDs = {};
const version = await versionsService.getVersionSave(queryWithKey.version, self.collection, key, false);
if (!version) {
throw new ForbiddenError();
}
const { delta } = version;
await transaction(self.knex, async (trx) => {
const itemsServiceAdmin = new ItemsService(self.collection, {
schema: self.schema,
accountability: {
admin: true,
},
knex: trx,
});
if (delta) {
const { rawDelta, defaultOverwrites } = splitRecursive(delta);
await itemsServiceAdmin.updateOne(key, rawDelta, {
emitEvents: false,
autoPurgeCache: false,
skipTracking: true,
overwriteDefaults: defaultOverwrites,
onItemCreate: (collection, pk) => {
if (collection in createdIDs === false)
createdIDs[collection] = [];
createdIDs[collection].push(pk);
},
});
}
const itemsServiceUser = new ItemsService(self.collection, {
schema: self.schema,
accountability: self.accountability,
knex: trx,
});
result = (await itemsServiceUser.readByQuery(queryWithKey, opts))[0];
await trx.rollback();
});
if (!result) {
throw new ForbiddenError();
}
return deepMapWithSchema(result, ([key, value], context) => {
if (context.relationType === 'm2o' || context.relationType === 'a2o') {
const ids = createdIDs[context.relation.related_collection];
const match = ids?.find((id) => String(id) === String(value));
if (match) {
return [key, null];
}
}
else if (context.relationType === 'o2m' && Array.isArray(value)) {
const ids = createdIDs[context.relation.collection];
return [
key,
value.map((val) => {
const match = ids?.find((id) => String(id) === String(val));
if (match) {
return null;
}
return val;
}),
];
}
if (context.field.field === context.collection.primary) {
const ids = createdIDs[context.collection.collection];
const match = ids?.find((id) => String(id) === String(value));
if (match) {
return [key, null];
}
}
return [key, value];
}, { collection: self.collection, schema: self.schema });
}