apple-books-export 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.
@@ -0,0 +1,6 @@
1
+ import type { Book } from "../types.js";
2
+ /**
3
+ * Export all books to a single JSON file
4
+ */
5
+ export declare function exportToJson(books: Book[], outputPath: string, singleFile?: boolean): string | string[];
6
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../src/exporters/json.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAExC;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAE,OAAc,GAAG,MAAM,GAAG,MAAM,EAAE,CAM7G"}
@@ -0,0 +1,103 @@
1
+ import { writeFileSync, mkdirSync } from "fs";
2
+ import { join, dirname } from "path";
3
+ /**
4
+ * Export all books to a single JSON file
5
+ */
6
+ export function exportToJson(books, outputPath, singleFile = true) {
7
+ if (singleFile) {
8
+ return exportToSingleJson(books, outputPath);
9
+ }
10
+ else {
11
+ return exportToMultipleJson(books, outputPath);
12
+ }
13
+ }
14
+ /**
15
+ * Export all books to a single JSON file
16
+ */
17
+ function exportToSingleJson(books, outputPath) {
18
+ // Ensure parent directory exists
19
+ mkdirSync(dirname(outputPath), { recursive: true });
20
+ const totalAnnotations = books.reduce((sum, book) => sum + book.annotations.length, 0);
21
+ const totalHighlights = books.reduce((sum, book) => sum + book.annotations.filter(a => a.type === 'highlight').length, 0);
22
+ const totalBookmarks = books.reduce((sum, book) => sum + book.annotations.filter(a => a.type === 'bookmark').length, 0);
23
+ const totalNotes = books.reduce((sum, book) => sum + book.annotations.filter(a => a.type === 'note').length, 0);
24
+ const exportData = {
25
+ exported: new Date().toISOString(),
26
+ totalBooks: books.length,
27
+ totalAnnotations,
28
+ statistics: {
29
+ highlights: totalHighlights,
30
+ bookmarks: totalBookmarks,
31
+ notes: totalNotes,
32
+ },
33
+ books: books.map(book => ({
34
+ assetId: book.assetId,
35
+ title: book.title,
36
+ author: book.author,
37
+ genre: book.genre,
38
+ annotationCount: book.annotations.length,
39
+ annotations: book.annotations.map(ann => ({
40
+ id: ann.id,
41
+ type: ann.type,
42
+ color: ann.color,
43
+ text: ann.text,
44
+ note: ann.note,
45
+ location: ann.location,
46
+ chapter: ann.chapter,
47
+ createdAt: ann.createdAt.toISOString(),
48
+ modifiedAt: ann.modifiedAt.toISOString(),
49
+ })),
50
+ })),
51
+ };
52
+ const json = JSON.stringify(exportData, null, 2);
53
+ writeFileSync(outputPath, json, 'utf-8');
54
+ return outputPath;
55
+ }
56
+ /**
57
+ * Sanitize filename by removing/replacing invalid characters
58
+ */
59
+ function sanitizeFilename(filename) {
60
+ return filename
61
+ .replace(/[/\\?%*:|"<>]/g, '-')
62
+ .replace(/\s+/g, ' ')
63
+ .trim()
64
+ .substring(0, 200);
65
+ }
66
+ /**
67
+ * Export each book to separate JSON files
68
+ */
69
+ function exportToMultipleJson(books, outputDir) {
70
+ // Create output directory
71
+ mkdirSync(outputDir, { recursive: true });
72
+ const filepaths = [];
73
+ for (const book of books) {
74
+ if (book.annotations.length === 0)
75
+ continue;
76
+ const bookTitle = book.title || `Unknown Book (${book.assetId.substring(0, 8)})`;
77
+ const filename = sanitizeFilename(`${bookTitle}.json`);
78
+ const filepath = join(outputDir, filename);
79
+ const bookData = {
80
+ assetId: book.assetId,
81
+ title: book.title,
82
+ author: book.author,
83
+ genre: book.genre,
84
+ exported: new Date().toISOString(),
85
+ annotationCount: book.annotations.length,
86
+ annotations: book.annotations.map(ann => ({
87
+ id: ann.id,
88
+ type: ann.type,
89
+ color: ann.color,
90
+ text: ann.text,
91
+ note: ann.note,
92
+ location: ann.location,
93
+ chapter: ann.chapter,
94
+ createdAt: ann.createdAt.toISOString(),
95
+ modifiedAt: ann.modifiedAt.toISOString(),
96
+ })),
97
+ };
98
+ const json = JSON.stringify(bookData, null, 2);
99
+ writeFileSync(filepath, json, 'utf-8');
100
+ filepaths.push(filepath);
101
+ }
102
+ return filepaths;
103
+ }
@@ -0,0 +1,14 @@
1
+ import type { Book } from "../types.js";
2
+ /**
3
+ * Export a single book to markdown file
4
+ */
5
+ export declare function exportBookToMarkdown(book: Book, outputDir: string): string;
6
+ /**
7
+ * Export all books to markdown files
8
+ */
9
+ export declare function exportToMarkdown(books: Book[], outputPath: string): string[];
10
+ /**
11
+ * Export all books to a single markdown file
12
+ */
13
+ export declare function exportToSingleMarkdown(books: Book[], outputPath: string): string;
14
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/exporters/markdown.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAc,MAAM,aAAa,CAAC;AA8DpD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CA6C1E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAW5E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAmDhF"}
@@ -0,0 +1,145 @@
1
+ import { writeFileSync, mkdirSync } from "fs";
2
+ import { join, dirname } from "path";
3
+ const COLOR_EMOJI = {
4
+ yellow: '🟡',
5
+ green: '🟢',
6
+ blue: '🔵',
7
+ pink: '🔴',
8
+ purple: '🟣',
9
+ underline: '➖',
10
+ };
11
+ const TYPE_EMOJI = {
12
+ highlight: '✨',
13
+ bookmark: '📌',
14
+ note: '📝',
15
+ };
16
+ /**
17
+ * Sanitize filename by removing/replacing invalid characters
18
+ */
19
+ function sanitizeFilename(filename) {
20
+ return filename
21
+ .replace(/[/\\?%*:|"<>]/g, '-')
22
+ .replace(/\s+/g, ' ')
23
+ .trim()
24
+ .substring(0, 200); // Limit length
25
+ }
26
+ /**
27
+ * Format a single annotation as markdown
28
+ */
29
+ function formatAnnotation(annotation, index) {
30
+ const colorEmoji = COLOR_EMOJI[annotation.color] || '⚪';
31
+ const typeEmoji = TYPE_EMOJI[annotation.type] || '📄';
32
+ let markdown = `\n## ${colorEmoji} ${typeEmoji} ${annotation.type.charAt(0).toUpperCase() + annotation.type.slice(1)}`;
33
+ if (annotation.location) {
34
+ markdown += ` - ${annotation.location}`;
35
+ }
36
+ markdown += `\n**Created:** ${annotation.createdAt.toLocaleDateString('en-US', {
37
+ year: 'numeric',
38
+ month: 'long',
39
+ day: 'numeric',
40
+ hour: '2-digit',
41
+ minute: '2-digit'
42
+ })}\n`;
43
+ if (annotation.text) {
44
+ markdown += `\n> ${annotation.text.split('\n').join('\n> ')}\n`;
45
+ }
46
+ if (annotation.note) {
47
+ markdown += `\n**Note:** *${annotation.note}*\n`;
48
+ }
49
+ markdown += '\n---\n';
50
+ return markdown;
51
+ }
52
+ /**
53
+ * Export a single book to markdown file
54
+ */
55
+ export function exportBookToMarkdown(book, outputDir) {
56
+ // Create output directory if it doesn't exist
57
+ mkdirSync(outputDir, { recursive: true });
58
+ // Generate filename
59
+ const bookTitle = book.title || `Unknown Book (${book.assetId.substring(0, 8)})`;
60
+ const filename = sanitizeFilename(`${bookTitle}.md`);
61
+ const filepath = join(outputDir, filename);
62
+ // Count annotation types
63
+ const highlights = book.annotations.filter(a => a.type === 'highlight').length;
64
+ const bookmarks = book.annotations.filter(a => a.type === 'bookmark').length;
65
+ const notes = book.annotations.filter(a => a.type === 'note').length;
66
+ // Build YAML frontmatter
67
+ let content = '---\n';
68
+ content += `title: "${book.title || 'Unknown'}"\n`;
69
+ content += `author: "${book.author || 'Unknown'}"\n`;
70
+ if (book.genre) {
71
+ content += `genre: "${book.genre}"\n`;
72
+ }
73
+ content += `assetId: "${book.assetId}"\n`;
74
+ content += `exported: "${new Date().toISOString()}"\n`;
75
+ content += `totalAnnotations: ${book.annotations.length}\n`;
76
+ content += `highlights: ${highlights}\n`;
77
+ content += `bookmarks: ${bookmarks}\n`;
78
+ content += `notes: ${notes}\n`;
79
+ content += '---\n\n';
80
+ // Book header
81
+ content += `# ${book.title || 'Unknown Book'}\n`;
82
+ if (book.author) {
83
+ content += `**by ${book.author}**\n`;
84
+ }
85
+ content += `\n*${book.annotations.length} annotations*\n`;
86
+ // Add annotations
87
+ book.annotations.forEach((annotation, index) => {
88
+ content += formatAnnotation(annotation, index);
89
+ });
90
+ // Write file
91
+ writeFileSync(filepath, content, 'utf-8');
92
+ return filepath;
93
+ }
94
+ /**
95
+ * Export all books to markdown files
96
+ */
97
+ export function exportToMarkdown(books, outputPath) {
98
+ const filepaths = [];
99
+ for (const book of books) {
100
+ if (book.annotations.length === 0)
101
+ continue;
102
+ const filepath = exportBookToMarkdown(book, outputPath);
103
+ filepaths.push(filepath);
104
+ }
105
+ return filepaths;
106
+ }
107
+ /**
108
+ * Export all books to a single markdown file
109
+ */
110
+ export function exportToSingleMarkdown(books, outputPath) {
111
+ // Ensure parent directory exists
112
+ mkdirSync(dirname(outputPath), { recursive: true });
113
+ const totalAnnotations = books.reduce((sum, book) => sum + book.annotations.length, 0);
114
+ const totalHighlights = books.reduce((sum, book) => sum + book.annotations.filter(a => a.type === 'highlight').length, 0);
115
+ const totalBookmarks = books.reduce((sum, book) => sum + book.annotations.filter(a => a.type === 'bookmark').length, 0);
116
+ const totalNotes = books.reduce((sum, book) => sum + book.annotations.filter(a => a.type === 'note').length, 0);
117
+ let content = '---\n';
118
+ content += `title: "Apple Books Export"\n`;
119
+ content += `exported: "${new Date().toISOString()}"\n`;
120
+ content += `totalBooks: ${books.length}\n`;
121
+ content += `totalAnnotations: ${totalAnnotations}\n`;
122
+ content += `highlights: ${totalHighlights}\n`;
123
+ content += `bookmarks: ${totalBookmarks}\n`;
124
+ content += `notes: ${totalNotes}\n`;
125
+ content += '---\n\n';
126
+ content += `# Apple Books Export\n\n`;
127
+ content += `Exported ${totalAnnotations} annotations from ${books.length} books\n\n`;
128
+ content += '---\n\n';
129
+ // Add each book
130
+ for (const book of books) {
131
+ if (book.annotations.length === 0)
132
+ continue;
133
+ content += `# ${book.title || 'Unknown Book'}\n`;
134
+ if (book.author) {
135
+ content += `**by ${book.author}**\n`;
136
+ }
137
+ content += `\n*${book.annotations.length} annotations*\n`;
138
+ book.annotations.forEach((annotation, index) => {
139
+ content += formatAnnotation(annotation, index);
140
+ });
141
+ content += '\n\n';
142
+ }
143
+ writeFileSync(outputPath, content, 'utf-8');
144
+ return outputPath;
145
+ }
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,232 @@
1
+ #!/usr/bin/env node
2
+ import { findDatabases, queryAnnotations, groupByBook, filterAnnotations } from "./database.js";
3
+ import { exportToMarkdown, exportToSingleMarkdown } from "./exporters/markdown.js";
4
+ import { exportToJson } from "./exporters/json.js";
5
+ import { exportToCsv } from "./exporters/csv.js";
6
+ import { exportToHtml } from "./exporters/html.js";
7
+ function printHelp() {
8
+ console.log(`
9
+ Apple Books Export Tool
10
+ Export highlights, bookmarks, and notes from Apple Books
11
+
12
+ USAGE:
13
+ npx apple-books-export [FORMAT] [OPTIONS]
14
+ bunx apple-books-export [FORMAT] [OPTIONS] # Faster with Bun
15
+
16
+ FORMATS:
17
+ html Interactive HTML (default)
18
+ markdown Markdown files
19
+ json JSON export
20
+ csv CSV export
21
+
22
+ OPTIONS:
23
+ --output <path> Output file path
24
+ --single-file Export all books to a single file (markdown/json only)
25
+ --highlights-only Export only highlights
26
+ --bookmarks-only Export only bookmarks
27
+ --notes-only Export only notes
28
+ --include-bookmarks Include bookmarks (excluded by default)
29
+ --colors <colors> Filter by colors: yellow,green,blue,pink,purple,underline
30
+ --annotations-db <path> Custom annotations database path
31
+ --library-db <path> Custom library database path
32
+ --help Show this help message
33
+
34
+ EXAMPLES:
35
+ # Export to HTML (default)
36
+ npx apple-books-export
37
+ npx apple-books-export html
38
+
39
+ # Export to Markdown (one file per book)
40
+ npx apple-books-export markdown --output ./exports
41
+
42
+ # Export to single JSON file
43
+ npx apple-books-export json --output ./all.json --single-file
44
+
45
+ # Export only yellow and green highlights
46
+ npx apple-books-export html --highlights-only --colors yellow,green
47
+
48
+ # Include bookmarks in export
49
+ npx apple-books-export html --include-bookmarks
50
+ `);
51
+ }
52
+ function parseArgs() {
53
+ const args = process.argv.slice(2);
54
+ const options = {
55
+ format: 'html',
56
+ output: '',
57
+ singleFile: false,
58
+ highlightsOnly: false,
59
+ bookmarksOnly: false,
60
+ notesOnly: false,
61
+ includeBookmarks: false,
62
+ help: false,
63
+ };
64
+ // Check for positional format argument (first arg without --)
65
+ if (args.length > 0 && !args[0].startsWith('--')) {
66
+ const formatArg = args[0].toLowerCase();
67
+ if (['html', 'markdown', 'json', 'csv'].includes(formatArg)) {
68
+ options.format = formatArg;
69
+ args.shift(); // Remove the format argument
70
+ }
71
+ }
72
+ for (let i = 0; i < args.length; i++) {
73
+ const arg = args[i];
74
+ switch (arg) {
75
+ case '--help':
76
+ case '-h':
77
+ options.help = true;
78
+ break;
79
+ case '--format':
80
+ case '-f':
81
+ options.format = args[++i];
82
+ break;
83
+ case '--output':
84
+ case '-o':
85
+ options.output = args[++i];
86
+ break;
87
+ case '--single-file':
88
+ options.singleFile = true;
89
+ break;
90
+ case '--highlights-only':
91
+ options.highlightsOnly = true;
92
+ break;
93
+ case '--bookmarks-only':
94
+ options.bookmarksOnly = true;
95
+ break;
96
+ case '--notes-only':
97
+ options.notesOnly = true;
98
+ break;
99
+ case '--include-bookmarks':
100
+ options.includeBookmarks = true;
101
+ break;
102
+ case '--colors':
103
+ options.colors = args[++i].split(',');
104
+ break;
105
+ case '--annotations-db':
106
+ options.annotationsDb = args[++i];
107
+ break;
108
+ case '--library-db':
109
+ options.libraryDb = args[++i];
110
+ break;
111
+ }
112
+ }
113
+ // Set default output paths based on format if not specified
114
+ if (!options.output) {
115
+ switch (options.format) {
116
+ case 'html':
117
+ options.output = './apple-books-export.html';
118
+ break;
119
+ case 'json':
120
+ options.output = './apple-books-export.json';
121
+ break;
122
+ case 'csv':
123
+ options.output = './apple-books-export.csv';
124
+ break;
125
+ case 'markdown':
126
+ options.output = './exports';
127
+ break;
128
+ }
129
+ }
130
+ return options;
131
+ }
132
+ async function main() {
133
+ const options = parseArgs();
134
+ if (options.help) {
135
+ printHelp();
136
+ process.exit(0);
137
+ }
138
+ console.log('🍎 Apple Books Export Tool\n');
139
+ try {
140
+ // Find databases
141
+ console.log('📚 Finding Apple Books databases...');
142
+ const { annotationsDb, libraryDb } = findDatabases({
143
+ annotations: options.annotationsDb,
144
+ library: options.libraryDb,
145
+ });
146
+ console.log(` ✓ Annotations: ${annotationsDb}`);
147
+ console.log(` ✓ Library: ${libraryDb}\n`);
148
+ // Query annotations
149
+ console.log('🔍 Reading annotations...');
150
+ const rawAnnotations = await queryAnnotations(annotationsDb, libraryDb);
151
+ console.log(` ✓ Found ${rawAnnotations.length} annotations\n`);
152
+ // Group by book
153
+ console.log('📖 Grouping by book...');
154
+ const allBooks = groupByBook(rawAnnotations);
155
+ console.log(` ✓ Found ${allBooks.length} books\n`);
156
+ // Filter annotations based on options
157
+ const includeHighlights = !options.bookmarksOnly && !options.notesOnly;
158
+ const includeBookmarks = options.includeBookmarks || options.bookmarksOnly;
159
+ const includeNotes = !options.highlightsOnly && !options.bookmarksOnly;
160
+ const filteredBooks = allBooks.map(book => ({
161
+ ...book,
162
+ annotations: filterAnnotations(book.annotations, {
163
+ includeHighlights,
164
+ includeBookmarks,
165
+ includeNotes,
166
+ colorFilters: options.colors,
167
+ }),
168
+ })).filter(book => book.annotations.length > 0);
169
+ if (filteredBooks.length === 0) {
170
+ console.log('⚠️ No annotations match the specified filters');
171
+ process.exit(0);
172
+ }
173
+ const totalAnnotations = filteredBooks.reduce((sum, book) => sum + book.annotations.length, 0);
174
+ console.log(`📊 Export statistics:`);
175
+ console.log(` • Books: ${filteredBooks.length}`);
176
+ console.log(` • Annotations: ${totalAnnotations}`);
177
+ const highlights = filteredBooks.reduce((sum, book) => sum + book.annotations.filter(a => a.type === 'highlight').length, 0);
178
+ const bookmarks = filteredBooks.reduce((sum, book) => sum + book.annotations.filter(a => a.type === 'bookmark').length, 0);
179
+ const notes = filteredBooks.reduce((sum, book) => sum + book.annotations.filter(a => a.type === 'note').length, 0);
180
+ if (highlights > 0)
181
+ console.log(` - Highlights: ${highlights}`);
182
+ if (bookmarks > 0)
183
+ console.log(` - Bookmarks: ${bookmarks}`);
184
+ if (notes > 0)
185
+ console.log(` - Notes: ${notes}`);
186
+ const orphaned = allBooks.filter(book => !book.title).length;
187
+ if (orphaned > 0) {
188
+ console.log(` - Orphaned annotations: ${orphaned} books`);
189
+ }
190
+ console.log();
191
+ // Export
192
+ console.log(`💾 Exporting to ${options.format}...`);
193
+ let result;
194
+ switch (options.format) {
195
+ case 'html':
196
+ result = exportToHtml(filteredBooks, options.output);
197
+ console.log(` ✓ Exported to: ${result}`);
198
+ break;
199
+ case 'markdown':
200
+ if (options.singleFile) {
201
+ result = exportToSingleMarkdown(filteredBooks, options.output);
202
+ console.log(` ✓ Exported to: ${result}`);
203
+ }
204
+ else {
205
+ result = exportToMarkdown(filteredBooks, options.output);
206
+ console.log(` ✓ Exported ${result.length} files to: ${options.output}`);
207
+ }
208
+ break;
209
+ case 'json':
210
+ result = exportToJson(filteredBooks, options.output, options.singleFile);
211
+ if (Array.isArray(result)) {
212
+ console.log(` ✓ Exported ${result.length} files to: ${options.output}`);
213
+ }
214
+ else {
215
+ console.log(` ✓ Exported to: ${result}`);
216
+ }
217
+ break;
218
+ case 'csv':
219
+ result = exportToCsv(filteredBooks, options.output);
220
+ console.log(` ✓ Exported to: ${result}`);
221
+ break;
222
+ default:
223
+ throw new Error(`Unknown format: ${options.format}`);
224
+ }
225
+ console.log('\n✅ Export complete!\n');
226
+ }
227
+ catch (error) {
228
+ console.error('\n❌ Error:', error instanceof Error ? error.message : error);
229
+ process.exit(1);
230
+ }
231
+ }
232
+ main();
@@ -0,0 +1,56 @@
1
+ export type AnnotationType = 'highlight' | 'bookmark' | 'note';
2
+ export type AnnotationColor = 'yellow' | 'green' | 'blue' | 'pink' | 'purple' | 'underline';
3
+ export interface Annotation {
4
+ id: number;
5
+ type: AnnotationType;
6
+ color: AnnotationColor;
7
+ text: string | null;
8
+ note: string | null;
9
+ location: string | null;
10
+ chapter: string | null;
11
+ createdAt: Date;
12
+ modifiedAt: Date;
13
+ }
14
+ export interface Book {
15
+ assetId: string;
16
+ title: string | null;
17
+ author: string | null;
18
+ genre: string | null;
19
+ annotations: Annotation[];
20
+ }
21
+ export type ExportFormat = 'html' | 'markdown' | 'json' | 'csv';
22
+ export interface ExportOptions {
23
+ format: ExportFormat;
24
+ outputPath: string;
25
+ groupByBook: boolean;
26
+ includeBookmarks: boolean;
27
+ includeNotes: boolean;
28
+ includeHighlights: boolean;
29
+ colorFilters?: AnnotationColor[];
30
+ singleFile?: boolean;
31
+ annotationsDbPath?: string;
32
+ libraryDbPath?: string;
33
+ }
34
+ export interface RawAnnotation {
35
+ id: number;
36
+ assetId: string;
37
+ text: string | null;
38
+ note: string | null;
39
+ style: number;
40
+ location: string | null;
41
+ createdAt: number;
42
+ modifiedAt: number;
43
+ deleted: number;
44
+ title: string | null;
45
+ author: string | null;
46
+ genre: string | null;
47
+ }
48
+ export interface ExportStats {
49
+ totalBooks: number;
50
+ totalAnnotations: number;
51
+ highlights: number;
52
+ bookmarks: number;
53
+ notes: number;
54
+ orphaned: number;
55
+ }
56
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,CAAC;AAC/D,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE5F,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,EAAE,IAAI,CAAC;IAChB,UAAU,EAAE,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,IAAI;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,WAAW,EAAE,UAAU,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,KAAK,CAAC;AAEhE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,OAAO,CAAC;IACtB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB"}
package/dist/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "apple-books-export",
3
+ "version": "1.0.0",
4
+ "description": "Export highlights, bookmarks, and notes from Apple Books",
5
+ "type": "module",
6
+ "bin": {
7
+ "apple-books-export": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "scripts": {
17
+ "export": "bun run src/index.ts",
18
+ "dev": "bun run src/index.ts",
19
+ "build": "tsc",
20
+ "prepublishOnly": "npm run build",
21
+ "test:local": "npm run build && node ./dist/index.js --help",
22
+ "test:bun": "npm run build && bun ./dist/index.js --help"
23
+ },
24
+ "keywords": [
25
+ "apple-books",
26
+ "export",
27
+ "highlights",
28
+ "notes",
29
+ "bookmarks",
30
+ "cli"
31
+ ],
32
+ "author": "",
33
+ "license": "MIT",
34
+ "dependencies": {
35
+ "better-sqlite3": "^11.10.0"
36
+ },
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ },
40
+ "os": [
41
+ "darwin"
42
+ ],
43
+ "devDependencies": {
44
+ "@types/better-sqlite3": "^7.6.13",
45
+ "@types/bun": "latest",
46
+ "typescript": "^5.9.3"
47
+ }
48
+ }