* Add script to denormalize avatars into contracts/comments * Also handle denormalizing answer avatar URLs * Small fixups
49 lines
1.3 KiB
TypeScript
49 lines
1.3 KiB
TypeScript
// Helper functions for maintaining the relationship between fields in one set of documents and denormalized copies in
|
|
// another set of documents.
|
|
|
|
import { DocumentSnapshot, Transaction } from 'firebase-admin/firestore'
|
|
|
|
export type DocumentValue = {
|
|
doc: DocumentSnapshot
|
|
field: string
|
|
val: any
|
|
}
|
|
export type DocumentCorrespondence = [DocumentSnapshot, DocumentSnapshot[]]
|
|
export type DocumentDiff = {
|
|
src: DocumentValue
|
|
dest: DocumentValue
|
|
}
|
|
|
|
export function findDiffs(
|
|
docs: DocumentCorrespondence[],
|
|
srcPath: string,
|
|
destPath: string
|
|
) {
|
|
const diffs: DocumentDiff[] = []
|
|
for (let [srcDoc, destDocs] of docs) {
|
|
const srcVal = srcDoc.get(srcPath)
|
|
for (let destDoc of destDocs) {
|
|
const destVal = destDoc.get(destPath)
|
|
if (destVal !== srcVal) {
|
|
diffs.push({
|
|
src: { doc: srcDoc, field: srcPath, val: srcVal },
|
|
dest: { doc: destDoc, field: destPath, val: destVal },
|
|
})
|
|
}
|
|
}
|
|
}
|
|
return diffs
|
|
}
|
|
|
|
export function describeDiff(diff: DocumentDiff) {
|
|
function describeDocVal(x: DocumentValue): string {
|
|
return `${x.doc.ref.path}.${x.field}: ${x.val}`
|
|
}
|
|
return `${describeDocVal(diff.src)} -> ${describeDocVal(diff.dest)}`
|
|
}
|
|
|
|
export function applyDiff(transaction: Transaction, diff: DocumentDiff) {
|
|
const { src, dest } = diff
|
|
transaction.update(dest.doc.ref, dest.field, src.val)
|
|
}
|