@graview/core 0.1.56 → 0.1.58

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/README.md +12 -4
  2. package/dist/capabilities.js +1 -1
  3. package/dist/capabilities.js.map +1 -1
  4. package/dist/cli/document-schema.js +3 -3
  5. package/dist/cli/document-schema.js.map +1 -1
  6. package/dist/document/blocks.d.ts +4 -2
  7. package/dist/document/blocks.d.ts.map +1 -1
  8. package/dist/document/blocks.js +7 -4
  9. package/dist/document/blocks.js.map +1 -1
  10. package/dist/document/compile.d.ts.map +1 -1
  11. package/dist/document/compile.js +4 -0
  12. package/dist/document/compile.js.map +1 -1
  13. package/dist/document/compiled.d.ts +2 -0
  14. package/dist/document/compiled.d.ts.map +1 -1
  15. package/dist/document/compiled.js +21 -1
  16. package/dist/document/compiled.js.map +1 -1
  17. package/dist/document/connection-findings.d.ts.map +1 -1
  18. package/dist/document/connection-findings.js +189 -25
  19. package/dist/document/connection-findings.js.map +1 -1
  20. package/dist/document/connection-spec.d.ts +42 -2
  21. package/dist/document/connection-spec.d.ts.map +1 -1
  22. package/dist/document/connection-spec.js +64 -19
  23. package/dist/document/connection-spec.js.map +1 -1
  24. package/dist/document/describe-place.d.ts +2 -0
  25. package/dist/document/describe-place.d.ts.map +1 -1
  26. package/dist/document/describe-place.js +8 -1
  27. package/dist/document/describe-place.js.map +1 -1
  28. package/dist/document/described.d.ts +2 -1
  29. package/dist/document/described.d.ts.map +1 -1
  30. package/dist/document/edit.d.ts +1 -1
  31. package/dist/document/edit.d.ts.map +1 -1
  32. package/dist/document/edit.js +101 -4
  33. package/dist/document/edit.js.map +1 -1
  34. package/dist/document/expr/evaluate.d.ts +1 -1
  35. package/dist/document/expr/evaluate.d.ts.map +1 -1
  36. package/dist/document/expr/evaluate.js +20 -1
  37. package/dist/document/expr/evaluate.js.map +1 -1
  38. package/dist/document/kept-in-step.d.ts +7 -0
  39. package/dist/document/kept-in-step.d.ts.map +1 -0
  40. package/dist/document/kept-in-step.js +28 -0
  41. package/dist/document/kept-in-step.js.map +1 -0
  42. package/dist/document/rule-line.d.ts.map +1 -1
  43. package/dist/document/rule-line.js +2 -0
  44. package/dist/document/rule-line.js.map +1 -1
  45. package/dist/document/schema.d.ts +33 -5
  46. package/dist/document/schema.d.ts.map +1 -1
  47. package/dist/document/schema.js +13 -1
  48. package/dist/document/schema.js.map +1 -1
  49. package/dist/document/to-document.d.ts.map +1 -1
  50. package/dist/document/to-document.js +4 -2
  51. package/dist/document/to-document.js.map +1 -1
  52. package/dist/document/views.d.ts +6 -1
  53. package/dist/document/views.d.ts.map +1 -1
  54. package/dist/document/views.js +16 -5
  55. package/dist/document/views.js.map +1 -1
  56. package/dist/document.schema.json +281 -98
  57. package/dist/mutations/derive-edits.d.ts +4 -2
  58. package/dist/mutations/derive-edits.d.ts.map +1 -1
  59. package/dist/mutations/derive-edits.js +13 -4
  60. package/dist/mutations/derive-edits.js.map +1 -1
  61. package/dist/scaffold/from-template.d.ts.map +1 -1
  62. package/dist/scaffold/from-template.js +2 -1
  63. package/dist/scaffold/from-template.js.map +1 -1
  64. package/dist/schema/field-words.d.ts +10 -0
  65. package/dist/schema/field-words.d.ts.map +1 -1
  66. package/dist/schema/field-words.js +26 -10
  67. package/dist/schema/field-words.js.map +1 -1
  68. package/dist/schema/reading.d.ts.map +1 -1
  69. package/dist/schema/reading.js +5 -2
  70. package/dist/schema/reading.js.map +1 -1
  71. package/dist/schema/types.d.ts +32 -0
  72. package/dist/schema/types.d.ts.map +1 -1
  73. package/dist/sync/connection-filter.d.ts +2 -2
  74. package/dist/sync/connection-filter.d.ts.map +1 -1
  75. package/dist/sync/connection-filter.js.map +1 -1
  76. package/dist/sync/connection.d.ts +72 -28
  77. package/dist/sync/connection.d.ts.map +1 -1
  78. package/dist/sync/connection.js +255 -43
  79. package/dist/sync/connection.js.map +1 -1
  80. package/dist/sync/creating-act.d.ts +20 -0
  81. package/dist/sync/creating-act.d.ts.map +1 -0
  82. package/dist/sync/creating-act.js +29 -0
  83. package/dist/sync/creating-act.js.map +1 -0
  84. package/dist/sync/engine.d.ts +83 -1
  85. package/dist/sync/engine.d.ts.map +1 -1
  86. package/dist/sync/engine.js +269 -32
  87. package/dist/sync/engine.js.map +1 -1
  88. package/dist/sync/google-calendar.d.ts +3 -0
  89. package/dist/sync/google-calendar.d.ts.map +1 -1
  90. package/dist/sync/index.d.ts +10 -4
  91. package/dist/sync/index.d.ts.map +1 -1
  92. package/dist/sync/index.js +6 -2
  93. package/dist/sync/index.js.map +1 -1
  94. package/dist/sync/notion-stub.d.ts +81 -0
  95. package/dist/sync/notion-stub.d.ts.map +1 -0
  96. package/dist/sync/notion-stub.js +467 -0
  97. package/dist/sync/notion-stub.js.map +1 -0
  98. package/dist/sync/notion-types.d.ts +23 -0
  99. package/dist/sync/notion-types.d.ts.map +1 -0
  100. package/dist/sync/notion-types.js +49 -0
  101. package/dist/sync/notion-types.js.map +1 -0
  102. package/dist/sync/notion.d.ts +98 -0
  103. package/dist/sync/notion.d.ts.map +1 -0
  104. package/dist/sync/notion.js +477 -0
  105. package/dist/sync/notion.js.map +1 -0
  106. package/dist/sync/types.d.ts +38 -0
  107. package/dist/sync/types.d.ts.map +1 -1
  108. package/dist/sync/types.js.map +1 -1
  109. package/dist/version.d.ts +1 -1
  110. package/dist/version.js +1 -1
  111. package/package.json +1 -1
