@catafal/notion-cli 5.9.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.
Files changed (162) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +552 -0
  3. package/bin/dev +17 -0
  4. package/bin/dev.cmd +3 -0
  5. package/bin/run +14 -0
  6. package/bin/run.cmd +3 -0
  7. package/dist/base-command.d.ts +73 -0
  8. package/dist/base-command.js +179 -0
  9. package/dist/base-flags.d.ts +14 -0
  10. package/dist/base-flags.js +59 -0
  11. package/dist/cache.d.ts +84 -0
  12. package/dist/cache.js +351 -0
  13. package/dist/commands/append.d.ts +37 -0
  14. package/dist/commands/append.js +120 -0
  15. package/dist/commands/batch/delete.d.ts +42 -0
  16. package/dist/commands/batch/delete.js +199 -0
  17. package/dist/commands/batch/retrieve.d.ts +43 -0
  18. package/dist/commands/batch/retrieve.js +272 -0
  19. package/dist/commands/block/append.d.ts +42 -0
  20. package/dist/commands/block/append.js +219 -0
  21. package/dist/commands/block/delete.d.ts +30 -0
  22. package/dist/commands/block/delete.js +97 -0
  23. package/dist/commands/block/retrieve/children.d.ts +31 -0
  24. package/dist/commands/block/retrieve/children.js +177 -0
  25. package/dist/commands/block/retrieve.d.ts +30 -0
  26. package/dist/commands/block/retrieve.js +101 -0
  27. package/dist/commands/block/update.d.ts +45 -0
  28. package/dist/commands/block/update.js +242 -0
  29. package/dist/commands/bookmark/list.d.ts +30 -0
  30. package/dist/commands/bookmark/list.js +60 -0
  31. package/dist/commands/bookmark/remove.d.ts +26 -0
  32. package/dist/commands/bookmark/remove.js +47 -0
  33. package/dist/commands/bookmark/set.d.ts +29 -0
  34. package/dist/commands/bookmark/set.js +96 -0
  35. package/dist/commands/browse.d.ts +13 -0
  36. package/dist/commands/browse.js +44 -0
  37. package/dist/commands/cache/info.d.ts +19 -0
  38. package/dist/commands/cache/info.js +145 -0
  39. package/dist/commands/config/set-token.d.ts +22 -0
  40. package/dist/commands/config/set-token.js +137 -0
  41. package/dist/commands/daily/index.d.ts +32 -0
  42. package/dist/commands/daily/index.js +135 -0
  43. package/dist/commands/daily/setup.d.ts +42 -0
  44. package/dist/commands/daily/setup.js +149 -0
  45. package/dist/commands/db/create.d.ts +31 -0
  46. package/dist/commands/db/create.js +124 -0
  47. package/dist/commands/db/query.d.ts +41 -0
  48. package/dist/commands/db/query.js +360 -0
  49. package/dist/commands/db/retrieve.d.ts +33 -0
  50. package/dist/commands/db/retrieve.js +134 -0
  51. package/dist/commands/db/schema.d.ts +32 -0
  52. package/dist/commands/db/schema.js +308 -0
  53. package/dist/commands/db/update.d.ts +31 -0
  54. package/dist/commands/db/update.js +117 -0
  55. package/dist/commands/doctor.d.ts +50 -0
  56. package/dist/commands/doctor.js +420 -0
  57. package/dist/commands/init.d.ts +65 -0
  58. package/dist/commands/init.js +479 -0
  59. package/dist/commands/list.d.ts +29 -0
  60. package/dist/commands/list.js +219 -0
  61. package/dist/commands/open.d.ts +29 -0
  62. package/dist/commands/open.js +100 -0
  63. package/dist/commands/page/create.d.ts +33 -0
  64. package/dist/commands/page/create.js +261 -0
  65. package/dist/commands/page/delete.d.ts +36 -0
  66. package/dist/commands/page/delete.js +107 -0
  67. package/dist/commands/page/export.d.ts +38 -0
  68. package/dist/commands/page/export.js +120 -0
  69. package/dist/commands/page/retrieve/property_item.d.ts +24 -0
  70. package/dist/commands/page/retrieve/property_item.js +75 -0
  71. package/dist/commands/page/retrieve.d.ts +36 -0
  72. package/dist/commands/page/retrieve.js +244 -0
  73. package/dist/commands/page/update.d.ts +34 -0
  74. package/dist/commands/page/update.js +184 -0
  75. package/dist/commands/quick.d.ts +35 -0
  76. package/dist/commands/quick.js +168 -0
  77. package/dist/commands/search.d.ts +43 -0
  78. package/dist/commands/search.js +361 -0
  79. package/dist/commands/stats.d.ts +35 -0
  80. package/dist/commands/stats.js +274 -0
  81. package/dist/commands/sync.d.ts +24 -0
  82. package/dist/commands/sync.js +183 -0
  83. package/dist/commands/template/get.d.ts +28 -0
  84. package/dist/commands/template/get.js +59 -0
  85. package/dist/commands/template/list.d.ts +32 -0
  86. package/dist/commands/template/list.js +62 -0
  87. package/dist/commands/template/remove.d.ts +27 -0
  88. package/dist/commands/template/remove.js +48 -0
  89. package/dist/commands/template/save.d.ts +32 -0
  90. package/dist/commands/template/save.js +92 -0
  91. package/dist/commands/template/use.d.ts +34 -0
  92. package/dist/commands/template/use.js +142 -0
  93. package/dist/commands/user/list.d.ts +27 -0
  94. package/dist/commands/user/list.js +99 -0
  95. package/dist/commands/user/retrieve/bot.d.ts +28 -0
  96. package/dist/commands/user/retrieve/bot.js +96 -0
  97. package/dist/commands/user/retrieve.d.ts +30 -0
  98. package/dist/commands/user/retrieve.js +103 -0
  99. package/dist/commands/whoami.d.ts +19 -0
  100. package/dist/commands/whoami.js +175 -0
  101. package/dist/deduplication.d.ts +41 -0
  102. package/dist/deduplication.js +71 -0
  103. package/dist/envelope.d.ts +169 -0
  104. package/dist/envelope.js +257 -0
  105. package/dist/errors/enhanced-errors.d.ts +168 -0
  106. package/dist/errors/enhanced-errors.js +567 -0
  107. package/dist/errors/index.d.ts +18 -0
  108. package/dist/errors/index.js +33 -0
  109. package/dist/examples/cache-retry-examples.d.ts +64 -0
  110. package/dist/examples/cache-retry-examples.js +375 -0
  111. package/dist/helper.d.ts +102 -0
  112. package/dist/helper.js +885 -0
  113. package/dist/http-agent.d.ts +38 -0
  114. package/dist/http-agent.js +60 -0
  115. package/dist/index.d.ts +1 -0
  116. package/dist/index.js +4 -0
  117. package/dist/interface.d.ts +4 -0
  118. package/dist/interface.js +2 -0
  119. package/dist/notion.d.ts +144 -0
  120. package/dist/notion.js +547 -0
  121. package/dist/retry.d.ts +72 -0
  122. package/dist/retry.js +381 -0
  123. package/dist/utils/bookmarks.d.ts +32 -0
  124. package/dist/utils/bookmarks.js +98 -0
  125. package/dist/utils/daily-config.d.ts +22 -0
  126. package/dist/utils/daily-config.js +60 -0
  127. package/dist/utils/disk-cache.d.ts +80 -0
  128. package/dist/utils/disk-cache.js +291 -0
  129. package/dist/utils/fuzzy.d.ts +36 -0
  130. package/dist/utils/fuzzy.js +69 -0
  131. package/dist/utils/interactive-navigator.d.ts +63 -0
  132. package/dist/utils/interactive-navigator.js +123 -0
  133. package/dist/utils/markdown-to-blocks.d.ts +21 -0
  134. package/dist/utils/markdown-to-blocks.js +333 -0
  135. package/dist/utils/notion-resolver.d.ts +49 -0
  136. package/dist/utils/notion-resolver.js +278 -0
  137. package/dist/utils/notion-url-parser.d.ts +48 -0
  138. package/dist/utils/notion-url-parser.js +121 -0
  139. package/dist/utils/property-expander.d.ts +45 -0
  140. package/dist/utils/property-expander.js +323 -0
  141. package/dist/utils/schema-examples.d.ts +40 -0
  142. package/dist/utils/schema-examples.js +359 -0
  143. package/dist/utils/schema-extractor.d.ts +65 -0
  144. package/dist/utils/schema-extractor.js +235 -0
  145. package/dist/utils/shell-config.d.ts +30 -0
  146. package/dist/utils/shell-config.js +84 -0
  147. package/dist/utils/table-formatter.d.ts +36 -0
  148. package/dist/utils/table-formatter.js +125 -0
  149. package/dist/utils/templates.d.ts +30 -0
  150. package/dist/utils/templates.js +82 -0
  151. package/dist/utils/terminal-banner.d.ts +24 -0
  152. package/dist/utils/terminal-banner.js +34 -0
  153. package/dist/utils/token-validator.d.ts +42 -0
  154. package/dist/utils/token-validator.js +66 -0
  155. package/dist/utils/update-notifier.d.ts +26 -0
  156. package/dist/utils/update-notifier.js +54 -0
  157. package/dist/utils/workspace-cache.d.ts +58 -0
  158. package/dist/utils/workspace-cache.js +185 -0
  159. package/oclif.manifest.json +6471 -0
  160. package/package.json +118 -0
  161. package/scripts/banner.js +38 -0
  162. package/scripts/postinstall.js +44 -0
