@magnetarjs/plugin-firestore
Version:
Magnetar plugin firestore
111 lines (108 loc) • 4.72 kB
JavaScript
import { arrStr, logWithFlair, logWithFlairGroup } from '@magnetarjs/utils';
import { and, collection, collectionGroup, getCountFromServer, getDocs, limit, onSnapshot, or, orderBy, query, startAfter, where, } from 'firebase/firestore';
import { isArray, isNumber } from 'is-what';
function applyQueryClause(queryClause) {
if ('and' in queryClause) {
return and(...queryClause.and.map((clause) => isArray(clause) ? where(...clause) : applyQueryClause(clause)));
}
if ('or' in queryClause) {
return or(...queryClause.or.map((clause) => isArray(clause) ? where(...clause) : applyQueryClause(clause)));
}
throw new Error('invalid query');
}
function applyQueryClauseDebug(queryClause) {
if ('and' in queryClause) {
const params = queryClause.and
.map((clause) => isArray(clause) ? `where(${arrStr(clause)})` : applyQueryClauseDebug(clause))
.join(', ');
return `and(${params})`;
}
if ('or' in queryClause) {
const params = queryClause.or
.map((clause) => isArray(clause) ? `where(${arrStr(clause)})` : applyQueryClauseDebug(clause))
.join(', ');
return `or(${params})`;
}
throw new Error('invalid query');
}
/**
* If the collectionPath includes a `*` it will use a collectionQuery for the part beyond that point
*/
export function getQueryInstance(collectionPath, config, db, debug) {
let q;
let qDebugString;
if (debug) {
;
window.magnetarDebugStartAfter = config.startAfter;
}
q = collectionPath.includes('*/')
? collectionGroup(db, collectionPath.split('*/')[1] ?? '')
: collection(db, collectionPath);
const qDebugCollection = collectionPath.includes('*/')
? `collectionGroup(db, "${collectionPath.split('*/')[1]}")`
: `collection(db, "${collectionPath}")`;
qDebugString = qDebugCollection;
for (const queryClause of config.query || []) {
q = query(q, applyQueryClause(queryClause));
qDebugString = `query(${qDebugString}, ${applyQueryClauseDebug(queryClause)})`;
}
for (const whereClause of config.where || []) {
q = query(q, where(...whereClause));
qDebugString = `query(${qDebugString}, where(${arrStr(whereClause)}))`;
}
for (const orderByClause of config.orderBy || []) {
q = query(q, orderBy(...orderByClause));
qDebugString = `query(${qDebugString}, orderBy(${arrStr(orderByClause)}))`;
}
if (config.startAfter) {
q = query(q, Array.isArray(config.startAfter)
? startAfter(...config.startAfter)
: startAfter(config.startAfter));
qDebugString = `query(${qDebugString}, ${Array.isArray(config.startAfter)
? `startAfter(${arrStr(config.startAfter)})`
: `startAfter(window.magnetarDebugStartAfter)`})`;
}
if (isNumber(config.limit)) {
q = query(q, limit(config.limit));
qDebugString = `query(${qDebugString}, limit(${config.limit}))`;
}
if (debug) {
logWithFlairGroup(`Firebase JS SDK Query (click to expand): ${qDebugCollection}...`, `// add \`db, getDocs, where, ...\` to window:
magnetarDebugAddFirebaseToWindow()
// debug by executing & tweaking:
const myQuery = ${qDebugString}
getDocs(myQuery)
.then(console.info)
.error(console.error)`, { preventLogFor: 10_000 });
if (!window.magnetarDebugAddFirebaseToWindowExplained) {
logWithFlair(`execute \`magnetarDebugAddFirebaseToWindow()\` to add these Firebase JS SDK variables to the window for debugging: db, getDocs, onSnapshot, getCountFromServer, and, collection, collectionGroup, limit, or, orderBy, query, startAfter, where`);
window.magnetarDebugAddFirebaseToWindow = () => {
;
window.db = db;
window.getDocs = getDocs;
window.onSnapshot = onSnapshot;
window.getCountFromServer = getCountFromServer;
window.and = and;
window.collection = collection;
window.collectionGroup = collectionGroup;
window.limit = limit;
window.or = or;
window.orderBy = orderBy;
window.query = query;
window.startAfter = startAfter;
window.where = where;
};
window.magnetarDebugAddFirebaseToWindowExplained = true;
}
}
return q;
}
export function docSnapshotToDocMetadata(docSnapshot) {
const docMetaData = {
data: docSnapshot.data(),
metadata: docSnapshot,
id: docSnapshot.id,
exists: docSnapshot.exists(),
};
return docMetaData;
}