@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,360 @@
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 fs = require("fs");
7
+ const path = require("path");
8
+ const helper_1 = require("../../helper");
9
+ const notion_1 = require("../../notion");
10
+ const base_flags_1 = require("../../base-flags");
11
+ const errors_1 = require("../../errors");
12
+ const notion_resolver_1 = require("../../utils/notion-resolver");
13
+ const table_formatter_1 = require("../../utils/table-formatter");
14
+ class DbQuery extends core_1.Command {
15
+ async run() {
16
+ const { flags, args } = await this.parse(DbQuery);
17
+ try {
18
+ // Handle deprecation warnings (output to stderr to not pollute stdout)
19
+ if (flags.rawFilter) {
20
+ console.error('⚠️ Warning: --rawFilter is deprecated and will be removed in v6.0.0');
21
+ console.error(' Use --filter instead: notion-cli db query DS_ID --filter \'...\'');
22
+ console.error('');
23
+ }
24
+ if (flags.fileFilter) {
25
+ console.error('⚠️ Warning: --fileFilter is deprecated and will be removed in v6.0.0');
26
+ console.error(' Use --file-filter instead: notion-cli db query DS_ID --file-filter ./filter.json');
27
+ console.error('');
28
+ }
29
+ // Resolve ID from URL, direct ID, or name (future)
30
+ const databaseId = await (0, notion_resolver_1.resolveNotionId)(args.database_id, 'database');
31
+ let queryParams;
32
+ // Build filter
33
+ let filter = undefined;
34
+ try {
35
+ if (flags.filter || flags.rawFilter) {
36
+ // JSON filter object (new flag or deprecated rawFilter)
37
+ const filterStr = flags.filter || flags.rawFilter;
38
+ try {
39
+ filter = JSON.parse(filterStr);
40
+ }
41
+ catch (error) {
42
+ throw errors_1.NotionCLIErrorFactory.invalidJson(filterStr, error);
43
+ }
44
+ }
45
+ else if (flags['file-filter'] || flags.fileFilter) {
46
+ // Load from file (new flag or deprecated fileFilter)
47
+ const filterFile = flags['file-filter'] || flags.fileFilter;
48
+ // Resolve path and prevent directory traversal outside cwd
49
+ const basePath = path.resolve('./');
50
+ const fp = path.resolve(basePath, filterFile);
51
+ if (!fp.startsWith(basePath)) {
52
+ throw new Error(`Invalid file path: must be within current directory`);
53
+ }
54
+ let fj;
55
+ try {
56
+ fj = fs.readFileSync(fp, { encoding: 'utf-8' });
57
+ filter = JSON.parse(fj);
58
+ }
59
+ catch (error) {
60
+ if (error.code === 'ENOENT') {
61
+ throw errors_1.NotionCLIErrorFactory.invalidJson(filterFile, new Error(`File not found: ${filterFile}`));
62
+ }
63
+ throw errors_1.NotionCLIErrorFactory.invalidJson(fj, error);
64
+ }
65
+ }
66
+ else if (flags.search) {
67
+ // Simple text search - convert to Notion filter
68
+ // Search across common text properties using OR
69
+ // Note: This searches properties named "Name", "Title", and "Description"
70
+ // For more complex searches, use --filter with explicit property names
71
+ filter = {
72
+ or: [
73
+ { property: 'Name', title: { contains: flags.search } },
74
+ { property: 'Title', title: { contains: flags.search } },
75
+ { property: 'Description', rich_text: { contains: flags.search } },
76
+ { property: 'Name', rich_text: { contains: flags.search } },
77
+ ]
78
+ };
79
+ }
80
+ // Build sorts
81
+ const sorts = [];
82
+ const direction = flags['sort-direction'] == 'desc' ? 'descending' : 'ascending';
83
+ if (flags['sort-property']) {
84
+ sorts.push({
85
+ property: flags['sort-property'],
86
+ direction: direction,
87
+ });
88
+ }
89
+ // Build query parameters
90
+ queryParams = {
91
+ data_source_id: databaseId,
92
+ filter: filter,
93
+ sorts: sorts.length > 0 ? sorts : undefined,
94
+ page_size: flags['page-size'],
95
+ };
96
+ }
97
+ catch (e) {
98
+ // Re-throw NotionCLIError, wrap others
99
+ if (e instanceof errors_1.NotionCLIError) {
100
+ throw e;
101
+ }
102
+ throw (0, errors_1.wrapNotionError)(e, {
103
+ resourceType: 'database',
104
+ userInput: args.database_id
105
+ });
106
+ }
107
+ // Fetch pages from database
108
+ let pages = [];
109
+ if (flags['page-all']) {
110
+ pages = await notion.fetchAllPagesInDS(databaseId, queryParams.filter);
111
+ }
112
+ else {
113
+ const res = await notion_1.client.dataSources.query(queryParams);
114
+ pages.push(...res.results);
115
+ }
116
+ // Apply minimal flag to strip metadata
117
+ if (flags.minimal) {
118
+ pages = (0, helper_1.stripMetadata)(pages);
119
+ }
120
+ // Apply property selection if --select flag is used
121
+ if (flags.select) {
122
+ const selectedProps = flags.select.split(',').map(p => p.trim());
123
+ pages = pages.map((page) => {
124
+ if (page.object === 'page' && page.properties) {
125
+ // Keep core fields, filter properties
126
+ const filtered = {
127
+ ...page,
128
+ properties: {}
129
+ };
130
+ // Copy only selected properties
131
+ selectedProps.forEach(propName => {
132
+ if (page.properties[propName]) {
133
+ filtered.properties[propName] = page.properties[propName];
134
+ }
135
+ });
136
+ return filtered;
137
+ }
138
+ return page;
139
+ });
140
+ }
141
+ // Define columns for table output
142
+ const columns = {
143
+ title: {
144
+ get: (row) => {
145
+ if (row.object == 'data_source' && (0, client_1.isFullDataSource)(row)) {
146
+ return (0, helper_1.getDataSourceTitle)(row);
147
+ }
148
+ if (row.object == 'page' && (0, client_1.isFullPage)(row)) {
149
+ return (0, helper_1.getPageTitle)(row);
150
+ }
151
+ return 'Untitled';
152
+ },
153
+ },
154
+ object: {},
155
+ id: {},
156
+ url: {},
157
+ };
158
+ // Handle compact JSON output
159
+ if (flags['compact-json']) {
160
+ (0, helper_1.outputCompactJson)(pages);
161
+ process.exit(0);
162
+ return;
163
+ }
164
+ // Handle markdown table output
165
+ if (flags.markdown) {
166
+ (0, helper_1.outputMarkdownTable)(pages, columns);
167
+ process.exit(0);
168
+ return;
169
+ }
170
+ // Handle pretty table output
171
+ if (flags.pretty) {
172
+ (0, helper_1.outputPrettyTable)(pages, columns);
173
+ // Show hint after table output (use first page as sample)
174
+ if (pages.length > 0) {
175
+ (0, helper_1.showRawFlagHint)(pages.length, pages[0]);
176
+ }
177
+ process.exit(0);
178
+ return;
179
+ }
180
+ // Handle JSON output for automation
181
+ if (flags.json) {
182
+ this.log(JSON.stringify({
183
+ success: true,
184
+ data: pages,
185
+ count: pages.length,
186
+ timestamp: new Date().toISOString()
187
+ }, null, 2));
188
+ process.exit(0);
189
+ return;
190
+ }
191
+ // Handle raw JSON output (legacy)
192
+ if (flags.raw) {
193
+ (0, helper_1.outputRawJson)(pages);
194
+ process.exit(0);
195
+ return;
196
+ }
197
+ // Handle table output (default)
198
+ const options = {
199
+ printLine: this.log.bind(this),
200
+ ...flags,
201
+ };
202
+ (0, table_formatter_1.formatTable)(pages, columns, options);
203
+ // Show hint after table output to make -r flag discoverable
204
+ // Use first page as sample to count fields
205
+ if (pages.length > 0) {
206
+ (0, helper_1.showRawFlagHint)(pages.length, pages[0]);
207
+ }
208
+ process.exit(0);
209
+ }
210
+ catch (error) {
211
+ const cliError = error instanceof errors_1.NotionCLIError
212
+ ? error
213
+ : (0, errors_1.wrapNotionError)(error, {
214
+ resourceType: 'database',
215
+ attemptedId: args.database_id,
216
+ endpoint: 'dataSources.query'
217
+ });
218
+ if (flags.json) {
219
+ this.log(JSON.stringify(cliError.toJSON(), null, 2));
220
+ }
221
+ else {
222
+ this.error(cliError.toHumanString());
223
+ }
224
+ process.exit(1);
225
+ }
226
+ }
227
+ }
228
+ DbQuery.description = 'Query a database';
229
+ DbQuery.aliases = ['db:q'];
230
+ DbQuery.examples = [
231
+ {
232
+ description: 'Query a database with full data (recommended for AI assistants)',
233
+ command: `$ notion-cli db query DATABASE_ID --raw`,
234
+ },
235
+ {
236
+ description: 'Query all records as JSON',
237
+ command: `$ notion-cli db query DATABASE_ID --json`,
238
+ },
239
+ {
240
+ description: 'Filter with JSON object (recommended for AI agents)',
241
+ command: `$ notion-cli db query DATABASE_ID --filter '{"property": "Status", "select": {"equals": "Done"}}' --json`,
242
+ },
243
+ {
244
+ description: 'Simple text search across properties',
245
+ command: `$ notion-cli db query DATABASE_ID --search "urgent" --json`,
246
+ },
247
+ {
248
+ description: 'Load complex filter from file',
249
+ command: `$ notion-cli db query DATABASE_ID --file-filter ./filter.json --json`,
250
+ },
251
+ {
252
+ description: 'Query with AND filter',
253
+ command: `$ notion-cli db query DATABASE_ID --filter '{"and": [{"property": "Status", "select": {"equals": "Done"}}, {"property": "Priority", "number": {"greater_than": 5}}]}' --json`,
254
+ },
255
+ {
256
+ description: 'Query using database URL',
257
+ command: `$ notion-cli db query https://notion.so/DATABASE_ID --json`,
258
+ },
259
+ {
260
+ description: 'Query with sorting',
261
+ command: `$ notion-cli db query DATABASE_ID --sort-property Name --sort-direction desc`,
262
+ },
263
+ {
264
+ description: 'Query with pagination',
265
+ command: `$ notion-cli db query DATABASE_ID --page-size 50`,
266
+ },
267
+ {
268
+ description: 'Get all pages (bypass pagination)',
269
+ command: `$ notion-cli db query DATABASE_ID --page-all`,
270
+ },
271
+ {
272
+ description: 'Output as CSV',
273
+ command: `$ notion-cli db query DATABASE_ID --csv`,
274
+ },
275
+ {
276
+ description: 'Output as markdown table',
277
+ command: `$ notion-cli db query DATABASE_ID --markdown`,
278
+ },
279
+ {
280
+ description: 'Output as compact JSON',
281
+ command: `$ notion-cli db query DATABASE_ID --compact-json`,
282
+ },
283
+ {
284
+ description: 'Output as pretty table',
285
+ command: `$ notion-cli db query DATABASE_ID --pretty`,
286
+ },
287
+ {
288
+ description: 'Select specific properties (60-80% token reduction)',
289
+ command: `$ notion-cli db query DATABASE_ID --select "title,status,priority" --json`,
290
+ },
291
+ ];
292
+ DbQuery.args = {
293
+ database_id: core_1.Args.string({
294
+ required: true,
295
+ description: 'Database or data source ID or URL (required for automation)',
296
+ }),
297
+ };
298
+ DbQuery.flags = {
299
+ 'page-size': core_1.Flags.integer({
300
+ char: 'p',
301
+ description: 'The number of results to return (1-100)',
302
+ min: 1,
303
+ max: 100,
304
+ default: 10,
305
+ }),
306
+ 'page-all': core_1.Flags.boolean({
307
+ char: 'A',
308
+ description: 'Get all pages (bypass pagination)',
309
+ default: false,
310
+ }),
311
+ 'sort-property': core_1.Flags.string({
312
+ description: 'The property to sort results by',
313
+ }),
314
+ 'sort-direction': core_1.Flags.string({
315
+ options: ['asc', 'desc'],
316
+ description: 'The direction to sort results',
317
+ default: 'asc',
318
+ }),
319
+ raw: core_1.Flags.boolean({
320
+ char: 'r',
321
+ description: 'Output raw JSON (recommended for AI assistants - returns all page data)',
322
+ default: false,
323
+ }),
324
+ ...table_formatter_1.tableFlags,
325
+ ...base_flags_1.AutomationFlags,
326
+ ...base_flags_1.OutputFormatFlags,
327
+ // New simplified filter interface (placed AFTER table flags to override)
328
+ filter: core_1.Flags.string({
329
+ char: 'f',
330
+ description: 'Filter as JSON object (Notion filter API format)',
331
+ exclusive: ['search', 'file-filter', 'rawFilter', 'fileFilter'],
332
+ }),
333
+ 'file-filter': core_1.Flags.string({
334
+ char: 'F',
335
+ description: 'Load filter from JSON file',
336
+ exclusive: ['filter', 'search', 'rawFilter', 'fileFilter'],
337
+ }),
338
+ search: core_1.Flags.string({
339
+ char: 's',
340
+ description: 'Simple text search (searches across title and common text properties)',
341
+ exclusive: ['filter', 'file-filter', 'rawFilter', 'fileFilter'],
342
+ }),
343
+ select: core_1.Flags.string({
344
+ description: 'Select specific properties to return (comma-separated). Reduces token usage by 60-80%.',
345
+ examples: ['title,status', 'title,status,priority,due_date'],
346
+ }),
347
+ // DEPRECATED: Keep for backward compatibility
348
+ rawFilter: core_1.Flags.string({
349
+ char: 'a',
350
+ description: 'DEPRECATED: Use --filter instead. JSON stringified filter string',
351
+ hidden: true,
352
+ exclusive: ['filter', 'search', 'file-filter', 'fileFilter'],
353
+ }),
354
+ fileFilter: core_1.Flags.string({
355
+ description: 'DEPRECATED: Use --file-filter instead. JSON filter file path',
356
+ hidden: true,
357
+ exclusive: ['filter', 'search', 'file-filter', 'rawFilter'],
358
+ }),
359
+ };
360
+ exports.default = DbQuery;
@@ -0,0 +1,33 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class DbRetrieve extends Command {
3
+ static description: string;
4
+ static aliases: string[];
5
+ static examples: {
6
+ description: string;
7
+ command: string;
8
+ }[];
9
+ static args: {
10
+ database_id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
11
+ };
12
+ static flags: {
13
+ markdown: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
14
+ 'compact-json': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
15
+ pretty: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
16
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
17
+ 'page-size': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
18
+ retry: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
19
+ timeout: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
20
+ 'no-cache': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
21
+ verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
22
+ minimal: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
23
+ columns: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
24
+ sort: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
25
+ filter: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
26
+ csv: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
27
+ extended: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
28
+ 'no-truncate': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
29
+ 'no-header': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
30
+ raw: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
31
+ };
32
+ run(): Promise<void>;
33
+ }
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const table_formatter_1 = require("../../utils/table-formatter");
5
+ const notion = require("../../notion");
6
+ const helper_1 = require("../../helper");
7
+ const base_flags_1 = require("../../base-flags");
8
+ const errors_1 = require("../../errors");
9
+ const notion_resolver_1 = require("../../utils/notion-resolver");
10
+ class DbRetrieve extends core_1.Command {
11
+ async run() {
12
+ const { args, flags } = await this.parse(DbRetrieve);
13
+ try {
14
+ // Resolve ID from URL, direct ID, or name (future)
15
+ const dataSourceId = await (0, notion_resolver_1.resolveNotionId)(args.database_id, 'database');
16
+ let res = await notion.retrieveDataSource(dataSourceId);
17
+ // Apply minimal flag to strip metadata
18
+ if (flags.minimal) {
19
+ res = (0, helper_1.stripMetadata)(res);
20
+ }
21
+ // Define columns for table output
22
+ const columns = {
23
+ title: {
24
+ get: (row) => {
25
+ return (0, helper_1.getDataSourceTitle)(row);
26
+ },
27
+ },
28
+ object: {},
29
+ id: {},
30
+ url: {},
31
+ };
32
+ // Handle compact JSON output
33
+ if (flags['compact-json']) {
34
+ (0, helper_1.outputCompactJson)(res);
35
+ process.exit(0);
36
+ return;
37
+ }
38
+ // Handle markdown table output
39
+ if (flags.markdown) {
40
+ (0, helper_1.outputMarkdownTable)([res], columns);
41
+ process.exit(0);
42
+ return;
43
+ }
44
+ // Handle pretty table output
45
+ if (flags.pretty) {
46
+ (0, helper_1.outputPrettyTable)([res], columns);
47
+ // Show hint after table output
48
+ (0, helper_1.showRawFlagHint)(1, res);
49
+ process.exit(0);
50
+ return;
51
+ }
52
+ // Handle JSON output for automation
53
+ if (flags.json) {
54
+ this.log(JSON.stringify({
55
+ success: true,
56
+ data: res,
57
+ timestamp: new Date().toISOString()
58
+ }, null, 2));
59
+ process.exit(0);
60
+ return;
61
+ }
62
+ // Handle raw JSON output (legacy)
63
+ if (flags.raw) {
64
+ (0, helper_1.outputRawJson)(res);
65
+ process.exit(0);
66
+ return;
67
+ }
68
+ // Handle table output (default)
69
+ const options = {
70
+ printLine: this.log.bind(this),
71
+ ...flags,
72
+ };
73
+ (0, table_formatter_1.formatTable)([res], columns, options);
74
+ // Show hint after table output to make -r flag discoverable
75
+ (0, helper_1.showRawFlagHint)(1, res);
76
+ process.exit(0);
77
+ }
78
+ catch (error) {
79
+ const cliError = error instanceof errors_1.NotionCLIError
80
+ ? error
81
+ : (0, errors_1.wrapNotionError)(error, {
82
+ resourceType: 'database',
83
+ endpoint: 'dataSources.retrieve'
84
+ });
85
+ if (flags.json) {
86
+ this.log(JSON.stringify(cliError.toJSON(), null, 2));
87
+ }
88
+ else {
89
+ this.error(cliError.toHumanString());
90
+ }
91
+ process.exit(1);
92
+ }
93
+ }
94
+ }
95
+ DbRetrieve.description = 'Retrieve a data source (table) schema and properties';
96
+ DbRetrieve.aliases = ['db:r', 'ds:retrieve', 'ds:r'];
97
+ DbRetrieve.examples = [
98
+ {
99
+ description: 'Retrieve a data source with full schema (recommended for AI assistants)',
100
+ command: 'notion-cli db retrieve DATA_SOURCE_ID -r',
101
+ },
102
+ {
103
+ description: 'Retrieve a data source schema via data_source_id',
104
+ command: 'notion-cli db retrieve DATA_SOURCE_ID',
105
+ },
106
+ {
107
+ description: 'Retrieve a data source via URL',
108
+ command: 'notion-cli db retrieve https://notion.so/DATABASE_ID',
109
+ },
110
+ {
111
+ description: 'Retrieve a data source and output as markdown table',
112
+ command: 'notion-cli db retrieve DATA_SOURCE_ID --markdown',
113
+ },
114
+ {
115
+ description: 'Retrieve a data source and output as compact JSON',
116
+ command: 'notion-cli db retrieve DATA_SOURCE_ID --compact-json',
117
+ },
118
+ ];
119
+ DbRetrieve.args = {
120
+ database_id: core_1.Args.string({
121
+ required: true,
122
+ description: 'Data source ID or URL (the ID of the table whose schema you want to retrieve)',
123
+ }),
124
+ };
125
+ DbRetrieve.flags = {
126
+ raw: core_1.Flags.boolean({
127
+ char: 'r',
128
+ description: 'output raw json (recommended for AI assistants - returns full schema)',
129
+ }),
130
+ ...table_formatter_1.tableFlags,
131
+ ...base_flags_1.AutomationFlags,
132
+ ...base_flags_1.OutputFormatFlags,
133
+ };
134
+ exports.default = DbRetrieve;
@@ -0,0 +1,32 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class DbSchema extends Command {
3
+ static description: string;
4
+ static aliases: string[];
5
+ static examples: {
6
+ description: string;
7
+ command: string;
8
+ }[];
9
+ static args: {
10
+ data_source_id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
11
+ };
12
+ static flags: {
13
+ output: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
14
+ properties: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
15
+ markdown: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
16
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
17
+ 'with-examples': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
18
+ };
19
+ run(): Promise<void>;
20
+ /**
21
+ * Output schema with examples in human-readable format
22
+ */
23
+ private outputSchemaWithExamples;
24
+ /**
25
+ * Output schema as formatted table
26
+ */
27
+ private outputTable;
28
+ /**
29
+ * Format schema as YAML
30
+ */
31
+ private formatAsYaml;
32
+ }