import type { ManifestDataSource, ManifestProperty, NotionPropertyType, } from "@notionhq/custom-blocks"; import type { CustomBlockDefaultBinding } from "./custom-block.js"; import type { DataSourceHandle } from "./notion-as-code/database.js"; import type { NotionAsCodeProperty } from "./notion-as-code/intents.js"; /** Lower a Notion-as-Code handle into the declaration consumed by custom block hosts. */ export function toCustomBlockDataSource(handle: DataSourceHandle): ManifestDataSource { return { name: handle.name, ...(handle.description === undefined ? {} : { description: handle.description }), properties: Object.fromEntries( Object.entries(handle.schema).map(([key, property]) => [ key, { name: key, ...(typeof property.description !== "string" ? {} : { description: property.description }), type: toCustomBlockPropertyType(property.type), } satisfies ManifestProperty, ]), ), }; } /** Keep resource IDs in the build artifact so deploy can resolve workspace-local IDs later. */ export function toCustomBlockDefaultBinding(handle: DataSourceHandle): CustomBlockDefaultBinding { return { dataSourceResourceId: handle.resourceId, propertyResourceIdsByKey: Object.fromEntries( Object.entries(handle.schema).map(([key, property]) => [key, property.resourceId]), ), }; } export function toCustomBlockPropertyType(type: NotionAsCodeProperty["type"]): NotionPropertyType { switch (type) { case "text": return "rich_text"; case "file": return "files"; case "person": return "people"; case "auto_increment_id": return "unique_id"; case "title": case "number": case "select": case "multi_select": case "status": case "date": case "checkbox": case "url": case "email": case "phone_number": case "relation": case "formula": case "rollup": case "created_time": case "last_edited_time": case "created_by": case "last_edited_by": case "verification": return type; default: return assertNever(type); } } function assertNever(value: never): never { throw new Error(`Unsupported Notion-as-Code property type: ${String(value)}`); }