@notionhq/apps 0.0.47 → 0.0.48

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.
@@ -1,6 +1,6 @@
1
1
  import { type Parent } from "./intents.js";
2
- /** Validate parent references accepted by Apps declarations. */
2
+ /** Validate parent references. Reserved Apps IDs are allowed as parents. */
3
3
  export declare function assertParent(parent: Parent): void;
4
- /** Reject empty or runtime-reserved resource IDs in user declarations. */
4
+ /** Reject empty or runtime-reserved IDs for created resources. */
5
5
  export declare function assertUserResourceId(resourceId: string): void;
6
6
  //# sourceMappingURL=resource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE7E,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAKjD;AAED,0EAA0E;AAC1E,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAO7D"}
1
+ {"version":3,"file":"resource.d.ts","sourceRoot":"","sources":["../../src/notion-as-code/resource.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,MAAM,EAAE,MAAM,cAAc,CAAC;AAE7E,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAOjD;AAED,kEAAkE;AAClE,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAO7D"}
@@ -3,7 +3,9 @@ function assertParent(parent) {
3
3
  if (parent.type !== "resourceId") {
4
4
  throw new Error("Notion-as-Code parents must reference a resourceId");
5
5
  }
6
- assertUserResourceId(parent.resourceId);
6
+ if (parent.resourceId.length === 0) {
7
+ throw new Error("Notion-as-Code resourceId must be a non-empty string");
8
+ }
7
9
  }
8
10
  function assertUserResourceId(resourceId) {
9
11
  if (resourceId.length === 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notionhq/apps",
3
- "version": "0.0.47",
3
+ "version": "0.0.48",
4
4
  "description": "An SDK for building workflow apps for Notion",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -155,8 +155,10 @@ Custom views do not accept standard view properties, sorts, or filters. Keep
155
155
  the view resource ID and the custom-block filename stable across builds.
156
156
 
157
157
  Keep resource IDs stable across builds. They identify declarations, not live
158
- Notion UUIDs. Avoid the reserved `__notion_apps_` prefix. Explicit parents
159
- use `{ type: "resourceId", resourceId: parent.resourceId }`; child helpers set
158
+ Notion UUIDs. Do not create resources whose IDs use the reserved
159
+ `__notion_apps_` prefix. Parenting to reserved IDs such as
160
+ `__notion_apps_app_md__` is allowed. Explicit parents use
161
+ `{ type: "resourceId", resourceId: parent.resourceId }`; child helpers set
160
162
  this reference for you. Pages and databases without a parent default to private
161
163
  top-level resources in the Apps workspace.
162
164
 
@@ -791,6 +791,32 @@ describe("Notion-as-Code database declarations", () => {
791
791
  expect(serialized.description).toBe("Metadata source");
792
792
  });
793
793
 
794
+ it("allows parenting a database to a reserved Apps resource ID", () => {
795
+ const recorder = startMetadataRecording();
796
+ notion.database("meetings-db", {
797
+ parent: { type: "resourceId", resourceId: "__notion_apps_app_md__" },
798
+ dataSourceResourceId: "meetings-source",
799
+ name: "Meetings",
800
+ schema: { Name: { resourceId: "meeting-name", type: "title" } },
801
+ });
802
+ expect(finishMetadataRecording(recorder).intents[0]).toEqual(
803
+ expect.objectContaining({
804
+ resourceId: "meetings-db",
805
+ parent: { type: "resourceId", resourceId: "__notion_apps_app_md__" },
806
+ }),
807
+ );
808
+ });
809
+
810
+ it("rejects creating a database whose resource ID uses the reserved Apps prefix", () => {
811
+ expect(() =>
812
+ notion.database("__notion_apps_meetings__", {
813
+ dataSourceResourceId: "meetings-source",
814
+ name: "Meetings",
815
+ schema: { Name: { resourceId: "meeting-name", type: "title" } },
816
+ }),
817
+ ).toThrow('Resource ID "__notion_apps_meetings__" uses the reserved Apps prefix');
818
+ });
819
+
794
820
  it("requires the status property configuration in authoring types", () => {
795
821
  const invalidStatusDeclaration = () =>
796
822
  notion.database("missing-status-options-database", {
@@ -28,6 +28,30 @@ describe("Notion-as-Code page declarations", () => {
28
28
  ]);
29
29
  });
30
30
 
31
+ it("allows parenting a page to a reserved Apps resource ID", () => {
32
+ const recorder = startMetadataRecording();
33
+ notion.page({
34
+ resourceId: "guide",
35
+ parent: { type: "resourceId", resourceId: "__notion_apps_app_md__" },
36
+ properties: { title: notion.text("Guide") },
37
+ });
38
+ expect(finishMetadataRecording(recorder).intents[0]).toEqual(
39
+ expect.objectContaining({
40
+ resourceId: "guide",
41
+ parent: { type: "resourceId", resourceId: "__notion_apps_app_md__" },
42
+ }),
43
+ );
44
+ });
45
+
46
+ it("rejects creating a page whose resource ID uses the reserved Apps prefix", () => {
47
+ expect(() =>
48
+ notion.page({
49
+ resourceId: "__notion_apps_guide__",
50
+ properties: { title: notion.text("Guide") },
51
+ }),
52
+ ).toThrow('Resource ID "__notion_apps_guide__" uses the reserved Apps prefix');
53
+ });
54
+
31
55
  it("records a regular page title separately from Markdown content", () => {
32
56
  const properties = {
33
57
  title: notion.text("Workflow guide"),
@@ -1,14 +1,16 @@
1
1
  import { APPS_RESERVED_RESOURCE_ID_PREFIX, type Parent } from "./intents.js";
2
2
 
3
- /** Validate parent references accepted by Apps declarations. */
3
+ /** Validate parent references. Reserved Apps IDs are allowed as parents. */
4
4
  export function assertParent(parent: Parent): void {
5
5
  if (parent.type !== "resourceId") {
6
6
  throw new Error("Notion-as-Code parents must reference a resourceId");
7
7
  }
8
- assertUserResourceId(parent.resourceId);
8
+ if (parent.resourceId.length === 0) {
9
+ throw new Error("Notion-as-Code resourceId must be a non-empty string");
10
+ }
9
11
  }
10
12
 
11
- /** Reject empty or runtime-reserved resource IDs in user declarations. */
13
+ /** Reject empty or runtime-reserved IDs for created resources. */
12
14
  export function assertUserResourceId(resourceId: string): void {
13
15
  if (resourceId.length === 0) {
14
16
  throw new Error("Notion-as-Code resourceId must be a non-empty string");