import {z} from 'zod' export type FireAntApiModelsIRIRPagePreviewRequest = {content?: Record | undefined, lang?: string | undefined}; export type CreateApiIrSymbolPagePreviewArgs = {symbol: string, body: FireAntApiModelsIRIRPagePreviewRequest}; export type CreateApiIrSymbolPagePreviewOptions = {baseUrl?: string | undefined, oauth2?: string | undefined, fetch?: typeof fetch | undefined}; export const fireAntApiModelsIRIRBundleCompany = z.object({name: z.string().optional(), shortName: z.string().optional(), exchange: z.string().optional(), industry: z.string().optional(), logo: z.string().optional(), website: z.string().optional(), oaUserId: z.string().optional(), oaName: z.string().optional()}); export const fireAntApiModelsIRIRLText = z.object({vi: z.string().optional(), en: z.string().optional()}); export const fireAntApiModelsIRIRBundleMedia = z.object({url: z.string().optional(), width: z.number().int().optional(), height: z.number().int().optional(), contentType: z.string().optional(), alt: fireAntApiModelsIRIRLText.optional()}); export const fireAntApiModelsIRIRQuoteSnapshot = z.object({price: z.number().optional(), refPrice: z.number().optional(), change: z.number().optional(), changePct: z.number().optional(), open: z.number().optional(), high: z.number().optional(), low: z.number().optional(), volume: z.number().optional(), value: z.number().optional(), marketCap: z.number().optional(), sharesOutstanding: z.number().optional(), freeShares: z.number().optional(), high52w: z.number().optional(), low52w: z.number().optional(), change1y: z.number().optional(), foreignRoom: z.number().optional(), foreignOwnership: z.number().optional(), beta: z.number().optional(), avgVolume10d: z.number().optional(), asOf: z.string().optional()}); export const fireAntApiModelsIRIRKeyFacts = z.object({companyName: z.string().optional(), shortName: z.string().optional(), internationalName: z.string().optional(), exchange: z.string().optional(), icbCode: z.string().optional(), industry: z.string().optional(), companyType: z.string().optional(), charterCapital: z.number().optional(), sharesOutstanding: z.number().optional(), listingDate: z.string().optional(), establishmentDate: z.string().optional(), headquarters: z.string().optional(), phone: z.string().optional(), email: z.string().optional(), website: z.string().optional(), employees: z.number().int().optional(), branches: z.number().int().optional(), taxCode: z.string().optional(), overview: z.string().optional(), businessAreas: z.string().optional(), isListed: z.boolean().optional()}); export const fireAntApiModelsIRIRFinancialSeries = z.object({period: z.string().optional(), periods: z.array(z.string()).optional(), values: z.record(z.string(), z.array(z.number())).optional(), sector: z.record(z.string(), z.array(z.number())).optional()}); export const fireAntApiModelsIRIRFinancialsData = z.object({companyType: z.string().optional(), quarterly: fireAntApiModelsIRIRFinancialSeries.optional(), annual: fireAntApiModelsIRIRFinancialSeries.optional(), ttm: z.record(z.string(), z.number()).optional(), latestPeriod: z.string().optional()}); export const fireAntApiModelsIRIRRatioItem = z.object({key: z.string().optional(), value: z.number().optional(), industry: z.number().optional()}); export const fireAntApiModelsIRIRDividendYear = z.object({year: z.number().int().optional(), cash: z.number().optional(), stock: z.number().optional()}); export const fireAntApiModelsIRIRCorporateEvent = z.object({id: z.number().int().optional(), kind: z.string().optional(), title: z.string().optional(), exDate: z.string().optional(), recordDate: z.string().optional(), payDate: z.string().optional()}); export const fireAntApiModelsIRIRPricePoint = z.object({d: z.string().optional(), c: z.number().optional(), v: z.number().optional()}); export const fireAntApiModelsIRIRPricesData = z.object({daily: z.array(fireAntApiModelsIRIRPricePoint).optional(), weekly: z.array(fireAntApiModelsIRIRPricePoint).optional()}); export const fireAntApiModelsIRIRHolderItem = z.object({name: z.string().optional(), position: z.string().optional(), shares: z.number().optional(), ownership: z.number().optional(), isOrganization: z.boolean().optional(), isForeigner: z.boolean().optional(), reported: z.string().optional()}); export const fireAntApiModelsIRIROwnership = z.object({state: z.number().optional(), foreign: z.number().optional(), other: z.number().optional(), freeFloat: z.number().optional(), foreignLimit: z.number().optional(), asOf: z.string().optional()}); export const fireAntApiModelsIRIROfficerItem = z.object({name: z.string().optional(), position: z.string().optional(), group: z.string().optional(), isForeigner: z.boolean().optional(), individualId: z.number().int().optional(), photoUrl: z.string().optional()}); export const fireAntApiModelsIRIRInsiderTrade = z.object({name: z.string().optional(), position: z.string().optional(), kind: z.string().optional(), registered: z.number().optional(), executed: z.number().optional(), startDate: z.string().optional(), endDate: z.string().optional(), executionDate: z.string().optional()}); export const fireAntApiModelsIRIRNewsItem = z.object({id: z.number().int().optional(), title: z.string().optional(), summary: z.string().optional(), date: z.string().optional(), url: z.string().optional(), source: z.string().optional(), kind: z.string().optional(), image: z.string().optional()}); export const fireAntApiModelsIRIRBundleDocument = z.object({id: z.number().int().optional(), title: z.string().optional(), category: z.number().int().optional(), period: z.string().optional(), language: z.string().optional(), url: z.string().optional(), fileName: z.string().optional(), size: z.number().int().optional(), contentType: z.string().optional(), publishedDate: z.string().optional(), downloads: z.number().int().optional()}); export const fireAntApiModelsIRIRBundleEvent = z.object({id: z.number().int().optional(), type: z.number().int().optional(), title: z.string().optional(), description: z.string().optional(), start: z.string().optional(), end: z.string().optional(), location: z.string().optional(), onlineUrl: z.string().optional(), livestreamPostId: z.number().int().optional(), status: z.number().int().optional(), registrable: z.boolean().optional(), registrations: z.number().int().optional()}); export const fireAntApiModelsIRIRBundleQuestion = z.object({id: z.number().int().optional(), body: z.string().optional(), askedByName: z.string().optional(), anonymous: z.boolean().optional(), askedAt: z.string().optional(), status: z.string().optional(), answer: z.string().optional(), answeredAt: z.string().optional(), upVotes: z.number().int().optional(), context: z.string().optional()}); export const fireAntApiModelsIRIRBundleQuestions = z.object({items: z.array(fireAntApiModelsIRIRBundleQuestion).optional(), total: z.number().int().optional(), answered: z.number().int().optional(), pending: z.number().int().optional()}); export const fireAntApiModelsIRIRBundleSurvey = z.object({companySurveyId: z.number().int().optional(), surveyId: z.number().int().optional(), title: z.string().optional(), status: z.number().int().optional(), endDate: z.string().optional(), responses: z.number().int().optional()}); export const fireAntApiModelsIRIRLivestreamInfo = z.object({postId: z.number().int().optional(), title: z.string().optional(), userId: z.string().optional(), started: z.boolean().optional(), ended: z.boolean().optional(), scheduledAt: z.string().optional(), viewUrl: z.string().optional(), thumbnail: z.string().optional()}); export const fireAntApiModelsIRIRPeerRow = z.object({symbol: z.string().optional(), name: z.string().optional(), self: z.boolean().optional(), values: z.record(z.string(), z.number()).optional()}); export const fireAntApiModelsIRIRPlanItem = z.object({metric: z.string().optional(), year: z.number().int().optional(), target: z.number().optional(), actual: z.number().optional(), ratio: z.number().optional(), source: z.string().optional(), quarters: z.array(z.number()).optional(), asOf: z.string().optional(), sourceDocumentId: z.number().int().optional()}); export const fireAntApiModelsIRIRPageData = z.object({quote: fireAntApiModelsIRIRQuoteSnapshot.optional(), facts: fireAntApiModelsIRIRKeyFacts.optional(), financials: fireAntApiModelsIRIRFinancialsData.optional(), ratios: z.array(fireAntApiModelsIRIRRatioItem).optional(), dividends: z.array(fireAntApiModelsIRIRDividendYear).optional(), corporateEvents: z.array(fireAntApiModelsIRIRCorporateEvent).optional(), prices: fireAntApiModelsIRIRPricesData.optional(), holders: z.array(fireAntApiModelsIRIRHolderItem).optional(), ownership: fireAntApiModelsIRIROwnership.optional(), officers: z.array(fireAntApiModelsIRIROfficerItem).optional(), insiderTrades: z.array(fireAntApiModelsIRIRInsiderTrade).optional(), disclosures: z.array(fireAntApiModelsIRIRNewsItem).optional(), news: z.array(fireAntApiModelsIRIRNewsItem).optional(), oaPosts: z.array(fireAntApiModelsIRIRNewsItem).optional(), documents: z.array(fireAntApiModelsIRIRBundleDocument).optional(), events: z.array(fireAntApiModelsIRIRBundleEvent).optional(), questions: fireAntApiModelsIRIRBundleQuestions.optional(), surveys: z.array(fireAntApiModelsIRIRBundleSurvey).optional(), livestreams: z.array(fireAntApiModelsIRIRLivestreamInfo).optional(), peers: z.array(fireAntApiModelsIRIRPeerRow).optional(), plan: z.array(fireAntApiModelsIRIRPlanItem).optional()}); export const fireAntApiModelsIRIRTokenValue = z.object({v: z.object({}).optional(), asOf: z.string().optional()}); export const fireAntApiModelsIRIRPageBundle = z.object({symbol: z.string().optional(), locale: z.string().optional(), status: z.string().optional(), official: z.boolean().optional(), verified: z.boolean().optional(), company: fireAntApiModelsIRIRBundleCompany.optional(), page: z.object({}).optional(), media: z.record(z.string(), fireAntApiModelsIRIRBundleMedia).optional(), data: fireAntApiModelsIRIRPageData.optional(), tokens: z.record(z.string(), fireAntApiModelsIRIRTokenValue).optional(), features: z.array(z.string()).optional(), version: z.number().int().optional(), publishedAt: z.string().optional(), generatedAt: z.string().optional(), canonicalUrl: z.string().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 }; /** * Dựng gói trang từ nội dung chưa lưu để xem trước như nhà đầu tư thấy * * POST /ir/{symbol}/page/preview */ export const createApiIrSymbolPagePreview = async (args: CreateApiIrSymbolPagePreviewArgs, options?: CreateApiIrSymbolPagePreviewOptions) => { const {baseUrl = "https://api.fireant.vn", fetch: fetchFn = fetch, oauth2} = options ?? {} const query = new URLSearchParams() const headers = new Headers() headers.set('content-type', "application/json") headers.set('accept', "application/json") if (oauth2 !== undefined) headers.set('authorization', `Bearer ${oauth2}`) const url = `${baseUrl.replace(/\/+$/, '')}/ir/${encodeURIComponent(String(args.symbol))}/page/preview${query.size > 0 ? `?${query}` : ''}` const res = await fetchFn(url, {method: "POST", headers, body: JSON.stringify(args.body)}) if (!res.ok) throw new Error(`Request failed with status ${res.status}`, {cause: {status: res.status, body: await res.text()}}) return validateResponse(fireAntApiModelsIRIRPageBundle, await res.json()) };