chore: ran biome format

This commit is contained in:
John Yeo
2025-09-22 14:45:25 +01:00
parent db19928cea
commit da2693567c
1358 changed files with 112670 additions and 112585 deletions

View File

@@ -9,7 +9,7 @@ export default function CustomerDetailsExample() {
const getEntitlement = (featureId: string) => {
return customer?.features.find(
(entitlement: any) => entitlement.feature_id === featureId
(entitlement: any) => entitlement.feature_id === featureId,
);
};

View File

@@ -1,6 +1,6 @@
import * as React from "react"
import * as React from "react";
import { cn } from "@/lib/utils"
import { cn } from "@/lib/utils";
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
return (
@@ -11,11 +11,11 @@ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
"file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
className
className,
)}
{...props}
/>
)
);
}
export { Input }
export { Input };

View File

@@ -1,10 +1,10 @@
"use client"
"use client";
import { useTheme } from "next-themes"
import { Toaster as Sonner, ToasterProps } from "sonner"
import { useTheme } from "next-themes";
import { Toaster as Sonner, ToasterProps } from "sonner";
const Toaster = ({ ...props }: ToasterProps) => {
const { theme = "system" } = useTheme()
const { theme = "system" } = useTheme();
return (
<Sonner
@@ -19,7 +19,7 @@ const Toaster = ({ ...props }: ToasterProps) => {
}
{...props}
/>
)
}
);
};
export { Toaster }
export { Toaster };

View File

@@ -1,19 +1,21 @@
import * as React from "react"
import * as React from "react";
const MOBILE_BREAKPOINT = 768
const MOBILE_BREAKPOINT = 768;
export function useIsMobile() {
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(undefined)
const [isMobile, setIsMobile] = React.useState<boolean | undefined>(
undefined,
);
React.useEffect(() => {
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`)
const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
const onChange = () => {
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
}
mql.addEventListener("change", onChange)
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
return () => mql.removeEventListener("change", onChange)
}, [])
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
};
mql.addEventListener("change", onChange);
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
return () => mql.removeEventListener("change", onChange);
}, []);
return !!isMobile
return !!isMobile;
}

View File

@@ -1,6 +1,6 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
import { clsx, type ClassValue } from "clsx";
import { twMerge } from "tailwind-merge";
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
return twMerge(clsx(inputs));
}

View File

@@ -83,7 +83,7 @@ const getSingleCustomer = async ({
// });
let scheduleIds = customers[0].customer_products.flatMap(
(cp) => cp.scheduled_ids || []
(cp) => cp.scheduled_ids || [],
);
scheduleIds = Array.from(new Set(scheduleIds));
@@ -121,7 +121,7 @@ const checkCustomerCorrect = async ({
}
fullCus.entities = entities.filter(
(entity) => entity.internal_customer_id === fullCus.internal_id
(entity) => entity.internal_customer_id === fullCus.internal_id,
);
// console.log(`Checking ${fullCus.email} (${fullCus.id})`);
@@ -148,12 +148,12 @@ const checkCustomerCorrect = async ({
cp.status !== CusProductStatus.Scheduled &&
(cusProduct.internal_entity_id
? cusProduct.internal_entity_id == cp.internal_entity_id
: true)
: true),
);
assert(
mainCusProd,
`Found scheduled cus product with no main product (${cusProduct.product.name})`
`Found scheduled cus product with no main product (${cusProduct.product.name})`,
);
}
@@ -168,22 +168,22 @@ const checkCustomerCorrect = async ({
cp.id !== cusProduct.id &&
!cp.product.is_add_on &&
cp.status !== CusProductStatus.Scheduled &&
cp.internal_entity_id == cusProduct.internal_entity_id
cp.internal_entity_id == cusProduct.internal_entity_id,
);
assert(
!otherCusProd,
`found two cus products from the same group: ${otherCusProd?.product.name} and ${cusProduct.product.name}`
`found two cus products from the same group: ${otherCusProd?.product.name} and ${cusProduct.product.name}`,
);
}
let stripeSubs = subs.filter((sub: any) =>
cusProduct.subscription_ids!.some((id: string) => id === sub.id)
cusProduct.subscription_ids!.some((id: string) => id === sub.id),
);
assert(
stripeSubs.length === cusProduct.subscription_ids!.length,
"number of stripe subs should be the same as number of subscription ids"
"number of stripe subs should be the same as number of subscription ids",
);
// let subItems = stripeSubs.flatMap((sub: any) => sub.items.data);
@@ -203,7 +203,7 @@ const checkCustomerCorrect = async ({
if (cusEnt.usage_allowed && !cusPrice) {
assert.fail(
`Feature ${cusEnt.feature_id} has usage allowed but no related cus price`
`Feature ${cusEnt.feature_id} has usage allowed but no related cus price`,
);
}
}
@@ -331,7 +331,7 @@ export const check = async () => {
schedules: stripeSchedules,
org,
entities,
})
}),
);
}
@@ -372,7 +372,7 @@ export const check = async () => {
}
console.log(
`COMPLETED ERROR CHECK FOR ${new Date().toISOString().slice(0, 16)}`
`COMPLETED ERROR CHECK FOR ${new Date().toISOString().slice(0, 16)}`,
);
if (process.env.NODE_ENV == "production") {

View File

@@ -47,7 +47,7 @@ export const check = async () => {
const checkCustomers = ["9bafd636-0c52-46b3-8ecd-1708d6faa373"];
fullCustomers = fullCustomers.filter((customer) =>
checkCustomers.includes(customer.id || "")
checkCustomers.includes(customer.id || ""),
);
for (const customer of fullCustomers) {

View File

@@ -20,7 +20,7 @@ const { db, client } = initDrizzle();
export const cronTask = async () => {
console.log(
"\n----------------------------------\nRUNNING RESET CRON:",
format(new UTCDate(), "yyyy-MM-dd HH:mm:ss")
format(new UTCDate(), "yyyy-MM-dd HH:mm:ss"),
);
try {
@@ -41,7 +41,7 @@ export const cronTask = async () => {
db,
cusEnt: cusEnt,
cacheEnabledOrgs,
})
}),
);
}
@@ -57,7 +57,7 @@ export const cronTask = async () => {
console.log(
"FINISHED RESET CRON:",
format(new UTCDate(), "yyyy-MM-dd HH:mm:ss")
format(new UTCDate(), "yyyy-MM-dd HH:mm:ss"),
);
console.log("----------------------------------\n");
} catch (error) {
@@ -75,7 +75,7 @@ const job = new CronJob(
},
null, // onComplete
true, // start immediately
"UTC" // timezone (adjust as needed)
"UTC", // timezone (adjust as needed)
);
cronTask();

View File

@@ -74,11 +74,11 @@ const checkSubAnchor = async ({
console.log("Checking billing cycle anchor");
console.log(
"Next reset at ",
format(new UTCDate(nextResetAt), "dd MMM yyyy HH:mm:ss")
format(new UTCDate(nextResetAt), "dd MMM yyyy HH:mm:ss"),
);
console.log(
"Billing cycle anchor",
format(new UTCDate(billingCycleAnchor), "dd MMM yyyy HH:mm:ss")
format(new UTCDate(billingCycleAnchor), "dd MMM yyyy HH:mm:ss"),
);
const billingCycleDay = getDate(new UTCDate(billingCycleAnchor));
@@ -134,7 +134,7 @@ const handleShortDurationCusEnt = async ({
}
console.log(
`Reseting short cus ent (${cusEnt.feature_id}) [${ent.interval}], customer: ${cusEnt.customer_id}, org: ${cusEnt.customer.org_id}`
`Reseting short cus ent (${cusEnt.feature_id}) [${ent.interval}], customer: ${cusEnt.customer_id}, org: ${cusEnt.customer.org_id}`,
);
let org = await OrgService.get({
@@ -190,7 +190,7 @@ export const resetCustomerEntitlement = async ({
const entOptions = getEntOptions(
cusEnt.customer_product.options,
cusEnt.entitlement
cusEnt.entitlement,
);
// Handle if entitlement changed to unlimited...
@@ -207,10 +207,10 @@ export const resetCustomerEntitlement = async ({
console.log(
`Reset ${cusEnt.id} | customer: ${chalk.yellow(
cusEnt.customer_id
cusEnt.customer_id,
)} | feature: ${chalk.yellow(
cusEnt.feature_id
)} | new balance: unlimited`
cusEnt.feature_id,
)} | new balance: unlimited`,
);
return;
}
@@ -226,10 +226,10 @@ export const resetCustomerEntitlement = async ({
console.log(
`Reset ${cusEnt.id} | customer: ${chalk.yellow(
cusEnt.customer_id
cusEnt.customer_id,
)} | feature: ${chalk.yellow(
cusEnt.feature_id
)} | reset to lifetime (next_reset_at: null)`
cusEnt.feature_id,
)} | reset to lifetime (next_reset_at: null)`,
);
return;
}
@@ -290,14 +290,14 @@ export const resetCustomerEntitlement = async ({
console.log(
`Reset ${cusEnt.id} | customer: ${chalk.yellow(
cusEnt.customer_id
cusEnt.customer_id,
)} | feature: ${chalk.yellow(
cusEnt.feature_id
cusEnt.feature_id,
)} | new balance: ${chalk.green(
resetBalance
resetBalance,
)} | new next_reset_at: ${chalk.green(
format(new UTCDate(nextResetAt), "dd MMM yyyy HH:mm:ss")
)}`
format(new UTCDate(nextResetAt), "dd MMM yyyy HH:mm:ss"),
)}`,
);
// let cacheOrg = cacheEnabledOrgs.find(
@@ -324,7 +324,7 @@ export const resetCustomerEntitlement = async ({
// }
} catch (error: any) {
console.log(
`Failed to reset ${cusEnt.id} | ${cusEnt.customer_id} | ${cusEnt.feature_id}, error: ${error}`
`Failed to reset ${cusEnt.id} | ${cusEnt.customer_id} | ${cusEnt.feature_id}, error: ${error}`,
);
}
};

View File

@@ -143,7 +143,7 @@ export const initLogger = () => {
},
},
// Use multistream to send logs to multiple destinations
pino.multistream(streams)
pino.multistream(streams),
);
return logger;

View File

@@ -62,7 +62,7 @@ autumnWebhookRouter.post(
switch (type) {
case WebhookEventType.CustomerProductsUpdated:
console.log(
`Type: ${type}, Scenario: ${data?.scenario}, Product: ${data?.updated_product?.id}`
`Type: ${type}, Scenario: ${data?.scenario}, Product: ${data?.updated_product?.id}`,
);
break;
case WebhookEventType.CustomerThresholdReached:
@@ -82,5 +82,5 @@ autumnWebhookRouter.post(
});
return;
}
}
},
);

View File

