{"version":3,"sources":["../src/init.ts","../src/user.ts","../src/utils.ts","../src/session.ts","../src/payment.ts","../src/product.ts","../src/subscription.ts"],"names":["registerVersion","getAuth","getFirestore","doc","collection","addDoc","onSnapshot","toUTCDateString","getDoc","query","where","getDocs","limit","getStatusAsArray"],"mappings":"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","file":"index.cjs","sourcesContent":["/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp, registerVersion } from \"firebase/app\";\n\nregisterVersion(\"firestore-stripe-payments\", \"__VERSION__\");\n\n/**\n * Serves as the main entry point to this library. Initializes the client SDK,\n * and returns a handle object that can be passed into other APIs.\n *\n * @param app - A FirebaseApp instance initialized by the Firebase JS SDK.\n * @param options - Configuration options for the SDK.\n * @returns An instance of the StripePayments class.\n */\nexport function getStripePayments(\n  app: FirebaseApp,\n  options: StripePaymentsOptions\n): StripePayments {\n  return StripePayments.create(app, options);\n}\n\n/**\n * Configuration options that indicate how the Stripe payments extension has been set up.\n */\nexport interface StripePaymentsOptions {\n  customersCollection: string;\n  productsCollection: string;\n}\n\ntype Components = Record<string, unknown>;\n\n/**\n * Holds the configuration and other state information of the SDK. An instance of this class\n * must be passed to almost all the other APIs of this library. Do not directly call the\n * constructor. Use the {@link getStripePayments} function to obtain an instance.\n */\nexport class StripePayments {\n  private readonly components: Components = {};\n\n  private constructor(\n    readonly app: FirebaseApp,\n    private readonly options: StripePaymentsOptions\n  ) {}\n\n  /**\n   * @internal\n   */\n  static create(\n    app: FirebaseApp,\n    options: StripePaymentsOptions\n  ): StripePayments {\n    return new StripePayments(app, options);\n  }\n\n  /**\n   * Name of the customers collection as configured in the extension.\n   */\n  get customersCollection(): string {\n    return this.options.customersCollection;\n  }\n\n  /**\n   * Name of the products collection as configured in the extension.\n   */\n  get productsCollection(): string {\n    return this.options.productsCollection;\n  }\n\n  /**\n   * @internal\n   */\n  getComponent<T>(key: string): T | null {\n    let dao = this.components[key];\n    if (dao) {\n      return dao as T;\n    }\n\n    return null;\n  }\n\n  /**\n   * @internal\n   */\n  setComponent<T>(key: string, dao: T) {\n    this.components[key] = dao;\n  }\n}\n\n/**\n * Union of possible error codes.\n */\nexport type StripePaymentsErrorCode =\n  | \"deadline-exceeded\"\n  | \"not-found\"\n  | \"permission-denied\"\n  | \"unauthenticated\"\n  | \"internal\";\n\n/**\n * An error thrown by this SDK.\n */\nexport class StripePaymentsError extends Error {\n  constructor(\n    readonly code: StripePaymentsErrorCode,\n    readonly message: string,\n    readonly cause?: any\n  ) {\n    super(message);\n  }\n}\n","/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from \"firebase/app\";\nimport { Auth, getAuth } from \"firebase/auth\";\nimport { StripePayments, StripePaymentsError } from \"./init\";\n\n/**\n * Internal API for retrieving the currently signed in user. Rejects with \"unauthenticated\" if\n * the user is not signed in. Exposed for internal use.\n *\n * @internal\n */\nexport function getCurrentUser(payments: StripePayments): Promise<string> {\n  try {\n    const uid: string = getCurrentUserSync(payments);\n    return Promise.resolve(uid);\n  } catch (err: unknown) {\n    return Promise.reject(err);\n  }\n}\n\n/**\n * Internal API for retrieving the currently signed in user. Throws \"unauthenticated\" if\n * the user is not signed in. Exposed for internal use.\n *\n * @internal\n */\nexport function getCurrentUserSync(payments: StripePayments): string {\n  const dao: UserDAO = getOrInitUserDAO(payments);\n  return dao.getCurrentUser();\n}\n\n/**\n * Internal interface for introspecting the current user's login session. Exposed for testing.\n *\n * @internal\n */\nexport interface UserDAO {\n  getCurrentUser(): string;\n}\n\nclass FirebaseAuthUserDAO implements UserDAO {\n  private readonly auth: Auth;\n\n  constructor(app: FirebaseApp) {\n    this.auth = getAuth(app);\n  }\n\n  public getCurrentUser(): string {\n    const currentUser: string | undefined = this.auth.currentUser?.uid;\n    if (!currentUser) {\n      throw new StripePaymentsError(\n        \"unauthenticated\",\n        \"Failed to determine currently signed in user. User not signed in.\"\n      );\n    }\n\n    return currentUser;\n  }\n}\n\nconst USER_DAO_KEY = \"user-dao\" as const;\n\nfunction getOrInitUserDAO(payments: StripePayments): UserDAO {\n  let dao: UserDAO | null = payments.getComponent<UserDAO>(USER_DAO_KEY);\n  if (!dao) {\n    dao = new FirebaseAuthUserDAO(payments.app);\n    setUserDAO(payments, dao);\n  }\n\n  return dao;\n}\n\n/**\n * Internal API for registering a {@link UserDAO} instance with {@link StripePayments}.\n * Exported for testing.\n *\n * @internal\n */\nexport function setUserDAO(payments: StripePayments, dao: UserDAO): void {\n  payments.setComponent(USER_DAO_KEY, dao);\n}\n","/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function checkNonEmptyString(arg: unknown, message?: string): void {\n  if (typeof arg !== \"string\" || arg === \"\") {\n    throw new Error(message ?? \"arg must be a non-empty string.\");\n  }\n}\n\nexport function checkPositiveNumber(arg: unknown, message?: string): void {\n  if (typeof arg !== \"number\" || isNaN(arg) || arg <= 0) {\n    throw new Error(message ?? \"arg must be positive number.\");\n  }\n}\n\nexport function checkNonEmptyArray(arg: unknown, message?: string): void {\n  if (!Array.isArray(arg) || arg.length === 0) {\n    throw new Error(message ?? \"arg must be a non-empty array.\");\n  }\n}\n","/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from \"firebase/app\";\nimport {\n  addDoc,\n  collection,\n  CollectionReference,\n  DocumentData,\n  DocumentReference,\n  DocumentSnapshot,\n  Firestore,\n  FirestoreDataConverter,\n  FirestoreError,\n  getFirestore,\n  onSnapshot,\n  QueryDocumentSnapshot,\n  Timestamp,\n  Unsubscribe,\n} from \"firebase/firestore\";\nimport { StripePayments, StripePaymentsError } from \"./init\";\nimport { getCurrentUser } from \"./user\";\nimport {\n  checkNonEmptyArray,\n  checkNonEmptyString,\n  checkPositiveNumber,\n} from \"./utils\";\n\n/**\n * Parameters common across all session types.\n */\nexport interface CommonSessionCreateParams {\n  /**\n   * Enables user redeemable promotion codes.\n   */\n  allow_promotion_codes?: boolean;\n\n  /**\n   * Set to true to enable automatic taxes. Defaults to false.\n   */\n  automatic_tax?: boolean;\n\n  /**\n   * A unique string to reference the Checkout Session. This can be a customer ID, a cart ID,\n   * or similar, and can be used to reconcile the session with your internal systems.\n   */\n  client_reference_id?: string;\n\n  /**\n   * The URL the customer will be directed to if they decide to cancel payment and return to\n   * your website.\n   */\n  cancel_url?: string;\n\n  /**\n   * Set of key-value pairs that you can attach to an object. This can be useful for storing\n   * additional information about the object in a structured format.\n   */\n  metadata?: { [key: string]: any };\n\n  /**\n   * The mode of the Checkout Session. If not specified defaults to `subscription`.\n   */\n  mode?: \"subscription\" | \"payment\";\n\n  /**\n   * A list of the types of payment methods (e.g., `card`) this Checkout Session can accept.\n   * Defaults to `[\"card\"]`.\n   */\n  payment_method_types?: PaymentMethodType[];\n\n  /**\n   * The promotion code to apply to this Session.\n   */\n  promotion_code?: string;\n\n  /**\n   * The URL to which Stripe should send customers when payment or setup is complete.\n   */\n  success_url?: string;\n\n  /**\n   * Controls tax ID collection settings for the session.\n   */\n  tax_id_collection?: boolean;\n\n  /**\n   * Indicates if a plan’s `trial_period_days` should be applied to the subscription. Defaults\n   * to `true`.\n   */\n  trial_from_plan?: boolean;\n}\n\n/**\n * Supported payment methods.\n */\nexport type PaymentMethodType =\n  | \"card\"\n  | \"acss_debit\"\n  | \"afterpay_clearpay\"\n  | \"alipay\"\n  | \"bacs_debit\"\n  | \"bancontact\"\n  | \"boleto\"\n  | \"eps\"\n  | \"fpx\"\n  | \"giropay\"\n  | \"grabpay\"\n  | \"ideal\"\n  | \"klarna\"\n  | \"oxxo\"\n  | \"p24\"\n  | \"sepa_debit\"\n  | \"sofort\"\n  | \"wechat_pay\";\n\n/**\n * Parameters for createing a session with one or more line items.\n */\nexport interface LineItemSessionCreateParams extends CommonSessionCreateParams {\n  line_items: LineItemParams[];\n}\n\n/**\n * Parameters common across all line item types.\n */\nexport interface CommonLineItemParams {\n  /**\n   * The description for the line item, to be displayed on the Checkout page.\n   */\n  description?: string;\n\n  /**\n   * The quantity of the line item being purchased.\n   */\n  quantity?: number;\n}\n\n/**\n * Parameters for createing a line item with a Stripe price ID.\n */\nexport interface PriceIdLineItemParams extends CommonLineItemParams {\n  /**\n   * The ID of the Stripe price.\n   */\n  price: string;\n}\n\n/**\n * Parameters for creating a new line item.\n */\nexport type LineItemParams = PriceIdLineItemParams;\n\n/**\n * Parameters for createing a session with a Stripe price ID.\n */\nexport interface PriceIdSessionCreateParams extends CommonSessionCreateParams {\n  /**\n   * The ID of the Stripe price.\n   */\n  price: string;\n\n  /**\n   * The quantity of the item being purchased. Defaults to 1.\n   */\n  quantity?: number;\n}\n\n/**\n * Parameters for creating a new session.\n */\nexport type SessionCreateParams =\n  | LineItemSessionCreateParams\n  | PriceIdSessionCreateParams;\n\nfunction hasLineItems(\n  params: SessionCreateParams\n): params is LineItemSessionCreateParams {\n  return \"line_items\" in params;\n}\n\n/**\n * Interface of Stripe checkout session.\n */\nexport interface Session {\n  /**\n   * The URL the customer will be directed to if they decide to cancel payment and return to\n   * your website.\n   */\n  readonly cancel_url: string;\n\n  /**\n   * Time when the session was created as a UTC timestamp.\n   */\n  readonly created_at: string;\n\n  /**\n   * Unique identifier for the session. Used to pass to `redirectToCheckout()` in Stripe.js.\n   */\n  readonly id: string;\n\n  /**\n   * The mode of the Checkout Session.\n   */\n  readonly mode: \"subscription\" | \"payment\";\n\n  /**\n   * The URL to which Stripe should send customers when payment or setup is complete.\n   */\n  readonly success_url: string;\n\n  /**\n   * The URL to the Checkout Session. Redirect the user to this URL to complete the payment.\n   */\n  readonly url: string;\n\n  /**\n   * Enables user redeemable promotion codes.\n   */\n  readonly allow_promotion_codes?: boolean;\n\n  /**\n   * Indicates whether automatic tax is enabled for the session\n   */\n  readonly automatic_tax?: boolean;\n\n  /**\n   * A unique string to reference the Checkout Session. This can be a customer ID, a cart ID,\n   * or similar, and can be used to reconcile the session with your internal systems.\n   */\n  readonly client_reference_id?: string;\n\n  /**\n   * The array of line items purchased with this session. A session is guaranteed to contain either\n   * {@link Session.line_items} or {@link Session.price}.\n   */\n  readonly line_items?: LineItem[];\n\n  /**\n   * Set of key-value pairs that you can attach to an object. This can be useful for storing\n   * additional information about the object in a structured format.\n   */\n  readonly metadata?: { [key: string]: any };\n\n  /**\n   * A list of the types of payment methods (e.g., `card`) this Checkout Session can accept.\n   * Defaults to `[\"card\"]`.\n   */\n  readonly payment_method_types?: PaymentMethodType[];\n\n  /**\n   * The ID of the Stripe price object purchased with this session. A session is guaranteed to\n   * contain either {@link Session.line_items} or {@link Session.price}.\n   */\n  readonly price?: string;\n\n  /**\n   * The promotion code to apply to this Session.\n   */\n  readonly promotion_code?: string;\n\n  /**\n   * The quantity of item purchased. Defaults to 1.\n   */\n  readonly quantity?: number;\n\n  /**\n   * Controls tax ID collection settings for the session.\n   */\n  readonly tax_id_collection?: boolean;\n\n  /**\n   * Indicates if a plan’s `trial_period_days` should be applied to the subscription. Defaults\n   * to `true`.\n   */\n  readonly trial_from_plan?: boolean;\n}\n\n/**\n * Interface of a Stripe line item associated with a checkout session. A line item represents\n * an individual item purchased using the session.\n */\nexport interface LineItem {\n  /**\n   * The amount to be collected per unit of the line item.\n   */\n  amount?: number;\n\n  /**\n   * Three-letter {@link https://www.iso.org/iso-4217-currency-codes.html | ISO currency code},\n   * in lowercase. Must be a {@link https://stripe.com/docs/currencies | supported currency}.\n   */\n  currency?: string;\n\n  /**\n   * The description for the line item, to be displayed on the Checkout page.\n   */\n  description?: string;\n\n  /**\n   * The name for the item to be displayed on the Checkout page.\n   */\n  name?: string;\n\n  /**\n   * The ID of the Stripe price.\n   */\n  price?: string;\n\n  /**\n   * The quantity of the line item being purchased.\n   */\n  quantity?: number;\n}\n\nexport const CREATE_SESSION_TIMEOUT_MILLIS = 30 * 1000;\n\n/**\n * Optional settings for the {@link createCheckoutSession} function.\n */\nexport interface CreateCheckoutSessionOptions {\n  /**\n   * Time to wait (in milliseconds) until the session is created and acknowledged by  Stripe.\n   * If not specified, defaults to {@link CREATE_SESSION_TIMEOUT_MILLIS}.\n   */\n  timeoutMillis?: number;\n}\n\n/**\n * Creates a new Stripe checkout session with the given parameters. Returned session contains a\n * session ID and a session URL that can be used to redirect the user to complete the checkout.\n * User must be currently signed in with Firebase Auth to call this API. If a timeout occurs\n * while waiting for the session to be created and acknowledged by Stripe, rejects with a\n * `deadline-exceeded` error. Default timeout duration is {@link CREATE_SESSION_TIMEOUT_MILLIS}.\n *\n * @param payments - A valid {@link StripePayments} object.\n * @param params - Parameters of the checkout session.\n * @param options - Optional settings to customize the behavior.\n * @returns Resolves with the created Stripe Session object.\n */\nexport function createCheckoutSession(\n  payments: StripePayments,\n  params: SessionCreateParams,\n  options?: CreateCheckoutSessionOptions\n): Promise<Session> {\n  params = { ...params };\n  checkAndUpdateCommonParams(params);\n  if (hasLineItems(params)) {\n    checkLineItemParams(params);\n  } else {\n    checkPriceIdParams(params);\n  }\n\n  const timeoutMillis: number = getTimeoutMillis(options?.timeoutMillis);\n  return getCurrentUser(payments).then((uid: string) => {\n    const dao: SessionDAO = getOrInitSessionDAO(payments);\n    return dao.createCheckoutSession(uid, params, timeoutMillis);\n  });\n}\n\nfunction checkAndUpdateCommonParams(params: SessionCreateParams): void {\n  if (typeof params.cancel_url !== \"undefined\") {\n    checkNonEmptyString(\n      params.cancel_url,\n      \"cancel_url must be a non-empty string.\"\n    );\n  } else {\n    params.cancel_url = window.location.href;\n  }\n\n  params.mode ??= \"subscription\";\n  if (typeof params.success_url !== \"undefined\") {\n    checkNonEmptyString(\n      params.success_url,\n      \"success_url must be a non-empty string.\"\n    );\n  } else {\n    params.success_url = window.location.href;\n  }\n}\n\nfunction checkLineItemParams(params: LineItemSessionCreateParams): void {\n  checkNonEmptyArray(\n    params.line_items,\n    \"line_items must be a non-empty array.\"\n  );\n}\n\nfunction checkPriceIdParams(params: PriceIdSessionCreateParams): void {\n  checkNonEmptyString(params.price, \"price must be a non-empty string.\");\n  if (typeof params.quantity !== \"undefined\") {\n    checkPositiveNumber(\n      params.quantity,\n      \"quantity must be a positive integer.\"\n    );\n  }\n}\n\nfunction getTimeoutMillis(timeoutMillis: number | undefined): number {\n  if (typeof timeoutMillis !== \"undefined\") {\n    checkPositiveNumber(\n      timeoutMillis,\n      \"timeoutMillis must be a positive number.\"\n    );\n    return timeoutMillis;\n  }\n\n  return CREATE_SESSION_TIMEOUT_MILLIS;\n}\n\n/**\n * Internal interface for all database interactions pertaining to Stripe sessions. Exported\n * for testing.\n *\n * @internal\n */\nexport interface SessionDAO {\n  createCheckoutSession(\n    uid: string,\n    params: SessionCreateParams,\n    timeoutMillis: number\n  ): Promise<Session>;\n}\n\nclass FirestoreSessionDAO implements SessionDAO {\n  private readonly firestore: Firestore;\n\n  constructor(app: FirebaseApp, private readonly customersCollection: string) {\n    this.firestore = getFirestore(app);\n  }\n\n  public async createCheckoutSession(\n    uid: string,\n    params: SessionCreateParams,\n    timeoutMillis: number\n  ): Promise<Session> {\n    const doc: DocumentReference = await this.addSessionDoc(uid, params);\n    return this.waitForSessionId(doc, timeoutMillis);\n  }\n\n  private async addSessionDoc(\n    uid: string,\n    params: SessionCreateParams\n  ): Promise<DocumentReference> {\n    const sessions: CollectionReference = collection(\n      this.firestore,\n      this.customersCollection,\n      uid,\n      \"checkout_sessions\"\n    );\n    try {\n      return await addDoc(sessions, params);\n    } catch (err) {\n      throw new StripePaymentsError(\n        \"internal\",\n        \"Error while querying Firestore.\",\n        err\n      );\n    }\n  }\n\n  private waitForSessionId(\n    doc: DocumentReference,\n    timeoutMillis: number\n  ): Promise<Session> {\n    let cancel: Unsubscribe;\n    return new Promise<Session>((resolve, reject) => {\n      const timeout: ReturnType<typeof setTimeout> = setTimeout(() => {\n        reject(\n          new StripePaymentsError(\n            \"deadline-exceeded\",\n            \"Timeout while waiting for session response.\"\n          )\n        );\n      }, timeoutMillis);\n      cancel = onSnapshot(\n        doc.withConverter(SESSION_CONVERTER),\n        (snap: DocumentSnapshot<PartialSession>) => {\n          const session: PartialSession | undefined = snap.data();\n          if (hasSessionId(session)) {\n            clearTimeout(timeout);\n            resolve(session);\n          }\n        },\n        (err: FirestoreError) => {\n          clearTimeout(timeout);\n          reject(\n            new StripePaymentsError(\n              \"internal\",\n              \"Error while querying Firestore.\",\n              err\n            )\n          );\n        }\n      );\n    }).finally(() => cancel());\n  }\n}\n\ntype PartialSession = Partial<Session>;\n\nfunction hasSessionId(session: PartialSession | undefined): session is Session {\n  return typeof session?.id !== \"undefined\";\n}\n\nconst SESSION_CONVERTER: FirestoreDataConverter<PartialSession> = {\n  toFirestore: (): DocumentData => {\n    throw new Error(\"Not implemented for readonly Session type.\");\n  },\n  fromFirestore: (snapshot: QueryDocumentSnapshot): PartialSession => {\n    const { created, sessionId, ...rest } = snapshot.data();\n    if (typeof sessionId !== \"undefined\") {\n      return {\n        ...(rest as Session),\n        id: sessionId,\n        created_at: toUTCDateString(created),\n      };\n    }\n\n    return { ...(rest as Session) };\n  },\n};\n\nfunction toUTCDateString(timestamp: Timestamp): string {\n  return timestamp.toDate().toUTCString();\n}\n\nconst SESSION_DAO_KEY = \"checkout-session-dao\" as const;\n\nfunction getOrInitSessionDAO(payments: StripePayments): SessionDAO {\n  let dao: SessionDAO | null =\n    payments.getComponent<SessionDAO>(SESSION_DAO_KEY);\n  if (!dao) {\n    dao = new FirestoreSessionDAO(payments.app, payments.customersCollection);\n    setSessionDAO(payments, dao);\n  }\n\n  return dao;\n}\n\n/**\n * Internal API for registering a {@link SessionDAO} instance with {@link StripePayments}.\n * Exported for testing.\n *\n * @internal\n */\nexport function setSessionDAO(payments: StripePayments, dao: SessionDAO): void {\n  payments.setComponent(SESSION_DAO_KEY, dao);\n}\n","/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from \"firebase/app\";\nimport {\n  collection,\n  CollectionReference,\n  doc,\n  DocumentChange,\n  DocumentData,\n  DocumentReference,\n  DocumentSnapshot,\n  Firestore,\n  FirestoreDataConverter,\n  FirestoreError,\n  getDoc,\n  getDocs,\n  getFirestore,\n  onSnapshot,\n  query,\n  Query,\n  QueryDocumentSnapshot,\n  QuerySnapshot,\n  where,\n} from \"firebase/firestore\";\nimport { StripePayments, StripePaymentsError } from \"./init\";\nimport { getCurrentUser, getCurrentUserSync } from \"./user\";\nimport { checkNonEmptyArray, checkNonEmptyString } from \"./utils\";\n\n/**\n * Interface of a Stripe payment stored in the app database.\n */\nexport interface Payment {\n  /**\n   * Amount intended to be collected by this payment. A positive integer representing how much\n   * to charge in the smallest currency unit (e.g., 100 cents to charge $1.00 or 100 to charge\n   * ¥100, a zero-decimal currency). The minimum amount is $0.50 US or equivalent in charge\n   * currency. The amount value supports up to eight digits (e.g., a value of 99999999 for a\n   * USD charge of $999,999.99).\n   */\n  readonly amount: number;\n\n  /**\n   * Amount that can be captured from this payment.\n   */\n  readonly amount_capturable: number;\n\n  /**\n   * Amount that was collected by this payment.\n   */\n  readonly amount_received: number;\n\n  /**\n   * The date when the payment was created as a UTC timestamp.\n   */\n  readonly created: string;\n\n  /**\n   * Three-letter ISO currency code, in lowercase. Must be a supported currency.\n   */\n  readonly currency: string;\n\n  /**\n   * ID of the Customer this payment belongs to, if one exists. Payment methods attached\n   * to other Customers cannot be used with this payment.\n   */\n  readonly customer: string | null;\n\n  /**\n   * An arbitrary string attached to the object. Often useful for displaying to users.\n   */\n  readonly description: string | null;\n\n  /**\n   * Unique Stripe payment ID.\n   */\n  readonly id: string;\n\n  /**\n   * ID of the invoice that created this payment, if it exists.\n   */\n  readonly invoice: string | null;\n\n  /**\n   * Set of key-value pairs that you can attach to an object. This can be useful for storing\n   * additional information about the object in a structured format.\n   */\n  readonly metadata: { [name: string]: string };\n\n  /**\n   * The list of payment method types (e.g. card) that this payment is allowed to use.\n   */\n  readonly payment_method_types: string[];\n\n  /**\n   * Array of product ID and price ID pairs.\n   */\n  readonly prices: Array<{ product: string; price: string }>;\n\n  /**\n   * Status of this payment.\n   */\n  readonly status: PaymentStatus;\n\n  /**\n   * Firebase Auth UID of the user that created the payment.\n   */\n  readonly uid: string;\n\n  readonly [propName: string]: any;\n}\n\n/**\n * Possible states a payment can be in.\n */\nexport type PaymentStatus =\n  | \"requires_payment_method\"\n  | \"requires_confirmation\"\n  | \"requires_action\"\n  | \"processing\"\n  | \"requires_capture\"\n  | \"cancelled\"\n  | \"succeeded\";\n\n/**\n * Retrieves an existing Stripe payment for the currently signed in user from the database.\n *\n * @param payments - A valid {@link StripePayments} object.\n * @param subscriptionId - ID of the payment to retrieve.\n * @returns Resolves with a Payment object if found. Rejects if the specified payment ID\n *  does not exist, or if the user is not signed in.\n */\nexport function getCurrentUserPayment(\n  payments: StripePayments,\n  paymentId: string\n): Promise<Payment> {\n  checkNonEmptyString(paymentId, \"paymentId must be a non-empty string.\");\n  return getCurrentUser(payments).then((uid: string) => {\n    const dao: PaymentDAO = getOrInitPaymentDAO(payments);\n    return dao.getPayment(uid, paymentId);\n  });\n}\n\n/**\n * Optional parameters for the {@link getCurrentUserPayments} function.\n */\nexport interface GetPaymentsOptions {\n  /**\n   * Specify one or more payment status values to retrieve. When set only the payments\n   * with the given status are returned.\n   */\n  status?: PaymentStatus | PaymentStatus[];\n}\n\nexport function getCurrentUserPayments(\n  payments: StripePayments,\n  options?: GetPaymentsOptions\n): Promise<Payment[]> {\n  const queryOptions: { status?: PaymentStatus[] } = {};\n  if (typeof options?.status !== \"undefined\") {\n    queryOptions.status = getStatusAsArray(options.status);\n  }\n\n  return getCurrentUser(payments).then((uid: string) => {\n    const dao: PaymentDAO = getOrInitPaymentDAO(payments);\n    return dao.getPayments(uid, queryOptions);\n  });\n}\n\n/**\n * Different types of changes that may occur on a payment object.\n */\nexport type PaymentChangeType = \"added\" | \"modified\" | \"removed\";\n\n/**\n * Represents the current state of a set of payments owned by a user.\n */\nexport interface PaymentSnapshot {\n  /**\n   * A list of all currently available payments ordered by the payment ID. Empty\n   * if no payments are available.\n   */\n  payments: Payment[];\n\n  /**\n   * The list of changes in the payments since the last snapshot.\n   */\n  changes: Array<{\n    type: PaymentChangeType;\n    payment: Payment;\n  }>;\n\n  /**\n   * Number of currently available payments. This is same as the length of the\n   * `payments` array in the snapshot.\n   */\n  size: number;\n\n  /**\n   * True if there are no payments available. False whenever at least one payment is\n   * present. When True, the `payments` array is empty, and the `size` is 0.\n   */\n  empty: boolean;\n}\n\n/**\n * Registers a listener to receive payment update events for the currently signed in\n * user. If the user is not signed in throws an `unauthenticated` error, and no listener is\n * registered.\n *\n * Upon successful registration, the `onUpdate` callback will fire once with\n * the current state of all the payments. From then onwards, each update to a payment\n * will fire the `onUpdate` callback with the latest state of the payments.\n *\n * @param payments - A valid {@link StripePayments} object.\n * @param onUpdate - A callback that will fire whenever the current user's payments\n *   are updated.\n * @param onError - A callback that will fire whenever an error occurs while listening to\n *   payment updates.\n * @returns A function that can be called to cancel and unregister the listener.\n */\nexport function onCurrentUserPaymentUpdate(\n  payments: StripePayments,\n  onUpdate: (snapshot: PaymentSnapshot) => void,\n  onError?: (error: StripePaymentsError) => void\n): () => void {\n  const uid: string = getCurrentUserSync(payments);\n  const dao: PaymentDAO = getOrInitPaymentDAO(payments);\n  return dao.onPaymentUpdate(uid, onUpdate, onError);\n}\n\nfunction getStatusAsArray(\n  status: PaymentStatus | PaymentStatus[]\n): PaymentStatus[] {\n  if (typeof status === \"string\") {\n    return [status];\n  }\n\n  checkNonEmptyArray(status, \"status must be a non-empty array.\");\n  return status;\n}\n\n/**\n * Internal interface for all database interactions pertaining to Stripe payments. Exported\n * for testing.\n *\n * @internal\n */\nexport interface PaymentDAO {\n  getPayment(uid: string, paymentId: string): Promise<Payment>;\n  getPayments(\n    uid: string,\n    options?: { status?: PaymentStatus[] }\n  ): Promise<Payment[]>;\n  onPaymentUpdate(\n    uid: string,\n    onUpdate: (snapshot: PaymentSnapshot) => void,\n    onError?: (error: StripePaymentsError) => void\n  ): () => void;\n}\n\nconst PAYMENT_CONVERTER: FirestoreDataConverter<Payment> = {\n  toFirestore: () => {\n    throw new Error(\"Not implemented for readonly Payment type.\");\n  },\n  fromFirestore: (snapshot: QueryDocumentSnapshot): Payment => {\n    const data: DocumentData = snapshot.data();\n    const refs: DocumentReference[] = data.prices;\n    const prices: Array<{ product: string; price: string }> = refs.map(\n      (priceRef: DocumentReference) => {\n        return {\n          product: priceRef.parent.parent!.id,\n          price: priceRef.id,\n        };\n      }\n    );\n\n    return {\n      amount: data.amount,\n      amount_capturable: data.amount_capturable,\n      amount_received: data.amount_received,\n      created: toUTCDateString(data.created),\n      currency: data.currency,\n      customer: data.customer,\n      description: data.description,\n      id: snapshot.id,\n      invoice: data.invoice,\n      metadata: data.metadata ?? {},\n      payment_method_types: data.payment_method_types,\n      prices,\n      status: data.status,\n      uid: snapshot.ref.parent.parent!.id,\n    };\n  },\n};\n\nfunction toUTCDateString(seconds: number): string {\n  const date = new Date(seconds * 1000);\n  return date.toUTCString();\n}\n\nconst PAYMENTS_COLLECTION = \"payments\" as const;\n\nclass FirestorePaymentDAO implements PaymentDAO {\n  private readonly firestore: Firestore;\n\n  constructor(app: FirebaseApp, private readonly customersCollection: string) {\n    this.firestore = getFirestore(app);\n  }\n\n  public async getPayment(uid: string, paymentId: string): Promise<Payment> {\n    const snap: QueryDocumentSnapshot<Payment> =\n      await this.getPaymentSnapshotIfExists(uid, paymentId);\n    return snap.data();\n  }\n\n  public async getPayments(\n    uid: string,\n    options?: { status?: PaymentStatus[] }\n  ): Promise<Payment[]> {\n    const querySnap: QuerySnapshot<Payment> = await this.getPaymentSnapshots(\n      uid,\n      options?.status\n    );\n    const payments: Payment[] = [];\n    querySnap.forEach((snap: QueryDocumentSnapshot<Payment>) => {\n      payments.push(snap.data());\n    });\n\n    return payments;\n  }\n\n  public onPaymentUpdate(\n    uid: string,\n    onUpdate: (snapshot: PaymentSnapshot) => void,\n    onError?: (error: StripePaymentsError) => void\n  ): () => void {\n    const payments: CollectionReference<Payment> = collection(\n      this.firestore,\n      this.customersCollection,\n      uid,\n      PAYMENTS_COLLECTION\n    ).withConverter(PAYMENT_CONVERTER);\n    return onSnapshot(\n      payments,\n      (querySnap: QuerySnapshot<Payment>) => {\n        const snapshot: PaymentSnapshot = {\n          payments: [],\n          changes: [],\n          size: querySnap.size,\n          empty: querySnap.empty,\n        };\n        querySnap.forEach((snap: QueryDocumentSnapshot<Payment>) => {\n          snapshot.payments.push(snap.data());\n        });\n        querySnap.docChanges().forEach((change: DocumentChange<Payment>) => {\n          snapshot.changes.push({\n            type: change.type,\n            payment: change.doc.data(),\n          });\n        });\n\n        onUpdate(snapshot);\n      },\n      (err: FirestoreError) => {\n        if (onError) {\n          const arg: StripePaymentsError = new StripePaymentsError(\n            \"internal\",\n            `Error while listening to database updates: ${err.message}`,\n            err\n          );\n          onError(arg);\n        }\n      }\n    );\n  }\n\n  private async getPaymentSnapshotIfExists(\n    uid: string,\n    paymentId: string\n  ): Promise<QueryDocumentSnapshot<Payment>> {\n    const paymentRef: DocumentReference<Payment> = doc(\n      this.firestore,\n      this.customersCollection,\n      uid,\n      PAYMENTS_COLLECTION,\n      paymentId\n    ).withConverter(PAYMENT_CONVERTER);\n    const snapshot: DocumentSnapshot<Payment> = await this.queryFirestore(() =>\n      getDoc(paymentRef)\n    );\n    if (!snapshot.exists()) {\n      throw new StripePaymentsError(\n        \"not-found\",\n        `No payment found with the ID: ${paymentId} for user: ${uid}`\n      );\n    }\n\n    return snapshot;\n  }\n\n  private async getPaymentSnapshots(\n    uid: string,\n    status?: PaymentStatus[]\n  ): Promise<QuerySnapshot<Payment>> {\n    let paymentsQuery: Query<Payment> = collection(\n      this.firestore,\n      this.customersCollection,\n      uid,\n      PAYMENTS_COLLECTION\n    ).withConverter(PAYMENT_CONVERTER);\n    if (status) {\n      paymentsQuery = query(paymentsQuery, where(\"status\", \"in\", status));\n    }\n\n    return await this.queryFirestore(() => getDocs(paymentsQuery));\n  }\n\n  private async queryFirestore<T>(fn: () => Promise<T>): Promise<T> {\n    try {\n      return await fn();\n    } catch (error) {\n      throw new StripePaymentsError(\n        \"internal\",\n        \"Unexpected error while querying Firestore\",\n        error\n      );\n    }\n  }\n}\n\nconst PAYMENT_DAO_KEY = \"payment-dao\" as const;\n\nfunction getOrInitPaymentDAO(payments: StripePayments): PaymentDAO {\n  let dao: PaymentDAO | null =\n    payments.getComponent<PaymentDAO>(PAYMENT_DAO_KEY);\n  if (!dao) {\n    dao = new FirestorePaymentDAO(payments.app, payments.customersCollection);\n    setPaymentDAO(payments, dao);\n  }\n\n  return dao;\n}\n\n/**\n * Internal API for registering a {@link PaymentDAO} instance with {@link StripePayments}.\n * Exported for testing.\n *\n * @internal\n */\nexport function setPaymentDAO(payments: StripePayments, dao: PaymentDAO): void {\n  payments.setComponent(PAYMENT_DAO_KEY, dao);\n}\n","/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from \"firebase/app\";\nimport {\n  collection,\n  CollectionReference,\n  doc,\n  DocumentData,\n  DocumentReference,\n  DocumentSnapshot,\n  Firestore,\n  FirestoreDataConverter,\n  getDoc,\n  getDocs,\n  getFirestore,\n  limit,\n  query,\n  Query,\n  QueryConstraint,\n  QueryDocumentSnapshot,\n  QuerySnapshot,\n  where,\n  type WhereFilterOp,\n} from \"firebase/firestore\";\nimport { StripePayments, StripePaymentsError } from \"./init\";\nimport { checkNonEmptyString } from \"./utils\";\n\n/**\n * Interface of a Stripe Product stored in the app database.\n */\nexport interface Product {\n  /**\n   * Unique Stripe product ID.\n   */\n  readonly id: string;\n\n  /**\n   * Whether the product is currently available for purchase.\n   */\n  readonly active: boolean;\n\n  /**\n   * The product's name, meant to be displayable to the customer. Whenever this product is sold\n   * via a subscription, name will show up on associated invoice line item descriptions.\n   */\n  readonly name: string;\n\n  /**\n   * The product's description, meant to be displayable to the customer. Use this field to\n   * optionally store a long form explanation of the product being sold for your own\n   * rendering purposes.\n   */\n  readonly description: string | null;\n\n  /**\n   * The Firebase role that will be assigned to the user if they are subscribed to this plan.\n   */\n  readonly role: string | null;\n\n  /**\n   * A list of up to 8 URLs of images for this product, meant to be displayable to the customer.\n   */\n  readonly images: string[];\n\n  /**\n   * A list of Prices for this billing product. Only populated if explicitly requested\n   * during retrieval.\n   */\n  readonly prices: Price[];\n\n  /**\n   * A collection of additional product metadata.\n   */\n  readonly metadata: { [key: string]: string | number | null };\n\n  readonly [propName: string]: any;\n}\n\n/**\n * Interface of a Stripe Price object stored in the app database.\n */\nexport interface Price {\n  /**\n   * Unique Stripe price ID.\n   */\n  readonly id: string;\n\n  /**\n   * ID of the Stripe product to which this price is related.\n   */\n  readonly product: string;\n\n  /**\n   * Whether the price can be used for new purchases.\n   */\n  readonly active: boolean;\n\n  /**\n   * Three-letter ISO currency code.\n   */\n  readonly currency: string;\n\n  /**\n   * The unit amount in cents to be charged, represented as a whole integer if possible.\n   */\n  readonly unit_amount: number | null;\n\n  /**\n   * A brief description of the price.\n   */\n  readonly description: string | null;\n\n  /**\n   * One of `one_time` or `recurring` depending on whether the price is for a one-time purchase\n   * or a recurring (subscription) purchase.\n   */\n  readonly type: \"one_time\" | \"recurring\";\n\n  /**\n   * The frequency at which a subscription is billed. One of `day`, `week`, `month` or `year`.\n   */\n  readonly interval: \"day\" | \"month\" | \"week\" | \"year\" | null;\n\n  /**\n   * The number of intervals (specified in the {@link Price.interval} attribute) between\n   * subscription billings. For example, `interval=month` and `interval_count=3` bills every\n   * 3 months.\n   */\n  readonly interval_count: number | null;\n\n  /**\n   * Default number of trial days when subscribing a customer to this price using\n   * {@link https://stripe.com/docs/api#create_subscription-trial_from_plan | trial_from_plan}.\n   */\n  readonly trial_period_days: number | null;\n\n  readonly [propName: string]: any;\n}\n\n/**\n * Optional parameters for the {@link getProduct} function.\n */\nexport interface GetProductOptions {\n  /**\n   * Set to `true` to retrieve the prices along with a product. If not set, the product is\n   * returned with no prices (i.e. {@link Product.prices} field will be empty).\n   */\n  includePrices?: boolean;\n}\n\n/**\n * Retrieves a Stripe product from the database.\n *\n * @param payments - A valid {@link StripePayments} object.\n * @param productId - ID of the product to retrieve.\n * @param options - A set of options to customize the behavior.\n * @returns Resolves with a Stripe Product object if found. Rejects if the specified product ID\n *  does not exist.\n */\nexport function getProduct(\n  payments: StripePayments,\n  productId: string,\n  options?: GetProductOptions\n): Promise<Product> {\n  checkNonEmptyString(productId, \"productId must be a non-empty string.\");\n  const dao: ProductDAO = getOrInitProductDAO(payments);\n  return dao.getProduct(productId).then((product: Product) => {\n    if (options?.includePrices) {\n      return getProductWithPrices(dao, product);\n    }\n\n    return product;\n  });\n}\n\n/**\n * Optional parameters for the {@link getProducts} function.\n */\nexport interface GetProductsOptions {\n  /**\n   * Set to `true` to retrieve only the currently active set of Stripe products. If not set,\n   * returns all available products. When set, the effect is same as if called with the filter\n   * `[\"active\", \"==\", true]`.\n   */\n  activeOnly?: boolean;\n\n  /**\n   * An array of optoinal filters that will be applied when querying the products from the app\n   * database.\n   */\n  where?: WhereFilter[];\n\n  /**\n   * Set to `true` to retrieve the prices along with a product. If not set, the product is\n   * returned with no prices (i.e. {@link Product.prices} field will be empty).\n   */\n  includePrices?: boolean;\n\n  /**\n   * Maximum number of products to return.\n   */\n  limit?: number;\n}\n\nexport type { WhereFilterOp } from \"firebase/firestore\";\n\n/**\n * A filter constraint that can be applied to database queries. Consists of a field name (in\n * Firestore dotted notation), a Firestore filter operator, and a value.\n */\nexport type WhereFilter = [string, WhereFilterOp, any];\n\n/**\n * Retrieves a Stripe product from the database.\n *\n * @param payments - A valid {@link StripePayments} object.\n * @param productId - ID of the product to retrieve.\n * @param options - A set of options to customize the behavior.\n * @returns Resolves with an array of Stripe Product objects. May be empty.\n */\nexport function getProducts(\n  payments: StripePayments,\n  options?: GetProductsOptions\n): Promise<Product[]> {\n  const dao: ProductDAO = getOrInitProductDAO(payments);\n  const { includePrices, ...rest } = options ?? {};\n  return dao.getProducts(rest).then((products: Product[]) => {\n    if (includePrices) {\n      const productsWithPrices: Promise<Product>[] = products.map(\n        (product: Product) => getProductWithPrices(dao, product)\n      );\n      return Promise.all(productsWithPrices);\n    }\n\n    return products;\n  });\n}\n\nasync function getProductWithPrices(\n  dao: ProductDAO,\n  product: Product\n): Promise<Product> {\n  const prices: Price[] = await dao.getPrices(product.id);\n  return { ...product, prices };\n}\n\n/**\n * Retrieves a Stripe price from the database.\n *\n * @param payments - A valid {@link StripePayments} object.\n * @param productId - ID of the product to which the price belongs.\n * @param priceId - ID of the price to retrieve.\n * @returns Resolves with a Stripe Price object if found. Rejects if the specified\n *   product ID or the price ID does not exist.\n */\nexport function getPrice(\n  payments: StripePayments,\n  productId: string,\n  priceId: string\n): Promise<Price> {\n  checkNonEmptyString(productId, \"productId must be a non-empty string.\");\n  checkNonEmptyString(priceId, \"priceId must be a non-empty string.\");\n  const dao: ProductDAO = getOrInitProductDAO(payments);\n  return dao.getPrice(productId, priceId);\n}\n\n/**\n * Retrieves all Stripe prices associated with the specified product.\n *\n * @param payments - A valid {@link StripePayments} object.\n * @param productId - ID of the product to which the prices belong.\n * @returns Resolves with an array of Stripe Price objects. Rejects if the specified\n *   product ID does not exist. If the product exists, but doesn't have any prices, resolves\n *   with the empty array.\n */\nexport function getPrices(\n  payments: StripePayments,\n  productId: string\n): Promise<Price[]> {\n  checkNonEmptyString(productId, \"productId must be a non-empty string.\");\n  const dao: ProductDAO = getOrInitProductDAO(payments);\n  return dao.getPrices(productId, { assertProduct: true });\n}\n\n/**\n * Internal interface for all database interactions pertaining to Stripe products. Exported\n * for testing.\n *\n * @internal\n */\nexport interface ProductDAO {\n  getProduct(productId: string): Promise<Product>;\n  getProducts(options?: {\n    activeOnly?: boolean;\n    where?: WhereFilter[];\n    limit?: number;\n  }): Promise<Product[]>;\n  getPrice(productId: string, priceId: string): Promise<Price>;\n  getPrices(\n    productId: string,\n    options?: { assertProduct?: boolean }\n  ): Promise<Price[]>;\n}\n\nconst PRODUCT_CONVERTER: FirestoreDataConverter<Product> = {\n  toFirestore: () => {\n    throw new Error(\"Not implemented for readonly Product type.\");\n  },\n  fromFirestore: (snapshot: QueryDocumentSnapshot): Product => {\n    return {\n      ...(snapshot.data() as Product),\n      id: snapshot.id,\n      prices: [],\n    };\n  },\n};\n\nconst PRICE_CONVERTER: FirestoreDataConverter<Price> = {\n  toFirestore: () => {\n    throw new Error(\"Not implemented for readonly Price type.\");\n  },\n  fromFirestore: (snapshot: QueryDocumentSnapshot): Price => {\n    const data: DocumentData = snapshot.data();\n    return {\n      ...(data as Price),\n      id: snapshot.id,\n      product: snapshot.ref.parent.parent!.id,\n    };\n  },\n};\n\nclass FirestoreProductDAO implements ProductDAO {\n  private readonly firestore: Firestore;\n\n  constructor(app: FirebaseApp, private readonly productsCollection: string) {\n    this.firestore = getFirestore(app);\n  }\n\n  public async getProduct(productId: string): Promise<Product> {\n    const snap: QueryDocumentSnapshot<Product> =\n      await this.getProductSnapshotIfExists(productId);\n    return snap.data();\n  }\n\n  public async getProducts(options?: {\n    activeOnly?: boolean;\n    where?: WhereFilter[];\n    limit?: number;\n  }): Promise<Product[]> {\n    const querySnap: QuerySnapshot<Product> = await this.getProductSnapshots(\n      options\n    );\n    const products: Product[] = [];\n    querySnap.forEach((snap: QueryDocumentSnapshot<Product>) => {\n      products.push(snap.data());\n    });\n\n    return products;\n  }\n\n  public async getPrice(productId: string, priceId: string): Promise<Price> {\n    const snap: QueryDocumentSnapshot<Price> =\n      await this.getPriceSnapshotIfExists(productId, priceId);\n    return snap.data();\n  }\n\n  public async getPrices(\n    productId: string,\n    options?: { assertProduct?: boolean | undefined }\n  ): Promise<Price[]> {\n    if (options?.assertProduct) {\n      await this.getProductSnapshotIfExists(productId);\n    }\n\n    const querySnap: QuerySnapshot<Price> = await this.getPriceSnapshots(\n      productId\n    );\n    const prices: Price[] = [];\n    querySnap.forEach((snap: QueryDocumentSnapshot<Price>) => {\n      prices.push(snap.data());\n    });\n\n    return prices;\n  }\n\n  private async getProductSnapshotIfExists(\n    productId: string\n  ): Promise<QueryDocumentSnapshot<Product>> {\n    const productRef: DocumentReference<Product> = doc(\n      this.firestore,\n      this.productsCollection,\n      productId\n    ).withConverter(PRODUCT_CONVERTER);\n    const snapshot: DocumentSnapshot<Product> = await this.queryFirestore(() =>\n      getDoc(productRef)\n    );\n    if (!snapshot.exists()) {\n      throw new StripePaymentsError(\n        \"not-found\",\n        `No product found with the ID: ${productId}`\n      );\n    }\n\n    return snapshot;\n  }\n\n  private async getProductSnapshots(options?: {\n    activeOnly?: boolean;\n    where?: WhereFilter[];\n    limit?: number;\n  }): Promise<QuerySnapshot<Product>> {\n    let productsQuery: Query<Product> = collection(\n      this.firestore,\n      this.productsCollection\n    ).withConverter(PRODUCT_CONVERTER);\n    const constraints: QueryConstraint[] = [];\n    if (options?.activeOnly) {\n      constraints.push(where(\"active\", \"==\", true));\n    }\n\n    if (options?.where) {\n      for (const filter of options.where) {\n        constraints.push(where(...filter));\n      }\n    }\n\n    if (typeof options?.limit !== \"undefined\") {\n      constraints.push(limit(options.limit));\n    }\n\n    return await this.queryFirestore(() => {\n      if (constraints.length > 0) {\n        productsQuery = query(productsQuery, ...constraints);\n      }\n\n      return getDocs(productsQuery);\n    });\n  }\n\n  private async getPriceSnapshotIfExists(\n    productId: string,\n    priceId: string\n  ): Promise<QueryDocumentSnapshot<Price>> {\n    const priceRef: DocumentReference<Price> = doc(\n      this.firestore,\n      this.productsCollection,\n      productId,\n      \"prices\",\n      priceId\n    ).withConverter(PRICE_CONVERTER);\n    const snapshot: DocumentSnapshot<Price> = await this.queryFirestore(() =>\n      getDoc(priceRef)\n    );\n    if (!snapshot.exists()) {\n      throw new StripePaymentsError(\n        \"not-found\",\n        `No price found with the product ID: ${productId} and price ID: ${priceId}`\n      );\n    }\n\n    return snapshot;\n  }\n\n  private async getPriceSnapshots(\n    productId: string\n  ): Promise<QuerySnapshot<Price>> {\n    const pricesCollection: CollectionReference<Price> = collection(\n      this.firestore,\n      this.productsCollection,\n      productId,\n      \"prices\"\n    ).withConverter(PRICE_CONVERTER);\n    return await this.queryFirestore(() => getDocs(pricesCollection));\n  }\n\n  private async queryFirestore<T>(fn: () => Promise<T>): Promise<T> {\n    try {\n      return await fn();\n    } catch (error) {\n      throw new StripePaymentsError(\n        \"internal\",\n        \"Unexpected error while querying Firestore\",\n        error\n      );\n    }\n  }\n}\n\nconst PRODUCT_DAO_KEY = \"product-dao\" as const;\n\nfunction getOrInitProductDAO(payments: StripePayments): ProductDAO {\n  let dao: ProductDAO | null =\n    payments.getComponent<ProductDAO>(PRODUCT_DAO_KEY);\n  if (!dao) {\n    dao = new FirestoreProductDAO(payments.app, payments.productsCollection);\n    setProductDAO(payments, dao);\n  }\n\n  return dao;\n}\n\n/**\n * Internal API for registering a {@link ProductDAO} instance with {@link StripePayments}. Exported\n * for testing.\n *\n * @internal\n */\nexport function setProductDAO(payments: StripePayments, dao: ProductDAO): void {\n  payments.setComponent(PRODUCT_DAO_KEY, dao);\n}\n","/*\n * Copyright 2021 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *    https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from \"firebase/app\";\nimport {\n  collection,\n  CollectionReference,\n  doc,\n  DocumentChange,\n  DocumentData,\n  DocumentReference,\n  DocumentSnapshot,\n  Firestore,\n  FirestoreDataConverter,\n  FirestoreError,\n  getDoc,\n  getDocs,\n  getFirestore,\n  onSnapshot,\n  query,\n  Query,\n  QueryDocumentSnapshot,\n  QuerySnapshot,\n  Timestamp,\n  where,\n} from \"firebase/firestore\";\nimport { StripePayments, StripePaymentsError } from \"./init\";\nimport { getCurrentUser, getCurrentUserSync } from \"./user\";\nimport { checkNonEmptyArray, checkNonEmptyString } from \"./utils\";\n\n/**\n * Interface of a Stripe Subscription stored in the app database.\n */\nexport interface Subscription {\n  /**\n   * A future date in UTC format at which the subscription will automatically get canceled.\n   */\n  readonly cancel_at: string | null;\n\n  /**\n   * If `true`, the subscription has been canceled by the user and will be deleted at the end\n   * of the billing period.\n   */\n  readonly cancel_at_period_end: boolean;\n\n  /**\n   * If the subscription has been canceled, the date of that cancellation as a UTC timestamp.\n   * If the subscription was canceled with {@link Subscription.cancel_at_period_end}, this field\n   * will still reflect the date of the initial cancellation request, not the end of the\n   * subscription period when the subscription is automatically moved to a canceled state.\n   */\n  readonly canceled_at: string | null;\n\n  /**\n   * The date when the subscription was created as a UTC timestamp.\n   */\n  readonly created: string;\n\n  /**\n   * End of the current period that the subscription has been invoiced for as a UTC timestamp.\n   * At the end of the period, a new invoice will be created.\n   */\n  readonly current_period_end: string;\n\n  /**\n   * Start of the current period that the subscription has been invoiced for as a UTC timestamp.\n   */\n  readonly current_period_start: string;\n\n  /**\n   * If the subscription has ended, the date the subscription ended as a UTC timestamp.\n   */\n  readonly ended_at: string | null;\n\n  /**\n   * Unique Stripe subscription ID.\n   */\n  readonly id: string;\n\n  /**\n   * Set of extra key-value pairs attached to the subscription object.\n   */\n  readonly metadata: { [name: string]: string };\n\n  /**\n   * Stripe price ID associated with this subscription.\n   */\n  readonly price: string;\n\n  /**\n   * Array of product ID and price ID pairs. If multiple recurring prices were provided to the\n   * checkout session (e.g. via `lineItems`) this array holds all recurring prices for this\n   * subscription. The first element of this array always corresponds to the\n   * {@link Subscription.price} and {@link Subscription.product} fields on the subscription.\n   */\n  readonly prices: Array<{ product: string; price: string }>;\n\n  /**\n   * Stripe product ID associated with this subscription.\n   */\n  readonly product: string;\n\n  /**\n   * Quantity of items purchased with this subscription.\n   */\n  readonly quantity: number | null;\n\n  /**\n   * The Firebae role that can be assigned to the user with this subscription.\n   */\n  readonly role: string | null;\n\n  /**\n   * The status of the subscription object\n   */\n  readonly status: SubscriptionStatus;\n\n  /**\n   * A link to the subscription in the Stripe dashboard.\n   */\n  readonly stripe_link: string;\n\n  /**\n   * If the subscription has a trial, the end date of that trial as a UTC timestamp.\n   */\n  readonly trial_end: string | null;\n\n  /**\n   * If the subscription has a trial, the start date of that trial as a UTC timestamp.\n   */\n  readonly trial_start: string | null;\n\n  /**\n   * Firebase Auth UID of the user that created the subscription.\n   */\n  readonly uid: string;\n\n  readonly [propName: string]: any;\n}\n\n/**\n * Possible states a subscription can be in.\n */\nexport type SubscriptionStatus =\n  | \"active\"\n  | \"canceled\"\n  | \"incomplete\"\n  | \"incomplete_expired\"\n  | \"past_due\"\n  | \"trialing\"\n  | \"unpaid\";\n\n/**\n * Retrieves an existing Stripe subscription for the currently signed in user from the database.\n *\n * @param payments - A valid {@link StripePayments} object.\n * @param subscriptionId - ID of the subscription to retrieve.\n * @returns Resolves with a Subscription object if found. Rejects if the specified subscription ID\n *  does not exist, or if the user is not signed in.\n */\nexport function getCurrentUserSubscription(\n  payments: StripePayments,\n  subscriptionId: string\n): Promise<Subscription> {\n  checkNonEmptyString(\n    subscriptionId,\n    \"subscriptionId must be a non-empty string.\"\n  );\n  return getCurrentUser(payments).then((uid: string) => {\n    const dao: SubscriptionDAO = getOrInitSubscriptionDAO(payments);\n    return dao.getSubscription(uid, subscriptionId);\n  });\n}\n\n/**\n * Optional parameters for the {@link getCurrentUserSubscriptions} function.\n */\nexport interface GetSubscriptionsOptions {\n  /**\n   * Specify one or more subscription status values to retrieve. When set only the subscriptions\n   * with the given status are returned.\n   */\n  status?: SubscriptionStatus | SubscriptionStatus[];\n}\n\n/**\n * Retrieves existing Stripe subscriptions for the currently signed in user from the database.\n *\n * @param payments - A valid {@link StripePayments} object.\n * @param options - A set of options to customize the behavior.\n * @returns Resolves with an array of Stripe subscriptions. May be empty.\n */\nexport function getCurrentUserSubscriptions(\n  payments: StripePayments,\n  options?: GetSubscriptionsOptions\n): Promise<Subscription[]> {\n  const queryOptions: { status?: SubscriptionStatus[] } = {};\n  if (typeof options?.status !== \"undefined\") {\n    queryOptions.status = getStatusAsArray(options.status);\n  }\n\n  return getCurrentUser(payments).then((uid: string) => {\n    const dao: SubscriptionDAO = getOrInitSubscriptionDAO(payments);\n    return dao.getSubscriptions(uid, queryOptions);\n  });\n}\n\n/**\n * Different types of changes that may occur on a subscription object.\n */\nexport type SubscriptionChangeType = \"added\" | \"modified\" | \"removed\";\n\n/**\n * Represents the current state of a set of subscriptions owned by a user.\n */\nexport interface SubscriptionSnapshot {\n  /**\n   * A list of all currently available subscriptions ordered by the subscription ID. Empty\n   * if no subscriptions are available.\n   */\n  subscriptions: Subscription[];\n\n  /**\n   * The list of changes in the subscriptions since the last snapshot.\n   */\n  changes: Array<{\n    type: SubscriptionChangeType;\n    subscription: Subscription;\n  }>;\n\n  /**\n   * Number of currently available subscriptions. This is same as the length of the\n   * `subscriptions` array in the snapshot.\n   */\n  size: number;\n\n  /**\n   * True if there are no subscriptions available. False whenever at least one subscription is\n   * present. When True, the `subscriptions` array is empty, and the `size` is 0.\n   */\n  empty: boolean;\n}\n\n/**\n * Registers a listener to receive subscription update events for the currently signed in\n * user. If the user is not signed in throws an `unauthenticated` error, and no listener is\n * registered.\n *\n * Upon successful registration, the `onUpdate` callback will fire once with\n * the current state of all the subscriptions. From then onwards, each update to a subscription\n * will fire the `onUpdate` callback with the latest state of the subscriptions.\n *\n * @param payments - A valid {@link StripePayments} object.\n * @param onUpdate - A callback that will fire whenever the current user's subscriptions\n *   are updated.\n * @param onError - A callback that will fire whenever an error occurs while listening to\n *   subscription updates.\n * @returns A function that can be called to cancel and unregister the listener.\n */\nexport function onCurrentUserSubscriptionUpdate(\n  payments: StripePayments,\n  onUpdate: (snapshot: SubscriptionSnapshot) => void,\n  onError?: (error: StripePaymentsError) => void\n): () => void {\n  const uid: string = getCurrentUserSync(payments);\n  const dao: SubscriptionDAO = getOrInitSubscriptionDAO(payments);\n  return dao.onSubscriptionUpdate(uid, onUpdate, onError);\n}\n\nfunction getStatusAsArray(\n  status: SubscriptionStatus | SubscriptionStatus[]\n): SubscriptionStatus[] {\n  if (typeof status === \"string\") {\n    return [status];\n  }\n\n  checkNonEmptyArray(status, \"status must be a non-empty array.\");\n  return status;\n}\n\n/**\n * Internal interface for all database interactions pertaining to Stripe subscriptions. Exported\n * for testing.\n *\n * @internal\n */\nexport interface SubscriptionDAO {\n  getSubscription(uid: string, subscriptionId: string): Promise<Subscription>;\n  getSubscriptions(\n    uid: string,\n    options?: { status?: SubscriptionStatus[] }\n  ): Promise<Subscription[]>;\n  onSubscriptionUpdate(\n    uid: string,\n    onUpdate: (snapshot: SubscriptionSnapshot) => void,\n    onError?: (error: StripePaymentsError) => void\n  ): () => void;\n}\n\nconst SUBSCRIPTION_CONVERTER: FirestoreDataConverter<Subscription> = {\n  toFirestore: () => {\n    throw new Error(\"Not implemented for readonly Subscription type.\");\n  },\n  fromFirestore: (snapshot: QueryDocumentSnapshot): Subscription => {\n    const data: DocumentData = snapshot.data();\n    const refs: DocumentReference[] = data.prices;\n    const prices: Array<{ product: string; price: string }> = refs.map(\n      (priceRef: DocumentReference) => {\n        return {\n          product: priceRef.parent.parent!.id,\n          price: priceRef.id,\n        };\n      }\n    );\n\n    return {\n      cancel_at: toNullableUTCDateString(data.cancel_at),\n      cancel_at_period_end: data.cancel_at_period_end,\n      canceled_at: toNullableUTCDateString(data.canceled_at),\n      created: toUTCDateString(data.created),\n      current_period_start: toUTCDateString(data.current_period_start),\n      current_period_end: toUTCDateString(data.current_period_end),\n      ended_at: toNullableUTCDateString(data.ended_at),\n      id: snapshot.id,\n      metadata: data.metadata ?? {},\n      price: (data.price as DocumentReference).id,\n      prices,\n      product: (data.product as DocumentReference).id,\n      quantity: data.quantity ?? null,\n      role: data.role ?? null,\n      status: data.status,\n      stripe_link: data.stripeLink,\n      trial_end: toNullableUTCDateString(data.trial_end),\n      trial_start: toNullableUTCDateString(data.trial_start),\n      uid: snapshot.ref.parent.parent!.id,\n    };\n  },\n};\n\nconst SUBSCRIPTIONS_COLLECTION = \"subscriptions\" as const;\n\nfunction toNullableUTCDateString(timestamp: Timestamp | null): string | null {\n  if (timestamp === null) {\n    return null;\n  }\n\n  return toUTCDateString(timestamp);\n}\n\nfunction toUTCDateString(timestamp: Timestamp): string {\n  return timestamp.toDate().toUTCString();\n}\n\nclass FirestoreSubscriptionDAO implements SubscriptionDAO {\n  private readonly firestore: Firestore;\n\n  constructor(app: FirebaseApp, private readonly customersCollection: string) {\n    this.firestore = getFirestore(app);\n  }\n\n  public async getSubscription(\n    uid: string,\n    subscriptionId: string\n  ): Promise<Subscription> {\n    const snap: QueryDocumentSnapshot<Subscription> =\n      await this.getSubscriptionSnapshotIfExists(uid, subscriptionId);\n    return snap.data();\n  }\n\n  public async getSubscriptions(\n    uid: string,\n    options?: { status?: SubscriptionStatus[] }\n  ): Promise<Subscription[]> {\n    const querySnap: QuerySnapshot<Subscription> =\n      await this.getSubscriptionSnapshots(uid, options?.status);\n    const subscriptions: Subscription[] = [];\n    querySnap.forEach((snap: QueryDocumentSnapshot<Subscription>) => {\n      subscriptions.push(snap.data());\n    });\n\n    return subscriptions;\n  }\n\n  public onSubscriptionUpdate(\n    uid: string,\n    onUpdate: (snapshot: SubscriptionSnapshot) => void,\n    onError?: (error: StripePaymentsError) => void\n  ): () => void {\n    const subscriptions: CollectionReference<Subscription> = collection(\n      this.firestore,\n      this.customersCollection,\n      uid,\n      SUBSCRIPTIONS_COLLECTION\n    ).withConverter(SUBSCRIPTION_CONVERTER);\n    return onSnapshot(\n      subscriptions,\n      (querySnap: QuerySnapshot<Subscription>) => {\n        const snapshot: SubscriptionSnapshot = {\n          subscriptions: [],\n          changes: [],\n          size: querySnap.size,\n          empty: querySnap.empty,\n        };\n        querySnap.forEach((snap: QueryDocumentSnapshot<Subscription>) => {\n          snapshot.subscriptions.push(snap.data());\n        });\n        querySnap\n          .docChanges()\n          .forEach((change: DocumentChange<Subscription>) => {\n            snapshot.changes.push({\n              type: change.type,\n              subscription: change.doc.data(),\n            });\n          });\n\n        onUpdate(snapshot);\n      },\n      (err: FirestoreError) => {\n        if (onError) {\n          const arg: StripePaymentsError = new StripePaymentsError(\n            \"internal\",\n            `Error while listening to database updates: ${err.message}`,\n            err\n          );\n          onError(arg);\n        }\n      }\n    );\n  }\n\n  private async getSubscriptionSnapshotIfExists(\n    uid: string,\n    subscriptionId: string\n  ): Promise<QueryDocumentSnapshot<Subscription>> {\n    const subscriptionRef: DocumentReference<Subscription> = doc(\n      this.firestore,\n      this.customersCollection,\n      uid,\n      SUBSCRIPTIONS_COLLECTION,\n      subscriptionId\n    ).withConverter(SUBSCRIPTION_CONVERTER);\n    const snapshot: DocumentSnapshot<Subscription> = await this.queryFirestore(\n      () => getDoc(subscriptionRef)\n    );\n    if (!snapshot.exists()) {\n      throw new StripePaymentsError(\n        \"not-found\",\n        `No subscription found with the ID: ${subscriptionId} for user: ${uid}`\n      );\n    }\n\n    return snapshot;\n  }\n\n  private async getSubscriptionSnapshots(\n    uid: string,\n    status?: SubscriptionStatus[]\n  ): Promise<QuerySnapshot<Subscription>> {\n    let subscriptionsQuery: Query<Subscription> = collection(\n      this.firestore,\n      this.customersCollection,\n      uid,\n      SUBSCRIPTIONS_COLLECTION\n    ).withConverter(SUBSCRIPTION_CONVERTER);\n    if (status) {\n      subscriptionsQuery = query(\n        subscriptionsQuery,\n        where(\"status\", \"in\", status)\n      );\n    }\n\n    return await this.queryFirestore(() => getDocs(subscriptionsQuery));\n  }\n\n  private async queryFirestore<T>(fn: () => Promise<T>): Promise<T> {\n    try {\n      return await fn();\n    } catch (error) {\n      throw new StripePaymentsError(\n        \"internal\",\n        \"Unexpected error while querying Firestore\",\n        error\n      );\n    }\n  }\n}\n\nconst SUBSCRIPTION_DAO_KEY = \"subscription-dao\" as const;\n\nfunction getOrInitSubscriptionDAO(payments: StripePayments): SubscriptionDAO {\n  let dao: SubscriptionDAO | null =\n    payments.getComponent<SubscriptionDAO>(SUBSCRIPTION_DAO_KEY);\n  if (!dao) {\n    dao = new FirestoreSubscriptionDAO(\n      payments.app,\n      payments.customersCollection\n    );\n    setSubscriptionDAO(payments, dao);\n  }\n\n  return dao;\n}\n\n/**\n * Internal API for registering a {@link SubscriptionDAO} instance with {@link StripePayments}.\n * Exported for testing.\n *\n * @internal\n */\nexport function setSubscriptionDAO(\n  payments: StripePayments,\n  dao: SubscriptionDAO\n): void {\n  payments.setComponent(SUBSCRIPTION_DAO_KEY, dao);\n}\n"]}