entityManager.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import ApiRequestService from "./apiRequestService";
  2. import {AssociativeArray} from "./data";
  3. import {useRepo} from "pinia-orm";
  4. import UrlBuilder from "~/services/utils/urlBuilder";
  5. import ModelNormalizer from "./serializer/normalizer/modelNormalizer";
  6. import HydraDenormalizer from "./serializer/denormalizer/hydraDenormalizer";
  7. import ApiModel from "~/models/ApiModel";
  8. /**
  9. * Entity manager: make operations on the models defined with the Pinia-Orm library
  10. *
  11. * @see https://pinia-orm.codedredd.de/
  12. */
  13. class EntityManager {
  14. private apiRequestService: ApiRequestService;
  15. public constructor(apiRequestService: ApiRequestService) {
  16. this.apiRequestService = apiRequestService
  17. }
  18. public getRepository(model: typeof ApiModel) {
  19. return useRepo(model)
  20. }
  21. private static getEntityModel(entity: ApiModel): typeof ApiModel{
  22. return Object.getPrototypeOf(entity)
  23. }
  24. /**
  25. * Fetch one entity by its id, save it to the store and returns it
  26. *
  27. * @param model Model of the object to fetch
  28. * @param id Id of the object to fetch
  29. * @param forceRefresh Force a new get request to the api ;
  30. * current object in store will be overwritten if it exists
  31. */
  32. public async fetch(model: typeof ApiModel, id: number, forceRefresh: boolean = false) {
  33. const repository = this.getRepository(model)
  34. // If the entity is already in the store and forceRefresh is false, return the object in store
  35. if (!forceRefresh) {
  36. const item = repository.find(id)
  37. if (item && typeof item !== 'undefined') {
  38. return item
  39. }
  40. }
  41. // Else, get the object from the API
  42. const url = UrlBuilder.concat('api', model.entity, String(id))
  43. const response = await this.apiRequestService.get(url)
  44. // deserialize the response
  45. const entity = await HydraDenormalizer.denormalize(response)
  46. entity.persisted = true
  47. entity.initialState = structuredClone(entity)
  48. // Save data into the store
  49. repository.save(entity)
  50. return entity
  51. }
  52. public findBy(model: typeof ApiModel, query: AssociativeArray) {
  53. // TODO: implement
  54. }
  55. public fetchAll(model: typeof ApiModel) {
  56. // TODO: implement
  57. }
  58. public async persist(model: typeof ApiModel, entity: ApiModel) {
  59. const data = ModelNormalizer.normalize(entity)
  60. let url = UrlBuilder.concat('api', model.entity)
  61. let response = null
  62. if (entity.persisted) {
  63. url = UrlBuilder.concat(url, String(entity.id))
  64. response = await this.apiRequestService.put(url, data)
  65. } else {
  66. response = await this.apiRequestService.post(url, data)
  67. }
  68. const fetchedEntity = await HydraDenormalizer.denormalize(response)
  69. fetchedEntity.persisted = true
  70. // Save data into the store
  71. const repository = this.getRepository(model)
  72. repository.save(fetchedEntity)
  73. return fetchedEntity
  74. }
  75. public async delete(model: typeof ApiModel, id: number) {
  76. const repository = this.getRepository(model)
  77. const entity = repository.find(id) as ApiModel
  78. if (!entity || typeof entity === 'undefined') {
  79. throw new Error(model + ' ' + id + ' does not exists in store')
  80. }
  81. // If object has been persisted to the datasource, send a delete request
  82. if (entity.persisted) {
  83. const url = UrlBuilder.concat('api', model.entity, String(id))
  84. await this.apiRequestService.delete(url)
  85. }
  86. // update the store
  87. repository.destroy(id)
  88. }
  89. public new(model: typeof ApiModel) {
  90. const repository = this.getRepository(model)
  91. const entity = repository.make()
  92. entity.persisted = false
  93. // Save data into the store
  94. repository.save(entity)
  95. return entity
  96. }
  97. public reset(entity: ApiModel) {
  98. if (entity.initialState === null) {
  99. console.log('object has no initial state - abort')
  100. return
  101. }
  102. entity = entity.initialState as ApiModel
  103. entity.initialState = structuredClone(entity)
  104. const repository = this.getRepository(this.getEntityModel(entity))
  105. repository.save(entity)
  106. }
  107. }
  108. export default EntityManager