@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
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { expectTypeOf, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
CustomAgentArgs,
|
|
5
|
+
CustomAgentPropertyUpdatedTrigger,
|
|
6
|
+
CustomAgentTrigger,
|
|
7
|
+
DatabasePageLayout,
|
|
8
|
+
NotionAsCodePropertyConfig,
|
|
9
|
+
PageArgs,
|
|
10
|
+
PageCoverReference,
|
|
11
|
+
PageLayoutPropertyModule,
|
|
12
|
+
SingleSourceDatabaseArgs,
|
|
13
|
+
} from "./index.js";
|
|
14
|
+
|
|
15
|
+
it("types page and database covers as URL references", () => {
|
|
16
|
+
expectTypeOf<{
|
|
17
|
+
type: "url";
|
|
18
|
+
url: "https://example.com/cover.png";
|
|
19
|
+
position: 0.25;
|
|
20
|
+
}>().toExtend<PageCoverReference>();
|
|
21
|
+
expectTypeOf<{
|
|
22
|
+
type: "external";
|
|
23
|
+
url: "https://example.com/cover.png";
|
|
24
|
+
}>().not.toExtend<PageCoverReference>();
|
|
25
|
+
expectTypeOf<PageArgs["cover"]>().toEqualTypeOf<PageCoverReference | undefined>();
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it("requires configuration for each advanced property kind", () => {
|
|
29
|
+
expectTypeOf<{
|
|
30
|
+
type: "relation";
|
|
31
|
+
resourceId: "project";
|
|
32
|
+
targetDataSourceResourceId: "projects";
|
|
33
|
+
limit: 1;
|
|
34
|
+
}>().toExtend<NotionAsCodePropertyConfig>();
|
|
35
|
+
expectTypeOf<{
|
|
36
|
+
type: "relation";
|
|
37
|
+
resourceId: "project";
|
|
38
|
+
}>().not.toExtend<NotionAsCodePropertyConfig>();
|
|
39
|
+
|
|
40
|
+
expectTypeOf<{
|
|
41
|
+
type: "rollup";
|
|
42
|
+
resourceId: "total";
|
|
43
|
+
relationPropertyResourceId: "project";
|
|
44
|
+
targetPropertyResourceId: "estimate";
|
|
45
|
+
targetPropertyType: "number";
|
|
46
|
+
aggregation: "sum";
|
|
47
|
+
}>().toExtend<NotionAsCodePropertyConfig>();
|
|
48
|
+
expectTypeOf<{
|
|
49
|
+
type: "rollup";
|
|
50
|
+
resourceId: "invalid-total";
|
|
51
|
+
relationPropertyResourceId: "project";
|
|
52
|
+
targetPropertyResourceId: "name";
|
|
53
|
+
targetPropertyType: "title";
|
|
54
|
+
aggregation: "sum";
|
|
55
|
+
}>().not.toExtend<NotionAsCodePropertyConfig>();
|
|
56
|
+
|
|
57
|
+
expectTypeOf<{
|
|
58
|
+
type: "verification";
|
|
59
|
+
resourceId: "verification";
|
|
60
|
+
verifierPropertyResourceId: "owner";
|
|
61
|
+
}>().toExtend<NotionAsCodePropertyConfig>();
|
|
62
|
+
expectTypeOf<{
|
|
63
|
+
type: "verification";
|
|
64
|
+
resourceId: "verification";
|
|
65
|
+
}>().not.toExtend<NotionAsCodePropertyConfig>();
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("links page-layout property styles and relation groups to the data source schema", () => {
|
|
69
|
+
type Schema = {
|
|
70
|
+
Name: { type: "title"; resourceId: "name" };
|
|
71
|
+
Estimate: { type: "number"; resourceId: "estimate" };
|
|
72
|
+
Owner: { type: "person"; resourceId: "owner" };
|
|
73
|
+
Project: {
|
|
74
|
+
type: "relation";
|
|
75
|
+
resourceId: "project";
|
|
76
|
+
targetDataSourceResourceId: "projects";
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
expectTypeOf<{
|
|
81
|
+
type: "property";
|
|
82
|
+
property: "estimate";
|
|
83
|
+
style: "large";
|
|
84
|
+
}>().toExtend<PageLayoutPropertyModule<Schema>>();
|
|
85
|
+
expectTypeOf<{
|
|
86
|
+
type: "property";
|
|
87
|
+
property: "estimate";
|
|
88
|
+
style: "landscape";
|
|
89
|
+
}>().not.toExtend<PageLayoutPropertyModule<Schema>>();
|
|
90
|
+
expectTypeOf<{
|
|
91
|
+
type: "property";
|
|
92
|
+
property: "name";
|
|
93
|
+
style: "large";
|
|
94
|
+
}>().not.toExtend<PageLayoutPropertyModule<Schema>>();
|
|
95
|
+
|
|
96
|
+
type ValidLayout = {
|
|
97
|
+
main: [
|
|
98
|
+
{ type: "properties"; properties: [{ property: "name" }] },
|
|
99
|
+
{
|
|
100
|
+
type: "relations";
|
|
101
|
+
relations: [{ property: "project"; display: "pageSection" }];
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
pinnedProperties: ["owner"];
|
|
105
|
+
};
|
|
106
|
+
type InvalidRelationLayout = {
|
|
107
|
+
main: [
|
|
108
|
+
{ type: "properties"; properties: [{ property: "name" }] },
|
|
109
|
+
{
|
|
110
|
+
type: "relations";
|
|
111
|
+
relations: [{ property: "estimate"; display: "pageSection" }];
|
|
112
|
+
},
|
|
113
|
+
];
|
|
114
|
+
};
|
|
115
|
+
expectTypeOf<ValidLayout>().toExtend<DatabasePageLayout<Schema>>();
|
|
116
|
+
expectTypeOf<InvalidRelationLayout>().not.toExtend<DatabasePageLayout<Schema>>();
|
|
117
|
+
|
|
118
|
+
expectTypeOf<{
|
|
119
|
+
dataSourceResourceId: "tasks";
|
|
120
|
+
name: "Tasks";
|
|
121
|
+
schema: Schema;
|
|
122
|
+
pageLayout: ValidLayout;
|
|
123
|
+
}>().toExtend<SingleSourceDatabaseArgs<Schema>>();
|
|
124
|
+
expectTypeOf<{
|
|
125
|
+
dataSourceResourceId: "tasks";
|
|
126
|
+
name: "Tasks";
|
|
127
|
+
schema: Schema;
|
|
128
|
+
pageLayout: InvalidRelationLayout;
|
|
129
|
+
}>().not.toExtend<SingleSourceDatabaseArgs<Schema>>();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("requires a meaningful custom agent trigger configuration", () => {
|
|
133
|
+
expectTypeOf<{
|
|
134
|
+
type: "recurrence";
|
|
135
|
+
resourceId: "weekday-trigger";
|
|
136
|
+
frequency: "week";
|
|
137
|
+
interval: 1;
|
|
138
|
+
start: "2026-09-21T09:00:00";
|
|
139
|
+
timeZone: "America/Los_Angeles";
|
|
140
|
+
weekdays: { MO: true; FR: true };
|
|
141
|
+
}>().toExtend<CustomAgentTrigger>();
|
|
142
|
+
expectTypeOf<{
|
|
143
|
+
type: "recurrence";
|
|
144
|
+
resourceId: "empty-weekdays";
|
|
145
|
+
frequency: "week";
|
|
146
|
+
interval: 1;
|
|
147
|
+
start: "2026-09-21T09:00:00";
|
|
148
|
+
timeZone: "America/Los_Angeles";
|
|
149
|
+
weekdays: {};
|
|
150
|
+
}>().not.toExtend<CustomAgentTrigger>();
|
|
151
|
+
|
|
152
|
+
expectTypeOf<{
|
|
153
|
+
type: "property_updated";
|
|
154
|
+
resourceId: "content-trigger";
|
|
155
|
+
dataSourceResourceId: "tasks";
|
|
156
|
+
triggerWhenPageContentEdited: true;
|
|
157
|
+
}>().toExtend<CustomAgentPropertyUpdatedTrigger>();
|
|
158
|
+
expectTypeOf<{
|
|
159
|
+
type: "property_updated";
|
|
160
|
+
resourceId: "empty-trigger";
|
|
161
|
+
dataSourceResourceId: "tasks";
|
|
162
|
+
}>().not.toExtend<CustomAgentPropertyUpdatedTrigger>();
|
|
163
|
+
|
|
164
|
+
expectTypeOf<CustomAgentArgs["triggers"]>().toEqualTypeOf<
|
|
165
|
+
readonly CustomAgentTrigger[] | undefined
|
|
166
|
+
>();
|
|
167
|
+
});
|
|
@@ -4,6 +4,30 @@ import { notion, type PageArgs, type PropertyValue } from "./index.js";
|
|
|
4
4
|
import { finishMetadataRecording, startMetadataRecording } from "./recorder.js";
|
|
5
5
|
|
|
6
6
|
describe("Notion-as-Code page declarations", () => {
|
|
7
|
+
it("records typed URL covers", () => {
|
|
8
|
+
const recorder = startMetadataRecording();
|
|
9
|
+
|
|
10
|
+
notion.page({
|
|
11
|
+
resourceId: "url-cover-page",
|
|
12
|
+
cover: {
|
|
13
|
+
type: "url",
|
|
14
|
+
url: "https://example.com/cover.png",
|
|
15
|
+
position: 0.25,
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
expect(finishMetadataRecording(recorder).intents).toEqual([
|
|
20
|
+
expect.objectContaining({
|
|
21
|
+
resourceId: "url-cover-page",
|
|
22
|
+
cover: {
|
|
23
|
+
type: "url",
|
|
24
|
+
url: "https://example.com/cover.png",
|
|
25
|
+
position: 0.25,
|
|
26
|
+
},
|
|
27
|
+
}),
|
|
28
|
+
]);
|
|
29
|
+
});
|
|
30
|
+
|
|
7
31
|
it("records a regular page title separately from Markdown content", () => {
|
|
8
32
|
const properties = {
|
|
9
33
|
title: notion.text("Workflow guide"),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
APPS_WORKSPACE_RESOURCE_ID,
|
|
3
3
|
type PageIntent,
|
|
4
|
+
type PageCoverReference,
|
|
4
5
|
type Parent,
|
|
5
6
|
type ResourceId,
|
|
6
7
|
} from "./intents.js";
|
|
@@ -56,8 +57,7 @@ export type PageArgs = {
|
|
|
56
57
|
resourceId: ResourceId;
|
|
57
58
|
/** Omit to create a private top-level page in the Apps workspace. */
|
|
58
59
|
parent?: Parent;
|
|
59
|
-
|
|
60
|
-
cover?: unknown;
|
|
60
|
+
cover?: PageCoverReference;
|
|
61
61
|
/**
|
|
62
62
|
* Page properties, including the page title.
|
|
63
63
|
*
|