{"version":3,"file":"create-usage-record.mjs","sources":["../../../../../../lib/billing/create-usage-record.ts"],"sourcesContent":["import {ConfigInterface} from '../base-types';\nimport {BillingError, GraphqlQueryError} from '../error';\nimport {GraphqlClient, graphqlClientClass} from '../clients/admin';\n\nimport {\n  AppSubscription,\n  BillingCreateUsageRecord,\n  BillingCreateUsageRecordParams,\n  UsageRecord,\n  UsageRecordCreateResponse,\n  Money,\n} from './types';\nimport {assessPayments} from './check';\nimport {\n  convertAppRecurringPricingMoney,\n  convertAppUsagePricingMoney,\n} from './utils';\n\ninterface InternalParams {\n  client: GraphqlClient;\n  isTest?: boolean;\n}\n\ninterface CreateUsageRecordVariables {\n  description: string;\n  price: Money;\n  subscriptionLineItemId: string;\n  idempotencyKey?: string;\n}\n\nconst CREATE_USAGE_RECORD_MUTATION = `\nmutation appUsageRecordCreate($description: String!, $price: MoneyInput!, $subscriptionLineItemId: ID!) {\n  appUsageRecordCreate(description: $description, price: $price, subscriptionLineItemId: $subscriptionLineItemId) {\n    userErrors {\n      field\n      message\n    }\n    appUsageRecord {\n      id\n      description\n      idempotencyKey\n      price {\n        amount\n        currencyCode\n      }\n      subscriptionLineItem {\n        id\n        plan {\n          pricingDetails {\n            ... on AppUsagePricing {\n              balanceUsed {\n                amount\n                currencyCode\n              }\n              cappedAmount {\n                amount\n                currencyCode\n              }\n              terms\n            }\n          }\n        }\n      }\n    }\n  }\n}\n`;\n\nexport function createUsageRecord(\n  config: ConfigInterface,\n): BillingCreateUsageRecord {\n  return async function createUsageRecord(\n    usageRecordInfo: BillingCreateUsageRecordParams,\n  ): Promise<UsageRecord> {\n    const {\n      session,\n      subscriptionLineItemId,\n      description,\n      price,\n      idempotencyKey,\n      isTest = true,\n    } = usageRecordInfo;\n\n    const GraphqlClient = graphqlClientClass({config});\n    const client = new GraphqlClient({session});\n\n    // If a subscription line item ID is not passed, we will query Shopify\n    // for an active usage subscription line item ID\n    const usageSubscriptionLineItemId = subscriptionLineItemId\n      ? subscriptionLineItemId\n      : await getUsageRecordSubscriptionLineItemId({client, isTest});\n\n    const variables: CreateUsageRecordVariables = {\n      description,\n      price,\n      subscriptionLineItemId: usageSubscriptionLineItemId,\n    };\n    if (idempotencyKey) {\n      variables.idempotencyKey = idempotencyKey;\n    }\n\n    try {\n      const response = await client.request<UsageRecordCreateResponse>(\n        CREATE_USAGE_RECORD_MUTATION,\n        {\n          variables,\n        },\n      );\n      if (response.data?.appUsageRecordCreate?.userErrors.length) {\n        throw new BillingError({\n          message: 'Error while creating a usage record',\n          errorData: response.data?.appUsageRecordCreate?.userErrors,\n        });\n      }\n\n      const appUsageRecord =\n        response.data?.appUsageRecordCreate?.appUsageRecord!;\n      convertAppRecurringPricingMoney(appUsageRecord.price);\n      convertAppUsagePricingMoney(\n        appUsageRecord.subscriptionLineItem.plan.pricingDetails,\n      );\n\n      return appUsageRecord;\n    } catch (error) {\n      if (error instanceof GraphqlQueryError) {\n        throw new BillingError({\n          message: error.message,\n          errorData: error.response?.errors,\n        });\n      } else {\n        throw error;\n      }\n    }\n  };\n}\n\nasync function getUsageRecordSubscriptionLineItemId({\n  client,\n  isTest,\n}: InternalParams): Promise<string> {\n  const payments = await assessPayments({client, isTest});\n\n  if (!payments.hasActivePayment) {\n    throw new BillingError({\n      message: 'No active payment found',\n      errorData: [],\n    });\n  }\n  if (!payments.appSubscriptions.length) {\n    throw new BillingError({\n      message: 'No active subscriptions found',\n      errorData: [],\n    });\n  }\n  if (payments.appSubscriptions) {\n    const usageSubscriptionLineItemId = getUsageLineItemId(\n      payments.appSubscriptions,\n    );\n    return usageSubscriptionLineItemId;\n  }\n  throw new BillingError({\n    message: 'Unable to find active subscription line item',\n    errorData: [],\n  });\n}\n\nfunction getUsageLineItemId(subscriptions: AppSubscription[]): string {\n  for (const subscription of subscriptions) {\n    // An app can have only one active subscription\n    if (subscription.status === 'ACTIVE' && subscription.lineItems) {\n      // An app can have only one usage subscription line item\n      for (const lineItem of subscription.lineItems) {\n        if ('balanceUsed' in lineItem.plan.pricingDetails) {\n          return lineItem.id;\n        }\n      }\n    }\n  }\n\n  throw new BillingError({\n    message: 'No active usage subscription found',\n    errorData: [],\n  });\n}\n"],"names":[],"mappings":"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"}