@notionhq/apps 0.0.30 → 0.0.32

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.
Files changed (53) hide show
  1. package/dist/cli/codegen.d.ts.map +1 -1
  2. package/dist/cli/codegen.js +6 -1
  3. package/dist/custom-block.d.ts +9 -2
  4. package/dist/custom-block.d.ts.map +1 -1
  5. package/dist/custom-block.js +3 -0
  6. package/dist/index.d.ts +2 -2
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/notion-as-code/custom-agent.d.ts +6 -5
  9. package/dist/notion-as-code/custom-agent.d.ts.map +1 -1
  10. package/dist/notion-as-code/custom-agent.js +15 -4
  11. package/dist/notion-as-code/database.d.ts +11 -0
  12. package/dist/notion-as-code/database.d.ts.map +1 -1
  13. package/dist/notion-as-code/database.js +61 -2
  14. package/dist/notion-as-code/index.d.ts +3 -3
  15. package/dist/notion-as-code/index.d.ts.map +1 -1
  16. package/dist/notion-as-code/intents.d.ts +7 -1
  17. package/dist/notion-as-code/intents.d.ts.map +1 -1
  18. package/dist/notion-as-code/provisioning.d.ts.map +1 -1
  19. package/dist/notion-as-code/provisioning.js +25 -0
  20. package/dist/notion-as-code/provisioning.test.d.ts +2 -0
  21. package/dist/notion-as-code/provisioning.test.d.ts.map +1 -0
  22. package/dist/notion-as-code/recorder.d.ts +6 -0
  23. package/dist/notion-as-code/recorder.d.ts.map +1 -1
  24. package/dist/notion-as-code/recorder.js +22 -1
  25. package/dist/notion-as-code/views.d.ts +11 -2
  26. package/dist/notion-as-code/views.d.ts.map +1 -1
  27. package/dist/workflow-access.d.ts +8 -3
  28. package/dist/workflow-access.d.ts.map +1 -1
  29. package/dist/workflow-access.js +33 -34
  30. package/dist/workflow.d.ts +1 -1
  31. package/dist/workflow.d.ts.map +1 -1
  32. package/package.json +1 -1
  33. package/skills/notion-as-code/SKILL.md +39 -8
  34. package/src/cli/build.test.ts +11 -0
  35. package/src/cli/codegen.test.ts +26 -1
  36. package/src/cli/codegen.ts +10 -2
  37. package/src/custom-block.test.ts +14 -0
  38. package/src/custom-block.ts +10 -0
  39. package/src/index.ts +2 -2
  40. package/src/notion-as-code/custom-agent.test.ts +62 -3
  41. package/src/notion-as-code/custom-agent.ts +19 -10
  42. package/src/notion-as-code/database.test.ts +105 -1
  43. package/src/notion-as-code/database.ts +77 -1
  44. package/src/notion-as-code/index.ts +2 -1
  45. package/src/notion-as-code/intents.ts +4 -1
  46. package/src/notion-as-code/notion-as-code-types.test.ts +21 -11
  47. package/src/notion-as-code/provisioning.test.ts +69 -0
  48. package/src/notion-as-code/provisioning.ts +27 -0
  49. package/src/notion-as-code/recorder.ts +27 -0
  50. package/src/notion-as-code/views-types.test.ts +24 -0
  51. package/src/notion-as-code/views.ts +24 -2
  52. package/src/workflow-access.ts +56 -51
  53. package/src/workflow.ts +1 -1
@@ -7,13 +7,13 @@ type WorkflowAccessContentResource = Exclude<WorkflowAccessResource, CustomAgent
7
7
  /** Resource kinds accepted by workflow access declarations. */
8
8
  export type WorkflowAccessResourceType = WorkflowAccessResource["resourceType"];
9
9
  /** Levels accepted by pages, databases, and data sources. */
10
- export type WorkflowAccessResourceLevel = "view" | "comment" | "edit" | "fullAccess";
10
+ export type ResourceAccessLevel = "view" | "comment" | "edit" | "fullAccess";
11
11
  /** The only level accepted by a custom agent. */
12
12
  export type WorkflowAccessAgentLevel = "call";
13
13
  /** Every level accepted by at least one workflow access resource. */
