import * as v from "valibot" import { notionDataSourceBindingsSchema } from "../dataSources/dataSource.js" import type { CustomBlockErrorInfo } from "../errors.js" import { notionBlockIdSchema } from "../ids.js" import { customBlockPageSchema } from "../pages/page.js" import { notionParentSchema } from "../parent.js" import { notionThemeSchema } from "../theme.js" import { notionUserSchema } from "../users/user.js" // The schema accepts any string code. The type lists known codes for // autocomplete, with an open string fallback for newer senders. export const customBlockInitErrorCodeSchema = v.string() export type CustomBlockInitErrorCode = | "no_ready" | "invalid_ready" | "manifest_unavailable" | "manifest_invalid" | "invalid_protocol_version" | "unsupported_protocol_version" | "context_unavailable" | "current_user_unavailable" | "missing_data_source_binding" | "data_source_unavailable" | "missing_property_binding" | "invalid_property_binding" | "not_in_iframe" | "init_timeout" | "unknown_error" | (string & {}) export type CustomBlockInitErrorInfo = CustomBlockErrorInfo export const customBlockInitErrorInfoSchema = v.object({ code: customBlockInitErrorCodeSchema, message: v.string(), isRetryable: v.boolean(), }) export class CustomBlockInitError extends Error implements CustomBlockErrorInfo { constructor(error: CustomBlockInitErrorInfo) { super(error.message) this.name = "CustomBlockInitError" this.code = error.code this.isRetryable = error.isRetryable } code: CustomBlockInitErrorCode isRetryable: boolean } /** * Initialization message sent by the host to the sandbox exactly once, in response to the * sandbox's `ready` message. After init, live updates flow through narrower messages * (`themeChanged`, `parentChanged`, `pageChanged`, `dataSourcesChanged`). */ export const initMessageSchema = v.variant("status", [ v.object({ type: v.literal("init"), status: v.literal("success"), theme: notionThemeSchema, blockId: notionBlockIdSchema, parent: notionParentSchema, page: customBlockPageSchema, dataSources: v.object({ bindings: notionDataSourceBindingsSchema, }), currentUser: notionUserSchema, }), v.object({ type: v.literal("init"), status: v.literal("error"), error: customBlockInitErrorInfoSchema, }), ]) export type InitMessage = v.InferOutput