@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.
- package/LICENSE +21 -0
- package/README.md +552 -0
- package/bin/dev +17 -0
- package/bin/dev.cmd +3 -0
- package/bin/run +14 -0
- package/bin/run.cmd +3 -0
- package/dist/base-command.d.ts +73 -0
- package/dist/base-command.js +179 -0
- package/dist/base-flags.d.ts +14 -0
- package/dist/base-flags.js +59 -0
- package/dist/cache.d.ts +84 -0
- package/dist/cache.js +351 -0
- package/dist/commands/append.d.ts +37 -0
- package/dist/commands/append.js +120 -0
- package/dist/commands/batch/delete.d.ts +42 -0
- package/dist/commands/batch/delete.js +199 -0
- package/dist/commands/batch/retrieve.d.ts +43 -0
- package/dist/commands/batch/retrieve.js +272 -0
- package/dist/commands/block/append.d.ts +42 -0
- package/dist/commands/block/append.js +219 -0
- package/dist/commands/block/delete.d.ts +30 -0
- package/dist/commands/block/delete.js +97 -0
- package/dist/commands/block/retrieve/children.d.ts +31 -0
- package/dist/commands/block/retrieve/children.js +177 -0
- package/dist/commands/block/retrieve.d.ts +30 -0
- package/dist/commands/block/retrieve.js +101 -0
- package/dist/commands/block/update.d.ts +45 -0
- package/dist/commands/block/update.js +242 -0
- package/dist/commands/bookmark/list.d.ts +30 -0
- package/dist/commands/bookmark/list.js +60 -0
- package/dist/commands/bookmark/remove.d.ts +26 -0
- package/dist/commands/bookmark/remove.js +47 -0
- package/dist/commands/bookmark/set.d.ts +29 -0
- package/dist/commands/bookmark/set.js +96 -0
- package/dist/commands/browse.d.ts +13 -0
- package/dist/commands/browse.js +44 -0
- package/dist/commands/cache/info.d.ts +19 -0
- package/dist/commands/cache/info.js +145 -0
- package/dist/commands/config/set-token.d.ts +22 -0
- package/dist/commands/config/set-token.js +137 -0
- package/dist/commands/daily/index.d.ts +32 -0
- package/dist/commands/daily/index.js +135 -0
- package/dist/commands/daily/setup.d.ts +42 -0
- package/dist/commands/daily/setup.js +149 -0
- package/dist/commands/db/create.d.ts +31 -0
- package/dist/commands/db/create.js +124 -0
- package/dist/commands/db/query.d.ts +41 -0
- package/dist/commands/db/query.js +360 -0
- package/dist/commands/db/retrieve.d.ts +33 -0
- package/dist/commands/db/retrieve.js +134 -0
- package/dist/commands/db/schema.d.ts +32 -0
- package/dist/commands/db/schema.js +308 -0
- package/dist/commands/db/update.d.ts +31 -0
- package/dist/commands/db/update.js +117 -0
- package/dist/commands/doctor.d.ts +50 -0
- package/dist/commands/doctor.js +420 -0
- package/dist/commands/init.d.ts +65 -0
- package/dist/commands/init.js +479 -0
- package/dist/commands/list.d.ts +29 -0
- package/dist/commands/list.js +219 -0
- package/dist/commands/open.d.ts +29 -0
- package/dist/commands/open.js +100 -0
- package/dist/commands/page/create.d.ts +33 -0
- package/dist/commands/page/create.js +261 -0
- package/dist/commands/page/delete.d.ts +36 -0
- package/dist/commands/page/delete.js +107 -0
- package/dist/commands/page/export.d.ts +38 -0
- package/dist/commands/page/export.js +120 -0
- package/dist/commands/page/retrieve/property_item.d.ts +24 -0
- package/dist/commands/page/retrieve/property_item.js +75 -0
- package/dist/commands/page/retrieve.d.ts +36 -0
- package/dist/commands/page/retrieve.js +244 -0
- package/dist/commands/page/update.d.ts +34 -0
- package/dist/commands/page/update.js +184 -0
- package/dist/commands/quick.d.ts +35 -0
- package/dist/commands/quick.js +168 -0
- package/dist/commands/search.d.ts +43 -0
- package/dist/commands/search.js +361 -0
- package/dist/commands/stats.d.ts +35 -0
- package/dist/commands/stats.js +274 -0
- package/dist/commands/sync.d.ts +24 -0
- package/dist/commands/sync.js +183 -0
- package/dist/commands/template/get.d.ts +28 -0
- package/dist/commands/template/get.js +59 -0
- package/dist/commands/template/list.d.ts +32 -0
- package/dist/commands/template/list.js +62 -0
- package/dist/commands/template/remove.d.ts +27 -0
- package/dist/commands/template/remove.js +48 -0
- package/dist/commands/template/save.d.ts +32 -0
- package/dist/commands/template/save.js +92 -0
- package/dist/commands/template/use.d.ts +34 -0
- package/dist/commands/template/use.js +142 -0
- package/dist/commands/user/list.d.ts +27 -0
- package/dist/commands/user/list.js +99 -0
- package/dist/commands/user/retrieve/bot.d.ts +28 -0
- package/dist/commands/user/retrieve/bot.js +96 -0
- package/dist/commands/user/retrieve.d.ts +30 -0
- package/dist/commands/user/retrieve.js +103 -0
- package/dist/commands/whoami.d.ts +19 -0
- package/dist/commands/whoami.js +175 -0
- package/dist/deduplication.d.ts +41 -0
- package/dist/deduplication.js +71 -0
- package/dist/envelope.d.ts +169 -0
- package/dist/envelope.js +257 -0
- package/dist/errors/enhanced-errors.d.ts +168 -0
- package/dist/errors/enhanced-errors.js +567 -0
- package/dist/errors/index.d.ts +18 -0
- package/dist/errors/index.js +33 -0
- package/dist/examples/cache-retry-examples.d.ts +64 -0
- package/dist/examples/cache-retry-examples.js +375 -0
- package/dist/helper.d.ts +102 -0
- package/dist/helper.js +885 -0
- package/dist/http-agent.d.ts +38 -0
- package/dist/http-agent.js +60 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4 -0
- package/dist/interface.d.ts +4 -0
- package/dist/interface.js +2 -0
- package/dist/notion.d.ts +144 -0
- package/dist/notion.js +547 -0
- package/dist/retry.d.ts +72 -0
- package/dist/retry.js +381 -0
- package/dist/utils/bookmarks.d.ts +32 -0
- package/dist/utils/bookmarks.js +98 -0
- package/dist/utils/daily-config.d.ts +22 -0
- package/dist/utils/daily-config.js +60 -0
- package/dist/utils/disk-cache.d.ts +80 -0
- package/dist/utils/disk-cache.js +291 -0
- package/dist/utils/fuzzy.d.ts +36 -0
- package/dist/utils/fuzzy.js +69 -0
- package/dist/utils/interactive-navigator.d.ts +63 -0
- package/dist/utils/interactive-navigator.js +123 -0
- package/dist/utils/markdown-to-blocks.d.ts +21 -0
- package/dist/utils/markdown-to-blocks.js +333 -0
- package/dist/utils/notion-resolver.d.ts +49 -0
- package/dist/utils/notion-resolver.js +278 -0
- package/dist/utils/notion-url-parser.d.ts +48 -0
- package/dist/utils/notion-url-parser.js +121 -0
- package/dist/utils/property-expander.d.ts +45 -0
- package/dist/utils/property-expander.js +323 -0
- package/dist/utils/schema-examples.d.ts +40 -0
- package/dist/utils/schema-examples.js +359 -0
- package/dist/utils/schema-extractor.d.ts +65 -0
- package/dist/utils/schema-extractor.js +235 -0
- package/dist/utils/shell-config.d.ts +30 -0
- package/dist/utils/shell-config.js +84 -0
- package/dist/utils/table-formatter.d.ts +36 -0
- package/dist/utils/table-formatter.js +125 -0
- package/dist/utils/templates.d.ts +30 -0
- package/dist/utils/templates.js +82 -0
- package/dist/utils/terminal-banner.d.ts +24 -0
- package/dist/utils/terminal-banner.js +34 -0
- package/dist/utils/token-validator.d.ts +42 -0
- package/dist/utils/token-validator.js +66 -0
- package/dist/utils/update-notifier.d.ts +26 -0
- package/dist/utils/update-notifier.js +54 -0
- package/dist/utils/workspace-cache.d.ts +58 -0
- package/dist/utils/workspace-cache.js +185 -0
- package/oclif.manifest.json +6471 -0
- package/package.json +118 -0
- package/scripts/banner.js +38 -0
- package/scripts/postinstall.js +44 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Remove Command
|
|
3
|
+
*
|
|
4
|
+
* Deletes a saved template by name. No-op if it doesn't exist.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from '@oclif/core';
|
|
7
|
+
export default class TemplateRemove extends Command {
|
|
8
|
+
static description: string;
|
|
9
|
+
static aliases: string[];
|
|
10
|
+
static examples: {
|
|
11
|
+
description: string;
|
|
12
|
+
command: string;
|
|
13
|
+
}[];
|
|
14
|
+
static args: {
|
|
15
|
+
name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
16
|
+
};
|
|
17
|
+
static flags: {
|
|
18
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
'page-size': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
|
+
retry: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
21
|
+
timeout: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
|
+
'no-cache': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
23
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
minimal: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
|
+
};
|
|
26
|
+
run(): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Template Remove Command
|
|
4
|
+
*
|
|
5
|
+
* Deletes a saved template by name. No-op if it doesn't exist.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const core_1 = require("@oclif/core");
|
|
9
|
+
const templates_1 = require("../../utils/templates");
|
|
10
|
+
const base_flags_1 = require("../../base-flags");
|
|
11
|
+
class TemplateRemove extends core_1.Command {
|
|
12
|
+
async run() {
|
|
13
|
+
const { args, flags } = await this.parse(TemplateRemove);
|
|
14
|
+
const existed = await (0, templates_1.removeTemplate)(args.name);
|
|
15
|
+
if (flags.json) {
|
|
16
|
+
this.log(JSON.stringify({
|
|
17
|
+
success: existed,
|
|
18
|
+
data: { name: args.name, removed: existed },
|
|
19
|
+
timestamp: new Date().toISOString()
|
|
20
|
+
}, null, 2));
|
|
21
|
+
process.exit(0);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (existed) {
|
|
25
|
+
this.log(`Removed template "${args.name}"`);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
this.log(`Template "${args.name}" not found.`);
|
|
29
|
+
this.log('Run `notion-cli template list` to see saved templates.');
|
|
30
|
+
}
|
|
31
|
+
process.exit(0);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
TemplateRemove.description = 'Remove a saved template';
|
|
35
|
+
TemplateRemove.aliases = ['tpl:rm'];
|
|
36
|
+
TemplateRemove.examples = [
|
|
37
|
+
{
|
|
38
|
+
description: 'Remove a template',
|
|
39
|
+
command: '$ notion-cli template remove "meeting"',
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
TemplateRemove.args = {
|
|
43
|
+
name: core_1.Args.string({ required: true, description: 'Template name to remove' }),
|
|
44
|
+
};
|
|
45
|
+
TemplateRemove.flags = {
|
|
46
|
+
...base_flags_1.AutomationFlags,
|
|
47
|
+
};
|
|
48
|
+
exports.default = TemplateRemove;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Save Command
|
|
3
|
+
*
|
|
4
|
+
* Saves a reusable page template with properties, body content, and/or icon.
|
|
5
|
+
* Templates use simple properties format (flat JSON) and are NOT tied to a
|
|
6
|
+
* specific database — they're expanded against the target schema at use-time.
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from '@oclif/core';
|
|
9
|
+
export default class TemplateSave extends Command {
|
|
10
|
+
static description: string;
|
|
11
|
+
static aliases: string[];
|
|
12
|
+
static examples: {
|
|
13
|
+
description: string;
|
|
14
|
+
command: string;
|
|
15
|
+
}[];
|
|
16
|
+
static args: {
|
|
17
|
+
name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
18
|
+
};
|
|
19
|
+
static flags: {
|
|
20
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
21
|
+
'page-size': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
|
+
retry: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
23
|
+
timeout: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
|
+
'no-cache': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
26
|
+
minimal: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
27
|
+
properties: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
28
|
+
content: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
29
|
+
icon: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
30
|
+
};
|
|
31
|
+
run(): Promise<void>;
|
|
32
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Template Save Command
|
|
4
|
+
*
|
|
5
|
+
* Saves a reusable page template with properties, body content, and/or icon.
|
|
6
|
+
* Templates use simple properties format (flat JSON) and are NOT tied to a
|
|
7
|
+
* specific database — they're expanded against the target schema at use-time.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
const core_1 = require("@oclif/core");
|
|
11
|
+
const templates_1 = require("../../utils/templates");
|
|
12
|
+
const base_flags_1 = require("../../base-flags");
|
|
13
|
+
const errors_1 = require("../../errors");
|
|
14
|
+
class TemplateSave extends core_1.Command {
|
|
15
|
+
async run() {
|
|
16
|
+
const { args, flags } = await this.parse(TemplateSave);
|
|
17
|
+
// Must provide at least one field
|
|
18
|
+
if (!flags.properties && !flags.content && !flags.icon) {
|
|
19
|
+
this.error('Provide at least one of --properties, --content, or --icon.\n' +
|
|
20
|
+
'Example: notion-cli template save "task" --properties \'{"Status": "To Do"}\'');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// Parse and validate properties JSON
|
|
25
|
+
let properties;
|
|
26
|
+
if (flags.properties) {
|
|
27
|
+
try {
|
|
28
|
+
properties = JSON.parse(flags.properties);
|
|
29
|
+
if (typeof properties !== 'object' || Array.isArray(properties) || properties === null) {
|
|
30
|
+
throw new Error('Properties must be a JSON object');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
throw new errors_1.NotionCLIError(errors_1.NotionCLIErrorCode.INVALID_JSON, `Invalid properties JSON: ${error.message}`, [{ description: 'Properties must be a JSON object like: {"Status": "To Do", "Priority": 3}' }]);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Build template object — only include fields that were provided
|
|
38
|
+
const template = {
|
|
39
|
+
...(properties && { properties }),
|
|
40
|
+
...(flags.content && { content: flags.content }),
|
|
41
|
+
...(flags.icon && { icon: flags.icon }),
|
|
42
|
+
};
|
|
43
|
+
await (0, templates_1.setTemplate)(args.name, template);
|
|
44
|
+
if (flags.json) {
|
|
45
|
+
this.log(JSON.stringify({
|
|
46
|
+
success: true,
|
|
47
|
+
data: { name: args.name, ...template },
|
|
48
|
+
timestamp: new Date().toISOString()
|
|
49
|
+
}, null, 2));
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this.log(`Saved template "${args.name}"`);
|
|
53
|
+
if (properties)
|
|
54
|
+
this.log(` Properties: ${Object.keys(properties).join(', ')}`);
|
|
55
|
+
if (flags.content)
|
|
56
|
+
this.log(` Content: ${flags.content.substring(0, 60)}${flags.content.length > 60 ? '...' : ''}`);
|
|
57
|
+
if (flags.icon)
|
|
58
|
+
this.log(` Icon: ${flags.icon}`);
|
|
59
|
+
}
|
|
60
|
+
process.exit(0);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
TemplateSave.description = 'Save a reusable page template';
|
|
64
|
+
TemplateSave.aliases = ['tpl:save'];
|
|
65
|
+
TemplateSave.examples = [
|
|
66
|
+
{
|
|
67
|
+
description: 'Save a template with properties',
|
|
68
|
+
command: '$ notion-cli template save "meeting" --properties \'{"Status": "To Do", "Type": "Meeting"}\'',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
description: 'Save with properties, body content, and icon',
|
|
72
|
+
command: '$ notion-cli template save "standup" --properties \'{"Status": "In Progress"}\' --content "# Standup\\n\\n## Done\\n\\n## Doing\\n\\n## Blockers" --icon "🧑💻"',
|
|
73
|
+
},
|
|
74
|
+
];
|
|
75
|
+
TemplateSave.args = {
|
|
76
|
+
name: core_1.Args.string({ required: true, description: 'Template name (e.g. "meeting", "task")' }),
|
|
77
|
+
};
|
|
78
|
+
TemplateSave.flags = {
|
|
79
|
+
properties: core_1.Flags.string({
|
|
80
|
+
char: 'p',
|
|
81
|
+
description: 'Properties as JSON (simple format, e.g. \'{"Status": "To Do"}\')',
|
|
82
|
+
}),
|
|
83
|
+
content: core_1.Flags.string({
|
|
84
|
+
char: 'c',
|
|
85
|
+
description: 'Markdown body content for the page',
|
|
86
|
+
}),
|
|
87
|
+
icon: core_1.Flags.string({
|
|
88
|
+
description: 'Emoji icon (e.g. "📋")',
|
|
89
|
+
}),
|
|
90
|
+
...base_flags_1.AutomationFlags,
|
|
91
|
+
};
|
|
92
|
+
exports.default = TemplateSave;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Use Command
|
|
3
|
+
*
|
|
4
|
+
* Creates a page from a saved template. The template's simple properties
|
|
5
|
+
* are expanded against the target database schema at runtime, making
|
|
6
|
+
* templates portable across different databases.
|
|
7
|
+
*
|
|
8
|
+
* Target database can be specified via --to flag or defaults to the
|
|
9
|
+
* default bookmark (same resolution as `quick` command).
|
|
10
|
+
*/
|
|
11
|
+
import { Command } from '@oclif/core';
|
|
12
|
+
export default class TemplateUse extends Command {
|
|
13
|
+
static description: string;
|
|
14
|
+
static aliases: string[];
|
|
15
|
+
static examples: {
|
|
16
|
+
description: string;
|
|
17
|
+
command: string;
|
|
18
|
+
}[];
|
|
19
|
+
static args: {
|
|
20
|
+
name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
21
|
+
};
|
|
22
|
+
static flags: {
|
|
23
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
'page-size': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
25
|
+
retry: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
26
|
+
timeout: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
27
|
+
'no-cache': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
28
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
29
|
+
minimal: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
30
|
+
to: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
31
|
+
title: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
32
|
+
};
|
|
33
|
+
run(): Promise<void>;
|
|
34
|
+
}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Template Use Command
|
|
4
|
+
*
|
|
5
|
+
* Creates a page from a saved template. The template's simple properties
|
|
6
|
+
* are expanded against the target database schema at runtime, making
|
|
7
|
+
* templates portable across different databases.
|
|
8
|
+
*
|
|
9
|
+
* Target database can be specified via --to flag or defaults to the
|
|
10
|
+
* default bookmark (same resolution as `quick` command).
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
const core_1 = require("@oclif/core");
|
|
14
|
+
const notion = require("../../notion");
|
|
15
|
+
const templates_1 = require("../../utils/templates");
|
|
16
|
+
const bookmarks_1 = require("../../utils/bookmarks");
|
|
17
|
+
const notion_resolver_1 = require("../../utils/notion-resolver");
|
|
18
|
+
const property_expander_1 = require("../../utils/property-expander");
|
|
19
|
+
const markdown_to_blocks_1 = require("../../utils/markdown-to-blocks");
|
|
20
|
+
const base_flags_1 = require("../../base-flags");
|
|
21
|
+
const errors_1 = require("../../errors");
|
|
22
|
+
class TemplateUse extends core_1.Command {
|
|
23
|
+
async run() {
|
|
24
|
+
const { args, flags } = await this.parse(TemplateUse);
|
|
25
|
+
try {
|
|
26
|
+
// 1. Load template
|
|
27
|
+
const template = await (0, templates_1.getTemplate)(args.name);
|
|
28
|
+
if (!template) {
|
|
29
|
+
this.error(`Template "${args.name}" not found.\nRun \`notion-cli template list\` to see saved templates.`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
// 2. Resolve target database
|
|
34
|
+
const target = flags.to || await (0, bookmarks_1.getDefaultBookmark)();
|
|
35
|
+
if (!target) {
|
|
36
|
+
this.error('No target database specified and no default bookmark set.\n' +
|
|
37
|
+
'Specify: notion-cli template use "name" --to DB_NAME_OR_ID --title "Title"\n' +
|
|
38
|
+
' or set a default: notion-cli bookmark set inbox DB_ID --default');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const dbId = await (0, notion_resolver_1.resolveNotionId)(target, 'database');
|
|
43
|
+
// 3. Get database schema to find title property and expand simple props
|
|
44
|
+
const schema = await notion.retrieveDataSource(dbId);
|
|
45
|
+
const titlePropName = findTitleProperty(schema);
|
|
46
|
+
// 4. Build properties — merge template props with title
|
|
47
|
+
let expandedProperties = {};
|
|
48
|
+
if (template.properties && Object.keys(template.properties).length > 0) {
|
|
49
|
+
// Inject title into simple properties before expanding
|
|
50
|
+
const merged = { ...template.properties, [titlePropName]: flags.title };
|
|
51
|
+
expandedProperties = await (0, property_expander_1.expandSimpleProperties)(merged, schema.properties);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// No template properties — just set title
|
|
55
|
+
expandedProperties = {
|
|
56
|
+
[titlePropName]: {
|
|
57
|
+
title: [{ text: { content: flags.title } }]
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// 5. Convert template content to blocks (if exists)
|
|
62
|
+
const children = template.content
|
|
63
|
+
? (0, markdown_to_blocks_1.markdownToBlocks)(template.content)
|
|
64
|
+
: undefined;
|
|
65
|
+
// 6. Build page params
|
|
66
|
+
const pageParams = {
|
|
67
|
+
parent: { data_source_id: dbId },
|
|
68
|
+
properties: expandedProperties,
|
|
69
|
+
...(children && { children }),
|
|
70
|
+
...(template.icon && { icon: { emoji: template.icon } }),
|
|
71
|
+
};
|
|
72
|
+
// 7. Create page
|
|
73
|
+
const res = await notion.createPage(pageParams);
|
|
74
|
+
// 8. Output
|
|
75
|
+
if (flags.json) {
|
|
76
|
+
this.log(JSON.stringify({
|
|
77
|
+
success: true,
|
|
78
|
+
data: res,
|
|
79
|
+
template: args.name,
|
|
80
|
+
timestamp: new Date().toISOString()
|
|
81
|
+
}, null, 2));
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
this.log(`Created from template "${args.name}": ${flags.title}`);
|
|
85
|
+
this.log(res.url);
|
|
86
|
+
}
|
|
87
|
+
process.exit(0);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
const cliError = error instanceof errors_1.NotionCLIError
|
|
91
|
+
? error
|
|
92
|
+
: (0, errors_1.wrapNotionError)(error, { endpoint: 'pages.create', resourceType: 'page' });
|
|
93
|
+
if (flags.json) {
|
|
94
|
+
this.log(JSON.stringify(cliError.toJSON(), null, 2));
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
this.error(cliError.toHumanString());
|
|
98
|
+
}
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
TemplateUse.description = 'Create a page from a saved template';
|
|
104
|
+
TemplateUse.aliases = ['tpl:use'];
|
|
105
|
+
TemplateUse.examples = [
|
|
106
|
+
{
|
|
107
|
+
description: 'Create a page from a template',
|
|
108
|
+
command: '$ notion-cli template use "meeting" --to tasks --title "Sprint Planning"',
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
description: 'Use default bookmark as target',
|
|
112
|
+
command: '$ notion-cli template use "task" --title "Fix login bug"',
|
|
113
|
+
},
|
|
114
|
+
];
|
|
115
|
+
TemplateUse.args = {
|
|
116
|
+
name: core_1.Args.string({ required: true, description: 'Template name to use' }),
|
|
117
|
+
};
|
|
118
|
+
TemplateUse.flags = {
|
|
119
|
+
to: core_1.Flags.string({
|
|
120
|
+
description: 'Target bookmark name, database name, or ID (defaults to default bookmark)',
|
|
121
|
+
}),
|
|
122
|
+
title: core_1.Flags.string({
|
|
123
|
+
char: 't',
|
|
124
|
+
description: 'Page title (overrides any title in template properties)',
|
|
125
|
+
required: true,
|
|
126
|
+
}),
|
|
127
|
+
...base_flags_1.AutomationFlags,
|
|
128
|
+
};
|
|
129
|
+
exports.default = TemplateUse;
|
|
130
|
+
/**
|
|
131
|
+
* Find the title property name in a database schema.
|
|
132
|
+
* Notion databases always have exactly one title property, but its name varies.
|
|
133
|
+
*/
|
|
134
|
+
function findTitleProperty(schema) {
|
|
135
|
+
if (schema.properties) {
|
|
136
|
+
for (const [name, prop] of Object.entries(schema.properties)) {
|
|
137
|
+
if (prop.type === 'title')
|
|
138
|
+
return name;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return 'Name';
|
|
142
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class UserList extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static aliases: string[];
|
|
5
|
+
static examples: {
|
|
6
|
+
description: string;
|
|
7
|
+
command: string;
|
|
8
|
+
}[];
|
|
9
|
+
static flags: {
|
|
10
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
'page-size': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
12
|
+
retry: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
timeout: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
14
|
+
'no-cache': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
minimal: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
17
|
+
columns: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
18
|
+
sort: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
|
+
filter: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
|
+
csv: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
21
|
+
extended: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
22
|
+
'no-truncate': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
23
|
+
'no-header': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
raw: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
|
+
};
|
|
26
|
+
run(): Promise<void>;
|
|
27
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
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
|
+
class UserList extends core_1.Command {
|
|
10
|
+
async run() {
|
|
11
|
+
const { flags } = await this.parse(UserList);
|
|
12
|
+
try {
|
|
13
|
+
let res = await notion.listUser();
|
|
14
|
+
// Apply minimal flag to strip metadata
|
|
15
|
+
if (flags.minimal) {
|
|
16
|
+
res = (0, helper_1.stripMetadata)(res);
|
|
17
|
+
}
|
|
18
|
+
// Handle JSON output for automation
|
|
19
|
+
if (flags.json) {
|
|
20
|
+
this.log(JSON.stringify({
|
|
21
|
+
success: true,
|
|
22
|
+
data: res,
|
|
23
|
+
timestamp: new Date().toISOString()
|
|
24
|
+
}, null, 2));
|
|
25
|
+
process.exit(0);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
// Handle raw JSON output (legacy)
|
|
29
|
+
if (flags.raw) {
|
|
30
|
+
(0, helper_1.outputRawJson)(res);
|
|
31
|
+
process.exit(0);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
// Handle table output
|
|
35
|
+
const columns = {
|
|
36
|
+
id: {},
|
|
37
|
+
name: {},
|
|
38
|
+
object: {},
|
|
39
|
+
type: {},
|
|
40
|
+
person_or_bot: {
|
|
41
|
+
header: 'person/bot',
|
|
42
|
+
get: (row) => {
|
|
43
|
+
if (row.type === 'person') {
|
|
44
|
+
return row.person;
|
|
45
|
+
}
|
|
46
|
+
return row.bot;
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
avatar_url: {},
|
|
50
|
+
};
|
|
51
|
+
const options = {
|
|
52
|
+
printLine: this.log.bind(this),
|
|
53
|
+
...flags,
|
|
54
|
+
};
|
|
55
|
+
(0, table_formatter_1.formatTable)(res.results, columns, options);
|
|
56
|
+
process.exit(0);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
const cliError = error instanceof errors_1.NotionCLIError
|
|
60
|
+
? error
|
|
61
|
+
: (0, errors_1.wrapNotionError)(error, {
|
|
62
|
+
resourceType: 'user',
|
|
63
|
+
endpoint: 'users.list'
|
|
64
|
+
});
|
|
65
|
+
if (flags.json) {
|
|
66
|
+
this.log(JSON.stringify(cliError.toJSON(), null, 2));
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
this.error(cliError.toHumanString());
|
|
70
|
+
}
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
UserList.description = 'List all users';
|
|
76
|
+
UserList.aliases = ['user:l'];
|
|
77
|
+
UserList.examples = [
|
|
78
|
+
{
|
|
79
|
+
description: 'List all users',
|
|
80
|
+
command: `$ notion-cli user list`,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
description: 'List all users and output raw json',
|
|
84
|
+
command: `$ notion-cli user list -r`,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
description: 'List all users and output JSON for automation',
|
|
88
|
+
command: `$ notion-cli user list --json`,
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
UserList.flags = {
|
|
92
|
+
raw: core_1.Flags.boolean({
|
|
93
|
+
char: 'r',
|
|
94
|
+
description: 'output raw json',
|
|
95
|
+
}),
|
|
96
|
+
...table_formatter_1.tableFlags,
|
|
97
|
+
...base_flags_1.AutomationFlags,
|
|
98
|
+
};
|
|
99
|
+
exports.default = UserList;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class UserRetrieveBot extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static aliases: string[];
|
|
5
|
+
static examples: {
|
|
6
|
+
description: string;
|
|
7
|
+
command: string;
|
|
8
|
+
}[];
|
|
9
|
+
static args: {};
|
|
10
|
+
static flags: {
|
|
11
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
'page-size': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
retry: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
timeout: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
|
+
'no-cache': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
17
|
+
minimal: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
columns: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
|
+
sort: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
|
+
filter: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
|
+
csv: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
22
|
+
extended: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
23
|
+
'no-truncate': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
'no-header': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
|
+
raw: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
26
|
+
};
|
|
27
|
+
run(): Promise<void>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const notion = require("../../../notion");
|
|
5
|
+
const helper_1 = require("../../../helper");
|
|
6
|
+
const base_flags_1 = require("../../../base-flags");
|
|
7
|
+
const errors_1 = require("../../../errors");
|
|
8
|
+
const table_formatter_1 = require("../../../utils/table-formatter");
|
|
9
|
+
class UserRetrieveBot extends core_1.Command {
|
|
10
|
+
async run() {
|
|
11
|
+
const { flags } = await this.parse(UserRetrieveBot);
|
|
12
|
+
try {
|
|
13
|
+
const res = await notion.botUser();
|
|
14
|
+
// Handle JSON output for automation
|
|
15
|
+
if (flags.json) {
|
|
16
|
+
this.log(JSON.stringify({
|
|
17
|
+
success: true,
|
|
18
|
+
data: res,
|
|
19
|
+
timestamp: new Date().toISOString()
|
|
20
|
+
}, null, 2));
|
|
21
|
+
process.exit(0);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// Handle raw JSON output (legacy)
|
|
25
|
+
if (flags.raw) {
|
|
26
|
+
(0, helper_1.outputRawJson)(res);
|
|
27
|
+
process.exit(0);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
// Handle table output
|
|
31
|
+
const columns = {
|
|
32
|
+
id: {},
|
|
33
|
+
name: {},
|
|
34
|
+
object: {},
|
|
35
|
+
type: {},
|
|
36
|
+
person_or_bot: {
|
|
37
|
+
header: 'person/bot',
|
|
38
|
+
get: (row) => {
|
|
39
|
+
if (row.type === 'person') {
|
|
40
|
+
return row.person;
|
|
41
|
+
}
|
|
42
|
+
return row.bot;
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
avatar_url: {},
|
|
46
|
+
};
|
|
47
|
+
const options = {
|
|
48
|
+
printLine: this.log.bind(this),
|
|
49
|
+
...flags,
|
|
50
|
+
};
|
|
51
|
+
(0, table_formatter_1.formatTable)([res], columns, options);
|
|
52
|
+
process.exit(0);
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
const cliError = error instanceof errors_1.NotionCLIError
|
|
56
|
+
? error
|
|
57
|
+
: (0, errors_1.wrapNotionError)(error, {
|
|
58
|
+
resourceType: 'user',
|
|
59
|
+
endpoint: 'users.me'
|
|
60
|
+
});
|
|
61
|
+
if (flags.json) {
|
|
62
|
+
this.log(JSON.stringify(cliError.toJSON(), null, 2));
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
this.error(cliError.toHumanString());
|
|
66
|
+
}
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
UserRetrieveBot.description = 'Retrieve a bot user';
|
|
72
|
+
UserRetrieveBot.aliases = ['user:r:b'];
|
|
73
|
+
UserRetrieveBot.examples = [
|
|
74
|
+
{
|
|
75
|
+
description: 'Retrieve a bot user',
|
|
76
|
+
command: `$ notion-cli user retrieve:bot`,
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
description: 'Retrieve a bot user and output raw json',
|
|
80
|
+
command: `$ notion-cli user retrieve:bot -r`,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
description: 'Retrieve a bot user and output JSON for automation',
|
|
84
|
+
command: `$ notion-cli user retrieve:bot --json`,
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
UserRetrieveBot.args = {};
|
|
88
|
+
UserRetrieveBot.flags = {
|
|
89
|
+
raw: core_1.Flags.boolean({
|
|
90
|
+
char: 'r',
|
|
91
|
+
description: 'output raw json',
|
|
92
|
+
}),
|
|
93
|
+
...table_formatter_1.tableFlags,
|
|
94
|
+
...base_flags_1.AutomationFlags,
|
|
95
|
+
};
|
|
96
|
+
exports.default = UserRetrieveBot;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class UserRetrieve extends Command {
|
|
3
|
+
static description: string;
|
|
4
|
+
static aliases: string[];
|
|
5
|
+
static examples: {
|
|
6
|
+
description: string;
|
|
7
|
+
command: string;
|
|
8
|
+
}[];
|
|
9
|
+
static args: {
|
|
10
|
+
user_id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
11
|
+
};
|
|
12
|
+
static flags: {
|
|
13
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
14
|
+
'page-size': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
15
|
+
retry: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
timeout: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
17
|
+
'no-cache': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
verbose: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
19
|
+
minimal: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
20
|
+
columns: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
|
+
sort: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
|
+
filter: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
|
+
csv: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
extended: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
|
+
'no-truncate': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
26
|
+
'no-header': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
27
|
+
raw: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
28
|
+
};
|
|
29
|
+
run(): Promise<void>;
|
|
30
|
+
}
|