import {z} from 'zod' export type GetApiFundingV1RoundsArgs = {limit?: number | undefined, page?: number | undefined, fundedEntityId?: Array | undefined, investorId?: Array | undefined, type?: (Array<'Accelerator' | 'Debt Financing' | 'Extended Pre Seed' | 'Extended Seed' | 'Extended Series A' | 'Extended Series B' | 'Extended Series C' | 'Extended Series D' | 'Grant' | 'ICO' | 'IPO' | 'Post IPO' | 'Post IPO Debt' | 'Pre Seed' | 'Pre Series A' | 'Pre Series B' | 'Private Token Sale' | 'Public Token Sale' | 'Seed' | 'Series A' | 'Series B' | 'Series C' | 'Series D' | 'Series E' | 'Series F' | 'Series G' | 'Series H' | 'Strategic' | 'Treasury Diversification' | 'Undisclosed'>) | undefined, stage?: (Array<'Seed' | 'Early Stage' | 'Late Stage' | 'Public Equity Offering' | 'Post Public Equity' | 'Miscellaneous'>) | undefined, raisedAmountMax?: number | undefined, raisedAmountMin?: number | undefined, isTokenFunded?: boolean | undefined, announcedBefore?: string | undefined, announcedAfter?: string | undefined}; export type GetApiFundingV1RoundsOptions = {baseUrl?: string | undefined, apiKey?: string | undefined, fetch?: typeof fetch | undefined}; export const announcement = z.record(z.string(), z.unknown()); export const fundingEntity = z.record(z.string(), z.unknown()); export const fundingRound = z.object({amountRaisedUSD: z.number().optional(), announcementDate: z.string(), announcements: z.array(announcement), fundedEntity: fundingEntity, id: z.string(), isTokenFunded: z.boolean(), stage: z.enum(["Seed", "Early Stage", "Late Stage", "Public Equity Offering", "Post Public Equity", "Miscellaneous"]), type: z.enum(["Accelerator", "Debt Financing", "Extended Pre Seed", "Extended Seed", "Extended Series A", "Extended Series B", "Extended Series C", "Extended Series D", "Grant", "ICO", "IPO", "Post IPO", "Post IPO Debt", "Pre Seed", "Pre Series A", "Pre Series B", "Private Token Sale", "Public Token Sale", "Seed", "Series A", "Series B", "Series C", "Series D", "Series E", "Series F", "Series G", "Series H", "Strategic", "Treasury Diversification", "Undisclosed"])}); export const pagination = z.object({limit: z.number().int(), page: z.number().int(), totalPages: z.number().int(), totalRows: z.number().int()}); export const getApiFundingV1RoundsResponse = z.object({data: z.array(fundingRound), error: z.string().optional(), metadata: pagination.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 }; /** * GetRounds * * GET /funding/v1/rounds */ export const getApiFundingV1Rounds = async (args: GetApiFundingV1RoundsArgs, options?: GetApiFundingV1RoundsOptions) => { const {baseUrl = "https://api.messari.io", fetch: fetchFn = fetch, apiKey} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('accept', "application/json") if (args.limit != null) query.append("limit", String(args.limit)) if (args.page != null) query.append("page", String(args.page)) for (const item of args.fundedEntityId ?? []) query.append("fundedEntityId", String(item)) for (const item of args.investorId ?? []) query.append("investorId", String(item)) for (const item of args.type ?? []) query.append("type", String(item)) for (const item of args.stage ?? []) query.append("stage", String(item)) if (args.raisedAmountMax != null) query.append("raisedAmountMax", String(args.raisedAmountMax)) if (args.raisedAmountMin != null) query.append("raisedAmountMin", String(args.raisedAmountMin)) if (args.isTokenFunded != null) query.append("isTokenFunded", String(args.isTokenFunded)) if (args.announcedBefore != null) query.append("announcedBefore", String(args.announcedBefore)) if (args.announcedAfter != null) query.append("announcedAfter", String(args.announcedAfter)) if (apiKey !== undefined) headers.set("X-Messari-API-Key", apiKey) const url = `${baseUrl.replace(/\/+$/, '')}/funding/v1/rounds${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(getApiFundingV1RoundsResponse, await res.json()) };