Repository: directus/directus
File: app/src/composables/use-item.ts (TypeScript)

Code before:
					relatedPrimaryKeyField,
					fieldsToFetch,
				);

				existingItems = existingItems.filter(
					(item) => !newRelatedItem.delete.includes(item[relatedPrimaryKeyField.field]),
				);

				for (const item of newRelatedItem.update) {
					updateJunctionRelatedKey(relation, existsJunctionRelated, item);
				}

				for (const item of existingItems) {
					updateExistingRelatedItems(newRelatedItem.update, item, relatedPrimaryKeyField, relation);
				}

				newRelatedItem.update.length = 0;

				for (const item of existingItems) {
					delete item[relatedPrimaryKeyField!.field];
					newRelatedItem.create.push(item);
				}
			}
		}

		const errors = validateItem(newItem, fieldsWithPermissions.value, isNew.value, false, currentVersion.value);
		if (nestedValidationErrors.value?.length) errors.push(...nestedValidationErrors.value);

		if (errors.length > 0) {
			validationErrors.value = errors;
			saving.value = false;
			throw errors;
		}

		try {
			const response = await api.post(getEndpoint(collection.value), newItem);

			notify({
				title: i18n.global.t('item_create_success', 1),
			});

			// Reset edits to the current item
			edits.value = {};

			return primaryKeyField.value ? response.data.data[primaryKeyField.value.field] : null;
		} catch (error) {
			saveErrorHandler(error);
		} finally {
			saving.value = false;
		}


Review comment (security):
It is not possible to use saveAsCopy for versions (or for versions other than `main`), so I think we should not pass the `currentVersion` Ref here, otherwise it might cause confusion in the future.

This also means that any changes made to this file can be undone, as well as the `use-item.test.ts` file.

```suggestion
		const errors = validateItem(newItem, fieldsWithPermissions.value, isNew.value);
```

Code after:
				);

				existingItems = existingItems.filter(
					(item) => !newRelatedItem.delete.includes(item[relatedPrimaryKeyField.field]),
				);

				for (const item of newRelatedItem.update) {
					updateJunctionRelatedKey(relation, existsJunctionRelated, item);
				}

				for (const item of existingItems) {
					updateExistingRelatedItems(newRelatedItem.update, item, relatedPrimaryKeyField, relation);
				}

				newRelatedItem.update.length = 0;

				for (const item of existingItems) {
					delete item[relatedPrimaryKeyField!.field];
					newRelatedItem.create.push(item);
				}
			}
		}

		const errors = validateItem(newItem, fieldsWithPermissions.value, isNew.value);
		if (nestedValidationErrors.value?.length) errors.push(...nestedValidationErrors.value);

		if (errors.length > 0) {
			validationErrors.value = errors;
			saving.value = false;
			throw errors;
		}

		try {
			const response = await api.post(getEndpoint(collection.value), newItem);

			notify({
				title: i18n.global.t('item_create_success', 1),
			});

			// Reset edits to the current item
			edits.value = {};

			return primaryKeyField.value ? response.data.data[primaryKeyField.value.field] : null;
		} catch (error) {
			saveErrorHandler(error);
		} finally {
			saving.value = false;
		}

		async function findExistingRelatedItems(
			item: Item,