UNPKG

@gouvfr-anct/mednum

Version:

✨ Permet de transformer une source de données vers le schéma des lieux de mediation numerique

55 lines (54 loc) 3.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.canTransform = exports.updateFingerprints = exports.fingerprintsFrom = exports.diffSinceLastTransform = void 0; const node_crypto_1 = require("node:crypto"); const DIFF_WITHOUT_ID = null; const hashFor = (item) => (0, node_crypto_1.createHash)('sha256').update(JSON.stringify(item)).digest('hex'); const hasSameHash = (currentHash, item) => currentHash === hashFor(item); const toInnerProperty = (source, key) => typeof source === 'string' ? source : source[key]; const getId = (idKey, item) => idKey.split('.').reduce(toInnerProperty, item).toString(); const onlyMatchingItemIds = (idKey, item) => (fingerprint) => fingerprint.sourceId === getId(idKey, item); const toItemToUpsert = (fingerprints, idKey) => (toUpsert, item) => hasSameHash(fingerprints.find(onlyMatchingItemIds(idKey, item))?.hash, item) ? toUpsert : [...toUpsert, item]; const toFingerprintId = (fingerprint) => fingerprint.sourceId; const toItemId = (idKey) => (currentItem) => getId(idKey, currentItem); const toIdsToDeleteFrom = (sourceItemIds) => (fingerprintsToDelete, fingerprint) => sourceItemIds.includes(fingerprint.sourceId) ? fingerprintsToDelete : [...fingerprintsToDelete, { sourceId: fingerprint.sourceId }]; const onlyWithHash = (fingerprint) => fingerprint.hash != null; const findItemsToTransform = (sourceItems, fingerprints, idKey) => idKey === '' ? DIFF_WITHOUT_ID : { toUpsert: sourceItems.reduce(toItemToUpsert(fingerprints, idKey), []), toDelete: fingerprints.filter(onlyWithHash).reduce(toIdsToDeleteFrom(sourceItems.map(toItemId(idKey))), []) }; const diffSinceLastTransform = (idKey, fingerprints) => (sourceItems) => findItemsToTransform(sourceItems, fingerprints, idKey); exports.diffSinceLastTransform = diffSinceLastTransform; const toFingerprint = (idKey) => (sourceItem) => ({ sourceId: getId(idKey, sourceItem), hash: hashFor(sourceItem) }); const onlyValidSourceId = (fingerprint) => fingerprint.sourceId !== ''; const fingerprintsFrom = (sourceItems, idKey) => sourceItems.map(toFingerprint(idKey)).filter(onlyValidSourceId); exports.fingerprintsFrom = fingerprintsFrom; const matchingFingerprintById = (fingerprint) => (nextFingerprint) => nextFingerprint.sourceId === fingerprint.sourceId; const updateFingerprintHash = (fingerprint, nextFingerprints) => ({ sourceId: fingerprint.sourceId, hash: nextFingerprints.find(matchingFingerprintById(fingerprint))?.hash ?? '' }); const toUpdatedFingerprintHash = (matchingIds, nextFingerprints) => (fingerprint) => matchingIds.includes(fingerprint.sourceId) ? updateFingerprintHash(fingerprint, nextFingerprints) : fingerprint; const onlyFingerprintsToAdd = (matchingIds) => (fingerprint) => !matchingIds.includes(fingerprint.sourceId) && fingerprint.sourceId !== ''; const onlyMatchingIds = (nextFingerprintsIds) => (fingerprintId) => nextFingerprintsIds.includes(fingerprintId); const onlyFingerprintsNotIn = (idsToRemove) => (fingerprint) => !idsToRemove.includes(fingerprint.sourceId); const updateFingerprints = (fingerprints, nextFingerprints, fingerprintToDelete = []) => { const fingerprintsIds = fingerprints.map(toFingerprintId); const nextFingerprintsIds = nextFingerprints.map(toFingerprintId); const matchingIds = fingerprintsIds.filter(onlyMatchingIds(nextFingerprintsIds)); const toDelete = fingerprintToDelete.map((fingerprint) => fingerprint.sourceId); return [ ...fingerprints.filter(onlyFingerprintsNotIn(toDelete)).map(toUpdatedFingerprintHash(matchingIds, nextFingerprints)), ...nextFingerprints.filter(onlyFingerprintsToAdd(matchingIds)) ]; }; exports.updateFingerprints = updateFingerprints; const canTransform = (diff) => diff != null; exports.canTransform = canTransform;