Skip to content

Commit 37082a5

Browse files
authored
feat: add unpublishDocs to CMS client (#901)
1 parent f6f66b8 commit 37082a5

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

.changeset/breezy-pianos-cover.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@blinkk/root-cms': patch
3+
---
4+
5+
feat: add unpublishDocs to cms client

packages/root-cms/core/client.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,89 @@ export class RootCMSClient {
607607
return publishedDocs;
608608
}
609609

610+
/**
611+
* Batch unpublishes a set of docs by id.
612+
*/
613+
async unpublishDocs(
614+
docIds: string[],
615+
options?: {unpublishedBy?: string; batch?: WriteBatch}
616+
) {
617+
const projectCollectionsPath = `Projects/${this.projectId}/Collections`;
618+
const unpublishedBy = options?.unpublishedBy || 'root-cms-client';
619+
620+
// Fetch the current draft data for each doc.
621+
const docRefs = docIds.map((docId) => {
622+
const [collection, slug] = docId.split('/');
623+
if (!collection || !slug) {
624+
throw new Error(`invalid doc id: ${docId}`);
625+
}
626+
const docRef = this.db.doc(
627+
`${projectCollectionsPath}/${collection}/Drafts/${slug}`
628+
);
629+
return docRef;
630+
});
631+
const docSnapshots = await this.db.getAll(...docRefs);
632+
const docs = docSnapshots
633+
// Retrieve snapshot data for each doc.
634+
.map((snapshot) => snapshot.data() as Doc)
635+
// Remove docs that don't exist.
636+
.filter((d) => !!d);
637+
638+
if (docs.length === 0) {
639+
console.log('no docs to unpublish');
640+
return [];
641+
}
642+
643+
let batchCount = 0;
644+
const batch = options?.batch || this.db.batch();
645+
const unpublishedDocs: any[] = [];
646+
647+
for (const doc of docs) {
648+
const {id, collection, slug} = doc;
649+
const draftRef = this.db.doc(
650+
`${projectCollectionsPath}/${collection}/Drafts/${slug}`
651+
);
652+
const scheduledRef = this.db.doc(
653+
`${projectCollectionsPath}/${collection}/Scheduled/${slug}`
654+
);
655+
const publishedRef = this.db.doc(
656+
`${projectCollectionsPath}/${collection}/Published/${slug}`
657+
);
658+
659+
// Update the draft doc to remove published fields.
660+
batch.update(draftRef, {
661+
'sys.modifiedAt': FieldValue.serverTimestamp(),
662+
'sys.modifiedBy': unpublishedBy,
663+
'sys.publishedAt': FieldValue.delete(),
664+
'sys.publishedBy': FieldValue.delete(),
665+
'sys.firstPublishedAt': FieldValue.delete(),
666+
'sys.firstPublishedBy': FieldValue.delete(),
667+
});
668+
batchCount += 1;
669+
670+
// Delete the scheduled doc, if any.
671+
batch.delete(scheduledRef);
672+
batchCount += 1;
673+
674+
// Delete the published doc.
675+
batch.delete(publishedRef);
676+
batchCount += 1;
677+
678+
unpublishedDocs.push(doc);
679+
680+
if (batchCount >= 400) {
681+
await batch.commit();
682+
batchCount = 0;
683+
}
684+
}
685+
686+
if (batchCount > 0) {
687+
await batch.commit();
688+
}
689+
console.log(`unpublished ${unpublishedDocs.length} docs!`);
690+
return unpublishedDocs;
691+
}
692+
610693
/**
611694
* Publishes scheduled docs.
612695
*/

0 commit comments

Comments
 (0)