Skip to content
Snippets Groups Projects
api.ts 1.61 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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)
        }
      }
    }