ts-fp-di-mikroorm
Version:
Persist ts-fp-di State as MikroORM Entities
87 lines (86 loc) • 3.88 kB
JavaScript
;
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]));
};