import {z} from 'zod' export type GetApiV1StocksTickerShareholderVotesArgs = {ticker: string, limit?: number | undefined}; export type GetApiV1StocksTickerShareholderVotesOptions = {baseUrl?: string | undefined, ApiKey?: string | undefined, fetch?: typeof fetch | undefined}; export const shareholderVoteCoverageDto = z.object({filingsOnFile: z.number().int().optional(), approved: z.number().int().optional(), awaitingExtraction: z.number().int().optional(), rejected: z.number().int().optional(), noVoteCounts: z.number().int().optional(), unreadable: z.number().int().optional(), beforeCoverage: z.number().int().optional(), coverageStartDate: z.string().optional()}); export const shareholderVoteFilingStateDto = z.object({state: z.string().nullable().optional(), documentId: z.string().optional(), form: z.string().nullable().optional(), filedDate: z.string().optional(), filingUrl: z.string().nullable().optional()}); export const listingNotice = z.object({status: z.string().nullable().optional(), ticker: z.string().nullable().optional(), delistedOn: z.string().nullable().optional(), successorTicker: z.string().nullable().optional()}); export const shareholderVoteFilingDto = z.object({documentId: z.string().optional(), form: z.string().nullable().optional(), filedDate: z.string().optional(), filingUrl: z.string().nullable().optional()}); export const shareholderVoteProposalDto = z.object({number: z.string().nullable().optional(), title: z.string().nullable().optional(), kind: z.string().nullable().optional(), nomineeName: z.string().nullable().optional(), votesFor: z.number().int().nullable().optional(), votesAgainst: z.number().int().nullable().optional(), votesAbstain: z.number().int().nullable().optional(), votesWithheld: z.number().int().nullable().optional(), brokerNonVotes: z.number().int().nullable().optional(), votesOneYear: z.number().int().nullable().optional(), votesTwoYears: z.number().int().nullable().optional(), votesThreeYears: z.number().int().nullable().optional(), outcome: z.string().nullable().optional(), outcomeQuote: z.string().nullable().optional()}); export const shareholderVoteMeetingFilingDto = z.object({role: z.string().nullable().optional(), source: shareholderVoteFilingDto.optional(), meetingDateQuote: z.string().nullable().optional(), supersededFilings: z.array(shareholderVoteFilingDto).nullable().optional(), proposals: z.array(shareholderVoteProposalDto).nullable().optional()}); export const shareholderVoteMeetingDto = z.object({meetingDate: z.string().nullable().optional(), filings: z.array(shareholderVoteMeetingFilingDto).nullable().optional()}); export const shareholderVotesResponse = z.object({ticker: z.string().nullable().optional(), status: z.string().nullable().optional(), meetingsOnRecord: z.number().int().optional(), coverage: shareholderVoteCoverageDto.optional(), unpublishedFilings: z.array(shareholderVoteFilingStateDto).nullable().optional(), listingNotice: listingNotice.optional(), data: z.array(shareholderVoteMeetingDto).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 }; /** * Shareholder meeting vote results from the company's SEC 8-K Item 5.07 filings, newest meeting first. Each meeting lists its verified filings (an approved 8-K/A replaces the 8-K only when it restates every matter; otherwise both are listed, never merged), each with every matter, one row per director nominee, with the counts as printed (null when the filing printed none), the stated outcome and its quote. status, coverage and unpublishedFilings make an empty or partial answer interpretable. * * GET /v1/stocks/{ticker}/shareholder-votes */ export const getApiV1StocksTickerShareholderVotes = async (args: GetApiV1StocksTickerShareholderVotesArgs, options?: GetApiV1StocksTickerShareholderVotesOptions) => { const {baseUrl = "https://api.equibles.com", 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 (ApiKey !== undefined) headers.set('authorization', `Bearer ${ApiKey}`) const url = `${baseUrl.replace(/\/+$/, '')}/v1/stocks/${encodeURIComponent(String(args.ticker))}/shareholder-votes${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(shareholderVotesResponse, await res.json()) };