import * as v from "valibot" /** * Hex-token identifiers for Notion's named colors. Mirrors the public API's * `select.options[].color` enum * (https://developers.notion.com/reference/property-object#select). */ export const notionPropertyColorSchema = v.picklist([ "default", "gray", "brown", "orange", "yellow", "green", "blue", "purple", "pink", "red", "gray_background", "brown_background", "orange_background", "yellow_background", "green_background", "blue_background", "purple_background", "pink_background", "red_background", "default_background", ]) export type NotionPropertyColor = v.InferOutput< typeof notionPropertyColorSchema > export const notionPropertyOptionSchema = v.object({ id: v.string(), name: v.string(), color: v.optional(notionPropertyColorSchema), description: v.optional(v.string()), }) export type NotionPropertyOption = v.InferOutput< typeof notionPropertyOptionSchema > export const notionStatusGroupSchema = v.object({ id: v.string(), name: v.string(), color: v.optional(notionPropertyColorSchema), option_ids: v.array(v.string()), }) export type NotionStatusGroup = v.InferOutput export const notionDualPropertySchema = v.object({ synced_property_id: v.string(), synced_property_name: v.string(), }) export type NotionDualProperty = v.InferOutput const baseProp = v.object({ name: v.string(), description: v.optional(v.string()), }) /** * Every Notion property type the bridge speaks, in a single readable list. * Mirrors the Notion public API * [property object](https://developers.notion.com/reference/property-object) * type field. Internal-only types (`button`, `verification`, * `last_visited_time`, `location`) and the four built-ins (`created_time`, * `last_edited_time`, `created_by`, `last_edited_by`) are included under their * bridge-native names. */ export const NOTION_PROPERTY_TYPES = [ "title", "rich_text", "number", "checkbox", "url", "email", "phone_number", "select", "multi_select", "status", "date", "people", "files", "unique_id", "relation", "place", "formula", "rollup", "button", "verification", "last_visited_time", "location", "created_time", "last_edited_time", "created_by", "last_edited_by", ] as const export const notionPropertyTypeSchema = v.picklist(NOTION_PROPERTY_TYPES) /** * String literal union of every supported Notion property type. Same set as * the discriminator in `NotionPropertySchema` — split out so the manifest * can declare expected property types without dragging in the per-type * payload shapes. */ export type NotionPropertyType = v.InferOutput /** * Per-property schema as exposed by the host over the custom-block bridge. * The `type` discriminator must be one of {@link NOTION_PROPERTY_TYPES}. */ export const notionPropertySchemaSchema = v.variant("type", [ v.object({ ...baseProp.entries, type: v.literal("title") }), v.object({ ...baseProp.entries, type: v.literal("rich_text") }), v.object({ ...baseProp.entries, type: v.literal("number") }), v.object({ ...baseProp.entries, type: v.literal("checkbox") }), v.object({ ...baseProp.entries, type: v.literal("url") }), v.object({ ...baseProp.entries, type: v.literal("email") }), v.object({ ...baseProp.entries, type: v.literal("phone_number") }), v.object({ ...baseProp.entries, type: v.literal("select"), options: v.array(notionPropertyOptionSchema), }), v.object({ ...baseProp.entries, type: v.literal("multi_select"), options: v.array(notionPropertyOptionSchema), }), v.object({ ...baseProp.entries, type: v.literal("status"), options: v.array(notionPropertyOptionSchema), groups: v.array(notionStatusGroupSchema), }), v.object({ ...baseProp.entries, type: v.literal("date") }), v.object({ ...baseProp.entries, type: v.literal("people") }), v.object({ ...baseProp.entries, type: v.literal("files") }), v.object({ ...baseProp.entries, type: v.literal("unique_id") }), v.object({ ...baseProp.entries, type: v.literal("relation"), data_source_id: v.optional(v.string()), dual_property: v.optional(notionDualPropertySchema), }), v.object({ ...baseProp.entries, type: v.literal("place") }), v.object({ ...baseProp.entries, type: v.literal("formula") }), v.object({ ...baseProp.entries, type: v.literal("rollup") }), // Internal-only types passed through under their bridge-native names. v.object({ ...baseProp.entries, type: v.literal("button") }), v.object({ ...baseProp.entries, type: v.literal("verification") }), v.object({ ...baseProp.entries, type: v.literal("last_visited_time") }), v.object({ ...baseProp.entries, type: v.literal("location") }), // Synthetic built-ins. The host always emits one of each per data source. v.object({ ...baseProp.entries, type: v.literal("created_time") }), v.object({ ...baseProp.entries, type: v.literal("last_edited_time") }), v.object({ ...baseProp.entries, type: v.literal("created_by") }), v.object({ ...baseProp.entries, type: v.literal("last_edited_by") }), ]) export type NotionPropertySchema = v.InferOutput< typeof notionPropertySchemaSchema > /** * The four synthetic built-in property IDs the host always includes in every * data source's `propertySchemasById` and every row's `propertiesById`. */ export const NOTION_BUILTIN_PROPERTY_IDS = [ "created_time", "last_edited_time", "created_by", "last_edited_by", ] as const export type NotionBuiltinPropertyId = (typeof NOTION_BUILTIN_PROPERTY_IDS)[number]