@lpenguin/notion-cli 1.0.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 +245 -0
- package/dist/commands/database/create.d.ts +8 -0
- package/dist/commands/database/create.d.ts.map +1 -0
- package/dist/commands/database/create.js +71 -0
- package/dist/commands/database/create.js.map +1 -0
- package/dist/commands/database/delete.d.ts +10 -0
- package/dist/commands/database/delete.d.ts.map +1 -0
- package/dist/commands/database/delete.js +83 -0
- package/dist/commands/database/delete.js.map +1 -0
- package/dist/commands/database/export.d.ts +11 -0
- package/dist/commands/database/export.d.ts.map +1 -0
- package/dist/commands/database/export.js +74 -0
- package/dist/commands/database/export.js.map +1 -0
- package/dist/commands/database/insert.d.ts +11 -0
- package/dist/commands/database/insert.d.ts.map +1 -0
- package/dist/commands/database/insert.js +93 -0
- package/dist/commands/database/insert.js.map +1 -0
- package/dist/commands/database/list.d.ts +10 -0
- package/dist/commands/database/list.d.ts.map +1 -0
- package/dist/commands/database/list.js +80 -0
- package/dist/commands/database/list.js.map +1 -0
- package/dist/commands/database/query.d.ts +10 -0
- package/dist/commands/database/query.d.ts.map +1 -0
- package/dist/commands/database/query.js +77 -0
- package/dist/commands/database/query.js.map +1 -0
- package/dist/commands/database/schema.d.ts +11 -0
- package/dist/commands/database/schema.d.ts.map +1 -0
- package/dist/commands/database/schema.js +76 -0
- package/dist/commands/database/schema.js.map +1 -0
- package/dist/commands/database/update.d.ts +11 -0
- package/dist/commands/database/update.d.ts.map +1 -0
- package/dist/commands/database/update.js +105 -0
- package/dist/commands/database/update.js.map +1 -0
- package/dist/commands/page/create.d.ts +11 -0
- package/dist/commands/page/create.d.ts.map +1 -0
- package/dist/commands/page/create.js +102 -0
- package/dist/commands/page/create.js.map +1 -0
- package/dist/commands/page/list.d.ts +10 -0
- package/dist/commands/page/list.d.ts.map +1 -0
- package/dist/commands/page/list.js +87 -0
- package/dist/commands/page/list.js.map +1 -0
- package/dist/commands/page/patch.d.ts +21 -0
- package/dist/commands/page/patch.d.ts.map +1 -0
- package/dist/commands/page/patch.js +156 -0
- package/dist/commands/page/patch.js.map +1 -0
- package/dist/commands/page/read.d.ts +10 -0
- package/dist/commands/page/read.d.ts.map +1 -0
- package/dist/commands/page/read.js +86 -0
- package/dist/commands/page/read.js.map +1 -0
- package/dist/commands/page/write-properties.d.ts +15 -0
- package/dist/commands/page/write-properties.d.ts.map +1 -0
- package/dist/commands/page/write-properties.js +128 -0
- package/dist/commands/page/write-properties.js.map +1 -0
- package/dist/commands/page/write.d.ts +14 -0
- package/dist/commands/page/write.d.ts.map +1 -0
- package/dist/commands/page/write.js +109 -0
- package/dist/commands/page/write.js.map +1 -0
- package/dist/commands/search.d.ts +18 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +129 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +121 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/block-patch.d.ts +61 -0
- package/dist/lib/block-patch.d.ts.map +1 -0
- package/dist/lib/block-patch.js +181 -0
- package/dist/lib/block-patch.js.map +1 -0
- package/dist/lib/client.d.ts +17 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/client.js +63 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/config.d.ts +19 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +65 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/csv.d.ts +45 -0
- package/dist/lib/csv.d.ts.map +1 -0
- package/dist/lib/csv.js +262 -0
- package/dist/lib/csv.js.map +1 -0
- package/dist/lib/db-properties.d.ts +11 -0
- package/dist/lib/db-properties.d.ts.map +1 -0
- package/dist/lib/db-properties.js +25 -0
- package/dist/lib/db-properties.js.map +1 -0
- package/dist/lib/errors.d.ts +34 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +86 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/file-upload.d.ts +25 -0
- package/dist/lib/file-upload.d.ts.map +1 -0
- package/dist/lib/file-upload.js +90 -0
- package/dist/lib/file-upload.js.map +1 -0
- package/dist/lib/markdown.d.ts +79 -0
- package/dist/lib/markdown.d.ts.map +1 -0
- package/dist/lib/markdown.js +320 -0
- package/dist/lib/markdown.js.map +1 -0
- package/dist/lib/output.d.ts +20 -0
- package/dist/lib/output.d.ts.map +1 -0
- package/dist/lib/output.js +67 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/patch.d.ts +23 -0
- package/dist/lib/patch.d.ts.map +1 -0
- package/dist/lib/patch.js +72 -0
- package/dist/lib/patch.js.map +1 -0
- package/dist/lib/rate-limit.d.ts +9 -0
- package/dist/lib/rate-limit.d.ts.map +1 -0
- package/dist/lib/rate-limit.js +67 -0
- package/dist/lib/rate-limit.js.map +1 -0
- package/dist/lib/safety.d.ts +17 -0
- package/dist/lib/safety.d.ts.map +1 -0
- package/dist/lib/safety.js +60 -0
- package/dist/lib/safety.js.map +1 -0
- package/dist/lib/types.d.ts +138 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +13 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/validator.d.ts +33 -0
- package/dist/lib/validator.d.ts.map +1 -0
- package/dist/lib/validator.js +68 -0
- package/dist/lib/validator.js.map +1 -0
- package/dist/utils/id.d.ts +14 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +33 -0
- package/dist/utils/id.js.map +1 -0
- package/dist/utils/logger.d.ts +20 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +43 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/string.d.ts +14 -0
- package/dist/utils/string.d.ts.map +1 -0
- package/dist/utils/string.js +37 -0
- package/dist/utils/string.js.map +1 -0
- package/package.json +64 -0
package/dist/lib/csv.js
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSV conversion utilities for Notion database rows.
|
|
3
|
+
*
|
|
4
|
+
* - Notion DB rows → CSV (export)
|
|
5
|
+
* - CSV → Notion DB row properties (import)
|
|
6
|
+
*
|
|
7
|
+
* Property type mapping:
|
|
8
|
+
* title, rich_text → string
|
|
9
|
+
* number → number
|
|
10
|
+
* select → string
|
|
11
|
+
* multi_select → semicolon-separated string
|
|
12
|
+
* date → ISO string (start / start|end for ranges)
|
|
13
|
+
* checkbox → "true" / "false"
|
|
14
|
+
* url, email, phone → string
|
|
15
|
+
* formula → computed string (read-only)
|
|
16
|
+
* relation → comma-separated page IDs
|
|
17
|
+
* rollup → computed string (read-only)
|
|
18
|
+
* status → string
|
|
19
|
+
* people → comma-separated user IDs
|
|
20
|
+
* files → comma-separated URLs
|
|
21
|
+
*/
|
|
22
|
+
import { stringify } from 'csv-stringify/sync';
|
|
23
|
+
import { parse } from 'csv-parse/sync';
|
|
24
|
+
import * as logger from '../utils/logger.js';
|
|
25
|
+
/**
|
|
26
|
+
* Convert Notion database query results to CSV string.
|
|
27
|
+
*/
|
|
28
|
+
export function rowsToCsv(rows, propertyNames) {
|
|
29
|
+
const headers = ['_notion_id', ...propertyNames];
|
|
30
|
+
const records = rows.map((row) => {
|
|
31
|
+
const record = { _notion_id: row.id };
|
|
32
|
+
for (const prop of propertyNames) {
|
|
33
|
+
const value = row.properties[prop];
|
|
34
|
+
record[prop] = value !== undefined ? extractPropertyValue(value) : '';
|
|
35
|
+
}
|
|
36
|
+
return record;
|
|
37
|
+
});
|
|
38
|
+
return stringify(records, {
|
|
39
|
+
header: true,
|
|
40
|
+
columns: headers,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Parse CSV string into row objects for database import.
|
|
45
|
+
* Returns an array of { id?: string, properties: Record<string, string> }.
|
|
46
|
+
*/
|
|
47
|
+
export function csvToRows(csvContent) {
|
|
48
|
+
const records = parse(csvContent, {
|
|
49
|
+
columns: true,
|
|
50
|
+
skip_empty_lines: true,
|
|
51
|
+
trim: true,
|
|
52
|
+
});
|
|
53
|
+
return records.map((record) => {
|
|
54
|
+
const id = record['_notion_id'];
|
|
55
|
+
const properties = {};
|
|
56
|
+
for (const [key, value] of Object.entries(record)) {
|
|
57
|
+
if (key !== '_notion_id') {
|
|
58
|
+
properties[key] = value;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
id: id !== undefined && id !== '' ? id : undefined,
|
|
63
|
+
properties,
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Build Notion property objects from CSV row values.
|
|
69
|
+
* Maps string values back to Notion property types.
|
|
70
|
+
*/
|
|
71
|
+
export function buildPropertyValue(type, value) {
|
|
72
|
+
if (value === '') {
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
switch (type) {
|
|
76
|
+
case 'title':
|
|
77
|
+
return {
|
|
78
|
+
title: [{ text: { content: value } }],
|
|
79
|
+
};
|
|
80
|
+
case 'rich_text':
|
|
81
|
+
return {
|
|
82
|
+
rich_text: [{ text: { content: value } }],
|
|
83
|
+
};
|
|
84
|
+
case 'number': {
|
|
85
|
+
const num = Number(value);
|
|
86
|
+
return Number.isNaN(num) ? undefined : { number: num };
|
|
87
|
+
}
|
|
88
|
+
case 'select':
|
|
89
|
+
return { select: { name: value } };
|
|
90
|
+
case 'multi_select':
|
|
91
|
+
return {
|
|
92
|
+
multi_select: value.split(';').map((v) => ({ name: v.trim() })),
|
|
93
|
+
};
|
|
94
|
+
case 'date': {
|
|
95
|
+
const parts = value.split('|');
|
|
96
|
+
const start = parts[0]?.trim();
|
|
97
|
+
const end = parts[1]?.trim();
|
|
98
|
+
if (start === undefined || start === '')
|
|
99
|
+
return undefined;
|
|
100
|
+
return {
|
|
101
|
+
date: {
|
|
102
|
+
start,
|
|
103
|
+
...(end !== undefined && end !== '' ? { end } : {}),
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
case 'checkbox':
|
|
108
|
+
return { checkbox: value.toLowerCase() === 'true' };
|
|
109
|
+
case 'url':
|
|
110
|
+
return { url: value };
|
|
111
|
+
case 'email':
|
|
112
|
+
return { email: value };
|
|
113
|
+
case 'phone_number':
|
|
114
|
+
return { phone_number: value };
|
|
115
|
+
case 'relation':
|
|
116
|
+
return {
|
|
117
|
+
relation: value.split(',').map((id) => ({ id: id.trim() })),
|
|
118
|
+
};
|
|
119
|
+
case 'status':
|
|
120
|
+
return { status: { name: value } };
|
|
121
|
+
default:
|
|
122
|
+
logger.warn(`Unsupported property type for import: ${type}. Skipping.`);
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Extract a human-readable string from a Notion property value.
|
|
128
|
+
*/
|
|
129
|
+
function extractPropertyValue(prop) {
|
|
130
|
+
const type = prop['type'];
|
|
131
|
+
if (type === undefined)
|
|
132
|
+
return JSON.stringify(prop);
|
|
133
|
+
switch (type) {
|
|
134
|
+
case 'title':
|
|
135
|
+
return extractRichText(prop['title']);
|
|
136
|
+
case 'rich_text':
|
|
137
|
+
return extractRichText(prop['rich_text']);
|
|
138
|
+
case 'number':
|
|
139
|
+
return prop['number'] !== null && prop['number'] !== undefined
|
|
140
|
+
? String(prop['number'])
|
|
141
|
+
: '';
|
|
142
|
+
case 'select':
|
|
143
|
+
return extractName(prop['select']);
|
|
144
|
+
case 'multi_select':
|
|
145
|
+
return extractMultiSelect(prop['multi_select']);
|
|
146
|
+
case 'date':
|
|
147
|
+
return extractDate(prop['date']);
|
|
148
|
+
case 'checkbox':
|
|
149
|
+
return String(prop['checkbox'] ?? false);
|
|
150
|
+
case 'url':
|
|
151
|
+
return String(prop['url'] ?? '');
|
|
152
|
+
case 'email':
|
|
153
|
+
return String(prop['email'] ?? '');
|
|
154
|
+
case 'phone_number':
|
|
155
|
+
return String(prop['phone_number'] ?? '');
|
|
156
|
+
case 'formula':
|
|
157
|
+
return extractFormula(prop['formula']);
|
|
158
|
+
case 'relation':
|
|
159
|
+
return extractRelation(prop['relation']);
|
|
160
|
+
case 'rollup':
|
|
161
|
+
return extractRollup(prop['rollup']);
|
|
162
|
+
case 'status':
|
|
163
|
+
return extractName(prop['status']);
|
|
164
|
+
case 'people':
|
|
165
|
+
return extractPeople(prop['people']);
|
|
166
|
+
case 'files':
|
|
167
|
+
return extractFiles(prop['files']);
|
|
168
|
+
case 'created_time':
|
|
169
|
+
return String(prop['created_time'] ?? '');
|
|
170
|
+
case 'last_edited_time':
|
|
171
|
+
return String(prop['last_edited_time'] ?? '');
|
|
172
|
+
case 'created_by':
|
|
173
|
+
return extractName(prop['created_by']);
|
|
174
|
+
case 'last_edited_by':
|
|
175
|
+
return extractName(prop['last_edited_by']);
|
|
176
|
+
default:
|
|
177
|
+
return JSON.stringify(prop);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function extractRichText(val) {
|
|
181
|
+
if (!Array.isArray(val))
|
|
182
|
+
return '';
|
|
183
|
+
return val
|
|
184
|
+
.map((t) => t['plain_text'] ?? '')
|
|
185
|
+
.join('');
|
|
186
|
+
}
|
|
187
|
+
function extractName(val) {
|
|
188
|
+
if (val === null || val === undefined)
|
|
189
|
+
return '';
|
|
190
|
+
return val['name'] ?? '';
|
|
191
|
+
}
|
|
192
|
+
function extractMultiSelect(val) {
|
|
193
|
+
if (!Array.isArray(val))
|
|
194
|
+
return '';
|
|
195
|
+
return val
|
|
196
|
+
.map((s) => s['name'] ?? '')
|
|
197
|
+
.join(';');
|
|
198
|
+
}
|
|
199
|
+
function extractDate(val) {
|
|
200
|
+
if (val === null || val === undefined)
|
|
201
|
+
return '';
|
|
202
|
+
const d = val;
|
|
203
|
+
const start = d['start'] ?? '';
|
|
204
|
+
const end = d['end'];
|
|
205
|
+
return end !== undefined ? `${start}|${end}` : start;
|
|
206
|
+
}
|
|
207
|
+
function extractFormula(val) {
|
|
208
|
+
if (val === null || val === undefined)
|
|
209
|
+
return '';
|
|
210
|
+
const f = val;
|
|
211
|
+
const fType = f['type'];
|
|
212
|
+
if (fType !== undefined && f[fType] !== undefined) {
|
|
213
|
+
return String(f[fType]);
|
|
214
|
+
}
|
|
215
|
+
return '';
|
|
216
|
+
}
|
|
217
|
+
function extractRelation(val) {
|
|
218
|
+
if (!Array.isArray(val))
|
|
219
|
+
return '';
|
|
220
|
+
return val
|
|
221
|
+
.map((r) => r['id'] ?? '')
|
|
222
|
+
.join(',');
|
|
223
|
+
}
|
|
224
|
+
function extractRollup(val) {
|
|
225
|
+
if (val === null || val === undefined)
|
|
226
|
+
return '';
|
|
227
|
+
const r = val;
|
|
228
|
+
const rType = r['type'];
|
|
229
|
+
if (rType === 'array' && Array.isArray(r['array'])) {
|
|
230
|
+
return r['array'].map((item) => extractPropertyValue(item)).join(';');
|
|
231
|
+
}
|
|
232
|
+
if (rType !== undefined && r[rType] !== undefined) {
|
|
233
|
+
return String(r[rType]);
|
|
234
|
+
}
|
|
235
|
+
return '';
|
|
236
|
+
}
|
|
237
|
+
function extractPeople(val) {
|
|
238
|
+
if (!Array.isArray(val))
|
|
239
|
+
return '';
|
|
240
|
+
return val
|
|
241
|
+
.map((p) => p['id'] ?? '')
|
|
242
|
+
.join(',');
|
|
243
|
+
}
|
|
244
|
+
function extractFiles(val) {
|
|
245
|
+
if (!Array.isArray(val))
|
|
246
|
+
return '';
|
|
247
|
+
return val
|
|
248
|
+
.map((f) => {
|
|
249
|
+
const fType = f['type'];
|
|
250
|
+
if (fType === 'external') {
|
|
251
|
+
const external = f['external'];
|
|
252
|
+
return external?.['url'] ?? '';
|
|
253
|
+
}
|
|
254
|
+
if (fType === 'file') {
|
|
255
|
+
const file = f['file'];
|
|
256
|
+
return file?.['url'] ?? '';
|
|
257
|
+
}
|
|
258
|
+
return '';
|
|
259
|
+
})
|
|
260
|
+
.join(',');
|
|
261
|
+
}
|
|
262
|
+
//# sourceMappingURL=csv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"csv.js","sourceRoot":"","sources":["../../src/lib/csv.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helper to build Notion page properties from CSV values + database schema.
|
|
3
|
+
* Used by both `db insert` and `db update` commands.
|
|
4
|
+
*/
|
|
5
|
+
import type { GetDataSourceResponse } from '@notionhq/client';
|
|
6
|
+
export type SchemaProperties = GetDataSourceResponse['properties'];
|
|
7
|
+
/**
|
|
8
|
+
* Build Notion page properties from CSV values + schema.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildNotionProperties(csvProps: Record<string, string>, schema: SchemaProperties): Record<string, unknown>;
|
|
11
|
+
//# sourceMappingURL=db-properties.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-properties.d.ts","sourceRoot":"","sources":["../../src/lib/db-properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAI9D,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;AAEnE;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,MAAM,EAAE,gBAAgB,GACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBzB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helper to build Notion page properties from CSV values + database schema.
|
|
3
|
+
* Used by both `db insert` and `db update` commands.
|
|
4
|
+
*/
|
|
5
|
+
import { buildPropertyValue } from './csv.js';
|
|
6
|
+
import * as logger from '../utils/logger.js';
|
|
7
|
+
/**
|
|
8
|
+
* Build Notion page properties from CSV values + schema.
|
|
9
|
+
*/
|
|
10
|
+
export function buildNotionProperties(csvProps, schema) {
|
|
11
|
+
const properties = {};
|
|
12
|
+
for (const [name, value] of Object.entries(csvProps)) {
|
|
13
|
+
const propSchema = schema[name];
|
|
14
|
+
if (propSchema === undefined) {
|
|
15
|
+
logger.warn(`Property "${name}" not found in database schema. Skipping.`);
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
const notionValue = buildPropertyValue(propSchema.type, value);
|
|
19
|
+
if (notionValue !== undefined) {
|
|
20
|
+
properties[name] = notionValue;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return properties;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=db-properties.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db-properties.js","sourceRoot":"","sources":["../../src/lib/db-properties.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAI7C;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,QAAgC,EAChC,MAAwB;IAExB,MAAM,UAAU,GAA4B,EAAE,CAAC;IAE/C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,aAAa,IAAI,2CAA2C,CAAC,CAAC;YAC1E,SAAS;QACX,CAAC;QAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC/D,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YAC9B,UAAU,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC;QACjC,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes with structured error codes.
|
|
3
|
+
* All errors sanitize sensitive information (tokens, secrets).
|
|
4
|
+
*/
|
|
5
|
+
import { type ExitCodeValue } from './types.js';
|
|
6
|
+
/** Base CLI error with structured code and exit code. */
|
|
7
|
+
export declare class CliError extends Error {
|
|
8
|
+
readonly code: string;
|
|
9
|
+
readonly exitCode: ExitCodeValue;
|
|
10
|
+
readonly details?: unknown;
|
|
11
|
+
constructor(message: string, code: string, exitCode: ExitCodeValue, details?: unknown);
|
|
12
|
+
}
|
|
13
|
+
export declare class AuthError extends CliError {
|
|
14
|
+
constructor(message?: string);
|
|
15
|
+
}
|
|
16
|
+
export declare class ValidationError extends CliError {
|
|
17
|
+
constructor(message: string, details?: unknown);
|
|
18
|
+
}
|
|
19
|
+
export declare class NotFoundError extends CliError {
|
|
20
|
+
constructor(resource: string, id: string);
|
|
21
|
+
}
|
|
22
|
+
export declare class RateLimitError extends CliError {
|
|
23
|
+
readonly retryAfterMs: number;
|
|
24
|
+
constructor(retryAfterMs: number);
|
|
25
|
+
}
|
|
26
|
+
export declare class PatchConflictError extends CliError {
|
|
27
|
+
constructor(message?: string);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Convert any thrown value into a structured CliError.
|
|
31
|
+
* Handles Notion API errors, Zod validation errors, and unknown throws.
|
|
32
|
+
*/
|
|
33
|
+
export declare function toCliError(err: unknown): CliError;
|
|
34
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAE1D,yDAAyD;AACzD,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;gBAEf,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,OAAO;CAOtF;AAED,qBAAa,SAAU,SAAQ,QAAQ;gBACzB,OAAO,SAA4D;CAIhF;AAED,qBAAa,eAAgB,SAAQ,QAAQ;gBAC/B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;CAI/C;AAED,qBAAa,aAAc,SAAQ,QAAQ;gBAC7B,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM;CAIzC;AAED,qBAAa,cAAe,SAAQ,QAAQ;IAC1C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;gBAElB,YAAY,EAAE,MAAM;CASjC;AAED,qBAAa,kBAAmB,SAAQ,QAAQ;gBAClC,OAAO,SAAuE;CAI3F;AAcD;;;GAGG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CA+BjD"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error classes with structured error codes.
|
|
3
|
+
* All errors sanitize sensitive information (tokens, secrets).
|
|
4
|
+
*/
|
|
5
|
+
import { ExitCode } from './types.js';
|
|
6
|
+
/** Base CLI error with structured code and exit code. */
|
|
7
|
+
export class CliError extends Error {
|
|
8
|
+
code;
|
|
9
|
+
exitCode;
|
|
10
|
+
details;
|
|
11
|
+
constructor(message, code, exitCode, details) {
|
|
12
|
+
super(sanitizeMessage(message));
|
|
13
|
+
this.name = 'CliError';
|
|
14
|
+
this.code = code;
|
|
15
|
+
this.exitCode = exitCode;
|
|
16
|
+
this.details = details;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class AuthError extends CliError {
|
|
20
|
+
constructor(message = 'Authentication failed. Set NOTION_TOKEN or use --token.') {
|
|
21
|
+
super(message, 'AUTH_ERROR', ExitCode.AUTH_ERROR);
|
|
22
|
+
this.name = 'AuthError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class ValidationError extends CliError {
|
|
26
|
+
constructor(message, details) {
|
|
27
|
+
super(message, 'VALIDATION_ERROR', ExitCode.VALIDATION_ERROR, details);
|
|
28
|
+
this.name = 'ValidationError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class NotFoundError extends CliError {
|
|
32
|
+
constructor(resource, id) {
|
|
33
|
+
super(`${resource} not found: ${id}`, 'NOT_FOUND', ExitCode.NOT_FOUND);
|
|
34
|
+
this.name = 'NotFoundError';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export class RateLimitError extends CliError {
|
|
38
|
+
retryAfterMs;
|
|
39
|
+
constructor(retryAfterMs) {
|
|
40
|
+
super(`Rate limited by Notion API. Retry after ${Math.ceil(retryAfterMs / 1000)}s.`, 'RATE_LIMITED', ExitCode.RATE_LIMITED);
|
|
41
|
+
this.name = 'RateLimitError';
|
|
42
|
+
this.retryAfterMs = retryAfterMs;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export class PatchConflictError extends CliError {
|
|
46
|
+
constructor(message = 'Patch cannot be applied: page content has changed since last read.') {
|
|
47
|
+
super(message, 'PATCH_CONFLICT', ExitCode.GENERAL_ERROR);
|
|
48
|
+
this.name = 'PatchConflictError';
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Strip any token-like strings from error messages.
|
|
53
|
+
* Matches patterns: ntn_*, secret_*, Bearer *, and long hex strings.
|
|
54
|
+
*/
|
|
55
|
+
function sanitizeMessage(message) {
|
|
56
|
+
return message
|
|
57
|
+
.replace(/\b(ntn_[A-Za-z0-9_-]+)\b/g, '[REDACTED]')
|
|
58
|
+
.replace(/\b(secret_[A-Za-z0-9_-]+)\b/g, '[REDACTED]')
|
|
59
|
+
.replace(/Bearer\s+[A-Za-z0-9_-]+/g, 'Bearer [REDACTED]')
|
|
60
|
+
.replace(/\b[a-f0-9]{40,}\b/gi, '[REDACTED]');
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Convert any thrown value into a structured CliError.
|
|
64
|
+
* Handles Notion API errors, Zod validation errors, and unknown throws.
|
|
65
|
+
*/
|
|
66
|
+
export function toCliError(err) {
|
|
67
|
+
if (err instanceof CliError) {
|
|
68
|
+
return err;
|
|
69
|
+
}
|
|
70
|
+
if (err instanceof Error) {
|
|
71
|
+
// Notion API error shape
|
|
72
|
+
const notionErr = err;
|
|
73
|
+
if (notionErr.status === 401 || notionErr.code === 'unauthorized') {
|
|
74
|
+
return new AuthError();
|
|
75
|
+
}
|
|
76
|
+
if (notionErr.status === 404 || notionErr.code === 'object_not_found') {
|
|
77
|
+
return new NotFoundError('Resource', 'unknown');
|
|
78
|
+
}
|
|
79
|
+
if (notionErr.status === 429) {
|
|
80
|
+
return new RateLimitError(1000);
|
|
81
|
+
}
|
|
82
|
+
return new CliError(err.message, 'GENERAL_ERROR', ExitCode.GENERAL_ERROR);
|
|
83
|
+
}
|
|
84
|
+
return new CliError(String(err), 'GENERAL_ERROR', ExitCode.GENERAL_ERROR);
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for uploading files to Notion.
|
|
3
|
+
*
|
|
4
|
+
* Handles file:// URLs by uploading them to Notion's file storage
|
|
5
|
+
* and returning the file upload ID for use in blocks.
|
|
6
|
+
*/
|
|
7
|
+
import { type Client } from '@notionhq/client';
|
|
8
|
+
/**
|
|
9
|
+
* Upload a local file to Notion.
|
|
10
|
+
*
|
|
11
|
+
* @param client - Notion client
|
|
12
|
+
* @param filePath - Local file path (without file:// prefix)
|
|
13
|
+
* @returns The file upload ID to use in blocks
|
|
14
|
+
*/
|
|
15
|
+
export declare function uploadFileToNotion(client: Client, filePath: string): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Check if a URL is a file:// URL.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isFileUrl(url: string): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Convert file:// URL to local file path.
|
|
22
|
+
* Handles both Unix and Windows paths.
|
|
23
|
+
*/
|
|
24
|
+
export declare function fileUrlToPath(url: string): string;
|
|
25
|
+
//# sourceMappingURL=file-upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-upload.d.ts","sourceRoot":"","sources":["../../src/lib/file-upload.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAO/C;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC,CA0CjB;AAwBD;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAE9C;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAiBjD"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for uploading files to Notion.
|
|
3
|
+
*
|
|
4
|
+
* Handles file:// URLs by uploading them to Notion's file storage
|
|
5
|
+
* and returning the file upload ID for use in blocks.
|
|
6
|
+
*/
|
|
7
|
+
import {} from '@notionhq/client';
|
|
8
|
+
import { readFileSync } from 'node:fs';
|
|
9
|
+
import { basename } from 'node:path';
|
|
10
|
+
import {} from '@notionhq/client/build/src/api-endpoints.js';
|
|
11
|
+
import * as logger from '../utils/logger.js';
|
|
12
|
+
import { withRateLimit } from './rate-limit.js';
|
|
13
|
+
/**
|
|
14
|
+
* Upload a local file to Notion.
|
|
15
|
+
*
|
|
16
|
+
* @param client - Notion client
|
|
17
|
+
* @param filePath - Local file path (without file:// prefix)
|
|
18
|
+
* @returns The file upload ID to use in blocks
|
|
19
|
+
*/
|
|
20
|
+
export async function uploadFileToNotion(client, filePath) {
|
|
21
|
+
logger.debug(`Uploading file to Notion: ${filePath}`);
|
|
22
|
+
// Read file content
|
|
23
|
+
const fileContent = readFileSync(filePath);
|
|
24
|
+
const filename = basename(filePath);
|
|
25
|
+
// Determine content type based on file extension
|
|
26
|
+
const contentType = getContentType(filename);
|
|
27
|
+
// Create file upload
|
|
28
|
+
const uploadResponse = await withRateLimit(() => client.fileUploads.create({
|
|
29
|
+
mode: 'single_part',
|
|
30
|
+
filename,
|
|
31
|
+
content_type: contentType,
|
|
32
|
+
}), 'fileUploads.create');
|
|
33
|
+
logger.debug(`Created file upload with ID: ${uploadResponse.id}`);
|
|
34
|
+
// Send file content
|
|
35
|
+
// Convert Buffer to Blob
|
|
36
|
+
const blob = new Blob([fileContent], { type: contentType });
|
|
37
|
+
await withRateLimit(() => client.fileUploads.send({
|
|
38
|
+
file_upload_id: uploadResponse.id,
|
|
39
|
+
file: {
|
|
40
|
+
data: blob,
|
|
41
|
+
filename,
|
|
42
|
+
},
|
|
43
|
+
}), 'fileUploads.send');
|
|
44
|
+
logger.debug(`File uploaded successfully: ${uploadResponse.id}`);
|
|
45
|
+
return uploadResponse.id;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Determine MIME type from filename extension.
|
|
49
|
+
*/
|
|
50
|
+
function getContentType(filename) {
|
|
51
|
+
const ext = filename.toLowerCase().split('.').pop();
|
|
52
|
+
const mimeTypes = {
|
|
53
|
+
jpg: 'image/jpeg',
|
|
54
|
+
jpeg: 'image/jpeg',
|
|
55
|
+
png: 'image/png',
|
|
56
|
+
gif: 'image/gif',
|
|
57
|
+
webp: 'image/webp',
|
|
58
|
+
svg: 'image/svg+xml',
|
|
59
|
+
bmp: 'image/bmp',
|
|
60
|
+
ico: 'image/x-icon',
|
|
61
|
+
tiff: 'image/tiff',
|
|
62
|
+
tif: 'image/tiff',
|
|
63
|
+
};
|
|
64
|
+
return mimeTypes[ext ?? ''] ?? 'application/octet-stream';
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Check if a URL is a file:// URL.
|
|
68
|
+
*/
|
|
69
|
+
export function isFileUrl(url) {
|
|
70
|
+
return url.startsWith('file://');
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Convert file:// URL to local file path.
|
|
74
|
+
* Handles both Unix and Windows paths.
|
|
75
|
+
*/
|
|
76
|
+
export function fileUrlToPath(url) {
|
|
77
|
+
if (!isFileUrl(url)) {
|
|
78
|
+
return url;
|
|
79
|
+
}
|
|
80
|
+
// Remove file:// prefix
|
|
81
|
+
let path = url.slice(7);
|
|
82
|
+
// Handle Windows paths (file:///C:/path)
|
|
83
|
+
if (/^\/[A-Za-z]:/.test(path)) {
|
|
84
|
+
path = path.slice(1);
|
|
85
|
+
}
|
|
86
|
+
// Decode URL encoding
|
|
87
|
+
path = decodeURIComponent(path);
|
|
88
|
+
return path;
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=file-upload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-upload.js","sourceRoot":"","sources":["../../src/lib/file-upload.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown conversion wrappers.
|
|
3
|
+
*
|
|
4
|
+
* - Markdown → Notion blocks: @tryfabric/martian
|
|
5
|
+
* - Notion → Markdown: notion-to-md (with unified converter)
|
|
6
|
+
*
|
|
7
|
+
* This module provides a clean interface over both libraries.
|
|
8
|
+
*
|
|
9
|
+
* IMPORTANT: All Notion→Markdown conversion uses `mdBlocksToMarkdown()`
|
|
10
|
+
* to ensure consistent output between `page read` and `page patch`.
|
|
11
|
+
*/
|
|
12
|
+
import { type MdBlock } from 'notion-to-md/build/types/index.js';
|
|
13
|
+
import { type Client } from '@notionhq/client';
|
|
14
|
+
import { type BlockObjectRequest } from '@notionhq/client/build/src/api-endpoints.js';
|
|
15
|
+
import { type BlockLineMapResult } from './types.js';
|
|
16
|
+
export type { MdBlock } from 'notion-to-md/build/types/index.js';
|
|
17
|
+
/**
|
|
18
|
+
* Convert a Markdown string to an array of Notion block objects.
|
|
19
|
+
* Uses @tryfabric/martian for the conversion.
|
|
20
|
+
*/
|
|
21
|
+
export declare function markdownToNotionBlocks(markdown: string): BlockObjectRequest[];
|
|
22
|
+
/**
|
|
23
|
+
* Process blocks and upload any file:// images to Notion.
|
|
24
|
+
* Returns modified blocks with uploaded file IDs.
|
|
25
|
+
*/
|
|
26
|
+
export declare function processImageUploads(client: Client, blocks: BlockObjectRequest[]): Promise<BlockObjectRequest[]>;
|
|
27
|
+
/**
|
|
28
|
+
* Unified MdBlock to Markdown converter.
|
|
29
|
+
*
|
|
30
|
+
* Converts MdBlocks to markdown while tracking which lines each block contributes.
|
|
31
|
+
* This is the SINGLE source of truth for Notion→Markdown conversion.
|
|
32
|
+
*
|
|
33
|
+
* Used by both `page read` and `page patch` to ensure consistent line numbers.
|
|
34
|
+
*
|
|
35
|
+
* @param blocks - Array of MdBlocks from notion-to-md
|
|
36
|
+
* @returns The markdown string and a mapping of blocks to line ranges
|
|
37
|
+
*/
|
|
38
|
+
export declare function mdBlocksToMarkdown(blocks: readonly MdBlock[]): BlockLineMapResult;
|
|
39
|
+
/**
|
|
40
|
+
* Fetch a Notion page's content as MdBlocks (preserving block IDs).
|
|
41
|
+
* Used for surgical patching where we need to track block → line mappings.
|
|
42
|
+
*/
|
|
43
|
+
export declare function fetchPageMdBlocks(client: Client, pageId: string): Promise<MdBlock[]>;
|
|
44
|
+
/**
|
|
45
|
+
* Fetch a Notion page's content and convert to Markdown.
|
|
46
|
+
* Uses the unified mdBlocksToMarkdown converter.
|
|
47
|
+
*/
|
|
48
|
+
export declare function notionPageToMarkdown(client: Client, pageId: string): Promise<string>;
|
|
49
|
+
/**
|
|
50
|
+
* Clean raw Markdown output:
|
|
51
|
+
* - Trim leading/trailing whitespace
|
|
52
|
+
* - Collapse 3+ consecutive newlines into exactly 2
|
|
53
|
+
*/
|
|
54
|
+
export declare function cleanMarkdownOutput(raw: string): string;
|
|
55
|
+
/**
|
|
56
|
+
* Recursively rewrite child_page blocks to paragraph so that
|
|
57
|
+
* toMarkdownString includes them in the output.
|
|
58
|
+
*/
|
|
59
|
+
export declare function fixChildPageBlocks(mdBlocks: MdBlock[]): void;
|
|
60
|
+
/**
|
|
61
|
+
* Convert Markdown to numbered-line format for patch operations.
|
|
62
|
+
* Each line is prefixed with its 1-based line number.
|
|
63
|
+
*
|
|
64
|
+
* Example output:
|
|
65
|
+
* 1: # Hello World
|
|
66
|
+
* 2:
|
|
67
|
+
* 3: Some content here.
|
|
68
|
+
*/
|
|
69
|
+
export declare function addLineNumbers(markdown: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* Remove line numbers from numbered-line format.
|
|
72
|
+
* Strips the "N: " prefix from each line.
|
|
73
|
+
*/
|
|
74
|
+
export declare function stripLineNumbers(numbered: string): string;
|
|
75
|
+
/**
|
|
76
|
+
* Extract the title (first H1) from Markdown content.
|
|
77
|
+
*/
|
|
78
|
+
export declare function extractTitle(markdown: string): string;
|
|
79
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/lib/markdown.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,mCAAmC,CAAC;AACjE,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,KAAK,kBAAkB,EAA6D,MAAM,6CAA6C,CAAC;AACjJ,OAAO,EAAyB,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAM5E,YAAY,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAC;AA6FjE;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAO7E;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,kBAAkB,EAAE,GAC3B,OAAO,CAAC,kBAAkB,EAAE,CAAC,CA8C/B;AAGD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,GAAG,kBAAkB,CA8BjF;AAwDD;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,EAAE,CAAC,CAuCpB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,CAS5D;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGrD"}
|