import { ChattyHostConnection , CallbackStore } from '@looker/chatty' ; import { deprecate } from 'util' ; import { EmbedClient } from './embed' ; import { LookerAuthConfig , LookerEmbedEventMap , LookerEmbedFilterParams } from './types' ; type EmbedClientConstructor < T > = { new ( host ) : T ; } ; interface LookerEmbedHostSettings { apiHost : string ; auth ? : LookerAuthConfig ; } interface UrlParams { [ key ] : string ; } function stringify ( params ) { const result = [ ] ; for ( const key in params ) { result . push ( `${ encodeURIComponent ( key ) }=${ encodeURIComponent ( params [ key ] ) }` ) ; } return result . join ( '&' ) ; } function escapeFilterParam ( param ) { return param . replace ( /,/g , '^,' ) ; } /**
 * The builder class for [[EmbedClient]]. Contains methods for defining the properties of embedded
 * Looker content.
 */ export class EmbedBuilder < T > { private _handlers : CallbackStore = { } ; private _appendTo : HTMLElement | null = null ; private _sandboxAttrs : string [ ] = [ ] ; private _classNames : string [ ] = [ ] ; private _frameBorder : string = '0' ; private _id ? : number | string ; private _params : UrlParams ; private _suffix : string = '' ; private _url ? : string | null ; private _sandboxedHost ? : boolean ; hidden constructor ( private _hostSettings , private _type , private _endpoint , private _clientConstructor ) { if ( this . sandboxedHost ) { this . _params = { embed_domain : this . _hostSettings . apiHost , sdk : '2' , sandboxed_host : 'true' } ; } else { const embedDomain = window . location . origin ; this . _params = { embed_domain : embedDomain , sdk : '2' } ; } } /**
     * Value for the `frame-border` attribute of an embedded iframe
     */ withFrameBorder ( attr ) { this . _frameBorder = attr ; return this ; } hidden param id withId ( id ) { this . _id = id ; return this ; } param params withParams ( params ) { for ( const key in params ) { this . _params [ key ] = params [ key ] ; } return this ; } filters withFilters ( filters , escape = false ) { if ( this . type === 'dashboard' ) { for ( const key in filters ) { this . _params [ key ] = escape ? escapeFilterParam ( filters [ key ] ) : filters [ key ] ; } } else { for ( const key in filters ) { this . _params [ `f[${ key }]` ] = escape ? escapeFilterParam ( filters [ key ] ) : filters [ key ] ; } } return this ; } param attr withSandboxAttr ( ... attr ) { this . _sandboxAttrs = this . _sandboxAttrs . concat ( attr ) ; return this ; } param className withClassName ( ... className ) { this . _classNames = this . _classNames . concat ( className ) ; return this ; } param suffix withNext ( suffix = '-next' ) { this . _suffix = suffix ; this . _endpoint += this . _suffix ; return this ; } param theme withTheme ( theme ) { this . _params . theme = theme ; return this ; } param apiHost withApiHost ( apiHost ) { if ( ! this . _hostSettings . apiHost ) { this . _hostSettings . apiHost = apiHost ; if ( this . sandboxedHost ) { this . _params . embed_domain = apiHost ; this . _params . sandboxed_host = 'true' ; } } else if ( this . _hostSettings . apiHost !== apiHost ) { throw new Error ( 'not allowed to change api host' ) ; } return this ; } param authUrl withAuthUrl ( authUrl ) { if ( ! this . _hostSettings . auth ?. url ) { this . _hostSettings . auth = { url : authUrl } ; } else if ( this . _hostSettings . auth . url !== authUrl ) { throw new Error ( 'not allowed to change auth url' ) ; } return this ; } param auth withAuth ( auth ) { if ( ! this . _hostSettings . auth ) { this . _hostSettings . auth = auth ; } else if ( this . _hostSettings . auth !== auth ) { throw new Error ( 'not allowed to change auth' ) ; } return this ; } hidden param url withUrl ( url ) { this . _url = url ; return this ; } hidden set sandboxedHost ( sandboxedHost ) { this . _sandboxedHost = sandboxedHost ; } hidden get sandboxedHost ( ) { if ( this . _sandboxedHost === undefined ) { const embedHostDomain = window . location . origin ; this . _sandboxedHost = embedHostDomain === 'null' || ! embedHostDomain ; } return this . _sandboxedHost ; } /**
     * The element to append the embedded content to.
     */ get el ( ) { return this . _appendTo || document . body ; } /**
     * the frame-border attribute to apply to the iframe
     */ get frameBorder ( ) { return this . _frameBorder ; } /**
     * The endpoint used to load content
     */ get endpoint ( ) { return this . _endpoint ; } /**
     * The type of embedded content, dashboard, look, and explore
     */ get type ( ) { return this . _type ; } /**
     * The address of the Looker instance being used
     */ get apiHost ( ) { return this . _hostSettings . apiHost ; } /**
     * The content URL of this embedded content, if provided
     */ get url ( ) { return this . _url ; } deprecated get authUrl ( ) { return this . _hostSettings . auth ?. url ; } /**
     * The auth config of this embedded content, if provided
     */ get auth ( ) { return this . _hostSettings . auth ; } hidden get embedUrl ( ) { const params = stringify ( this . _params ) ; return `${ this . endpoint }/${ this . id }?${ params }` ; } hidden get handlers ( ) { return this . _handlers ; } /**
     * The sandbox attributes of an embedded content iframe, if provided
     */ get sandboxAttrs ( ) { return this . _sandboxAttrs ; } /**
     * The classnames to apply to the embedded content
     */ get classNames ( ) { return this . _classNames ; } /**
     * The the suffix to append to the content type portion of the url
     */ get suffix ( ) { return this . _suffix ; } /**
     * The ID of this embedded content, if provided
     */ get id ( ) { return this . _id ; } hidden get clientConstructor ( ) { return this . _clientConstructor ; } param el appendTo ( el ) { if ( typeof el === 'string' ) { this . _appendTo = document . querySelector ( el ) ; } else { this . _appendTo = el ; } return this ; } typeparam param name param handler on < K extends keyof LookerEmbedEventMap > ( name , handler ) { this . _handlers [ name ] = this . _handlers [ name ] ? this . _handlers [ name ] : [ ] ; this . _handlers [ name ] . push ( handler ) ; return this ; } /**
     * Constructs the embedded content, including creating the DOM element that contains the content.
     */ build ( ) { return new EmbedClient < T > ( this ) ; } }