@kamilio/wire 0.1.2 → 0.1.4
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 -1
- package/bin/wire-mcp.mjs +1 -1
- package/dist/adapters/root.d.ts +5 -2
- package/dist/adapters/root.d.ts.map +1 -1
- package/dist/adapters/root.js +58 -30
- package/dist/adapters/root.js.map +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +9 -36
- package/dist/auth.js.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/executable.d.ts +3 -1
- package/dist/executable.d.ts.map +1 -1
- package/dist/executable.js +38 -12
- package/dist/executable.js.map +1 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +22 -7
- package/dist/hooks.js.map +1 -1
- package/node_modules/provider-asana/dist/asana-project.d.ts.map +1 -1
- package/node_modules/provider-asana/dist/asana-project.js +3 -0
- package/node_modules/provider-asana/dist/asana-project.js.map +1 -1
- package/node_modules/provider-asana/src/asana-project.ts +2 -0
- package/node_modules/provider-chatgpt/dist/chatgpt.d.ts.map +1 -1
- package/node_modules/provider-chatgpt/dist/chatgpt.js +24 -3
- package/node_modules/provider-chatgpt/dist/chatgpt.js.map +1 -1
- package/node_modules/provider-chatgpt/src/chatgpt.ts +21 -3
- package/node_modules/provider-gmail/dist/gmail.d.ts.map +1 -1
- package/node_modules/provider-gmail/dist/gmail.js +8 -2
- package/node_modules/provider-gmail/dist/gmail.js.map +1 -1
- package/node_modules/provider-gmail/src/gmail.ts +8 -2
- package/node_modules/provider-google-docs/dist/google-docs.d.ts.map +1 -1
- package/node_modules/provider-google-docs/dist/google-docs.js +373 -9
- package/node_modules/provider-google-docs/dist/google-docs.js.map +1 -1
- package/node_modules/provider-google-docs/dist/google-forms.d.ts +28 -0
- package/node_modules/provider-google-docs/dist/google-forms.d.ts.map +1 -0
- package/node_modules/provider-google-docs/dist/google-forms.js +191 -0
- package/node_modules/provider-google-docs/dist/google-forms.js.map +1 -0
- package/node_modules/provider-google-docs/dist/index.d.ts +26 -0
- package/node_modules/provider-google-docs/dist/index.d.ts.map +1 -1
- package/node_modules/provider-google-docs/dist/index.js +3 -1
- package/node_modules/provider-google-docs/dist/index.js.map +1 -1
- package/node_modules/provider-google-docs/src/google-docs.ts +342 -10
- package/node_modules/provider-google-docs/src/google-forms.ts +179 -0
- package/node_modules/provider-google-docs/src/index.ts +3 -1
- package/node_modules/provider-notion/dist/notion-sync.d.ts +2 -2
- package/node_modules/provider-notion/dist/notion-sync.d.ts.map +1 -1
- package/node_modules/provider-notion/dist/notion-sync.js +89 -38
- package/node_modules/provider-notion/dist/notion-sync.js.map +1 -1
- package/node_modules/provider-notion/dist/notion.js +1 -1
- package/node_modules/provider-notion/dist/notion.js.map +1 -1
- package/node_modules/provider-notion/src/notion-sync.ts +90 -35
- package/node_modules/provider-notion/src/notion.ts +1 -1
- package/node_modules/provider-slack/dist/slack.d.ts.map +1 -1
- package/node_modules/provider-slack/dist/slack.js +14 -7
- package/node_modules/provider-slack/dist/slack.js.map +1 -1
- package/node_modules/provider-slack/src/slack.ts +14 -5
- package/node_modules/provider-zoom/dist/zoom-hub.d.ts.map +1 -1
- package/node_modules/provider-zoom/dist/zoom-hub.js +42 -35
- package/node_modules/provider-zoom/dist/zoom-hub.js.map +1 -1
- package/node_modules/provider-zoom/src/zoom-hub.ts +40 -35
- package/node_modules/wire-core/dist/core/model.d.ts +1 -1
- package/node_modules/wire-core/dist/core/model.d.ts.map +1 -1
- package/node_modules/wire-core/dist/core/transform.d.ts +1 -0
- package/node_modules/wire-core/dist/core/transform.d.ts.map +1 -1
- package/node_modules/wire-core/dist/core/transform.js +4 -0
- package/node_modules/wire-core/dist/core/transform.js.map +1 -1
- package/node_modules/wire-core/dist/index.d.ts +3 -2
- package/node_modules/wire-core/dist/index.d.ts.map +1 -1
- package/node_modules/wire-core/dist/index.js +2 -2
- package/node_modules/wire-core/dist/index.js.map +1 -1
- package/node_modules/wire-core/dist/operations.d.ts +3 -0
- package/node_modules/wire-core/dist/operations.d.ts.map +1 -1
- package/node_modules/wire-core/dist/operations.js +50 -9
- package/node_modules/wire-core/dist/operations.js.map +1 -1
- package/node_modules/wire-core/dist/ports.d.ts +1 -0
- package/node_modules/wire-core/dist/ports.d.ts.map +1 -1
- package/node_modules/wire-core/dist/runtime/chrome.d.ts +1 -0
- package/node_modules/wire-core/dist/runtime/chrome.d.ts.map +1 -1
- package/node_modules/wire-core/dist/runtime/chrome.js +91 -83
- package/node_modules/wire-core/dist/runtime/chrome.js.map +1 -1
- package/node_modules/wire-core/dist/runtime/cookies.d.ts.map +1 -1
- package/node_modules/wire-core/dist/runtime/cookies.js +7 -2
- package/node_modules/wire-core/dist/runtime/cookies.js.map +1 -1
- package/node_modules/wire-core/dist/runtime/node.d.ts.map +1 -1
- package/node_modules/wire-core/dist/runtime/node.js +4 -0
- package/node_modules/wire-core/dist/runtime/node.js.map +1 -1
- package/node_modules/wire-core/dist/storage/registry.d.ts.map +1 -1
- package/node_modules/wire-core/dist/storage/registry.js +95 -208
- package/node_modules/wire-core/dist/storage/registry.js.map +1 -1
- package/node_modules/wire-core/dist/storage/workspace.d.ts +3 -0
- package/node_modules/wire-core/dist/storage/workspace.d.ts.map +1 -1
- package/node_modules/wire-core/dist/storage/workspace.js +10 -1
- package/node_modules/wire-core/dist/storage/workspace.js.map +1 -1
- package/node_modules/wire-core/package.json +4 -0
- package/node_modules/wire-core/src/core/model.ts +1 -1
- package/node_modules/wire-core/src/core/transform.ts +5 -1
- package/node_modules/wire-core/src/index.ts +3 -2
- package/node_modules/wire-core/src/operations.ts +56 -10
- package/node_modules/wire-core/src/ports.ts +1 -0
- package/node_modules/wire-core/src/runtime/chrome.ts +99 -80
- package/node_modules/wire-core/src/runtime/cookies.ts +4 -2
- package/node_modules/wire-core/src/runtime/node.ts +4 -0
- package/node_modules/wire-core/src/storage/registry.ts +48 -15
- package/node_modules/wire-core/src/storage/workspace.ts +10 -1
- package/package.json +1 -1
- package/src/adapters/root.ts +51 -31
- package/src/auth.ts +10 -29
- package/src/cli.ts +2 -2
- package/src/executable.ts +38 -12
- package/src/hooks.ts +21 -6
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notion-sync.d.ts","sourceRoot":"","sources":["../src/notion-sync.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAErD,MAAM,MAAM,cAAc,GAAG,SAAS,EAAE,EAAE,CAAC;AAC3C,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,cAAc,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AACzI,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,CAAC,CAAC;AACtG,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,SAAS,SAAS,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAC9H,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AACrI,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAChH,KAAK,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"notion-sync.d.ts","sourceRoot":"","sources":["../src/notion-sync.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ function inlineCode(value) {
|
|
|
20
20
|
return `${ticks}${value}${ticks}`;
|
|
21
21
|
}
|
|
22
22
|
function escapeInlineMarkdown(value) {
|
|
23
|
-
return value.replace(/\\/g, "\\\\").replace(/\*/g, "\\*").replace(/~/g, "\\~").replace(/\[/g, "\\[").replace(/\]/g, "\\]");
|
|
23
|
+
return value.replace(/\\/g, "\\\\").replace(/\*/g, "\\*").replace(/~/g, "\\~").replace(/`/g, "\\`").replace(/\[/g, "\\[").replace(/\]/g, "\\]");
|
|
24
24
|
}
|
|
25
25
|
function unescapeInlineMarkdown(value) {
|
|
26
26
|
return value.replace(/\\([\\*~[\]()])/g, "$1");
|
|
@@ -60,6 +60,10 @@ function markdownLink(value) {
|
|
|
60
60
|
function normalizeMarks(marks) {
|
|
61
61
|
return marks.filter((mark) => Array.isArray(mark) && mark.length > 0 && array(mark)[0] !== "m").map((mark) => clone(mark)).sort((left, right) => compact(left).localeCompare(compact(right)));
|
|
62
62
|
}
|
|
63
|
+
function renderMarks(marks) {
|
|
64
|
+
const priority = new Map([["c", 0], ["_", 1], ["h", 2], ["e", 3], ["p", 4], ["u", 5], ["d", 6], ["s", 7], ["i", 8], ["b", 9], ["a", 10]]);
|
|
65
|
+
return [...marks].sort((left, right) => priority.get(array(left)[0]) - priority.get(array(right)[0]) || compact(left).localeCompare(compact(right)));
|
|
66
|
+
}
|
|
63
67
|
function normalizeRichText(value) {
|
|
64
68
|
const output = [];
|
|
65
69
|
for (const raw of value) {
|
|
@@ -132,6 +136,17 @@ function parseInline(value) {
|
|
|
132
136
|
rest = rest.slice(mentionSpan[0].length);
|
|
133
137
|
continue;
|
|
134
138
|
}
|
|
139
|
+
if (rest.startsWith("***")) {
|
|
140
|
+
const end = closingDelimiter(rest, 3, "***");
|
|
141
|
+
if (end !== -1) {
|
|
142
|
+
for (const segment of parseInline(rest.slice(3, end))) {
|
|
143
|
+
const marks = normalizeMarks([...(segment[1] ?? []), ["b"], ["i"]]);
|
|
144
|
+
push(segment[0], marks);
|
|
145
|
+
}
|
|
146
|
+
rest = rest.slice(end + 3);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
135
150
|
if (rest.startsWith("**")) {
|
|
136
151
|
const end = closingDelimiter(rest, 2, "**");
|
|
137
152
|
if (end !== -1) {
|
|
@@ -197,7 +212,7 @@ function parseInline(value) {
|
|
|
197
212
|
function renderSegment(content, marks) {
|
|
198
213
|
let rendered = marks.some((raw) => raw[0] === "c") ? content : escapeInlineMarkdown(content);
|
|
199
214
|
let link = null;
|
|
200
|
-
for (const raw of marks) {
|
|
215
|
+
for (const raw of renderMarks(marks)) {
|
|
201
216
|
const mark = raw;
|
|
202
217
|
if (mark[0] === "c")
|
|
203
218
|
rendered = inlineCode(rendered);
|
|
@@ -277,6 +292,9 @@ function isTableSeparator(row) {
|
|
|
277
292
|
function markdownBlockStart(stripped) {
|
|
278
293
|
return /^(#{1,6})\s+|^[-*]\s+|^\d+\.\s+|^-\s+\[[ xX]\]\s+|^```|^---$|^!\[|^>|^\||^:::/.test(stripped);
|
|
279
294
|
}
|
|
295
|
+
function escapeBlockMarkdownLine(line) {
|
|
296
|
+
return markdownBlockStart(line) ? `\\${line}` : line;
|
|
297
|
+
}
|
|
280
298
|
function colonFenceBody(lines, index) {
|
|
281
299
|
const body = [];
|
|
282
300
|
let depth = 0;
|
|
@@ -373,8 +391,13 @@ function parseLines(lines, baseIndent = 0) {
|
|
|
373
391
|
continue;
|
|
374
392
|
}
|
|
375
393
|
if (stripped.startsWith("> ")) {
|
|
376
|
-
|
|
394
|
+
const content = [stripped.slice(2)];
|
|
377
395
|
index += 1;
|
|
396
|
+
while (index < lines.length && lines[index].trim() !== "" && baseIndent + lineIndent(lines[index]) === indent && stripIndent(lines[index]).startsWith("> ")) {
|
|
397
|
+
content.push(stripIndent(lines[index]).slice(2));
|
|
398
|
+
index += 1;
|
|
399
|
+
}
|
|
400
|
+
blocks.push({ type: "quote", content: content.join("\n"), properties: {}, rich_text: parseInline(content.join("\n")), indent });
|
|
378
401
|
continue;
|
|
379
402
|
}
|
|
380
403
|
if (stripped.startsWith("|")) {
|
|
@@ -488,7 +511,26 @@ function parseLines(lines, baseIndent = 0) {
|
|
|
488
511
|
export function parseNotionMarkdown(markdown) {
|
|
489
512
|
return parseLines(markdown.replace(/^\ufeff/, "").split("\n"));
|
|
490
513
|
}
|
|
491
|
-
function
|
|
514
|
+
function tableRowCells(block, columnOrder) {
|
|
515
|
+
const cells = object(block.properties["cells"]);
|
|
516
|
+
if (columnOrder === undefined)
|
|
517
|
+
return cells;
|
|
518
|
+
const localColumns = Object.keys(cells);
|
|
519
|
+
return Object.fromEntries(columnOrder.map((column, index) => [column, cells[localColumns[index]]]));
|
|
520
|
+
}
|
|
521
|
+
function tableColumnOrder(remote, local) {
|
|
522
|
+
const localColumns = local.properties["column_ids"];
|
|
523
|
+
if (remote === undefined)
|
|
524
|
+
return localColumns;
|
|
525
|
+
const remoteColumns = object(remote["format"])["table_block_column_order"];
|
|
526
|
+
const used = new Set();
|
|
527
|
+
return localColumns.map((column, index) => {
|
|
528
|
+
const value = index < remoteColumns.length ? remoteColumns[index] : used.has(column) ? `column_${index}_${randomUUID().replaceAll("-", "")}` : column;
|
|
529
|
+
used.add(value);
|
|
530
|
+
return value;
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
function parserBlockToNotionBlock(block, id, parentId, parentTable, spaceId, userId, currentTime, columnOrder) {
|
|
492
534
|
const base = { id, type: block.type, space_id: spaceId, parent_id: parentId, parent_table: parentTable, alive: true, created_time: currentTime, created_by_table: "notion_user", created_by_id: userId, last_edited_time: currentTime, last_edited_by_table: "notion_user", last_edited_by_id: userId };
|
|
493
535
|
if (block.properties["notion_opaque"] !== undefined)
|
|
494
536
|
return { ...object(block.properties["notion_opaque"]), ...base };
|
|
@@ -503,9 +545,9 @@ function parserBlockToNotionBlock(block, id, parentId, parentTable, spaceId, use
|
|
|
503
545
|
if (block.type === "image")
|
|
504
546
|
return { ...base, properties: { source: [[block.properties["source"]]], alt_text: [[block.properties["alt_text"]]], ...(block.properties["caption"] === undefined ? {} : { caption: block.properties["caption"] }) } };
|
|
505
547
|
if (block.type === "table")
|
|
506
|
-
return { ...base, properties: {}, format: { table_block_column_order: block.properties["column_ids"], table_block_column_header: block.properties["has_header"], table_block_row_header: block.properties["has_row_header"] } };
|
|
548
|
+
return { ...base, properties: {}, format: { table_block_column_order: columnOrder ?? block.properties["column_ids"], table_block_column_header: block.properties["has_header"], table_block_row_header: block.properties["has_row_header"] } };
|
|
507
549
|
if (block.type === "table_row")
|
|
508
|
-
return { ...base, properties: block
|
|
550
|
+
return { ...base, properties: tableRowCells(block, columnOrder) };
|
|
509
551
|
if (block.type === "column_list" || block.type === "transclusion_container")
|
|
510
552
|
return { ...base, properties: {} };
|
|
511
553
|
if (block.type === "column")
|
|
@@ -516,12 +558,13 @@ function parserBlockToNotionBlock(block, id, parentId, parentTable, spaceId, use
|
|
|
516
558
|
return { ...base, properties: { title: block.rich_text }, ...(block.properties["format"] === undefined ? {} : { format: block.properties["format"] }) };
|
|
517
559
|
return { ...base, properties: { title: block.rich_text } };
|
|
518
560
|
}
|
|
519
|
-
export function buildNotionCreateOperations(blocks, pageId, spaceId, userId, currentTime, createId = () => randomUUID()) {
|
|
561
|
+
export function buildNotionCreateOperations(blocks, pageId, spaceId, userId, currentTime, createId = () => randomUUID(), initialTableColumnOrder) {
|
|
520
562
|
const operations = [];
|
|
521
563
|
const topLevelIds = [];
|
|
522
564
|
const lastAtIndent = new Map();
|
|
523
565
|
const lastChildByParent = new Map();
|
|
524
566
|
let lastTableId = null;
|
|
567
|
+
let tableColumnOrder = initialTableColumnOrder;
|
|
525
568
|
for (const block of blocks) {
|
|
526
569
|
const blockId = formatBlockId(createId().replaceAll("-", ""));
|
|
527
570
|
let parentId = pageId;
|
|
@@ -536,14 +579,16 @@ export function buildNotionCreateOperations(blocks, pageId, spaceId, userId, cur
|
|
|
536
579
|
if (block.type !== "table_row" && block.indent === 0)
|
|
537
580
|
topLevelIds.push(blockId);
|
|
538
581
|
const parentTable = "block";
|
|
539
|
-
operations.push({ pointer: pointer(blockId, spaceId), path: [], command: "set", args: parserBlockToNotionBlock(block, blockId, parentId, parentTable, spaceId, userId, currentTime) });
|
|
582
|
+
operations.push({ pointer: pointer(blockId, spaceId), path: [], command: "set", args: parserBlockToNotionBlock(block, blockId, parentId, parentTable, spaceId, userId, currentTime, block.type === "table_row" ? tableColumnOrder : undefined) });
|
|
540
583
|
const after = lastChildByParent.get(parentId);
|
|
541
584
|
operations.push({ pointer: pointer(parentId, spaceId), path: ["content"], command: after === undefined ? "listBefore" : "listAfter", args: after === undefined ? { id: blockId } : { id: blockId, after } });
|
|
542
585
|
lastChildByParent.set(parentId, blockId);
|
|
543
586
|
if (["bulleted_list", "numbered_list", "to_do", "quote", "callout", "toggle", "header", "sub_header", "sub_sub_header", "table", "page", "column_list", "column", "transclusion_container"].includes(block.type))
|
|
544
587
|
lastAtIndent.set(block.indent, blockId);
|
|
545
|
-
if (block.type === "table")
|
|
588
|
+
if (block.type === "table") {
|
|
546
589
|
lastTableId = blockId;
|
|
590
|
+
tableColumnOrder = block.properties["column_ids"];
|
|
591
|
+
}
|
|
547
592
|
}
|
|
548
593
|
if (operations.length > 0)
|
|
549
594
|
operations.push({ pointer: pointer(pageId, spaceId), path: ["last_edited_time"], command: "set", args: currentTime });
|
|
@@ -560,7 +605,7 @@ function canonicalBlock(value, columnOrder) {
|
|
|
560
605
|
if (type === "table")
|
|
561
606
|
return { type, column_count: object(value["format"])["table_block_column_order"].length };
|
|
562
607
|
if (type === "table_row")
|
|
563
|
-
return { type, cells: columnOrder.map((column) => normalizeRichText(object(value["properties"])[column])) };
|
|
608
|
+
return { type, cells: columnOrder.map((column) => normalizeRichText(object(value["properties"])[column] ?? [])) };
|
|
564
609
|
if (type === "image")
|
|
565
610
|
return { type, source: object(value["properties"])["source"], alt_text: object(value["properties"])["alt_text"], caption: object(value["properties"])["caption"] ?? null };
|
|
566
611
|
if (["divider", "column_list", "transclusion_container"].includes(type))
|
|
@@ -584,10 +629,14 @@ function canonicalParserBlock(block, columnOrder) {
|
|
|
584
629
|
return { type: "to_do", title: normalizeRichText(block.rich_text), checked: [[block.properties["checked"] === true ? "Yes" : "No"]] };
|
|
585
630
|
if (block.type === "table")
|
|
586
631
|
return { type: "table", column_count: block.properties["column_ids"].length };
|
|
587
|
-
if (block.type === "table_row")
|
|
588
|
-
|
|
632
|
+
if (block.type === "table_row") {
|
|
633
|
+
const cells = tableRowCells(block, columnOrder);
|
|
634
|
+
return { type: "table_row", cells: columnOrder.map((column) => normalizeRichText(cells[column] ?? [])) };
|
|
635
|
+
}
|
|
589
636
|
if (block.type === "image")
|
|
590
637
|
return { type: "image", source: [[block.properties["source"]]], alt_text: [[block.properties["alt_text"]]], caption: block.properties["caption"] ?? null };
|
|
638
|
+
if (block.type === "page" || block.type === "equation")
|
|
639
|
+
return { type: block.type, title: normalizeRichText(block.rich_text) };
|
|
591
640
|
if (block.type === "column")
|
|
592
641
|
return { type: "column", column_ratio: object(block.properties["format"] ?? {})["column_ratio"] ?? null };
|
|
593
642
|
if (block.type === "column_list" || block.type === "transclusion_container")
|
|
@@ -621,18 +670,21 @@ function localTree(blocks) {
|
|
|
621
670
|
}
|
|
622
671
|
return roots;
|
|
623
672
|
}
|
|
624
|
-
function outputNode(node, remoteNode, parentId, remote, currentTime) {
|
|
673
|
+
function outputNode(node, remoteNode, parentId, remote, currentTime, columnOrder) {
|
|
625
674
|
const id = remoteNode?.id ?? formatBlockId(randomUUID().replaceAll("-", ""));
|
|
626
|
-
|
|
675
|
+
const block = parserBlockToNotionBlock(node.block, id, parentId, "block", remote.spaceId, remote.userId, currentTime, node.block.type === "table" ? tableColumnOrder(remoteNode?.block, node.block) : node.block.type === "table_row" ? columnOrder : undefined);
|
|
676
|
+
const nextColumnOrder = block["type"] === "table" ? object(block["format"])["table_block_column_order"] : columnOrder;
|
|
677
|
+
return { id, block, children: node.children.map((child, index) => outputNode(child, remoteNode?.children[index], id, remote, currentTime, nextColumnOrder)) };
|
|
627
678
|
}
|
|
628
|
-
function emitUpdates(remote, local, blockId, spaceId) {
|
|
679
|
+
function emitUpdates(remote, local, blockId, spaceId, columnOrder) {
|
|
629
680
|
const operations = [];
|
|
630
681
|
const remoteType = remote["type"] === "text" && object(remote["format"] ?? {})["toggleable"] === true ? "toggle" : remote["type"];
|
|
631
682
|
const localType = local.type === "toggle" ? "text" : local.type;
|
|
632
683
|
const typeChanged = remoteType !== local.type;
|
|
633
684
|
if (typeChanged)
|
|
634
685
|
operations.push({ pointer: pointer(blockId, spaceId), path: ["type"], command: "set", args: localType });
|
|
635
|
-
const
|
|
686
|
+
const effectiveColumnOrder = local.type === "table" ? tableColumnOrder(remote, local) : columnOrder;
|
|
687
|
+
const args = parserBlockToNotionBlock(local, blockId, remote["parent_id"] ?? "", "block", spaceId, "", 0, local.type === "table" || local.type === "table_row" ? effectiveColumnOrder : undefined);
|
|
636
688
|
const remoteProperties = object(remote["properties"] ?? {});
|
|
637
689
|
const nextProperties = object(args["properties"] ?? {});
|
|
638
690
|
if (typeChanged) {
|
|
@@ -659,8 +711,8 @@ function flattenLocalSubtree(node) {
|
|
|
659
711
|
walk(node, 0);
|
|
660
712
|
return blocks;
|
|
661
713
|
}
|
|
662
|
-
function buildNotionCreateSubtreeOperations(node, parentId, ambient) {
|
|
663
|
-
return buildNotionCreateOperations(flattenLocalSubtree(node), parentId, ambient.spaceId, ambient.userId, ambient.currentTime);
|
|
714
|
+
function buildNotionCreateSubtreeOperations(node, parentId, ambient, columnOrder) {
|
|
715
|
+
return buildNotionCreateOperations(flattenLocalSubtree(node), parentId, ambient.spaceId, ambient.userId, ambient.currentTime, undefined, columnOrder);
|
|
664
716
|
}
|
|
665
717
|
function positionRootCreateOperations(operations, parentId, spaceId, previousId) {
|
|
666
718
|
return operations.map((operation) => {
|
|
@@ -682,10 +734,10 @@ function deleteRemoteSubtreeOperations(node, parentId, spaceId) {
|
|
|
682
734
|
{ pointer: pointer(parentId, spaceId), path: ["content"], command: "listRemove", args: { id: node.id } },
|
|
683
735
|
];
|
|
684
736
|
}
|
|
685
|
-
function diffNotionChildLists(remoteParent, localChildren, ambient, summary, columnOrder) {
|
|
737
|
+
function diffNotionChildLists(remoteParent, localChildren, ambient, summary, columnOrder, localParent) {
|
|
686
738
|
const operations = [];
|
|
687
739
|
const remoteChildren = [...remoteParent.children];
|
|
688
|
-
const nextColumnOrder = remoteParent.block["type"] === "table" ?
|
|
740
|
+
const nextColumnOrder = remoteParent.block["type"] === "table" ? tableColumnOrder(remoteParent.block, localParent) : columnOrder;
|
|
689
741
|
const remoteHash = (index) => notionBlockContentHash(remoteChildren[index].block, nextColumnOrder);
|
|
690
742
|
const localHash = (index) => notionBlockContentHash(localChildren[index].block, nextColumnOrder);
|
|
691
743
|
let remoteIndex = 0;
|
|
@@ -695,7 +747,7 @@ function diffNotionChildLists(remoteParent, localChildren, ambient, summary, col
|
|
|
695
747
|
const remoteNode = remoteChildren[remoteIndex];
|
|
696
748
|
const localNode = localChildren[localIndex];
|
|
697
749
|
if (remoteHash(remoteIndex) === localHash(localIndex)) {
|
|
698
|
-
operations.push(...diffNotionChildLists(remoteNode, localNode.children, ambient, summary, nextColumnOrder));
|
|
750
|
+
operations.push(...diffNotionChildLists(remoteNode, localNode.children, ambient, summary, nextColumnOrder, localNode.block));
|
|
699
751
|
previousId = remoteNode.id;
|
|
700
752
|
remoteIndex += 1;
|
|
701
753
|
localIndex += 1;
|
|
@@ -712,7 +764,7 @@ function diffNotionChildLists(remoteParent, localChildren, ambient, summary, col
|
|
|
712
764
|
continue;
|
|
713
765
|
}
|
|
714
766
|
if (localIndex + 1 < localChildren.length && remoteHash(remoteIndex) === localHash(localIndex + 1)) {
|
|
715
|
-
const built = buildNotionCreateSubtreeOperations(localNode, remoteParent.id, ambient);
|
|
767
|
+
const built = buildNotionCreateSubtreeOperations(localNode, remoteParent.id, ambient, nextColumnOrder);
|
|
716
768
|
operations.push(...positionRootCreateOperations(built.operations, remoteParent.id, ambient.spaceId, previousId));
|
|
717
769
|
summary.inserted += localSubtreeSize(localNode);
|
|
718
770
|
previousId = built.topLevelIds[0];
|
|
@@ -726,8 +778,8 @@ function diffNotionChildLists(remoteParent, localChildren, ambient, summary, col
|
|
|
726
778
|
continue;
|
|
727
779
|
}
|
|
728
780
|
const before = operations.length;
|
|
729
|
-
operations.push(...emitUpdates(remoteNode.block, localNode.block, remoteNode.id, ambient.spaceId));
|
|
730
|
-
operations.push(...diffNotionChildLists(remoteNode, localNode.children, ambient, summary, nextColumnOrder));
|
|
781
|
+
operations.push(...emitUpdates(remoteNode.block, localNode.block, remoteNode.id, ambient.spaceId, nextColumnOrder));
|
|
782
|
+
operations.push(...diffNotionChildLists(remoteNode, localNode.children, ambient, summary, nextColumnOrder, localNode.block));
|
|
731
783
|
if (operations.length > before)
|
|
732
784
|
summary.updated += 1;
|
|
733
785
|
previousId = remoteNode.id;
|
|
@@ -736,7 +788,7 @@ function diffNotionChildLists(remoteParent, localChildren, ambient, summary, col
|
|
|
736
788
|
}
|
|
737
789
|
while (localIndex < localChildren.length) {
|
|
738
790
|
const localNode = localChildren[localIndex];
|
|
739
|
-
const built = buildNotionCreateSubtreeOperations(localNode, remoteParent.id, ambient);
|
|
791
|
+
const built = buildNotionCreateSubtreeOperations(localNode, remoteParent.id, ambient, nextColumnOrder);
|
|
740
792
|
operations.push(...positionRootCreateOperations(built.operations, remoteParent.id, ambient.spaceId, previousId ?? remoteChildren[remoteChildren.length - 1]?.id));
|
|
741
793
|
summary.inserted += localSubtreeSize(localNode);
|
|
742
794
|
previousId = built.topLevelIds[0];
|
|
@@ -770,21 +822,21 @@ function renderNode(tree, indent, parentType = "") {
|
|
|
770
822
|
}
|
|
771
823
|
if (type === "bulleted_list") {
|
|
772
824
|
const lines = title.split("\n");
|
|
773
|
-
return [`${prefix}- ${lines[0]}`, ...lines.slice(1).map((line) => `${prefix} ${line}`), ...tree.children.flatMap((child) => renderNode(child, indent + 1, type))];
|
|
825
|
+
return [`${prefix}- ${lines[0]}`, ...lines.slice(1).map((line) => `${prefix} ${escapeBlockMarkdownLine(line)}`), ...tree.children.flatMap((child) => renderNode(child, indent + 1, type))];
|
|
774
826
|
}
|
|
775
827
|
if (type === "numbered_list") {
|
|
776
828
|
const lines = title.split("\n");
|
|
777
|
-
return [`${prefix}1. ${lines[0]}`, ...lines.slice(1).map((line) => `${prefix} ${line}`), ...tree.children.flatMap((child) => renderNode(child, indent + 1, type))];
|
|
829
|
+
return [`${prefix}1. ${lines[0]}`, ...lines.slice(1).map((line) => `${prefix} ${escapeBlockMarkdownLine(line)}`), ...tree.children.flatMap((child) => renderNode(child, indent + 1, type))];
|
|
778
830
|
}
|
|
779
831
|
if (type === "to_do") {
|
|
780
832
|
const checked = richTextText(properties["checked"] ?? [["No"]]) === "Yes";
|
|
781
833
|
if (title === "")
|
|
782
834
|
return [`${prefix}:::to-do`, `${prefix}:::checked ${JSON.stringify(checked)}`, prefix, ...tree.children.flatMap((child) => renderNode(child, indent + 1, type)), `${prefix}:::`];
|
|
783
835
|
const lines = title.split("\n");
|
|
784
|
-
return [`${prefix}- [${checked ? "x" : " "}] ${lines[0]}`, ...lines.slice(1).map((line) => `${prefix} ${line}`), ...tree.children.flatMap((child) => renderNode(child, indent + 1, type))];
|
|
836
|
+
return [`${prefix}- [${checked ? "x" : " "}] ${lines[0]}`, ...lines.slice(1).map((line) => `${prefix} ${escapeBlockMarkdownLine(line)}`), ...tree.children.flatMap((child) => renderNode(child, indent + 1, type))];
|
|
785
837
|
}
|
|
786
838
|
if (type === "quote")
|
|
787
|
-
return [`${prefix}> ${
|
|
839
|
+
return [...title.split("\n").map((line) => `${prefix}> ${escapeBlockMarkdownLine(line)}`), ...tree.children.flatMap((child) => renderNode(child, indent + 1, type))];
|
|
788
840
|
if (type === "divider")
|
|
789
841
|
return [`${prefix}---`];
|
|
790
842
|
if (type === "code") {
|
|
@@ -823,7 +875,7 @@ function renderNode(tree, indent, parentType = "") {
|
|
|
823
875
|
return [`${prefix}:::text`, `${prefix}:::`];
|
|
824
876
|
if (["bulleted_list", "numbered_list", "to_do"].includes(parentType))
|
|
825
877
|
return [`${prefix}:::text`, ...title.split("\n").map((line) => `${prefix}${line}`), `${prefix}:::`];
|
|
826
|
-
return
|
|
878
|
+
return title.split("\n").map((line) => `${prefix}${escapeBlockMarkdownLine(line)}`);
|
|
827
879
|
}
|
|
828
880
|
export function renderNotionTreeToMarkdown(tree, mentions) {
|
|
829
881
|
const title = renderRichText(object(tree.block["properties"])["title"]);
|
|
@@ -851,9 +903,9 @@ async function fetchTree(runtime, url, source) {
|
|
|
851
903
|
await runtime.http.request(url, { headers: { cookie } });
|
|
852
904
|
const spaces = await notionPost(runtime, "getSpaces", cookie, {}, {});
|
|
853
905
|
const spaceView = object(object(spaces[userId])["space_view"]);
|
|
854
|
-
const
|
|
906
|
+
const initialSpaceId = object(spaceView[Object.keys(spaceView)[0]])["spaceId"];
|
|
855
907
|
const pageId = formatBlockId(source.identifier);
|
|
856
|
-
|
|
908
|
+
let headers = { "x-notion-active-user-header": userId, "x-notion-space-id": initialSpaceId, referer: url, ...(csrf === undefined ? {} : { "x-csrf-token": csrf }) };
|
|
857
909
|
const blocks = new Map();
|
|
858
910
|
let stack = [];
|
|
859
911
|
let chunkNumber = 0;
|
|
@@ -865,6 +917,8 @@ async function fetchTree(runtime, url, source) {
|
|
|
865
917
|
stack = cursors.length === 0 ? [] : cursors[0]["stack"];
|
|
866
918
|
chunkNumber += 1;
|
|
867
919
|
} while (stack.length > 0);
|
|
920
|
+
const spaceId = blocks.get(pageId)["space_id"];
|
|
921
|
+
headers = { ...headers, "x-notion-space-id": spaceId };
|
|
868
922
|
while (true) {
|
|
869
923
|
const missing = new Set();
|
|
870
924
|
const pending = [pageId];
|
|
@@ -918,6 +972,8 @@ export async function uploadNotionDocument(runtime, markdown, _markdownPath) {
|
|
|
918
972
|
const csrf = cookies.find((value) => value.name === "csrf")?.value;
|
|
919
973
|
const spaces = await notionPost(runtime, "getSpaces", cookie, {}, {});
|
|
920
974
|
const spaceView = object(object(spaces[userId])["space_view"]);
|
|
975
|
+
if (Object.keys(spaceView).length !== 1)
|
|
976
|
+
throw new Error("Notion upload requires an explicit target workspace.");
|
|
921
977
|
const spaceId = object(spaceView[Object.keys(spaceView)[0]])["spaceId"];
|
|
922
978
|
const pageId = randomUUID();
|
|
923
979
|
const compactPageId = pageId.replaceAll("-", "");
|
|
@@ -964,8 +1020,7 @@ function splitTitle(markdown) {
|
|
|
964
1020
|
return { title: first.replace(/^#+\s+/, "").trim(), body: lines.slice(1).join("\n") };
|
|
965
1021
|
return { title: "", body: markdown };
|
|
966
1022
|
}
|
|
967
|
-
export async function synchronizeNotionDocument(runtime, url, base, markdown, _markdownPath) {
|
|
968
|
-
const source = { service: "notion", identifier: /([a-f0-9]{32})/.exec(url)[1], type: "document" };
|
|
1023
|
+
export async function synchronizeNotionDocument(runtime, url, source, base, markdown, _markdownPath) {
|
|
969
1024
|
const remote = await fetchTree(runtime, url, source);
|
|
970
1025
|
const baseObject = object(base);
|
|
971
1026
|
const mentions = baseUserMentions(baseObject);
|
|
@@ -980,10 +1035,6 @@ export async function synchronizeNotionDocument(runtime, url, base, markdown, _m
|
|
|
980
1035
|
const remoteTitleChanged = baseSplit.title !== currentSplit.title;
|
|
981
1036
|
const localBodyChanged = baseSplit.body !== split.body;
|
|
982
1037
|
const remoteBodyChanged = baseSplit.body !== currentSplit.body;
|
|
983
|
-
if (localTitleChanged && remoteTitleChanged && split.title !== currentSplit.title)
|
|
984
|
-
throw new Error("Markdown and Notion changed since last sync");
|
|
985
|
-
if (localBodyChanged && remoteBodyChanged && split.body !== currentSplit.body)
|
|
986
|
-
throw new Error("Markdown and Notion changed since last sync");
|
|
987
1038
|
if ((localTitleChanged || localBodyChanged) && (remoteTitleChanged || remoteBodyChanged)) {
|
|
988
1039
|
split = { title: localTitleChanged ? split.title : currentSplit.title, body: localBodyChanged ? split.body : currentSplit.body };
|
|
989
1040
|
fieldMerged = true;
|