@@ -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