import {z} from 'zod' export type GetApiApiCompanyResearchSummaryArgs = {symbol?: string | undefined, cik?: number | undefined, cusip?: string | undefined, composite_figi?: string | undefined, share_class_figi?: string | undefined}; export type GetApiApiCompanyResearchSummaryOptions = {baseUrl?: string | undefined, bearerAuth?: string | undefined, fetch?: typeof fetch | undefined}; export const entityLink = z.object({name: z.string(), cik: z.number().int().nullable(), relationType: z.string(), effectiveDate: z.string().nullable().optional(), corroborated: z.boolean()}); export const companyDetails = z.object({name: z.string().optional(), cik: z.number().int().optional(), sic: z.string().optional(), industry: z.string().optional(), industryGroup: z.string().nullable().optional(), sector: z.string().optional(), description: z.string().optional(), fiscalYearEndMonth: z.number().int().optional(), fiscalYearEndDay: z.number().int().optional(), symbols: z.array(z.string()).optional(), exchanges: z.array(z.string()).optional(), address: z.string().optional(), city: z.string().optional(), state: z.string().optional(), zip: z.string().optional(), country: z.string().optional(), phone: z.string().optional(), type: z.string().nullable().optional(), status: z.enum(["operating", "delisted"]).optional(), webUrl: z.string().nullable().optional(), investorRelationsUrl: z.string().nullable().optional(), logoUrl: z.string().nullable().optional(), ipoDate: z.string().optional(), employees: z.object({count: z.number().int().optional(), asOf: z.string().optional()}).optional(), predecessors: z.array(entityLink).optional(), successors: z.array(entityLink).optional()}); export const fiscalPeriod = z.enum(["FY", "Q1", "Q2", "Q3", "Q4", "TTM"]); export const altmanZone = z.enum(["safe", "grey", "distress"]); export const keyMetricsGeneral = z.object({revenue: z.number().nullable().optional(), netIncome: z.number().nullable().optional(), grossMargin: z.number().nullable().optional(), operatingMargin: z.number().nullable().optional(), profitMargin: z.number().nullable().optional(), debtToEquity: z.number().nullable().optional(), quickRatio: z.number().nullable().optional(), currentRatio: z.number().nullable().optional(), roa: z.number().nullable().optional(), roe: z.number().nullable().optional(), roic: z.number().nullable().optional(), eps: z.number().nullable().optional(), ebitda: z.number().nullable().optional(), freeCashFlow: z.number().nullable().optional(), fcfMargin: z.number().nullable().optional(), fcfNetIncome: z.number().nullable().optional(), assetTurnover: z.number().nullable().optional(), interestCoverage: z.number().nullable().optional(), netDebt: z.number().nullable().optional(), netDebtEbitda: z.number().nullable().optional(), investedCapital: z.number().nullable().optional(), sbcRevenue: z.number().nullable().optional(), dividendPayout: z.number().nullable().optional(), netShareChange: z.number().nullable().optional(), cashRatio: z.number().nullable().optional(), operatingCashFlowRatio: z.number().nullable().optional(), receivablesTurnover: z.number().nullable().optional(), payablesTurnover: z.number().nullable().optional(), inventoryTurnover: z.number().nullable().optional(), fixedAssetTurnover: z.number().nullable().optional(), financialLeverageRatio: z.number().nullable().optional(), longTermDebtToCapitalRatio: z.number().nullable().optional(), freeCashFlowOperatingCashFlowRatio: z.number().nullable().optional(), capitalExpenditureCoverageRatio: z.number().nullable().optional(), pretaxProfitMargin: z.number().nullable().optional(), effectiveTaxRate: z.number().nullable().optional(), revenuePerShare: z.number().nullable().optional(), netIncomePerShare: z.number().nullable().optional(), operatingCashFlowPerShare: z.number().nullable().optional(), freeCashFlowPerShare: z.number().nullable().optional(), cashPerShare: z.number().nullable().optional(), bookValuePerShare: z.number().nullable().optional()}); export const keyMetricsSector = z.object({affo: z.number().nullable().optional(), allowancePctAr: z.number().nullable().optional(), allowanceToLoans: z.number().nullable().optional(), aroCurrent: z.number().nullable().optional(), aroNoncurrent: z.number().nullable().optional(), assetTurnover: z.number().nullable().optional(), bondingCapacity: z.number().nullable().optional(), bookValueGrowth: z.number().nullable().optional(), capexDda: z.number().nullable().optional(), capexDepreciation: z.number().nullable().optional(), capexRevenue: z.number().nullable().optional(), ccc: z.number().nullable().optional(), cipRatio: z.number().nullable().optional(), combinedRatio: z.number().nullable().optional(), contractAssetRatio: z.number().nullable().optional(), contractLiabilityRatio: z.number().nullable().optional(), dacRatio: z.number().nullable().optional(), daysInventory: z.number().nullable().optional(), debtEbitda: z.number().nullable().optional(), debtEquity: z.number().nullable().optional(), debtToAssets: z.number().nullable().optional(), debtToEquity: z.number().nullable().optional(), dio: z.number().nullable().optional(), dividendCoverage: z.number().nullable().optional(), dividendPayout: z.number().nullable().optional(), dpo: z.number().nullable().optional(), dso: z.number().nullable().optional(), ebitdaMargin: z.number().nullable().optional(), efficiencyRatio: z.number().nullable().optional(), expenseRatio: z.number().nullable().optional(), ffo: z.number().nullable().optional(), ffoPerShare: z.number().nullable().optional(), floatSize: z.number().nullable().optional(), floatYield: z.number().nullable().optional(), grossMargin: z.number().nullable().optional(), incomePerStore: z.number().nullable().optional(), insuranceLeverage: z.number().nullable().optional(), interestCoverage: z.number().nullable().optional(), interestExpense: z.number().nullable().optional(), interestIncome: z.number().nullable().optional(), inventoryPerStore: z.number().nullable().optional(), inventoryRevenue: z.number().nullable().optional(), inventoryTurnover: z.number().nullable().optional(), investmentIncome: z.number().nullable().optional(), loanToDeposit: z.number().nullable().optional(), lossRatio: z.number().nullable().optional(), netInterestIncome: z.number().nullable().optional(), netMargin: z.number().nullable().optional(), netProfitMargin: z.number().nullable().optional(), nim: z.number().nullable().optional(), ocfRevenue: z.number().nullable().optional(), operatingMargin: z.number().nullable().optional(), operatingRatio: z.number().nullable().optional(), payoutRatio: z.number().nullable().optional(), ppeIntensity: z.number().nullable().optional(), premiumGrowth: z.number().nullable().optional(), provisionToLoans: z.number().nullable().optional(), reserveRatio: z.number().nullable().optional(), retainage: z.number().nullable().optional(), revenueGrowth: z.number().nullable().optional(), revenuePerStore: z.number().nullable().optional(), roa: z.number().nullable().optional(), roe: z.number().nullable().optional(), sgaRevenue: z.number().nullable().optional(), storeCount: z.number().nullable().optional(), underwritingIncome: z.number().nullable().optional(), warrantyReserve: z.number().nullable().optional(), workingCapitalRatio: z.number().nullable().optional()}); export const keyMetricsIndustry = z.object({billings: z.number().nullable().optional(), capexToDepreciation: z.number().nullable().optional(), capexToRevenue: z.number().nullable().optional(), cashRunwayQuarters: z.number().nullable().optional(), daToRevenue: z.number().nullable().optional(), debtToEbitda: z.number().nullable().optional(), debtToEquity: z.number().nullable().optional(), deferredRevenue: z.number().nullable().optional(), deferredRevenueGrowth: z.number().nullable().optional(), dividendPayout: z.number().nullable().optional(), ebitdaMargin: z.number().nullable().optional(), fcfConversion: z.number().nullable().optional(), fcfMargin: z.number().nullable().optional(), grossMargin: z.number().nullable().optional(), interestCoverage: z.number().nullable().optional(), inventoryTurnover: z.number().nullable().optional(), rdToRevenue: z.number().nullable().optional(), remainingPerformanceObligations: z.number().nullable().optional(), sbcToRevenue: z.number().nullable().optional(), sgaToRevenue: z.number().nullable().optional()}); export const getApiApiCompanyResearchSummaryResponse = z.object({profile: companyDetails.optional(), snapshot: z.object({symbol: z.string().optional(), period: z.string().optional(), fiscalYear: z.number().int().optional(), fiscalPeriod: fiscalPeriod.optional(), eps: z.number().nullable().optional(), epsDiluted: z.number().nullable().optional(), netIncome: z.number().nullable().optional(), revenue: z.number().nullable().optional(), grossMargin: z.number().nullable().optional(), operatingMargin: z.number().nullable().optional(), netMargin: z.number().nullable().optional(), roe: z.number().nullable().optional(), roic: z.number().nullable().optional(), freeCashFlow: z.number().nullable().optional(), fcfToNetIncome: z.number().nullable().optional(), revenueGrowth: z.number().nullable().optional(), epsGrowth: z.number().nullable().optional(), netIncomeGrowth: z.number().nullable().optional(), piotroskiFScore: z.number().int().optional(), altmanZScore: z.number().nullable().optional(), altmanZone: altmanZone.nullable().optional(), nextEarningsDate: z.string().nullable().optional(), nextFilingDate: z.string().nullable().optional()}).nullable().optional(), keyMetrics: z.object({period: z.string().optional(), fiscalYear: z.number().int().optional(), fiscalPeriod: fiscalPeriod.optional(), sector: z.string().nullable().optional(), sectorId: z.string().nullable().optional(), industry: z.string().nullable().optional(), industryId: z.string().nullable().optional(), general: keyMetricsGeneral.optional(), sectorMetrics: keyMetricsSector.optional(), industryMetrics: keyMetricsIndustry.optional()}).nullable().optional()}); export const validateResponse = async ( schema: { readonly '~standard': { readonly validate: (value: unknown) => ({ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }) | Promise<{ readonly value: Output; readonly issues?: undefined } | { readonly issues: ReadonlyArray<{ readonly message: string; readonly path?: ReadonlyArray | undefined }> }> } }, value: unknown ): Promise => { const result = await schema['~standard'].validate(value) if (result.issues !== undefined) { const detail = result.issues .map(({ message, path }) => path?.length ? `${path.map((segment) => String(typeof segment === 'object' ? segment.key : segment)).join('.')}: ${message}` : message ) .join('; ') throw new Error(`Response does not match the schema: ${detail}`, { cause: { issues: result.issues } }) } return result.value }; /** * Research summary * * GET /api/company/research-summary */ export const getApiApiCompanyResearchSummary = async (args: GetApiApiCompanyResearchSummaryArgs, options?: GetApiApiCompanyResearchSummaryOptions) => { const {baseUrl = "https://api.stockfit.io/v1", fetch: fetchFn = fetch, bearerAuth} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.symbol != null) query.append("symbol", String(args.symbol)) if (args.cik != null) query.append("cik", String(args.cik)) if (args.cusip != null) query.append("cusip", String(args.cusip)) if (args.composite_figi != null) query.append("composite_figi", String(args.composite_figi)) if (args.share_class_figi != null) query.append("share_class_figi", String(args.share_class_figi)) if (bearerAuth !== undefined) headers.set('authorization', `Bearer ${bearerAuth}`) const url = `${baseUrl.replace(/\/+$/, '')}/api/company/research-summary${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "GET", headers}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(getApiApiCompanyResearchSummaryResponse, await res.json()) };