14
- export type WorkflowAccessLevel = WorkflowAccessResourceLevel | WorkflowAccessAgentLevel;
14
+ export type WorkflowAccessLevel = ResourceAccessLevel | WorkflowAccessAgentLevel;
15
15
  /** The level set accepted by a particular resource kind. */
16
- export type WorkflowAccessLevelFor<TType extends WorkflowAccessResourceType> = TType extends "customAgent" ? WorkflowAccessAgentLevel : WorkflowAccessResourceLevel;
16
+ export type WorkflowAccessLevelFor<TType extends WorkflowAccessResourceType> = TType extends "customAgent" ? WorkflowAccessAgentLevel : ResourceAccessLevel;
17
17
  type AccessResourceFor<TType extends WorkflowAccessResourceType> = Extract<WorkflowAccessResource, {
18
18
  resourceType: TType;
19
19
  }>;
@@ -86,6 +86,11 @@ declare function call(resource: CustomAgentHandle): Readonly<{
86
86
  * grant or change the workflow's existing Notion-module permissions.
87
87
  */
88
88
  export declare function normalizeWorkflowAccess(declarations: WorkflowAccessDeclarations | undefined): WorkflowAccessRequirements;
89
+ /**
90
+ * Check one access entry and return its resource type, ID, and level.
91
+ * Workflows check the entry's alias separately; custom-agent grants have no alias.
92
+ */
93
+ export declare function normalizeAccessDeclaration(declaration: unknown, label: string): WorkflowAccessRequirement;
89
94
  /**
90
95
  * Resolve trusted per-invocation NaC bindings into the minimal context value.
91
96
  * This exposes only declared aliases and does not determine Notion API
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-access.d.ts","sourceRoot":"","sources":["../src/workflow-access.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflow-access.d.ts","sourceRoot":"","sources":["../src/workflow-access.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1E,OAAO,KAAK,EACX,gBAAgB,EAChB,cAAc,EACd,0BAA0B,EAC1B,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,2EAA2E;AAC3E,MAAM,MAAM,sBAAsB,GAC/B,UAAU,GACV,cAAc,GACd,0BAA0B,GAC1B,gBAAgB,GAChB,iBAAiB,CAAC;AAErB,KAAK,6BAA6B,GAAG,OAAO,CAAC,sBAAsB,EAAE,iBAAiB,CAAC,CAAC;AAExF,+DAA+D;AAC/D,MAAM,MAAM,0BAA0B,GAAG,sBAAsB,CAAC,cAAc,CAAC,CAAC;AAEhF,6DAA6D;AAC7D,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,CAAC;AAE7E,iDAAiD;AACjD,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAE9C,qEAAqE;AACrE,MAAM,MAAM,mBAAmB,GAAG,mBAAmB,GAAG,wBAAwB,CAAC;AAEjF,4DAA4D;AAC5D,MAAM,MAAM,sBAAsB,CAAC,KAAK,SAAS,0BAA0B,IAC1E,KAAK,SAAS,aAAa,GAAG,wBAAwB,GAAG,mBAAmB,CAAC;AAE9E,KAAK,iBAAiB,CAAC,KAAK,SAAS,0BAA0B,IAAI,OAAO,CACzE,sBAAsB,EACtB;IAAE,YAAY,EAAE,KAAK,CAAA;CAAE,CACvB,CAAC;AAEF,iFAAiF;AACjF,MAAM,MAAM,yBAAyB,GAAG;KACtC,KAAK,IAAI,0BAA0B,GAAG;QACtC,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;QAC5C,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC,KAAK,CAAC,CAAC;KAC9C;CACD,CAAC,0BAA0B,CAAC,CAAC;AAE9B,iFAAiF;AACjF,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAC;AAE7F,qFAAqF;AACrF,MAAM,MAAM,yBAAyB,GAAG;KACtC,KAAK,IAAI,0BAA0B,GAAG;QACtC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC;QACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC,KAAK,CAAC,CAAC;KAC9C;CACD,CAAC,0BAA0B,CAAC,CAAC;AAE9B,mEAAmE;AACnE,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC,CAAC;AAE7F,8DAA8D;AAC9D,MAAM,MAAM,mBAAmB,CAC9B,KAAK,SAAS,0BAA0B,GAAG,0BAA0B,IAClE,QAAQ,CAAC;IACZ,IAAI,EAAE,KAAK,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;CACX,CAAC,CAAC;AAEH,4DAA4D;AAC5D,MAAM,MAAM,cAAc,CACzB,OAAO,SAAS,0BAA0B,GAAG,0BAA0B,IACpE,QAAQ,CAAC;KACX,IAAI,IAAI,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS;QAC9C,QAAQ,CAAC,QAAQ,EAAE;YAAE,QAAQ,CAAC,YAAY,EAAE,MAAM,KAAK,CAAA;SAAE,CAAC;KAC1D,GACE,KAAK,SAAS,0BAA0B,GACvC,mBAAmB,CAAC,KAAK,CAAC,GAC1B,KAAK,GACN,KAAK;CACR,CAAC,CAAC;AAEH,mFAAmF;AACnF,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAEnF,gFAAgF;AAChF,eAAO,MAAM,MAAM;;;;;;CAMlB,CAAC;AAEF,iBAAS,IAAI,CAAC,SAAS,SAAS,6BAA6B,EAC5D,QAAQ,EAAE,SAAS,GACjB,QAAQ,CAAC;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAElD;AAED,iBAAS,OAAO,CAAC,SAAS,SAAS,6BAA6B,EAC/D,QAAQ,EAAE,SAAS,GACjB,QAAQ,CAAC;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC,CAErD;AAED,iBAAS,IAAI,CAAC,SAAS,SAAS,6BAA6B,EAC5D,QAAQ,EAAE,SAAS,GACjB,QAAQ,CAAC;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAElD;AAED,iBAAS,UAAU,CAAC,SAAS,SAAS,6BAA6B,EAClE,QAAQ,EAAE,SAAS,GACjB,QAAQ,CAAC;IAAE,QAAQ,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC,CAExD;AAED,iBAAS,IAAI,CACZ,QAAQ,EAAE,iBAAiB,GACzB,QAAQ,CAAC;IAAE,QAAQ,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAE1D;AAWD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACtC,YAAY,EAAE,0BAA0B,GAAG,SAAS,GAClD,0BAA0B,CAuB5B;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACzC,WAAW,EAAE,OAAO,EACpB,KAAK,EAAE,MAAM,GACX,yBAAyB,CA2C3B;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,SAAS,0BAA0B,EAC/E,YAAY,EAAE,0BAA0B,GAAG,SAAS,GAClD,cAAc,CAAC,OAAO,CAAC,CAAC"}
@@ -43,43 +43,41 @@ function normalizeWorkflowAccess(declarations) {
43
43
  if (!ACCESS_ALIAS_PATTERN.test(alias) || RESERVED_ACCESS_ALIASES.has(alias)) {
44
44
  throw new Error(`Invalid workflow access alias: ${alias}`);
45
45
  }
46
- const declaration = source[alias];
47
- if (!isRecord(declaration) || !Object.hasOwn(declaration, "resource") || !Object.hasOwn(declaration, "level")) {
48
- throw new Error(`Workflow access "${alias}" must declare a resource and level.`);
46
+ normalized[alias] = normalizeAccessDeclaration(source[alias], `Workflow access "${alias}"`);
47
+ }
48
+ return Object.freeze(normalized);
49
+ }
50
+ function normalizeAccessDeclaration(declaration, label) {
51
+ if (!isRecord(declaration) || !Object.hasOwn(declaration, "resource") || !Object.hasOwn(declaration, "level")) {
52
+ throw new Error(`${label} must declare a resource and level.`);
53
+ }
54
+ const resource = declaration.resource;
55
+ if (!isRecord(resource) || !Object.hasOwn(resource, "resourceType") || !Object.hasOwn(resource, "resourceId") || typeof resource.resourceId !== "string" || resource.resourceId.length === 0 || !isWorkflowAccessResourceType(resource.resourceType)) {
56
+ throw new Error(`${label} must reference a supported NaC resource handle.`);
57
+ }
58
+ let requirement;
59
+ if (resource.resourceType === "customAgent") {
60
+ if (declaration.level !== "call") {
61
+ throw new Error(`${label} custom agents only support level "call".`);
49
62
  }
50
- const resource = declaration.resource;
51
- if (!isRecord(resource) || !Object.hasOwn(resource, "resourceType") || !Object.hasOwn(resource, "resourceId") || typeof resource.resourceId !== "string" || resource.resourceId.length === 0 || !isWorkflowAccessResourceType(resource.resourceType)) {
63
+ requirement = {
64
+ type: resource.resourceType,
65
+ resourceId: resource.resourceId,
66
+ level: declaration.level
67
+ };
68
+ } else {
69
+ if (!isResourceAccessLevel(declaration.level)) {
52
70
  throw new Error(
53
- `Workflow access "${alias}" must reference a supported NaC resource handle.`
71
+ `${label} ${resource.resourceType} level must be view, comment, edit, or fullAccess.`
54
72
  );
55
73
  }
56
- let requirement;
57
- if (resource.resourceType === "customAgent") {
58
- if (declaration.level !== "call") {
59
- throw new Error(
60
- `Workflow access "${alias}" custom agents only support level "call".`
61
- );
62
- }
63
- requirement = {
64
- type: resource.resourceType,
65
- resourceId: resource.resourceId,
66
- level: declaration.level
67
- };
68
- } else {
69
- if (!isWorkflowAccessResourceLevel(declaration.level)) {
70
- throw new Error(
71
- `Workflow access "${alias}" ${resource.resourceType} level must be view, comment, edit, or fullAccess.`
72
- );
73
- }
74
- requirement = {
75
- type: resource.resourceType,
76
- resourceId: resource.resourceId,
77
- level: declaration.level
78
- };
79
- }
80
- normalized[alias] = Object.freeze(requirement);
74
+ requirement = {
75
+ type: resource.resourceType,
76
+ resourceId: resource.resourceId,
77
+ level: declaration.level
78
+ };
81
79
  }
82
- return Object.freeze(normalized);
80
+ return Object.freeze(requirement);
83
81
  }
84
82
  function hydrateWorkflowAccess(requirements) {
85
83
  const expected = requirements ?? {};
@@ -132,7 +130,7 @@ function hydrateWorkflowAccess(requirements) {
132
130
  function isWorkflowAccessResourceType(value) {
133
131
  return typeof value === "string" && Object.hasOwn(RESOURCE_TYPES, value);
134
132
  }
135
- function isWorkflowAccessResourceLevel(value) {
133
+ function isResourceAccessLevel(value) {
136
134
  return value === "view" || value === "comment" || value === "edit" || value === "fullAccess";
137
135
  }
138
136
  function isBinding(value) {
@@ -141,7 +139,7 @@ function isBinding(value) {
141
139
  if (keys.length !== 4 || !keys.includes("type") || !keys.includes("resourceId") || !keys.includes("level") || !keys.includes("id")) {
142
140
  return false;
143
141
  }
144
- return isWorkflowAccessResourceType(value.type) && typeof value.resourceId === "string" && value.resourceId.length > 0 && typeof value.level === "string" && (isWorkflowAccessResourceLevel(value.level) || value.level === "call") && typeof value.id === "string" && value.id.length > 0;
142
+ return isWorkflowAccessResourceType(value.type) && typeof value.resourceId === "string" && value.resourceId.length > 0 && typeof value.level === "string" && (isResourceAccessLevel(value.level) || value.level === "call") && typeof value.id === "string" && value.id.length > 0;
145
143
  }
146
144
  function assertPlainObject(value, message) {
147
145
  if (!isRecord(value)) throw new Error(message);
@@ -154,5 +152,6 @@ function isRecord(value) {
154
152
  export {
155
153
  access,
156
154
  hydrateWorkflowAccess,
155
+ normalizeAccessDeclaration,
157
156
  normalizeWorkflowAccess
158
157
  };
@@ -92,7 +92,7 @@ type WorkflowWaitResult = WorkflowWaitUntilResult | WorkflowWaitForInputResult;
92
92
  type WorkflowHandlerResult = {
93
93
  status: "success";
94
94
  } | WorkflowWaitResult;
95
- export type { WorkflowAccess, WorkflowAccessAgentLevel, WorkflowAccessBindings, WorkflowAccessDeclaration, WorkflowAccessDeclarations, WorkflowAccessLevel, WorkflowAccessLevelFor, WorkflowAccessResource, WorkflowAccessResourceLevel, WorkflowAccessResourceType, WorkflowAccessRequirement, WorkflowAccessRequirements, WorkflowAccessValue, } from "./workflow-access.js";
95
+ export type { WorkflowAccess, WorkflowAccessAgentLevel, WorkflowAccessBindings, WorkflowAccessDeclaration, WorkflowAccessDeclarations, WorkflowAccessLevel, WorkflowAccessLevelFor, WorkflowAccessResource, ResourceAccessLevel, WorkflowAccessResourceType, WorkflowAccessRequirement, WorkflowAccessRequirements, WorkflowAccessValue, } from "./workflow-access.js";
96
96
  export { access } from "./workflow-access.js";
97
97
  export type WorkflowEvent = WorkflowEventMap[keyof WorkflowEventMap];
98
98
  export type WorkflowEventForTrigger<T extends WorkflowTrigger> = WorkflowEventMap[T["type"]];
@@ -1 +1 @@
1
- {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"workflow.d.ts","sourceRoot":"","sources":["../src/workflow.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notionhq/apps",
3
- "version": "0.0.30",
3
+ "version": "0.0.32",
4
4
  "description": "An SDK for building workflow apps for Notion",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -85,7 +85,7 @@ 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.
@@ -121,6 +121,34 @@ const linkedIssues = database("project-issues-linked", {
121
121
  The table view above is typed by its `type: "table"` schema and links to the
122
122
  explicit `issues-source` resource ID.
123
123
 
124
+ Attach a declared custom block as a database view with `addCustomView`. The
125
+ custom block must be declared in `src/customBlocks/<key>.ts`. If its default
126
+ bindings match exactly one data source owned by the database, the SDK infers
127
+ that source. Otherwise pass one of the database's own data-source handles.
128
+
129
+ ```ts
130
+ import { customBlock, database } from "@notionhq/apps";
131
+
132
+ const tasks = database("tasks-db", {
133
+ dataSourceResourceId: "tasks-source",
134
+ name: "Tasks",
135
+ schema: { Name: { type: "title", resourceId: "task-name" } },
136
+ });
137
+ const board = customBlock({
138
+ path: "./blocks/board",
139
+ dataSources: { tasks },
140
+ });
141
+
142
+ tasks.addCustomView({
143
+ resourceId: "tasks-board-view",
144
+ name: "Board",
145
+ customBlock: board,
146
+ });
147
+ ```
148
+
149
+ Custom views do not accept standard view properties, sorts, or filters. Keep
150
+ the view resource ID and the custom-block filename stable across builds.
151
+
124
152
  Keep resource IDs stable across builds. They identify declarations, not live
125
153
  Notion UUIDs. Avoid the reserved `__notion_apps_` prefix. Explicit parents
126
154
  use `{ type: "resourceId", resourceId: parent.resourceId }`; child helpers set
@@ -153,10 +181,11 @@ Do not add every optional field by default. Decide on each field separately:
153
181
  exact model values in the installed declarations. Otherwise omit it and let
154
182
  Notion choose the model.
155
183
  - `access`: set only for declared pages or databases the agent must use. Grant
156
- the least-capable suitable role: `can_view` for reading, `can_comment` for
157
- comments, `can_edit_content` for editing content, or `full_access` only when
158
- broader access is required. Use the target handle's `resourceId`; this is
159
- separate from a workflow's `access.call(agent)` binding.
184
+ the least-capable suitable helper: `access.view(handle)` for reading,
185
+ `access.comment(handle)` for comments, `access.edit(handle)` for editing, or
186
+ `access.fullAccess(handle)` only when broader access is required. Pass a page
187
+ or database handle, not a resource ID or data-source handle. Custom-agent
188
+ declarations do not accept `access.call(agent)`.
160
189
  - `webAccess`: set `true` only when the agent must search the web. Set `false`
161
190
  when the declaration must explicitly disable web search. For a new agent,
162
191
  omission defaults to `false`; for an existing agent, omission preserves its
@@ -169,19 +198,21 @@ Do not add every optional field by default. Decide on each field separately:
169
198
  - `triggers`: set only when the agent should run automatically. Use
170
199
  `recurrence` for a schedule, `page_added` for new rows in a data source, and
171
200
  `property_updated` for selected property edits and/or page-content edits.
172
- Do not add a trigger merely because its data source also appears in `access`.
201
+ Do not add a trigger merely because its containing database also appears in `access`.
173
202
 
174
203
  For an existing agent, `access` is additive: each entry adds a grant or updates
175
204
  that resource's role, while unlisted grants remain unchanged. Omitting `access`
176
205
  and passing `access: []` both preserve existing grants. Reuse declared resource
177
- IDs and choose roles deliberately:
206
+ handles and choose levels deliberately:
178
207
 
179
208
  ```ts
209
+ import { access, customAgent } from "@notionhq/apps";
210
+
180
211
  customAgent({
181
212
  resourceId: "project-analyst",
182
213
  name: "Project analyst",
183
214
  instructions: "Summarize project status and identify blocked work.",
184
- access: [{ resourceId: projects.resourceId, role: "can_view" }],
215
+ access: [access.view(projects)],
185
216
  webAccess: true,
186
217
  });
187
218
  ```
@@ -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
 
@@ -49,6 +49,31 @@ describe("generateMetadataEntry", () => {
49
49
  },
50
50
  ]);
51
51
 
52
- expect(entry).toContain(`await import("../src/customBlocks/board.ts");`);
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
  });
@@ -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
- .map((capability) => `await import(${JSON.stringify(`../${capability.sourcePath}`)});`)
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();
@@ -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",
@@ -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";
@@ -18,7 +18,7 @@ export {
18
18
  type WorkflowAccessLevel,
19
19
  type WorkflowAccessLevelFor,
20
20
  type WorkflowAccessResource,
21
- type WorkflowAccessResourceLevel,
21
+ type ResourceAccessLevel,
22
22
  type WorkflowAccessResourceType,
23
23
  type WorkflowAccessRequirement,
24
24
  type WorkflowAccessRequirements,
@@ -1,10 +1,17 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
 
3
+ import { access } from "../workflow-access.js";
4
+
3
5
  import { notion } from "./index.js";
4
6
  import { finishMetadataRecording, startMetadataRecording } from "./recorder.js";
5
7
 
6
8
  describe("Notion-as-Code custom agent declarations", () => {
7
9
  it("records access, web, URL trust, and triggers", () => {
10
+ const tasks = notion.database("tasks-db", {
11
+ dataSourceResourceId: "tasks",
12
+ name: "Tasks",
13
+ schema: { Title: { resourceId: "title", type: "title" } },
14
+ });
8
15
  const recorder = startMetadataRecording();
9
16
 
10
17
  notion.customAgent({
@@ -12,7 +19,7 @@ describe("Notion-as-Code custom agent declarations", () => {
12
19
  name: "Triage agent",
13
20
  webAccess: true,
14
21
  trustedUrls: { type: "all" },
15
- access: [{ resourceId: "tasks", role: "can_edit_content" }],
22
+ access: [access.edit(tasks)],
16
23
  triggers: [
17
24
  {
18
25
  type: "recurrence",
@@ -42,7 +49,7 @@ describe("Notion-as-Code custom agent declarations", () => {
42
49
  name: "Triage agent",
43
50
  webAccess: true,
44
51
  trustedUrls: { type: "all" },
45
- access: [{ resourceId: "tasks", role: "can_edit_content" }],
52
+ access: [{ resourceId: "tasks-db", level: "edit" }],
46
53
  triggers: [
47
54
  {
48
55
  type: "recurrence",
@@ -88,8 +95,60 @@ describe("Notion-as-Code custom agent declarations", () => {
88
95
  notion.customAgent({
89
96
  resourceId: "triage-agent",
90
97
  name: "Triage agent",
91
- access: [{ resourceId: "__notion_apps_tasks", role: "can_view" }],
98
+ access: [
99
+ access.view({
100
+ ...notion.page({ resourceId: "tasks" }),
101
+ resourceId: "__notion_apps_tasks",
102
+ }),
103
+ ],
92
104
  }),
93
105
  ).toThrow("reserved");
94
106
  });
95
107
  });
108
+
109
+ it.each(["view", "comment", "edit", "fullAccess"] as const)(
110
+ "serializes page %s access using the workflow level",
111
+ (level) => {
112
+ const home = notion.page({ resourceId: "home" });
113
+ const recorder = startMetadataRecording();
114
+ notion.customAgent({ resourceId: "agent", name: "Agent", access: [access[level](home)] });
115
+ expect(finishMetadataRecording(recorder).intents).toEqual([
116
+ {
117
+ type: "custom_agent",
118
+ resourceId: "agent",
119
+ name: "Agent",
120
+ access: [{ resourceId: "home", level }],
121
+ },
122
+ ]);
123
+ },
124
+ );
125
+
126
+ it("rejects data source grants from untyped callers", () => {
127
+ const table = notion.database("table", {
128
+ dataSourceResourceId: "source",
129
+ name: "Table",
130
+ schema: { Title: { resourceId: "title", type: "title" } },
131
+ });
132
+ expect(() =>
133
+ Reflect.apply(notion.customAgent, undefined, [
134
+ {
135
+ resourceId: "agent",
136
+ name: "Agent",
137
+ access: [access.view(table.dataSource)],
138
+ },
139
+ ]),
140
+ ).toThrow("page or database handle");
141
+ });
142
+
143
+ it("rejects agent call grants from untyped callers", () => {
144
+ const agent = notion.customAgent({ resourceId: "target", name: "Target" });
145
+ expect(() =>
146
+ Reflect.apply(notion.customAgent, undefined, [
147
+ {
148
+ resourceId: "agent",
149
+ name: "Agent",
150
+ access: [access.call(agent)],
151
+ },
152
+ ]),
153
+ ).toThrow("page or database handle");
154
+ });
@@ -1,3 +1,4 @@
1
+ import { normalizeAccessDeclaration, type WorkflowAccessDeclaration } from "../workflow-access.js";
1
2
  import type { CustomAgentIntent, NotionAsCodeIcon, ResourceId } from "./intents.js";
2
3
  import { recordIntent } from "./recorder.js";
3
4
  import { assertUserResourceId } from "./resource.js";
@@ -107,13 +108,11 @@ export type CustomAgentTrigger =
107
108
  * These values map to Notion module permissions: full access, content editing,
108
109
  * commenting, and read-only.
109
110
  */
110
- export type CustomAgentAccessRole = "full_access" | "can_edit_content" | "can_comment" | "can_view";
111
-
112
111
  /** Grants a custom agent access to a page or database resource. */
113
- export type CustomAgentAccess = {
114
- resourceId: ResourceId;
115
- role: CustomAgentAccessRole;
116
- };
112
+ export type CustomAgentAccess = Extract<
113
+ WorkflowAccessDeclaration,
114
+ { readonly resource: { readonly resourceType: "page" | "database" } }
115
+ >;
117
116
 
118
117
  /**
119
118
  * URL trust settings for a custom agent.
@@ -163,9 +162,14 @@ export type CustomAgentHandle = {
163
162
  /** Declare a custom agent and validate every resource reference. */
164
163
  export function customAgent(args: CustomAgentArgs): CustomAgentHandle {
165
164
  assertUserResourceId(args.resourceId);
166
- for (const grant of args.access ?? []) {
167
- assertUserResourceId(grant.resourceId);
168
- }
165
+ const grants = args.access?.map((grant) => {
166
+ const requirement = normalizeAccessDeclaration(grant, "Custom agent access");
167
+ if (requirement.type !== "page" && requirement.type !== "database") {
168
+ throw new Error("Custom agent access requires a page or database handle.");
169
+ }
170
+ assertUserResourceId(requirement.resourceId);
171
+ return { resourceId: requirement.resourceId, level: requirement.level };
172
+ });
169
173
  for (const trigger of args.triggers ?? []) {
170
174
  assertUserResourceId(trigger.resourceId);
171
175
  if (trigger.type === "page_added" || trigger.type === "property_updated") {
@@ -177,7 +181,12 @@ export function customAgent(args: CustomAgentArgs): CustomAgentHandle {
177
181
  }
178
182
  }
179
183
  }
180
- recordIntent({ type: "custom_agent", ...args } satisfies {
184
+ const { access: _access, ...intent } = args;
185
+ recordIntent({
186
+ type: "custom_agent",
187
+ ...intent,
188
+ ...(grants === undefined ? {} : { access: grants }),
189
+ } satisfies {
181
190
  type: "custom_agent";
182
191
  } & CustomAgentIntent);
183
192
  return { resourceType: "customAgent", resourceId: args.resourceId };