@@ -0,0 +1,98 @@
1
+ import type { Fetcher } from "./google-calendar.js";
2
+ import type { RemoteSystem } from "./types.js";
3
+ /**
4
+ * A Notion database, as a transport.
5
+ *
6
+ * One data source of a database is one resource (`pages`), and each of its
7
+ * pages one record. A database holds one data source, or several (since
8
+ * Notion's 2025-09-03 API, a database may gather several tables under one
9
+ * name); a database of one is read through it, and one of several is named
10
+ * by `source`, its name or its id, or refused with a sentence naming them.
11
+ * Everything Notion-specific is here — property objects, `last_edited_time`,
12
+ * `has_more`, `archived` — and the engine sees plain values keyed by the
13
+ * names its mapping uses:
14
+ *
15
+ * - A property is named by its name in Notion, matched as written and then
16
+ * ignoring case, spaces and punctuation ("dueDate" finds "Due date"); a
17
+ * `titleRef` that matches no property is the database's title. A name
18
+ * that finds no property, or one of a type its field cannot hold, is left
19
+ * out and said once (`say`).
20
+ * - Values are plain: words for a title, rich text, select, status, URL,
21
+ * email and phone; a number; `true`/`false`; a list of names for a
22
+ * multi-select and for people (read only — never written); a date's start,
23
+ * a day or an instant as Notion has it. An empty property is `null`.
24
+ * - A PULL asks for the pages edited since the last one it saw, oldest
25
+ * first, following `next_cursor` to the end; without a cursor, and every
26
+ * `sweepEvery`, it reads the whole database, and a page it knew (`known`)
27
+ * that is no longer there — archived, in the trash, moved out — is gone.
28
+ * - A version is the page's `last_edited_time` (Notion keeps it to the
29
+ * minute) with a hash of its values, so our own write coming back is an
30
+ * echo and somebody's edit within the same minute is still news.
31
+ * - A PUSH makes a page in the database, sets the properties of one, or
32
+ * archives one. Words go as plain text, cut into Notion's 2000-character
33
+ * pieces.
34
+ * - A RELATION property is a kind's relation (`refs` naming it with the
35
+ * type `NOTION_EDGE`): its value is the ids of the pages it reaches, every
36
+ * one of them — Notion lists 25 on a page and the rest through the
37
+ * property's own endpoint, which is followed — and it is written whole.
38
+ * - Notion asking us to slow down (429) is waited out as its `Retry-After`
39
+ * says, within a bound; a refused secret (401) and a database the
40
+ * integration cannot see (404) are said as sentences that say what to do.
41
+ */
42
+ export declare const NOTION_API = "https://api.notion.com/v1";
43
+ export declare const NOTION_VERSION = "2025-09-03";
44
+ export interface NotionOptions {
45
+ /** The database's id: the 32 characters in its link, before `?v=`. */
46
+ readonly databaseId: string;
47
+ /** The data source to keep in step, by its name or id, when the database holds several. */
48
+ readonly source?: string;
49
+ /** The internal integration's secret, asked before every request. */
50
+ token(): Promise<string> | string;
51
+ /** What the secret is called where it is kept (`NOTION_TOKEN`), for the sentence a refusal says. Never its value. */
52
+ readonly secretName?: string;
53
+ readonly fetch?: Fetcher;
54
+ readonly baseUrl?: string;
55
+ /** Pages per request of a pull (Notion allows up to 100). Every page is followed. */
56
+ readonly pageSize?: number;
57
+ /**
58
+ * The names the mapping uses, each with the type of the field it lands
59
+ * in (absent when any type is welcome), or `NOTION_EDGE` for a relation
60
+ * property kept as a kind's relation. Absent: every property Notion
61
+ * keeps in step, by its own name.
62
+ */
63
+ readonly refs?: Readonly<Record<string, string | undefined>>;
64
+ /** Names of `refs` that may find no property without its being said (a relation matched by name). */
65
+ readonly quiet?: readonly string[];
66
+ /** A name that, finding no property of its own, is the database's title. */
67
+ readonly titleRef?: string;
68
+ /** The pages this sync has linked, by Notion's id, so a full read can tell which are gone. */
69
+ known?(): readonly string[];
70
+ /** How often a pull reads the whole database to see what was archived, in ms (10 minutes by default). */
71
+ readonly sweepEvery?: number;
72
+ /** The longest a run waits out Notion's rate limit, in ms (60 seconds by default). */
73
+ readonly maxWait?: number;
74
+ /** A note said once: a name that finds no property, a property left alone. */
75
+ say?(line: string): void;
76
+ now?(): number;
77
+ sleep?(ms: number): Promise<void>;
78
+ }
79
+ /** What Notion answered, when it was not a yes. */
80
+ export declare class NotionError extends Error {
81
+ readonly status: number;
82
+ readonly code?: string | undefined;
83
+ constructor(message: string, status: number, code?: string | undefined);
84
+ }
85
+ type Json = Record<string, unknown>;
86
+ /** The same id however it was written: lower case, no hyphens. */
87
+ export declare const notionKey: (id: string) => string;
88
+ /** A property's value, plain. */
89
+ export declare function notionValue(property: Json): unknown;
90
+ /** Words as Notion's rich text: plain, in pieces of at most 2000 characters, a pair of surrogates never split. */
91
+ export declare function notionText(value: unknown): Json[];
92
+ /** A plain value as the property object Notion takes, for a property of `type`. */
93
+ export declare function notionProperty(type: string, value: unknown): Json;
94
+ /** A page's version: when it was last edited, and what it holds. */
95
+ export declare function notionVersion(page: Json): string;
96
+ export declare function notion(options: NotionOptions): RemoteSystem;
97
+ export {};
98
+ //# sourceMappingURL=notion.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notion.d.ts","sourceRoot":"","sources":["../../src/sync/notion.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD,OAAO,KAAK,EAA2B,YAAY,EAAe,MAAM,YAAY,CAAC;AAErF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAEH,eAAO,MAAM,UAAU,8BAA8B,CAAC;AACtD,eAAO,MAAM,cAAc,eAAe,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,2FAA2F;IAC3F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAClC,qHAAqH;IACrH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,qFAAqF;IACrF,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC7D,qGAAqG;IACrG,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,8FAA8F;IAC9F,KAAK,CAAC,IAAI,SAAS,MAAM,EAAE,CAAC;IAC5B,yGAAyG;IACzG,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,sFAAsF;IACtF,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,8EAA8E;IAC9E,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,GAAG,CAAC,IAAI,MAAM,CAAC;IACf,KAAK,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAED,mDAAmD;AACnD,qBAAa,WAAY,SAAQ,KAAK;IAGlC,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;gBAFtB,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,YAAA;CAKzB;AAED,KAAK,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAkBpC,kEAAkE;AAClE,eAAO,MAAM,SAAS,GAAI,IAAI,MAAM,WAAuC,CAAC;AAI5E,iCAAiC;AACjC,wBAAgB,WAAW,CAAC,QAAQ,EAAE,IAAI,GAAG,OAAO,CAqCnD;AAED,kHAAkH;AAClH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,EAAE,CAcjD;AAED,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CA0BjE;AAuBD,oEAAoE;AACpE,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEhD;AAgBD,wBAAgB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,YAAY,CA8R3D"}
@@ -0,0 +1,477 @@
1
+ import { NOTION_EDGE, NOTION_FITS, NOTION_LEFT_ALONE, NOTION_READ_ONLY, notionFits } from "./notion-types.js";
2
+ /**
3
+ * A Notion database, as a transport.
4
+ *
5
+ * One data source of a database is one resource (`pages`), and each of its
6
+ * pages one record. A database holds one data source, or several (since
7
+ * Notion's 2025-09-03 API, a database may gather several tables under one
8
+ * name); a database of one is read through it, and one of several is named
9
+ * by `source`, its name or its id, or refused with a sentence naming them.
10
+ * Everything Notion-specific is here — property objects, `last_edited_time`,
11
+ * `has_more`, `archived` — and the engine sees plain values keyed by the
12
+ * names its mapping uses:
13
+ *
14
+ * - A property is named by its name in Notion, matched as written and then
15
+ * ignoring case, spaces and punctuation ("dueDate" finds "Due date"); a
16
+ * `titleRef` that matches no property is the database's title. A name
17
+ * that finds no property, or one of a type its field cannot hold, is left
18
+ * out and said once (`say`).
19
+ * - Values are plain: words for a title, rich text, select, status, URL,
20
+ * email and phone; a number; `true`/`false`; a list of names for a
21
+ * multi-select and for people (read only — never written); a date's start,
22
+ * a day or an instant as Notion has it. An empty property is `null`.
23
+ * - A PULL asks for the pages edited since the last one it saw, oldest
24
+ * first, following `next_cursor` to the end; without a cursor, and every
25
+ * `sweepEvery`, it reads the whole database, and a page it knew (`known`)
26
+ * that is no longer there — archived, in the trash, moved out — is gone.
27
+ * - A version is the page's `last_edited_time` (Notion keeps it to the
28
+ * minute) with a hash of its values, so our own write coming back is an
29
+ * echo and somebody's edit within the same minute is still news.
30
+ * - A PUSH makes a page in the database, sets the properties of one, or
31
+ * archives one. Words go as plain text, cut into Notion's 2000-character
32
+ * pieces.
33
+ * - A RELATION property is a kind's relation (`refs` naming it with the
34
+ * type `NOTION_EDGE`): its value is the ids of the pages it reaches, every
35
+ * one of them — Notion lists 25 on a page and the rest through the
36
+ * property's own endpoint, which is followed — and it is written whole.
37
+ * - Notion asking us to slow down (429) is waited out as its `Retry-After`
38
+ * says, within a bound; a refused secret (401) and a database the
39
+ * integration cannot see (404) are said as sentences that say what to do.
40
+ */
41
+ export const NOTION_API = "https://api.notion.com/v1";
42
+ export const NOTION_VERSION = "2025-09-03";
43
+ /** What Notion answered, when it was not a yes. */
44
+ export class NotionError extends Error {
45
+ status;
46
+ code;
47
+ constructor(message, status, code) {
48
+ super(message);
49
+ this.status = status;
50
+ this.code = code;
51
+ this.name = "NotionError";
52
+ }
53
+ }
54
+ /** A value written as the option the property already has, where one is the same words ("in-progress" is "In progress"). */
55
+ function asOption(property, value) {
56
+ const one = (word) => (typeof word === "string" ? (property.options.find((option) => option === word) ?? property.options.find((option) => loose(option) === loose(word)) ?? word) : word);
57
+ return Array.isArray(value) ? value.map(one) : one(value);
58
+ }
59
+ const MOST_TEXT = 2000;
60
+ const MOST_PIECES = 100;
61
+ const DEFAULT_SWEEP = 10 * 60 * 1000;
62
+ /** The same id however it was written: lower case, no hyphens. */
63
+ export const notionKey = (id) => id.replace(/-/g, "").toLowerCase();
64
+ /** A name compared loosely: "Due date", "dueDate" and "due_date" are one. */
65
+ const loose = (name) => name.toLowerCase().replace(/[^a-z0-9]/g, "");
66
+ /** A property's value, plain. */
67
+ export function notionValue(property) {
68
+ const type = String(property["type"] ?? "");
69
+ const raw = property[type];
70
+ switch (type) {
71
+ case "title":
72
+ case "rich_text": {
73
+ const text = (raw ?? []).map((part) => String(part["plain_text"] ?? part["text"]?.["content"] ?? "")).join("");
74
+ return text === "" ? null : text;
75
+ }
76
+ case "number":
77
+ return typeof raw === "number" ? raw : null;
78
+ case "select":
79
+ case "status":
80
+ return raw && typeof raw === "object" ? (raw["name"] ?? null) : null;
81
+ case "multi_select": {
82
+ const names = (raw ?? []).map((option) => String(option["name"]));
83
+ return names.length > 0 ? names : null;
84
+ }
85
+ case "date":
86
+ return raw && typeof raw === "object" ? (raw["start"] ?? null) : null;
87
+ case "checkbox":
88
+ return raw === true;
89
+ case "url":
90
+ case "email":
91
+ case "phone_number":
92
+ return typeof raw === "string" && raw !== "" ? raw : null;
93
+ case "people": {
94
+ const names = (raw ?? []).map((person) => String(person["name"] ?? person["id"]));
95
+ return names.length > 0 ? names : null;
96
+ }
97
+ case "relation": {
98
+ const ids = (raw ?? []).map((page) => String(page["id"]));
99
+ return ids.length > 0 ? ids : null;
100
+ }
101
+ default:
102
+ return undefined;
103
+ }
104
+ }
105
+ /** Words as Notion's rich text: plain, in pieces of at most 2000 characters, a pair of surrogates never split. */
106
+ export function notionText(value) {
107
+ const text = value === null || value === undefined ? "" : Array.isArray(value) ? value.join(", ") : String(value);
108
+ const pieces = [];
109
+ for (let at = 0; at < text.length;) {
110
+ let end = Math.min(at + MOST_TEXT, text.length);
111
+ const last = text.charCodeAt(end - 1);
112
+ if (end < text.length && last >= 0xd800 && last <= 0xdbff)
113
+ end -= 1;
114
+ pieces.push({ type: "text", text: { content: text.slice(at, end) } });
115
+ at = end;
116
+ }
117
+ if (pieces.length > MOST_PIECES) {
118
+ throw new Error(`notion: ${text.length} characters is more than a Notion property holds (${MOST_TEXT * MOST_PIECES})`);
119
+ }
120
+ return pieces;
121
+ }
122
+ /** A plain value as the property object Notion takes, for a property of `type`. */
123
+ export function notionProperty(type, value) {
124
+ const empty = value === null || value === undefined || value === "";
125
+ switch (type) {
126
+ case "title":
127
+ case "rich_text":
128
+ return { [type]: notionText(value) };
129
+ case "number":
130
+ return { number: empty ? null : Number(value) };
131
+ case "select":
132
+ case "status":
133
+ return { [type]: empty ? null : { name: String(value) } };
134
+ case "multi_select":
135
+ return { multi_select: empty ? [] : (Array.isArray(value) ? value : [value]).map((name) => ({ name: String(name) })) };
136
+ case "date":
137
+ return { date: empty ? null : { start: String(value) } };
138
+ case "checkbox":
139
+ return { checkbox: value === true };
140
+ case "url":
141
+ case "email":
142
+ case "phone_number":
143
+ return { [type]: empty ? null : String(value) };
144
+ case "relation":
145
+ return { relation: empty ? [] : (Array.isArray(value) ? value : [value]).map((id) => ({ id: String(id) })) };
146
+ default:
147
+ throw new Error(`notion: a ${type} property is not written from here`);
148
+ }
149
+ }
150
+ /** A short, stable hash of a page's values: what makes an edit in the same minute as ours news. */
151
+ function hashOf(values) {
152
+ const text = JSON.stringify(Object.keys(values).sort().map((key) => [key, values[key] ?? null]));
153
+ let hash = 0x811c9dc5;
154
+ for (let at = 0; at < text.length; at++) {
155
+ hash ^= text.charCodeAt(at);
156
+ hash = Math.imul(hash, 0x01000193) >>> 0;
157
+ }
158
+ return hash.toString(16).padStart(8, "0");
159
+ }
160
+ /** Every value Notion keeps in step on a page, by property name. */
161
+ function valuesOf(page) {
162
+ const out = {};
163
+ for (const [name, property] of Object.entries(page["properties"] ?? {})) {
164
+ if (!NOTION_FITS[String(property["type"])] && property["type"] !== "relation")
165
+ continue;
166
+ out[name] = notionValue(property);
167
+ }
168
+ return out;
169
+ }
170
+ /** A page's version: when it was last edited, and what it holds. */
171
+ export function notionVersion(page) {
172
+ return `${String(page["last_edited_time"] ?? "")}~${hashOf(valuesOf(page))}`;
173
+ }
174
+ const readCursor = (cursor) => {
175
+ if (!cursor)
176
+ return undefined;
177
+ try {
178
+ const parsed = JSON.parse(cursor);
179
+ return typeof parsed.swept === "number" ? { swept: parsed.swept, ...(typeof parsed.since === "string" ? { since: parsed.since } : {}) } : undefined;
180
+ }
181
+ catch {
182
+ return undefined;
183
+ }
184
+ };
185
+ export function notion(options) {
186
+ const doFetch = options.fetch ?? globalThis.fetch;
187
+ const base = options.baseUrl ?? NOTION_API;
188
+ const databaseId = options.databaseId;
189
+ const secret = options.secretName ?? "the integration's secret";
190
+ const now = options.now ?? (() => Date.now());
191
+ const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
192
+ const maxWait = options.maxWait ?? 60_000;
193
+ const said = new Set();
194
+ const note = (line) => {
195
+ if (said.has(line))
196
+ return;
197
+ said.add(line);
198
+ options.say?.(line);
199
+ };
200
+ /** One request, Notion's rate limit waited out; anything but a yes thrown as a `NotionError`. */
201
+ const call = async (method, path, body) => {
202
+ let waited = 0;
203
+ for (;;) {
204
+ const response = await doFetch(`${base}${path}`, {
205
+ method,
206
+ headers: {
207
+ authorization: `Bearer ${await options.token()}`,
208
+ "notion-version": NOTION_VERSION,
209
+ "content-type": "application/json",
210
+ },
211
+ ...(body ? { body: JSON.stringify(body) } : {}),
212
+ });
213
+ if (response.status === 429) {
214
+ const after = Number(response.headers?.get("retry-after") ?? "");
215
+ const wait = Math.min(Number.isFinite(after) && after > 0 ? after * 1000 : 1000, maxWait);
216
+ if (waited + wait > maxWait)
217
+ throw new NotionError(`notion: Notion is still limiting the rate after ${Math.round(waited / 1000)} s of waiting (HTTP 429); the next pass tries again`, 429, "rate_limited");
218
+ waited += wait;
219
+ await sleep(wait);
220
+ continue;
221
+ }
222
+ const answer = (await response.json().catch(() => ({})));
223
+ if (response.ok)
224
+ return answer;
225
+ const code = typeof answer["code"] === "string" ? answer["code"] : undefined;
226
+ const said = typeof answer["message"] === "string" ? answer["message"] : "";
227
+ if (response.status === 401) {
228
+ throw new NotionError(`notion: Notion refused ${secret} (HTTP 401): it is not an integration secret Notion takes — copy the Internal Integration Secret from the integration's page again`, 401, code);
229
+ }
230
+ if (response.status === 403) {
231
+ throw new NotionError(`notion: the integration may not do this (HTTP 403): give it the capabilities to read, update and insert content`, 403, code);
232
+ }
233
+ throw new NotionError(`notion: HTTP ${response.status}${code ? ` ${code}` : ""}${said ? `: ${said}` : ""}`, response.status, code);
234
+ }
235
+ };
236
+ /** The data source this connection keeps in step: the database's only one, or the one `source` names. */
237
+ let sourceId;
238
+ const dataSource = async () => {
239
+ if (sourceId)
240
+ return sourceId;
241
+ let answer;
242
+ try {
243
+ answer = await call("GET", `/databases/${encodeURIComponent(databaseId)}`);
244
+ }
245
+ catch (error) {
246
+ if (error instanceof NotionError && error.status === 404) {
247
+ throw new NotionError(`notion: the integration cannot see a database ${databaseId} (HTTP 404): share the database with the integration — in Notion, the database's ••• menu → Connections → add it`, 404, error.code);
248
+ }
249
+ if (error instanceof NotionError && error.status === 400) {
250
+ throw new NotionError(`notion: ${databaseId} is not a database id Notion takes (HTTP 400) — the id is the 32 characters in the database's link, before ?v=${error.message.replace(/^notion: HTTP 400[^:]*/, "")}`, 400, error.code);
251
+ }
252
+ throw error;
253
+ }
254
+ const sources = (answer["data_sources"] ?? []).map((one) => ({ id: String(one["id"]), name: String(one["name"] ?? "") }));
255
+ const title = (answer["title"] ?? []).map((part) => String(part["plain_text"] ?? "")).join("") || databaseId;
256
+ const named = options.source;
257
+ const chosen = named
258
+ ? (sources.find((one) => notionKey(one.id) === notionKey(named)) ?? sources.find((one) => one.name === named) ?? sources.find((one) => loose(one.name) === loose(named)))
259
+ : sources.length === 1
260
+ ? sources[0]
261
+ : undefined;
262
+ if (!chosen) {
263
+ const list = sources.map((one) => one.name || one.id).join(", ");
264
+ throw new NotionError(named
265
+ ? `notion: the database ${title} has no data source ${named}; it holds ${list || "none"}`
266
+ : `notion: the database ${title} holds ${sources.length} data sources — ${list} — so the connection says which with source`, 400, "validation_error");
267
+ }
268
+ sourceId = chosen.id;
269
+ return chosen.id;
270
+ };
271
+ /** The data source's properties, by name — and a sentence when the integration cannot see it. */
272
+ let schema;
273
+ const database = async () => {
274
+ const answer = await call("GET", `/data_sources/${encodeURIComponent(await dataSource())}`);
275
+ const properties = new Map();
276
+ for (const [name, property] of Object.entries(answer["properties"] ?? {})) {
277
+ const type = String(property["type"]);
278
+ const options = property[type]?.["options"] ?? [];
279
+ properties.set(name, { name, type, options: options.map((option) => String(option["name"])) });
280
+ }
281
+ schema = properties;
282
+ return properties;
283
+ };
284
+ /** The mapping's names, each to the property it finds: by name, loosely, and the title for `titleRef`. */
285
+ const resolve = (properties) => {
286
+ const found = resolveRefs(properties);
287
+ // What is kept in step by nothing, said once: a formula, a rollup, a relation no relation here holds.
288
+ const held = new Set([...found.values()].map((property) => property.name));
289
+ const alone = [...properties.values()].filter((property) => !NOTION_FITS[property.type] && !held.has(property.name));
290
+ if (alone.length > 0) {
291
+ note(`left alone in Notion: ${alone.map((property) => `${property.name} (${property.type}${NOTION_LEFT_ALONE[property.type] ? `: ${NOTION_LEFT_ALONE[property.type]}` : ""})`).join(", ")}`);
292
+ }
293
+ return found;
294
+ };
295
+ const resolveRefs = (properties) => {
296
+ const found = new Map();
297
+ if (!options.refs) {
298
+ for (const property of properties.values())
299
+ if (NOTION_FITS[property.type])
300
+ found.set(property.name, property);
301
+ return found;
302
+ }
303
+ const byLoose = new Map([...properties.values()].map((property) => [loose(property.name), property]));
304
+ const title = [...properties.values()].find((property) => property.type === "title");
305
+ const missing = [];
306
+ for (const [ref, fieldType] of Object.entries(options.refs)) {
307
+ const property = properties.get(ref) ?? byLoose.get(loose(ref)) ?? (ref === options.titleRef ? title : undefined);
308
+ if (!property) {
309
+ if (!options.quiet?.includes(ref))
310
+ missing.push(ref);
311
+ continue;
312
+ }
313
+ if (fieldType === NOTION_EDGE || property.type === "relation") {
314
+ if (fieldType === NOTION_EDGE && property.type === "relation")
315
+ found.set(ref, property);
316
+ else if (fieldType === NOTION_EDGE)
317
+ note(`${ref}: the property ${property.name} is a ${property.type} property, and a relation holds only a relation property, so it is left out`);
318
+ else
319
+ note(`${ref}: the property ${property.name} is a relation, which a relation of the kind holds and a field does not, so it is left out`);
320
+ continue;
321
+ }
322
+ if (!NOTION_FITS[property.type]) {
323
+ note(`${ref}: the property ${property.name} is a ${property.type} property, which is not kept in step, so it is left out`);
324
+ continue;
325
+ }
326
+ if (fieldType && !notionFits(property.type, fieldType)) {
327
+ note(`${ref}: the property ${property.name} is a ${property.type} property, and a ${fieldType} field cannot hold it, so it is left out`);
328
+ continue;
329
+ }
330
+ found.set(ref, property);
331
+ }
332
+ if (missing.length > 0)
333
+ note(`no property in the database for ${missing.join(", ")}, so ${missing.length === 1 ? "it is" : "they are"} not kept in step`);
334
+ return found;
335
+ };
336
+ const fieldsOf = async (page, resolved) => {
337
+ const properties = page["properties"] ?? {};
338
+ const out = {};
339
+ for (const [ref, property] of resolved) {
340
+ const value = properties[property.name];
341
+ if (!value)
342
+ continue;
343
+ // Notion lists a relation's first 25 pages on the page; the rest are read through the property's own endpoint.
344
+ out[ref] = value["type"] === "relation" && value["has_more"] === true ? await relationOf(String(page["id"]), String(value["id"])) : notionValue(value);
345
+ }
346
+ return out;
347
+ };
348
+ /** Every page a relation property of a page reaches, following the property item endpoint to the end. */
349
+ const relationOf = async (pageId, propertyId) => {
350
+ const ids = [];
351
+ let start;
352
+ for (;;) {
353
+ const answer = await call("GET", `/pages/${encodeURIComponent(pageId)}/properties/${encodeURIComponent(propertyId)}?page_size=100${start ? `&start_cursor=${encodeURIComponent(start)}` : ""}`);
354
+ for (const item of answer["results"] ?? []) {
355
+ const id = item["relation"]?.["id"];
356
+ if (typeof id === "string")
357
+ ids.push(id);
358
+ }
359
+ if (answer["has_more"] === true && typeof answer["next_cursor"] === "string") {
360
+ start = answer["next_cursor"];
361
+ continue;
362
+ }
363
+ return ids.length > 0 ? ids : null;
364
+ }
365
+ };
366
+ /** Every page of one query: edited on or after `since`, oldest first; without it, the whole database. */
367
+ const query = async (since) => {
368
+ const pages = [];
369
+ let start;
370
+ for (;;) {
371
+ const answer = await call("POST", `/data_sources/${encodeURIComponent(await dataSource())}/query`, {
372
+ page_size: options.pageSize ?? 100,
373
+ sorts: [{ timestamp: "last_edited_time", direction: "ascending" }],
374
+ ...(since ? { filter: { timestamp: "last_edited_time", last_edited_time: { on_or_after: since } } } : {}),
375
+ ...(start ? { start_cursor: start } : {}),
376
+ });
377
+ pages.push(...(answer["results"] ?? []));
378
+ if (answer["has_more"] === true && typeof answer["next_cursor"] === "string") {
379
+ start = answer["next_cursor"];
380
+ continue;
381
+ }
382
+ return pages;
383
+ }
384
+ };
385
+ /** Whether a page this sync knew is gone from the database: archived, in the trash, moved out, or not there at all. */
386
+ const goneFromDatabase = async (id) => {
387
+ try {
388
+ const page = await call("GET", `/pages/${encodeURIComponent(id)}`);
389
+ const parent = page["parent"];
390
+ return page["archived"] === true || page["in_trash"] === true || notionKey(String(parent?.["data_source_id"] ?? "")) !== notionKey(await dataSource());
391
+ }
392
+ catch (error) {
393
+ if (error instanceof NotionError && error.status === 404)
394
+ return true;
395
+ throw error;
396
+ }
397
+ };
398
+ return {
399
+ name: "notion",
400
+ async pull(cursor) {
401
+ const resolved = resolve(await database());
402
+ const at = readCursor(cursor);
403
+ const time = now();
404
+ const whole = !at || time - at.swept >= (options.sweepEvery ?? DEFAULT_SWEEP);
405
+ const pages = await query(whole ? undefined : at.since);
406
+ let since = at?.since;
407
+ const changes = [];
408
+ for (const page of pages) {
409
+ const edited = String(page["last_edited_time"] ?? "");
410
+ if (edited && (!since || edited > since))
411
+ since = edited;
412
+ const archived = page["archived"] === true || page["in_trash"] === true;
413
+ changes.push({ resource: "pages", id: String(page["id"]), version: notionVersion(page), ...(archived ? { deleted: true } : { fields: await fieldsOf(page, resolved) }) });
414
+ }
415
+ if (whole && options.known) {
416
+ const listed = new Set(pages.map((page) => notionKey(String(page["id"]))));
417
+ for (const id of options.known()) {
418
+ if (listed.has(notionKey(id)))
419
+ continue;
420
+ if (await goneFromDatabase(id))
421
+ changes.push({ resource: "pages", id, version: "gone", deleted: true });
422
+ }
423
+ }
424
+ return { changes, cursor: JSON.stringify({ ...(since ? { since } : {}), swept: whole ? time : at.swept }) };
425
+ },
426
+ async push(writes) {
427
+ const resolved = resolve(schema ?? (await database()));
428
+ const acks = [];
429
+ for (const write of writes) {
430
+ try {
431
+ acks.push(await one(write, resolved));
432
+ }
433
+ catch (error) {
434
+ // One refusal is not a failed run: the engine keeps the local state for this write and says so.
435
+ acks.push({ localId: write.localId, id: write.id ?? "", version: "", error: error instanceof Error ? error.message : String(error) });
436
+ }
437
+ }
438
+ return acks;
439
+ },
440
+ };
441
+ async function one(write, resolved) {
442
+ if (write.deleted && write.id) {
443
+ try {
444
+ await call("PATCH", `/pages/${encodeURIComponent(write.id)}`, { in_trash: true });
445
+ }
446
+ catch (error) {
447
+ // Already gone there is what a delete asks for.
448
+ if (!(error instanceof NotionError && error.status === 404))
449
+ throw error;
450
+ }
451
+ return { localId: write.localId, id: write.id, version: "" };
452
+ }
453
+ const properties = {};
454
+ for (const [ref, value] of Object.entries(write.fields ?? {})) {
455
+ const property = resolved.get(ref);
456
+ if (!property || NOTION_READ_ONLY.has(property.type))
457
+ continue;
458
+ properties[property.name] = notionProperty(property.type, property.options.length > 0 ? asOption(property, value) : value);
459
+ }
460
+ if (write.id && Object.keys(properties).length === 0)
461
+ return { localId: write.localId, id: write.id, version: "" };
462
+ let page;
463
+ try {
464
+ page = write.id
465
+ ? await call("PATCH", `/pages/${encodeURIComponent(write.id)}`, { properties })
466
+ : await call("POST", "/pages", { parent: { type: "data_source_id", data_source_id: await dataSource() }, properties });
467
+ }
468
+ catch (error) {
469
+ if (write.id && error instanceof NotionError && error.status === 404) {
470
+ throw new NotionError(`notion: the page ${write.id} is not one the integration can see any more: it was deleted, or its database is no longer shared with the integration`, 404, error.code);
471
+ }
472
+ throw error;
473
+ }
474
+ return { localId: write.localId, id: String(page["id"]), version: notionVersion(page) };
475
+ }
476
+ }
477
+ //# sourceMappingURL=notion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notion.js","sourceRoot":"","sources":["../../src/sync/notion.ts"],"names":[],"mappings":"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"}