@notionhq/apps 0.0.19 → 0.0.20

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/README.md CHANGED
@@ -23,8 +23,12 @@ Import the helpers your app uses:
23
23
 
24
24
  ```ts
25
25
  import { page, workflow } from "@notionhq/apps";
26
+ import { notion } from "@notionhq/apps/notion-as-code";
26
27
 
27
- const home = page({ resourceId: "home" });
28
+ const home = page({
29
+ resourceId: "home",
30
+ properties: { title: notion.text("App home") },
31
+ });
28
32
 
29
33
  export default workflow({
30
34
  name: "Follow up",
@@ -1,9 +1,10 @@
1
+ import type { TextValue } from "./page.js";
1
2
  /** Serialize Notion-as-Code date values for Apps property payloads. */
2
- export declare function date(startDate: string, endDate?: string): unknown[][];
3
+ export declare function date(startDate: string, endDate?: string): TextValue;
3
4
  /** Serialize Notion-as-Code datetime values for Apps property payloads. */
4
5
  export declare function datetime(value: {
5
6
  start: string;
6
7
  end?: string;
7
8
  timeZone?: string;
8
- }): unknown[][];
9
+ }): TextValue;
9
10
  //# sourceMappingURL=date.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/date.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,wBAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE,EAAE,CAWrE;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,EAAE,EAAE,CA6B/F"}
1
+ {"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/date.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,uEAAuE;AACvE,wBAAgB,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAWnE;AAED,2EAA2E;AAC3E,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CA6B7F"}
@@ -1,7 +1,7 @@
1
1
  import { customAgent } from "./custom-agent.js";
2
2
  import { database } from "./database.js";
3
3
  import { date, datetime } from "./date.js";
4
- import { page } from "./page.js";
4
+ import { page, type TextValue, type VerificationInput, type VerificationPropertyValue } from "./page.js";
5
5
  import { teamspace } from "./teamspace.js";
6
6
  import { view } from "./view.js";
7
7
  declare const notionAsCodeFacade: {
@@ -10,22 +10,19 @@ declare const notionAsCodeFacade: {
10
10
  page: typeof page;
11
11
  customAgent: typeof customAgent;
12
12
  view: typeof view;
13
- text: (value: string) => string[][];
14
- number: (value: number) => string[][];
13
+ text: (value: string) => TextValue;
14
+ number: (value: number) => TextValue;
15
15
  date: typeof date;
16
16
  datetime: typeof datetime;
17
+ verification: (value: VerificationInput) => VerificationPropertyValue;
17
18
  select: (value: string) => string;
18
19
  status: (value: string) => string;
19
20
  multiSelect: (values: readonly string[]) => string;
20
- checkbox: (value: boolean) => string[][];
21
- url: (value: string) => (string | string[][])[][];
22
- email: (value: string) => (string | string[][])[][];
23
- phone: (value: string) => string[][];
21
+ checkbox: (value: boolean) => TextValue;
22
+ url: (value: string) => TextValue;
23
+ email: (value: string) => TextValue;
24
+ phone: (value: string) => TextValue;
24
25
  relation: (value: string | readonly string[]) => string | any[] | readonly string[];
25
- file: (resourceId: string) => {
26
- type: "file";
27
- resourceId: string;
28
- };
29
26
  };
30
27
  export type NotionAsCodeFacade = typeof notionAsCodeFacade;
31
28
  /** Create the runtime facade used to declare Notion-as-Code project metadata. */
@@ -1 +1 @@
1
- {"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/handles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,QAAA,MAAM,kBAAkB;;;;;;kBAMT,MAAM;oBACJ,MAAM;;;oBAGN,MAAM;oBACN,MAAM;0BACA,SAAS,MAAM,EAAE;sBACrB,OAAO;iBACZ,MAAM;mBACJ,MAAM;mBACN,MAAM;sBACH,MAAM,GAAG,SAAS,MAAM,EAAE;uBACzB,MAAM;;;;CAIzB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC;AAE3D,iFAAiF;AACjF,wBAAgB,YAAY,IAAI,kBAAkB,CAEjD"}
1
+ {"version":3,"file":"handles.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/handles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EACN,IAAI,EACJ,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,QAAA,MAAM,kBAAkB;;;;;;kBAMT,MAAM,KAAG,SAAS;oBAChB,MAAM,KAAG,SAAS;;;0BAGZ,iBAAiB,KAAG,yBAAyB;oBAInD,MAAM;oBACN,MAAM;0BACA,SAAS,MAAM,EAAE;sBACrB,OAAO,KAAG,SAAS;iBACxB,MAAM,KAAG,SAAS;mBAChB,MAAM,KAAG,SAAS;mBAClB,MAAM,KAAG,SAAS;sBACf,MAAM,GAAG,SAAS,MAAM,EAAE;CAC5C,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,OAAO,kBAAkB,CAAC;AAE3D,iFAAiF;AACjF,wBAAgB,YAAY,IAAI,kBAAkB,CAEjD"}
@@ -1,8 +1,9 @@
1
1
  import { customAgent } from "./custom-agent.js";
2
2
  import { database } from "./database.js";
3
3
  import { date, datetime } from "./date.js";
4
- import { page } from "./page.js";
5
- import { assertUserResourceId } from "./resource.js";
4
+ import {
5
+ page
6
+ } from "./page.js";
6
7
  import { teamspace } from "./teamspace.js";
7
8
  import { view } from "./view.js";
8
9
  const notionAsCodeFacade = {
@@ -15,6 +16,10 @@ const notionAsCodeFacade = {
15
16
  number: (value) => [[String(value)]],
16
17
  date,
17
18
  datetime,
19
+ verification: (value) => ({
20
+ ...value,
21
+ type: "verification"
22
+ }),
18
23
  select: (value) => value,
19
24
  status: (value) => value,
20
25
  multiSelect: (values) => values.join(","),
@@ -22,11 +27,7 @@ const notionAsCodeFacade = {
22
27
  url: (value) => [[value, [["a", value]]]],
23
28
  email: (value) => [[value, [["a", `mailto:${value}`]]]],
24
29
  phone: (value) => [[value]],
25
- relation: (value) => Array.isArray(value) ? [...value] : value,
26
- file: (resourceId) => {
27
- assertUserResourceId(resourceId);
28
- return { type: "file", resourceId };
29
- }
30
+ relation: (value) => Array.isArray(value) ? [...value] : value
30
31
  };
31
32
  function createNotion() {
32
33
  return notionAsCodeFacade;
@@ -2,7 +2,7 @@ export { APPS_RESERVED_RESOURCE_ID_PREFIX, APPS_WORKSPACE_RESOURCE_ID } from "./
2
2
  export type { DatabaseIntent, DataSourceDefinition, NotionAsCodeIcon, NotionAsCodeProperty, NotionAsCodePropertyConfig, NotionAsCodeSchema, NotionAsCodeSelectOption, NotionAsCodeStatusOption, Parent, ResourceId, } from "./intents.js";
3
3
  export type { CustomAgentArgs, CustomAgentHandle } from "./custom-agent.js";
4
4
  export type { ChildDatabaseArgs, ChildDatabaseFactory, ChildMultiSourceDatabaseArgs, ChildSingleSourceDatabaseArgs, DataSourceArgs, DataSourceHandle, DataSourceMap, DatabaseArgs, DatabaseHandle, MultiSourceDatabaseArgs, SingleSourceDatabaseArgs, SingleSourceDatabaseHandle, } from "./database.js";
5
- export type { ChildPageArgs, PageArgs, PageHandle } from "./page.js";
5
+ export type { ChildPageArgs, PageArgs, PageHandle, PropertyValue, SimpleTextToken, TextValue, VerificationInput, VerificationPropertyValue, } from "./page.js";
6
6
  export type { TeamspaceArgs, TeamspaceHandle } from "./teamspace.js";
7
7
  export type { ViewArgs, ViewHandle } from "./view.js";
8
8
  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";
@@ -13,21 +13,18 @@ export declare const notion: {
13
13
  page: typeof import("./page.js").page;
14
14
  customAgent: typeof import("./custom-agent.js").customAgent;
15
15
  view: typeof import("./view.js").view;
16
- text: (value: string) => string[][];
17
- number: (value: number) => string[][];
16
+ text: (value: string) => import("./page.js").TextValue;
17
+ number: (value: number) => import("./page.js").TextValue;
18
18
  date: typeof import("./date.js").date;
19
19
  datetime: typeof import("./date.js").datetime;
20
+ verification: (value: import("./page.js").VerificationInput) => import("./page.js").VerificationPropertyValue;
20
21
  select: (value: string) => string;
21
22
  status: (value: string) => string;
22
23
  multiSelect: (values: readonly string[]) => string;
23
- checkbox: (value: boolean) => string[][];
24
- url: (value: string) => (string | string[][])[][];
25
- email: (value: string) => (string | string[][])[][];
26
- phone: (value: string) => string[][];
24
+ checkbox: (value: boolean) => import("./page.js").TextValue;
25
+ url: (value: string) => import("./page.js").TextValue;
26
+ email: (value: string) => import("./page.js").TextValue;
27
+ phone: (value: string) => import("./page.js").TextValue;
27
28
  relation: (value: string | readonly string[]) => string | any[] | readonly string[];
28
- file: (resourceId: string) => {
29
- type: "file";
30
- resourceId: string;
31
- };
32
29
  };
33
30
  //# sourceMappingURL=index.d.ts.map
@@ -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,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,MAAM,EACN,UAAU,GACV,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,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,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACrE,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,cAAc,EACd,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,0BAA0B,EAC1B,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,MAAM,EACN,UAAU,GACV,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC5E,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,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,11 +1,59 @@
1
1
  import { type Parent, type ResourceId } from "./intents.js";
2
2
  import { type ChildDatabaseFactory } from "./database.js";
3
+ /**
4
+ * A single text token: plain text as `[string]`, or text with annotations as
5
+ * `[string, ...annotations]`.
6
+ */
7
+ export type SimpleTextToken = [string] | [string, ...unknown[]];
8
+ /**
9
+ * The JSON-serializable text format returned by Notion-as-Code text helpers.
10
+ */
11
+ export type TextValue = SimpleTextToken[];
12
+ export type VerificationInput = {
13
+ state: "verified";
14
+ /** Set an expiration with `notion.datetime(...)`; omit it for indefinite verification. */
15
+ datetime?: TextValue;
16
+ } | {
17
+ state: "unverified";
18
+ };
19
+ export type VerificationPropertyValue = VerificationInput & {
20
+ type: "verification";
21
+ };
22
+ /**
23
+ * A page property value accepted by Notion as Code.
24
+ *
25
+ * Use helpers from `@notionhq/apps/notion-as-code` to construct rich values
26
+ * such as text, dates, checkboxes, and URLs.
27
+ */
28
+ export type PropertyValue = string | number | TextValue | string[] | VerificationPropertyValue | undefined;
29
+ /**
30
+ * Arguments for declaring a page.
31
+ *
32
+ * For a regular page, set its title through
33
+ * `properties.title: notion.text("My Page Title")`. For a database page, use
34
+ * the title property's schema name instead of `title`.
35
+ */
3
36
  export type PageArgs = {
4
37
  resourceId: ResourceId;
5
38
  /** Omit to create a private top-level page in the Apps workspace. */
6
39
  parent?: Parent;
7
40
  cover?: unknown;
8
- properties?: Record<string, unknown>;
41
+ /**
42
+ * Page properties, including the page title.
43
+ *
44
+ * @example Regular page
45
+ * properties: { title: notion.text("My Page Title") }
46
+ *
47
+ * @example Database page
48
+ * properties: { Name: notion.text("Task Name"), Status: "In Progress" }
49
+ */
50
+ properties?: Record<string, PropertyValue | undefined>;
51
+ /**
52
+ * Page body in Notion-flavored Markdown.
53
+ *
54
+ * Markdown headings create child blocks. They do not set the page title;
55
+ * set a regular page's title with `properties.title`.
56
+ */
9
57
  content?: string;
10
58
  fullWidth?: boolean;
11
59
  };
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/page.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,MAAM,EACX,KAAK,UAAU,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAI/E,MAAM,MAAM,QAAQ,GAAG;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAErD,MAAM,MAAM,UAAU,GAAG;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,oBAAoB,CAAC;IAClC,OAAO,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,UAAU,CAAC;CAC7C,CAAC;AAEF,oFAAoF;AACpF,wBAAgB,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAS/C;AAED,6DAA6D;AAC7D,wBAAgB,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAgBrF"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/page.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,KAAK,MAAM,EACX,KAAK,UAAU,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAI/E;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;AAEhE;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,eAAe,EAAE,CAAC;AAE1C,MAAM,MAAM,iBAAiB,GAC1B;IACA,KAAK,EAAE,UAAU,CAAC;IAClB,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,SAAS,CAAC;CACpB,GACD;IAAE,KAAK,EAAE,YAAY,CAAA;CAAE,CAAC;AAE3B,MAAM,MAAM,yBAAyB,GAAG,iBAAiB,GAAG;IAC3D,IAAI,EAAE,cAAc,CAAC;CACrB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GACtB,MAAM,GACN,MAAM,GACN,SAAS,GACT,MAAM,EAAE,GACR,yBAAyB,GACzB,SAAS,CAAC;AAEb;;;;;;GAMG;AACH,MAAM,MAAM,QAAQ,GAAG;IACtB,UAAU,EAAE,UAAU,CAAC;IACvB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC,CAAC;IACvD;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAErD,MAAM,MAAM,UAAU,GAAG;IACxB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,oBAAoB,CAAC;IAClC,OAAO,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,UAAU,CAAC;CAC7C,CAAC;AAEF,oFAAoF;AACpF,wBAAgB,IAAI,CAAC,IAAI,EAAE,QAAQ,GAAG,UAAU,CAS/C;AAED,6DAA6D;AAC7D,wBAAgB,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAgBrF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=page.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.test.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/page.test.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notionhq/apps",
3
- "version": "0.0.19",
3
+ "version": "0.0.20",
4
4
  "description": "An SDK for building workflow apps for Notion",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -75,7 +75,8 @@ root exports support:
75
75
 
76
76
  - `teamspace({ resourceId, name, accessLevel })`, with `addPage` and
77
77
  `teamspace.addDatabase(id, args)` on the returned handle.
78
- - `page({ resourceId, parent?, properties?, content? })`, with
78
+ - `page({ resourceId, parent?, properties?, content? })`; regular page titles use
79
+ `properties: { title: notion.text("My Page Title") }`. It also has
79
80
  `addPage` and `page.addDatabase(id, args)` for children.
80
81
  - `database(resourceId, { dataSourceResourceId, name, schema, parent?, views? })`,
81
82
  returning a single source as `handle.dataSource`, or
@@ -90,6 +91,11 @@ root exports support:
90
91
  Use property resource IDs in view filters, sorts, and layout options; calendar
91
92
  views require `calendarBy`, and timeline views require `timelineBy`.
92
93
 
94
+ For a regular page, set the title with
95
+ `properties: { title: notion.text("My Page Title") }`. A Markdown heading in
96
+ `content` creates a child heading block; it does not set the page title. For a
97
+ database page, use the title property's schema name instead of `title`.
98
+
93
99
  A database declaration must include at least one data source or at least one
94
100
  view. A linked-only database may omit `datasources`, or use `datasources: {}`,
95
101
  only when `views` is nonempty. `{}`, `{ datasources: {} }`, and
@@ -131,8 +137,7 @@ The Apps SDK exposes a subset of Notion as Code. Data sources are nested inside
131
137
  Apps deployment rejects workspace creation or changes and supplies the App's
132
138
  workspace binding itself. Value helpers and types stay on their existing
133
139
  subpaths. For example, import `{ notion }` from `@notionhq/apps/notion-as-code`
134
- for `notion.text(...)` or `notion.file(resourceId)`. The latter creates a file
135
- reference, not an upload or file declaration. These helpers are not root exports.
140
+ for `notion.text(...)`. These helpers are not root exports.
136
141
  CLI acceptance of a serialized intent envelope alone does not establish server
137
142
  support for its contents.
138
143
 
@@ -120,10 +120,12 @@ guide page in `src/workflows/sayHello/lib/notion.ts`:
120
120
 
121
121
  ```ts
