@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.
- package/dist/notion-as-code/custom-agent.d.ts +75 -1
- package/dist/notion-as-code/custom-agent.d.ts.map +1 -1
- package/dist/notion-as-code/custom-agent.js +11 -0
- package/dist/notion-as-code/custom-agent.test.d.ts +2 -0
- package/dist/notion-as-code/custom-agent.test.d.ts.map +1 -0
- package/dist/notion-as-code/database.d.ts +5 -1
- package/dist/notion-as-code/database.d.ts.map +1 -1
- package/dist/notion-as-code/database.js +3 -1
- package/dist/notion-as-code/index.d.ts +2 -2
- package/dist/notion-as-code/index.d.ts.map +1 -1
- package/dist/notion-as-code/intents.d.ts +133 -11
- package/dist/notion-as-code/intents.d.ts.map +1 -1
- package/dist/notion-as-code/notion-as-code-types.test.d.ts +2 -0
- package/dist/notion-as-code/notion-as-code-types.test.d.ts.map +1 -0
- package/dist/notion-as-code/page.d.ts +2 -2
- package/dist/notion-as-code/page.d.ts.map +1 -1
- package/package.json +1 -1
- package/skills/notion-as-code/SKILL.md +11 -6
- package/src/notion-as-code/custom-agent.test.ts +79 -0
- package/src/notion-as-code/custom-agent.ts +111 -2
- package/src/notion-as-code/database.test.ts +38 -0
- package/src/notion-as-code/database.ts +7 -0
- package/src/notion-as-code/index.ts +39 -1
- package/src/notion-as-code/intents.ts +219 -24
- package/src/notion-as-code/notion-as-code-types.test.ts +167 -0
- package/src/notion-as-code/page.test.ts +24 -0
- package/src/notion-as-code/page.ts +2 -2
|
@@ -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
|
-
|
|
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 {
|
|
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
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
|
-
|
|
|
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.
|
|
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">
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
145
|
-
cover?: unknown;
|
|
340
|
+
cover?: PageCoverReference;
|
|
146
341
|
hideDataSourceTitle?: boolean;
|
|
147
342
|
hideDatabaseTitleIfEmpty?: boolean;
|
|
148
343
|
name?: string;
|