This commit is contained in:
John Yeo
2026-01-23 17:13:19 +00:00
parent 3f4247e453
commit cb05d169a2
454 changed files with 9436 additions and 9160 deletions

View File

@@ -26,6 +26,7 @@ Write integration tests for the Autumn billing system using the `initScenario` p
- Use `Decimal.js` for balance calculations in track tests
- Unique `customerId` per test
- Use generic types with `AutumnInt`: `autumnV1.customers.get<ApiCustomerV3>()`, `autumnV1.check<CheckResponseV1>()`
- **USE UTILITY FUNCTIONS WHENEVER POSSIBLE** - the shorter the code, the better. Check `server/tests/integration/billing/utils/` for existing utilities like `expectCustomerProducts`, `expectProductScheduled`, `expectCustomerInvoiceCorrect`, etc.
**DON'T:**
- Use `describe/beforeAll/test` (legacy pattern)
@@ -33,6 +34,7 @@ Write integration tests for the Autumn billing system using the `initScenario` p
- Share state between tests
- Use raw arithmetic for balance calculations (floating point errors)
- Use `as unknown as Type` casting - use generic types instead
- Write manual assertion loops when a utility function exists
## AutumnInt Response Types

View File

@@ -1,9 +1,9 @@
#!/usr/bin/env node
import { randomBytes } from "crypto";
import { writeFileSync, copyFileSync, readFileSync } from "fs";
import inquirer from "inquirer";
import { spawnSync } from "child_process";
import chalk from "chalk";
import { spawnSync } from "child_process";
import { randomBytes } from "crypto";
import { copyFileSync, readFileSync, writeFileSync } from "fs";
import inquirer from "inquirer";
const genUrlSafeBase64 = (bytes) => {
return randomBytes(bytes)
@@ -253,7 +253,7 @@ async function main() {
};
let databaseUrl = "";
let stripeWebhookVars = [];
const stripeWebhookVars = [];
databaseUrl = await handleDatabaseSetup();
// stripeWebhookVars = await handleLocalRunSetup();

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env node
import { randomBytes } from "crypto";
import { writeFileSync, copyFileSync } from "fs";
import chalk from "chalk";
import { randomBytes } from "crypto";
import { copyFileSync, writeFileSync } from "fs";
const genUrlSafeBase64 = (bytes) => {
return randomBytes(bytes)
@@ -26,8 +26,8 @@ async function main() {
STRIPE_WEBHOOK_URL: process.env.STRIPE_WEBHOOK_URL,
};
let databaseUrl = process.env.DATABASE_URL;
let stripeWebhookVars = [];
const databaseUrl = process.env.DATABASE_URL;
const stripeWebhookVars = [];
// stripeWebhookVars = await handleLocalRunSetup();
// Step 11: Write to server/.env

View File

@@ -1,5 +1,5 @@
import inquirer from "inquirer";
import chalk from "chalk";
import inquirer from "inquirer";
/**
* Prompts user for Stripe test API key
@@ -111,7 +111,9 @@ export async function setupTunnelUrl(): Promise<string> {
),
);
console.log(
chalk.cyan("You can use tools like ngrok, localtunnel, or Cloudflare Tunnel."),
chalk.cyan(
"You can use tools like ngrok, localtunnel, or Cloudflare Tunnel.",
),
);
console.log(chalk.cyan("Example: https://your-subdomain.ngrok.io\n"));

View File

@@ -9,9 +9,15 @@ import postgres from "postgres";
export const client = postgres(process.env.DATABASE_URL!);
export const db = drizzle(client, { schema });
export const initDrizzle = (params?: { maxConnections?: number, replica?: boolean }) => {
export const initDrizzle = (params?: {
maxConnections?: number;
replica?: boolean;
}) => {
const maxConnections = params?.maxConnections || 10;
const dbUrl = (params?.replica ? process.env.DATABASE_REPLICA_URL : process.env.DATABASE_URL) ?? "";
const dbUrl =
(params?.replica
? process.env.DATABASE_REPLICA_URL
: process.env.DATABASE_URL) ?? "";
const client = postgres(dbUrl, {
max: maxConnections,
});

View File

@@ -1,6 +1,5 @@
import { Redis } from "@upstash/redis";
const upstash = new Redis({
url: process.env.CLOUD_UPSTASH_REDIS_REST_URL,
token: process.env.CLOUD_UPSTASH_REDIS_REST_TOKEN,

View File

@@ -124,7 +124,6 @@ export function createRoute<
middlewares.push(validator("json", opts.body));
}
// Same for query
if (opts.versionedQuery && opts.resource) {
middlewares.push(
@@ -143,7 +142,6 @@ export function createRoute<
middlewares.push(validator("param", opts.params));
}
// Add expand middleware after query validation
if (opts.query || opts.versionedQuery) {
middlewares.push(expandMiddleware());

View File

@@ -32,4 +32,3 @@ export const handleGetOrgMember = createRoute({
return c.json({ userId: orgMember.userId });
},
});

View File

@@ -1,10 +1,10 @@
import { isFreeProduct } from "@/internal/products/productUtils.js";
import {
AttachBranch,
AttachPreview,
type AttachPreview,
AttachScenario,
FullProduct,
type FullProduct,
} from "@autumn/shared";
import { isFreeProduct } from "@/internal/products/productUtils.js";
export const getAttachScenario = async ({
preview,
@@ -13,7 +13,7 @@ export const getAttachScenario = async ({
preview: AttachPreview;
product: FullProduct;
}) => {
let branch = preview.branch;
const branch = preview.branch;
if (
branch == AttachBranch.New ||

View File

@@ -1,7 +1,7 @@
import {
fullCustomerToCustomerEntitlements,
type FullCustomer,
findCustomerEntitlementById,
fullCustomerToCustomerEntitlements,
} from "@autumn/shared";
import type { AutumnContext } from "@/honoUtils/HonoEnv.js";
import type { DeductionUpdate } from "../types/deductionUpdate.js";

View File

@@ -1,7 +1,7 @@
import {
cusEntToStartingBalance,
fullCustomerToCustomerEntitlements,
type FullCustomer,
fullCustomerToCustomerEntitlements,
getMaxOverage,
getRelevantFeatures,
isAllocatedCustomerEntitlement,

View File

@@ -1,6 +1,6 @@
import { DrizzleCli } from "@/db/initDrizzle.js";
import { Customer, customers } from "@autumn/shared";
import { type Customer, customers } from "@autumn/shared";
import { inArray } from "drizzle-orm";
import type { DrizzleCli } from "@/db/initDrizzle.js";
export class CusReadService {
static async getInInternalIds({

View File

@@ -527,7 +527,10 @@ export class CusSearchService {
}
// Call searchByProduct if we have version filters OR status filters
if ((filters?.version && filters?.version.length > 0) || (filters?.status && filters?.status.length > 0)) {
if (
(filters?.version && filters?.version.length > 0) ||
(filters?.status && filters?.status.length > 0)
) {
return await CusSearchService.searchByProduct({
db,
orgId,

View File

@@ -1,14 +1,14 @@
import { getExistingCusProducts } from "@/internal/customers/cusProducts/cusProductUtils/getExistingCusProducts.js";
import { ItemSet } from "@/utils/models/ItemSet.js";
import {
AttachConfig,
FullCusProduct,
type AttachConfig,
type FullCusProduct,
getCusProductMinQuantity,
ProductOptions,
type ProductOptions,
} from "@autumn/shared";
import { getStripeSubItems2 } from "@/external/stripe/stripeSubUtils/getStripeSubItems.js";
import type { AttachParams } from "@/internal/customers/cusProducts/AttachParams.js";
import { getExistingCusProducts } from "@/internal/customers/cusProducts/cusProductUtils/getExistingCusProducts.js";
import type { ItemSet } from "@/utils/models/ItemSet.js";
import { mergeItemSets } from "./mergeItemSets.js";
import { AttachParams } from "@/internal/customers/cusProducts/AttachParams.js";
export const getProdListWithoutEntities = ({
attachParams,
@@ -19,7 +19,7 @@ export const getProdListWithoutEntities = ({
}) => {
const newProdList = structuredClone(productsList);
for (let i = 0; i < newProdList.length; i++) {
let productOptions = newProdList[i];
const productOptions = newProdList[i];
newProdList[i] = {
...productOptions,
quantity:

View File

@@ -1,4 +1,4 @@
import { ItemSet } from "@/utils/models/ItemSet.js";
import type { ItemSet } from "@/utils/models/ItemSet.js";
export const mergeItemSets = ({
curItemSet,

View File

@@ -1,5 +1,5 @@
import type Stripe from "stripe";
import { subToPeriodStartEnd } from "@/external/stripe/stripeSubUtils/convertSubUtils.js";
import Stripe from "stripe";
export const getNextCycle = (stripeSubs: Stripe.Subscription[]) => {
const { end } = subToPeriodStartEnd({ sub: stripeSubs[0] });

View File

@@ -1,4 +1,4 @@
import Stripe from "stripe";
import type Stripe from "stripe";
export const shouldCancelSub = ({
sub,

View File

@@ -1,5 +1,4 @@
import { EntitlementWithFeature } from "@autumn/shared";
import { Price } from "@autumn/shared";
import type { EntitlementWithFeature, Price } from "@autumn/shared";
export const hasPriceIdsChanged = ({
oldPrices,

View File

@@ -1,19 +1,18 @@
import { AttachParams } from "@/internal/customers/cusProducts/AttachParams.js";
import { constructPreviewItem } from "@/internal/invoices/previewItemUtils/constructPreviewItem.js";
import { Proration } from "@/internal/invoices/prorationUtils.js";
import { getUsageFromBalance } from "@/internal/products/prices/priceUtils/arrearProratedUtils/getPrevAndNewUsages.js";
import { generateId } from "@/utils/genUtils.js";
import {
FullEntitlement,
FullCustomerEntitlement,
PreviewLineItem,
Price,
AttachReplaceableSchema,
type FullCustomerEntitlement,
type FullEntitlement,
type PreviewLineItem,
type Price,
usageToFeatureName,
} from "@autumn/shared";
import { attachParamsToProduct } from "../convertAttachParams.js";
import type { AttachParams } from "@/internal/customers/cusProducts/AttachParams.js";
import { constructPreviewItem } from "@/internal/invoices/previewItemUtils/constructPreviewItem.js";
import type { Proration } from "@/internal/invoices/prorationUtils.js";
import { getUsageFromBalance } from "@/internal/products/prices/priceUtils/arrearProratedUtils/getPrevAndNewUsages.js";
import { priceToInvoiceItem } from "@/internal/products/prices/priceUtils/priceToInvoiceItem.js";
import { AttachReplaceableSchema } from "@autumn/shared";
import { generateId } from "@/utils/genUtils.js";
import { attachParamsToProduct } from "../convertAttachParams.js";
export const getContUseDowngradeItems = async ({
price,
@@ -34,31 +33,31 @@ export const getContUseDowngradeItems = async ({
proration?: Proration;
logger: any;
}) => {
let prevInvoiceItem = curItem;
let prevBalance = prevCusEnt.entitlement.allowance! - curUsage;
const prevInvoiceItem = curItem;
const prevBalance = prevCusEnt.entitlement.allowance! - curUsage;
const product = attachParamsToProduct({ attachParams });
const feature = prevCusEnt.entitlement.feature;
let { usage: prevUsage, overage: prevOverage } = getUsageFromBalance({
const { usage: prevUsage, overage: prevOverage } = getUsageFromBalance({
ent: prevCusEnt.entitlement,
price,
balance: prevBalance,
});
let { usage: newUsage, overage: newOverage } = getUsageFromBalance({
const { usage: newUsage, overage: newOverage } = getUsageFromBalance({
ent,
price,
balance: prevBalance,
});
if (prevOverage == 0) {
let { usage: newUsage } = getUsageFromBalance({
const { usage: newUsage } = getUsageFromBalance({
ent,
price,
balance: ent.allowance! - curUsage,
});
let newItem = priceToInvoiceItem({
const newItem = priceToInvoiceItem({
price,
ent,
org: attachParams.org,
@@ -87,9 +86,9 @@ export const getContUseDowngradeItems = async ({
now: attachParams.now,
});
let numReplaceables = newUsage - prevUsage;
const numReplaceables = newUsage - prevUsage;
let replaceables = Array.from({ length: numReplaceables }, (_, i) =>
const replaceables = Array.from({ length: numReplaceables }, (_, i) =>
AttachReplaceableSchema.parse({
ent: ent,
id: generateId("rep"),
@@ -103,7 +102,7 @@ export const getContUseDowngradeItems = async ({
feature,
});
let replaceableItem = constructPreviewItem({
const replaceableItem = constructPreviewItem({
priceStr: `${numReplaceables} free ${featureName}`,
price,
description: `${product.name} - ${featureName}`,

View File

@@ -1,7 +1,7 @@
import { DrizzleCli } from "@/db/initDrizzle.js";
import type { Entitlement, Price } from "@autumn/shared";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { EntitlementService } from "@/internal/products/entitlements/EntitlementService.js";
import { PriceService } from "@/internal/products/prices/PriceService.js";
import { Entitlement, Price } from "@autumn/shared";
export const insertCustomItems = async ({
db,

View File

@@ -1,4 +1,4 @@
import Stripe from "stripe";
import type Stripe from "stripe";
// Normalize items for comparison (order-agnostic, price id as string)
const normalizePhaseItems = (

View File

@@ -1,5 +1,5 @@
import { differenceInDays } from "date-fns";
import Stripe from "stripe";
import type Stripe from "stripe";
export const phaseAndUnixMatch = ({
phase,

View File

@@ -1,4 +1,4 @@
import { AttachBranch } from "@autumn/shared";
import type { AttachBranch } from "@autumn/shared";
export enum ProrationBehavior {
Immediately = "immediately",

View File

@@ -1,5 +1,5 @@
import { AttachConfig, CusProductStatus } from "@autumn/shared";
import { AttachParams } from "../../cusProducts/AttachParams.js";
import { type AttachConfig, CusProductStatus } from "@autumn/shared";
import type { AttachParams } from "../../cusProducts/AttachParams.js";
export const handleUnifiedAttach = async ({
req,

View File

@@ -1,6 +1,10 @@
import { DrizzleCli } from "@/db/initDrizzle.js";
import { InsertReplaceable, Replaceable, replaceables } from "@autumn/shared";
import {
type InsertReplaceable,
type Replaceable,
replaceables,
} from "@autumn/shared";
import { eq, inArray } from "drizzle-orm";
import type { DrizzleCli } from "@/db/initDrizzle.js";
export class RepService {
static async insert({

View File

@@ -1,6 +1,6 @@
// 1. Get min next reset at cus ent
import { Feature, FullCustomerEntitlement } from "@autumn/shared";
import type { Feature, FullCustomerEntitlement } from "@autumn/shared";
export const getMinNextResetAtCusEnt = ({
cusEnts,

View File

@@ -1,9 +1,9 @@
import {
type CustomerEntitlement,
type EntitlementWithFeature,
type FullCusProduct,
type FullCustomerEntitlement,
type Rollover,
import type {
CustomerEntitlement,
EntitlementWithFeature,
FullCusProduct,
FullCustomerEntitlement,
Rollover,
} from "@autumn/shared";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { generateId } from "@/utils/genUtils.js";

View File

@@ -52,9 +52,11 @@ export const setCachedApiCustomer = async ({
});
// Build entity api customers (entity-level features only)
const filteredFullCus = filterEntityLevelCustomerEntitlementsFromFullCustomer({
const filteredFullCus = filterEntityLevelCustomerEntitlementsFromFullCustomer(
{
fullCustomer: fullCus,
});
},
);
// Build entities first
const entityBatch: {

View File

@@ -75,7 +75,8 @@ export const setCachedGrantedBalance = async ({
// ============================================================================
// 2. Build entity balances batch (entity-level products only)
// ============================================================================
const entityLevelCusProducts = filterEntityLevelCustomerEntitlementsFromFullCustomer({
const entityLevelCusProducts =
filterEntityLevelCustomerEntitlementsFromFullCustomer({
fullCustomer: fullCus,
}).customer_products;

View File

@@ -522,7 +522,8 @@ export const getPaginatedFullCusQuery = ({
FROM customers c
WHERE c.org_id = ${orgId}
AND c.env = ${env}
${internalCustomerIds && internalCustomerIds.length > 0
${
internalCustomerIds && internalCustomerIds.length > 0
? sql`AND c.internal_id IN (${sql.join(
internalCustomerIds.map((id) => sql`${id}`),
sql`, `,
@@ -607,7 +608,8 @@ export const getPaginatedFullCusQuery = ({
GROUP BY cpwp.internal_customer_id
)
${withSubs
${
withSubs
? sql`, customer_subscriptions AS (
SELECT
cpwp.internal_customer_id,
@@ -622,7 +624,8 @@ export const getPaginatedFullCusQuery = ({
: sql``
}
${withEntities
${
withEntities
? sql`, customer_entities AS (
SELECT
e.internal_customer_id,
@@ -637,7 +640,8 @@ export const getPaginatedFullCusQuery = ({
: sql``
}
${includeInvoices
${
includeInvoices
? sql`, customer_invoices AS (
SELECT
i.internal_customer_id,
@@ -652,7 +656,8 @@ export const getPaginatedFullCusQuery = ({
: sql``
}
${withTrialsUsed
${
withTrialsUsed
? sql`, customer_trials_used AS (
SELECT
cp.internal_customer_id,

View File

@@ -90,7 +90,9 @@ export const handleDecreaseAndTransfer = async ({
replaceables: [],
entities: fullCus.entities,
features,
internalEntityId: toEntity?.internal_id ? toEntity.internal_id : undefined,
internalEntityId: toEntity?.internal_id
? toEntity.internal_id
: undefined,
entityId: toEntity?.id ? toEntity.id : undefined,
},
product,

View File

@@ -1,17 +1,21 @@
import type {
Feature,
Organization,
ProductItem,
ProductV2,
} from "@autumn/shared";
import { getFeatureNameWithCapital } from "@/internal/features/utils/displayUtils.js";
import {
featurePricetoPricecnItem,
getPriceText,
} from "@/internal/products/pricecn/pricecnUtils.js";
import {
isFeatureItem,
isFeaturePriceItem,
isPriceItem,
} from "@/internal/products/product-items/productItemUtils/getItemType.js";
import { Feature, Organization, ProductItem, ProductV2 } from "@autumn/shared";
import { formatCurrency, formatTiers } from "./previewUtils.js";
import { isFeaturePriceItem } from "@/internal/products/product-items/productItemUtils/getItemType.js";
import { notNullish } from "@/utils/genUtils.js";
import { getFeatureNameWithCapital } from "@/internal/features/utils/displayUtils.js";
import { formatCurrency, formatTiers } from "./previewUtils.js";
export const getProductChargeText = ({
product,
@@ -22,10 +26,10 @@ export const getProductChargeText = ({
org: Organization;
features: Feature[];
}) => {
let basePrices = product.items.filter((i) => isPriceItem(i));
let total = basePrices.reduce((acc, curr) => acc + curr.price!, 0);
const basePrices = product.items.filter((i) => isPriceItem(i));
const total = basePrices.reduce((acc, curr) => acc + curr.price!, 0);
let itemStrs = [];
const itemStrs = [];
if (total > 0) {
itemStrs.push(
formatCurrency({
@@ -35,18 +39,18 @@ export const getProductChargeText = ({
);
}
let prepaidPrices = product.items.filter(
const prepaidPrices = product.items.filter(
(i) => isFeaturePriceItem(i) && i.usage_model == "prepaid",
);
let prepaidStrings = prepaidPrices.map((i) => {
let feature = features.find((f) => f.id === i.feature_id);
let priceStr = formatTiers({
const prepaidStrings = prepaidPrices.map((i) => {
const feature = features.find((f) => f.id === i.feature_id);
const priceStr = formatTiers({
tiers: i.tiers!,
org,
});
let featureStr =
const featureStr =
i.billing_units && i.billing_units > 1
? `${i.billing_units} ${feature?.name}`
: feature?.name;
@@ -67,15 +71,15 @@ export const getItemDescription = ({
product: ProductV2;
org: Organization;
}) => {
let prices = product.items.filter((i) => !isFeatureItem(i));
const prices = product.items.filter((i) => !isFeatureItem(i));
let priceStr = getPriceText({
const priceStr = getPriceText({
item,
org,
});
if (isPriceItem(item)) {
let baseName =
const baseName =
prices.length == 1
? product.name
: notNullish(item.interval)
@@ -84,7 +88,7 @@ export const getItemDescription = ({
return baseName;
} else {
let feature = features.find((f) => f.id === item.feature_id);
const feature = features.find((f) => f.id === item.feature_id);
// let pricecnItem = featurePricetoPricecnItem({
// feature,
// item,

View File

@@ -1,4 +1,4 @@
import { Organization, PriceTier } from "@autumn/shared";
import type { Organization, PriceTier } from "@autumn/shared";
export const formatCurrency = ({
amount,
@@ -30,11 +30,11 @@ export const formatTiers = ({
});
}
let tiersStart = formatCurrency({
const tiersStart = formatCurrency({
amount: tiers[0].amount,
defaultCurrency: org.default_currency!,
});
let tiersEnd = formatCurrency({
const tiersEnd = formatCurrency({
amount: tiers[tiers.length - 1].amount,
defaultCurrency: org.default_currency!,
});
@@ -50,8 +50,8 @@ export const getItemsHtml = ({
org: Organization;
}) => {
let html = "";
let pricedItems = items.filter((item) => item.amount != 0);
let totalAmount = pricedItems.reduce((acc: number, item: any) => {
const pricedItems = items.filter((item) => item.amount != 0);
const totalAmount = pricedItems.reduce((acc: number, item: any) => {
return acc + item.amount;
}, 0);
@@ -74,7 +74,7 @@ export const getItemsHtml = ({
export const itemsToHtml = ({ items }: { items: any[] }) => {
let html = "";
for (let item of items) {
for (const item of items) {
if (item.amount == 0) {
continue;
}

View File

@@ -1,8 +1,8 @@
import { MigrationService } from "../migrations/MigrationService.js";
import { MigrationJobStep, type Organization } from "@autumn/shared";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { sendTextEmail } from "@/external/resend/resendUtils.js";
import { MigrationJobStep, Organization } from "@autumn/shared";
import { DrizzleCli } from "@/db/initDrizzle.js";
import { safeResend } from "@/external/resend/safeResend.js";
import { MigrationService } from "../migrations/MigrationService.js";
import { FROM_AUTUMN } from "./constants.js";
export const sendMigrationEmail = safeResend({
@@ -15,15 +15,15 @@ export const sendMigrationEmail = safeResend({
migrationJobId: string;
org: Organization;
}) => {
let migrationJob = await MigrationService.getJob({
const migrationJob = await MigrationService.getJob({
db,
id: migrationJobId,
});
// Send email
let getCustomersStep =
const getCustomersStep =
migrationJob.step_details[MigrationJobStep.GetCustomers];
let migrateStep =
const migrateStep =
migrationJob.step_details[MigrationJobStep.MigrateCustomers];
console.log("Sending migration email");

View File

@@ -1,6 +1,6 @@
import OTPEmail from "@emails/OTPEmail.js";
import { logger } from "@/external/logtail/logtailUtils.js";
import { createResendCli } from "@/external/resend/resendUtils.js";
import OTPEmail from "@emails/OTPEmail.js";
import { FROM_AUTUMN } from "./constants.js";
const sendOTPEmail = async ({ email, otp }: { email: string; otp: string }) => {

View File

@@ -1,7 +1,7 @@
import { DrizzleCli } from "@/db/initDrizzle.js";
import { EntityService } from "@/internal/api/entities/EntityService.js";
import { Feature, getFeatureName } from "@autumn/shared";
import { type Feature, getFeatureName } from "@autumn/shared";
import { AppEnv, Entity } from "autumn-js";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { EntityService } from "@/internal/api/entities/EntityService.js";
export const getEntityInvoiceDescription = async ({
db,
@@ -15,12 +15,12 @@ export const getEntityInvoiceDescription = async ({
logger: any;
}) => {
try {
let entity = await EntityService.getByInternalId({
const entity = await EntityService.getByInternalId({
db,
internalId: internalEntityId,
});
let feature = features.find(
const feature = features.find(
(f) => f.internal_id == entity?.internal_feature_id,
);
@@ -32,7 +32,7 @@ export const getEntityInvoiceDescription = async ({
}
if (feature && entDetails) {
let featureName = getFeatureName({
const featureName = getFeatureName({
feature,
plural: false,
capitalize: true,

View File

@@ -1,10 +1,10 @@
import { generateId, notNullish, nullish } from "@/utils/genUtils.js";
import {
AppEnv,
Entity,
type AppEnv,
type Entity,
FeatureType,
FullCusEntWithFullCusProduct,
} from "@autumn/shared";
import { generateId, notNullish, nullish } from "@/utils/genUtils.js";
export const constructEntity = ({
inputEntity,
@@ -21,7 +21,7 @@ export const constructEntity = ({
env: AppEnv;
deleted?: boolean;
}) => {
let entity: Entity = {
const entity: Entity = {
internal_id: generateId("ety"),
id: inputEntity.id,
name: inputEntity.name,

View File

@@ -1,6 +1,5 @@
import { notNullish } from "@/utils/genUtils.js";
import { nullish } from "@/utils/genUtils.js";
import { Entity } from "@autumn/shared";
import type { Entity } from "@autumn/shared";
import { notNullish, nullish } from "@/utils/genUtils.js";
export const logEntityToAction = ({
entityToAction,
@@ -35,11 +34,13 @@ export const getEntityToAction = ({
feature: any;
logger: any;
}) => {
let entityToAction: any = {};
const entityToAction: any = {};
let createCount = 0;
let replacedEntities: string[] = [];
const replacedEntities: string[] = [];
for (const inputEntity of inputEntities) {
let curEntity = existingEntities.find((e: any) => e.id === inputEntity.id);
const curEntity = existingEntities.find(
(e: any) => e.id === inputEntity.id,
);
if (curEntity && curEntity.deleted) {
entityToAction[inputEntity.id] = {

View File

@@ -1,6 +1,4 @@
import { Feature } from "@autumn/shared";
import { Organization } from "@autumn/shared";
import { type Feature, Organization } from "@autumn/shared";
export const getFeatureName = ({
feature,

View File

@@ -1,5 +1,5 @@
import { createRoute } from "@/honoMiddlewares/routeHandler.js";
import { createStripeCli } from "@/external/connect/createStripeCli.js";
import { createRoute } from "@/honoMiddlewares/routeHandler.js";
/**
* Get Stripe invoice by Stripe invoice ID

View File

@@ -1,6 +1,11 @@
import { Organization, Price, Product, UsagePriceConfig } from "@autumn/shared";
import type {
Organization,
Price,
Product,
UsagePriceConfig,
} from "@autumn/shared";
import { Decimal } from "decimal.js";
import Stripe from "stripe";
import type Stripe from "stripe";
export const constructStripeInvoiceItem = ({
product,
@@ -29,7 +34,7 @@ export const constructStripeInvoiceItem = ({
new Decimal(amount).mul(100).round().toNumber(),
);
let priceData =
const priceData =
amountInCents > 0
? {
price_data: {
@@ -43,7 +48,7 @@ export const constructStripeInvoiceItem = ({
currency: org.default_currency || "usd",
};
let invoiceItem: Stripe.InvoiceItemCreateParams = {
const invoiceItem: Stripe.InvoiceItemCreateParams = {
subscription: stripeSubId,
...priceData,

View File

@@ -11,7 +11,8 @@ const invoiceRedirectLimiter = rateLimiter<HonoEnv>({
windowMs: 60 * 1000, // 1 minute
limit: 10,
standardHeaders: "draft-6",
keyGenerator: (c) => c.req.header("x-forwarded-for") ?? c.req.header("x-real-ip") ?? "unknown",
keyGenerator: (c) =>
c.req.header("x-forwarded-for") ?? c.req.header("x-real-ip") ?? "unknown",
});
publicInvoiceRouter.get(

View File

@@ -1,11 +1,11 @@
import { generateId } from "@/utils/genUtils.js";
import {
AppEnv,
MigrationError,
MigrationJob,
type AppEnv,
type MigrationError,
type MigrationJob,
MigrationJobStep,
Product,
type Product,
} from "@autumn/shared";
import { generateId } from "@/utils/genUtils.js";
export const constructMigrationError = ({
migrationJobId,
@@ -20,7 +20,7 @@ export const constructMigrationError = ({
code: string;
message: string;
}) => {
let migrationError: MigrationError = {
const migrationError: MigrationError = {
migration_job_id: migrationJobId,
internal_customer_id: internalCustomerId,
data,
@@ -40,7 +40,7 @@ export const constructMigrationJob = ({
fromProduct: Product;
toProduct: Product;
}) => {
let migrationJob: MigrationJob = {
const migrationJob: MigrationJob = {
id: generateId("mig_job"),
created_at: Date.now(),
updated_at: Date.now(),

View File

@@ -18,8 +18,7 @@ export const handleDeleteView = createRoute({
// Remove from list
const listKey = `saved_views_list:${org.id}:${env}`;
const existingViews =
(await CacheManager.getJson<string[]>(listKey)) || [];
const existingViews = (await CacheManager.getJson<string[]>(listKey)) || [];
const updatedViews = existingViews.filter((id: string) => id !== viewId);
await CacheManager.setJson(listKey, updatedViews, "forever");

View File

@@ -39,7 +39,11 @@ export const parseChatProducts = async ({
env: AppEnv.Sandbox,
});
const { prices, entitlements, features: updatedFeatures } = await handleNewProductItems({
const {
prices,
entitlements,
features: updatedFeatures,
} = await handleNewProductItems({
db,
curPrices: [],
curEnts: [],

View File

@@ -1,9 +1,9 @@
import { AppEnv, type Organization } from "@autumn/shared";
import type { Logger } from "@/external/logtail/logtailUtils.js";
import {
deauthorizeAccount,
deleteConnectedAccount,
} from "@/external/connect/connectUtils.js";
import type { Logger } from "@/external/logtail/logtailUtils.js";
import { deleteSvixApp } from "@/external/svix/svixHelpers.js";
import { deleteStripeWebhook } from "../orgUtils.js";

View File

@@ -95,7 +95,10 @@ export const createProduct = async ({
const newFullProduct: FullProduct = {
...product,
prices,
entitlements: getEntsWithFeature({ ents: entitlements, features: updatedFeatures }),
entitlements: getEntsWithFeature({
ents: entitlements,
features: updatedFeatures,
}),
free_trial: newFreeTrial,
};

View File

@@ -1,4 +1,4 @@
import { Entitlement, Price, UsagePriceConfig } from "@autumn/shared";
import type { Entitlement, Price, UsagePriceConfig } from "@autumn/shared";
import { Decimal } from "decimal.js";
export const getUsageFromBalance = ({
@@ -10,17 +10,17 @@ export const getUsageFromBalance = ({
price: Price;
balance: number;
}) => {
let config = price.config as UsagePriceConfig;
let billingUnits = config.billing_units || 1;
const config = price.config as UsagePriceConfig;
const billingUnits = config.billing_units || 1;
let overage = -Math.min(0, balance);
let roundedOverage = new Decimal(overage)
const overage = -Math.min(0, balance);
const roundedOverage = new Decimal(overage)
.div(billingUnits)
.ceil()
.mul(billingUnits)
.toNumber();
let usage = new Decimal(ent.allowance!).sub(balance).toNumber();
const usage = new Decimal(ent.allowance!).sub(balance).toNumber();
let roundedUsage = usage;
if (overage > 0) {

View File

@@ -1,9 +1,14 @@
import { DrizzleCli } from "@/db/initDrizzle.js";
import { PriceService } from "../PriceService.js";
import { FixedPriceConfig, prices, PriceType } from "@autumn/shared";
import {
type FixedPriceConfig,
type Price,
PriceType,
prices,
type UsagePriceConfig,
} from "@autumn/shared";
import { eq } from "drizzle-orm";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { generateId } from "@/utils/genUtils.js";
import { Price, UsagePriceConfig } from "@autumn/shared";
import { PriceService } from "../PriceService.js";
export const copyPrice = async ({
db,
@@ -20,7 +25,7 @@ export const copyPrice = async ({
isCustom?: boolean;
withPrevConfig?: boolean;
}) => {
let price = (await db.query.prices.findFirst({
const price = (await db.query.prices.findFirst({
where: eq(prices.id, priceId),
})) as Price;

View File

@@ -1,4 +1,4 @@
import { BillingType, Price } from "@autumn/shared";
import { BillingType, type Price } from "@autumn/shared";
import { getBillingType } from "../priceUtils.js";
const BillingTypeOrder = [
@@ -11,8 +11,8 @@ const BillingTypeOrder = [
export const sortPricesByType = (prices: Price[]) => {
return prices.sort((a, b) => {
let aType = getBillingType(a.config);
let bType = getBillingType(b.config);
const aType = getBillingType(a.config);
const bType = getBillingType(b.config);
return BillingTypeOrder.indexOf(aType) - BillingTypeOrder.indexOf(bType);
});
};

View File

@@ -1,7 +1,7 @@
import {
Feature,
type Feature,
FeatureType,
ProductItem,
type ProductItem,
ProductItemFeatureType,
UsageModel,
} from "@autumn/shared";

View File

@@ -36,7 +36,10 @@ honoProductRouter.delete("/:product_id", ...handleDeleteProductHono);
honoProductRouter.post("/:product_id/copy", ...handleCopyProductV2);
// Info before deleting plan
honoProductRouter.get("/:product_id/has_customers", ...handlePlanHasCustomersV2);
honoProductRouter.get(
"/:product_id/has_customers",
...handlePlanHasCustomersV2,
);
honoProductRouter.post(
"/:product_id/has_customers",
...handlePlanHasCustomersV2,

View File

@@ -1,12 +1,15 @@
import { FeatureId, sendProductEvent } from "@/external/autumn/autumnUtils.js";
import { isEntitled } from "@/external/autumn/autumnUtils.js";
import {
FeatureId,
isEntitled,
sendProductEvent,
} from "@/external/autumn/autumnUtils.js";
import { handleRequestError } from "@/utils/errorUtils.js";
export const pricingMiddleware = async (req: any, res: any, next: any) => {
let path = req.url;
let method = req.method;
const path = req.url;
const method = req.method;
let host = req.headers.host;
const host = req.headers.host;
if (host.includes("localhost")) {
next();
return;
@@ -33,7 +36,7 @@ export const pricingMiddleware = async (req: any, res: any, next: any) => {
});
}
if (path.match(/^\/products\/[^\/]+$/) && method === "DELETE") {
if (path.match(/^\/products\/[^/]+$/) && method === "DELETE") {
console.log("sending product delete event");
await sendProductEvent({
org: req.org,

View File

@@ -1,6 +1,6 @@
import { AppEnv, AuthType, ErrCode } from "@autumn/shared";
import { verifyPublicKey } from "@/internal/dev/api-keys/publicKeyUtils.js";
import RecaseError from "@/utils/errorUtils.js";
import { AppEnv, AuthType, ErrCode } from "@autumn/shared";
const allowedEndpoints = [
{
@@ -82,7 +82,7 @@ export const verifyBearerPublishableKey = async (
});
}
let env: AppEnv = pkey.startsWith("am_pk_test")
const env: AppEnv = pkey.startsWith("am_pk_test")
? AppEnv.Sandbox
: AppEnv.Live;
@@ -100,7 +100,7 @@ export const verifyBearerPublishableKey = async (
});
}
let { org, features } = data;
const { org, features } = data;
req.minOrg = {
id: org.id,

View File

@@ -1,8 +1,9 @@
export const parseAuthHeader = (req: any) => {
let authHeader = req.headers["Authorization"] || req.headers["authorization"];
const authHeader =
req.headers["Authorization"] || req.headers["authorization"];
if (!authHeader || !authHeader.startsWith("Bearer ")) {
return null;
}
let bearerToken = authHeader.split(" ")[1];
const bearerToken = authHeader.split(" ")[1];
return bearerToken;
};

View File

@@ -45,9 +45,6 @@ export const checkSubCountMatch = async ({
.from(metadata)
.where(inArray(metadata.stripe_invoice_id, invoiceIds as string[]));
if (
stripeSubs.length - (metadataCount?.[0]?.count || 0) !==
subIds.length

View File

@@ -17,7 +17,9 @@ export const saveCheckState = async ({
result: StateCheckResult;
}): Promise<void> => {
const newFailedChecks = result.checks
.filter((c): c is typeof c & { type: CheckType } => c.type !== "overall_status")
.filter(
(c): c is typeof c & { type: CheckType } => c.type !== "overall_status",
)
.filter((c) => !c.passed);
// Skip Redis entirely if all checks pass
@@ -25,14 +27,18 @@ export const saveCheckState = async ({
const stateKey = `state:${org.id}:${env}:${fullCus.internal_id}`;
const existingState = (await upstash.get(stateKey)) as RedisChecksState | null;
const existingState = (await upstash.get(
stateKey,
)) as RedisChecksState | null;
if (existingState) {
// Merge with existing state
const existingFailedTypes = new Set<CheckType>(existingState.checks.map((c) => c.type));
const newFailedTypes = new Set<CheckType>(newFailedChecks.map((c) => c.type));
const existingFailedTypes = new Set<CheckType>(
existingState.checks.map((c) => c.type),
);
const newFailedTypes = new Set<CheckType>(
newFailedChecks.map((c) => c.type),
);
// Checks that were fixed (existed before but not now)
const checksToRemove = new Set<CheckType>(
@@ -44,7 +50,9 @@ export const saveCheckState = async ({
);
// Keep checks that still fail, remove ones that are fixed
const updatedChecks = existingState.checks.filter((c) => !checksToRemove.has(c.type));
const updatedChecks = existingState.checks.filter(
(c) => !checksToRemove.has(c.type),
);
// Add new failing checks
for (const check of newFailedChecks) {
@@ -65,7 +73,6 @@ export const saveCheckState = async ({
checks: updatedChecks,
};
await upstash.set(stateKey, JSON.stringify(updatedState));
} else {
// Create new state
const newState: RedisChecksState = {
@@ -87,7 +94,5 @@ export const saveCheckState = async ({
})),
};
await upstash.set(stateKey, JSON.stringify(newState));
}
};

View File

@@ -50,6 +50,6 @@ export const generatePublishableKey = (env: string) => {
// .replace(/[+/=]/g, "") // Remove non-URL safe characters
// .slice(0, 100); // Ensure exactly 100 characters
let envString = env === AppEnv.Sandbox ? "test_" : "live_";
const envString = env === AppEnv.Sandbox ? "test_" : "live_";
return `am_pk_${envString}${KSUID.randomSync().string}`;
};

View File

@@ -19,8 +19,6 @@ export const checkEnvVars = () => {
process.exit(1);
}
if (!process.env.BETTER_AUTH_SECRET || !process.env.BETTER_AUTH_URL) {
console.error(`BETTER_AUTH_SECRET or BETTER_AUTH_URL is not set`);
process.exit(1);

View File

@@ -1,4 +1,4 @@
import { type Price } from "@autumn/shared";
import type { Price } from "@autumn/shared";
import type Stripe from "stripe";
// export const ItemSetSchema = z.object({

View File

@@ -1,12 +1,12 @@
import { DrizzleCli } from "@/db/initDrizzle.js";
import {
AppEnv,
customers,
features,
Organization,
type Organization,
products,
} from "@autumn/shared";
import { and, eq, inArray } from "drizzle-orm";
import type { DrizzleCli } from "@/db/initDrizzle.js";
export const clearCustomersInBatches = async ({
db,

View File

@@ -11,7 +11,7 @@ export const parseCsv = ({
return new Promise((resolve, reject) => {
const stream = fs.createReadStream(path);
const results: any[] = [];
let headers: string[] = [];
const headers: string[] = [];
stream
.pipe(csv({ separator: delimiter }))
.on("data", (data) => {

View File

@@ -1,8 +1,8 @@
import { DrizzleCli } from "@/db/initDrizzle.js";
import { AppEnv, FullCusProduct } from "@autumn/shared";
import { AppEnv, type FullCusProduct } from "@autumn/shared";
import { sql } from "drizzle-orm";
import type { DrizzleCli } from "@/db/initDrizzle.js";
let cusProductsQuery = ({
const cusProductsQuery = ({
lastProductId,
internalProductId,
pageSize = 250,
@@ -87,8 +87,8 @@ export const getAllFullCusProducts = async ({
internalProductId: string;
}) => {
let lastProductId = "";
let allData: any[] = [];
let pageSize = 500;
const allData: any[] = [];
const pageSize = 500;
while (true) {
const data = await db.execute(

View File

@@ -1,7 +1,6 @@
import { DrizzleCli } from "@/db/initDrizzle.js";
import { user } from "@autumn/shared";
import { desc } from "drizzle-orm";
import type { DrizzleCli } from "@/db/initDrizzle.js";
export const getAllUsers = async (db: DrizzleCli) => {
const users = [];

View File

@@ -1,9 +1,9 @@
import { Organization, AppEnv } from "@autumn/shared";
import { AppEnv, type Organization } from "@autumn/shared";
import { deleteAllStripeCustomers } from "@/external/stripe/stripeCusUtils.js";
import {
deactivateStripeMeters,
deleteAllStripeProducts,
} from "@/external/stripe/stripeProductUtils.js";
import { deleteAllStripeCustomers } from "@/external/stripe/stripeCusUtils.js";
export const resetOrgStripe = async ({ org }: { org: Organization }) => {
const env = AppEnv.Sandbox;

View File

@@ -1,8 +1,6 @@
import { Duration, EntInterval } from "@autumn/shared";
import { Entitlement } from "@autumn/shared";
import { add } from "date-fns";
import { Duration, EntInterval, Entitlement } from "@autumn/shared";
import { UTCDate } from "@date-fns/utc";
import { add } from "date-fns";
import { formatUnixToDate } from "./genUtils.js";
// Time conversion constants

View File

@@ -1,13 +1,13 @@
import { beforeAll, describe, expect, test } from "bun:test";
import { LegacyVersion } from "@autumn/shared";
import chalk from "chalk";
import { addHours, addMonths } from "date-fns";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { hoursToFinalizeInvoice } from "@tests/utils/constants.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { getBasePrice } from "@tests/utils/testProductUtils/testProductUtils.js";
import chalk from "chalk";
import { addHours, addMonths } from "date-fns";
import type Stripe from "stripe";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructFeatureItem } from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";

View File

@@ -1,12 +1,12 @@
import { beforeAll, describe, expect, test } from "bun:test";
import { LegacyVersion } from "@autumn/shared";
import chalk from "chalk";
import { addDays, addMonths } from "date-fns";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { expectProductAttached } from "@tests/utils/expectUtils/expectProductAttached.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { addDays, addMonths } from "date-fns";
import type Stripe from "stripe";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { calculateProrationAmount } from "@/internal/invoices/prorationUtils.js";
import {

View File

@@ -1,8 +1,5 @@
import { beforeAll, describe, expect, test } from "bun:test";
import { LegacyVersion } from "@autumn/shared";
import chalk from "chalk";
import { addMonths } from "date-fns";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import {
@@ -11,6 +8,9 @@ import {
} from "@tests/utils/expectUtils/expectScheduleUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { getBasePrice } from "@tests/utils/testProductUtils/testProductUtils.js";
import chalk from "chalk";
import { addMonths } from "date-fns";
import type Stripe from "stripe";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructFeatureItem } from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";

View File

@@ -1,6 +1,5 @@
import { beforeAll, describe, expect, test } from "bun:test";
import { ApiVersion, type AppEnv, LegacyVersion } from "@autumn/shared";
import chalk from "chalk";
import { TestFeature } from "@tests/setup/v2Features.js";
import {
getPrepaidCusEnt,
@@ -8,6 +7,7 @@ import {
} from "@tests/utils/cusProductUtils/cusEntSearchUtils.js";
import { getMainCusProduct } from "@tests/utils/cusProductUtils/cusProductUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { timeout } from "@/utils/genUtils.js";

View File

@@ -1,6 +1,5 @@
import { beforeAll, describe, expect, test } from "bun:test";
import { ApiVersion, type AppEnv, LegacyVersion } from "@autumn/shared";
import chalk from "chalk";
import { TestFeature } from "@tests/setup/v2Features.js";
import {
getLifetimeFreeCusEnt,
@@ -8,6 +7,7 @@ import {
} from "@tests/utils/cusProductUtils/cusEntSearchUtils.js";
import { getMainCusProduct } from "@tests/utils/cusProductUtils/cusProductUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { timeout } from "@/utils/genUtils.js";

View File

@@ -2,8 +2,6 @@
import { beforeAll, describe, expect, test } from "bun:test";
import { ApiVersion, type AppEnv } from "@autumn/shared";
import chalk from "chalk";
import { addMonths } from "date-fns";
import { TestFeature } from "@tests/setup/v2Features.js";
import {
getLifetimeFreeCusEnt,
@@ -11,6 +9,8 @@ import {
} from "@tests/utils/cusProductUtils/cusEntSearchUtils.js";
import { getMainCusProduct } from "@tests/utils/cusProductUtils/cusProductUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { addMonths } from "date-fns";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { timeout } from "@/utils/genUtils.js";

View File

@@ -3,8 +3,8 @@ import { TestFeature } from "@tests/setup/v2Features.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { constructPriceItem } from "@/internal/products/product-items/productItemUtils.js";
import {
constructFeatureItem,
constructArrearItem,
constructFeatureItem,
} from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";
import { createSharedProducts } from "@/utils/scriptUtils/testUtils/createSharedProduct.js";

View File

@@ -5,12 +5,12 @@ import {
ProductItemInterval,
UsageModel,
} from "@autumn/shared";
import chalk from "chalk";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { expectCustomerV0Correct } from "@tests/utils/expectUtils/expectCustomerV0Correct.js";
import { getExpectedInvoiceTotal } from "@tests/utils/expectUtils/expectInvoiceUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import type Stripe from "stripe";
import { constructPriceItem } from "@/internal/products/product-items/productItemUtils.js";
import { convertProductV2ToV1 } from "@/internal/products/productUtils/productV2Utils/convertProductV2ToV1.js";
import { constructRawProduct } from "@/utils/scriptUtils/createTestProducts.js";

View File

@@ -1,10 +1,10 @@
import { beforeAll, describe, expect, test } from "bun:test";
import { ErrCode, LegacyVersion, type LimitedItem } from "@autumn/shared";
import chalk from "chalk";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { expectAutumnError } from "@tests/utils/expectUtils/expectErrUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructArrearProratedItem } from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";

View File

@@ -1,10 +1,10 @@
import { beforeAll, describe, expect, test } from "bun:test";
import { LegacyVersion, type LimitedItem } from "@autumn/shared";
import chalk from "chalk";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import type Stripe from "stripe";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { timeout } from "@/utils/genUtils.js";
import {

View File

@@ -1,11 +1,11 @@
import { beforeAll, describe, test } from "bun:test";
import { ErrCode, LegacyVersion, type LimitedItem } from "@autumn/shared";
import chalk from "chalk";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { expectAutumnError } from "@tests/utils/expectUtils/expectErrUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import type Stripe from "stripe";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructPrepaidItem } from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";

View File

@@ -1,14 +1,14 @@
import { LegacyVersion, OnDecrease, OnIncrease } from "@autumn/shared";
import { beforeAll, describe, expect, test } from "bun:test";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import type Stripe from "stripe";
import { LegacyVersion, OnDecrease, OnIncrease } from "@autumn/shared";
import { replaceItems } from "@tests/attach/utils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { expectSubQuantityCorrect } from "@tests/utils/expectUtils/expectContUseUtils.js";
import { advanceTestClock } from "@tests/utils/stripeUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import type Stripe from "stripe";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructArrearProratedItem } from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";

View File

@@ -1,12 +1,12 @@
import { LegacyVersion, OnDecrease, OnIncrease } from "@autumn/shared";
import { beforeAll, describe, test } from "bun:test";
import chalk from "chalk";
import { LegacyVersion, OnDecrease, OnIncrease } from "@autumn/shared";
import { replaceItems } from "@tests/attach/utils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { attachNewContUseAndExpectCorrect } from "@tests/utils/expectUtils/expectContUse/expectUpdateContUse.js";
import { expectSubQuantityCorrect } from "@tests/utils/expectUtils/expectContUseUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructArrearProratedItem } from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";

View File

@@ -1,14 +1,14 @@
import { LegacyVersion, OnDecrease, OnIncrease } from "@autumn/shared";
import { beforeAll, describe, expect, test } from "bun:test";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import { LegacyVersion, OnDecrease, OnIncrease } from "@autumn/shared";
import { replaceItems } from "@tests/attach/utils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { attachNewContUseAndExpectCorrect } from "@tests/utils/expectUtils/expectContUse/expectUpdateContUse.js";
import { expectSubQuantityCorrect } from "@tests/utils/expectUtils/expectContUseUtils.js";
import { advanceTestClock } from "@tests/utils/stripeUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { subToPeriodStartEnd } from "@/external/stripe/stripeSubUtils/convertSubUtils.js";
import { calculateProrationAmount } from "@/internal/invoices/prorationUtils.js";

View File

@@ -1,11 +1,11 @@
import { LegacyVersion, OnDecrease, OnIncrease } from "@autumn/shared";
import { beforeAll, describe, test } from "bun:test";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { LegacyVersion, OnDecrease, OnIncrease } from "@autumn/shared";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { advanceTestClock } from "@tests/utils/stripeUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructArrearProratedItem } from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";

View File

@@ -1,12 +1,12 @@
import { beforeAll, describe, test } from "bun:test";
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import chalk from "chalk";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { expectFeaturesCorrect } from "@tests/utils/expectUtils/expectFeaturesCorrect.js";
import { expectProductAttached } from "@tests/utils/expectUtils/expectProductAttached.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import type Stripe from "stripe";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructFeatureItem } from "@/utils/scriptUtils/constructItem.js";

View File

@@ -5,13 +5,13 @@ import {
type Entitlement,
ProductItemInterval,
} from "@autumn/shared";
import chalk from "chalk";
import { AutumnCli } from "@tests/cli/AutumnCli.js";
import { TestFeature } from "@tests/setup/v2Features.js";
import { expectCustomerV0Correct } from "@tests/utils/expectUtils/expectCustomerV0Correct.js";
import { timeout } from "@tests/utils/genUtils.js";
import { completeCheckoutForm } from "@tests/utils/stripeUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { convertProductV2ToV1 } from "@/internal/products/productUtils/productV2Utils/convertProductV2ToV1.js";

View File

@@ -1,12 +1,12 @@
import { beforeAll, describe, test } from "bun:test";
import { ApiVersion } from "@autumn/shared";
import chalk from "chalk";
import { AutumnCli } from "@tests/cli/AutumnCli.js";
import { TestFeature } from "@tests/setup/v2Features.js";
import { expectCustomerV0Correct } from "@tests/utils/expectUtils/expectCustomerV0Correct.js";
import { timeout } from "@tests/utils/genUtils.js";
import { completeCheckoutForm } from "@tests/utils/stripeUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructPrepaidItem } from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";

View File

@@ -1,7 +1,5 @@
import { beforeAll, describe, test } from "bun:test";
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import chalk from "chalk";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import {
@@ -9,6 +7,8 @@ import {
expectNextCycleCorrect,
} from "@tests/utils/expectUtils/expectScheduleUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import type Stripe from "stripe";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructFeatureItem } from "@/internal/products/product-items/productItemUtils.js";

View File

@@ -1,20 +1,20 @@
import { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { ProductV2, Organization } from "@autumn/shared";
import { AppEnv } from "autumn-js";
import { expect } from "bun:test";
import type { Organization, ProductV2 } from "@autumn/shared";
import { expectSubToBeCorrect } from "@tests/merged/mergeUtils/expectSubCorrect.js";
import { expectResetAtCorrect } from "@tests/utils/expectUtils/expectAttach/expectResetAtCorrect.js";
import { expectTrialEndsAtCorrect } from "@tests/utils/expectUtils/expectAttach/expectTrialEndsAt.js";
import { expectFeaturesCorrect } from "@tests/utils/expectUtils/expectFeaturesCorrect.js";
import {
expectSubItemsCorrect,
getSubsFromCusId,
} from "@tests/utils/expectUtils/expectSubUtils.js";
import Stripe from "stripe";
import { expect } from "bun:test";
import { expectFeaturesCorrect } from "@tests/utils/expectUtils/expectFeaturesCorrect.js";
import { expectResetAtCorrect } from "@tests/utils/expectUtils/expectAttach/expectResetAtCorrect.js";
import { isFreeProductV2 } from "@/internal/products/productUtils/classifyProduct.js";
import { expectTrialEndsAtCorrect } from "@tests/utils/expectUtils/expectAttach/expectTrialEndsAt.js";
import { timeout } from "@/utils/genUtils.js";
import type { AppEnv } from "autumn-js";
import type Stripe from "stripe";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import type { AutumnInt } from "@/external/autumn/autumnCli.js";
import { subToPeriodStartEnd } from "@/external/stripe/stripeSubUtils/convertSubUtils.js";
import { expectSubToBeCorrect } from "@tests/merged/mergeUtils/expectSubCorrect.js";
import { isFreeProductV2 } from "@/internal/products/productUtils/classifyProduct.js";
import { timeout } from "@/utils/genUtils.js";
export const expectSubsSame = ({
subsBefore,
@@ -25,8 +25,8 @@ export const expectSubsSame = ({
}) => {
// let invoicesBefore = subsBefore.map((sub) => sub.latest_invoice);
// let invoicesAfter = subsAfter.map((sub) => sub.latest_invoice);
let subIdsBefore = subsBefore.map((sub) => sub.id);
let subIdsAfter = subsAfter.map((sub) => sub.id);
const subIdsBefore = subsBefore.map((sub) => sub.id);
const subIdsAfter = subsAfter.map((sub) => sub.id);
const periodsBefore = subsBefore.map((sub) => subToPeriodStartEnd({ sub }));
const periodsAfter = subsAfter.map((sub) => subToPeriodStartEnd({ sub }));

View File

@@ -1,13 +1,9 @@
import {
BillingInterval,
LegacyVersion,
type ProductV2,
} from "@autumn/shared";
import { beforeAll, describe, test } from "bun:test";
import chalk from "chalk";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { BillingInterval, LegacyVersion, type ProductV2 } from "@autumn/shared";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructPriceItem } from "@/internal/products/product-items/productItemUtils.js";
import { constructArrearItem } from "@/utils/scriptUtils/constructItem.js";

View File

@@ -1,18 +1,18 @@
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import { beforeAll, describe, expect, test } from "bun:test";
import chalk from "chalk";
import type Stripe from "stripe";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import {
expectDowngradeCorrect,
expectNextCycleCorrect,
} from "@tests/utils/expectUtils/expectScheduleUtils.js";
import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js";
import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import type Stripe from "stripe";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";
import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js";
import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js";
const testCase = "others1";

View File

@@ -1,9 +1,9 @@
import { beforeAll, describe, expect, test } from "bun:test";
import { LegacyVersion } from "@autumn/shared";
import chalk from "chalk";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { attachFailedPaymentMethod } from "@/external/stripe/stripeCusUtils.js";
import { CusService } from "@/internal/customers/CusService.js";

View File

@@ -1,15 +1,15 @@
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import { beforeAll, describe, expect, test } from "bun:test";
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import type Stripe from "stripe";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js";
import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { attachFailedPaymentMethod } from "@/external/stripe/stripeCusUtils.js";
import { CusService } from "@/internal/customers/CusService.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";
import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js";
import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js";
const testCase = "others3";

View File

@@ -1,17 +1,17 @@
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import { beforeAll, describe, expect, test } from "bun:test";
import chalk from "chalk";
import type Stripe from "stripe";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import { TestFeature } from "@tests/setup/v2Features.js";
import { expectAttachCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js";
import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { getBasePrice } from "@tests/utils/testProductUtils/testProductUtils.js";
import chalk from "chalk";
import type Stripe from "stripe";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructArrearItem } from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";
import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js";
import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js";
export const pro = constructProduct({
items: [constructArrearItem({ featureId: TestFeature.Words })],

View File

@@ -1,12 +1,10 @@
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import { beforeAll, describe, expect, test } from "bun:test";
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import { TestFeature } from "@tests/setup/v2Features.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { getBasePrice } from "@tests/utils/testProductUtils/testProductUtils.js";
import chalk from "chalk";
import type Stripe from "stripe";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { TestFeature } from "@tests/setup/v2Features.js";
import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js";
import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js";
import { getBasePrice } from "@tests/utils/testProductUtils/testProductUtils.js";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import {
@@ -14,6 +12,8 @@ import {
constructPrepaidItem,
} from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";
import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js";
import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js";
export const pro = constructProduct({
items: [

View File

@@ -1,17 +1,17 @@
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import { beforeAll, describe, expect, test } from "bun:test";
import chalk from "chalk";
import type Stripe from "stripe";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { expectAutumnError } from "@tests/utils/expectUtils/expectErrUtils.js";
import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js";
import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import type Stripe from "stripe";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructFeatureItem } from "@/utils/scriptUtils/constructItem.js";
import { constructProduct } from "@/utils/scriptUtils/createTestProducts.js";
import { initCustomerV3 } from "@/utils/scriptUtils/testUtils/initCustomerV3.js";
import { initProductsV0 } from "@/utils/scriptUtils/testUtils/initProductsV0.js";
export const free = constructProduct({
items: [

View File

@@ -1,13 +1,9 @@
import {
AttachBranch,
BillingInterval,
LegacyVersion,
} from "@autumn/shared";
import { beforeAll, describe, expect, test } from "bun:test";
import chalk from "chalk";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { AttachBranch, BillingInterval, LegacyVersion } from "@autumn/shared";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructPriceItem } from "@/internal/products/product-items/productItemUtils.js";
import { nullish } from "@/utils/genUtils.js";

View File

@@ -5,9 +5,6 @@ import {
LegacyVersion,
type Organization,
} from "@autumn/shared";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { expectAutumnError } from "@tests/utils/expectUtils/expectErrUtils.js";
@@ -15,6 +12,9 @@ import { createProducts } from "@tests/utils/productUtils.js";
import { advanceTestClock } from "@tests/utils/stripeUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import { addPrefixToProducts } from "@tests/utils/testProductUtils/testProductUtils.js";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import type Stripe from "stripe";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { timeout } from "@/utils/genUtils.js";

View File

@@ -1,12 +1,12 @@
import { beforeAll, describe, test } from "bun:test";
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { advanceTestClock } from "@tests/utils/stripeUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import type Stripe from "stripe";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructPrepaidItem } from "@/utils/scriptUtils/constructItem.js";

View File

@@ -1,12 +1,12 @@
import { beforeAll, describe, test } from "bun:test";
import { type AppEnv, LegacyVersion, type Organization } from "@autumn/shared";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { attachAndExpectCorrect } from "@tests/utils/expectUtils/expectAttach.js";
import { advanceTestClock } from "@tests/utils/stripeUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { addWeeks } from "date-fns";
import type Stripe from "stripe";
import type { DrizzleCli } from "@/db/initDrizzle.js";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructPrepaidItem } from "@/utils/scriptUtils/constructItem.js";

View File

@@ -5,12 +5,12 @@ import {
FreeTrialDuration,
ProductItemInterval,
} from "@autumn/shared";
import chalk from "chalk";
import { addDays } from "date-fns";
import type Stripe from "stripe";
import { TestFeature } from "@tests/setup/v2Features.js";
import { expectCustomerV0Correct } from "@tests/utils/expectUtils/expectCustomerV0Correct.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import { addDays } from "date-fns";
import type Stripe from "stripe";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import { constructPriceItem } from "@/internal/products/product-items/productItemUtils.js";
import { constructFeatureItem } from "@/utils/scriptUtils/constructItem.js";

View File

@@ -6,13 +6,13 @@ import {
type Customer,
ProductItemInterval,
} from "@autumn/shared";
import chalk from "chalk";
import type Stripe from "stripe";
import { AutumnCli } from "@tests/cli/AutumnCli.js";
import { TestFeature } from "@tests/setup/v2Features.js";
import { expectCustomerV0Correct } from "@tests/utils/expectUtils/expectCustomerV0Correct.js";
import { expectAutumnError } from "@tests/utils/expectUtils/expectErrUtils.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";
import type Stripe from "stripe";
import { AutumnInt } from "@/external/autumn/autumnCli.js";
import {
attachFailedPaymentMethod,

View File

@@ -1,5 +1,9 @@
import { beforeAll, describe, expect, test } from "bun:test";
import { ApiVersion, type CheckResponseV2, ResetInterval } from "@autumn/shared";
import {
ApiVersion,
type CheckResponseV2,
ResetInterval,
} from "@autumn/shared";
import { TestFeature } from "@tests/setup/v2Features.js";
import ctx from "@tests/utils/testInitUtils/createTestContext.js";
import chalk from "chalk";

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