@notionhq/apps 0.0.41 → 0.0.42

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 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAUlD,MAAM,MAAM,WAAW,GAAG;IACzB,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA2CxE"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAalD,MAAM,MAAM,WAAW,GAAG;IACzB,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA2CxE"}
package/dist/cli/build.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { rolldown } from "rolldown";
4
+ import { APPS_WORKSPACE_RESOURCE_ID } from "../notion-as-code/intents.js";
4
5
  import {
5
6
  createProvisioningArtifact
6
7
  } from "../notion-as-code/provisioning.js";
@@ -8,6 +9,7 @@ import { clearRegisteredPacers } from "../pacer.js";
8
9
  import { generateEntry, generateMetadataEntry, generateBlocksEntry } from "./codegen.js";
9
10
  import { discoverCapabilities } from "./discover.js";
10
11
  import { extractManifest, extractProvisioning, extractBlockConfigs } from "./emit-manifest.js";
12
+ const APP_MD_RESOURCE_ID = "__notion_apps_app_md__";
11
13
  async function buildApp(projectRoot) {
12
14
  const capabilities = await discoverCapabilities(projectRoot);
13
15
  if (capabilities.length === 0) {
@@ -45,14 +47,36 @@ async function buildApp(projectRoot) {
45
47
  }
46
48
  async function emitProvisioningArtifact(projectRoot, entityProvisioning) {
47
49
  const provisioningPath = path.join(projectRoot, "dist", "provisioning.json");
48
- if (entityProvisioning.intents.length === 0) {
50
+ const appPage = await readAppPage(projectRoot);
51
+ if (entityProvisioning.intents.length === 0 && !appPage) {
49
52
  await fs.promises.rm(provisioningPath, { force: true });
50
53
  return;
51
54
  }
52
- const artifact = createProvisioningArtifact(entityProvisioning.intents);
55
+ const artifact = createProvisioningArtifact([
56
+ ...entityProvisioning.intents,
57
+ ...appPage ? [appPage] : []
58
+ ]);
53
59
  await fs.promises.writeFile(provisioningPath, `${JSON.stringify(artifact, null, " ")}
54
60
  `);
55
61
  }
62
+ async function readAppPage(projectRoot) {
63
+ let content;
64
+ try {
65
+ content = await fs.promises.readFile(path.join(projectRoot, "APP.md"), "utf8");
66
+ } catch (error) {
67
+ if (error.code === "ENOENT") {
68
+ return void 0;
69
+ }
70
+ throw error;
71
+ }
72
+ return {
73
+ type: "page",
74
+ resourceId: APP_MD_RESOURCE_ID,
75
+ parent: { type: "resourceId", resourceId: APPS_WORKSPACE_RESOURCE_ID },
76
+ properties: { title: [["APP.md"]] },
77
+ content
78
+ };
79
+ }
56
80
  async function buildMetadata(projectRoot, capabilities) {
57
81
  const metadataEntryPath = path.join(projectRoot, ".notion", "metadata-entry.ts");
58
82
  const metadataBundlePath = path.join(projectRoot, ".notion", "metadata.js");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notionhq/apps",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "description": "An SDK for building workflow apps for Notion",
5
5
  "license": "MIT",
6
6
  "bin": {
@@ -456,6 +456,43 @@ describe("buildApp", () => {
456
456
  });
457
457
  });
458
458
 
459
+ it("emits APP.md as a private page with stable identity and resource references", async () => {
460
+ const root = await fs.promises.mkdtemp(path.join(FIXTURES, "app-md-"));
461
+ try {
462
+ await fs.promises.cp(
463
+ path.join(FIXTURES, "notion-as-code", "src"),
464
+ path.join(root, "src"),
465
+ {
466
+ recursive: true,
467
+ },
468
+ );
469
+ const markdown =
470
+ '# App guide\n\nSee <mention-page url="{{github-app-private-page}}">Home</mention-page>.\n';
471
+ await fs.promises.writeFile(path.join(root, "APP.md"), markdown);
472
+ await buildApp(root);
473
+ const provisioningPath = path.join(root, "dist", "provisioning.json");
474
+ const provisioning = JSON.parse(await fs.promises.readFile(provisioningPath, "utf8"));
475
+ expect(provisioning.intents.at(-1)).toEqual({
476
+ type: "page",
477
+ resourceId: "__notion_apps_app_md__",
478
+ parent: { type: "resourceId", resourceId: "__notion_apps_workspace__" },
479
+ properties: { title: [["APP.md"]] },
480
+ content: markdown,
481
+ });
482
+
483
+ await fs.promises.rm(path.join(root, "APP.md"));
484
+ await buildApp(root);
485
+ const withoutAppPage = JSON.parse(await fs.promises.readFile(provisioningPath, "utf8"));
486
+ expect(withoutAppPage.intents).not.toEqual(
487
+ expect.arrayContaining([
488
+ expect.objectContaining({ resourceId: "__notion_apps_app_md__" }),
489
+ ]),
490
+ );
491
+ } finally {
492
+ await fs.promises.rm(root, { recursive: true, force: true });
493
+ }
494
+ });
495
+
459
496
  it("removes provisioning when a rebuild no longer declares Notion resources", async () => {
460
497
  const root = await fs.promises.mkdtemp(path.join(FIXTURES, "provisioning-rebuild-"));
461
498
  try {
package/src/cli/build.ts CHANGED
@@ -4,6 +4,7 @@ import * as path from "node:path";
4
4
  import { rolldown } from "rolldown";
5
5
 
6
6
  import type { AppManifest } from "../manifest.js";
7
+ import { APPS_WORKSPACE_RESOURCE_ID, type PageIntent } from "../notion-as-code/intents.js";
7
8
  import {
8
9
  createProvisioningArtifact,
9
10
  type RecordedProvisioning,
@@ -13,6 +14,8 @@ import { generateEntry, generateMetadataEntry, generateBlocksEntry } from "./cod
13
14
  import { discoverCapabilities, type DiscoveredCapability } from "./discover.js";
14
15
  import { extractManifest, extractProvisioning, extractBlockConfigs } from "./emit-manifest.js";
15
16
 
17
+ const APP_MD_RESOURCE_ID = "__notion_apps_app_md__";
18
+
16
19
  export type BuildResult = {
17
20
  manifest: AppManifest;
18
21
  bundlePath: string;
@@ -75,15 +78,40 @@ async function emitProvisioningArtifact(
75
78
  entityProvisioning: RecordedProvisioning,
76
79
  ): Promise<void> {
77
80
  const provisioningPath = path.join(projectRoot, "dist", "provisioning.json");
78
- if (entityProvisioning.intents.length === 0) {
81
+ const appPage = await readAppPage(projectRoot);
82
+ if (entityProvisioning.intents.length === 0 && !appPage) {
79
83
  await fs.promises.rm(provisioningPath, { force: true });
80
84
  return;
81
85
  }
82
86
 
83
- const artifact = createProvisioningArtifact(entityProvisioning.intents);
87
+ const artifact = createProvisioningArtifact([
88
+ ...entityProvisioning.intents,
89
+ ...(appPage ? [appPage] : []),
90
+ ]);
84
91
  await fs.promises.writeFile(provisioningPath, `${JSON.stringify(artifact, null, "\t")}\n`);
85
92
  }
86
93
 
94
+ async function readAppPage(
95
+ projectRoot: string,
96
+ ): Promise<({ type: "page" } & PageIntent) | undefined> {
97
+ let content: string;
98
+ try {
99
+ content = await fs.promises.readFile(path.join(projectRoot, "APP.md"), "utf8");
100
+ } catch (error) {
101
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") {
102
+ return undefined;
103
+ }
104
+ throw error;
105
+ }
106
+ return {
107
+ type: "page",
108
+ resourceId: APP_MD_RESOURCE_ID,
109
+ parent: { type: "resourceId", resourceId: APPS_WORKSPACE_RESOURCE_ID },
110
+ properties: { title: [["APP.md"]] },
111
+ content,
112
+ };
113
+ }
114
+
87
115
  /** Bundle capabilities separately to record their Notion-as-Code declarations without shipping them. */
88
116
  async function buildMetadata(
89
117
  projectRoot: string,