spb/market-atlas
Public
TypeScript 96.7%
SQL 1.6%
CSS 0.8%
JavaScript 0.5%
1import { z } from "zod";2import {3 ASSET_CLASSES,4 EVENT_TYPES,5 FIELDS,6 OBSERVATION_TYPES,7 REALTIME_STATUSES,8 RIGHTS_STATUSES,9 SEVERITIES,10 SOURCE_TYPES,11 TIMESTAMP_TRUSTS,12} from "./enums.js";1314export const InstrumentHintSchema = z.object({15 assetClass: z.enum(ASSET_CLASSES),16 name: z.string().optional(),17 exchangeId: z.string().nullable().optional(),18 mic: z.string().nullable().optional(),19 currency: z.string().nullable().optional(),20 country: z.string().nullable().optional(),21 base: z.string().nullable().optional(),22 quote: z.string().nullable().optional(),23 securityType: z.string().nullable().optional(),24 companyName: z.string().nullable().optional(),25 cik: z.string().nullable().optional(),26 metadata: z.record(z.unknown()).optional(),27});2829export const NormalizedObservationSchema = z.object({30 symbol: z.string().min(1).max(64),31 instrumentId: z.string().optional(),32 instrumentHint: InstrumentHintSchema.optional(),33 field: z.enum(FIELDS),34 value: z.number().finite(),35 currency: z.string().nullable().optional(),36 observationType: z.enum(OBSERVATION_TYPES).optional(),37 sourceTimestamp: z.number().int().nullable(),38 timestampTrust: z.enum(TIMESTAMP_TRUSTS),39 sequence: z.union([z.number(), z.string()]).nullable().optional(),40 rightsStatus: z.enum(RIGHTS_STATUSES),41 realtimeStatus: z.enum(REALTIME_STATUSES),42 confidence: z.number().min(0).max(1).optional(),43 meta: z.record(z.unknown()).optional(),44});4546export const MarketEventSchema = z.object({47 version: z.literal(1),48 id: z.string(),49 type: z.enum(EVENT_TYPES),50 instrumentIds: z.array(z.string()),51 entityIds: z.array(z.string()),52 timestamp: z.number().int(),53 severity: z.enum(SEVERITIES),54 confidence: z.number().min(0).max(1),55 sourceCount: z.number().int().nonnegative(),56 sources: z.array(z.string()),57 title: z.string(),58 summary: z.string().nullable(),59 data: z.record(z.unknown()),60 fingerprint: z.string(),61 supportingObservations: z.array(z.string()),62});6364export const ConnectorMetadataSchema = z.object({65 id: z.string().regex(/^[a-z0-9][a-z0-9-]{1,60}$/),66 name: z.string(),67 version: z.string(),68 sourceId: z.string(),69 organization: z.string().nullable(),70 sourceType: z.enum(SOURCE_TYPES),71 jurisdiction: z.string().nullable(),72 rightsStatus: z.enum(RIGHTS_STATUSES),73 realtimeStatus: z.enum(REALTIME_STATUSES),74 expectedLatencyMs: z.number().nullable(),75 supportsStreaming: z.boolean(),76 supportsHistorical: z.boolean(),77 assetClasses: z.array(z.enum(ASSET_CLASSES)),78 exchanges: z.array(z.string()),79 homepage: z.string().url().nullable(),80 description: z.string(),81 rightsNotes: z.string().nullable(),82 termsUrl: z.string().url().nullable(),83 sourceFamily: z.string().nullable(),84 enabled: z.boolean(),85});8687/** WebSocket client → gateway messages. */88export const StreamClientMessageSchema = z.discriminatedUnion("action", [89 z.object({ action: z.literal("subscribe"), channels: z.array(z.string().max(120)).max(500) }),90 z.object({ action: z.literal("unsubscribe"), channels: z.array(z.string().max(120)).max(500) }),91 z.object({ action: z.literal("ping"), id: z.union([z.string(), z.number()]).optional() }),92]);93export type StreamClientMessage = z.infer<typeof StreamClientMessageSchema>;94