UNPKG

ts-fp-di-mikroorm

Version:

Persist ts-fp-di State as MikroORM Entities

87 lines (86 loc) 3.88 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.entityConstructor = exports.onPersist = exports.em = exports.wrapTsFpDiMikroorm = void 0; const node_util_1 = require("node:util"); const ts_fp_di_1 = require("ts-fp-di"); const TS_FP_DI_MIKROORM_EM = 'ts-fp-di-mikroorm-em'; const TS_FP_DI_MIKROORM_ENTITIES = 'ts-fp-di-mikroorm-entities'; const TS_FP_DI_MIKROORM_ON_PERSIST_CB = 'ts-fp-di-mikroorm-on-persist-cb'; const wrapTsFpDiMikroorm = async (orm, cb) => { return await (0, ts_fp_di_1.diInit)(async () => { const em = orm.em.fork(); (0, ts_fp_di_1.diSet)(TS_FP_DI_MIKROORM_EM, em); (0, ts_fp_di_1.diSet)(TS_FP_DI_MIKROORM_ENTITIES, new Set(orm.config.get('entities'))); const resp = await cb(); const allState = await Promise.all([ ...(ts_fp_di_1.als.getStore()?.state.values() ?? []), ...(ts_fp_di_1.als.getStore()?.once.values() ?? []), ...(ts_fp_di_1.als.getStore()?.derived.values() ?? []), ]); const entities = Array.from(entitiesSet(allState).values()); const entitiesForUpsert = entities.filter(ent => !!ent.$forUpsert); await Promise.all(entitiesForUpsert.map(fetchExistingEntity)); await Promise.all(entities.map(persistEntity)); await em.flush(); if ((0, ts_fp_di_1.diHas)(TS_FP_DI_MIKROORM_ON_PERSIST_CB)) { await (0, ts_fp_di_1.diDep)(TS_FP_DI_MIKROORM_ON_PERSIST_CB)(); } return resp; }); }; exports.wrapTsFpDiMikroorm = wrapTsFpDiMikroorm; const em = () => (0, ts_fp_di_1.diDep)(TS_FP_DI_MIKROORM_EM); exports.em = em; const onPersist = (cb) => { (0, ts_fp_di_1.diSet)(TS_FP_DI_MIKROORM_ON_PERSIST_CB, cb); }; exports.onPersist = onPersist; const entityConstructor = (self, ent) => Object.entries(ent).forEach(([key, val]) => Reflect.set(self, key, val)); exports.entityConstructor = entityConstructor; const entitiesSet = (maybeEntity, entities = new Set()) => { if (Array.isArray(maybeEntity)) { return arrayToSet(maybeEntity, entities); } if (node_util_1.types.isMap(maybeEntity) || node_util_1.types.isSet(maybeEntity)) { return arrayToSet(Array.from(maybeEntity.values()), entities); } if (!isEntity(maybeEntity)) { return entities; } if (maybeEntity.$noPersist) { return entities; } return new Set(entities).add(maybeEntity); }; const arrayToSet = (maybeEntity, entities) => { const sets = maybeEntity.map(maybeEnt => entitiesSet(maybeEnt, entities)); const resp = new Set(entities); sets.forEach(set => Array.from(set.values()).forEach(ent => resp.add(ent))); return resp; }; const fetchExistingEntity = (entity) => { const em = (0, ts_fp_di_1.diDep)(TS_FP_DI_MIKROORM_EM); const pks = em.getMetadata().getByClassName(entity.constructor.name).primaryKeys; return em.findOne(entity.constructor, Object.fromEntries(pks.map(pk => [pk, entity[pk]]))); }; const persistEntity = async (entity) => { const em = (0, ts_fp_di_1.diDep)(TS_FP_DI_MIKROORM_EM); if (entity.$forDelete) { return em.remove(entity); } const updated = entity.$forUpdate ? getRef(entity) : entity.$forUpsert ? await fetchExistingEntity(entity) : null; if (updated) { Object.entries(entity) .filter(([, v]) => v !== void 0) .forEach(([k, v]) => (updated[k] = v)); } return em.persist(updated ?? entity); }; const isEntity = (maybeEntity) => (0, ts_fp_di_1.diDep)(TS_FP_DI_MIKROORM_ENTITIES).has(Object.getPrototypeOf(maybeEntity ?? {}).constructor); const getRef = (entity) => { const em = (0, ts_fp_di_1.diDep)(TS_FP_DI_MIKROORM_EM); return em.getReference(entity.constructor.name, em .getMetadata() .getByClassName(entity.constructor.name) .primaryKeys.map(pk => entity[pk])); };