@andrzejchm/notion-cli 0.7.0 → 0.8.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/README.md +1 -0
- package/dist/cli.js +372 -259
- package/dist/cli.js.map +1 -1
- package/docs/FEATURE-PARITY.md +15 -18
- package/docs/README.agents.md +17 -0
- package/docs/skills/using-notion-cli/SKILL.md +35 -4
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { readFileSync } from "fs";
|
|
5
5
|
import { dirname, join as join3 } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
|
-
import { Command as
|
|
7
|
+
import { Command as Command23 } from "commander";
|
|
8
8
|
|
|
9
9
|
// src/commands/append.ts
|
|
10
10
|
import { Command } from "commander";
|
|
@@ -659,7 +659,22 @@ async function replaceMarkdown(client, pageId, newMarkdown, options) {
|
|
|
659
659
|
}
|
|
660
660
|
});
|
|
661
661
|
}
|
|
662
|
-
|
|
662
|
+
function buildIconCover(options) {
|
|
663
|
+
const result = {};
|
|
664
|
+
if (options?.icon) {
|
|
665
|
+
const isUrl = /^https?:\/\//i.test(options.icon);
|
|
666
|
+
if (isUrl) {
|
|
667
|
+
result.icon = { type: "external", external: { url: options.icon } };
|
|
668
|
+
} else {
|
|
669
|
+
result.icon = { type: "emoji", emoji: options.icon };
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
if (options?.cover) {
|
|
673
|
+
result.cover = { type: "external", external: { url: options.cover } };
|
|
674
|
+
}
|
|
675
|
+
return result;
|
|
676
|
+
}
|
|
677
|
+
async function createPage(client, parentId, title, markdown, options) {
|
|
663
678
|
const response = await client.pages.create({
|
|
664
679
|
parent: { type: "page_id", page_id: parentId },
|
|
665
680
|
properties: {
|
|
@@ -667,7 +682,24 @@ async function createPage(client, parentId, title, markdown) {
|
|
|
667
682
|
title: [{ type: "text", text: { content: title, link: null } }]
|
|
668
683
|
}
|
|
669
684
|
},
|
|
670
|
-
...markdown.trim() ? { markdown } : {}
|
|
685
|
+
...markdown.trim() ? { markdown } : {},
|
|
686
|
+
...buildIconCover(options)
|
|
687
|
+
});
|
|
688
|
+
const url = "url" in response ? response.url : response.id;
|
|
689
|
+
return url;
|
|
690
|
+
}
|
|
691
|
+
async function createPageInDatabase(client, databaseId, titlePropName, title, extraProperties, markdown, options) {
|
|
692
|
+
const properties = {
|
|
693
|
+
...extraProperties,
|
|
694
|
+
[titlePropName]: {
|
|
695
|
+
title: [{ type: "text", text: { content: title, link: null } }]
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
const response = await client.pages.create({
|
|
699
|
+
parent: { type: "database_id", database_id: databaseId },
|
|
700
|
+
properties,
|
|
701
|
+
...markdown.trim() ? { markdown } : {},
|
|
702
|
+
...buildIconCover(options)
|
|
671
703
|
});
|
|
672
704
|
const url = "url" in response ? response.url : response.id;
|
|
673
705
|
return url;
|
|
@@ -737,6 +769,102 @@ function appendCommand() {
|
|
|
737
769
|
return cmd;
|
|
738
770
|
}
|
|
739
771
|
|
|
772
|
+
// src/commands/archive.ts
|
|
773
|
+
import { Command as Command2 } from "commander";
|
|
774
|
+
|
|
775
|
+
// src/output/format.ts
|
|
776
|
+
var _mode = "auto";
|
|
777
|
+
function setOutputMode(mode) {
|
|
778
|
+
_mode = mode;
|
|
779
|
+
}
|
|
780
|
+
function getOutputMode() {
|
|
781
|
+
return _mode;
|
|
782
|
+
}
|
|
783
|
+
function isatty() {
|
|
784
|
+
return Boolean(process.stdout.isTTY);
|
|
785
|
+
}
|
|
786
|
+
function isHumanMode() {
|
|
787
|
+
if (_mode === "json") return false;
|
|
788
|
+
if (_mode === "md") return false;
|
|
789
|
+
return true;
|
|
790
|
+
}
|
|
791
|
+
function formatJSON(data) {
|
|
792
|
+
return JSON.stringify(data, null, 2);
|
|
793
|
+
}
|
|
794
|
+
var COLUMN_CAPS = {
|
|
795
|
+
TITLE: 50,
|
|
796
|
+
ID: 36
|
|
797
|
+
};
|
|
798
|
+
var DEFAULT_MAX_COL_WIDTH = 40;
|
|
799
|
+
function getColumnCap(header) {
|
|
800
|
+
return COLUMN_CAPS[header.toUpperCase()] ?? DEFAULT_MAX_COL_WIDTH;
|
|
801
|
+
}
|
|
802
|
+
function truncate(str, maxLen) {
|
|
803
|
+
if (str.length <= maxLen) return str;
|
|
804
|
+
return `${str.slice(0, maxLen - 1)}\u2026`;
|
|
805
|
+
}
|
|
806
|
+
function formatTable(rows, headers) {
|
|
807
|
+
const colWidths = headers.map((header, colIdx) => {
|
|
808
|
+
const cap = getColumnCap(header);
|
|
809
|
+
const headerLen = header.length;
|
|
810
|
+
const maxRowLen = rows.reduce((max, row) => {
|
|
811
|
+
const cell = row[colIdx] ?? "";
|
|
812
|
+
return Math.max(max, cell.length);
|
|
813
|
+
}, 0);
|
|
814
|
+
return Math.min(Math.max(headerLen, maxRowLen), cap);
|
|
815
|
+
});
|
|
816
|
+
const sep = "\u2500";
|
|
817
|
+
const colSep = " ";
|
|
818
|
+
const headerRow = headers.map((h, i) => h.padEnd(colWidths[i])).join(colSep);
|
|
819
|
+
const separatorRow = colWidths.map((w) => sep.repeat(w)).join(colSep);
|
|
820
|
+
const dataRows = rows.map(
|
|
821
|
+
(row) => headers.map((_, i) => {
|
|
822
|
+
const cell = row[i] ?? "";
|
|
823
|
+
return truncate(cell, colWidths[i]).padEnd(colWidths[i]);
|
|
824
|
+
}).join(colSep)
|
|
825
|
+
);
|
|
826
|
+
return [headerRow, separatorRow, ...dataRows].join("\n");
|
|
827
|
+
}
|
|
828
|
+
function printOutput(data, tableHeaders, tableRows) {
|
|
829
|
+
const mode = getOutputMode();
|
|
830
|
+
if (mode === "json") {
|
|
831
|
+
process.stdout.write(`${formatJSON(data)}
|
|
832
|
+
`);
|
|
833
|
+
} else if (isHumanMode() && tableHeaders && tableRows) {
|
|
834
|
+
printWithPager(`${formatTable(tableRows, tableHeaders)}
|
|
835
|
+
`);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
function printWithPager(text) {
|
|
839
|
+
process.stdout.write(text);
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
// src/commands/archive.ts
|
|
843
|
+
function archiveCommand() {
|
|
844
|
+
const cmd = new Command2("archive");
|
|
845
|
+
cmd.description("archive (trash) a Notion page").argument("<id/url>", "Notion page ID or URL").action(
|
|
846
|
+
withErrorHandling(async (idOrUrl) => {
|
|
847
|
+
const { token, source } = await resolveToken();
|
|
848
|
+
reportTokenSource(source);
|
|
849
|
+
const client = createNotionClient(token);
|
|
850
|
+
const id = parseNotionId(idOrUrl);
|
|
851
|
+
const uuid = toUuid(id);
|
|
852
|
+
const updatedPage = await client.pages.update({
|
|
853
|
+
page_id: uuid,
|
|
854
|
+
archived: true
|
|
855
|
+
});
|
|
856
|
+
const mode = getOutputMode();
|
|
857
|
+
if (mode === "json") {
|
|
858
|
+
process.stdout.write(`${formatJSON(updatedPage)}
|
|
859
|
+
`);
|
|
860
|
+
} else {
|
|
861
|
+
process.stdout.write("Page archived.\n");
|
|
862
|
+
}
|
|
863
|
+
})
|
|
864
|
+
);
|
|
865
|
+
return cmd;
|
|
866
|
+
}
|
|
867
|
+
|
|
740
868
|
// src/commands/auth/index.ts
|
|
741
869
|
function authDefaultAction(authCmd2) {
|
|
742
870
|
return async () => {
|
|
@@ -746,7 +874,7 @@ function authDefaultAction(authCmd2) {
|
|
|
746
874
|
|
|
747
875
|
// src/commands/auth/login.ts
|
|
748
876
|
import { input } from "@inquirer/prompts";
|
|
749
|
-
import { Command as
|
|
877
|
+
import { Command as Command3 } from "commander";
|
|
750
878
|
|
|
751
879
|
// src/oauth/oauth-flow.ts
|
|
752
880
|
import { spawn } from "child_process";
|
|
@@ -993,7 +1121,7 @@ Waiting for callback (up to 120 seconds)...
|
|
|
993
1121
|
|
|
994
1122
|
// src/commands/auth/login.ts
|
|
995
1123
|
function loginCommand() {
|
|
996
|
-
const cmd = new
|
|
1124
|
+
const cmd = new Command3("login");
|
|
997
1125
|
cmd.description("authenticate with Notion via OAuth").option("--profile <name>", "profile name to store credentials in").option(
|
|
998
1126
|
"--manual",
|
|
999
1127
|
"print auth URL instead of opening browser (for headless OAuth)"
|
|
@@ -1056,7 +1184,7 @@ function loginCommand() {
|
|
|
1056
1184
|
|
|
1057
1185
|
// src/commands/auth/logout.ts
|
|
1058
1186
|
import { select } from "@inquirer/prompts";
|
|
1059
|
-
import { Command as
|
|
1187
|
+
import { Command as Command4 } from "commander";
|
|
1060
1188
|
function profileLabel(name, profile) {
|
|
1061
1189
|
const parts = [];
|
|
1062
1190
|
if (profile.oauth_access_token)
|
|
@@ -1069,7 +1197,7 @@ function profileLabel(name, profile) {
|
|
|
1069
1197
|
return `${bold(name)} ${dim(authDesc)}${workspace}`;
|
|
1070
1198
|
}
|
|
1071
1199
|
function logoutCommand() {
|
|
1072
|
-
const cmd = new
|
|
1200
|
+
const cmd = new Command4("logout");
|
|
1073
1201
|
cmd.description("remove a profile and its credentials").option(
|
|
1074
1202
|
"--profile <name>",
|
|
1075
1203
|
"profile name to remove (skips interactive selector)"
|
|
@@ -1127,9 +1255,9 @@ function logoutCommand() {
|
|
|
1127
1255
|
}
|
|
1128
1256
|
|
|
1129
1257
|
// src/commands/auth/status.ts
|
|
1130
|
-
import { Command as
|
|
1258
|
+
import { Command as Command5 } from "commander";
|
|
1131
1259
|
function statusCommand() {
|
|
1132
|
-
const cmd = new
|
|
1260
|
+
const cmd = new Command5("status");
|
|
1133
1261
|
cmd.description("show authentication status for the active profile").option("--profile <name>", "profile name to check").action(
|
|
1134
1262
|
withErrorHandling(async (opts) => {
|
|
1135
1263
|
let profileName = opts.profile;
|
|
@@ -1187,9 +1315,9 @@ function statusCommand() {
|
|
|
1187
1315
|
}
|
|
1188
1316
|
|
|
1189
1317
|
// src/commands/comment-add.ts
|
|
1190
|
-
import { Command as
|
|
1318
|
+
import { Command as Command6 } from "commander";
|
|
1191
1319
|
function commentAddCommand() {
|
|
1192
|
-
const cmd = new
|
|
1320
|
+
const cmd = new Command6("comment");
|
|
1193
1321
|
cmd.description("add a comment to a Notion page").argument("<id/url>", "Notion page ID or URL").requiredOption("-m, --message <text>", "comment text to post").action(
|
|
1194
1322
|
withErrorHandling(async (idOrUrl, opts) => {
|
|
1195
1323
|
const { token, source } = await resolveToken();
|
|
@@ -1207,74 +1335,7 @@ function commentAddCommand() {
|
|
|
1207
1335
|
}
|
|
1208
1336
|
|
|
1209
1337
|
// src/commands/comments.ts
|
|
1210
|
-
import { Command as
|
|
1211
|
-
|
|
1212
|
-
// src/output/format.ts
|
|
1213
|
-
var _mode = "auto";
|
|
1214
|
-
function setOutputMode(mode) {
|
|
1215
|
-
_mode = mode;
|
|
1216
|
-
}
|
|
1217
|
-
function getOutputMode() {
|
|
1218
|
-
return _mode;
|
|
1219
|
-
}
|
|
1220
|
-
function isatty() {
|
|
1221
|
-
return Boolean(process.stdout.isTTY);
|
|
1222
|
-
}
|
|
1223
|
-
function isHumanMode() {
|
|
1224
|
-
if (_mode === "json") return false;
|
|
1225
|
-
if (_mode === "md") return false;
|
|
1226
|
-
return true;
|
|
1227
|
-
}
|
|
1228
|
-
function formatJSON(data) {
|
|
1229
|
-
return JSON.stringify(data, null, 2);
|
|
1230
|
-
}
|
|
1231
|
-
var COLUMN_CAPS = {
|
|
1232
|
-
TITLE: 50,
|
|
1233
|
-
ID: 36
|
|
1234
|
-
};
|
|
1235
|
-
var DEFAULT_MAX_COL_WIDTH = 40;
|
|
1236
|
-
function getColumnCap(header) {
|
|
1237
|
-
return COLUMN_CAPS[header.toUpperCase()] ?? DEFAULT_MAX_COL_WIDTH;
|
|
1238
|
-
}
|
|
1239
|
-
function truncate(str, maxLen) {
|
|
1240
|
-
if (str.length <= maxLen) return str;
|
|
1241
|
-
return `${str.slice(0, maxLen - 1)}\u2026`;
|
|
1242
|
-
}
|
|
1243
|
-
function formatTable(rows, headers) {
|
|
1244
|
-
const colWidths = headers.map((header, colIdx) => {
|
|
1245
|
-
const cap = getColumnCap(header);
|
|
1246
|
-
const headerLen = header.length;
|
|
1247
|
-
const maxRowLen = rows.reduce((max, row) => {
|
|
1248
|
-
const cell = row[colIdx] ?? "";
|
|
1249
|
-
return Math.max(max, cell.length);
|
|
1250
|
-
}, 0);
|
|
1251
|
-
return Math.min(Math.max(headerLen, maxRowLen), cap);
|
|
1252
|
-
});
|
|
1253
|
-
const sep = "\u2500";
|
|
1254
|
-
const colSep = " ";
|
|
1255
|
-
const headerRow = headers.map((h, i) => h.padEnd(colWidths[i])).join(colSep);
|
|
1256
|
-
const separatorRow = colWidths.map((w) => sep.repeat(w)).join(colSep);
|
|
1257
|
-
const dataRows = rows.map(
|
|
1258
|
-
(row) => headers.map((_, i) => {
|
|
1259
|
-
const cell = row[i] ?? "";
|
|
1260
|
-
return truncate(cell, colWidths[i]).padEnd(colWidths[i]);
|
|
1261
|
-
}).join(colSep)
|
|
1262
|
-
);
|
|
1263
|
-
return [headerRow, separatorRow, ...dataRows].join("\n");
|
|
1264
|
-
}
|
|
1265
|
-
function printOutput(data, tableHeaders, tableRows) {
|
|
1266
|
-
const mode = getOutputMode();
|
|
1267
|
-
if (mode === "json") {
|
|
1268
|
-
process.stdout.write(`${formatJSON(data)}
|
|
1269
|
-
`);
|
|
1270
|
-
} else if (isHumanMode() && tableHeaders && tableRows) {
|
|
1271
|
-
printWithPager(`${formatTable(tableRows, tableHeaders)}
|
|
1272
|
-
`);
|
|
1273
|
-
}
|
|
1274
|
-
}
|
|
1275
|
-
function printWithPager(text) {
|
|
1276
|
-
process.stdout.write(text);
|
|
1277
|
-
}
|
|
1338
|
+
import { Command as Command7 } from "commander";
|
|
1278
1339
|
|
|
1279
1340
|
// src/output/paginate.ts
|
|
1280
1341
|
async function paginateResults(fetcher) {
|
|
@@ -1292,7 +1353,7 @@ async function paginateResults(fetcher) {
|
|
|
1292
1353
|
|
|
1293
1354
|
// src/commands/comments.ts
|
|
1294
1355
|
function commentsCommand() {
|
|
1295
|
-
const cmd = new
|
|
1356
|
+
const cmd = new Command7("comments");
|
|
1296
1357
|
cmd.description("list comments on a Notion page").argument("<id/url>", "Notion page ID or URL").option("--json", "output as JSON").action(
|
|
1297
1358
|
withErrorHandling(async (idOrUrl, opts) => {
|
|
1298
1359
|
if (opts.json) setOutputMode("json");
|
|
@@ -1323,7 +1384,7 @@ function commentsCommand() {
|
|
|
1323
1384
|
}
|
|
1324
1385
|
|
|
1325
1386
|
// src/commands/completion.ts
|
|
1326
|
-
import { Command as
|
|
1387
|
+
import { Command as Command8 } from "commander";
|
|
1327
1388
|
var BASH_COMPLETION = `# notion bash completion
|
|
1328
1389
|
_notion_completion() {
|
|
1329
1390
|
local cur prev words cword
|
|
@@ -1425,7 +1486,7 @@ complete -c notion -n '__fish_seen_subcommand_from completion' -a zsh -d 'zsh co
|
|
|
1425
1486
|
complete -c notion -n '__fish_seen_subcommand_from completion' -a fish -d 'fish completion script'
|
|
1426
1487
|
`;
|
|
1427
1488
|
function completionCommand() {
|
|
1428
|
-
const cmd = new
|
|
1489
|
+
const cmd = new Command8("completion");
|
|
1429
1490
|
cmd.description("output shell completion script").argument("<shell>", "shell type (bash, zsh, fish)").action(
|
|
1430
1491
|
withErrorHandling(async (shell) => {
|
|
1431
1492
|
switch (shell) {
|
|
@@ -1451,40 +1512,6 @@ function completionCommand() {
|
|
|
1451
1512
|
}
|
|
1452
1513
|
|
|
1453
1514
|
// src/commands/create-page.ts
|
|
1454
|
-
import { Command as Command8 } from "commander";
|
|
1455
|
-
function createPageCommand() {
|
|
1456
|
-
const cmd = new Command8("create-page");
|
|
1457
|
-
cmd.description("create a new Notion page under a parent page").requiredOption("--parent <id/url>", "parent page ID or URL").requiredOption("--title <title>", "page title").option(
|
|
1458
|
-
"-m, --message <markdown>",
|
|
1459
|
-
"inline markdown content for the page body"
|
|
1460
|
-
).action(
|
|
1461
|
-
withErrorHandling(
|
|
1462
|
-
async (opts) => {
|
|
1463
|
-
const { token, source } = await resolveToken();
|
|
1464
|
-
reportTokenSource(source);
|
|
1465
|
-
const client = createNotionClient(token);
|
|
1466
|
-
let markdown = "";
|
|
1467
|
-
if (opts.message) {
|
|
1468
|
-
markdown = opts.message;
|
|
1469
|
-
} else if (!process.stdin.isTTY) {
|
|
1470
|
-
markdown = await readStdin();
|
|
1471
|
-
}
|
|
1472
|
-
const parentUuid = toUuid(parseNotionId(opts.parent));
|
|
1473
|
-
const url = await createPage(
|
|
1474
|
-
client,
|
|
1475
|
-
parentUuid,
|
|
1476
|
-
opts.title,
|
|
1477
|
-
markdown
|
|
1478
|
-
);
|
|
1479
|
-
process.stdout.write(`${url}
|
|
1480
|
-
`);
|
|
1481
|
-
}
|
|
1482
|
-
)
|
|
1483
|
-
);
|
|
1484
|
-
return cmd;
|
|
1485
|
-
}
|
|
1486
|
-
|
|
1487
|
-
// src/commands/db/query.ts
|
|
1488
1515
|
import { Command as Command9 } from "commander";
|
|
1489
1516
|
|
|
1490
1517
|
// src/services/database.service.ts
|
|
@@ -1510,7 +1537,8 @@ async function fetchDatabaseSchema(client, dbId) {
|
|
|
1510
1537
|
properties[name] = config;
|
|
1511
1538
|
}
|
|
1512
1539
|
}
|
|
1513
|
-
|
|
1540
|
+
const databaseId = "parent" in ds && ds.parent && typeof ds.parent === "object" && "database_id" in ds.parent ? ds.parent.database_id : dbId;
|
|
1541
|
+
return { id: dbId, databaseId, title, properties };
|
|
1514
1542
|
}
|
|
1515
1543
|
async function queryDatabase(client, dbId, opts = {}) {
|
|
1516
1544
|
const rawPages = await paginateResults(
|
|
@@ -1651,7 +1679,202 @@ function displayPropertyValue(prop) {
|
|
|
1651
1679
|
}
|
|
1652
1680
|
}
|
|
1653
1681
|
|
|
1682
|
+
// src/services/update.service.ts
|
|
1683
|
+
var UNSUPPORTED_TYPES = /* @__PURE__ */ new Set([
|
|
1684
|
+
"relation",
|
|
1685
|
+
"formula",
|
|
1686
|
+
"rollup",
|
|
1687
|
+
"created_time",
|
|
1688
|
+
"created_by",
|
|
1689
|
+
"last_edited_time",
|
|
1690
|
+
"last_edited_by",
|
|
1691
|
+
"files",
|
|
1692
|
+
"unique_id",
|
|
1693
|
+
"verification",
|
|
1694
|
+
"button"
|
|
1695
|
+
]);
|
|
1696
|
+
function buildPropertyUpdate(propName, propType, value) {
|
|
1697
|
+
if (UNSUPPORTED_TYPES.has(propType)) {
|
|
1698
|
+
throw new CliError(
|
|
1699
|
+
ErrorCodes.INVALID_ARG,
|
|
1700
|
+
`Property "${propName}" has type "${propType}" which cannot be set via the CLI.`,
|
|
1701
|
+
"Supported types: title, rich_text, select, status, multi_select, number, checkbox, url, email, phone_number, date"
|
|
1702
|
+
);
|
|
1703
|
+
}
|
|
1704
|
+
if (value === "") {
|
|
1705
|
+
return null;
|
|
1706
|
+
}
|
|
1707
|
+
switch (propType) {
|
|
1708
|
+
case "title":
|
|
1709
|
+
return { title: [{ type: "text", text: { content: value } }] };
|
|
1710
|
+
case "rich_text":
|
|
1711
|
+
return { rich_text: [{ type: "text", text: { content: value } }] };
|
|
1712
|
+
case "select":
|
|
1713
|
+
return { select: { name: value } };
|
|
1714
|
+
case "status":
|
|
1715
|
+
return { status: { name: value } };
|
|
1716
|
+
case "multi_select":
|
|
1717
|
+
return {
|
|
1718
|
+
multi_select: value.split(",").map((v) => v.trim()).filter(Boolean).map((v) => ({ name: v }))
|
|
1719
|
+
};
|
|
1720
|
+
case "number": {
|
|
1721
|
+
const n = Number(value);
|
|
1722
|
+
if (Number.isNaN(n)) {
|
|
1723
|
+
throw new CliError(
|
|
1724
|
+
ErrorCodes.INVALID_ARG,
|
|
1725
|
+
`Invalid number value "${value}" for property "${propName}".`,
|
|
1726
|
+
'Provide a numeric value, e.g. --prop "Count=42"'
|
|
1727
|
+
);
|
|
1728
|
+
}
|
|
1729
|
+
return { number: n };
|
|
1730
|
+
}
|
|
1731
|
+
case "checkbox": {
|
|
1732
|
+
const lower = value.toLowerCase();
|
|
1733
|
+
return { checkbox: lower === "true" || lower === "yes" };
|
|
1734
|
+
}
|
|
1735
|
+
case "url":
|
|
1736
|
+
return { url: value };
|
|
1737
|
+
case "email":
|
|
1738
|
+
return { email: value };
|
|
1739
|
+
case "phone_number":
|
|
1740
|
+
return { phone_number: value };
|
|
1741
|
+
case "date": {
|
|
1742
|
+
const parts = value.split(",");
|
|
1743
|
+
const start = parts[0].trim();
|
|
1744
|
+
const end = parts[1]?.trim();
|
|
1745
|
+
return { date: end ? { start, end } : { start } };
|
|
1746
|
+
}
|
|
1747
|
+
default:
|
|
1748
|
+
throw new CliError(
|
|
1749
|
+
ErrorCodes.INVALID_ARG,
|
|
1750
|
+
`Property "${propName}" has unsupported type "${propType}".`,
|
|
1751
|
+
"Supported types: title, rich_text, select, status, multi_select, number, checkbox, url, email, phone_number, date"
|
|
1752
|
+
);
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
function buildPropertiesPayload(propStrings, schemaOrPage) {
|
|
1756
|
+
const isPage = "object" in schemaOrPage && schemaOrPage.object === "page";
|
|
1757
|
+
const schema = isPage ? schemaOrPage.properties : schemaOrPage;
|
|
1758
|
+
const result = {};
|
|
1759
|
+
for (const propString of propStrings) {
|
|
1760
|
+
const eqIdx = propString.indexOf("=");
|
|
1761
|
+
if (eqIdx === -1) {
|
|
1762
|
+
throw new CliError(
|
|
1763
|
+
ErrorCodes.INVALID_ARG,
|
|
1764
|
+
`Invalid --prop value: "${propString}". Expected format: "PropertyName=Value".`,
|
|
1765
|
+
'Example: --prop "Status=Done"'
|
|
1766
|
+
);
|
|
1767
|
+
}
|
|
1768
|
+
const propName = propString.slice(0, eqIdx).trim();
|
|
1769
|
+
const value = propString.slice(eqIdx + 1);
|
|
1770
|
+
const schemaProp = schema[propName];
|
|
1771
|
+
if (!schemaProp) {
|
|
1772
|
+
const available = Object.keys(schema).join(", ");
|
|
1773
|
+
throw new CliError(
|
|
1774
|
+
ErrorCodes.INVALID_ARG,
|
|
1775
|
+
`Property "${propName}" not found on this page.`,
|
|
1776
|
+
`Available properties: ${available}`
|
|
1777
|
+
);
|
|
1778
|
+
}
|
|
1779
|
+
const propType = schemaProp.type;
|
|
1780
|
+
const payload = buildPropertyUpdate(propName, propType, value);
|
|
1781
|
+
result[propName] = payload;
|
|
1782
|
+
}
|
|
1783
|
+
return result;
|
|
1784
|
+
}
|
|
1785
|
+
async function updatePageProperties(client, pageId, properties) {
|
|
1786
|
+
const response = await client.pages.update({
|
|
1787
|
+
page_id: pageId,
|
|
1788
|
+
properties
|
|
1789
|
+
});
|
|
1790
|
+
return response;
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
// src/commands/create-page.ts
|
|
1794
|
+
function collectProps(val, acc) {
|
|
1795
|
+
acc.push(val);
|
|
1796
|
+
return acc;
|
|
1797
|
+
}
|
|
1798
|
+
async function tryGetDatabaseSchema(client, uuid) {
|
|
1799
|
+
try {
|
|
1800
|
+
return await fetchDatabaseSchema(client, uuid);
|
|
1801
|
+
} catch {
|
|
1802
|
+
return null;
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
function createPageCommand() {
|
|
1806
|
+
const cmd = new Command9("create-page");
|
|
1807
|
+
cmd.description("create a new Notion page under a parent page or database").requiredOption("--parent <id/url>", "parent page or database ID/URL").requiredOption("--title <title>", "page title").option(
|
|
1808
|
+
"-m, --message <markdown>",
|
|
1809
|
+
"inline markdown content for the page body"
|
|
1810
|
+
).option(
|
|
1811
|
+
"--prop <property=value>",
|
|
1812
|
+
"set a property value (repeatable, database parents only)",
|
|
1813
|
+
collectProps,
|
|
1814
|
+
[]
|
|
1815
|
+
).option("--icon <emoji-or-url>", "page icon \u2014 emoji character or image URL").option("--cover <url>", "page cover image URL").action(
|
|
1816
|
+
withErrorHandling(async (opts) => {
|
|
1817
|
+
const { token, source } = await resolveToken();
|
|
1818
|
+
reportTokenSource(source);
|
|
1819
|
+
const client = createNotionClient(token);
|
|
1820
|
+
let markdown = "";
|
|
1821
|
+
if (opts.message) {
|
|
1822
|
+
markdown = opts.message;
|
|
1823
|
+
} else if (!process.stdin.isTTY) {
|
|
1824
|
+
markdown = await readStdin();
|
|
1825
|
+
}
|
|
1826
|
+
const parentUuid = toUuid(parseNotionId(opts.parent));
|
|
1827
|
+
const iconCover = { icon: opts.icon, cover: opts.cover };
|
|
1828
|
+
const dbSchema = await tryGetDatabaseSchema(client, parentUuid);
|
|
1829
|
+
if (dbSchema) {
|
|
1830
|
+
const titleEntry = Object.entries(dbSchema.properties).find(
|
|
1831
|
+
([, prop]) => prop.type === "title"
|
|
1832
|
+
);
|
|
1833
|
+
if (!titleEntry) {
|
|
1834
|
+
throw new CliError(
|
|
1835
|
+
ErrorCodes.API_ERROR,
|
|
1836
|
+
"Database has no title property.",
|
|
1837
|
+
"This database cannot accept new pages."
|
|
1838
|
+
);
|
|
1839
|
+
}
|
|
1840
|
+
const [titlePropName] = titleEntry;
|
|
1841
|
+
const extraProperties = opts.prop.length > 0 ? buildPropertiesPayload(opts.prop, dbSchema.properties) : {};
|
|
1842
|
+
const url = await createPageInDatabase(
|
|
1843
|
+
client,
|
|
1844
|
+
dbSchema.databaseId,
|
|
1845
|
+
titlePropName,
|
|
1846
|
+
opts.title,
|
|
1847
|
+
extraProperties,
|
|
1848
|
+
markdown,
|
|
1849
|
+
iconCover
|
|
1850
|
+
);
|
|
1851
|
+
process.stdout.write(`${url}
|
|
1852
|
+
`);
|
|
1853
|
+
} else {
|
|
1854
|
+
if (opts.prop.length > 0) {
|
|
1855
|
+
throw new CliError(
|
|
1856
|
+
ErrorCodes.INVALID_ARG,
|
|
1857
|
+
"--prop is only supported when the parent is a database.",
|
|
1858
|
+
"To set properties, use a database ID/URL as --parent"
|
|
1859
|
+
);
|
|
1860
|
+
}
|
|
1861
|
+
const url = await createPage(
|
|
1862
|
+
client,
|
|
1863
|
+
parentUuid,
|
|
1864
|
+
opts.title,
|
|
1865
|
+
markdown,
|
|
1866
|
+
iconCover
|
|
1867
|
+
);
|
|
1868
|
+
process.stdout.write(`${url}
|
|
1869
|
+
`);
|
|
1870
|
+
}
|
|
1871
|
+
})
|
|
1872
|
+
);
|
|
1873
|
+
return cmd;
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1654
1876
|
// src/commands/db/query.ts
|
|
1877
|
+
import { Command as Command10 } from "commander";
|
|
1655
1878
|
var SKIP_TYPES_IN_AUTO = /* @__PURE__ */ new Set(["relation", "rich_text", "people"]);
|
|
1656
1879
|
function autoSelectColumns(schema, entries) {
|
|
1657
1880
|
const termWidth = process.stdout.columns || 120;
|
|
@@ -1679,7 +1902,7 @@ function autoSelectColumns(schema, entries) {
|
|
|
1679
1902
|
return selected;
|
|
1680
1903
|
}
|
|
1681
1904
|
function dbQueryCommand() {
|
|
1682
|
-
return new
|
|
1905
|
+
return new Command10("query").description("Query database entries with optional filtering and sorting").argument("<id>", "Notion database ID or URL").option(
|
|
1683
1906
|
"--filter <filter>",
|
|
1684
1907
|
'Filter entries (repeatable): --filter "Status=Done"',
|
|
1685
1908
|
collect,
|
|
@@ -1734,9 +1957,9 @@ function collect(value, previous) {
|
|
|
1734
1957
|
}
|
|
1735
1958
|
|
|
1736
1959
|
// src/commands/db/schema.ts
|
|
1737
|
-
import { Command as
|
|
1960
|
+
import { Command as Command11 } from "commander";
|
|
1738
1961
|
function dbSchemaCommand() {
|
|
1739
|
-
return new
|
|
1962
|
+
return new Command11("schema").description("Show database schema (property names, types, and options)").argument("<id>", "Notion database ID or URL").option("--json", "Output raw JSON").action(
|
|
1740
1963
|
withErrorHandling(async (id, options) => {
|
|
1741
1964
|
const { token } = await resolveToken();
|
|
1742
1965
|
const client = createNotionClient(token);
|
|
@@ -1760,13 +1983,13 @@ function dbSchemaCommand() {
|
|
|
1760
1983
|
}
|
|
1761
1984
|
|
|
1762
1985
|
// src/commands/edit-page.ts
|
|
1763
|
-
import { Command as
|
|
1986
|
+
import { Command as Command12 } from "commander";
|
|
1764
1987
|
function collect2(val, acc) {
|
|
1765
1988
|
acc.push(val);
|
|
1766
1989
|
return acc;
|
|
1767
1990
|
}
|
|
1768
1991
|
function editPageCommand() {
|
|
1769
|
-
const cmd = new
|
|
1992
|
+
const cmd = new Command12("edit-page");
|
|
1770
1993
|
cmd.description(
|
|
1771
1994
|
"replace a Notion page's content \u2014 full page or a targeted section"
|
|
1772
1995
|
).argument("<id/url>", "Notion page ID or URL").option(
|
|
@@ -1864,7 +2087,7 @@ function editPageCommand() {
|
|
|
1864
2087
|
|
|
1865
2088
|
// src/commands/init.ts
|
|
1866
2089
|
import { confirm, input as input2, password } from "@inquirer/prompts";
|
|
1867
|
-
import { Command as
|
|
2090
|
+
import { Command as Command13 } from "commander";
|
|
1868
2091
|
async function runInitFlow() {
|
|
1869
2092
|
const profileName = await input2({
|
|
1870
2093
|
message: "Profile name:",
|
|
@@ -1944,7 +2167,7 @@ async function runInitFlow() {
|
|
|
1944
2167
|
stderrWrite(dim(" notion auth login"));
|
|
1945
2168
|
}
|
|
1946
2169
|
function initCommand() {
|
|
1947
|
-
const cmd = new
|
|
2170
|
+
const cmd = new Command13("init");
|
|
1948
2171
|
cmd.description("authenticate with Notion and save a profile").action(
|
|
1949
2172
|
withErrorHandling(async () => {
|
|
1950
2173
|
if (!process.stdin.isTTY) {
|
|
@@ -1962,7 +2185,7 @@ function initCommand() {
|
|
|
1962
2185
|
|
|
1963
2186
|
// src/commands/ls.ts
|
|
1964
2187
|
import { isFullPageOrDataSource } from "@notionhq/client";
|
|
1965
|
-
import { Command as
|
|
2188
|
+
import { Command as Command14 } from "commander";
|
|
1966
2189
|
function getTitle(item) {
|
|
1967
2190
|
if (item.object === "data_source") {
|
|
1968
2191
|
return item.title.map((t) => t.plain_text).join("") || "(untitled)";
|
|
@@ -1979,7 +2202,7 @@ function displayType(item) {
|
|
|
1979
2202
|
return item.object === "data_source" ? "database" : item.object;
|
|
1980
2203
|
}
|
|
1981
2204
|
function lsCommand() {
|
|
1982
|
-
const cmd = new
|
|
2205
|
+
const cmd = new Command14("ls");
|
|
1983
2206
|
cmd.description("list accessible Notion pages and databases").option(
|
|
1984
2207
|
"--type <type>",
|
|
1985
2208
|
"filter by object type (page or database)",
|
|
@@ -2042,10 +2265,10 @@ function lsCommand() {
|
|
|
2042
2265
|
// src/commands/open.ts
|
|
2043
2266
|
import { exec } from "child_process";
|
|
2044
2267
|
import { promisify } from "util";
|
|
2045
|
-
import { Command as
|
|
2268
|
+
import { Command as Command15 } from "commander";
|
|
2046
2269
|
var execAsync = promisify(exec);
|
|
2047
2270
|
function openCommand() {
|
|
2048
|
-
const cmd = new
|
|
2271
|
+
const cmd = new Command15("open");
|
|
2049
2272
|
cmd.description("open a Notion page in the default browser").argument("<id/url>", "Notion page ID or URL").action(
|
|
2050
2273
|
withErrorHandling(async (idOrUrl) => {
|
|
2051
2274
|
const id = parseNotionId(idOrUrl);
|
|
@@ -2061,9 +2284,9 @@ function openCommand() {
|
|
|
2061
2284
|
}
|
|
2062
2285
|
|
|
2063
2286
|
// src/commands/profile/list.ts
|
|
2064
|
-
import { Command as
|
|
2287
|
+
import { Command as Command16 } from "commander";
|
|
2065
2288
|
function profileListCommand() {
|
|
2066
|
-
const cmd = new
|
|
2289
|
+
const cmd = new Command16("list");
|
|
2067
2290
|
cmd.description("list all authentication profiles").action(
|
|
2068
2291
|
withErrorHandling(async () => {
|
|
2069
2292
|
const config = await readGlobalConfig();
|
|
@@ -2092,9 +2315,9 @@ function profileListCommand() {
|
|
|
2092
2315
|
}
|
|
2093
2316
|
|
|
2094
2317
|
// src/commands/profile/remove.ts
|
|
2095
|
-
import { Command as
|
|
2318
|
+
import { Command as Command17 } from "commander";
|
|
2096
2319
|
function profileRemoveCommand() {
|
|
2097
|
-
const cmd = new
|
|
2320
|
+
const cmd = new Command17("remove");
|
|
2098
2321
|
cmd.description("remove an authentication profile").argument("<name>", "profile name to remove").action(
|
|
2099
2322
|
withErrorHandling(async (name) => {
|
|
2100
2323
|
const config = await readGlobalConfig();
|
|
@@ -2120,9 +2343,9 @@ function profileRemoveCommand() {
|
|
|
2120
2343
|
}
|
|
2121
2344
|
|
|
2122
2345
|
// src/commands/profile/use.ts
|
|
2123
|
-
import { Command as
|
|
2346
|
+
import { Command as Command18 } from "commander";
|
|
2124
2347
|
function profileUseCommand() {
|
|
2125
|
-
const cmd = new
|
|
2348
|
+
const cmd = new Command18("use");
|
|
2126
2349
|
cmd.description("switch the active profile").argument("<name>", "profile name to activate").action(
|
|
2127
2350
|
withErrorHandling(async (name) => {
|
|
2128
2351
|
const config = await readGlobalConfig();
|
|
@@ -2145,7 +2368,7 @@ function profileUseCommand() {
|
|
|
2145
2368
|
}
|
|
2146
2369
|
|
|
2147
2370
|
// src/commands/read.ts
|
|
2148
|
-
import { Command as
|
|
2371
|
+
import { Command as Command19 } from "commander";
|
|
2149
2372
|
|
|
2150
2373
|
// src/output/markdown.ts
|
|
2151
2374
|
import { Chalk as Chalk2 } from "chalk";
|
|
@@ -2285,7 +2508,7 @@ async function fetchPageMarkdown(client, pageId) {
|
|
|
2285
2508
|
|
|
2286
2509
|
// src/commands/read.ts
|
|
2287
2510
|
function readCommand() {
|
|
2288
|
-
return new
|
|
2511
|
+
return new Command19("read").description("Read a Notion page as markdown").argument("<id>", "Notion page ID or URL").action(
|
|
2289
2512
|
withErrorHandling(async (id) => {
|
|
2290
2513
|
const { token } = await resolveToken();
|
|
2291
2514
|
const client = createNotionClient(token);
|
|
@@ -2311,7 +2534,7 @@ function readCommand() {
|
|
|
2311
2534
|
|
|
2312
2535
|
// src/commands/search.ts
|
|
2313
2536
|
import { isFullPageOrDataSource as isFullPageOrDataSource2 } from "@notionhq/client";
|
|
2314
|
-
import { Command as
|
|
2537
|
+
import { Command as Command20 } from "commander";
|
|
2315
2538
|
function getTitle2(item) {
|
|
2316
2539
|
if (item.object === "data_source") {
|
|
2317
2540
|
return item.title.map((t) => t.plain_text).join("") || "(untitled)";
|
|
@@ -2331,7 +2554,7 @@ function displayType2(item) {
|
|
|
2331
2554
|
return item.object === "data_source" ? "database" : item.object;
|
|
2332
2555
|
}
|
|
2333
2556
|
function searchCommand() {
|
|
2334
|
-
const cmd = new
|
|
2557
|
+
const cmd = new Command20("search");
|
|
2335
2558
|
cmd.description("search Notion workspace by keyword").argument("<query>", "search keyword").option(
|
|
2336
2559
|
"--type <type>",
|
|
2337
2560
|
"filter by object type (page or database)",
|
|
@@ -2389,128 +2612,17 @@ function searchCommand() {
|
|
|
2389
2612
|
}
|
|
2390
2613
|
|
|
2391
2614
|
// src/commands/update.ts
|
|
2392
|
-
import { Command as
|
|
2393
|
-
|
|
2394
|
-
// src/services/update.service.ts
|
|
2395
|
-
var UNSUPPORTED_TYPES = /* @__PURE__ */ new Set([
|
|
2396
|
-
"relation",
|
|
2397
|
-
"formula",
|
|
2398
|
-
"rollup",
|
|
2399
|
-
"created_time",
|
|
2400
|
-
"created_by",
|
|
2401
|
-
"last_edited_time",
|
|
2402
|
-
"last_edited_by",
|
|
2403
|
-
"files",
|
|
2404
|
-
"unique_id",
|
|
2405
|
-
"verification",
|
|
2406
|
-
"button"
|
|
2407
|
-
]);
|
|
2408
|
-
function buildPropertyUpdate(propName, propType, value) {
|
|
2409
|
-
if (UNSUPPORTED_TYPES.has(propType)) {
|
|
2410
|
-
throw new CliError(
|
|
2411
|
-
ErrorCodes.INVALID_ARG,
|
|
2412
|
-
`Property "${propName}" has type "${propType}" which cannot be set via the CLI.`,
|
|
2413
|
-
"Supported types: title, rich_text, select, status, multi_select, number, checkbox, url, email, phone_number, date"
|
|
2414
|
-
);
|
|
2415
|
-
}
|
|
2416
|
-
if (value === "") {
|
|
2417
|
-
return null;
|
|
2418
|
-
}
|
|
2419
|
-
switch (propType) {
|
|
2420
|
-
case "title":
|
|
2421
|
-
return { title: [{ type: "text", text: { content: value } }] };
|
|
2422
|
-
case "rich_text":
|
|
2423
|
-
return { rich_text: [{ type: "text", text: { content: value } }] };
|
|
2424
|
-
case "select":
|
|
2425
|
-
return { select: { name: value } };
|
|
2426
|
-
case "status":
|
|
2427
|
-
return { status: { name: value } };
|
|
2428
|
-
case "multi_select":
|
|
2429
|
-
return {
|
|
2430
|
-
multi_select: value.split(",").map((v) => v.trim()).filter(Boolean).map((v) => ({ name: v }))
|
|
2431
|
-
};
|
|
2432
|
-
case "number": {
|
|
2433
|
-
const n = Number(value);
|
|
2434
|
-
if (Number.isNaN(n)) {
|
|
2435
|
-
throw new CliError(
|
|
2436
|
-
ErrorCodes.INVALID_ARG,
|
|
2437
|
-
`Invalid number value "${value}" for property "${propName}".`,
|
|
2438
|
-
'Provide a numeric value, e.g. --prop "Count=42"'
|
|
2439
|
-
);
|
|
2440
|
-
}
|
|
2441
|
-
return { number: n };
|
|
2442
|
-
}
|
|
2443
|
-
case "checkbox": {
|
|
2444
|
-
const lower = value.toLowerCase();
|
|
2445
|
-
return { checkbox: lower === "true" || lower === "yes" };
|
|
2446
|
-
}
|
|
2447
|
-
case "url":
|
|
2448
|
-
return { url: value };
|
|
2449
|
-
case "email":
|
|
2450
|
-
return { email: value };
|
|
2451
|
-
case "phone_number":
|
|
2452
|
-
return { phone_number: value };
|
|
2453
|
-
case "date": {
|
|
2454
|
-
const parts = value.split(",");
|
|
2455
|
-
const start = parts[0].trim();
|
|
2456
|
-
const end = parts[1]?.trim();
|
|
2457
|
-
return { date: end ? { start, end } : { start } };
|
|
2458
|
-
}
|
|
2459
|
-
default:
|
|
2460
|
-
throw new CliError(
|
|
2461
|
-
ErrorCodes.INVALID_ARG,
|
|
2462
|
-
`Property "${propName}" has unsupported type "${propType}".`,
|
|
2463
|
-
"Supported types: title, rich_text, select, status, multi_select, number, checkbox, url, email, phone_number, date"
|
|
2464
|
-
);
|
|
2465
|
-
}
|
|
2466
|
-
}
|
|
2467
|
-
function buildPropertiesPayload(propStrings, page) {
|
|
2468
|
-
const result = {};
|
|
2469
|
-
for (const propString of propStrings) {
|
|
2470
|
-
const eqIdx = propString.indexOf("=");
|
|
2471
|
-
if (eqIdx === -1) {
|
|
2472
|
-
throw new CliError(
|
|
2473
|
-
ErrorCodes.INVALID_ARG,
|
|
2474
|
-
`Invalid --prop value: "${propString}". Expected format: "PropertyName=Value".`,
|
|
2475
|
-
'Example: --prop "Status=Done"'
|
|
2476
|
-
);
|
|
2477
|
-
}
|
|
2478
|
-
const propName = propString.slice(0, eqIdx).trim();
|
|
2479
|
-
const value = propString.slice(eqIdx + 1);
|
|
2480
|
-
const schemaProp = page.properties[propName];
|
|
2481
|
-
if (!schemaProp) {
|
|
2482
|
-
const available = Object.keys(page.properties).join(", ");
|
|
2483
|
-
throw new CliError(
|
|
2484
|
-
ErrorCodes.INVALID_ARG,
|
|
2485
|
-
`Property "${propName}" not found on this page.`,
|
|
2486
|
-
`Available properties: ${available}`
|
|
2487
|
-
);
|
|
2488
|
-
}
|
|
2489
|
-
const propType = schemaProp.type;
|
|
2490
|
-
const payload = buildPropertyUpdate(propName, propType, value);
|
|
2491
|
-
result[propName] = payload;
|
|
2492
|
-
}
|
|
2493
|
-
return result;
|
|
2494
|
-
}
|
|
2495
|
-
async function updatePageProperties(client, pageId, properties) {
|
|
2496
|
-
const response = await client.pages.update({
|
|
2497
|
-
page_id: pageId,
|
|
2498
|
-
properties
|
|
2499
|
-
});
|
|
2500
|
-
return response;
|
|
2501
|
-
}
|
|
2502
|
-
|
|
2503
|
-
// src/commands/update.ts
|
|
2504
|
-
function collectProps(val, acc) {
|
|
2615
|
+
import { Command as Command21 } from "commander";
|
|
2616
|
+
function collectProps2(val, acc) {
|
|
2505
2617
|
acc.push(val);
|
|
2506
2618
|
return acc;
|
|
2507
2619
|
}
|
|
2508
2620
|
function updateCommand() {
|
|
2509
|
-
const cmd = new
|
|
2621
|
+
const cmd = new Command21("update");
|
|
2510
2622
|
cmd.description("update properties on a Notion page").argument("<id/url>", "Notion page ID or URL").option(
|
|
2511
2623
|
"--prop <property=value>",
|
|
2512
2624
|
"set a property value (repeatable)",
|
|
2513
|
-
|
|
2625
|
+
collectProps2,
|
|
2514
2626
|
[]
|
|
2515
2627
|
).option("--title <title>", "set the page title").action(
|
|
2516
2628
|
withErrorHandling(async (idOrUrl, opts) => {
|
|
@@ -2564,7 +2676,7 @@ function updateCommand() {
|
|
|
2564
2676
|
}
|
|
2565
2677
|
|
|
2566
2678
|
// src/commands/users.ts
|
|
2567
|
-
import { Command as
|
|
2679
|
+
import { Command as Command22 } from "commander";
|
|
2568
2680
|
function getEmailOrWorkspace(user) {
|
|
2569
2681
|
if (user.type === "person") {
|
|
2570
2682
|
return user.person.email ?? "\u2014";
|
|
@@ -2576,7 +2688,7 @@ function getEmailOrWorkspace(user) {
|
|
|
2576
2688
|
return "\u2014";
|
|
2577
2689
|
}
|
|
2578
2690
|
function usersCommand() {
|
|
2579
|
-
const cmd = new
|
|
2691
|
+
const cmd = new Command22("users");
|
|
2580
2692
|
cmd.description("list all users in the workspace").option("--json", "output as JSON").action(
|
|
2581
2693
|
withErrorHandling(async (opts) => {
|
|
2582
2694
|
if (opts.json) setOutputMode("json");
|
|
@@ -2607,7 +2719,7 @@ var __dirname = dirname(__filename);
|
|
|
2607
2719
|
var pkg = JSON.parse(
|
|
2608
2720
|
readFileSync(join3(__dirname, "../package.json"), "utf-8")
|
|
2609
2721
|
);
|
|
2610
|
-
var program = new
|
|
2722
|
+
var program = new Command23();
|
|
2611
2723
|
program.name("notion").description("Notion CLI \u2014 read Notion pages and databases from the terminal").version(pkg.version);
|
|
2612
2724
|
program.option("--verbose", "show API requests/responses").option("--color", "force color output").option("--json", "force JSON output (overrides TTY detection)").option("--md", "force markdown output for page content");
|
|
2613
2725
|
program.configureOutput({
|
|
@@ -2628,7 +2740,7 @@ program.hook("preAction", (thisCommand) => {
|
|
|
2628
2740
|
setOutputMode("md");
|
|
2629
2741
|
}
|
|
2630
2742
|
});
|
|
2631
|
-
var authCmd = new
|
|
2743
|
+
var authCmd = new Command23("auth").description("manage Notion authentication");
|
|
2632
2744
|
authCmd.action(authDefaultAction(authCmd));
|
|
2633
2745
|
authCmd.addCommand(loginCommand());
|
|
2634
2746
|
authCmd.addCommand(logoutCommand());
|
|
@@ -2638,7 +2750,7 @@ authCmd.addCommand(profileUseCommand());
|
|
|
2638
2750
|
authCmd.addCommand(profileRemoveCommand());
|
|
2639
2751
|
program.addCommand(authCmd);
|
|
2640
2752
|
program.addCommand(initCommand(), { hidden: true });
|
|
2641
|
-
var profileCmd = new
|
|
2753
|
+
var profileCmd = new Command23("profile").description(
|
|
2642
2754
|
"manage authentication profiles"
|
|
2643
2755
|
);
|
|
2644
2756
|
profileCmd.addCommand(profileListCommand());
|
|
@@ -2656,7 +2768,8 @@ program.addCommand(appendCommand());
|
|
|
2656
2768
|
program.addCommand(createPageCommand());
|
|
2657
2769
|
program.addCommand(editPageCommand());
|
|
2658
2770
|
program.addCommand(updateCommand());
|
|
2659
|
-
|
|
2771
|
+
program.addCommand(archiveCommand());
|
|
2772
|
+
var dbCmd = new Command23("db").description("Database operations");
|
|
2660
2773
|
dbCmd.addCommand(dbSchemaCommand());
|
|
2661
2774
|
dbCmd.addCommand(dbQueryCommand());
|
|
2662
2775
|
program.addCommand(dbCmd);
|