@@ -22,7 +22,7 @@ export class CacheManager {
}
this.client = new Redis(redisUrl, {
retryStrategy: (times) => {
retryStrategy: () => {
return 5000;
},
});
@@ -59,7 +59,7 @@ export class CacheManager {
}
public static async getJson(key: string) {
let client = await CacheManager.getClient();
const client = await CacheManager.getClient();
if (!client) {
throw new Error("Cache client not initialized");
@@ -70,7 +70,7 @@ export class CacheManager {
return null;
}
let res = await client.get(key);
const res = await client.get(key);
if (!res) {
return null;
@@ -79,8 +79,12 @@ export class CacheManager {
return JSON.parse(res);
}
public static async setJson(key: string, value: any, ttl: number | string = 3600) {
let client = await CacheManager.getClient();
public static async setJson(
key: string,
value: any,
ttl: number | string = 3600,
) {
const client = await CacheManager.getClient();
if (!client) {
throw new Error("Cache client not initialized");
}
@@ -90,9 +94,9 @@ export class CacheManager {
return;
}
if(typeof ttl === 'number') {
if (typeof ttl === "number") {
await client.set(key, JSON.stringify(value), "EX", ttl);
} else if(typeof ttl === 'string' && ttl.toLowerCase() === 'forever') {
} else if (typeof ttl === "string" && ttl.toLowerCase() === "forever") {
await client.set(key, JSON.stringify(value));
}
}
@@ -104,7 +108,7 @@ export class CacheManager {
action: string;
value: string;
}) {
let client = await CacheManager.getClient();
const client = await CacheManager.getClient();
if (!client) {
throw new Error("Cache client not initialized");
}
@@ -118,7 +122,7 @@ export class CacheManager {
}
static async disconnect() {
let client = await CacheManager.getClient();
const client = await CacheManager.getClient();
if (!client) {
throw new Error("Cache client not initialized");
}

View File

@@ -91,7 +91,7 @@ export const getStripeKey = async (orgId: string, env: AppEnv) => {
export const createOrgAndAssignUser = async (
name: string,
slug: string,
userId: string
userId: string,
) => {
try {
const orgRes = await clerkClient.organizations.createOrganization({

View File

@@ -92,22 +92,22 @@ export class ClickHouseManager {
];
const queryResults = await Promise.allSettled(
requiredQueries.map((query) => ClickHouseManager.readSQLFile(query))
requiredQueries.map((query) => ClickHouseManager.readSQLFile(query)),
);
const failedQueries = queryResults.filter(
(result) => result.status === "rejected"
(result) => result.status === "rejected",
);
if (failedQueries.length > 0) {
console.error(
`Failed to read ${failedQueries.length} ClickHouse queries. Please re-pull the latest version of Autumn. `
`Failed to read ${failedQueries.length} ClickHouse queries. Please re-pull the latest version of Autumn. `,
);
failedQueries.forEach((result, index) => {
if (result.status === "rejected") {
console.error(
`Query ${requiredQueries[index]} failed:`,
result.reason
result.reason,
);
}
});
@@ -122,7 +122,7 @@ export class ClickHouseManager {
if (!ClickHouseManager.clickhouseAvailable) {
console.log(
"0. ClickHouse is not available, please set the CLICKHOUSE_URL, CLICKHOUSE_USERNAME, and CLICKHOUSE_PASSWORD environment variables."
"0. ClickHouse is not available, please set the CLICKHOUSE_URL, CLICKHOUSE_USERNAME, and CLICKHOUSE_PASSWORD environment variables.",
);
return;
}
@@ -134,7 +134,7 @@ export class ClickHouseManager {
if (process.env.CLICKHOUSE_SKIP_ENSURES?.toLowerCase() === "true") {
console.group();
console.log(
"✓ Skipping query ensures - queries assumed to exist already"
"✓ Skipping query ensures - queries assumed to exist already",
);
console.groupEnd();
return;
@@ -159,7 +159,7 @@ export class ClickHouseManager {
console.error(`✗ Failed to execute query ${query}:`, error);
process.exit(1);
}
})
}),
);
console.groupEnd();
@@ -180,7 +180,7 @@ export class ClickHouseManager {
private async executeQuery(
query: ClickHouseQuery,
client: ClickHouseClient,
options: any = {}
options: any = {},
) {
const queryContent = await this.readSQLFile(query);
if (!queryContent) {
@@ -210,7 +210,7 @@ export class ClickHouseManager {
client?: ClickHouseClient,
options: QueryParams = {
format: "TabSeparatedRaw",
} as QueryParams
} as QueryParams,
) {
const manager = await ClickHouseManager.getInstance();
const clickhouseClient = client || (await ClickHouseManager.getClient());

View File

@@ -45,7 +45,7 @@ const createLogMethod = (pinoMethod: any, logtailMethod?: any) => {
const errorObject = args.find((arg) => arg instanceof Error);
if (errorObject) {
message = rewriteAppPath(
errorObject.stack || errorObject.message || "Error occurred"
errorObject.stack || errorObject.message || "Error occurred",
);
}
}

View File

@@ -108,7 +108,7 @@ export const createStripeMeteredPrice = async ({
export const arrearProratedToStripeTiers = (
price: Price,
entitlement: EntitlementWithFeature
entitlement: EntitlementWithFeature,
) => {
let usageConfig = structuredClone(price.config) as UsagePriceConfig;

View File

@@ -53,7 +53,7 @@ export const searchStripeMeter = async ({
logger.info(`Stripe meter list took ${end - start}ms`);
let stripeMeter = allStripeMeters.find(
(m) => m.event_name == eventName || m.id == meterId
(m) => m.event_name == eventName || m.id == meterId,
);
return stripeMeter;
@@ -87,7 +87,7 @@ export const getStripeMeter = async ({
createNew = true;
} else {
logger.info(
`✅ Found existing meter for ${product.name} - ${feature!.name}`
`✅ Found existing meter for ${product.name} - ${feature!.name}`,
);
return stripeMeter;
}
@@ -107,7 +107,7 @@ export const getStripeMeter = async ({
// IN ARREAR
export const priceToInArrearTiers = (
price: Price,
entitlement: Entitlement
entitlement: Entitlement,
) => {
let usageConfig = structuredClone(price.config) as UsagePriceConfig;
const tiers: any[] = [];
@@ -177,7 +177,7 @@ export const createStripeInArrearPrice = async ({
if (internalEntityId && !useCheckout) {
if (!curStripeProduct) {
logger.info(
`Creating stripe in arrear product for ${relatedEnt.feature.name} (internal entity ID exists!)`
`Creating stripe in arrear product for ${relatedEnt.feature.name} (internal entity ID exists!)`,
);
let stripeProduct = await stripeCli.products.create({
name: `${product.name} - ${feature!.name}`,
@@ -199,7 +199,7 @@ export const createStripeInArrearPrice = async ({
}
logger.info(
`Creating stripe in arrear price for ${relatedEnt.feature.name} (no internal entity ID)`
`Creating stripe in arrear price for ${relatedEnt.feature.name} (no internal entity ID)`,
);
if (!feature) {
@@ -223,7 +223,7 @@ export const createStripeInArrearPrice = async ({
const tiers = priceToInArrearTiers(
price,
getPriceEntitlement(price, entitlements)
getPriceEntitlement(price, entitlements),
);
let priceAmountData = {};

View File

@@ -23,7 +23,7 @@ import { DrizzleCli } from "@/db/initDrizzle.js";
export const prepaidToStripeTiers = (
price: Price,
entitlement: EntitlementWithFeature
entitlement: EntitlementWithFeature,
) => {
let usageConfig = structuredClone(price.config) as UsagePriceConfig;

View File

@@ -30,7 +30,7 @@ export const priceToOneOffAndTiered = ({
const amount = getPriceForOverage(price, overage);
if (!config.stripe_product_id) {
console.log(
`WARNING: One off & tiered in advance price has no stripe product id: ${price.id}, ${relatedEnt.feature.name}`
`WARNING: One off & tiered in advance price has no stripe product id: ${price.id}, ${relatedEnt.feature.name}`,
);
}
return {

View File

@@ -57,7 +57,7 @@ export const deleteCouponFromCus = async ({
try {
let stripeCus = (await stripeCli.customers.retrieve(
stripeCusId
stripeCusId,
)) as Stripe.Customer;
if (stripeCus.discount?.id === discountId) {
await stripeCli.customers.deleteDiscount(stripeCusId, discountId);

View File

@@ -87,8 +87,8 @@ const couponToStripeValue = ({
const amountOff = Math.round(
prices?.reduce(
(acc, price) => acc + (price.config as FixedPriceConfig).amount,
0
) || 0
0,
) || 0,
);
console.log("amountOff in couponToStripeValue", amountOff);
@@ -162,7 +162,7 @@ export const createStripeCoupon = async ({
for (const promoCode of reward.promo_codes) {
try {
const stripePromoCode = await stripeCli.promotionCodes.retrieve(
promoCode.code
promoCode.code,
);
throw new RecaseError({
message: `Promo code ${promoCode.code} (${stripePromoCode.id}) already exists in Stripe`,

View File

@@ -58,7 +58,7 @@ export async function ensureStripeProductsWithEnv({
for (let fullProduct of fullProducts) {
const initProduct = async () => {
let existsInStripe = products.data.find(
(p) => p.id === fullProduct.processor?.id
(p) => p.id === fullProduct.processor?.id,
);
if (existsInStripe) {
@@ -75,7 +75,7 @@ export async function ensureStripeProductsWithEnv({
});
logger.info(
`initialized product ${fullProduct.id} in Stripe during Stripe connection, env: ${env}`
`initialized product ${fullProduct.id} in Stripe during Stripe connection, env: ${env}`,
);
} catch (error) {
logger.error(`Failed to init product in stripe: ${error}`);

View File

@@ -46,11 +46,11 @@ export const createStripeSubThroughInvoice = async ({
let subItems = items.filter(
(i: any, index: number) =>
prices[index].config!.interval !== BillingInterval.OneOff
prices[index].config!.interval !== BillingInterval.OneOff,
);
let invoiceItems = items.filter(
(i: any, index: number) =>
prices[index].config!.interval === BillingInterval.OneOff
prices[index].config!.interval === BillingInterval.OneOff,
);
try {

View File

@@ -96,7 +96,7 @@ export const payForInvoice = async ({
};
} catch (error: any) {
logger.error(
`❌ Stripe error: Failed to pay invoice: ${error?.message || error}`
`❌ Stripe error: Failed to pay invoice: ${error?.message || error}`,
);
if (voidIfFailed) {
@@ -189,7 +189,7 @@ export const getInvoiceDiscounts = ({
let autumnDiscounts = expandedInvoice.discounts.map((discount: any) => {
const amountOff = discount.coupon.amount_off;
const amountUsed = totalDiscountAmounts?.find(
(item) => item.discount === discount.id
(item) => item.discount === discount.id,
)?.amount;
let autumnDiscount: InvoiceDiscount = {

View File

@@ -16,7 +16,7 @@ export const checkKeyValid = async (apiKey: string) => {
export const createWebhookEndpoint = async (
apiKey: string,
env: AppEnv,
orgId: string
orgId: string,
) => {
const stripe = new Stripe(apiKey);

View File

@@ -46,7 +46,7 @@ export const getStripeSubs = async ({
} catch (error: any) {
console.log(
`(warning) getStripeSubs: Failed to get sub ${subId}`,
error.message
error.message,
);
return null;
}
@@ -134,7 +134,7 @@ export const getUsageBasedSub = async ({
let autumnSub = autumnSubs?.find((sub) => sub.stripe_id == stripeSub.id);
if (autumnSub) {
let containsFeature = autumnSub.usage_features.includes(
feature.internal_id!
feature.internal_id!,
);
if (containsFeature) {
return stripeSub;
@@ -150,7 +150,7 @@ export const getUsageBasedSub = async ({
if (
!usageFeatures ||
usageFeatures.find(
(feat: any) => feat.internal_id == feature.internal_id
(feat: any) => feat.internal_id == feature.internal_id,
) === undefined
) {
continue;
@@ -180,14 +180,15 @@ export const getSubItemsForCusProduct = async ({
prices.some(
(p) =>
p.config?.stripe_price_id == item.price.id ||
(p.config as UsagePriceConfig).stripe_product_id == item.price.product
(p.config as UsagePriceConfig).stripe_product_id ==
item.price.product,
)
) {
subItems.push(item);
}
}
let otherSubItems = stripeSub.items.data.filter(
(item) => !subItems.some((i) => i.id == item.id)
(item) => !subItems.some((i) => i.id == item.id),
);
return { subItems, otherSubItems };
@@ -207,7 +208,7 @@ export const getStripeSchedules = async ({
scheduleId,
{
expand: ["phases.items.price"],
}
},
);
if (schedule.status == "canceled") {
@@ -217,7 +218,7 @@ export const getStripeSchedules = async ({
const batchPricesGet = [];
for (const item of schedule.phases[0].items) {
batchPricesGet.push(
stripeCli.prices.retrieve((item.price as Stripe.Price).id as string)
stripeCli.prices.retrieve((item.price as Stripe.Price).id as string),
);
}
const prices = await Promise.all(batchPricesGet);

View File

@@ -58,7 +58,7 @@ const getIntervalToPrices = (prices: Price[]) => {
if (oneOffPrices && Object.keys(intervalToPrices).length > 1) {
const nextIntervalKey = Object.keys(intervalToPrices)[0];
intervalToPrices[nextIntervalKey!].push(
...structuredClone(intervalToPrices[BillingInterval.OneOff])
...structuredClone(intervalToPrices[BillingInterval.OneOff]),
);
delete intervalToPrices[BillingInterval.OneOff];
}
@@ -151,7 +151,7 @@ export const getStripeSubItems = async ({
products: attachParams.products,
price,
},
}
},
);
throw new RecaseError({
code: ErrCode.ProductNotFound,
@@ -190,7 +190,7 @@ export const getStripeSubItems = async ({
org,
interval: interval as BillingInterval,
intervalCount,
})
}),
);
}
@@ -216,7 +216,7 @@ export const getStripeSubItems = async ({
interval: b.interval,
intervalCount: b.intervalCount,
},
})
}),
);
return itemSets;
@@ -276,7 +276,7 @@ export const getStripeSubItems2 = async ({
products: attachParams.products,
price,
},
}
},
);
throw new RecaseError({
code: ErrCode.ProductNotFound,

View File

@@ -93,7 +93,7 @@ export const findStripeItemForPrice = ({
config.stripe_product_id == si.price?.product ||
config.stripe_empty_price_id == si.price?.id
);
}
},
);
if (stripeItem) return stripeItem;
@@ -108,7 +108,7 @@ export const findStripeItemForPrice = ({
config.stripe_price_id == si.price?.id ||
(stripeProdId && si.price?.product == stripeProdId)
);
}
},
);
}
@@ -179,7 +179,7 @@ export const findStripePriceFromPrices = ({
autumnStripePricesMatch({
stripePrice: p,
autumnPrice,
})
}),
);
};

View File

@@ -26,9 +26,9 @@ export const undoSubUpdate = async ({
(item) =>
!prevItems.some((prevItem) =>
curSub.items.data.some(
(curItem) => curItem.price.id === item.price.id
)
)
(curItem) => curItem.price.id === item.price.id,
),
),
)
.map((item) => {
return {

View File

@@ -38,7 +38,7 @@ const logStripeWebhook = ({
event: Stripe.Event;
}) => {
req.logtail.info(
`${chalk.yellow("STRIPE").padEnd(18)} ${event.type.padEnd(30)} ${req.org.slug} | ${event.id}`
`${chalk.yellow("STRIPE").padEnd(18)} ${event.type.padEnd(30)} ${req.org.slug} | ${event.id}`,
);
};
@@ -85,7 +85,7 @@ stripeWebhookRouter.post(
event = await stripe.webhooks.constructEventAsync(
request.body,
sig,
webhookSecret
webhookSecret,
);
} catch (err: any) {
response.status(400).send(`Webhook Error: ${err.message}`);
@@ -280,7 +280,7 @@ stripeWebhookRouter.post(
// DO NOT DELETE -- RESPONSIBLE FOR SENDING SUCCESSFUL RESPONSE TO STRIPE...
response.status(200).send();
}
},
);
const coreEvents = [
@@ -319,7 +319,7 @@ export const handleStripeWebhookRefresh = async ({
eventType,
object: data.object,
},
}
},
);
return;
}
@@ -331,7 +331,7 @@ export const handleStripeWebhookRefresh = async ({
if (!cus) {
logger.warn(
`Searched for customer by stripe id, but not found: ${stripeCusId}`
`Searched for customer by stripe id, but not found: ${stripeCusId}`,
);
return;
}

View File

@@ -56,7 +56,7 @@ export const calculateMetered1Price = ({
}) => {
const allowance = product.entitlements.metered1.allowance;
const usagePrice = product.prices.find(
(p: any) => p.config.feature_id === metered1Feature.id
(p: any) => p.config.feature_id === metered1Feature.id,
);
const usageConfig = usagePrice.config as UsagePriceConfig;

View File

@@ -76,7 +76,7 @@ export const handleCheckoutSessionCompleted = async ({
console.log(
"Handling checkout.completed: autumn metadata:",
checkoutSession.metadata?.autumn_metadata_id
checkoutSession.metadata?.autumn_metadata_id,
);
if (attachParams.setupPayment) {
@@ -132,14 +132,14 @@ export const handleCheckoutSessionCompleted = async ({
console.log("Inserting products list");
for (const productOptions of attachParams.productsList) {
const product = attachParams.products.find(
(p) => p.id === productOptions.product_id
(p) => p.id === productOptions.product_id,
);
if (!product) {
logger.error(
`checkout.completed: product not found for productOptions: ${JSON.stringify(
productOptions
)}`
productOptions,
)}`,
);
continue;
}
@@ -149,7 +149,7 @@ export const handleCheckoutSessionCompleted = async ({
attachParams: attachToInsertParams(
attachParams,
product,
productOptions.entity_id || undefined
productOptions.entity_id || undefined,
),
subscriptionIds: checkoutSub ? [checkoutSub?.id!] : undefined,
anchorToUnix,
@@ -182,7 +182,7 @@ export const handleCheckoutSessionCompleted = async ({
attachParams,
invoiceId,
logger,
})
}),
);
}

View File

@@ -19,7 +19,7 @@ export const getOptionsFromCheckoutSession = async ({
const usageInAdvanceExists = attachParams.prices.some(
(price) =>
getBillingType(price.config as UsagePriceConfig) ==
BillingType.UsageInAdvance
BillingType.UsageInAdvance,
);
if (!usageInAdvanceExists) {
@@ -54,7 +54,7 @@ export const getOptionsFromCheckoutSession = async ({
}
const index = optionsList.findIndex(
(feature) => feature.internal_feature_id == config.internal_feature_id
(feature) => feature.internal_feature_id == config.internal_feature_id,
);
if (index == -1) {

View File

@@ -92,7 +92,7 @@ export const handleCheckoutSub = async ({
price: emptyPrice,
quantity: 0,
}
: (getEmptyPriceItem({ price: arrearPrice, org }) as any)
: (getEmptyPriceItem({ price: arrearPrice, org }) as any),
);
}
}

View File

@@ -42,7 +42,7 @@ export const handleRemainingSets = async ({
attachParams.apiVersion == APIVersion.v1_4
) {
const replaceIndex = remainingItems.findIndex(
(item) => item.price == config.stripe_price_id
(item) => item.price == config.stripe_price_id,
);
if (replaceIndex != -1) {

View File

@@ -33,7 +33,7 @@ export async function handleCusDiscountDeleted({
if (customer.env !== env || customer.org_id !== org.id) {
logger.info(
`discount.deleted: env or org mismatch, skipping, ${customer.env} !== ${env} || ${customer.org_id} !== ${org.id}`
`discount.deleted: env or org mismatch, skipping, ${customer.env} !== ${env} || ${customer.org_id} !== ${org.id}`,
);
return;
}
@@ -45,7 +45,7 @@ export async function handleCusDiscountDeleted({
});
logger.info(
`discount.deleted:, discount ID: ${discount.id}, found ${redemptions.length} redemptions`
`discount.deleted:, discount ID: ${discount.id}, found ${redemptions.length} redemptions`,
);
if (redemptions.length == 0) return;
@@ -55,12 +55,12 @@ export async function handleCusDiscountDeleted({
r.reward_program.reward.id ===
(typeof discount.coupon == "string"
? discount.coupon
: discount.coupon.id)
: discount.coupon.id),
);
if (discount.subscription) {
logger.info(
`Discount is a subscription, paidProductRedemption: ${paidProductRedemption?.id}`
`Discount is a subscription, paidProductRedemption: ${paidProductRedemption?.id}`,
);
if (!paidProductRedemption) return;
@@ -88,7 +88,7 @@ export async function handleCusDiscountDeleted({
});
} catch (error: any) {
logger.error(
`Failed to update subscription ${discount.subscription} with paid product coupon, error: ${error.message}`
`Failed to update subscription ${discount.subscription} with paid product coupon, error: ${error.message}`,
);
throw error;
}
@@ -119,12 +119,12 @@ export async function handleCusDiscountDeleted({
});
const stripeCus = (await stripeCli.customers.retrieve(
discount.customer
discount.customer,
)) as Stripe.Customer;
if (stripeCus && notNullish(stripeCus.discount)) {
logger.info(
`discount.deleted: stripe customer ${discount.customer} already has a discount`
`discount.deleted: stripe customer ${discount.customer} already has a discount`,
);
return;
}
@@ -138,7 +138,7 @@ export async function handleCusDiscountDeleted({
if (!reward) {
logger.warn(
`discount.deleted: reward ${redemption.reward_program.internal_id} not found`
`discount.deleted: reward ${redemption.reward_program.internal_id} not found`,
);
return;
}
@@ -163,7 +163,7 @@ export async function handleCusDiscountDeleted({
});
logger.info(
`discount.deleted: applied reward ${reward.name} on customer ${customer.name} (${customer.id})`
`discount.deleted: applied reward ${reward.name} on customer ${customer.name} (${customer.id})`,
);
logger.info(`Redemption ID: ${redemption.id}`);
}

View File

@@ -47,7 +47,7 @@ export const handleContUsePrices = async ({
let feature = cusEnt.entitlement.feature;
logger.info(
`Handling invoice.created for in arrear prorated, feature: ${feature.id}`
`Handling invoice.created for in arrear prorated, feature: ${feature.id}`,
);
let replaceables = cusEnt.replaceables.filter((r) => r.delete_next_cycle);

View File

@@ -84,7 +84,7 @@ const handleInArrearProrated = async ({
let feature = cusEnt.entitlement.feature;
logger.info(
`Handling invoice.created for in arrear prorated, feature: ${feature.id}`
`Handling invoice.created for in arrear prorated, feature: ${feature.id}`,
);
let deletedEntities = await EntityService.list({
@@ -100,12 +100,12 @@ const handleInArrearProrated = async ({
}
logger.info(
`✨ Handling in arrear prorated, customer ${customer.name}, org: ${org.slug}`
`✨ Handling in arrear prorated, customer ${customer.name}, org: ${org.slug}`,
);
logger.info(
`Deleting entities, feature ${feature.id}, customer ${customer.id}, org ${org.slug}`,
deletedEntities
deletedEntities,
);
// Get linked cus ents
@@ -119,7 +119,7 @@ const handleInArrearProrated = async ({
}
logger.info(
`Linked cus ent: ${linkedCusEnt.feature_id}, isLinked: ${isLinked}`
`Linked cus ent: ${linkedCusEnt.feature_id}, isLinked: ${isLinked}`,
);
// Delete cus ent ids
@@ -140,7 +140,7 @@ const handleInArrearProrated = async ({
console.log(`Updated ${updated.length} cus ents`);
logger.info(
`Feature: ${feature.id}, customer: ${customer.id}, deleted entities from cus ent`
`Feature: ${feature.id}, customer: ${customer.id}, deleted entities from cus ent`,
);
linkedCusEnt.entities = newEntities;
}
@@ -154,7 +154,7 @@ const handleInArrearProrated = async ({
logger.info(
`Feature: ${feature.id}, Deleted ${
deletedEntities.length
}, entities: ${deletedEntities.map((e) => `${e.id}`).join(", ")}`
}, entities: ${deletedEntities.map((e) => `${e.id}`).join(", ")}`,
);
// Increase balance
@@ -319,13 +319,13 @@ export const handleInvoiceCreated = async ({
if (activeProducts.length == 0) {
logger.warn(
`Stripe invoice.created -- no active products found (${org.slug})`
`Stripe invoice.created -- no active products found (${org.slug})`,
);
return;
}
let internalEntityId = activeProducts.find(
(p) => p.internal_entity_id
(p) => p.internal_entity_id,
)?.internal_entity_id;
let features = await FeatureService.list({

View File

@@ -51,7 +51,7 @@ export const handlePrepaidPrices = async ({
if (!cusEnt) {
logger.error(
`Tried to handle prepaid price for ${cusPrice.id} (${cusPrice.price.id}) but no cus ent found`
`Tried to handle prepaid price for ${cusPrice.id} (${cusPrice.price.id}) but no cus ent found`,
);
return;
}

View File

@@ -50,8 +50,8 @@ export const handleUsagePrices = async ({
Math.abs(
differenceInMinutes(
new Date(activeProduct.created_at),
new Date(invoice.created * 1000)
)
new Date(invoice.created * 1000),
),
) < 10;
let invoiceFromUpgrade =
@@ -106,7 +106,7 @@ export const handleUsagePrices = async ({
} else {
if (!config.stripe_meter_id) {
logger.warn(
`Price ${price.id} has no stripe meter id, skipping invoice.created for usage in arrear`
`Price ${price.id} has no stripe meter id, skipping invoice.created for usage in arrear`,
);
return;
}
@@ -118,7 +118,7 @@ export const handleUsagePrices = async ({
});
const usageTimestamp = Math.round(
subDays(new Date(invoice.created * 1000), 1).getTime() / 1000
subDays(new Date(invoice.created * 1000), 1).getTime() / 1000,
);
await submitUsageToStripe({

View File

@@ -69,7 +69,7 @@ export const handleInvoiceFinalized = async ({
}
let prices = activeProducts.flatMap((cp) =>
cp.customer_prices.map((cpr: FullCustomerPrice) => cpr.price)
cp.customer_prices.map((cpr: FullCustomerPrice) => cpr.price),
);
let invoiceItems = await getInvoiceItems({

View File

@@ -78,7 +78,7 @@ export const handleSubCreated = async ({
try {
subUsageFeatures = JSON.parse(subscription.metadata?.usage_features);
subUsageFeatures = subUsageFeatures.map(
(feature: any) => feature.internal_id
(feature: any) => feature.internal_id,
);
} catch (error) {
console.log("Error parsing usage features", error);
@@ -102,7 +102,7 @@ export const handleSubCreated = async ({
console.log(
"Handling subscription.created for scheduled cus products:",
cusProds.length
cusProds.length,
);
let batchUpdate = [];
@@ -131,7 +131,7 @@ export const handleSubCreated = async ({
let invoiceItems = await getInvoiceItems({
stripeInvoice: invoice,
prices: cusProd.customer_prices.map(
(cpr: FullCustomerPrice) => cpr.price
(cpr: FullCustomerPrice) => cpr.price,
),
logger,
});
@@ -171,7 +171,7 @@ export const handleSubCreated = async ({
.map((cp) => cp.price)
.filter(
(p: Price) =>
getBillingType(p.config as any) == BillingType.UsageInArrear
getBillingType(p.config as any) == BillingType.UsageInArrear,
);
if (arrearPrices.length == 0) {
@@ -181,7 +181,7 @@ export const handleSubCreated = async ({
let itemsToDelete = [];
for (const arrearPrice of arrearPrices) {
let subItem = subscription.items.data.find(
(i) => i.price.id == arrearPrice.config?.stripe_price_id
(i) => i.price.id == arrearPrice.config?.stripe_price_id,
);
if (!subItem) {
@@ -200,12 +200,12 @@ export const handleSubCreated = async ({
items: itemsToDelete,
});
console.log(
`sub.created, cus product with entity: deleted ${itemsToDelete.length} items`
`sub.created, cus product with entity: deleted ${itemsToDelete.length} items`,
);
} catch (error) {
logger.error(
`sub.created, cus product with entity: failed to delete items`,
error
error,
);
}
}

View File

@@ -30,7 +30,7 @@ export const handleSubDeleted = async ({
if (activeCusProducts.length === 0) {
if (data.livemode) {
logger.warn(
`subscription.deleted: ${data.id} - no customer products found`
`subscription.deleted: ${data.id} - no customer products found`,
);
return;
}
@@ -47,14 +47,14 @@ export const handleSubDeleted = async ({
cancellationComment === "autumn_cancel"
) {
logger.info(
`sub.deleted: ${subscription.id} from ${cancellationComment}, skipping`
`sub.deleted: ${subscription.id} from ${cancellationComment}, skipping`,
);
return;
}
if (cancellationComment?.includes("trial_canceled")) {
logger.info(
`sub.deleted: ${subscription.id} from trial canceled, skipping`
`sub.deleted: ${subscription.id} from trial canceled, skipping`,
);
return;
}

View File

@@ -68,7 +68,7 @@ export const handleCusProductDeleted = async ({
if (usagePrices.length > 0) {
logger.info(
`sub.deleted, submitting usage for ${fullCus.id}, ${cusProduct.product.name}`
`sub.deleted, submitting usage for ${fullCus.id}, ${cusProduct.product.name}`,
);
await createUsageInvoice({
@@ -89,14 +89,14 @@ export const handleCusProductDeleted = async ({
if (scheduled_ids && scheduled_ids.length > 0 && !prematurelyCanceled) {
logger.info(
`sub.deleted: removing sub_id from cus product ${cusProduct.id}`
`sub.deleted: removing sub_id from cus product ${cusProduct.id}`,
);
await CusProductService.update({
db,
cusProductId: cusProduct.id,
updates: {
subscription_ids: cusProduct.subscription_ids?.filter(
(id) => id !== subscription.id
(id) => id !== subscription.id,
),
},
});

View File

@@ -93,7 +93,7 @@ export const handleSubscriptionUpdated = async ({
if (updatedCusProducts.length > 0) {
logger.info(
`✅ Updated ${updatedCusProducts.length} customer product${updatedCusProducts.length === 1 ? "" : "s"} (${updatedCusProducts.map((cp) => cp.id).join(", ")}) - Status: ${updatedCusProducts[0].status}${updatedCusProducts[0].canceled_at ? `, Canceled: ${new Date(updatedCusProducts[0].canceled_at).toISOString()}` : ""}`
`✅ Updated ${updatedCusProducts.length} customer product${updatedCusProducts.length === 1 ? "" : "s"} (${updatedCusProducts.map((cp) => cp.id).join(", ")}) - Status: ${updatedCusProducts[0].status}${updatedCusProducts[0].canceled_at ? `, Canceled: ${new Date(updatedCusProducts[0].canceled_at).toISOString()}` : ""}`,
);
}
@@ -121,7 +121,7 @@ export const handleSubscriptionUpdated = async ({
} catch (error) {
logger.warn(
`Failed to update sub from stripe. Stripe sub ID: ${subscription.id}, org: ${org.slug}, env: ${env}`,
error
error,
);
}
@@ -133,11 +133,11 @@ export const handleSubscriptionUpdated = async ({
});
const latestInvoice = await stripeCli.invoices.retrieve(
subscription.latest_invoice
subscription.latest_invoice,
);
logger.info(
`Latest invoice billing reason: ${latestInvoice.billing_reason}`
`Latest invoice billing reason: ${latestInvoice.billing_reason}`,
);
logger.info(`Latest invoice status: ${latestInvoice.status}`);
@@ -155,7 +155,7 @@ export const handleSubscriptionUpdated = async ({
latestInvoiceStatus: latestInvoice.status,
latestInvoiceBillingReason: latestInvoice.billing_reason,
},
}
},
);
return;
}
@@ -171,7 +171,7 @@ export const handleSubscriptionUpdated = async ({
latestInvoiceStatus: latestInvoice.status,
latestInvoiceBillingReason: latestInvoice.billing_reason,
},
}
},
);
await stripeCli.subscriptions.cancel(subscription.id);
await stripeCli.invoices.voidInvoice(subscription.latest_invoice);
@@ -187,7 +187,7 @@ export const handleSubscriptionUpdated = async ({
latestInvoiceStatus: latestInvoice.status,
latestInvoiceBillingReason: latestInvoice.billing_reason,
},
}
},
);
}
}

View File

@@ -31,7 +31,7 @@ export const handleSchedulePhaseCompleted = async ({
subObject.schedule as string,
{
expand: ["customer"],
}
},
);
const cusProducts = await CusProductService.getByScheduleId({
@@ -52,7 +52,7 @@ export const handleSchedulePhaseCompleted = async ({
if (shouldExpire) {
logger.info(
`Expiring cus product: ${cusProduct.product.name} (entity ID: ${cusProduct.entity_id})`
`Expiring cus product: ${cusProduct.product.name} (entity ID: ${cusProduct.entity_id})`,
);
await CusProductService.update({
db: req.db,
@@ -104,7 +104,7 @@ export const handleSchedulePhaseCompleted = async ({
const currentPhase = schedule.phases.findIndex(
(phase) =>
phase.start_date <= Math.floor(now / 1000) &&
(phase.end_date ? phase.end_date > Math.floor(now / 1000) : true)
(phase.end_date ? phase.end_date > Math.floor(now / 1000) : true),
);
if (
@@ -123,7 +123,7 @@ export const handleSchedulePhaseCompleted = async ({
});
} catch (error: any) {
logger.error(
`schedule.phase.completed: failed to cancel schedule ${schedule.id}, error: ${error.message}`
`schedule.phase.completed: failed to cancel schedule ${schedule.id}, error: ${error.message}`,
);
}
}

View File

@@ -62,7 +62,7 @@ const updateCusProductCanceled = async ({
}
logger.info(
`Updating cus products for sub ${sub.id} to canceled | canceled_at: ${canceledAt}`
`Updating cus products for sub ${sub.id} to canceled | canceled_at: ${canceledAt}`,
);
await CusProductService.updateByStripeSubId({
@@ -145,8 +145,8 @@ export const handleSubCanceled = async ({
let defaultProducts = allDefaultProducts.filter((p) =>
updatedCusProducts.some(
(cp: FullCusProduct) =>
cp.product.group == p.group && nullish(cp.internal_entity_id)
)
cp.product.group == p.group && nullish(cp.internal_entity_id),
),
);
if (defaultProducts.length == 0) return;
@@ -156,14 +156,14 @@ export const handleSubCanceled = async ({
const productNames = defaultProducts.map((p) => p.name).join(", ");
const periodEnd = formatUnixToDateTime(end * 1000);
logger.info(
`subscription.updated: canceled -> attempting to schedule default products: ${productNames}, period end: ${periodEnd}`
`subscription.updated: canceled -> attempting to schedule default products: ${productNames}, period end: ${periodEnd}`,
);
}
let scheduledCusProducts: FullCusProduct[] = [];
for (let product of defaultProducts) {
let alreadyScheduled = cusProducts.some(
(cp: FullCusProduct) => cp.product.group == product.group
(cp: FullCusProduct) => cp.product.group == product.group,
);
if (alreadyScheduled) {
@@ -205,7 +205,7 @@ export const handleSubCanceled = async ({
scenario: AttachScenario.Cancel,
cusProduct: cusProd,
scheduledCusProduct: scheduledCusProducts.find(
(cp) => cp.product.group === cusProd.product.group
(cp) => cp.product.group === cusProd.product.group,
),
});
} catch (error) {}

View File

@@ -103,7 +103,7 @@ export const handleSubRenewed = async ({
if (curScheduledProduct) {
logger.info(
`sub.updated: renewed -> removing scheduled: ${curScheduledProduct.product.name}, main product: ${updatedCusProducts[0].product.name}`
`sub.updated: renewed -> removing scheduled: ${curScheduledProduct.product.name}, main product: ${updatedCusProducts[0].product.name}`,
);
await CusProductService.delete({
@@ -126,7 +126,7 @@ export const handleSubRenewed = async ({
scenario: AttachScenario.Renew,
cusProduct: cusProd,
deletedCusProduct: deletedCusProducts.find(
(cp) => cp.product.group === cusProd.product.group
(cp) => cp.product.group === cusProd.product.group,
),
});
}

View File

@@ -14,7 +14,9 @@ export const subscribeToOrgUpdates = async ({ db }: { db: DrizzleCli }) => {
}
});
console.log("Successfully subscribed to organization updates via PostgreSQL LISTEN/NOTIFY");
console.log(
"Successfully subscribed to organization updates via PostgreSQL LISTEN/NOTIFY",
);
} catch (error) {
console.warn("Error subscribing to org updates:", error);
}

View File

@@ -25,7 +25,7 @@ const fetchWithRetry = fetchRetry(fetch, {
console.warn(
`Retrying request... Attempt #${attempt + 1} - Status: ${
response?.status
}`
}`,
);
return true;
}
@@ -38,7 +38,7 @@ export const createSupabaseClient = () => {
try {
return createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_SERVICE_KEY!
process.env.SUPABASE_SERVICE_KEY!,
);
} catch (error) {
console.error("Error creating Supabase client:", error);

View File

@@ -5,7 +5,7 @@ export const verifySvixSignature = async (req: any, res: any) => {
if (!SIGNING_SECRET) {
throw new Error(
"Error: Please add SIGNING_SECRET from Clerk Dashboard to .env"
"Error: Please add SIGNING_SECRET from Clerk Dashboard to .env",
);
}
@@ -43,7 +43,7 @@ export const verifySvixSignature = async (req: any, res: any) => {
// Use constant-time comparison to prevent timing attacks
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(svixSignature)
Buffer.from(svixSignature),
);
} catch (err) {
return false;

View File

@@ -68,7 +68,7 @@ const init = async () => {
"If-Modified-Since",
"If-Unmodified-Since",
],
})
}),
);
app.all("/api/auth/*", toNodeHandler(auth));

View File

@@ -33,6 +33,8 @@ WHERE
const resultJson = await result.json();
return (resultJson.data as { total_payment_volume: number, label: string }[])[0];
return (
resultJson.data as { total_payment_volume: number; label: string }[]
)[0];
}
}

View File

@@ -84,14 +84,14 @@ analyticsRouter.post("", (req, res) =>
});
let usageList = events.data.filter(
(event: any) => event.period <= Date.now()
(event: any) => event.period <= Date.now(),
);
res.status(200).json({
list: usageList,
});
},
})
}),
);
export { analyticsRouter };

View File

@@ -20,7 +20,7 @@ export async function getBillingCycleStartDate(
orgId: string,
customer?: FullCustomer,
db?: DrizzleCli,
intervalType?: "1bc" | "3bc"
intervalType?: "1bc" | "3bc",
) {
// If no customer provided, return empty object (for aggregateAll case)
if (!customer || !db || !intervalType) {
@@ -42,13 +42,13 @@ export async function getBillingCycleStartDate(
const subscriptions = customer.subscriptions || [];
const cusProducts = customer.customer_products.filter(
(product: FullCusProduct) => ACTIVE_STATUSES.includes(product.status)
(product: FullCusProduct) => ACTIVE_STATUSES.includes(product.status),
);
if (cusProducts.length === 0) return {};
const fullProducts = cusProducts.map((cp: FullCusProduct) =>
cusProductToProduct({ cusProduct: cp })
cusProductToProduct({ cusProduct: cp }),
);
const areAllProductsFree = checkIfAllProductsAreFree(fullProducts);
@@ -64,7 +64,7 @@ export async function getBillingCycleStartDate(
}
export function checkIfAllProductsAreFree(
fullProducts: FullProduct[]
fullProducts: FullProduct[],
): boolean {
return fullProducts.every((product: FullProduct) => {
const isFree = isFreeProduct(product.prices);
@@ -79,7 +79,7 @@ export function formatDateToString(date: Date): string {
export function getDateRangesFromSubscriptions(
customerProductsFiltered: FullCusProduct[],
subscriptions: Subscription[]
subscriptions: Subscription[],
): { startDates: string[]; endDates: string[] } {
const startDates: string[] = [];
const endDates: string[] = [];
@@ -88,19 +88,19 @@ export function getDateRangesFromSubscriptions(
product.subscription_ids?.forEach((subscriptionId: string) => {
const subscription = subscriptions.find(
(subscription: Subscription) =>
subscription.stripe_id === subscriptionId
subscription.stripe_id === subscriptionId,
);
if (subscription) {
startDates.push(
formatDateToString(
new Date((subscription.current_period_start ?? 0) * 1000)
)
new Date((subscription.current_period_start ?? 0) * 1000),
),
);
endDates.push(
formatDateToString(
new Date((subscription.current_period_end ?? 0) * 1000)
)
new Date((subscription.current_period_end ?? 0) * 1000),
),
);
}
});
@@ -110,7 +110,7 @@ export function getDateRangesFromSubscriptions(
}
export function getDateRangesFromEntitlements(
customerProducts?: FullCusProduct[]
customerProducts?: FullCusProduct[],
): { startDates: string[]; endDates: string[] } {
const startDates: string[] = [];
const endDates: string[] = [];
@@ -120,8 +120,8 @@ export function getDateRangesFromEntitlements(
JSON.stringify(
customerProducts?.map((x) => x.customer_entitlements),
null,
4
)
4,
),
);
if (!customerProducts || customerProducts.length < 1) {
@@ -140,20 +140,20 @@ export function getDateRangesFromEntitlements(
(entitlement: FullCustomerEntitlement) => {
if (entitlement.next_reset_at) {
endDates.push(
formatDateToString(new Date(entitlement.next_reset_at))
formatDateToString(new Date(entitlement.next_reset_at)),
);
}
const startDate = calculateStartDateFromInterval(
entitlement.entitlement.interval,
entitlement.next_reset_at,
entitlement.created_at
entitlement.created_at,
);
if (startDate) {
startDates.push(startDate);
}
}
},
);
});
@@ -163,7 +163,7 @@ export function getDateRangesFromEntitlements(
export function calculateBillingCycleResult(
startDates: string[],
endDates: string[],
intervalType: "1bc" | "3bc"
intervalType: "1bc" | "3bc",
) {
const startDate = new Date(startDates[0]);
const endDate = new Date(endDates[0]);
@@ -180,7 +180,7 @@ export function calculateBillingCycleResult(
export function calculateStartDateFromInterval(
interval: EntInterval | null | undefined,
nextResetAt: number | null | undefined,
createdAt: number
createdAt: number,
): string | null {
if (!nextResetAt && interval !== EntInterval.Lifetime) {
return null;
@@ -197,7 +197,7 @@ export function calculateStartDateFromInterval(
return formatDateToString(new Date(nextResetAt! - 24 * 60 * 60 * 1000));
case EntInterval.Week:
return formatDateToString(
new Date(nextResetAt! - 7 * 24 * 60 * 60 * 1000)
new Date(nextResetAt! - 7 * 24 * 60 * 60 * 1000),
);
case EntInterval.Month:
const monthResetDate = new Date(nextResetAt!);
@@ -222,7 +222,7 @@ export function calculateStartDateFromInterval(
export function generateEventCountExpressions(
eventNames: string[],
noCount: boolean = false
noCount: boolean = false,
): string {
const expressions = eventNames.map((eventName) => {
// Replicate ClickHouse's replaceAll(eventName, '''', '''''')

View File

@@ -179,7 +179,7 @@ export const handleProductsUpdated = async ({
await ActionService.insert(db, action);
} else {
logger.warn(
"products.updated, no req object found, skipping action insert"
"products.updated, no req object found, skipping action insert",
);
}
} catch (error: any) {

View File

@@ -55,7 +55,7 @@ analyticsRouter.get("/event_names", async (req: any, res: any) =>
features.some(
(feature: Feature) =>
feature.type == FeatureType.Metered &&
feature.config.filters?.[0]?.value.includes(result[i])
feature.config.filters?.[0]?.value.includes(result[i]),
)
) {
eventNames.push(result[i]);
@@ -73,7 +73,7 @@ analyticsRouter.get("/event_names", async (req: any, res: any) =>
eventNames,
});
},
})
}),
);
const getTopEvents = async ({ req }: { req: ExtendedRequest }) => {
@@ -106,7 +106,7 @@ const getTopEvents = async ({ req }: { req: ExtendedRequest }) => {
features.some(
(feature: Feature) =>
feature.type == FeatureType.Metered &&
feature.config.filters?.[0]?.value.includes(result[i])
feature.config.filters?.[0]?.value.includes(result[i]),
)
) {
eventNames.push(result[i]);
@@ -201,7 +201,7 @@ analyticsRouter.post("/events", async (req: any, res: any) =>
bcExclusionFlag,
});
},
})
}),
);
analyticsRouter.post("/raw", async (req: any, res: any) =>
@@ -253,5 +253,5 @@ analyticsRouter.post("/raw", async (req: any, res: any) =>
rawEvents: events,
});
},
})
}),
);

View File

@@ -167,9 +167,9 @@ export class CusBatchService {
: null,
balance: ce.balance ? parseFloat(ce.balance) || 0 : 0,
adjustment: ce.adjustment ? parseFloat(ce.adjustment) || 0 : 0,
})
}),
),
})
}),
);
}

View File

@@ -35,18 +35,18 @@ const schema = z.object({
}),
{
invalid_type_error: "statuses must be an array of strings",
}
},
)
.optional()
.refine(
(statuses) =>
!statuses ||
statuses.every((status) =>
Object.values(CusProductStatus).includes(status)
Object.values(CusProductStatus).includes(status),
),
{
message: `statuses must contain only valid values: ${Object.values(CusProductStatus).join(", ")}`,
}
},
),
});

View File

@@ -61,13 +61,13 @@ export const getSingleEntityResponse = async ({
p.internal_entity_id == entity.internal_id ||
nullish(p.internal_entity_id)
);
}
},
);
let entitySubs = (fullCus.subscriptions || []).filter((s: Subscription) =>
entityCusProducts.some((p: FullCusProduct) =>
p.subscription_ids?.includes(s.stripe_id || "")
)
p.subscription_ids?.includes(s.stripe_id || ""),
),
);
let { main, addOns } = await processFullCusProducts({
@@ -151,7 +151,7 @@ export const getEntityResponse = async ({
for (const entityId of entityIds) {
const entity = fullCus.entities.find(
(e: Entity) => e.id == entityId || e.internal_id == entityId
(e: Entity) => e.id == entityId || e.internal_id == entityId,
);
if (!entity) {

View File

@@ -52,7 +52,7 @@ export const handleGetEntity = async (req: any, res: any) =>
logger,
})
: undefined,
})
}),
);
},
});

View File

@@ -135,7 +135,7 @@ checkRouter.post("", async (req: any, res: any) => {
const { allowed, balance } = v2Response;
const featureToUse = allFeatures.find(
(f: Feature) => f.id === v2Response.feature_id
(f: Feature) => f.id === v2Response.feature_id,
);
if (allowed && req.isPublic !== true) {

View File

@@ -151,7 +151,7 @@ export const getOptions = ({
}
const currentOptions = cusProduct?.options.find(
(o) => o.feature_id == i.feature_id
(o) => o.feature_id == i.feature_id,
);
let currentQuantity = currentOptions?.quantity;

View File

@@ -22,7 +22,7 @@ const getFeatureAndCreditSystems = ({
const { features } = req;
const feature: Feature | undefined = features.find(
(feature: Feature) => feature.id === featureId
(feature: Feature) => feature.id === featureId,
);
const creditSystems = getCreditSystemsFromFeature({
@@ -83,7 +83,7 @@ export const getCheckData = async ({ req }: { req: any }) => {
cusEnt,
entity: customer.entity!,
features: allFeatures,
})
}),
);
}

View File

@@ -26,12 +26,12 @@ export const getFeatureToUse = ({
}) => {
// 1. If there's a credit system
let featureCusEnts = cusEnts.filter((cusEnt) =>
cusEntMatchesFeature({ cusEnt, feature })
cusEntMatchesFeature({ cusEnt, feature }),
);
if (creditSystems.length > 0) {
let creditCusEnts = cusEnts.filter((cusEnt) =>
cusEntMatchesFeature({ cusEnt, feature: creditSystems[0] })
cusEntMatchesFeature({ cusEnt, feature: creditSystems[0] }),
);
if (creditCusEnts.length > 0) {
@@ -75,7 +75,7 @@ export const getV2CheckResponse = async ({
});
const featureCusEnts = cusEnts.filter((cusEnt) =>
cusEntMatchesFeature({ cusEnt, feature: featureToUse })
cusEntMatchesFeature({ cusEnt, feature: featureToUse }),
);
const { unlimited, usageAllowed } = getUnlimitedAndUsageAllowed({
@@ -84,7 +84,7 @@ export const getV2CheckResponse = async ({
});
const cusPrices = cusProducts.flatMap(
(cusProduct) => cusProduct.customer_prices
(cusProduct) => cusProduct.customer_prices,
);
const balances = await getCusBalances({

View File

@@ -66,8 +66,8 @@ export class EventService {
and(
eq(events.internal_customer_id, internalCustomerId),
eq(events.org_id, orgId),
eq(events.env, env)
)
eq(events.env, env),
),
)
.orderBy(desc(events.created_at))
.limit(limit);

View File

@@ -129,7 +129,7 @@ const getAffectedFeatures = async ({
creditSystemContainsFeature({
creditSystem: cs,
meteredFeatureId: f.id,
})
}),
)
);
});

View File

@@ -56,7 +56,7 @@ const getCusFeatureAndOrg = async ({
creditSystemContainsFeature({
creditSystem: f,
meteredFeatureId: featureId,
})
}),
);
if (!feature) {

View File

@@ -58,7 +58,7 @@ export default async (req: any, res: any) =>
{
db,
referralCodeId: referralCode.id,
}
},
);
if (

View File

@@ -37,7 +37,9 @@ export default async (req: any, res: any) =>
try {
await stripeCli.coupons.del(reward.id);
} catch (error) {
console.log(`Failed to delete coupon from stripe: ${(error as { message: string }).message}`);
console.log(
`Failed to delete coupon from stripe: ${(error as { message: string }).message}`,
);
}
await RewardService.delete({

View File

@@ -1,7 +1,8 @@
import { RewardService } from "@/internal/rewards/RewardService.js";
import { routeHandler } from "@/utils/routerUtils.js";
export default async (req: any, res: any) => routeHandler({
export default async (req: any, res: any) =>
routeHandler({
req,
res,
action: "get reward",
@@ -17,5 +18,5 @@ export default async (req: any, res: any) => routeHandler({
});
res.status(200).json(reward);
}
});
},
});

View File

@@ -3,4 +3,9 @@ import handleDeleteCoupon from "./handleDeleteCoupon.js";
import handleGetCoupon from "./handleGetCoupon.js";
import handleUpdateCoupon from "./handleUpdateCoupon.js";
export { handleCreateCoupon, handleDeleteCoupon, handleGetCoupon, handleUpdateCoupon };
export {
handleCreateCoupon,
handleDeleteCoupon,
handleGetCoupon,
handleUpdateCoupon,
};

View File

@@ -88,5 +88,5 @@ rewardProgramRouter.put("/:id", (req, res) =>
return res.status(200).json(updatedRewardProgram);
},
})
}),
);

View File

@@ -1,5 +1,10 @@
import express, { type Router } from "express";
import { handleCreateCoupon, handleDeleteCoupon, handleGetCoupon, handleUpdateCoupon } from "./handlers/rewards/index.js";
import {
handleCreateCoupon,
handleDeleteCoupon,
handleGetCoupon,
handleUpdateCoupon,
} from "./handlers/rewards/index.js";
const rewardRouter: Router = express.Router();

View File

@@ -67,7 +67,7 @@ trmnlRouter.post("/device_id", withOrgAuth, async (req: any, res: any) => {
upstash = upstash!;
const trmnlConfig = (await upstash.get(
`trmnl:device:${req.body.deviceId}`
`trmnl:device:${req.body.deviceId}`,
)) as {
orgId: string;
hideRevenue: boolean;
@@ -229,7 +229,7 @@ trmnlRouter.post(
hideRevenue: req.org.hideRevenue,
});
},
})
}),
);
export { trmnlRouter };

View File

@@ -113,7 +113,7 @@ export class CusSearchService {
// 1. Create base query to fetch all customerproducts
let activeProdFilter = or(
eq(customerProducts.status, CusProductStatus.Active),
eq(customerProducts.status, CusProductStatus.PastDue)
eq(customerProducts.status, CusProductStatus.PastDue),
);
if (filters.status && filters.status.length > 0) {
@@ -142,9 +142,9 @@ export class CusSearchService {
...productVersionFilters.map((pv) =>
and(
eq(customerProducts.product_id, pv.productId),
eq(products.version, pv.version)
)
)
eq(products.version, pv.version),
),
),
)
: undefined,
// Legacy product filtering (fallback)
@@ -158,13 +158,13 @@ export class CusSearchService {
case "canceled":
return and(
isNotNull(customerProducts.canceled_at),
activeProdFilter
activeProdFilter,
);
case "free_trial":
return and(
gt(customerProducts.trial_ends_at, Date.now()),
isNotNull(customerProducts.free_trial_id),
activeProdFilter
activeProdFilter,
);
case CusProductStatus.Expired:
return and(
@@ -178,32 +178,32 @@ export class CusSearchService {
and(
eq(
customerProductsAlias.internal_customer_id,
customerProducts.internal_customer_id
customerProducts.internal_customer_id,
),
eq(
customerProductsAlias.product_id,
customerProducts.product_id
customerProducts.product_id,
),
or(
eq(
customerProductsAlias.status,
CusProductStatus.Active
CusProductStatus.Active,
),
eq(
customerProductsAlias.status,
CusProductStatus.PastDue
)
)
)
)
)
CusProductStatus.PastDue,
),
),
),
),
),
);
default:
return eq(customerProducts.status, status);
}
})
}),
)
: undefined
: undefined,
);
let cusFilter = and(
@@ -214,9 +214,9 @@ export class CusSearchService {
? or(
ilike(customers.id, `%${search}%`),
ilike(customers.name, `%${search}%`),
ilike(customers.email, `%${search}%`)
ilike(customers.email, `%${search}%`),
)
: undefined
: undefined,
);
// Build the where clause
@@ -232,7 +232,7 @@ export class CusSearchService {
const whereClause = and(
shouldApplyActiveFilter ? activeProdFilter : undefined,
filtersDrizzle,
cusFilter
cusFilter,
// resolvedLastItem && resolvedLastItem.internal_id
// ? lt(customers.internal_id, resolvedLastItem.internal_id)
// : undefined
@@ -252,18 +252,18 @@ export class CusSearchService {
.from(customerProducts)
.leftJoin(
customers,
eq(customerProducts.internal_customer_id, customers.internal_id)
eq(customerProducts.internal_customer_id, customers.internal_id),
);
if (hasProductFilters) {
return baseQuery.innerJoin(
products,
eq(customerProducts.internal_product_id, products.internal_id)
eq(customerProducts.internal_product_id, products.internal_id),
);
} else {
return baseQuery.leftJoin(
products,
eq(customerProducts.internal_product_id, products.internal_id)
eq(customerProducts.internal_product_id, products.internal_id),
);
}
};
@@ -290,24 +290,24 @@ export class CusSearchService {
const baseCountQuery = db
.select({
totalCount: sql<number>`count(distinct ${customers.internal_id})`.as(
"total_count"
"total_count",
),
})
.from(customerProducts)
.leftJoin(
customers,
eq(customerProducts.internal_customer_id, customers.internal_id)
eq(customerProducts.internal_customer_id, customers.internal_id),
);
if (hasProductFilters) {
return baseCountQuery.innerJoin(
products,
eq(customerProducts.internal_product_id, products.internal_id)
eq(customerProducts.internal_product_id, products.internal_id),
);
} else {
return baseCountQuery.leftJoin(
products,
eq(customerProducts.internal_product_id, products.internal_id)
eq(customerProducts.internal_product_id, products.internal_id),
);
}
};
@@ -318,8 +318,8 @@ export class CusSearchService {
and(
shouldApplyActiveFilter ? activeProdFilter : undefined,
filtersDrizzle,
cusFilter
)
cusFilter,
),
),
]);
@@ -379,10 +379,10 @@ export class CusSearchService {
or(
eq(customerProducts.status, CusProductStatus.Active),
eq(customerProducts.status, CusProductStatus.PastDue),
eq(customerProducts.status, CusProductStatus.Scheduled)
)
)
)
eq(customerProducts.status, CusProductStatus.Scheduled),
),
),
),
);
const baseWhereClause = and(
@@ -392,10 +392,10 @@ export class CusSearchService {
? or(
ilike(customers.id, `%${search}%`),
ilike(customers.name, `%${search}%`),
ilike(customers.email, `%${search}%`)
ilike(customers.email, `%${search}%`),
)
: undefined,
noneFilter
noneFilter,
);
let baseQuery;
@@ -434,11 +434,11 @@ export class CusSearchService {
? or(
ilike(customers.id, `%${search}%`),
ilike(customers.name, `%${search}%`),
ilike(customers.email, `%${search}%`)
ilike(customers.email, `%${search}%`),
)
: undefined,
noneFilter
)
noneFilter,
),
),
]);
@@ -482,8 +482,8 @@ export class CusSearchService {
and(
eq(customers.internal_id, lastItem.internal_id),
eq(customers.org_id, orgId),
eq(customers.env, env)
)
eq(customers.env, env),
),
)
.limit(1);
@@ -533,9 +533,9 @@ export class CusSearchService {
? or(
ilike(customers.id, `%${search}%`),
ilike(customers.name, `%${search}%`),
ilike(customers.email, `%${search}%`)
ilike(customers.email, `%${search}%`),
)
: undefined
: undefined,
);
// Build the where clause for base query
@@ -543,7 +543,7 @@ export class CusSearchService {
filterClause,
resolvedLastItem && resolvedLastItem.internal_id
? lt(customers.internal_id, resolvedLastItem.internal_id)
: undefined
: undefined,
);
// Create the base customer query as a subquery with appropriate pagination
@@ -598,11 +598,11 @@ export class CusSearchService {
.from(baseQuery)
.leftJoin(
customerProducts,
eq(baseQuery.internal_id, customerProducts.internal_customer_id)
eq(baseQuery.internal_id, customerProducts.internal_customer_id),
)
.leftJoin(
products,
eq(customerProducts.internal_product_id, products.internal_id)
eq(customerProducts.internal_product_id, products.internal_id),
)
.orderBy(desc(baseQuery.internal_id)),
totalCountQuery,

View File

@@ -73,7 +73,7 @@ export class CusService {
withTrialsUsed,
withSubs,
withEvents,
entityId
entityId,
);
let result = await db.execute(query);
@@ -124,10 +124,10 @@ export class CusService {
where: and(
or(
eq(customers.id, idOrInternalId),
eq(customers.internal_id, idOrInternalId)
eq(customers.internal_id, idOrInternalId),
),
eq(customers.org_id, orgId),
eq(customers.env, env)
eq(customers.env, env),
),
});
@@ -153,7 +153,7 @@ export class CusService {
where: and(
ilike(customers.email, email),
eq(customers.org_id, orgId),
eq(customers.env, env)
eq(customers.env, env),
),
});
@@ -276,8 +276,8 @@ export class CusService {
and(
eq(customers.internal_id, internalId),
eq(customers.org_id, orgId),
eq(customers.env, env)
)
eq(customers.env, env),
),
)
.returning();

View File

@@ -201,7 +201,7 @@ export const expireOrDeleteCusProduct = async ({
cp.status === CusProductStatus.Scheduled &&
(internalEntityId
? cp.internal_entity_id === internalEntityId
: nullish(cp.internal_entity_id))
: nullish(cp.internal_entity_id)),
);
if (curScheduledProduct) {
@@ -354,7 +354,7 @@ export const createFullCusProduct = async ({
const cusProdId = generateId("cus_prod");
logger.info(
`Inserting cus product ${product.id} for ${customer.name}, cus product ID: ${cusProdId}`
`Inserting cus product ${product.id} for ${customer.name}, cus product ID: ${cusProdId}`,
);
logger.info(productOptions);
@@ -499,7 +499,7 @@ export const createFullCusProduct = async ({
db,
rows: operation.toInsert,
fullCusEnt: operation.cusEnt,
})
}),
);
}
@@ -521,7 +521,7 @@ export const createFullCusProduct = async ({
// db,
// cusEntID: ce.id,
// }),
}))
})),
);
const fullCusProduct = {

View File

@@ -69,13 +69,13 @@ export const handleCreateCheckout = async ({
getNextStartOfMonthUnix({
interval: itemSets[0].interval,
intervalCount: itemSets[0].intervalCount,
}) / 1000
}) / 1000,
)
: undefined;
if (attachParams.billingAnchor) {
billingCycleAnchorUnixSeconds = Math.floor(
attachParams.billingAnchor / 1000
attachParams.billingAnchor / 1000,
);
}
@@ -162,7 +162,7 @@ export const handleCreateCheckout = async ({
try {
checkout = await stripeCli.checkout.sessions.create(sessionParams);
logger.info(
`✅ Successfully created checkout for customer ${customer.id || customer.internal_id}`
`✅ Successfully created checkout for customer ${customer.id || customer.internal_id}`,
);
} catch (error: any) {
let msg = error.message;
@@ -177,7 +177,7 @@ export const handleCreateCheckout = async ({
});
logger.info(
`✅ Created fallback checkout session with card payment method for customer ${customer.id || customer.internal_id}`
`✅ Created fallback checkout session with card payment method for customer ${customer.id || customer.internal_id}`,
);
} else {
throw error;
@@ -199,7 +199,7 @@ export const handleCreateCheckout = async ({
}, product(s) ${attachParams.products.map((p) => p.name).join(", ")}`,
product_ids: attachParams.products.map((p) => p.id),
customer_id: customer.id || customer.internal_id,
})
}),
);
} else {
res.status(200).json({

View File

@@ -95,7 +95,7 @@ export const handleCreateInvoiceCheckout = async ({
product_ids: attachParams.products.map((p) => p.id),
customer_id:
attachParams.customer.id || attachParams.customer.internal_id,
})
}),
);
return;
}
@@ -109,7 +109,7 @@ export const handleCreateInvoiceCheckout = async ({
product_ids: attachParams.products.map((p) => p.id),
customer_id:
attachParams.customer.id || attachParams.customer.internal_id,
})
}),
);
}

View File

@@ -35,7 +35,7 @@ export const initCusEntEntities = ({
resetBalance?: number | null;
}) => {
let newEntities: Record<string, EntityBalance> | null = notNullish(
entitlement.entity_feature_id
entitlement.entity_feature_id,
)
? {}
: null;

View File

@@ -139,7 +139,7 @@ export const createStripeSub2 = async ({
latestInvoice.status === "draft"
) {
subscription.latest_invoice = await stripeCli.invoices.finalizeInvoice(
(subscription.latest_invoice as Stripe.Invoice).id!
(subscription.latest_invoice as Stripe.Invoice).id!,
);
}

View File

@@ -18,7 +18,7 @@ export const getMergeCusProduct = async ({
let mergeCusProduct = undefined;
if (!config.disableMerge && !freeTrial) {
mergeCusProduct = cusProducts?.find((cp) =>
products.some((p) => p.group == cp.product.group)
products.some((p) => p.group == cp.product.group),
);
}

View File

@@ -150,7 +150,7 @@ export const handleOneOffFunction = async ({
if (config.invoiceCheckout) {
if (stripeInvoice.status === "draft" && config.finalizeInvoice) {
stripeInvoice = await stripeCli.invoices.finalizeInvoice(
stripeInvoice.id!
stripeInvoice.id!,
);
}
@@ -199,7 +199,7 @@ export const handleOneOffFunction = async ({
db: req.db,
attachParams: attachToInsertParams(attachParams, product),
logger,
})
}),
);
}
await Promise.all(batchInsert);
@@ -226,7 +226,7 @@ export const handleOneOffFunction = async ({
product_ids: products.map((p) => p.id),
customer_id: customer.id || customer.internal_id,
scenario: AttachScenario.New,
})
}),
);
}
};

View File

@@ -253,7 +253,7 @@ export const handlePaidProduct = async ({
}) || 0) * 1000
: undefined),
logger,
})
}),
);
}
await Promise.all(batchInsert);
@@ -272,7 +272,7 @@ export const handlePaidProduct = async ({
invoice: invoiceOnly
? attachToInvoiceResponse({ invoice })
: undefined,
})
}),
);
} else {
res.status(200).json({

View File

@@ -53,7 +53,7 @@ export const handleRenewProduct = async ({
code: SuccessCode.RenewedProduct,
message: `Successfully renewed product ${product.name}`,
product_ids: [product.id],
})
}),
);
return;
}
@@ -63,7 +63,7 @@ export const handleRenewProduct = async ({
(cp) =>
cp.subscription_ids?.includes(curSubId!) &&
cp.canceled &&
cp.id !== curCusProduct?.id
cp.id !== curCusProduct?.id,
);
let expectedEnd = undefined;
@@ -73,7 +73,7 @@ export const handleRenewProduct = async ({
subId: curSubId,
});
const subItems = curSub?.items.data.filter((item) =>
subItemInCusProduct({ cusProduct: curCusProduct!, subItem: item })
subItemInCusProduct({ cusProduct: curCusProduct!, subItem: item }),
);
expectedEnd = getLatestPeriodEnd({ subItems });
}
@@ -117,7 +117,7 @@ export const handleRenewProduct = async ({
// Case 1: Add current cus product back to schedule and remove scheduled product from schedule
if (schedule) {
logger.info(
`RENEW FLOW: adding cur cus product back to schedule ${schedule.id}`
`RENEW FLOW: adding cur cus product back to schedule ${schedule.id}`,
);
const newItems = await paramsToScheduleItems({
req,
@@ -149,7 +149,7 @@ export const handleRenewProduct = async ({
});
} else {
logger.info(
`RENEW FLOW: no new schedule items, releasing schedule ${schedule.id}`
`RENEW FLOW: no new schedule items, releasing schedule ${schedule.id}`,
);
await stripeCli.subscriptionSchedules.release(schedule.id);
@@ -233,7 +233,7 @@ export const handleRenewProduct = async ({
product_ids: [product.id],
customer_id:
attachParams.customer.id || attachParams.customer.internal_id,
})
}),
);
}
};

View File

@@ -46,14 +46,14 @@ export const handleInvoiceCheckoutPaid = async ({
console.log("Inserting products list");
for (const productOptions of attachParams.productsList) {
const product = attachParams.products.find(
(p) => p.id === productOptions.product_id
(p) => p.id === productOptions.product_id,
);
if (!product) {
logger.error(
`checkout.completed: product not found for productOptions: ${JSON.stringify(
productOptions
)}`
productOptions,
)}`,
);
continue;
}
@@ -63,7 +63,7 @@ export const handleInvoiceCheckoutPaid = async ({
attachParams: attachToInsertParams(
attachParams,
product,
productOptions.entity_id || undefined
productOptions.entity_id || undefined,
),
subscriptionIds: subIds,
anchorToUnix,
@@ -84,7 +84,7 @@ export const handleInvoiceCheckoutPaid = async ({
carryExistingUsages: config.carryUsage,
scenario: AttachScenario.New,
logger: req.logger,
})
}),
);
}
@@ -92,6 +92,6 @@ export const handleInvoiceCheckoutPaid = async ({
}
req.logger.info(
`✅ invoice.paid, successfully inserted cus products: ${attachParams.products.map((p) => p.id).join(", ")}`
`✅ invoice.paid, successfully inserted cus products: ${attachParams.products.map((p) => p.id).join(", ")}`,
);
};

View File

@@ -56,11 +56,11 @@ export const getAddAndRemoveProducts = async ({
for (const productOptions of productsList) {
const product = attachParams.products.find(
(p) => p.id === productOptions.product_id
(p) => p.id === productOptions.product_id,
);
const entity = attachParams.customer.entities.find(
(e) => e.id === productOptions.entity_id
(e) => e.id === productOptions.entity_id,
);
const { curSameProduct, curScheduledProduct } = getExistingCusProducts({

View File

@@ -170,7 +170,7 @@ export const handleMultiAttachFlow = async ({
});
for (const productOptions of newProdList) {
const product = attachParams.products.find(
(p) => p.id === productOptions.product_id
(p) => p.id === productOptions.product_id,
)!;
if (productOptions.quantity === 0) continue;
@@ -185,7 +185,7 @@ export const handleMultiAttachFlow = async ({
attachParams: attachToInsertParams(
attachParams,
product,
productOptions.entity_id || undefined
productOptions.entity_id || undefined,
),
subscriptionIds: curSub ? [curSub?.id!] : undefined,
anchorToUnix,
@@ -196,7 +196,7 @@ export const handleMultiAttachFlow = async ({
mergeCusProduct && isTrialing({ cusProduct: mergeCusProduct })
? mergeCusProduct?.trial_ends_at!
: undefined,
})
}),
);
}
@@ -214,8 +214,8 @@ export const handleMultiAttachFlow = async ({
invoice: attachParams.invoiceOnly
? attachToInvoiceResponse({ invoice })
: undefined,
})
)
}),
),
);
}
};

View File

@@ -48,7 +48,7 @@ export const handleScheduleFunction2 = async ({
const curCusProduct = attachParamsToCurCusProduct({ attachParams });
const curSub = await paramsToCurSub({ attachParams });
const subItems = curSub?.items.data.filter((item) =>
subItemInCusProduct({ cusProduct: curCusProduct!, subItem: item })
subItemInCusProduct({ cusProduct: curCusProduct!, subItem: item }),
);
const expectedEnd = getLatestPeriodEnd({ subItems });
@@ -74,7 +74,7 @@ export const handleScheduleFunction2 = async ({
if (currentPhaseIndex == newItems.phases.length - 1) {
logger.info(
`SCHEDULE FLOW: no subsequent phases, releasing schedule ${schedule?.id}`
`SCHEDULE FLOW: no subsequent phases, releasing schedule ${schedule?.id}`,
);
await stripeCli.subscriptionSchedules.release(schedule!.id);
await CusProductService.updateByStripeScheduledId({
@@ -195,7 +195,7 @@ export const handleScheduleFunction2 = async ({
product_ids: [product.id],
customer_id:
attachParams.customer.id || attachParams.customer.internal_id,
})
}),
);
} else {
res.status(200).json({

View File

@@ -73,7 +73,7 @@ export const handleQuantityDowngrade = async ({
.minus(
notNullish(oldOptions.upcoming_quantity)
? oldOptions.upcoming_quantity!
: oldOptions.quantity
: oldOptions.quantity,
)
.toNumber();
@@ -117,7 +117,7 @@ export const handleQuantityDowngrade = async ({
const product = cusProductToProduct({ cusProduct });
const feature = req.features.find(
(f: Feature) => f.internal_id == newOptions.internal_feature_id
(f: Feature) => f.internal_id == newOptions.internal_feature_id,
)!;
const invoiceItem = constructStripeInvoiceItem({
product,
@@ -135,13 +135,13 @@ export const handleQuantityDowngrade = async ({
stripeSubId: stripeSub.id,
stripeCustomerId: stripeSub.customer as string,
periodStart: Math.floor(
attachParams.now ? attachParams.now / 1000 : Date.now()
attachParams.now ? attachParams.now / 1000 : Date.now(),
),
periodEnd: Math.floor(end * 1000),
});
logger.info(
`🔥 Creating downgrade prepaid invoice item: ${invoiceItem.description} - ${amount}`
`🔥 Creating downgrade prepaid invoice item: ${invoiceItem.description} - ${amount}`,
);
await stripeCli.invoiceItems.create(invoiceItem);

View File

@@ -62,7 +62,7 @@ export const handleQuantityUpgrade = async ({
.minus(
notNullish(oldOptions.upcoming_quantity)
? oldOptions.upcoming_quantity!
: oldOptions.quantity
: oldOptions.quantity,
)
.toNumber();
@@ -114,7 +114,7 @@ export const handleQuantityUpgrade = async ({
// });
const feature = features.find(
(f: Feature) => f.internal_id == newOptions.internal_feature_id
(f: Feature) => f.internal_id == newOptions.internal_feature_id,
)!;
const product = cusProductToProduct({ cusProduct });
@@ -138,7 +138,7 @@ export const handleQuantityUpgrade = async ({
});
logger.info(
`🔥 Creating prepaid invoice item: ${invoiceItem.description} - ${amount}`
`🔥 Creating prepaid invoice item: ${invoiceItem.description} - ${amount}`,
);
await stripeCli.invoiceItems.create(invoiceItem);
@@ -192,7 +192,7 @@ export const handleQuantityUpgrade = async ({
if (cusEnt) {
const incrementBy = new Decimal(difference).mul(billingUnits).toNumber();
logger.info(
`🔥 Incrementing feature ${cusEnt.entitlement.feature.id} balance by ${incrementBy}`
`🔥 Incrementing feature ${cusEnt.entitlement.feature.id} balance by ${incrementBy}`,
);
await CusEntService.increment({
db,

View File

@@ -155,7 +155,7 @@ export const createUsageInvoiceItems = async ({
const invoiceItem = invoiceItems[i];
const createInvoiceItem = async () => {
logger.info(
`🌟 Creating usage invoice item: ${invoiceItem.description}, amount: ${invoiceItem.price_data.unit_amount}`
`🌟 Creating usage invoice item: ${invoiceItem.description}, amount: ${invoiceItem.price_data.unit_amount}`,
);
await stripeCli.invoiceItems.create({
@@ -195,7 +195,7 @@ export const resetUsageBalances = async ({
});
let index = cusProduct.customer_entitlements.findIndex(
(ce) => ce.id === cusEntId
(ce) => ce.id === cusEntId,
);
cusProduct.customer_entitlements[index] = {

View File

@@ -109,7 +109,7 @@ export const handleUpgradeFlow = async ({
// Do something about current sub...
} else if (shouldCancelSub({ sub: curSub!, newSubItems: subItems })) {
logger.info(
`UPGRADE FLOW: canceling sub ${curSub!.id}, proration: ${config.proration}`
`UPGRADE FLOW: canceling sub ${curSub!.id}, proration: ${config.proration}`,
);
canceled = true;
const { stripeCli } = attachParams;
@@ -201,7 +201,7 @@ export const handleUpgradeFlow = async ({
db: req.db,
attachParams: attachToInsertParams(
attachParams,
attachParams.products[0]
attachParams.products[0],
),
subscriptionIds: curCusProduct!.subscription_ids || [],
disableFreeTrial: config.disableTrial,
@@ -228,7 +228,7 @@ export const handleUpgradeFlow = async ({
: undefined,
code: "updated_product_successfully",
message: `Successfully updated product`,
})
}),
);
} else {
res.status(200).json({

View File

@@ -74,7 +74,7 @@ export const handleUpgradeFlowSchedule = async ({
// pro, pro -> free, pro -> premium, pro (need to cancel initial schedule)
if (newCurPhaseIndex == newItems.phases.length - 1) {
logger.info(
`UPGRADE FLOW: no subsequent phases, releasing schedule ${schedule?.id}`
`UPGRADE FLOW: no subsequent phases, releasing schedule ${schedule?.id}`,
);
await stripeCli.subscriptionSchedules.release(schedule!.id);
await CusProductService.updateByStripeScheduledId({
@@ -91,7 +91,7 @@ export const handleUpgradeFlowSchedule = async ({
(cp) =>
cp.id !== curCusProduct?.id &&
cp.subscription_ids?.includes(curSub.id) &&
ACTIVE_STATUSES.includes(cp.status)
ACTIVE_STATUSES.includes(cp.status),
)
.every((cp) => cp.canceled) && isFreeProduct(prices);

View File

@@ -70,7 +70,7 @@ export const priceToNewPreviewItem = ({
const applyRewards = rewards?.filter(
(r) =>
r.discount_config?.price_ids?.includes(price.id) ||
r.discount_config?.apply_to_all
r.discount_config?.apply_to_all,
);
for (const reward of applyRewards ?? []) {

View File

@@ -125,7 +125,7 @@ export const handlePublicAttachErrors = async ({
// 1. If on paid plan, not allowed to switch product
const curProductFree = isFreeProduct(
curCusProduct?.customer_prices.map((cp: any) => cp.price) || [] // if no current product...
curCusProduct?.customer_prices.map((cp: any) => cp.price) || [], // if no current product...
);
if (!curProductFree) {
@@ -180,7 +180,7 @@ export const checkStripeConnections = async ({
env,
customer,
logger,
})
}),
);
}
@@ -192,7 +192,7 @@ export const checkStripeConnections = async ({
env,
product,
logger,
})
}),
);
}
await Promise.all(batchProductUpdates);
@@ -236,7 +236,7 @@ export const createStripePrices = async ({
logger,
internalEntityId: attachParams.internalEntityId,
useCheckout,
})
}),
);
}
await Promise.all(batchPriceUpdates);

View File

@@ -46,7 +46,7 @@ const getProductsForAttach = async ({
if (prod.is_add_on) continue;
let otherProd = products.find(
(p) => p.group === prod.group && !p.is_add_on && p.id !== prod.id
(p) => p.group === prod.group && !p.is_add_on && p.id !== prod.id,
);
if (otherProd && !otherProd.is_add_on && !isOneOff(prod.prices)) {

View File

@@ -40,7 +40,7 @@ export const getRewards = async ({
for (const reward of rewardArray) {
const corresponding = rewards.find(
(r) => r.id === reward || r.promo_codes.some((c) => c.code === reward)
(r) => r.id === reward || r.promo_codes.some((c) => c.code === reward),
);
if (!corresponding) {

View File

@@ -81,7 +81,7 @@ export const isMainTrialBranch = ({
(cp) =>
cp.id !== curMainProduct!.id &&
ACTIVE_STATUSES.includes(cp.status) &&
cp.subscription_ids?.includes(subId)
cp.subscription_ids?.includes(subId),
);
if (otherCusProductsOnSub.length > 1) {

Some files were not shown because too many files have changed in this diff Show More