@@ -0,0 +1,43 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Search extends Command {
3
+ static description: string;
4
+ static args: {
5
+ query: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static examples: {
8
+ description: string;
9
+ command: string;
10
+ }[];
11
+ static flags: {
12
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
+ 'page-size': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
14
+ retry: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
+ timeout: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
16
+ 'no-cache': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
17
+ verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
18
+ minimal: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
19
+ markdown: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
20
+ 'compact-json': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
21
+ pretty: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
22
+ columns: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
23
+ sort: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
24
+ filter: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
25
+ csv: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
26
+ extended: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
27
+ 'no-truncate': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
28
+ 'no-header': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
29
+ query: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
30
+ sort_direction: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
31
+ property: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
32
+ start_cursor: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
33
+ page_size: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
34
+ database: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
35
+ 'created-after': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
36
+ 'created-before': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
37
+ 'edited-after': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
38
+ 'edited-before': import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
39
+ limit: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
40
+ raw: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
41
+ };
42
+ run(): Promise<void>;
43
+ }
@@ -0,0 +1,361 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const notion = require("../notion");
5
+ const client_1 = require("@notionhq/client");
6
+ const helper_1 = require("../helper");
7
+ const base_flags_1 = require("../base-flags");
8
+ const errors_1 = require("../errors");
9
+ const dayjs = require("dayjs");
10
+ const table_formatter_1 = require("../utils/table-formatter");
11
+ class Search extends core_1.Command {
12
+ async run() {
13
+ var _a;
14
+ const { args, flags } = await this.parse(Search);
15
+ // Positional arg as default, -q flag overrides if both provided
16
+ const query = (_a = flags.query) !== null && _a !== void 0 ? _a : args.query;
17
+ try {
18
+ // Validate date filters
19
+ if (flags['created-after'] && !dayjs(flags['created-after']).isValid()) {
20
+ throw new errors_1.NotionCLIError(errors_1.NotionCLIErrorCode.VALIDATION_ERROR, `Invalid date format for --created-after: ${flags['created-after']}. Use ISO 8601 format (YYYY-MM-DD).`, [], { userInput: flags['created-after'] });
21
+ }
22
+ if (flags['created-before'] && !dayjs(flags['created-before']).isValid()) {
23
+ throw new errors_1.NotionCLIError(errors_1.NotionCLIErrorCode.VALIDATION_ERROR, `Invalid date format for --created-before: ${flags['created-before']}. Use ISO 8601 format (YYYY-MM-DD).`, [], { userInput: flags['created-before'] });
24
+ }
25
+ if (flags['edited-after'] && !dayjs(flags['edited-after']).isValid()) {
26
+ throw new errors_1.NotionCLIError(errors_1.NotionCLIErrorCode.VALIDATION_ERROR, `Invalid date format for --edited-after: ${flags['edited-after']}. Use ISO 8601 format (YYYY-MM-DD).`, [], { userInput: flags['edited-after'] });
27
+ }
28
+ if (flags['edited-before'] && !dayjs(flags['edited-before']).isValid()) {
29
+ throw new errors_1.NotionCLIError(errors_1.NotionCLIErrorCode.VALIDATION_ERROR, `Invalid date format for --edited-before: ${flags['edited-before']}. Use ISO 8601 format (YYYY-MM-DD).`, [], { userInput: flags['edited-before'] });
30
+ }
31
+ const params = {};
32
+ if (query) {
33
+ params.query = query;
34
+ }
35
+ if (flags.sort_direction) {
36
+ let direction;
37
+ if (flags.sort_direction == 'asc') {
38
+ direction = 'ascending';
39
+ }
40
+ else {
41
+ direction = 'descending';
42
+ }
43
+ params.sort = {
44
+ direction: direction,
45
+ timestamp: 'last_edited_time',
46
+ };
47
+ }
48
+ if (flags.property == 'data_source' || flags.property == 'page') {
49
+ params.filter = {
50
+ value: flags.property,
51
+ property: 'object',
52
+ };
53
+ }
54
+ if (flags.start_cursor) {
55
+ params.start_cursor = flags.start_cursor;
56
+ }
57
+ // Increase page_size if we need to apply client-side filters
58
+ // This ensures we get enough results before filtering
59
+ const hasClientSideFilters = flags.database || flags['created-after'] ||
60
+ flags['created-before'] || flags['edited-after'] || flags['edited-before'];
61
+ if (hasClientSideFilters) {
62
+ // Use 100 (max) to get more results for filtering
63
+ params.page_size = 100;
64
+ }
65
+ else if (flags.page_size) {
66
+ params.page_size = flags.page_size;
67
+ }
68
+ if (process.env.DEBUG) {
69
+ console.log(params);
70
+ }
71
+ let res = await notion.search(params);
72
+ // Apply minimal flag to strip metadata
73
+ if (flags.minimal) {
74
+ res = (0, helper_1.stripMetadata)(res);
75
+ }
76
+ // Apply client-side filters (Notion API doesn't support these natively in search)
77
+ let filteredResults = res.results;
78
+ // Filter by database (parent)
79
+ if (flags.database) {
80
+ filteredResults = filteredResults.filter((result) => {
81
+ if ((0, client_1.isFullPage)(result) && result.parent) {
82
+ if ('database_id' in result.parent) {
83
+ return result.parent.database_id === flags.database;
84
+ }
85
+ }
86
+ return false;
87
+ });
88
+ }
89
+ // Filter by created date
90
+ if (flags['created-after']) {
91
+ const afterDate = dayjs(flags['created-after']);
92
+ filteredResults = filteredResults.filter((result) => {
93
+ if ('created_time' in result) {
94
+ return dayjs(result.created_time).isAfter(afterDate) ||
95
+ dayjs(result.created_time).isSame(afterDate, 'day');
96
+ }
97
+ return false;
98
+ });
99
+ }
100
+ if (flags['created-before']) {
101
+ const beforeDate = dayjs(flags['created-before']);
102
+ filteredResults = filteredResults.filter((result) => {
103
+ if ('created_time' in result) {
104
+ return dayjs(result.created_time).isBefore(beforeDate) ||
105
+ dayjs(result.created_time).isSame(beforeDate, 'day');
106
+ }
107
+ return false;
108
+ });
109
+ }
110
+ // Filter by edited date
111
+ if (flags['edited-after']) {
112
+ const afterDate = dayjs(flags['edited-after']);
113
+ filteredResults = filteredResults.filter((result) => {
114
+ if ('last_edited_time' in result) {
115
+ return dayjs(result.last_edited_time).isAfter(afterDate) ||
116
+ dayjs(result.last_edited_time).isSame(afterDate, 'day');
117
+ }
118
+ return false;
119
+ });
120
+ }
121
+ if (flags['edited-before']) {
122
+ const beforeDate = dayjs(flags['edited-before']);
123
+ filteredResults = filteredResults.filter((result) => {
124
+ if ('last_edited_time' in result) {
125
+ return dayjs(result.last_edited_time).isBefore(beforeDate) ||
126
+ dayjs(result.last_edited_time).isSame(beforeDate, 'day');
127
+ }
128
+ return false;
129
+ });
130
+ }
131
+ // Apply limit after all filters
132
+ if (flags.limit) {
133
+ filteredResults = filteredResults.slice(0, flags.limit);
134
+ }
135
+ // Update res.results with filtered results
136
+ res.results = filteredResults;
137
+ // Handle JSON output for automation (takes precedence)
138
+ if (flags.json) {
139
+ this.log(JSON.stringify({
140
+ success: true,
141
+ data: res,
142
+ timestamp: new Date().toISOString()
143
+ }, null, 2));
144
+ process.exit(0);
145
+ return;
146
+ }
147
+ // Define columns for table output
148
+ const columns = {
149
+ title: {
150
+ get: (row) => {
151
+ if (row.object == 'database' && (0, client_1.isFullDatabase)(row)) {
152
+ return (0, helper_1.getDbTitle)(row);
153
+ }
154
+ if (row.object == 'data_source' && (0, client_1.isFullDataSource)(row)) {
155
+ return (0, helper_1.getDataSourceTitle)(row);
156
+ }
157
+ if (row.object == 'page' && (0, client_1.isFullPage)(row)) {
158
+ return (0, helper_1.getPageTitle)(row);
159
+ }
160
+ return 'Untitled';
161
+ },
162
+ },
163
+ object: {},
164
+ id: {},
165
+ url: {},
166
+ };
167
+ // Handle compact JSON output
168
+ if (flags['compact-json']) {
169
+ (0, helper_1.outputCompactJson)(res.results);
170
+ process.exit(0);
171
+ return;
172
+ }
173
+ // Handle markdown table output
174
+ if (flags.markdown) {
175
+ (0, helper_1.outputMarkdownTable)(res.results, columns);
176
+ process.exit(0);
177
+ return;
178
+ }
179
+ // Handle pretty table output
180
+ if (flags.pretty) {
181
+ (0, helper_1.outputPrettyTable)(res.results, columns);
182
+ // Show hint after table output (use first result as sample)
183
+ if (res.results.length > 0) {
184
+ (0, helper_1.showRawFlagHint)(res.results.length, res.results[0]);
185
+ }
186
+ process.exit(0);
187
+ return;
188
+ }
189
+ // Handle raw JSON output
190
+ if (flags.raw) {
191
+ (0, helper_1.outputRawJson)(res);
192
+ process.exit(0);
193
+ return;
194
+ }
195
+ // Handle table output (default)
196
+ const options = {
197
+ printLine: this.log.bind(this),
198
+ ...flags,
199
+ };
200
+ (0, table_formatter_1.formatTable)(res.results, columns, options);
201
+ // Show hint after table output to make -r flag discoverable
202
+ // Use first result as sample to count fields
203
+ if (res.results.length > 0) {
204
+ (0, helper_1.showRawFlagHint)(res.results.length, res.results[0]);
205
+ }
206
+ }
207
+ catch (error) {
208
+ const cliError = error instanceof errors_1.NotionCLIError
209
+ ? error
210
+ : (0, errors_1.wrapNotionError)(error, {
211
+ endpoint: 'search',
212
+ userInput: query || flags.filter
213
+ });
214
+ if (flags.json) {
215
+ this.log(JSON.stringify(cliError.toJSON(), null, 2));
216
+ }
217
+ else {
218
+ this.error(cliError.toHumanString());
219
+ }
220
+ process.exit(1);
221
+ }
222
+ }
223
+ }
224
+ Search.description = 'Search by title';
225
+ Search.args = {
226
+ query: core_1.Args.string({
227
+ required: false,
228
+ description: 'Search query (or use -q flag)',
229
+ }),
230
+ };
231
+ Search.examples = [
232
+ {
233
+ description: 'Search by title (positional argument)',
234
+ command: `$ notion-cli search 'My Page'`,
235
+ },
236
+ {
237
+ description: 'Search with full data (recommended for AI assistants)',
238
+ command: `$ notion-cli search 'My Page' -r`,
239
+ },
240
+ {
241
+ description: 'Search by title (flag syntax)',
242
+ command: `$ notion-cli search -q 'My Page'`,
243
+ },
244
+ {
245
+ description: 'Search only within a specific database',
246
+ command: `$ notion-cli search -q 'meeting' --database DB_ID`,
247
+ },
248
+ {
249
+ description: 'Search with created date filter',
250
+ command: `$ notion-cli search -q 'report' --created-after 2025-10-01`,
251
+ },
252
+ {
253
+ description: 'Search with edited date filter',
254
+ command: `$ notion-cli search -q 'project' --edited-after 2025-10-20`,
255
+ },
256
+ {
257
+ description: 'Limit number of results',
258
+ command: `$ notion-cli search -q 'task' --limit 20`,
259
+ },
260
+ {
261
+ description: 'Combined filters',
262
+ command: `$ notion-cli search -q 'project' -d DB_ID --edited-after 2025-10-20 --limit 10`,
263
+ },
264
+ {
265
+ description: 'Search by title and output csv',
266
+ command: `$ notion-cli search -q 'My Page' --csv`,
267
+ },
268
+ {
269
+ description: 'Search by title and output raw json',
270
+ command: `$ notion-cli search -q 'My Page' -r`,
271
+ },
272
+ {
273
+ description: 'Search by title and output markdown table',
274
+ command: `$ notion-cli search -q 'My Page' --markdown`,
275
+ },
276
+ {
277
+ description: 'Search by title and output compact JSON',
278
+ command: `$ notion-cli search -q 'My Page' --compact-json`,
279
+ },
280
+ {
281
+ description: 'Search by title and output pretty table',
282
+ command: `$ notion-cli search -q 'My Page' --pretty`,
283
+ },
284
+ {
285
+ description: 'Search by title and output table with specific columns',
286
+ command: `$ notion-cli search -q 'My Page' --columns=title,object`,
287
+ },
288
+ {
289
+ description: 'Search by title and output table with specific columns and sort direction',
290
+ command: `$ notion-cli search -q 'My Page' --columns=title,object -d asc`,
291
+ },
292
+ {
293
+ description: 'Search by title and output table with specific columns and sort direction and page size',
294
+ command: `$ notion-cli search -q 'My Page' -columns=title,object -d asc -s 10`,
295
+ },
296
+ {
297
+ description: 'Search by title and output table with specific columns and sort direction and page size and start cursor',
298
+ command: `$ notion-cli search -q 'My Page' --columns=title,object -d asc -s 10 -c START_CURSOR_ID`,
299
+ },
300
+ {
301
+ description: 'Search by title and output table with specific columns and sort direction and page size and start cursor and property',
302
+ command: `$ notion-cli search -q 'My Page' --columns=title,object -d asc -s 10 -c START_CURSOR_ID -p page`,
303
+ },
304
+ {
305
+ description: 'Search and output JSON for automation',
306
+ command: `$ notion-cli search -q 'My Page' --json`,
307
+ },
308
+ ];
309
+ Search.flags = {
310
+ query: core_1.Flags.string({
311
+ char: 'q',
312
+ description: 'The text that the API compares page and database titles against',
313
+ }),
314
+ sort_direction: core_1.Flags.string({
315
+ char: 'd',
316
+ options: ['asc', 'desc'],
317
+ description: 'The direction to sort results. The only supported timestamp value is "last_edited_time"',
318
+ default: 'desc',
319
+ }),
320
+ property: core_1.Flags.string({
321
+ char: 'p',
322
+ options: ['data_source', 'page'],
323
+ }),
324
+ start_cursor: core_1.Flags.string({
325
+ char: 'c',
326
+ }),
327
+ page_size: core_1.Flags.integer({
328
+ char: 's',
329
+ description: 'The number of results to return. The default is 5, with a minimum of 1 and a maximum of 100.',
330
+ min: 1,
331
+ max: 100,
332
+ default: 5,
333
+ }),
334
+ database: core_1.Flags.string({
335
+ description: 'Limit search to pages within a specific database (data source ID)',
336
+ }),
337
+ 'created-after': core_1.Flags.string({
338
+ description: 'Filter results created after this date (ISO 8601 format: YYYY-MM-DD)',
339
+ }),
340
+ 'created-before': core_1.Flags.string({
341
+ description: 'Filter results created before this date (ISO 8601 format: YYYY-MM-DD)',
342
+ }),
343
+ 'edited-after': core_1.Flags.string({
344
+ description: 'Filter results edited after this date (ISO 8601 format: YYYY-MM-DD)',
345
+ }),
346
+ 'edited-before': core_1.Flags.string({
347
+ description: 'Filter results edited before this date (ISO 8601 format: YYYY-MM-DD)',
348
+ }),
349
+ limit: core_1.Flags.integer({
350
+ description: 'Maximum number of results to return (applied after filters)',
351
+ min: 1,
352
+ }),
353
+ raw: core_1.Flags.boolean({
354
+ char: 'r',
355
+ description: 'output raw json (recommended for AI assistants - returns all search results)',
356
+ }),
357
+ ...table_formatter_1.tableFlags,
358
+ ...base_flags_1.OutputFormatFlags,
359
+ ...base_flags_1.AutomationFlags,
360
+ };
361
+ exports.default = Search;
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Stats Dashboard Command
3
+ *
4
+ * Shows a bird's-eye view of the Notion workspace: database count, user count,
5
+ * property type breakdown, and per-database details. Data comes primarily from
6
+ * the workspace cache (fast), with optional --live flag for page counts (slower).
7
+ *
8
+ * notion-cli stats # fast dashboard from cache
9
+ * notion-cli stats --live # also fetch page counts per DB
10
+ * notion-cli stats --relations # show database relation graph
11
+ * notion-cli stats --json # JSON output for automation
12
+ */
13
+ import { Command } from '@oclif/core';
14
+ export default class Stats extends Command {
15
+ static description: string;
16
+ static aliases: string[];
17
+ static examples: {
18
+ description: string;
19
+ command: string;
20
+ }[];
21
+ static flags: {
22
+ live: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
23
+ relations: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
24
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
25
+ 'page-size': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
26
+ retry: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
27
+ timeout: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
28
+ 'no-cache': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
29
+ verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
30
+ minimal: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
31
+ };
32
+ run(): Promise<void>;
33
+ /** Convert milliseconds to a human-friendly age string (e.g. "2h ago"). */
34
+ private formatAge;
35
+ }