import { toDataBody , isObject , capable } from "./utils" ; import Collection from "./collection" ; import * as requests from "./requests" ; import KintoClientBase , { PaginatedParams , PaginationResult } from "./base" ; import { KintoRequest , KintoIdObject , Permission , KintoResponse , HistoryEntry , KintoObject , Group , OperationResponse , MappableObject , } from "./types" ; import { HttpResponse } from "./http" ; import { AggregateResponse } from "./batch" ; export interface BucketOptions { safe ? : boolean ; headers ? : Record < string , string > ; retry ? : number ; } /**
 * Abstract representation of a selected bucket.
 *
 */ export default class Bucket { private client : KintoClientBase ; public name : string ; private _endpoints : KintoClientBase [ "endpoints" ] ; private _retry : number ; private _safe : boolean ; private _headers : Record < string , string > ; param { KintoClient } client param { String } name param options param { Object } options . headers param { Boolean } options . safe param { Number } options . retry constructor ( client , name , options = { } ) { ignore this . client = client ; type { String } this . name = name ; this . _endpoints = client . endpoints ; ignore this . _headers = options . headers || { } ; this . _retry = options . retry || 0 ; this . _safe = ! ! options . safe ; } get execute ( ) : KintoClientBase [ "execute" ] { return this . client . execute . bind ( this . client ) ; } get headers ( ) : Record < string , string > { return this . _headers ; } private private _getHeaders ( options ) { return { ... this . _headers , ... options . headers , } ; } private param { Object } options returns { Boolean } private _getSafe ( options ) { return { safe : this . _safe , ... options } . safe ; } private private _getRetry ( options ) { return { retry : this . _retry , ... options } . retry ; } param { String } name param options param { Object } options . headers param { Boolean } options . safe return { Collection } collection ( name , options = { } ) { return new Collection ( this . client , this , name , { headers : this . _getHeaders ( options ) , retry : this . _getRetry ( options ) , safe : this . _getSafe ( options ) , } ) ; } param options param { Object } options . headers param { Number } options . retry return { Promise < String , Error > } async getCollectionsTimestamp ( options = { } ) { const path = this . _endpoints . collection ( this . name ) ; const request = { headers : this . _getHeaders ( options ) , path , method : "HEAD" , } ; const { headers } = ( await this . client . execute ( request , { raw : true , retry : this . _getRetry ( options ) , } ) ) as HttpResponse < { } > ; return headers . get ( "ETag" ) ; } param options param { Object } options . headers param { Number } options . retry return { Promise < String , Error > } async getGroupsTimestamp ( options = { } ) { const path = this . _endpoints . group ( this . name ) ; const request = { headers : this . _getHeaders ( options ) , path , method : "HEAD" , } ; const { headers } = ( await this . client . execute ( request , { raw : true , retry : this . _getRetry ( options ) , } ) ) as HttpResponse < { } > ; return headers . get ( "ETag" ) ; } param options param { Object } options . headers param { Object } options . query param { Array } options . fields param { Number } options . retry return { Promise < Object , Error > } async getData < T > ( options = { } ) { const path = this . _endpoints . bucket ( this . name ) ; const request = { headers : this . _getHeaders ( options ) , path , } ; const { data } = ( await this . client . execute ( request , { retry : this . _getRetry ( options ) , query : options . query , fields : options . fields , } ) ) as { data : T ; } ; return data ; } param { Object } data param options param { Object } options . headers param { Boolean } options . safe param { Number } options . retry param { Boolean } options . patch param { Number } options . last_modified return { Promise < Object , Error > } async setData < T extends MappableObject > ( data , options = { } ) { if ( ! isObject ( data ) ) { throw new Error ( "A bucket object is required." ) ; } const bucket = { ... data , id : this . name , } ; const bucketId = bucket . id ; if ( bucket . id === "default" ) { delete bucket . id ; } const path = this . _endpoints . bucket ( bucketId ) ; const { patch , permissions } = options ; const { last_modified } = { ... data , ... options } ; const request = requests . updateRequest ( path , { data : bucket , permissions } , { last_modified , patch , headers : this . _getHeaders ( options ) , safe : this . _getSafe ( options ) , } ) ; return this . client . execute < KintoResponse < T > > ( request , { retry : this . _getRetry ( options ) , } ) as Promise < KintoResponse < T > > ; } param options param { Object } options . headers param { Number } options . retry return { Promise < Array < Object > , Error > } @ capable ( [ "history" ] ) async listHistory < T > ( options = { } ) { const path = this . _endpoints . history ( this . name ) ; return this . client . paginatedList < HistoryEntry < T > > ( path , options , { headers : this . _getHeaders ( options ) , retry : this . _getRetry ( options ) , } ) ; } param options param { Object } options . filters param { Object } options . headers param { Number } options . retry param { Array } options . fields return { Promise < Array < Object > , Error > } async listCollections ( options = { } ) { const path = this . _endpoints . collection ( this . name ) ; return this . client . paginatedList < KintoObject > ( path , options , { headers : this . _getHeaders ( options ) , retry : this . _getRetry ( options ) , } ) ; } param { String | undefined } id param options param { Boolean } options . safe param { Object } options . headers param { Number } options . retry param { Object } options . permissions param { Object } options . data return { Promise < Object , Error > } async createCollection ( id ? , options = { } ) { const { permissions , data = { } } = options ; data . id = id ; const path = this . _endpoints . collection ( this . name , id ) ; const request = requests . createRequest ( path , { data , permissions } , { headers : this . _getHeaders ( options ) , safe : this . _getSafe ( options ) , } ) ; return this . client . execute < KintoResponse < { } > > ( request , { retry : this . _getRetry ( options ) , } ) as Promise < KintoResponse < { } > > ; } param { Object | String } collection param options param { Object } options . headers param { Number } options . retry param { Boolean } options . safe param { Number } options . last_modified return { Promise < Object , Error > } async deleteCollection ( collection , options = { } ) { const collectionObj = toDataBody ( collection ) ; if ( ! collectionObj . id ) { throw new Error ( "A collection id is required." ) ; } const { id } = collectionObj ; const { last_modified } = { ... collectionObj , ... options } ; const path = this . _endpoints . collection ( this . name , id ) ; const request = requests . deleteRequest ( path , { last_modified , headers : this . _getHeaders ( options ) , safe : this . _getSafe ( options ) , } ) ; return this . client . execute < KintoResponse < { deleted : boolean ; } > > ( request , { retry : this . _getRetry ( options ) , } ) as Promise < KintoResponse < { deleted : boolean ; } > > ; } param options param { Object } options . filters param { Object } options . headers param { Number } options . retry param { Array } options . fields return { Promise < Array < Object > , Error > } async deleteCollections ( options = { } ) { const path = this . _endpoints . collection ( this . name ) ; return this . client . paginatedDelete < KintoObject > ( path , options , { headers : this . _getHeaders ( options ) , retry : this . _getRetry ( options ) , } ) ; } param options param { Object } options . filters param { Object } options . headers param { Number } options . retry param { Array } options . fields return { Promise < Array < Object > , Error > } async listGroups ( options = { } ) { const path = this . _endpoints . group ( this . name ) ; return this . client . paginatedList < Group > ( path , options , { headers : this . _getHeaders ( options ) , retry : this . _getRetry ( options ) , } ) ; } param { String } id param options param { Object } options . headers param { Number } options . retry param { Object } options . query param { Array } options . fields return { Promise < Object , Error > } async getGroup ( id , options = { } ) { const path = this . _endpoints . group ( this . name , id ) ; const request = { headers : this . _getHeaders ( options ) , path , } ; return this . client . execute < KintoResponse < Group > > ( request , { retry : this . _getRetry ( options ) , query : options . query , fields : options . fields , } ) as Promise < KintoResponse < Group > > ; } param { String | undefined } id param { Array < String > } members param options param { Object } options . data param { Object } options . permissions param { Boolean } options . safe param { Object } options . headers param { Number } options . retry return { Promise < Object , Error > } async createGroup ( id ? , members = [ ] , options = { } ) { const data = { ... options . data , id , members , } ; const path = this . _endpoints . group ( this . name , id ) ; const { permissions } = options ; const request = requests . createRequest ( path , { data , permissions } , { headers : this . _getHeaders ( options ) , safe : this . _getSafe ( options ) , } ) ; return this . client . execute < KintoResponse < Group > > ( request , { retry : this . _getRetry ( options ) , } ) as Promise < KintoResponse < Group > > ; } param { Object } group param options param { Object } options . data param { Object } options . permissions param { Boolean } options . safe param { Object } options . headers param { Number } options . retry param { Number } options . last_modified return { Promise < Object , Error > } async updateGroup < T extends MappableObject > ( group , options = { } ) { if ( ! isObject ( group ) ) { throw new Error ( "A group object is required." ) ; } if ( ! group . id ) { throw new Error ( "A group id is required." ) ; } const data = { ... options . data , ... group , } ; const path = this . _endpoints . group ( this . name , group . id ) ; const { patch , permissions } = options ; const { last_modified } = { ... data , ... options } ; const request = requests . updateRequest ( path , { data , permissions } , { last_modified , patch , headers : this . _getHeaders ( options ) , safe : this . _getSafe ( options ) , } ) ; return this . client . execute < KintoResponse < T & { members : string [ ] ; } > > ( request , { retry : this . _getRetry ( options ) , } ) as Promise < KintoResponse < T & { members : string [ ] ; } > > ; } param { Object | String } group param options param { Object } options . headers param { Number } options . retry param { Boolean } options . safe param { Number } options . last_modified return { Promise < Object , Error > } async deleteGroup ( group , options = { } ) { const groupObj = toDataBody ( group ) ; const { id } = groupObj ; const { last_modified } = { ... groupObj , ... options } ; const path = this . _endpoints . group ( this . name , id ) ; const request = requests . deleteRequest ( path , { last_modified , headers : this . _getHeaders ( options ) , safe : this . _getSafe ( options ) , } ) ; return this . client . execute < KintoResponse < { deleted : boolean ; } > > ( request , { retry : this . _getRetry ( options ) , } ) as Promise < KintoResponse < { deleted : boolean ; } > > ; } param options param { Object } options . filters param { Object } options . headers param { Number } options . retry param { Array } options . fields return { Promise < Array < Object > , Error > } async deleteGroups ( options = { } ) { const path = this . _endpoints . group ( this . name ) ; return this . client . paginatedDelete < KintoObject > ( path , options , { headers : this . _getHeaders ( options ) , retry : this . _getRetry ( options ) , } ) ; } param options param { Object } options . headers param { Number } options . retry return { Promise < Object , Error > } async getPermissions ( options = { } ) { const request = { headers : this . _getHeaders ( options ) , path : this . _endpoints . bucket ( this . name ) , } ; const { permissions } = ( await this . client . execute < KintoResponse > ( request , { retry : this . _getRetry ( options ) , } ) ) as KintoResponse ; return permissions ; } param { Object } permissions param options param { Boolean } options . safe param { Object } options . headers param { Number } options . retry param { Object } options . last_modified return { Promise < Object , Error > } async setPermissions ( permissions , options = { } ) { if ( ! isObject ( permissions ) ) { throw new Error ( "A permissions object is required." ) ; } const path = this . _endpoints . bucket ( this . name ) ; const { last_modified } = options ; const data = { last_modified } ; const request = requests . updateRequest ( path , { data , permissions } , { headers : this . _getHeaders ( options ) , safe : this . _getSafe ( options ) , } ) ; return this . client . execute < KintoResponse < { } > > ( request , { retry : this . _getRetry ( options ) , } ) as Promise < KintoResponse < { } > > ; } param { Object } permissions param options param { Boolean } options . safe param { Object } options . headers param { Number } options . retry param { Object } options . last_modified return { Promise < Object , Error > } async addPermissions ( permissions , options = { } ) { if ( ! isObject ( permissions ) ) { throw new Error ( "A permissions object is required." ) ; } const path = this . _endpoints . bucket ( this . name ) ; const { last_modified } = options ; const request = requests . jsonPatchPermissionsRequest ( path , permissions , "add" , { last_modified , headers : this . _getHeaders ( options ) , safe : this . _getSafe ( options ) , } ) ; return this . client . execute < KintoResponse < { } > > ( request , { retry : this . _getRetry ( options ) , } ) as Promise < KintoResponse < { } > > ; } param { Object } permissions param options param { Boolean } options . safe param { Object } options . headers param { Number } options . retry param { Object } options . last_modified return { Promise < Object , Error > } async removePermissions ( permissions , options = { } ) { if ( ! isObject ( permissions ) ) { throw new Error ( "A permissions object is required." ) ; } const path = this . _endpoints . bucket ( this . name ) ; const { last_modified } = options ; const request = requests . jsonPatchPermissionsRequest ( path , permissions , "remove" , { last_modified , headers : this . _getHeaders ( options ) , safe : this . _getSafe ( options ) , } ) ; return this . client . execute < KintoResponse < { } > > ( request , { retry : this . _getRetry ( options ) , } ) as Promise < KintoResponse < { } > > ; } param { Function } fn param options param { Object } options . headers param { Boolean } options . safe param { Number } options . retry param { Boolean } options . aggregate return { Promise < Object , Error > } async batch ( fn , options = { } ) { return this . client . batch ( fn , { bucket : this . name , headers : this . _getHeaders ( options ) , retry : this . _getRetry ( options ) , safe : this . _getSafe ( options ) , aggregate : ! ! options . aggregate , } ) ; } }