122
122
  import { page } from "@notionhq/apps";
123
+ import { notion } from "@notionhq/apps/notion-as-code";
123
124
 
124
125
  export const guide = page({
125
126
  resourceId: "workflow-guide",
126
- content: "# Workflow guide\nThis App runs a scheduled workflow.",
127
+ properties: { title: notion.text("Workflow guide") },
128
+ content: "This App runs a scheduled workflow.",
127
129
  });
128
130
  ```
129
131
 
@@ -1,5 +1,7 @@
1
+ import type { TextValue } from "./page.js";
2
+
1
3
  /** Serialize Notion-as-Code date values for Apps property payloads. */
2
- export function date(startDate: string, endDate?: string): unknown[][] {
4
+ export function date(startDate: string, endDate?: string): TextValue {
3
5
  const start_date = parseIsoDate(startDate);
4
6
  const end_date = endDate === undefined ? undefined : parseIsoDate(endDate);
5
7
  if (end_date !== undefined && end_date < start_date) {
@@ -13,7 +15,7 @@ export function date(startDate: string, endDate?: string): unknown[][] {
13
15
  }
14
16
 
15
17
  /** Serialize Notion-as-Code datetime values for Apps property payloads. */
16
- export function datetime(value: { start: string; end?: string; timeZone?: string }): unknown[][] {
18
+ export function datetime(value: { start: string; end?: string; timeZone?: string }): TextValue {
17
19
  const timeZone = value.timeZone ?? "UTC";
18
20
  try {
19
21
  new Intl.DateTimeFormat("en-US", { timeZone }).format();
@@ -1,8 +1,12 @@
1
1
  import { customAgent } from "./custom-agent.js";
2
2
  import { database } from "./database.js";
3
3
  import { date, datetime } from "./date.js";
4
- import { page } from "./page.js";
5
- import { assertUserResourceId } from "./resource.js";
4
+ import {
5
+ page,
6
+ type TextValue,
7
+ type VerificationInput,
8
+ type VerificationPropertyValue,
9
+ } from "./page.js";
6
10
  import { teamspace } from "./teamspace.js";
7
11
  import { view } from "./view.js";
8
12
 
@@ -12,22 +16,22 @@ const notionAsCodeFacade = {
12
16
  page,
13
17
  customAgent,
14
18
  view,
15
- text: (value: string) => [[value]],
16
- number: (value: number) => [[String(value)]],
19
+ text: (value: string): TextValue => [[value]],
20
+ number: (value: number): TextValue => [[String(value)]],
17
21
  date,
18
22
  datetime,
23
+ verification: (value: VerificationInput): VerificationPropertyValue => ({
24
+ ...value,
25
+ type: "verification",
26
+ }),
19
27
  select: (value: string) => value,
20
28
  status: (value: string) => value,
21
29
  multiSelect: (values: readonly string[]) => values.join(","),
22
- checkbox: (value: boolean) => [[value ? "Yes" : "No"]],
23
- url: (value: string) => [[value, [["a", value]]]],
24
- email: (value: string) => [[value, [["a", `mailto:${value}`]]]],
25
- phone: (value: string) => [[value]],
30
+ checkbox: (value: boolean): TextValue => [[value ? "Yes" : "No"]],
31
+ url: (value: string): TextValue => [[value, [["a", value]]]],
32
+ email: (value: string): TextValue => [[value, [["a", `mailto:${value}`]]]],
33
+ phone: (value: string): TextValue => [[value]],
26
34
  relation: (value: string | readonly string[]) => (Array.isArray(value) ? [...value] : value),
27
- file: (resourceId: string) => {
28
- assertUserResourceId(resourceId);
29
- return { type: "file" as const, resourceId };
30
- },
31
35
  };
32
36
 
33
37
  export type NotionAsCodeFacade = typeof notionAsCodeFacade;
@@ -28,7 +28,16 @@ export type {
28
28
  SingleSourceDatabaseArgs,
29
29
  SingleSourceDatabaseHandle,
30
30
  } from "./database.js";
31
- export type { ChildPageArgs, PageArgs, PageHandle } from "./page.js";
31
+ export type {
32
+ ChildPageArgs,
33
+ PageArgs,
34
+ PageHandle,
35
+ PropertyValue,
36
+ SimpleTextToken,
37
+ TextValue,
38
+ VerificationInput,
39
+ VerificationPropertyValue,
40
+ } from "./page.js";
32
41
  export type { TeamspaceArgs, TeamspaceHandle } from "./teamspace.js";
33
42
  export type { ViewArgs, ViewHandle } from "./view.js";
34
43
  export type {
@@ -0,0 +1,35 @@
1
+ import { describe, expect, expectTypeOf, it } from "vitest";
2
+
3
+ import { notion, type PageArgs, type PropertyValue } from "./index.js";
4
+ import { finishMetadataRecording, startMetadataRecording } from "./recorder.js";
5
+
6
+ describe("Notion-as-Code page declarations", () => {
7
+ it("records a regular page title separately from Markdown content", () => {
8
+ const properties = {
9
+ title: notion.text("Workflow guide"),
10
+ } satisfies Record<string, PropertyValue | undefined>;
11
+ const recorder = startMetadataRecording();
12
+
13
+ notion.page({
14
+ resourceId: "workflow-guide",
15
+ properties,
16
+ content: "# Body heading",
17
+ });
18
+
19
+ expectTypeOf<PageArgs["properties"]>().toEqualTypeOf<
20
+ Record<string, PropertyValue | undefined> | undefined
21
+ >();
22
+ expect(finishMetadataRecording(recorder).intents).toEqual([
23
+ {
24
+ type: "page",
25
+ resourceId: "workflow-guide",
26
+ parent: {
27
+ type: "resourceId",
28
+ resourceId: "__notion_apps_workspace__",
29
+ },
30
+ properties: { title: [["Workflow guide"]] },
31
+ content: "# Body heading",
32
+ },
33
+ ]);
34
+ });
35
+ });
@@ -8,14 +8,72 @@ import { createChildDatabase, type ChildDatabaseFactory } from "./database.js";
8
8
  import { recordIntent } from "./recorder.js";
9
9
  import { assertParent, assertUserResourceId } from "./resource.js";
10
10
 
11
+ /**
12
+ * A single text token: plain text as `[string]`, or text with annotations as
13
+ * `[string, ...annotations]`.
14
+ */
15
+ export type SimpleTextToken = [string] | [string, ...unknown[]];
16
+
17
+ /**
18
+ * The JSON-serializable text format returned by Notion-as-Code text helpers.
19
+ */
20
+ export type TextValue = SimpleTextToken[];
21
+
22
+ export type VerificationInput =
23
+ | {
24
+ state: "verified";
25
+ /** Set an expiration with `notion.datetime(...)`; omit it for indefinite verification. */
26
+ datetime?: TextValue;
27
+ }
28
+ | { state: "unverified" };
29
+
30
+ export type VerificationPropertyValue = VerificationInput & {
31
+ type: "verification";
32
+ };
33
+
34
+ /**
35
+ * A page property value accepted by Notion as Code.
36
+ *
37
+ * Use helpers from `@notionhq/apps/notion-as-code` to construct rich values
38
+ * such as text, dates, checkboxes, and URLs.
39
+ */
40
+ export type PropertyValue =
41
+ | string
42
+ | number
43
+ | TextValue
44
+ | string[]
45
+ | VerificationPropertyValue
46
+ | undefined;
47
+
48
+ /**
49
+ * Arguments for declaring a page.
50
+ *
51
+ * For a regular page, set its title through
52
+ * `properties.title: notion.text("My Page Title")`. For a database page, use
53
+ * the title property's schema name instead of `title`.
54
+ */
11
55
  export type PageArgs = {
12
56
  resourceId: ResourceId;
13
57
  /** Omit to create a private top-level page in the Apps workspace. */
14
58
  parent?: Parent;
15
59
  // TODO: Port cover types.
16
60
  cover?: unknown;
17
- // TODO: Port page property types.
18
- properties?: Record<string, unknown>;
61
+ /**
62
+ * Page properties, including the page title.
63
+ *
64
+ * @example Regular page
65
+ * properties: { title: notion.text("My Page Title") }
66
+ *
67
+ * @example Database page
68
+ * properties: { Name: notion.text("Task Name"), Status: "In Progress" }
69
+ */
70
+ properties?: Record<string, PropertyValue | undefined>;
71
+ /**
72
+ * Page body in Notion-flavored Markdown.
73
+ *
74
+ * Markdown headings create child blocks. They do not set the page title;
75
+ * set a regular page's title with `properties.title`.
76
+ */
19
77
  content?: string;
20
78
  fullWidth?: boolean;
21
79
  };