@notionhq/apps 0.0.20 → 0.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,105 @@ import type { CustomAgentIntent, NotionAsCodeIcon, ResourceId } from "./intents.
2
2
  import { recordIntent } from "./recorder.js";
3
3
  import { assertUserResourceId } from "./resource.js";
4
4
 
5
+ type RecurrenceWeekday = "MO" | "TU" | "WE" | "TH" | "FR" | "SA" | "SU";
6
+
7
+ /** A nonempty selection of weekdays for a weekly recurrence. */
8
+ export type RecurrenceWeekdays = {
9
+ [Day in RecurrenceWeekday]?: true;
10
+ } & {
11
+ [Day in RecurrenceWeekday]: Required<Pick<Record<RecurrenceWeekday, true>, Day>>;
12
+ }[RecurrenceWeekday];
13
+
14
+ export type MonthlyWeekdayOccurrence = "1st" | "2nd" | "3rd" | "4th" | "last";
15
+
16
+ export type MonthlyRecurrenceRestriction =
17
+ | { type: "day_of_month"; day: number }
18
+ | {
19
+ type: "weekday_of_month";
20
+ weekday: RecurrenceWeekday;
21
+ occurrence: MonthlyWeekdayOccurrence;
22
+ };
23
+
24
+ export type RecurrenceScheduleEnd =
25
+ | { type: "date"; endsAt: string }
26
+ | { type: "occurrences"; count: number };
27
+
28
+ type RecurrenceScheduleBase = {
29
+ interval: number;
30
+ start: string;
31
+ timeZone: string;
32
+ end?: RecurrenceScheduleEnd;
33
+ };
34
+
35
+ export type HourlyRecurrenceSchedule = RecurrenceScheduleBase & {
36
+ frequency: "hour";
37
+ };
38
+
39
+ export type DailyRecurrenceSchedule = RecurrenceScheduleBase & {
40
+ frequency: "day";
41
+ };
42
+
43
+ export type WeeklyRecurrenceSchedule = RecurrenceScheduleBase & {
44
+ frequency: "week";
45
+ weekdays: RecurrenceWeekdays;
46
+ };
47
+
48
+ export type MonthlyRecurrenceSchedule = RecurrenceScheduleBase & {
49
+ frequency: "month";
50
+ monthlyRestriction: MonthlyRecurrenceRestriction;
51
+ };
52
+
53
+ export type YearlyRecurrenceSchedule = RecurrenceScheduleBase & {
54
+ frequency: "year";
55
+ };
56
+
57
+ export type CustomAgentRecurrenceSchedule = (
58
+ | HourlyRecurrenceSchedule
59
+ | DailyRecurrenceSchedule
60
+ | WeeklyRecurrenceSchedule
61
+ | MonthlyRecurrenceSchedule
62
+ | YearlyRecurrenceSchedule
63
+ ) & {
64
+ type: "recurrence";
65
+ };
66
+
67
+ export type CustomAgentTriggerBase = {
68
+ resourceId: ResourceId;
69
+ enabled?: boolean;
70
+ };
71
+
72
+ export type CustomAgentRecurrenceTrigger = CustomAgentTriggerBase & CustomAgentRecurrenceSchedule;
73
+
74
+ export type PropertyTriggerCondition = {
75
+ type: "property_edited";
76
+ };
77
+
78
+ export type CustomAgentPageAddedTrigger = CustomAgentTriggerBase & {
79
+ type: "page_added";
80
+ dataSourceResourceId: ResourceId;
81
+ };
82
+
83
+ type PropertyUpdatedTriggerTarget =
84
+ | {
85
+ propertyConditions: Readonly<Record<ResourceId, PropertyTriggerCondition>>;
86
+ triggerWhenPageContentEdited?: boolean;
87
+ }
88
+ | {
89
+ propertyConditions?: never;
90
+ triggerWhenPageContentEdited: true;
91
+ };
92
+
93
+ export type CustomAgentPropertyUpdatedTrigger = CustomAgentTriggerBase &
94
+ PropertyUpdatedTriggerTarget & {
95
+ type: "property_updated";
96
+ dataSourceResourceId: ResourceId;
97
+ };
98
+
99
+ export type CustomAgentTrigger =
100
+ | CustomAgentRecurrenceTrigger
101
+ | CustomAgentPageAddedTrigger
102
+ | CustomAgentPropertyUpdatedTrigger;
103
+
5
104
  export type CustomAgentArgs = {
6
105
  resourceId: ResourceId;
7
106
  name: string;
@@ -9,8 +108,7 @@ export type CustomAgentArgs = {
9
108
  instructions?: string;
10
109
  model?: "ambrosia-tart-high" | "opal-quince-medium" | "almond-croissant-low";
11
110
  sharedResources?: readonly ResourceId[];
12
- // TODO: Port custom agent trigger types.
13
- triggers?: readonly unknown[];
111
+ triggers?: readonly CustomAgentTrigger[];
14
112
  };
15
113
 
16
114
  export type CustomAgentHandle = {
@@ -24,6 +122,17 @@ export function customAgent(args: CustomAgentArgs): CustomAgentHandle {
24
122
  for (const resourceId of args.sharedResources ?? []) {
25
123
  assertUserResourceId(resourceId);
26
124
  }
125
+ for (const trigger of args.triggers ?? []) {
126
+ assertUserResourceId(trigger.resourceId);
127
+ if (trigger.type === "page_added" || trigger.type === "property_updated") {
128
+ assertUserResourceId(trigger.dataSourceResourceId);
129
+ }
130
+ if (trigger.type === "property_updated") {
131
+ for (const propertyResourceId of Object.keys(trigger.propertyConditions ?? {})) {
132
+ assertUserResourceId(propertyResourceId);
133
+ }
134
+ }
135
+ }
27
136
  recordIntent({ type: "custom_agent", ...args } satisfies {
28
137
  type: "custom_agent";
29
138
  } & CustomAgentIntent);
@@ -8,6 +8,44 @@ import { APPS_WORKSPACE_RESOURCE_ID } from "./intents.js";
8
8
  import { finishMetadataRecording, startMetadataRecording } from "./recorder.js";
9
9
 
10
10
  describe("Notion-as-Code database declarations", () => {
11
+ it("records a single-source page layout on the data source", () => {
12
+ const recorder = startMetadataRecording();
13
+
14
+ notion.database("layout-database", {
15
+ dataSourceResourceId: "layout-source",
16
+ name: "Tasks",
17
+ schema: {
18
+ Name: { type: "title", resourceId: "name" },
19
+ Estimate: { type: "number", resourceId: "estimate" },
20
+ },
21
+ pageLayout: {
22
+ main: [
23
+ { type: "properties", properties: [{ property: "name" }] },
24
+ { type: "property", property: "estimate", style: "large" },
25
+ ],
26
+ pinnedProperties: ["estimate"],
27
+ },
28
+ });
29
+
30
+ expect(finishMetadataRecording(recorder).intents).toEqual([
31
+ expect.objectContaining({
32
+ resourceId: "layout-database",
33
+ dataSources: [
34
+ expect.objectContaining({
35
+ resourceId: "layout-source",
36
+ pageLayout: {
37
+ main: [
38
+ { type: "properties", properties: [{ property: "name" }] },
39
+ { type: "property", property: "estimate", style: "large" },
40
+ ],
41
+ pinnedProperties: ["estimate"],
42
+ },
43
+ }),
44
+ ],
45
+ }),
46
+ ]);
47
+ });
48
+
11
49
  it("converts the single-source form with keyed schemas and resolved property names", () => {
12
50
  const recorder = startMetadataRecording();
13
51
  const schema = {
@@ -2,6 +2,7 @@ import type { Database } from "../database.js";
2
2
  import {
3
3
  APPS_WORKSPACE_RESOURCE_ID,
4
4
  type DatabaseIntent,
5
+ type DatabasePageLayout,
5
6
  type DataSourceDefinition,
6
7
  type NotionAsCodeIcon,
7
8
  type NotionAsCodeProperty,
@@ -26,6 +27,7 @@ export type DataSourceArgs<Schema extends NotionAsCodeSchema = NotionAsCodeSchem
26
27
  name?: never;
27
28
  schema: Schema;
28
29
  icon?: NotionAsCodeIcon;
30
+ pageLayout?: DatabasePageLayout<Schema>;
29
31
  };
30
32
 
31
33
  /** Data sources keyed by the names used to access their handles. */
@@ -42,6 +44,7 @@ type SingleSourceDatabaseOptions<Schema extends NotionAsCodeSchema = NotionAsCod
42
44
  dataSourceResourceId: ResourceId;
43
45
  name: string;
44
46
  schema: Schema;
47
+ pageLayout?: DatabasePageLayout<Schema>;
45
48
  datasources?: never;
46
49
  };
47
50
 
@@ -61,6 +64,7 @@ type MultiSourceDatabaseOptions<DataSources extends DataSourceMap = DataSourceMa
61
64
  datasources: DataSources;
62
65
  dataSourceResourceId?: never;
63
66
  schema?: never;
67
+ pageLayout?: never;
64
68
  } & (keyof NoInfer<DataSources> extends never
65
69
  ? { views: NonEmptyViewSchemas }
66
70
  : { views?: readonly ViewSchema[] });
@@ -76,6 +80,7 @@ type ViewOnlyDatabaseOptions = DatabaseMetadata & {
76
80
  datasources?: never;
77
81
  dataSourceResourceId?: never;
78
82
  schema?: never;
83
+ pageLayout?: never;
79
84
  views: NonEmptyViewSchemas;
80
85
  };
81
86
 
@@ -255,6 +260,7 @@ function buildDatabaseHandle(
255
260
  resourceId: args.dataSourceResourceId,
256
261
  name: args.name,
257
262
  properties: normalizeProperties(args.schema),
263
+ ...(args.pageLayout === undefined ? {} : { pageLayout: args.pageLayout }),
258
264
  };
259
265
  const handle = recordDatabase(databaseResourceId, args, parent, [
260
266
  { key: "dataSource", schema: args.schema, definition: source },
@@ -295,6 +301,7 @@ function normalizeDatabaseMetadata(args: DatabaseArgs): DatabaseMetadata {
295
301
  schema: _schema,
296
302
  datasources: _datasources,
297
303
  dataSourceResourceId: _dataSourceResourceId,
304
+ pageLayout: _pageLayout,
298
305
  ...metadata
299
306
  } = args;
300
307
  return metadata;
@@ -2,6 +2,9 @@ import { createNotion } from "./handles.js";
2
2
 
3
3
  export { APPS_RESERVED_RESOURCE_ID_PREFIX, APPS_WORKSPACE_RESOURCE_ID } from "./intents.js";
4
4
  export type {
5
+ ContentPageLayoutTab,
6
+ DatabasePageLayout,
7
+ DatabasePageLayoutTab,
5
8
  DatabaseIntent,
6
9
  DataSourceDefinition,
7
10
  NotionAsCodeIcon,
@@ -10,10 +13,45 @@ export type {
10
13
  NotionAsCodeSchema,
11
14
  NotionAsCodeSelectOption,
12
15
  NotionAsCodeStatusOption,
16
+ PageCoverReference,
17
+ PageLayoutMainModule,
18
+ PageLayoutNumberAndFormulaStyle,
19
+ PageLayoutPersonStyle,
20
+ PageLayoutPropertiesModule,
21
+ PageLayoutPropertyConfig,
22
+ PageLayoutPropertyModule,
23
+ PageLayoutPropertySection,
24
+ PageLayoutRelationConfig,
25
+ PageLayoutRelationsGroupModule,
26
+ PageLayoutSidebarModule,
13
27
  Parent,
14
28
  ResourceId,
29
+ RollupBaseAggregationType,
30
+ RollupDateAggregationType,
31
+ RollupNumberAggregationType,
32
+ RollupTargetPropertyType,
33
+ ViewPageLayoutTab,
15
34
  } from "./intents.js";
16
- export type { CustomAgentArgs, CustomAgentHandle } from "./custom-agent.js";
35
+ export type {
36
+ CustomAgentArgs,
37
+ CustomAgentHandle,
38
+ CustomAgentPageAddedTrigger,
39
+ CustomAgentPropertyUpdatedTrigger,
40
+ CustomAgentRecurrenceSchedule,
41
+ CustomAgentRecurrenceTrigger,
42
+ CustomAgentTrigger,
43
+ CustomAgentTriggerBase,
44
+ DailyRecurrenceSchedule,
45
+ HourlyRecurrenceSchedule,
46
+ MonthlyRecurrenceRestriction,
47
+ MonthlyRecurrenceSchedule,
48
+ MonthlyWeekdayOccurrence,
49
+ PropertyTriggerCondition,
50
+ RecurrenceScheduleEnd,
51
+ RecurrenceWeekdays,
52
+ WeeklyRecurrenceSchedule,
53
+ YearlyRecurrenceSchedule,
54
+ } from "./custom-agent.js";
17
55
  export type {
18
56
  ChildDatabaseArgs,
19
57
  ChildDatabaseFactory,
@@ -21,6 +21,14 @@ export type NotionAsCodeIcon =
21
21
  | { type: "notion_icon"; description: string; color?: string }
22
22
  | { type: "file"; resourceId: ResourceId };
23
23
 
24
+ /** A URL reference used as a page or database cover. */
25
+ export type PageCoverReference = {
26
+ type: "url";
27
+ url: string;
28
+ /** Vertical position from the top, where 0 is the top and 1 is the bottom. */
29
+ position?: number;
30
+ };
31
+
24
32
  export type NotionAsCodeSelectColor =
25
33
  | "default"
26
34
  | "gray"
@@ -49,20 +57,102 @@ type PropertyBase = {
49
57
  description?: string;
50
58
  };
51
59
 
52
- type UnsupportedProperty = PropertyBase & {
53
- type:
54
- | "relation"
55
- | "formula"
56
- | "rollup"
57
- | "created_time"
58
- | "last_edited_time"
59
- | "created_by"
60
- | "last_edited_by"
61
- | "auto_increment_id"
62
- | "person"
63
- | "verification";
64
- // TODO: Port configuration types for unsupported property kinds.
65
- [key: string]: unknown;
60
+ /** Rollup aggregations supported for every target property type. */
61
+ export type RollupBaseAggregationType =
62
+ | "count"
63
+ | "count_values"
64
+ | "unique"
65
+ | "empty"
66
+ | "not_empty"
67
+ | "percent_empty"
68
+ | "percent_not_empty"
69
+ | "show_unique";
70
+
71
+ /** Numeric-only rollup aggregations. */
72
+ export type RollupNumberAggregationType =
73
+ | RollupBaseAggregationType
74
+ | "sum"
75
+ | "average"
76
+ | "median"
77
+ | "min"
78
+ | "max"
79
+ | "range";
80
+
81
+ /** Date-only rollup aggregations. */
82
+ export type RollupDateAggregationType =
83
+ | RollupBaseAggregationType
84
+ | "earliest_date"
85
+ | "latest_date"
86
+ | "date_range";
87
+
88
+ export type RollupTargetPropertyType =
89
+ | "title"
90
+ | "text"
91
+ | "number"
92
+ | "select"
93
+ | "multi_select"
94
+ | "status"
95
+ | "date"
96
+ | "checkbox"
97
+ | "url"
98
+ | "email"
99
+ | "phone_number"
100
+ | "relation"
101
+ | "person"
102
+ | "created_time"
103
+ | "last_edited_time"
104
+ | "created_by"
105
+ | "last_edited_by";
106
+
107
+ type RollupTarget =
108
+ | {
109
+ targetPropertyType: "number";
110
+ aggregation?: RollupNumberAggregationType;
111
+ }
112
+ | {
113
+ targetPropertyType: "date" | "created_time" | "last_edited_time";
114
+ aggregation?: RollupDateAggregationType;
115
+ }
116
+ | {
117
+ targetPropertyType: Exclude<
118
+ RollupTargetPropertyType,
119
+ "number" | "date" | "created_time" | "last_edited_time"
120
+ >;
121
+ aggregation?: RollupBaseAggregationType;
122
+ };
123
+
124
+ type RelationProperty = PropertyBase & {
125
+ type: "relation";
126
+ targetDataSourceResourceId: ResourceId;
127
+ targetDataSourcePropertyResourceId?: ResourceId;
128
+ limit?: 1;
129
+ };
130
+
131
+ type FormulaProperty = PropertyBase & {
132
+ type: "formula";
133
+ expression?: string;
134
+ };
135
+
136
+ type RollupProperty = PropertyBase &
137
+ RollupTarget & {
138
+ type: "rollup";
139
+ relationPropertyResourceId: ResourceId;
140
+ targetPropertyResourceId: ResourceId;
141
+ };
142
+
143
+ type AutoIncrementIdProperty = PropertyBase & {
144
+ type: "auto_increment_id";
145
+ prefix?: string;
146
+ };
147
+
148
+ type PersonProperty = PropertyBase & {
149
+ type: "person";
150
+ limit?: 1;
151
+ };
152
+
153
+ type VerificationProperty = PropertyBase & {
154
+ type: "verification";
155
+ verifierPropertyResourceId: ResourceId;
66
156
  };
67
157
 
68
158
  /** A normalized Notion-as-Code property with its resolved display name. */
@@ -90,22 +180,29 @@ export type NotionAsCodeProperty =
90
180
  | (PropertyBase & { type: "email" })
91
181
  | (PropertyBase & { type: "phone_number" })
92
182
  | (PropertyBase & { type: "file" })
93
- | UnsupportedProperty;
183
+ | RelationProperty
184
+ | FormulaProperty
185
+ | RollupProperty
186
+ | (PropertyBase & { type: "created_time" })
187
+ | (PropertyBase & { type: "last_edited_time" })
188
+ | (PropertyBase & { type: "created_by" })
189
+ | (PropertyBase & { type: "last_edited_by" })
190
+ | AutoIncrementIdProperty
191
+ | PersonProperty
192
+ | VerificationProperty;
94
193
 
95
194
  /**
96
195
  * `T extends unknown` applies Omit to each property variant separately, preserving
97
196
  * variant-specific fields such as required status options. Plain Omit on the union
98
- * would retain only shared keys. Pick also restores type/resourceId on the
99
- * unsupported variant, whose string index signature would otherwise erase them.
197
+ * would retain only shared keys.
100
198
  */
101
199
  type DistributivePropertyConfig<T extends NotionAsCodeProperty> = T extends unknown
102
- ? Omit<T, "name"> & Pick<T, "type" | "resourceId">
200
+ ? Omit<T, "name">
103
201
  : never;
104
202
 
105
203
  /**
106
204
  * Authoring properties are keyed by their schema object name. A property-level
107
- * `name` override would make the key and serialized property diverge, so it is
108
- * explicitly rejected even for the string-indexed unsupported-property variant.
205
+ * `name` override would make the key and serialized property diverge.
109
206
  */
110
207
  export type NotionAsCodePropertyConfig = DistributivePropertyConfig<NotionAsCodeProperty> & {
111
208
  name?: never;
@@ -113,6 +210,106 @@ export type NotionAsCodePropertyConfig = DistributivePropertyConfig<NotionAsCode
113
210
  /** A keyed property schema, with object keys supplying serialized property names. */
114
211
  export type NotionAsCodeSchema = Record<string, NotionAsCodePropertyConfig>;
115
212
 
213
+ type SchemaProperty<Schema extends NotionAsCodeSchema> = Schema[keyof Schema & string];
214
+ type PropertyType = NotionAsCodePropertyConfig["type"];
215
+ type PropertyResourceIdFor<
216
+ Schema extends NotionAsCodeSchema,
217
+ Types extends PropertyType = PropertyType,
218
+ > = Extract<SchemaProperty<Schema>, { type: Types }>["resourceId"];
219
+
220
+ export type PageLayoutPropertyConfig<Schema extends NotionAsCodeSchema = NotionAsCodeSchema> = {
221
+ property: PropertyResourceIdFor<Schema>;
222
+ visibility?: "show" | "hide_if_empty" | "hide";
223
+ };
224
+
225
+ export type PageLayoutPropertySection<Schema extends NotionAsCodeSchema = NotionAsCodeSchema> = {
226
+ name: string;
227
+ properties: readonly PageLayoutPropertyConfig<Schema>[];
228
+ };
229
+
230
+ export type PageLayoutPropertiesModule<Schema extends NotionAsCodeSchema = NotionAsCodeSchema> = {
231
+ type: "properties";
232
+ } & (
233
+ | {
234
+ properties?: readonly PageLayoutPropertyConfig<Schema>[];
235
+ sections?: never;
236
+ }
237
+ | {
238
+ sections: readonly PageLayoutPropertySection<Schema>[];
239
+ properties?: never;
240
+ }
241
+ );
242
+
243
+ export type PageLayoutPersonStyle = "compact" | "large";
244
+ export type PageLayoutNumberAndFormulaStyle = "large" | "small";
245
+
246
+ type PageLayoutStyleFor<Property extends NotionAsCodePropertyConfig> = Property["type"] extends
247
+ | "person"
248
+ | "created_by"
249
+ | "last_edited_by"
250
+ ? { style?: PageLayoutPersonStyle }
251
+ : Property["type"] extends "number" | "formula"
252
+ ? { style?: PageLayoutNumberAndFormulaStyle }
253
+ : { style?: never };
254
+
255
+ type PageLayoutPropertyModuleFor<Property extends NotionAsCodePropertyConfig> =
256
+ Property extends unknown
257
+ ? {
258
+ type: "property";
259
+ property: Property["resourceId"];
260
+ } & PageLayoutStyleFor<Property>
261
+ : never;
262
+
263
+ /**
264
+ * A standalone property module. Its available style is inferred from the
265
+ * referenced property's type when the layout is declared with a literal schema.
266
+ */
267
+ export type PageLayoutPropertyModule<Schema extends NotionAsCodeSchema = NotionAsCodeSchema> =
268
+ PageLayoutPropertyModuleFor<SchemaProperty<Schema>>;
269
+
270
+ export type PageLayoutRelationConfig<Schema extends NotionAsCodeSchema = NotionAsCodeSchema> = {
271
+ property: PropertyResourceIdFor<Schema, "relation">;
272
+ display: "pageSection" | "minimal";
273
+ };
274
+
275
+ export type PageLayoutRelationsGroupModule<Schema extends NotionAsCodeSchema = NotionAsCodeSchema> =
276
+ {
277
+ type: "relations";
278
+ relations: readonly PageLayoutRelationConfig<Schema>[];
279
+ };
280
+
281
+ export type PageLayoutMainModule<Schema extends NotionAsCodeSchema = NotionAsCodeSchema> =
282
+ | PageLayoutPropertiesModule<Schema>
283
+ | PageLayoutPropertyModule<Schema>
284
+ | PageLayoutRelationsGroupModule<Schema>;
285
+
286
+ export type PageLayoutSidebarModule<Schema extends NotionAsCodeSchema = NotionAsCodeSchema> =
287
+ | PageLayoutPropertiesModule<Schema>
288
+ | PageLayoutPropertyModule<Schema>;
289
+
290
+ export type ContentPageLayoutTab = {
291
+ type: "content";
292
+ name?: string;
293
+ };
294
+
295
+ export type ViewPageLayoutTab = {
296
+ type: "view";
297
+ resourceId: ResourceId;
298
+ };
299
+
300
+ export type DatabasePageLayoutTab = ContentPageLayoutTab | ViewPageLayoutTab;
301
+
302
+ export type DatabasePageLayout<Schema extends NotionAsCodeSchema = NotionAsCodeSchema> = {
303
+ main: readonly PageLayoutMainModule<Schema>[];
304
+ sidebar?: readonly PageLayoutSidebarModule<Schema>[];
305
+ pinnedProperties?: readonly PropertyResourceIdFor<Schema>[];
306
+ discussions?: "top" | "bottom" | "hidden";
307
+ tabs?: readonly DatabasePageLayoutTab[];
308
+ fullWidth?: boolean;
309
+ showPropertyIcons?: boolean;
310
+ showTemplates?: boolean;
311
+ };
312
+
116
313
  /** The normalized data-source shape emitted in provisioning artifacts. */
117
314
  export type DataSourceDefinition<
118
315
  Properties extends readonly NotionAsCodeProperty[] = readonly NotionAsCodeProperty[],
@@ -121,8 +318,7 @@ export type DataSourceDefinition<
121
318
  name: string;
122
319
  properties: Properties;
123
320
  icon?: NotionAsCodeIcon;
124
- // TODO: Port page layout types.
125
- pageLayout?: unknown;
321
+ pageLayout?: DatabasePageLayout;
126
322
  };
127
323
 
128
324
  export type TeamspaceIntent = TeamspaceArgs & {
@@ -141,8 +337,7 @@ export type DatabaseIntent = {
141
337
  dataSources: readonly DataSourceDefinition[];
142
338
  views?: readonly ViewSchema[];
143
339
  icon?: NotionAsCodeIcon;
144
- // TODO: Port cover types.
145
- cover?: unknown;
340
+ cover?: PageCoverReference;
146
341
  hideDataSourceTitle?: boolean;
147
342
  hideDatabaseTitleIfEmpty?: boolean;
148
343
  name?: string;