@notionhq/apps 0.0.31 → 0.0.33
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/cli/codegen.d.ts.map +1 -1
- package/dist/cli/codegen.js +6 -1
- package/dist/custom-block.d.ts +9 -2
- package/dist/custom-block.d.ts.map +1 -1
- package/dist/custom-block.js +3 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/notion-as-code/database.d.ts +11 -0
- package/dist/notion-as-code/database.d.ts.map +1 -1
- package/dist/notion-as-code/database.js +61 -2
- 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/provisioning.d.ts.map +1 -1
- package/dist/notion-as-code/provisioning.js +25 -0
- package/dist/notion-as-code/provisioning.test.d.ts +2 -0
- package/dist/notion-as-code/provisioning.test.d.ts.map +1 -0
- package/dist/notion-as-code/recorder.d.ts +6 -0
- package/dist/notion-as-code/recorder.d.ts.map +1 -1
- package/dist/notion-as-code/recorder.js +22 -1
- package/dist/notion-as-code/views.d.ts +11 -2
- package/dist/notion-as-code/views.d.ts.map +1 -1
- package/package.json +1 -1
- package/skills/notion-as-code/SKILL.md +34 -1
- package/skills/workflow/SKILL.md +4 -0
- package/src/cli/build.test.ts +11 -0
- package/src/cli/codegen.test.ts +26 -1
- package/src/cli/codegen.ts +10 -2
- package/src/custom-block.test.ts +14 -0
- package/src/custom-block.ts +10 -0
- package/src/index.ts +1 -1
- package/src/notion-as-code/database.test.ts +105 -1
- package/src/notion-as-code/database.ts +77 -1
- package/src/notion-as-code/index.ts +2 -0
- package/src/notion-as-code/provisioning.test.ts +69 -0
- package/src/notion-as-code/provisioning.ts +27 -0
- package/src/notion-as-code/recorder.ts +27 -0
- package/src/notion-as-code/views-types.test.ts +24 -0
- package/src/notion-as-code/views.ts +24 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/cli/codegen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,SAAS,oBAAoB,EAAE,GAAG,MAAM,CA6CnF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,SAAS,oBAAoB,EAAE,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/cli/codegen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,SAAS,oBAAoB,EAAE,GAAG,MAAM,CA6CnF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,SAAS,oBAAoB,EAAE,GAAG,MAAM,CAuB3F;AAED,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,SAAS,oBAAoB,EAAE,GAAG,MAAM,CAWzF"}
|
package/dist/cli/codegen.js
CHANGED
|
@@ -39,11 +39,16 @@ export async function run(
|
|
|
39
39
|
`;
|
|
40
40
|
}
|
|
41
41
|
function generateMetadataEntry(capabilities) {
|
|
42
|
-
const imports = capabilities.
|
|
42
|
+
const imports = [...capabilities].sort(
|
|
43
|
+
(left, right) => Number(right.type === "custom_block") - Number(left.type === "custom_block")
|
|
44
|
+
).map(
|
|
45
|
+
(capability) => `await withMetadataCapabilityKey(${capability.type === "custom_block" ? JSON.stringify(capability.key) : "undefined"}, () => import(${JSON.stringify(`../${capability.sourcePath}`)}));`
|
|
46
|
+
).join("\n");
|
|
43
47
|
return `// Generated by \`notion-apps build\`. Do not edit.
|
|
44
48
|
import {
|
|
45
49
|
finishMetadataRecording,
|
|
46
50
|
startMetadataRecording,
|
|
51
|
+
withMetadataCapabilityKey,
|
|
47
52
|
} from "@notionhq/apps/notion-as-code/recorder";
|
|
48
53
|
|
|
49
54
|
const recorder = startMetadataRecording();
|
package/dist/custom-block.d.ts
CHANGED
|
@@ -4,6 +4,12 @@ export type CustomBlockDefaultBinding = {
|
|
|
4
4
|
dataSourceResourceId: string;
|
|
5
5
|
propertyResourceIdsByKey: Record<string, string>;
|
|
6
6
|
};
|
|
7
|
+
export type CustomBlockHandle = {
|
|
8
|
+
readonly key?: string;
|
|
9
|
+
readonly config: {
|
|
10
|
+
readonly defaultBindings?: Readonly<Record<string, CustomBlockDefaultBinding>>;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
7
13
|
type CustomBlockDataSource = ManifestDataSource | DataSourceHandle | SingleSourceDatabaseHandle;
|
|
8
14
|
export type CustomBlockOptions = {
|
|
9
15
|
path: string;
|
|
@@ -22,7 +28,6 @@ export type CustomBlockOptions = {
|
|
|
22
28
|
});
|
|
23
29
|
/** Declare a browser project. Its filename under src/customBlocks supplies its key. */
|
|
24
30
|
export declare function customBlock(options: CustomBlockOptions): {
|
|
25
|
-
_tag: "custom_block";
|
|
26
31
|
config: {
|
|
27
32
|
defaultBindings?: Record<string, CustomBlockDefaultBinding>;
|
|
28
33
|
source: {
|
|
@@ -51,7 +56,7 @@ export declare function customBlock(options: CustomBlockOptions): {
|
|
|
51
56
|
[x: string]: {
|
|
52
57
|
name: string;
|
|
53
58
|
description?: string | undefined;
|
|
54
|
-
type: "number" | "date" | "url" | "title" | "email" | "phone_number" | "checkbox" | "select" | "multi_select" | "status" | "people" | "place" | "relation" | "
|
|
59
|
+
type: "number" | "date" | "url" | "title" | "email" | "phone_number" | "checkbox" | "select" | "multi_select" | "status" | "people" | "place" | "relation" | "created_by" | "last_edited_by" | "created_time" | "last_edited_time" | "last_visited_time" | "location" | "formula" | "rollup" | "verification" | "rich_text" | "files" | "unique_id" | "button";
|
|
55
60
|
};
|
|
56
61
|
};
|
|
57
62
|
}>;
|
|
@@ -61,6 +66,8 @@ export declare function customBlock(options: CustomBlockOptions): {
|
|
|
61
66
|
version: 1;
|
|
62
67
|
};
|
|
63
68
|
};
|
|
69
|
+
key?: string;
|
|
70
|
+
_tag: "custom_block";
|
|
64
71
|
};
|
|
65
72
|
export {};
|
|
66
73
|
//# sourceMappingURL=custom-block.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-block.d.ts","sourceRoot":"","sources":["../src/custom-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"custom-block.d.ts","sourceRoot":"","sources":["../src/custom-block.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE,OAAO,KAAK,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAIjG,MAAM,MAAM,yBAAyB,GAAG;IACvC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,wBAAwB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE;QAChB,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAC;KAC/E,CAAC;CACF,CAAC;AAEF,KAAK,qBAAqB,GAAG,kBAAkB,GAAG,gBAAgB,GAAG,0BAA0B,CAAC;AAEhG,MAAM,MAAM,kBAAkB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;CACpD,GAAG,CACD;IAAE,MAAM,EAAE,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,CAAA;CAAE,GACjD;IAAE,MAAM,CAAC,EAAE,KAAK,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CACvD,CAAC;AAEF,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkCtD"}
|
package/dist/custom-block.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getCurrentMetadataCapabilityKey } from "./notion-as-code/recorder.js";
|
|
1
2
|
import { toCustomBlockDefaultBinding, toCustomBlockDataSource } from "./translate.js";
|
|
2
3
|
function customBlock(options) {
|
|
3
4
|
if (typeof options.path !== "string" || options.path.trim() === "") {
|
|
@@ -10,8 +11,10 @@ function customBlock(options) {
|
|
|
10
11
|
);
|
|
11
12
|
}
|
|
12
13
|
const { dataSources, defaultBindings } = lowerDataSources(options.dataSources ?? {});
|
|
14
|
+
const key = getCurrentMetadataCapabilityKey();
|
|
13
15
|
return {
|
|
14
16
|
_tag: "custom_block",
|
|
17
|
+
...key === void 0 ? {} : { key },
|
|
15
18
|
config: {
|
|
16
19
|
source: options.static ? { type: "static", path: options.path } : {
|
|
17
20
|
type: "project",
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { customBlock } from "./custom-block.js";
|
|
1
|
+
export { customBlock, type CustomBlockHandle } from "./custom-block.js";
|
|
2
2
|
export { customAgent } from "./notion-as-code/custom-agent.js";
|
|
3
3
|
export { database } from "./notion-as-code/database.js";
|
|
4
4
|
export { page } from "./notion-as-code/page.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACN,MAAM,EACN,KAAK,EACL,QAAQ,EACR,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,0BAA0B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,4BAA4B,GACjC,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Database } from "../database.js";
|
|
2
|
+
import type { CustomBlockHandle } from "../custom-block.js";
|
|
2
3
|
import { type DatabaseIntent, type DatabasePageLayout, type NotionAsCodeIcon, type NotionAsCodeSchema, type Parent, type ResourceId } from "./intents.js";
|
|
3
4
|
import { type ChildPageArgs, type PageHandle } from "./page.js";
|
|
4
5
|
import { type AppsSchemaForSchema } from "./schema.js";
|
|
@@ -87,6 +88,16 @@ type DatabaseHandleBase = {
|
|
|
87
88
|
readonly resourceType: "database";
|
|
88
89
|
readonly resourceId: string;
|
|
89
90
|
addView: (view: ViewSchema) => void;
|
|
91
|
+
addCustomView: (view: AddCustomViewArgs) => void;
|
|
92
|
+
};
|
|
93
|
+
export type AddCustomViewArgs = {
|
|
94
|
+
resourceId: ResourceId;
|
|
95
|
+
name?: string;
|
|
96
|
+
icon?: Extract<NotionAsCodeIcon, {
|
|
97
|
+
type: "notion_icon";
|
|
98
|
+
}>;
|
|
99
|
+
customBlock: CustomBlockHandle;
|
|
100
|
+
dataSource?: DataSourceHandle;
|
|
90
101
|
};
|
|
91
102
|
/** Map each authoring source key to a handle backed by that source's own schema. */
|
|
92
103
|
export type DatabaseHandle<DataSources extends DataSourceMap = DataSourceMap> = DatabaseHandleBase & {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/database.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
APPS_WORKSPACE_RESOURCE_ID
|
|
3
3
|
} from "./intents.js";
|
|
4
4
|
import { createPage } from "./page.js";
|
|
5
|
-
import { recordIntent } from "./recorder.js";
|
|
5
|
+
import { isMetadataRecording, recordIntent } from "./recorder.js";
|
|
6
6
|
import { assertParent, assertUserResourceId } from "./resource.js";
|
|
7
7
|
import { createAppsDatabase } from "./schema.js";
|
|
8
8
|
function database(databaseResourceId, args) {
|
|
@@ -58,7 +58,8 @@ function buildDatabaseHandle(databaseResourceId, args, parent) {
|
|
|
58
58
|
resourceType: "database",
|
|
59
59
|
resourceId: databaseResourceId,
|
|
60
60
|
dataSource,
|
|
61
|
-
addView: handle.addView
|
|
61
|
+
addView: handle.addView,
|
|
62
|
+
addCustomView: handle.addCustomView
|
|
62
63
|
};
|
|
63
64
|
}
|
|
64
65
|
if (args.datasources !== void 0) {
|
|
@@ -160,9 +161,67 @@ function createDatabase(intent, sourceEntries) {
|
|
|
160
161
|
datasources: handles,
|
|
161
162
|
addView(view) {
|
|
162
163
|
recordIntent({ type: "view", databaseResourceId: intent.resourceId, view });
|
|
164
|
+
},
|
|
165
|
+
addCustomView(view) {
|
|
166
|
+
recordCustomView(intent.resourceId, view, handles);
|
|
163
167
|
}
|
|
164
168
|
};
|
|
165
169
|
}
|
|
170
|
+
function recordCustomView(databaseResourceId, view, handles) {
|
|
171
|
+
assertUserResourceId(view.resourceId);
|
|
172
|
+
const customBlockKey = view.customBlock.key;
|
|
173
|
+
if (typeof customBlockKey !== "string" || customBlockKey.trim() === "") {
|
|
174
|
+
if (!isMetadataRecording()) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
throw new Error(
|
|
178
|
+
"addCustomView must be called from the custom block capability file so its key is available during build"
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
const dataSources = Object.values(handles);
|
|
182
|
+
const boundDataSourceIds = new Set(
|
|
183
|
+
Object.values(view.customBlock.config.defaultBindings ?? {}).map(
|
|
184
|
+
(binding) => binding.dataSourceResourceId
|
|
185
|
+
)
|
|
186
|
+
);
|
|
187
|
+
let dataSourceResourceId;
|
|
188
|
+
if (view.dataSource !== void 0) {
|
|
189
|
+
if (!dataSources.includes(view.dataSource)) {
|
|
190
|
+
throw new Error(
|
|
191
|
+
`Custom view "${view.resourceId}" dataSource must belong to database "${databaseResourceId}"`
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
if (!boundDataSourceIds.has(view.dataSource.resourceId)) {
|
|
195
|
+
throw new Error(
|
|
196
|
+
`Custom view "${view.resourceId}" dataSource must be bound by custom block "${customBlockKey}"`
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
dataSourceResourceId = view.dataSource.resourceId;
|
|
200
|
+
} else {
|
|
201
|
+
const matchingSources = dataSources.filter(
|
|
202
|
+
(source) => boundDataSourceIds.has(source.resourceId)
|
|
203
|
+
);
|
|
204
|
+
const matchingSource = matchingSources[0];
|
|
205
|
+
if (matchingSources.length !== 1 || matchingSource === void 0) {
|
|
206
|
+
throw new Error(
|
|
207
|
+
`Custom view "${view.resourceId}" must bind exactly one data source from database "${databaseResourceId}" or specify dataSource`
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
dataSourceResourceId = matchingSource.resourceId;
|
|
211
|
+
}
|
|
212
|
+
recordIntent({
|
|
213
|
+
type: "view",
|
|
214
|
+
databaseResourceId,
|
|
215
|
+
view: {
|
|
216
|
+
type: "custom",
|
|
217
|
+
resourceId: view.resourceId,
|
|
218
|
+
...view.name === void 0 ? {} : { name: view.name },
|
|
219
|
+
...view.icon === void 0 ? {} : { icon: view.icon },
|
|
220
|
+
dataSourceResourceId,
|
|
221
|
+
customBlockKey
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
166
225
|
function createDataSourceHandle(dataSource, schema, databaseDescription) {
|
|
167
226
|
const propertyResourceIds = /* @__PURE__ */ new Set();
|
|
168
227
|
const propertyNames = /* @__PURE__ */ new Set();
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export { APPS_RESERVED_RESOURCE_ID_PREFIX, APPS_WORKSPACE_RESOURCE_ID } from "./intents.js";
|
|
2
2
|
export type { ContentPageLayoutTab, DatabasePageLayout, DatabasePageLayoutTab, DatabaseIntent, DataSourceDefinition, NotionAsCodeIcon, NotionAsCodeProperty, NotionAsCodePropertyConfig, NotionAsCodeSchema, NotionAsCodeSelectOption, NotionAsCodeStatusOption, PageCoverReference, PageLayoutMainModule, PageLayoutNumberAndFormulaStyle, PageLayoutPersonStyle, PageLayoutPropertiesModule, PageLayoutPropertyConfig, PageLayoutPropertyModule, PageLayoutPropertySection, PageLayoutRelationConfig, PageLayoutRelationsGroupModule, PageLayoutSidebarModule, Parent, ResourceId, RollupBaseAggregationType, RollupDateAggregationType, RollupNumberAggregationType, RollupTargetPropertyType, ViewPageLayoutTab, } from "./intents.js";
|
|
3
3
|
export type { CustomAgentAccess, CustomAgentArgs, CustomAgentHandle, CustomAgentPageAddedTrigger, CustomAgentPropertyUpdatedTrigger, CustomAgentRecurrenceSchedule, CustomAgentRecurrenceTrigger, CustomAgentTrustedUrls, CustomAgentTrigger, CustomAgentTriggerBase, DailyRecurrenceSchedule, HourlyRecurrenceSchedule, MonthlyRecurrenceRestriction, MonthlyRecurrenceSchedule, MonthlyWeekdayOccurrence, PropertyTriggerCondition, RecurrenceScheduleEnd, RecurrenceWeekdays, WeeklyRecurrenceSchedule, YearlyRecurrenceSchedule, } from "./custom-agent.js";
|
|
4
|
-
export type { ChildDatabaseArgs, ChildDatabaseFactory, ChildMultiSourceDatabaseArgs, ChildSingleSourceDatabaseArgs, DataSourceArgs, DataSourceHandle, DataSourceMap, DatabaseArgs, DatabaseHandle, MultiSourceDatabaseArgs, SingleSourceDatabaseArgs, SingleSourceDatabaseHandle, } from "./database.js";
|
|
4
|
+
export type { AddCustomViewArgs, ChildDatabaseArgs, ChildDatabaseFactory, ChildMultiSourceDatabaseArgs, ChildSingleSourceDatabaseArgs, DataSourceArgs, DataSourceHandle, DataSourceMap, DatabaseArgs, DatabaseHandle, MultiSourceDatabaseArgs, SingleSourceDatabaseArgs, SingleSourceDatabaseHandle, } from "./database.js";
|
|
5
5
|
export { toCustomBlockDefaultBinding, toCustomBlockDataSource } from "../translate.js";
|
|
6
6
|
export type { ChildPageArgs, PageArgs, PageHandle, PropertyValue, SimpleTextToken, TextValue, VerificationInput, VerificationPropertyValue, } from "./page.js";
|
|
7
7
|
export type { TeamspaceArgs, TeamspaceHandle } from "./teamspace.js";
|
|
8
8
|
export type { ViewArgs, ViewHandle } from "./view.js";
|
|
9
|
-
export type { AdvancedFilterSchema, BasePropertyFilter, BaseViewSchema, BoardViewSchema, CalendarViewSchema, CheckboxGroupByFormat, CheckboxPropertyFilter, CoverAspectFormat, CoverFormat, CoverSizeFormat, DatabaseViewSortDirection, DateFilterMode, DateGroupByFormat, DatePropertyFilter, DatePropertyFilterValue, DatePropertyTypes, ExactDatePropertyFilterValue, ExactRangeDatePropertyFilterValue, FeedViewSchema, FilterSchema, FormulaGroupByFormat, GalleryViewSchema, GroupByFormat, GroupByFormatBase, GroupFormat, ListViewSchema, LocationGroupByFormat, MultiSelectPropertyFilter, NumberGroupByFormat, NumberPropertyFilter, PersonGroupByFormat, PersonPropertyFilter, PropertyFilterSchema, PropertyFormat, PropertyViewSortSchema, PropertyVisibility, RelationGroupByFormat, RelationPropertyFilter, RelativeDatePreset, RelativeDatePropertyFilterValue, RelativeDateRangeUnit, RelativeToTodayDatePropertyFilterValue, SelectGroupByFormat, SelectPropertyFilter, StatusGroupByFormat, StatusPropertyFilter, TableViewSchema, TextGroupByFormat, TextPropertyFilter, TimelineViewSchema, ViewSchema, ViewType, } from "./views.js";
|
|
9
|
+
export type { AdvancedFilterSchema, BasePropertyFilter, BaseViewSchema, BoardViewSchema, CalendarViewSchema, CheckboxGroupByFormat, CheckboxPropertyFilter, CoverAspectFormat, CoverFormat, CoverSizeFormat, CustomViewSchema, DatabaseViewSortDirection, DateFilterMode, DateGroupByFormat, DatePropertyFilter, DatePropertyFilterValue, DatePropertyTypes, ExactDatePropertyFilterValue, ExactRangeDatePropertyFilterValue, FeedViewSchema, FilterSchema, FormulaGroupByFormat, GalleryViewSchema, GroupByFormat, GroupByFormatBase, GroupFormat, ListViewSchema, LocationGroupByFormat, MultiSelectPropertyFilter, NumberGroupByFormat, NumberPropertyFilter, PersonGroupByFormat, PersonPropertyFilter, PropertyFilterSchema, PropertyFormat, PropertyViewSortSchema, PropertyVisibility, RelationGroupByFormat, RelationPropertyFilter, RelativeDatePreset, RelativeDatePropertyFilterValue, RelativeDateRangeUnit, RelativeToTodayDatePropertyFilterValue, SelectGroupByFormat, SelectPropertyFilter, StatusGroupByFormat, StatusPropertyFilter, TableViewSchema, TextGroupByFormat, TextPropertyFilter, TimelineViewSchema, ViewSchema, ViewType, } from "./views.js";
|
|
10
10
|
/** Experimental Notion-as-Code facade for Apps SDK project metadata. */
|
|
11
11
|
export declare const notion: {
|
|
12
12
|
teamspace: typeof import("./teamspace.js").teamspace;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gCAAgC,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC5F,YAAY,EACX,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,oBAAoB,EACpB,+BAA+B,EAC/B,qBAAqB,EACrB,0BAA0B,EAC1B,wBAAwB,EACxB,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACxB,8BAA8B,EAC9B,uBAAuB,EACvB,MAAM,EACN,UAAU,EACV,yBAAyB,EACzB,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EACxB,iBAAiB,GACjB,MAAM,cAAc,CAAC;AACtB,YAAY,EACX,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,2BAA2B,EAC3B,iCAAiC,EACjC,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,4BAA4B,EAC5B,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACX,iBAAiB,EACjB,oBAAoB,EACpB,4BAA4B,EAC5B,6BAA6B,EAC7B,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,GAC1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACvF,YAAY,EACX,aAAa,EACb,QAAQ,EACR,UAAU,EACV,aAAa,EACb,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,yBAAyB,GACzB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACtD,YAAY,EACX,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,yBAAyB,EACzB,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,4BAA4B,EAC5B,iCAAiC,EACjC,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,yBAAyB,EACzB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,+BAA+B,EAC/B,qBAAqB,EACrB,sCAAsC,EACtC,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACV,QAAQ,GACR,MAAM,YAAY,CAAC;AAEpB,wEAAwE;AACxE,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;CAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gCAAgC,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC5F,YAAY,EACX,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,oBAAoB,EACpB,+BAA+B,EAC/B,qBAAqB,EACrB,0BAA0B,EAC1B,wBAAwB,EACxB,wBAAwB,EACxB,yBAAyB,EACzB,wBAAwB,EACxB,8BAA8B,EAC9B,uBAAuB,EACvB,MAAM,EACN,UAAU,EACV,yBAAyB,EACzB,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EACxB,iBAAiB,GACjB,MAAM,cAAc,CAAC;AACtB,YAAY,EACX,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,2BAA2B,EAC3B,iCAAiC,EACjC,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,wBAAwB,EACxB,4BAA4B,EAC5B,yBAAyB,EACzB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACX,iBAAiB,EACjB,iBAAiB,EACjB,oBAAoB,EACpB,4BAA4B,EAC5B,6BAA6B,EAC7B,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,cAAc,EACd,uBAAuB,EACvB,wBAAwB,EACxB,0BAA0B,GAC1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,2BAA2B,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AACvF,YAAY,EACX,aAAa,EACb,QAAQ,EACR,UAAU,EACV,aAAa,EACb,eAAe,EACf,SAAS,EACT,iBAAiB,EACjB,yBAAyB,GACzB,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrE,YAAY,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACtD,YAAY,EACX,oBAAoB,EACpB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,iBAAiB,EACjB,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,yBAAyB,EACzB,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,4BAA4B,EAC5B,iCAAiC,EACjC,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,iBAAiB,EACjB,aAAa,EACb,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,qBAAqB,EACrB,yBAAyB,EACzB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,cAAc,EACd,sBAAsB,EACtB,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,+BAA+B,EAC/B,qBAAqB,EACrB,sCAAsC,EACtC,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACV,QAAQ,GACR,MAAM,YAAY,CAAC;AAEpB,wEAAwE;AACxE,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;CAAiB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provisioning.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/provisioning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"provisioning.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/provisioning.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtD,eAAO,MAAM,wBAAwB,gCAAgC,CAAC;AAEtE,qFAAqF;AACrF,MAAM,MAAM,oBAAoB,GAAG;IAClC,OAAO,EAAE,iBAAiB,EAAE,CAAC;CAC7B,CAAC;AAEF,0FAA0F;AAC1F,MAAM,MAAM,kBAAkB,GAC3B,IAAI,CAAC,OAAO,CAAC,iBAAiB,EAAE;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC,EAAE,QAAQ,CAAC,GACjE,OAAO,CAAC,iBAAiB,EAAE;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC,CAAC;AAErD,MAAM,MAAM,oBAAoB,GAAG;IAClC,OAAO,EAAE,OAAO,wBAAwB,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACvC,CAAC;AAEF,kFAAkF;AAClF,wBAAgB,0BAA0B,CACzC,OAAO,EAAE,SAAS,iBAAiB,EAAE,GACnC,oBAAoB,CAuBtB;AAED,iEAAiE;AACjE,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAOpF"}
|
|
@@ -2,6 +2,13 @@ const APPS_PROVISIONING_SCHEMA = "notion:apps-provisioning:v1";
|
|
|
2
2
|
function createProvisioningArtifact(intents) {
|
|
3
3
|
const provisioningIntents = [];
|
|
4
4
|
for (const intent of intents) {
|
|
5
|
+
if (intent.type === "view") {
|
|
6
|
+
validateCustomView(intent.view);
|
|
7
|
+
} else if (intent.type === "database") {
|
|
8
|
+
for (const view of intent.views ?? []) {
|
|
9
|
+
validateCustomView(view);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
5
12
|
if (intent.type === "teamspace") {
|
|
6
13
|
const { parent: _parent, ...teamspace } = intent;
|
|
7
14
|
provisioningIntents.push(teamspace);
|
|
@@ -18,6 +25,24 @@ function createProvisioningArtifact(intents) {
|
|
|
18
25
|
function isRecordedProvisioning(value) {
|
|
19
26
|
return typeof value === "object" && value !== null && "intents" in value && Array.isArray(value.intents);
|
|
20
27
|
}
|
|
28
|
+
function validateCustomView(view) {
|
|
29
|
+
if (view.type === "custom") {
|
|
30
|
+
if (typeof view.customBlockKey !== "string" || view.customBlockKey.trim() === "") {
|
|
31
|
+
throw new Error("Custom views require a non-empty customBlockKey");
|
|
32
|
+
}
|
|
33
|
+
for (const field of [
|
|
34
|
+
"sorts",
|
|
35
|
+
"filters",
|
|
36
|
+
"properties",
|
|
37
|
+
"showPageIcon",
|
|
38
|
+
"defaultTemplate"
|
|
39
|
+
]) {
|
|
40
|
+
if (field in view) {
|
|
41
|
+
throw new Error(`Custom views do not support ${field}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
21
46
|
export {
|
|
22
47
|
APPS_PROVISIONING_SCHEMA,
|
|
23
48
|
createProvisioningArtifact,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provisioning.test.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/provisioning.test.ts"],"names":[],"mappings":""}
|
|
@@ -7,4 +7,10 @@ export declare function startMetadataRecording(): RecordedProvisioning;
|
|
|
7
7
|
export declare function finishMetadataRecording(recorder: RecordedProvisioning): RecordedProvisioning;
|
|
8
8
|
/** Record one declaration when metadata collection is active. */
|
|
9
9
|
export declare function recordIntent(intent: InfraAsCodeIntent): void;
|
|
10
|
+
/** Evaluate one discovered capability with its build-time identity available to declarations. */
|
|
11
|
+
export declare function withMetadataCapabilityKey<T>(capabilityKey: string | undefined, evaluate: () => Promise<T>): Promise<T>;
|
|
12
|
+
/** Return the capability key only while a metadata bundle is recording. */
|
|
13
|
+
export declare function getCurrentMetadataCapabilityKey(): string | undefined;
|
|
14
|
+
/** Whether declarations are currently being collected by the build metadata bundle. */
|
|
15
|
+
export declare function isMetadataRecording(): boolean;
|
|
10
16
|
//# sourceMappingURL=recorder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/recorder.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/recorder.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAC1F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAK9D,8DAA8D;AAC9D,wBAAgB,sBAAsB,IAAI,oBAAoB,CAK7D;AAED,yEAAyE;AACzE,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,oBAAoB,GAAG,oBAAoB,CAO5F;AAED,iEAAiE;AACjE,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAE5D;AAED,iGAAiG;AACjG,wBAAsB,yBAAyB,CAAC,CAAC,EAChD,aAAa,EAAE,MAAM,GAAG,SAAS,EACjC,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACxB,OAAO,CAAC,CAAC,CAAC,CAQZ;AAED,2EAA2E;AAC3E,wBAAgB,+BAA+B,IAAI,MAAM,GAAG,SAAS,CAEpE;AAED,uFAAuF;AACvF,wBAAgB,mBAAmB,IAAI,OAAO,CAE7C"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
let activeRecorder;
|
|
2
|
+
let currentCapabilityKey;
|
|
2
3
|
function startMetadataRecording() {
|
|
3
4
|
const recorder = { intents: [] };
|
|
4
5
|
activeRecorder = recorder;
|
|
6
|
+
currentCapabilityKey = void 0;
|
|
5
7
|
return recorder;
|
|
6
8
|
}
|
|
7
9
|
function finishMetadataRecording(recorder) {
|
|
@@ -9,13 +11,32 @@ function finishMetadataRecording(recorder) {
|
|
|
9
11
|
throw new Error("Notion-as-Code metadata recorder was replaced before build completed");
|
|
10
12
|
}
|
|
11
13
|
activeRecorder = void 0;
|
|
14
|
+
currentCapabilityKey = void 0;
|
|
12
15
|
return recorder;
|
|
13
16
|
}
|
|
14
17
|
function recordIntent(intent) {
|
|
15
18
|
activeRecorder?.intents.push(intent);
|
|
16
19
|
}
|
|
20
|
+
async function withMetadataCapabilityKey(capabilityKey, evaluate) {
|
|
21
|
+
const previousCapabilityKey = currentCapabilityKey;
|
|
22
|
+
currentCapabilityKey = capabilityKey;
|
|
23
|
+
try {
|
|
24
|
+
return await evaluate();
|
|
25
|
+
} finally {
|
|
26
|
+
currentCapabilityKey = previousCapabilityKey;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
function getCurrentMetadataCapabilityKey() {
|
|
30
|
+
return activeRecorder === void 0 ? void 0 : currentCapabilityKey;
|
|
31
|
+
}
|
|
32
|
+
function isMetadataRecording() {
|
|
33
|
+
return activeRecorder !== void 0;
|
|
34
|
+
}
|
|
17
35
|
export {
|
|
18
36
|
finishMetadataRecording,
|
|
37
|
+
getCurrentMetadataCapabilityKey,
|
|
38
|
+
isMetadataRecording,
|
|
19
39
|
recordIntent,
|
|
20
|
-
startMetadataRecording
|
|
40
|
+
startMetadataRecording,
|
|
41
|
+
withMetadataCapabilityKey
|
|
21
42
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { NotionAsCodeIcon, NotionAsCodeProperty, ResourceId } from "./intents.js";
|
|
2
|
-
export type ViewType = "table" | "board" | "calendar" | "list" | "gallery" | "feed" | "timeline";
|
|
2
|
+
export type ViewType = "table" | "board" | "calendar" | "list" | "gallery" | "feed" | "timeline" | "custom";
|
|
3
3
|
export type PropertyVisibility = "show" | "hide" | "hide_if_empty";
|
|
4
4
|
/**
|
|
5
5
|
* Format for a single visible property entry in a view (table / board / list /
|
|
@@ -483,6 +483,15 @@ export type TimelineViewSchema = BaseViewSchema & {
|
|
|
483
483
|
timelineByEnd?: ResourceId;
|
|
484
484
|
showTable?: boolean;
|
|
485
485
|
};
|
|
486
|
-
export type
|
|
486
|
+
export type CustomViewSchema = Omit<BaseViewSchema, "type" | "sorts" | "filters" | "showPageIcon" | "defaultTemplate"> & {
|
|
487
|
+
type: "custom";
|
|
488
|
+
customBlockKey: string;
|
|
489
|
+
sorts?: never;
|
|
490
|
+
filters?: never;
|
|
491
|
+
properties?: never;
|
|
492
|
+
showPageIcon?: never;
|
|
493
|
+
defaultTemplate?: never;
|
|
494
|
+
};
|
|
495
|
+
export type ViewSchema = TableViewSchema | BoardViewSchema | CalendarViewSchema | ListViewSchema | GalleryViewSchema | FeedViewSchema | TimelineViewSchema | CustomViewSchema;
|
|
487
496
|
export {};
|
|
488
497
|
//# sourceMappingURL=views.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"views.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/views.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAGvF,MAAM,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"views.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/views.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -85,10 +85,15 @@ root exports support:
|
|
|
85
85
|
returning a single source as `handle.dataSource`, or
|
|
86
86
|
`database(resourceId, { datasources: { Key: { resourceId, schema } }, views?, parent? })`,
|
|
87
87
|
returning sources as `handle.datasources.Key`. A source's `addPage` declares a row;
|
|
88
|
-
the database handle also exposes `addView`.
|
|
88
|
+
the database handle also exposes `addView` and `addCustomView`.
|
|
89
89
|
- `customAgent({ resourceId, name, ... })`; only `resourceId` and `name` are
|
|
90
90
|
required. Choose optional fields individually as described below, and inspect
|
|
91
91
|
the installed types before using them.
|
|
92
|
+
|
|
93
|
+
When an App calls a custom agent, read the
|
|
94
|
+
[Notion Agent APIs overview](https://developers.notion.com/guides/notion-agent-apis/overview)
|
|
95
|
+
first.
|
|
96
|
+
|
|
92
97
|
- `view({ databaseResourceId, resourceId, type, dataSourceResourceId, ... })`,
|
|
93
98
|
returning a handle with `resourceId`. This is also available as `notion.view`.
|
|
94
99
|
Use property resource IDs in view filters, sorts, and layout options; calendar
|
|
@@ -121,6 +126,34 @@ const linkedIssues = database("project-issues-linked", {
|
|
|
121
126
|
The table view above is typed by its `type: "table"` schema and links to the
|
|
122
127
|
explicit `issues-source` resource ID.
|
|
123
128
|
|
|
129
|
+
Attach a declared custom block as a database view with `addCustomView`. The
|
|
130
|
+
custom block must be declared in `src/customBlocks/<key>.ts`. If its default
|
|
131
|
+
bindings match exactly one data source owned by the database, the SDK infers
|
|
132
|
+
that source. Otherwise pass one of the database's own data-source handles.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
import { customBlock, database } from "@notionhq/apps";
|
|
136
|
+
|
|
137
|
+
const tasks = database("tasks-db", {
|
|
138
|
+
dataSourceResourceId: "tasks-source",
|
|
139
|
+
name: "Tasks",
|
|
140
|
+
schema: { Name: { type: "title", resourceId: "task-name" } },
|
|
141
|
+
});
|
|
142
|
+
const board = customBlock({
|
|
143
|
+
path: "./blocks/board",
|
|
144
|
+
dataSources: { tasks },
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
tasks.addCustomView({
|
|
148
|
+
resourceId: "tasks-board-view",
|
|
149
|
+
name: "Board",
|
|
150
|
+
customBlock: board,
|
|
151
|
+
});
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Custom views do not accept standard view properties, sorts, or filters. Keep
|
|
155
|
+
the view resource ID and the custom-block filename stable across builds.
|
|
156
|
+
|
|
124
157
|
Keep resource IDs stable across builds. They identify declarations, not live
|
|
125
158
|
Notion UUIDs. Avoid the reserved `__notion_apps_` prefix. Explicit parents
|
|
126
159
|
use `{ type: "resourceId", resourceId: parent.resourceId }`; child helpers set
|
package/skills/workflow/SKILL.md
CHANGED
|
@@ -167,6 +167,10 @@ typed `context.access` exposes each declared alias as a readonly `{ type, id }`,
|
|
|
167
167
|
not the declaration handle or a permission-management API. UI-granted resources
|
|
168
168
|
are permissions only: they do not create `context.access` aliases.
|
|
169
169
|
|
|
170
|
+
When a workflow calls a custom agent, read the
|
|
171
|
+
[Notion Agent APIs overview](https://developers.notion.com/guides/notion-agent-apis/overview)
|
|
172
|
+
first.
|
|
173
|
+
|
|
170
174
|
For a resource already granted to the workflow in Notion's UI, use its live
|
|
171
175
|
record ID directly in a `context.notion` call:
|
|
172
176
|
|
package/src/cli/build.test.ts
CHANGED
|
@@ -241,6 +241,17 @@ describe("buildApp", () => {
|
|
|
241
241
|
}),
|
|
242
242
|
],
|
|
243
243
|
}),
|
|
244
|
+
{
|
|
245
|
+
type: "view",
|
|
246
|
+
databaseResourceId: "tasks-db",
|
|
247
|
+
view: {
|
|
248
|
+
type: "custom",
|
|
249
|
+
resourceId: "tasks-board-view",
|
|
250
|
+
name: "Board",
|
|
251
|
+
dataSourceResourceId: "tasks-source",
|
|
252
|
+
customBlockKey: "board",
|
|
253
|
+
},
|
|
254
|
+
},
|
|
244
255
|
]);
|
|
245
256
|
});
|
|
246
257
|
|
package/src/cli/codegen.test.ts
CHANGED
|
@@ -49,6 +49,31 @@ describe("generateMetadataEntry", () => {
|
|
|
49
49
|
},
|
|
50
50
|
]);
|
|
51
51
|
|
|
52
|
-
expect(entry).toContain(
|
|
52
|
+
expect(entry).toContain(
|
|
53
|
+
`await withMetadataCapabilityKey("board", () => import("../src/customBlocks/board.ts"));`,
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it("evaluates custom blocks under their capability key before other modules", () => {
|
|
58
|
+
const entry = generateMetadataEntry([
|
|
59
|
+
{
|
|
60
|
+
type: "workflow",
|
|
61
|
+
tag: "workflow",
|
|
62
|
+
runtime: "worker",
|
|
63
|
+
key: "notify",
|
|
64
|
+
sourcePath: "src/workflows/notify.ts",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
type: "custom_block",
|
|
68
|
+
tag: "custom_block",
|
|
69
|
+
runtime: "build",
|
|
70
|
+
key: "board",
|
|
71
|
+
sourcePath: "src/customBlocks/board.ts",
|
|
72
|
+
},
|
|
73
|
+
]);
|
|
74
|
+
|
|
75
|
+
expect(entry.indexOf("src/customBlocks/board.ts")).toBeLessThan(
|
|
76
|
+
entry.indexOf("src/workflows/notify.ts"),
|
|
77
|
+
);
|
|
53
78
|
});
|
|
54
79
|
});
|
package/src/cli/codegen.ts
CHANGED
|
@@ -59,14 +59,22 @@ export async function run(
|
|
|
59
59
|
* recorder starts and remain isolated from the deployed Worker entry.
|
|
60
60
|
*/
|
|
61
61
|
export function generateMetadataEntry(capabilities: readonly DiscoveredCapability[]): string {
|
|
62
|
-
const imports = capabilities
|
|
63
|
-
.
|
|
62
|
+
const imports = [...capabilities]
|
|
63
|
+
.sort(
|
|
64
|
+
(left, right) =>
|
|
65
|
+
Number(right.type === "custom_block") - Number(left.type === "custom_block"),
|
|
66
|
+
)
|
|
67
|
+
.map(
|
|
68
|
+
(capability) =>
|
|
69
|
+
`await withMetadataCapabilityKey(${capability.type === "custom_block" ? JSON.stringify(capability.key) : "undefined"}, () => import(${JSON.stringify(`../${capability.sourcePath}`)}));`,
|
|
70
|
+
)
|
|
64
71
|
.join("\n");
|
|
65
72
|
|
|
66
73
|
return `// Generated by \`notion-apps build\`. Do not edit.
|
|
67
74
|
import {
|
|
68
75
|
finishMetadataRecording,
|
|
69
76
|
startMetadataRecording,
|
|
77
|
+
withMetadataCapabilityKey,
|
|
70
78
|
} from "@notionhq/apps/notion-as-code/recorder";
|
|
71
79
|
|
|
72
80
|
const recorder = startMetadataRecording();
|
package/src/custom-block.test.ts
CHANGED
|
@@ -2,9 +2,23 @@ import { describe, expect, expectTypeOf, it } from "vitest";
|
|
|
2
2
|
|
|
3
3
|
import { customBlock, type CustomBlockOptions } from "./custom-block.js";
|
|
4
4
|
import { notion, type DatabaseHandle } from "./notion-as-code/index.js";
|
|
5
|
+
import {
|
|
6
|
+
finishMetadataRecording,
|
|
7
|
+
startMetadataRecording,
|
|
8
|
+
withMetadataCapabilityKey,
|
|
9
|
+
} from "./notion-as-code/recorder.js";
|
|
5
10
|
import { toCustomBlockPropertyType } from "./translate.js";
|
|
6
11
|
|
|
7
12
|
describe("customBlock", () => {
|
|
13
|
+
it("stamps the current capability key only during metadata recording", async () => {
|
|
14
|
+
expect(customBlock({ path: "blocks/board" }).key).toBeUndefined();
|
|
15
|
+
const recorder = startMetadataRecording();
|
|
16
|
+
const block = await withMetadataCapabilityKey("board", async () =>
|
|
17
|
+
customBlock({ path: "blocks/board" }),
|
|
18
|
+
);
|
|
19
|
+
expect(block.key).toBe("board");
|
|
20
|
+
finishMetadataRecording(recorder);
|
|
21
|
+
});
|
|
8
22
|
it("supports static assets without a build command", () => {
|
|
9
23
|
expect(customBlock({ path: "assets", static: true }).config.source).toEqual({
|
|
10
24
|
type: "static",
|
package/src/custom-block.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ManifestDataSource } from "@notionhq/custom-blocks";
|
|
2
2
|
|
|
3
3
|
import type { DataSourceHandle, SingleSourceDatabaseHandle } from "./notion-as-code/database.js";
|
|
4
|
+
import { getCurrentMetadataCapabilityKey } from "./notion-as-code/recorder.js";
|
|
4
5
|
import { toCustomBlockDefaultBinding, toCustomBlockDataSource } from "./translate.js";
|
|
5
6
|
|
|
6
7
|
export type CustomBlockDefaultBinding = {
|
|
@@ -8,6 +9,13 @@ export type CustomBlockDefaultBinding = {
|
|
|
8
9
|
propertyResourceIdsByKey: Record<string, string>;
|
|
9
10
|
};
|
|
10
11
|
|
|
12
|
+
export type CustomBlockHandle = {
|
|
13
|
+
readonly key?: string;
|
|
14
|
+
readonly config: {
|
|
15
|
+
readonly defaultBindings?: Readonly<Record<string, CustomBlockDefaultBinding>>;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
11
19
|
type CustomBlockDataSource = ManifestDataSource | DataSourceHandle | SingleSourceDatabaseHandle;
|
|
12
20
|
|
|
13
21
|
export type CustomBlockOptions = {
|
|
@@ -33,8 +41,10 @@ export function customBlock(options: CustomBlockOptions) {
|
|
|
33
41
|
);
|
|
34
42
|
}
|
|
35
43
|
const { dataSources, defaultBindings } = lowerDataSources(options.dataSources ?? {});
|
|
44
|
+
const key = getCurrentMetadataCapabilityKey();
|
|
36
45
|
return {
|
|
37
46
|
_tag: "custom_block" as const,
|
|
47
|
+
...(key === undefined ? {} : { key }),
|
|
38
48
|
config: {
|
|
39
49
|
source: options.static
|
|
40
50
|
? { type: "static" as const, path: options.path }
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { customBlock } from "./custom-block.js";
|
|
1
|
+
export { customBlock, type CustomBlockHandle } from "./custom-block.js";
|
|
2
2
|
export { customAgent } from "./notion-as-code/custom-agent.js";
|
|
3
3
|
export { database } from "./notion-as-code/database.js";
|
|
4
4
|
export { page } from "./notion-as-code/page.js";
|
|
@@ -1,13 +1,117 @@
|
|
|
1
1
|
import { describe, expect, expectTypeOf, it } from "vitest";
|
|
2
2
|
|
|
3
3
|
import { Builder } from "../builder.js";
|
|
4
|
+
import { customBlock } from "../custom-block.js";
|
|
4
5
|
import { ExecutionError } from "../error.js";
|
|
5
6
|
import { sync } from "../sync.js";
|
|
6
7
|
import { notion, type DataSourceHandle, type SingleSourceDatabaseHandle } from "./index.js";
|
|
7
8
|
import { APPS_WORKSPACE_RESOURCE_ID } from "./intents.js";
|
|
8
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
finishMetadataRecording,
|
|
11
|
+
startMetadataRecording,
|
|
12
|
+
withMetadataCapabilityKey,
|
|
13
|
+
} from "./recorder.js";
|
|
9
14
|
|
|
10
15
|
describe("Notion-as-Code database declarations", () => {
|
|
16
|
+
it("infers a custom view data source from the block's default bindings", async () => {
|
|
17
|
+
const recorder = startMetadataRecording();
|
|
18
|
+
const tasks = notion.database("tasks-db", {
|
|
19
|
+
dataSourceResourceId: "tasks-source",
|
|
20
|
+
name: "Tasks",
|
|
21
|
+
schema: { Name: { resourceId: "task-name", type: "title" } },
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
await withMetadataCapabilityKey("board", async () => {
|
|
25
|
+
const board = customBlock({
|
|
26
|
+
path: "./blocks/board",
|
|
27
|
+
dataSources: { tasks },
|
|
28
|
+
});
|
|
29
|
+
tasks.addCustomView({
|
|
30
|
+
resourceId: "tasks-board-view",
|
|
31
|
+
name: "Board",
|
|
32
|
+
customBlock: board,
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
expect(finishMetadataRecording(recorder).intents.at(-1)).toEqual({
|
|
37
|
+
type: "view",
|
|
38
|
+
databaseResourceId: "tasks-db",
|
|
39
|
+
view: {
|
|
40
|
+
type: "custom",
|
|
41
|
+
resourceId: "tasks-board-view",
|
|
42
|
+
name: "Board",
|
|
43
|
+
dataSourceResourceId: "tasks-source",
|
|
44
|
+
customBlockKey: "board",
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it("requires an explicit bound source when a block binds multiple database sources", async () => {
|
|
50
|
+
const recorder = startMetadataRecording();
|
|
51
|
+
const tasks = notion.database("tasks-db", {
|
|
52
|
+
name: "Tasks",
|
|
53
|
+
datasources: {
|
|
54
|
+
Active: {
|
|
55
|
+
resourceId: "active-source",
|
|
56
|
+
schema: { Name: { resourceId: "active-name", type: "title" } },
|
|
57
|
+
},
|
|
58
|
+
Archive: {
|
|
59
|
+
resourceId: "archive-source",
|
|
60
|
+
schema: { Name: { resourceId: "archive-name", type: "title" } },
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
const projects = notion.database("projects-db", {
|
|
65
|
+
dataSourceResourceId: "projects-source",
|
|
66
|
+
name: "Projects",
|
|
67
|
+
schema: { Name: { resourceId: "project-name", type: "title" } },
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
await withMetadataCapabilityKey("board", async () => {
|
|
71
|
+
const board = customBlock({
|
|
72
|
+
path: "./blocks/board",
|
|
73
|
+
dataSources: {
|
|
74
|
+
active: tasks.datasources.Active,
|
|
75
|
+
archive: tasks.datasources.Archive,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
expect(() =>
|
|
79
|
+
tasks.addCustomView({
|
|
80
|
+
resourceId: "ambiguous-board-view",
|
|
81
|
+
customBlock: board,
|
|
82
|
+
}),
|
|
83
|
+
).toThrow("must bind exactly one data source");
|
|
84
|
+
tasks.addCustomView({
|
|
85
|
+
resourceId: "active-board-view",
|
|
86
|
+
customBlock: board,
|
|
87
|
+
dataSource: tasks.datasources.Active,
|
|
88
|
+
});
|
|
89
|
+
expect(() =>
|
|
90
|
+
tasks.addCustomView({
|
|
91
|
+
resourceId: "foreign-board-view",
|
|
92
|
+
customBlock: board,
|
|
93
|
+
dataSource: projects.dataSource,
|
|
94
|
+
}),
|
|
95
|
+
).toThrow('dataSource must belong to database "tasks-db"');
|
|
96
|
+
const activeOnlyBoard = customBlock({
|
|
97
|
+
path: "./blocks/active-board",
|
|
98
|
+
dataSources: { active: tasks.datasources.Active },
|
|
99
|
+
});
|
|
100
|
+
expect(() =>
|
|
101
|
+
tasks.addCustomView({
|
|
102
|
+
resourceId: "unbound-board-view",
|
|
103
|
+
customBlock: activeOnlyBoard,
|
|
104
|
+
dataSource: tasks.datasources.Archive,
|
|
105
|
+
}),
|
|
106
|
+
).toThrow('dataSource must be bound by custom block "board"');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
expect(finishMetadataRecording(recorder).intents.at(-1)).toEqual(
|
|
110
|
+
expect.objectContaining({
|
|
111
|
+
view: expect.objectContaining({ dataSourceResourceId: "active-source" }),
|
|
112
|
+
}),
|
|
113
|
+
);
|
|
114
|
+
});
|
|
11
115
|
it("records a single-source page layout on the data source", () => {
|
|
12
116
|
const recorder = startMetadataRecording();
|
|
13
117
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Database } from "../database.js";
|
|
2
|
+
import type { CustomBlockHandle } from "../custom-block.js";
|
|
2
3
|
import {
|
|
3
4
|
APPS_WORKSPACE_RESOURCE_ID,
|
|
4
5
|
type DatabaseIntent,
|
|
@@ -11,7 +12,7 @@ import {
|
|
|
11
12
|
type ResourceId,
|
|
12
13
|
} from "./intents.js";
|
|
13
14
|
import { createPage, type ChildPageArgs, type PageHandle } from "./page.js";
|
|
14
|
-
import { recordIntent } from "./recorder.js";
|
|
15
|
+
import { isMetadataRecording, recordIntent } from "./recorder.js";
|
|
15
16
|
import { assertParent, assertUserResourceId } from "./resource.js";
|
|
16
17
|
import { createAppsDatabase, type AppsSchemaForSchema } from "./schema.js";
|
|
17
18
|
import type { ViewSchema } from "./views.js";
|
|
@@ -132,6 +133,15 @@ type DatabaseHandleBase = {
|
|
|
132
133
|
readonly resourceType: "database";
|
|
133
134
|
readonly resourceId: string;
|
|
134
135
|
addView: (view: ViewSchema) => void;
|
|
136
|
+
addCustomView: (view: AddCustomViewArgs) => void;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export type AddCustomViewArgs = {
|
|
140
|
+
resourceId: ResourceId;
|
|
141
|
+
name?: string;
|
|
142
|
+
icon?: Extract<NotionAsCodeIcon, { type: "notion_icon" }>;
|
|
143
|
+
customBlock: CustomBlockHandle;
|
|
144
|
+
dataSource?: DataSourceHandle;
|
|
135
145
|
};
|
|
136
146
|
|
|
137
147
|
/** Map each authoring source key to a handle backed by that source's own schema. */
|
|
@@ -278,6 +288,7 @@ function buildDatabaseHandle(
|
|
|
278
288
|
resourceId: databaseResourceId,
|
|
279
289
|
dataSource,
|
|
280
290
|
addView: handle.addView,
|
|
291
|
+
addCustomView: handle.addCustomView,
|
|
281
292
|
};
|
|
282
293
|
}
|
|
283
294
|
|
|
@@ -416,9 +427,74 @@ function createDatabase(
|
|
|
416
427
|
addView(view) {
|
|
417
428
|
recordIntent({ type: "view", databaseResourceId: intent.resourceId, view });
|
|
418
429
|
},
|
|
430
|
+
addCustomView(view) {
|
|
431
|
+
recordCustomView(intent.resourceId, view, handles);
|
|
432
|
+
},
|
|
419
433
|
};
|
|
420
434
|
}
|
|
421
435
|
|
|
436
|
+
function recordCustomView(
|
|
437
|
+
databaseResourceId: ResourceId,
|
|
438
|
+
view: AddCustomViewArgs,
|
|
439
|
+
handles: Readonly<Record<string, DataSourceHandle>>,
|
|
440
|
+
): void {
|
|
441
|
+
assertUserResourceId(view.resourceId);
|
|
442
|
+
const customBlockKey = view.customBlock.key;
|
|
443
|
+
if (typeof customBlockKey !== "string" || customBlockKey.trim() === "") {
|
|
444
|
+
if (!isMetadataRecording()) {
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
throw new Error(
|
|
448
|
+
"addCustomView must be called from the custom block capability file so its key is available during build",
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
const dataSources = Object.values(handles);
|
|
453
|
+
const boundDataSourceIds = new Set(
|
|
454
|
+
Object.values(view.customBlock.config.defaultBindings ?? {}).map(
|
|
455
|
+
(binding) => binding.dataSourceResourceId,
|
|
456
|
+
),
|
|
457
|
+
);
|
|
458
|
+
let dataSourceResourceId: string;
|
|
459
|
+
if (view.dataSource !== undefined) {
|
|
460
|
+
if (!dataSources.includes(view.dataSource)) {
|
|
461
|
+
throw new Error(
|
|
462
|
+
`Custom view "${view.resourceId}" dataSource must belong to database "${databaseResourceId}"`,
|
|
463
|
+
);
|
|
464
|
+
}
|
|
465
|
+
if (!boundDataSourceIds.has(view.dataSource.resourceId)) {
|
|
466
|
+
throw new Error(
|
|
467
|
+
`Custom view "${view.resourceId}" dataSource must be bound by custom block "${customBlockKey}"`,
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
dataSourceResourceId = view.dataSource.resourceId;
|
|
471
|
+
} else {
|
|
472
|
+
const matchingSources = dataSources.filter((source) =>
|
|
473
|
+
boundDataSourceIds.has(source.resourceId),
|
|
474
|
+
);
|
|
475
|
+
const matchingSource = matchingSources[0];
|
|
476
|
+
if (matchingSources.length !== 1 || matchingSource === undefined) {
|
|
477
|
+
throw new Error(
|
|
478
|
+
`Custom view "${view.resourceId}" must bind exactly one data source from database "${databaseResourceId}" or specify dataSource`,
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
dataSourceResourceId = matchingSource.resourceId;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
recordIntent({
|
|
485
|
+
type: "view",
|
|
486
|
+
databaseResourceId,
|
|
487
|
+
view: {
|
|
488
|
+
type: "custom",
|
|
489
|
+
resourceId: view.resourceId,
|
|
490
|
+
...(view.name === undefined ? {} : { name: view.name }),
|
|
491
|
+
...(view.icon === undefined ? {} : { icon: view.icon }),
|
|
492
|
+
dataSourceResourceId,
|
|
493
|
+
customBlockKey,
|
|
494
|
+
},
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
|
|
422
498
|
/** Create a data-source handle backed by the Apps database used by syncs. */
|
|
423
499
|
function createDataSourceHandle(
|
|
424
500
|
dataSource: DataSourceDefinition,
|
|
@@ -55,6 +55,7 @@ export type {
|
|
|
55
55
|
YearlyRecurrenceSchedule,
|
|
56
56
|
} from "./custom-agent.js";
|
|
57
57
|
export type {
|
|
58
|
+
AddCustomViewArgs,
|
|
58
59
|
ChildDatabaseArgs,
|
|
59
60
|
ChildDatabaseFactory,
|
|
60
61
|
ChildMultiSourceDatabaseArgs,
|
|
@@ -92,6 +93,7 @@ export type {
|
|
|
92
93
|
CoverAspectFormat,
|
|
93
94
|
CoverFormat,
|
|
94
95
|
CoverSizeFormat,
|
|
96
|
+
CustomViewSchema,
|
|
95
97
|
DatabaseViewSortDirection,
|
|
96
98
|
DateFilterMode,
|
|
97
99
|
DateGroupByFormat,
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
|
|
3
|
+
import { notion } from "./index.js";
|
|
4
|
+
import { createProvisioningArtifact } from "./provisioning.js";
|
|
5
|
+
import { finishMetadataRecording, startMetadataRecording } from "./recorder.js";
|
|
6
|
+
import type { CustomViewSchema } from "./views.js";
|
|
7
|
+
|
|
8
|
+
const customView: CustomViewSchema = {
|
|
9
|
+
resourceId: "tasks-board-view",
|
|
10
|
+
dataSourceResourceId: "tasks-source",
|
|
11
|
+
type: "custom",
|
|
12
|
+
customBlockKey: "board",
|
|
13
|
+
};
|
|
14
|
+
const databaseArgs = {
|
|
15
|
+
name: "Tasks",
|
|
16
|
+
dataSourceResourceId: "tasks-source",
|
|
17
|
+
schema: { Name: { resourceId: "task-name", type: "title" } },
|
|
18
|
+
} as const;
|
|
19
|
+
|
|
20
|
+
describe.each([
|
|
21
|
+
{
|
|
22
|
+
name: "standalone views",
|
|
23
|
+
declare: (view: CustomViewSchema) =>
|
|
24
|
+
notion.view({ ...view, databaseResourceId: "tasks-db" }),
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "database views",
|
|
28
|
+
declare: (view: CustomViewSchema) =>
|
|
29
|
+
notion.database("tasks-db", { ...databaseArgs, views: [view] }),
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: "addView",
|
|
33
|
+
declare: (view: CustomViewSchema) =>
|
|
34
|
+
notion.database("tasks-db", databaseArgs).addView(view),
|
|
35
|
+
},
|
|
36
|
+
])("provisioning $name", ({ declare }) => {
|
|
37
|
+
it.each([
|
|
38
|
+
["sorts", []],
|
|
39
|
+
["filters", []],
|
|
40
|
+
["properties", []],
|
|
41
|
+
["showPageIcon", true],
|
|
42
|
+
["defaultTemplate", "template"],
|
|
43
|
+
] as const)("rejects %s on custom views when creating the artifact", (field, value) => {
|
|
44
|
+
const recorder = startMetadataRecording();
|
|
45
|
+
// Extra fields can arrive from JavaScript callers despite the TypeScript contract.
|
|
46
|
+
declare({ ...customView, [field]: value });
|
|
47
|
+
const { intents } = finishMetadataRecording(recorder);
|
|
48
|
+
|
|
49
|
+
expect(() => createProvisioningArtifact(intents)).toThrow(
|
|
50
|
+
`Custom views do not support ${field}`,
|
|
51
|
+
);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("rejects a blank custom block key when creating the artifact", () => {
|
|
55
|
+
const recorder = startMetadataRecording();
|
|
56
|
+
declare({ ...customView, customBlockKey: " " });
|
|
57
|
+
const { intents } = finishMetadataRecording(recorder);
|
|
58
|
+
|
|
59
|
+
expect(() => createProvisioningArtifact(intents)).toThrow("non-empty customBlockKey");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("preserves the custom block key for server-side capability resolution", () => {
|
|
63
|
+
const recorder = startMetadataRecording();
|
|
64
|
+
declare(customView);
|
|
65
|
+
const { intents } = finishMetadataRecording(recorder);
|
|
66
|
+
|
|
67
|
+
expect(createProvisioningArtifact(intents).intents).toEqual(intents);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { InfraAsCodeIntent } from "./intents.js";
|
|
2
|
+
import type { ViewSchema } from "./views.js";
|
|
2
3
|
|
|
3
4
|
export const APPS_PROVISIONING_SCHEMA = "notion:apps-provisioning:v1";
|
|
4
5
|
|
|
@@ -24,6 +25,13 @@ export function createProvisioningArtifact(
|
|
|
24
25
|
): ProvisioningArtifact {
|
|
25
26
|
const provisioningIntents: ProvisioningIntent[] = [];
|
|
26
27
|
for (const intent of intents) {
|
|
28
|
+
if (intent.type === "view") {
|
|
29
|
+
validateCustomView(intent.view);
|
|
30
|
+
} else if (intent.type === "database") {
|
|
31
|
+
for (const view of intent.views ?? []) {
|
|
32
|
+
validateCustomView(view);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
27
35
|
if (intent.type === "teamspace") {
|
|
28
36
|
const { parent: _parent, ...teamspace } = intent;
|
|
29
37
|
provisioningIntents.push(teamspace);
|
|
@@ -48,3 +56,22 @@ export function isRecordedProvisioning(value: unknown): value is RecordedProvisi
|
|
|
48
56
|
Array.isArray(value.intents)
|
|
49
57
|
);
|
|
50
58
|
}
|
|
59
|
+
|
|
60
|
+
function validateCustomView(view: ViewSchema): void {
|
|
61
|
+
if (view.type === "custom") {
|
|
62
|
+
if (typeof view.customBlockKey !== "string" || view.customBlockKey.trim() === "") {
|
|
63
|
+
throw new Error("Custom views require a non-empty customBlockKey");
|
|
64
|
+
}
|
|
65
|
+
for (const field of [
|
|
66
|
+
"sorts",
|
|
67
|
+
"filters",
|
|
68
|
+
"properties",
|
|
69
|
+
"showPageIcon",
|
|
70
|
+
"defaultTemplate",
|
|
71
|
+
] as const) {
|
|
72
|
+
if (field in view) {
|
|
73
|
+
throw new Error(`Custom views do not support ${field}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -3,11 +3,13 @@ import type { InfraAsCodeIntent } from "./intents.js";
|
|
|
3
3
|
import type { RecordedProvisioning } from "./provisioning.js";
|
|
4
4
|
|
|
5
5
|
let activeRecorder: RecordedProvisioning | undefined;
|
|
6
|
+
let currentCapabilityKey: string | undefined;
|
|
6
7
|
|
|
7
8
|
/** Start collecting declarations from the metadata bundle. */
|
|
8
9
|
export function startMetadataRecording(): RecordedProvisioning {
|
|
9
10
|
const recorder: RecordedProvisioning = { intents: [] };
|
|
10
11
|
activeRecorder = recorder;
|
|
12
|
+
currentCapabilityKey = undefined;
|
|
11
13
|
return recorder;
|
|
12
14
|
}
|
|
13
15
|
|
|
@@ -17,6 +19,7 @@ export function finishMetadataRecording(recorder: RecordedProvisioning): Recorde
|
|
|
17
19
|
throw new Error("Notion-as-Code metadata recorder was replaced before build completed");
|
|
18
20
|
}
|
|
19
21
|
activeRecorder = undefined;
|
|
22
|
+
currentCapabilityKey = undefined;
|
|
20
23
|
return recorder;
|
|
21
24
|
}
|
|
22
25
|
|
|
@@ -24,3 +27,27 @@ export function finishMetadataRecording(recorder: RecordedProvisioning): Recorde
|
|
|
24
27
|
export function recordIntent(intent: InfraAsCodeIntent): void {
|
|
25
28
|
activeRecorder?.intents.push(intent);
|
|
26
29
|
}
|
|
30
|
+
|
|
31
|
+
/** Evaluate one discovered capability with its build-time identity available to declarations. */
|
|
32
|
+
export async function withMetadataCapabilityKey<T>(
|
|
33
|
+
capabilityKey: string | undefined,
|
|
34
|
+
evaluate: () => Promise<T>,
|
|
35
|
+
): Promise<T> {
|
|
36
|
+
const previousCapabilityKey = currentCapabilityKey;
|
|
37
|
+
currentCapabilityKey = capabilityKey;
|
|
38
|
+
try {
|
|
39
|
+
return await evaluate();
|
|
40
|
+
} finally {
|
|
41
|
+
currentCapabilityKey = previousCapabilityKey;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Return the capability key only while a metadata bundle is recording. */
|
|
46
|
+
export function getCurrentMetadataCapabilityKey(): string | undefined {
|
|
47
|
+
return activeRecorder === undefined ? undefined : currentCapabilityKey;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Whether declarations are currently being collected by the build metadata bundle. */
|
|
51
|
+
export function isMetadataRecording(): boolean {
|
|
52
|
+
return activeRecorder !== undefined;
|
|
53
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { expectTypeOf, it } from "vitest";
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
|
+
CustomViewSchema,
|
|
4
5
|
DatabaseArgs,
|
|
5
6
|
DatabaseHandle,
|
|
6
7
|
DatePropertyFilter,
|
|
@@ -8,6 +9,29 @@ import type {
|
|
|
8
9
|
ViewSchema,
|
|
9
10
|
} from "./index.js";
|
|
10
11
|
|
|
12
|
+
it("keeps custom views free of standard view query and property configuration", () => {
|
|
13
|
+
expectTypeOf<{
|
|
14
|
+
resourceId: "custom-view";
|
|
15
|
+
dataSourceResourceId: "source";
|
|
16
|
+
type: "custom";
|
|
17
|
+
customBlockKey: "board";
|
|
18
|
+
}>().toExtend<CustomViewSchema>();
|
|
19
|
+
expectTypeOf<{
|
|
20
|
+
resourceId: "custom-view";
|
|
21
|
+
dataSourceResourceId: "source";
|
|
22
|
+
type: "custom";
|
|
23
|
+
customBlockKey: "board";
|
|
24
|
+
sorts: [];
|
|
25
|
+
}>().not.toExtend<ViewSchema>();
|
|
26
|
+
expectTypeOf<{
|
|
27
|
+
resourceId: "custom-view";
|
|
28
|
+
dataSourceResourceId: "source";
|
|
29
|
+
type: "custom";
|
|
30
|
+
customBlockKey: "board";
|
|
31
|
+
properties: [];
|
|
32
|
+
}>().not.toExtend<ViewSchema>();
|
|
33
|
+
});
|
|
34
|
+
|
|
11
35
|
it("requires date properties for calendar and timeline views at both entrypoints", () => {
|
|
12
36
|
type MissingDateProperty = {
|
|
13
37
|
resourceId: "view";
|
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import type { NotionAsCodeIcon, NotionAsCodeProperty, ResourceId } from "./intents.js";
|
|
2
2
|
|
|
3
3
|
// Ported from notion-next/src/server/helpers/infraAsCode/types.ts.
|
|
4
|
-
export type ViewType =
|
|
4
|
+
export type ViewType =
|
|
5
|
+
| "table"
|
|
6
|
+
| "board"
|
|
7
|
+
| "calendar"
|
|
8
|
+
| "list"
|
|
9
|
+
| "gallery"
|
|
10
|
+
| "feed"
|
|
11
|
+
| "timeline"
|
|
12
|
+
| "custom";
|
|
5
13
|
|
|
6
14
|
export type PropertyVisibility = "show" | "hide" | "hide_if_empty";
|
|
7
15
|
|
|
@@ -563,6 +571,19 @@ export type TimelineViewSchema = BaseViewSchema & {
|
|
|
563
571
|
showTable?: boolean;
|
|
564
572
|
};
|
|
565
573
|
|
|
574
|
+
export type CustomViewSchema = Omit<
|
|
575
|
+
BaseViewSchema,
|
|
576
|
+
"type" | "sorts" | "filters" | "showPageIcon" | "defaultTemplate"
|
|
577
|
+
> & {
|
|
578
|
+
type: "custom";
|
|
579
|
+
customBlockKey: string;
|
|
580
|
+
sorts?: never;
|
|
581
|
+
filters?: never;
|
|
582
|
+
properties?: never;
|
|
583
|
+
showPageIcon?: never;
|
|
584
|
+
defaultTemplate?: never;
|
|
585
|
+
};
|
|
586
|
+
|
|
566
587
|
export type ViewSchema =
|
|
567
588
|
| TableViewSchema
|
|
568
589
|
| BoardViewSchema
|
|
@@ -570,4 +591,5 @@ export type ViewSchema =
|
|
|
570
591
|
| ListViewSchema
|
|
571
592
|
| GalleryViewSchema
|
|
572
593
|
| FeedViewSchema
|
|
573
|
-
| TimelineViewSchema
|
|
594
|
+
| TimelineViewSchema
|
|
595
|
+
| CustomViewSchema;
|