/** * OpsxAPI 集合数据模型 —— UI / 导入导出 / 持久化共用的唯一事实源。 */ export type RequestMethod = | "GET" | "POST" | "PUT" | "PATCH" | "DELETE" | "HEAD" | "OPTIONS"; export const REQUEST_METHODS: RequestMethod[] = [ "GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS", ]; export type RequestKind = "http" | "graphql" | "websocket" | "sse" | "socketio" | "mqtt"; export const REQUEST_KINDS: RequestKind[] = [ "http", "graphql", "websocket", "sse", "socketio", "mqtt", ]; export const KIND_LABELS: Record = { http: "HTTP", graphql: "GraphQL", websocket: "WebSocket", sse: "SSE", socketio: "Socket.IO", mqtt: "MQTT", }; /** 键值行:Params / Headers / Cookies / 表单 / 环境变量共用 */ export type KVRow = { id: string; key: string; value: string; enabled: boolean; description?: string; }; export type BodyMode = | "none" | "json" | "xml" | "text" | "html" | "urlencoded" | "form-data"; export const BODY_MODE_LABELS: Record = { none: "none", json: "JSON", xml: "XML", text: "Text", html: "HTML", urlencoded: "x-www-form-urlencoded", "form-data": "form-data", }; export const RAW_BODY_MODES: BodyMode[] = ["json", "xml", "text", "html"]; export type AuthMode = "none" | "bearer" | "basic" | "apikey"; export type AuthConfig = { mode: AuthMode; bearer?: string; basicUser?: string; basicPass?: string; apiKeyName?: string; apiKeyValue?: string; apiKeyIn?: "header" | "query"; }; export type HttpRequestData = { kind: "http"; method: RequestMethod; url: string; query: KVRow[]; headers: KVRow[]; cookies: KVRow[]; auth: AuthConfig; bodyMode: BodyMode; bodyRaw: string; bodyForm: KVRow[]; }; export type GraphqlRequestData = { kind: "graphql"; url: string; headers: KVRow[]; auth: AuthConfig; query: string; variables: string; }; export type WebsocketRequestData = { kind: "websocket"; url: string; headers: KVRow[]; protocols: string; }; export type SseRequestData = { kind: "sse"; url: string; headers: KVRow[]; query: KVRow[]; auth: AuthConfig; lastEventId: string; /** 仅解析 data: 行为 JSON */ dataOnly: boolean; }; export type SocketIoRequestData = { kind: "socketio"; url: string; /** 额外连接参数(JSON:auth / transports / path …) */ options: string; /** 监听的服务端事件名 */ listenEvents: string[]; sendEvent: string; sendArgs: string; }; export type MqttRequestData = { kind: "mqtt"; brokerUrl: string; username: string; password: string; clientId: string; /** 订阅主题,逗号分隔 */ subscribeTopics: string; publishTopic: string; publishPayload: string; qos: 0 | 1 | 2; }; export type RequestData = | HttpRequestData | GraphqlRequestData | WebsocketRequestData | SseRequestData | SocketIoRequestData | MqttRequestData; export type RequestDataOf = Extract; export type RequestNodeBase = { id: string; type: "request"; name: string; description?: string; createdAt: number; updatedAt: number; }; export type HttpApiNode = RequestNodeBase & { kind: "http"; data: HttpRequestData }; export type GraphqlApiNode = RequestNodeBase & { kind: "graphql"; data: GraphqlRequestData }; export type WebsocketApiNode = RequestNodeBase & { kind: "websocket"; data: WebsocketRequestData }; export type SseApiNode = RequestNodeBase & { kind: "sse"; data: SseRequestData }; export type SocketIoApiNode = RequestNodeBase & { kind: "socketio"; data: SocketIoRequestData }; export type MqttApiNode = RequestNodeBase & { kind: "mqtt"; data: MqttRequestData }; /** 判别联合:`node.kind === "http"` 时自动收窄 data 类型 */ export type RequestNode = | HttpApiNode | GraphqlApiNode | WebsocketApiNode | SseApiNode | SocketIoApiNode | MqttApiNode; export type FolderNode = { id: string; type: "folder"; name: string; description?: string; children: CollectionNode[]; createdAt: number; updatedAt: number; }; export type CollectionNode = RequestNode | FolderNode; /** 一个集合(项目),本身是一个顶层目录 */ export type Collection = { id: string; type: "collection"; name: string; description?: string; children: CollectionNode[]; createdAt: number; updatedAt: number; }; export type Environment = { id: string; name: string; variables: KVRow[]; }; export type HistoryEntry = { id: string; at: number; kind: RequestKind; label: string; method?: RequestMethod; url: string; status?: number; durationMs?: number; ok: boolean; /** 关联的请求节点 id(可回跳) */ nodeId?: string; }; export type ThemeMode = "dark" | "light"; export type WorkspaceSettings = { theme: ThemeMode; /** 请求超时(毫秒) */ timeoutMs: number; }; export type WorkspaceData = { version: 2; collections: Collection[]; environments: Environment[]; activeEnvironmentId: string | null; history: HistoryEntry[]; settings: WorkspaceSettings; }; /** 导入结果:集合 + 建议写入环境的前缀变量(如 baseUrl) */ export type ImportResult = { collections: Collection[]; environmentVariables: { key: string; value: string }[]; warnings: string[]; };