<commit_before>import { Injectable, Inject } from '@angular/core';

import { Observable } from 'rxjs/Observable';

import { WindowRef } from './window-ref';
import { LazyStripeAPILoader, Status } from './api-loader.service';

import {
  STRIPE_PUBLISHABLE_KEY,
  StripeJS,
  STRIPE_OPTIONS
} from '../interfaces/stripe';
import { Element } from '../interfaces/element';
import { Elements, ElementsOptions } from '../interfaces/elements';
import {
  SourceData,
  SourceResult,
  isSourceData,
  SourceParams
} from '../interfaces/sources';
import {
  CardDataOptions,
  TokenResult,
  BankAccount,
  BankAccountData,
  PiiData,
  Pii,
  isBankAccount,
  isBankAccountData,
  isPii,
  isPiiData
} from '../interfaces/token';

@Injectable()
export class StripeService {
  private stripe: StripeJS;

  constructor(
    @Inject(STRIPE_PUBLISHABLE_KEY) private key: string,
    @Inject(STRIPE_OPTIONS) private options: string,
    private loader: LazyStripeAPILoader,
    private window: WindowRef
  ) {
    this.loader
      .asStream()
      .filter((status: Status) => status.loaded === true)
      .subscribe(() => {
        const Stripe = (this.window.getNativeWindow() as any).Stripe;
        this.stripe = this.options
          ? (Stripe(this.key, this.options) as StripeJS)
          : (Stripe(this.key) as StripeJS);
      });
  }

  public changeKey(key: string, options?: string): Observable<StripeJS> {
    const obs = this.loader
      .asStream()
      .filter((status: Status) => status.loaded === true)
      .map(() => {
        const Stripe = (this.window.getNativeWindow() as any).Stripe;
        this.stripe = options
          ? (Stripe(key, options) as StripeJS)
          : (Stripe(key) as StripeJS);
        return this.stripe;
      })
      .publishLast()
      .refCount();
    obs.subscribe();
    return obs;
  }

  public elements(options?: ElementsOptions): Observable<Elements> {
    return this.loader
      .asStream()
      .filter((status: Status) => status.loaded === true)
      .map(() => this.stripe.elements(options));
  }

  public createToken(
    a: Element | BankAccount | Pii,
    b: CardDataOptions | BankAccountData | PiiData | undefined
  ): Observable<TokenResult> {
    if (isBankAccount(a) && isBankAccountData(b)) {
      return Observable.fromPromise(this.stripe.createToken(a, b));
    } else if (isPii(a) && isPiiData(b)) {
      return Observable.fromPromise(this.stripe.createToken(a, b));
    } else {
      return Observable.fromPromise(
        this.stripe.createToken(a as Element, b as CardDataOptions | undefined)
      );
    }
  }

  public createSource(
    a: Element | SourceData,
    b?: SourceData | undefined
  ): Observable<SourceResult> {
    if (isSourceData(a)) {
      return Observable.fromPromise(this.stripe.createSource(a as SourceData));
    }
    return Observable.fromPromise(this.stripe.createSource(a as Element, b));
  }

  public retrieveSource(source: SourceParams): Observable<SourceResult> {
    return Observable.fromPromise(this.stripe.retrieveSource(source));
  }
}<commit_msg>impr(service): minor refactor to access stripe object easily<commit_after>import { Injectable, Inject } from '@angular/core';

import { Observable } from 'rxjs/Observable';

import { WindowRef } from './window-ref';
import { LazyStripeAPILoader, Status } from './api-loader.service';

import {
  STRIPE_PUBLISHABLE_KEY,
  StripeJS,
  STRIPE_OPTIONS
} from '../interfaces/stripe';
import { Element } from '../interfaces/element';
import { Elements, ElementsOptions } from '../interfaces/elements';
import {
  SourceData,
  SourceResult,
  isSourceData,
  SourceParams
} from '../interfaces/sources';
import {
  CardDataOptions,
  TokenResult,
  BankAccount,
  BankAccountData,
  PiiData,
  Pii,
  isBankAccount,
  isBankAccountData,
  isPii,
  isPiiData
} from '../interfaces/token';

@Injectable()
export class StripeService {
  private stripe: StripeJS;

  constructor(
    @Inject(STRIPE_PUBLISHABLE_KEY) private key: string,
    @Inject(STRIPE_OPTIONS) private options: string,
    private loader: LazyStripeAPILoader,
    private window: WindowRef
  ) {
    this.stripeObject().subscribe((Stripe: any) => {
      this.stripe = this.options
        ? (Stripe(this.key, this.options) as StripeJS)
        : (Stripe(this.key) as StripeJS);
    });
  }

  public elements(options?: ElementsOptions): Observable<Elements> {
    return this.stripeObject().map(() => this.stripe.elements(options));
  }

  public changeKey(key: string, options?: string): Observable<StripeJS> {
    const obs = this.stripeObject()
      .map((Stripe: any) => {
        this.stripe = options
          ? (Stripe(key, options) as StripeJS)
          : (Stripe(key) as StripeJS);
        return this.stripe;
      })
      .publishLast()
      .refCount();
    obs.subscribe();
    return obs;
  }

  public createToken(
    a: Element | BankAccount | Pii,
    b: CardDataOptions | BankAccountData | PiiData | undefined
  ): Observable<TokenResult> {
    if (isBankAccount(a) && isBankAccountData(b)) {
      return Observable.fromPromise(this.stripe.createToken(a, b));
    } else if (isPii(a) && isPiiData(b)) {
      return Observable.fromPromise(this.stripe.createToken(a, b));
    } else {
      return Observable.fromPromise(
        this.stripe.createToken(a as Element, b as CardDataOptions | undefined)
      );
    }
  }

  public createSource(
    a: Element | SourceData,
    b?: SourceData | undefined
  ): Observable<SourceResult> {
    if (isSourceData(a)) {
      return Observable.fromPromise(this.stripe.createSource(a as SourceData));
    }
    return Observable.fromPromise(this.stripe.createSource(a as Element, b));
  }

  public retrieveSource(source: SourceParams): Observable<SourceResult> {
    return Observable.fromPromise(this.stripe.retrieveSource(source));
  }

  private stripeObject(): Observable<any> {
    return this.loader
      .asStream()
      .filter((status: Status) => status.loaded === true)
      .map(() => (this.window.getNativeWindow() as any).Stripe);
  }
}
{'fraction_non_alphanumeric': 0.12991735537190083, 'fraction_numerical': 0.0, 'mean_word_length': 3.397529069767442, 'pattern_counts': {'":': 0, '<': 14, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6515646', 'n_tokens_mistral': 1951, 'n_tokens_neox': 1902, 'n_words': 408}