import type { CapabilityContext } from "./context.js"; import type { Database } from "./database.js"; import type { DataSourceHandle } from "./notion-as-code/database.js"; import type { NotionAsCodeSchema } from "./notion-as-code/intents.js"; import type { AppsSchemaForSchema } from "./notion-as-code/schema.js"; import { type PacerEntry } from "./pacer.js"; import type { DatabaseSchema, PropertyConfiguration, TextProperty, TitleProperty } from "./schema.js"; import type { Cover, HandlerOptions, Icon, NormalizedSchedule, PeopleValue, PlaceValue, RelationValue, Schedule, TextValue } from "./types.js"; type KeyProperty = TitleProperty | TextProperty; /** Names of title or rich-text properties in a database schema. */ export type KeyPropertyName = Extract<{ [P in keyof S]: S[P] extends KeyProperty ? P : never; }[keyof S], string>; type PropertyValue = T extends { type: "people"; } ? PeopleValue : T extends { type: "place"; } ? PlaceValue : T extends { type: "relation"; } ? RelationValue : TextValue; type SyncPropertyName = Extract; /** * Collect unknown property names across the whole inferred change union before checking it. * Otherwise a valid subset properties object could structurally hide an invalid sibling row. */ type SyncUnknownPropertyNames = Change extends { type: "upsert"; properties: infer Properties extends object; } ? Exclude : never; /** Require at least one key while keeping all other keys optional. */ type AtLeastOne = Partial & { [RequiredKey in keyof T]-?: Required>; }[keyof T]; type SyncUpsertProperties> = AtLeastOne<{ [P in Exclude, PrimaryKey>]: PropertyValue; }>; type ExactSyncHandlerResult = Result & { changes: [SyncUnknownPropertyNames] extends [ never ] ? Result["changes"] : never; }; export type SyncMode = "replace" | "incremental"; /** Upsert one or more known non-primary-key properties; the key is supplied separately. */ export type SyncChangeUpsert> = { type: "upsert"; key: string; properties: SyncUpsertProperties; upstreamUpdatedAt?: string; icon?: Icon; cover?: Cover; pageContentMarkdown?: string; }; export type SyncChangeDelete = { type: "delete"; key: string; }; export type SyncChange> = SyncChangeUpsert | SyncChangeDelete; export type SyncHandlerResult, State> = { changes: SyncChange[]; hasMore?: boolean; nextState?: State; }; export type SyncConfiguration, State, Result extends SyncHandlerResult = SyncHandlerResult> = { database: Database; primaryKey: PrimaryKey; mode?: SyncMode; schedule?: Schedule; handler: (state: State | undefined, context: CapabilityContext) => Promise, NoInfer, State> & ExactSyncHandlerResult>, NoInfer>, Result>>; }; /** Configuration for a sync backed by a Notion-as-Code data source. */ export type DataSourceSyncConfiguration>, State, Result extends SyncHandlerResult, PrimaryKey, State> = SyncHandlerResult, PrimaryKey, State>> = Omit, PrimaryKey, State, Result>, "database"> & { dataSource: DataSourceHandle; }; export type SyncRuntimeContext = { state?: unknown; userContext?: unknown; pacers?: Record; }; type SyncDefinitionConfig = { database: Database; primaryKeyProperty: string; mode?: SyncMode; schedule?: NormalizedSchedule; }; export type SyncRunResult = { changes: unknown[]; hasMore: boolean; nextUserContext?: unknown; nextPacerStates: Record; }; export type Sync = KeyPropertyName, State = unknown> = { _tag: "sync"; config: SyncDefinitionConfig; handler: (context?: SyncRuntimeContext, options?: HandlerOptions) => Promise; }; export type SyncChangeFor = Definition extends Sync ? SyncChange : never; export type SyncStateFor = Definition extends Sync ? State : never; /** Create a database sync. Default-export it from a sync file. */ export declare function createSync, State = unknown, const Result extends SyncHandlerResult = SyncHandlerResult>(configuration: SyncConfiguration): Sync; /** Create a sync backed by a Notion-as-Code data source. */ export declare function sync>, State = unknown, const Result extends SyncHandlerResult, PrimaryKey, State> = SyncHandlerResult, PrimaryKey, State>>(configuration: DataSourceSyncConfiguration): Sync, PrimaryKey, State>; export {}; //# sourceMappingURL=sync.d.ts.map