safe-notion 0.1.4 → 0.2.0

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.
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function createSearchCommand(): Command;
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // @bun
3
3
 
4
4
  // src/index.ts
5
- import { Command as Command5 } from "commander";
5
+ import { Command as Command6 } from "commander";
6
6
 
7
7
  // src/commands/page.ts
8
8
  import { Command } from "commander";
@@ -450,6 +450,17 @@ class NotionSafeClient {
450
450
  await this.ensurePermission(blockId, "block:delete");
451
451
  return this.client.blocks.delete({ block_id: blockId });
452
452
  }
453
+ async search(params) {
454
+ const hasReadPermission = this.config.defaultPermission === "read" || this.config.rules.some((rule) => rule.permissions.some((p) => ["page:read", "database:read", "block:read"].includes(p)));
455
+ if (!hasReadPermission) {
456
+ const error = {
457
+ error: "Search not allowed: no read permissions configured",
458
+ code: "PERMISSION_DENIED"
459
+ };
460
+ throw error;
461
+ }
462
+ return this.client.search(params);
463
+ }
453
464
  clearCache() {
454
465
  clearCache();
455
466
  }
@@ -695,6 +706,54 @@ function createConfigCommand() {
695
706
  return config;
696
707
  }
697
708
 
709
+ // src/commands/search.ts
710
+ import { Command as Command5 } from "commander";
711
+ function createSearchCommand() {
712
+ const search = new Command5("search").description("Search pages and databases");
713
+ search.argument("[query]", "Search query string").option("--filter <type>", "Filter by object type: page or database").option("--sort <direction>", "Sort by last_edited_time: ascending or descending").option("--start-cursor <cursor>", "Pagination cursor").option("--page-size <size>", "Number of results per page", "100").action(async (query, options) => {
714
+ try {
715
+ const client = getClient();
716
+ const params = {};
717
+ if (query) {
718
+ params.query = query;
719
+ }
720
+ if (options.filter) {
721
+ const filterValue = options.filter === "database" ? "data_source" : options.filter;
722
+ if (filterValue !== "page" && filterValue !== "data_source") {
723
+ throw {
724
+ error: "Invalid filter value. Must be 'page' or 'database'",
725
+ code: "INVALID_ARGUMENT"
726
+ };
727
+ }
728
+ params.filter = { property: "object", value: filterValue };
729
+ }
730
+ if (options.sort) {
731
+ if (options.sort !== "ascending" && options.sort !== "descending") {
732
+ throw {
733
+ error: "Invalid sort value. Must be 'ascending' or 'descending'",
734
+ code: "INVALID_ARGUMENT"
735
+ };
736
+ }
737
+ params.sort = {
738
+ direction: options.sort,
739
+ timestamp: "last_edited_time"
740
+ };
741
+ }
742
+ if (options.startCursor) {
743
+ params.start_cursor = options.startCursor;
744
+ }
745
+ if (options.pageSize) {
746
+ params.page_size = parseInt(options.pageSize, 10);
747
+ }
748
+ const result = await client.search(params);
749
+ outputJson(result);
750
+ } catch (error) {
751
+ handleError(error);
752
+ }
753
+ });
754
+ return search;
755
+ }
756
+
698
757
  // src/notion-client.ts
699
758
  import { Client as Client2 } from "@notionhq/client";
700
759
  import { LogLevel as LogLevel2 } from "@notionhq/client/build/src/logging";
@@ -706,7 +765,7 @@ function setDebugMode(enabled) {
706
765
  var clientInstance2 = null;
707
766
 
708
767
  // src/index.ts
709
- var program = new Command5;
768
+ var program = new Command6;
710
769
  program.name("notion-safe").description("A safe Notion API wrapper CLI for AI agents").version("0.1.0").option("--debug", "Enable debug output including API warnings").hook("preAction", () => {
711
770
  const opts = program.opts();
712
771
  if (opts.debug) {
@@ -717,4 +776,5 @@ program.addCommand(createPageCommand());
717
776
  program.addCommand(createDbCommand());
718
777
  program.addCommand(createBlockCommand());
719
778
  program.addCommand(createConfigCommand());
779
+ program.addCommand(createSearchCommand());
720
780
  program.parse();
@@ -24,6 +24,19 @@ export declare class NotionSafeClient {
24
24
  getBlockChildren(blockId: string, startCursor?: string, pageSize?: number): Promise<unknown>;
25
25
  appendBlockChildren(blockId: string, children: AppendBlockChildrenParams["children"]): Promise<unknown>;
26
26
  deleteBlock(blockId: string): Promise<unknown>;
27
+ search(params: {
28
+ query?: string;
29
+ filter?: {
30
+ property: "object";
31
+ value: "page" | "data_source";
32
+ };
33
+ sort?: {
34
+ direction: "ascending" | "descending";
35
+ timestamp: "last_edited_time";
36
+ };
37
+ start_cursor?: string;
38
+ page_size?: number;
39
+ }): Promise<unknown>;
27
40
  clearCache(): void;
28
41
  }
29
42
  export declare function getClient(): NotionSafeClient;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "safe-notion",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "description": "A safe Notion API wrapper CLI for AI agents with granular permission control",
5
5
  "license": "MIT",
6
6
  "author": "shoppingjaws",