import { createURLBuilder } from '@rokoli/bnb/common' import { ID, PartialUpdateOperation } from '@rokoli/bnb/drf' import { APIObject } from '@rokoli/bnb' import { MaybeRefOrGetter, toValue } from 'vue' import { areSetsEqual } from '@/util' export const createTankURL = createURLBuilder(import.meta.env.VUE_APP_API_TANK, false) export const createSteeringURL = createURLBuilder(import.meta.env.VUE_APP_API_STEERING) export function createRelationManager<T extends APIObject>( partialUpdate: PartialUpdateOperation<T, Partial<T>>, getObject?: MaybeRefOrGetter<T>, ) { type AnyRelations = Partial<{ [K in keyof T]: T[K] extends ID[] ? T[K] : never }> return function (data: AnyRelations, object?: T): Promise<T> { const obj = typeof object !== 'undefined' ? object : toValue(getObject) const updateData = {} as Record<keyof T, ID[]> if (typeof obj === 'undefined') { throw new TypeError('You must either pass an object getter or pass the object on update.') } for (const _key of Object.keys(data)) { const key = _key as keyof T const currentValue = obj[key] as ID[] const newValue = data[key] as ID[] if (!Array.isArray(currentValue) || !Array.isArray(newValue)) { const message = `${_key} is not a relation on object` console.error(message, obj) throw new TypeError(message) } if (!areSetsEqual(currentValue, newValue)) { updateData[key] = newValue } } if (Object.keys(updateData).length > 0) { return partialUpdate(obj.id, updateData as Partial<T>) } else { return Promise.resolve(obj as T) } } }