import { EntityRawSchemaArray, RelationDefinitionRawSchemaArray, Client, Schema, getLooseSchema, Transaction, } from "@cubicweb/client"; import { RaRecord, UpdateManyParams, UpdateManyResult, UpdateParams, UpdateResult, } from "./types.js"; import { getGet } from "./get.js"; import { executeApiTransaction } from "./utils/requests.js"; import { generateUpdateEntityByEidRQL } from "@cubicweb/rql-generator"; // FIXME when updating relation, cardinality checks are not possible for the destination. Problems with 1, + and ?: // The input will allow any edit because is does not check the cardinality of the destination. // // Example: in the museum tutorial schema with the is_in relation, 1* cardinality, with Museum as subject and // City as object. // Editing the city of a museum works as expected: // we cannot remove a city from a museum, only change it because the field is required. // But editing the museums associated with a city does not work as expected (editing is_in from the city object): // the input field allows removing a museum from a city because it respects city cardinality constraints (*), // but removing a museum from a city will not respect the museum cardinality, the museum will be without a city. // We might also add relations from one museum to several cities, which is not allowed. export const getUpdate = < E extends EntityRawSchemaArray, R extends RelationDefinitionRawSchemaArray >( client: Client, schema: Schema ) => { const update = async ( resource: E[number]["type"], updateParams: UpdateParams ): Promise> => { const eid = typeof updateParams.id === "string" ? parseInt(updateParams.id) : updateParams.id; const entityTypeSchema = getLooseSchema(schema).getEntity(resource); if (entityTypeSchema === null) { throw new Error(`Could not find entity ${resource}`); } const transaction = new Transaction(); const queries = generateUpdateEntityByEidRQL( schema, resource, eid, updateParams.data, updateParams.previousData ); transaction.push(...queries); await executeApiTransaction(client, transaction); const meta: | { getAfterUpdate?: { enabled?: boolean; // eslint-disable-next-line @typescript-eslint/no-explicit-any meta?: any; }; } | undefined = updateParams.meta; if (meta?.getAfterUpdate?.enabled !== false) { const newData: UpdateResult = await getGet( client, schema ).getOne(resource, { id: updateParams.id, meta: meta?.getAfterUpdate?.meta, }); return newData; } return { data: updateParams.data as RaRecord }; }; const updateMany = async ( resource: E[number]["type"], { data, ids }: UpdateManyParams ): Promise => { console.log("updateMany"); console.log(resource); console.log(data); console.log(ids); const entitySchema = getLooseSchema(schema).getEntity(resource); if (entitySchema == null) { return Promise.reject( `Entity '${resource}' does not exist in the schema` ); } // TODO implement this return Promise.reject("updateMany not implemented"); }; return { update, updateMany }; };