onelibrary-connect 1.1.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,537 @@
1
+ /**
2
+ * OneLibrary Database Adapter
3
+ *
4
+ * Provides an interface for reading the OneLibrary (exportLibrary.db) SQLite database
5
+ * used by modern rekordbox versions and Pioneer DJ devices.
6
+ */
7
+ import { MyTagAttribute, PlaylistAttribute, } from './schema.js';
8
+ import { openOneLibraryDb } from './connection.js';
9
+ /**
10
+ * Adapter for OneLibrary database that matches the ORM interface.
11
+ * Queries the SQLite file directly instead of hydrating into memory.
12
+ */
13
+ export class OneLibraryAdapter {
14
+ type = 'oneLibrary';
15
+ #db;
16
+ #stmtCache = new Map();
17
+ constructor(dbPath) {
18
+ this.#db = openOneLibraryDb(dbPath);
19
+ }
20
+ /**
21
+ * Close the database connection
22
+ */
23
+ close() {
24
+ this.#stmtCache.clear();
25
+ this.#db.close();
26
+ }
27
+ /**
28
+ * Get or create a prepared statement (cached)
29
+ */
30
+ #getStmt(sql) {
31
+ let stmt = this.#stmtCache.get(sql);
32
+ if (!stmt) {
33
+ stmt = this.#db.prepare(sql);
34
+ this.#stmtCache.set(sql, stmt);
35
+ }
36
+ return stmt;
37
+ }
38
+ // ==========================================================================
39
+ // Track Queries
40
+ // ==========================================================================
41
+ /**
42
+ * Find a track by ID
43
+ */
44
+ findTrack(id) {
45
+ const row = this.#getStmt(`
46
+ SELECT c.*,
47
+ a.name as artistName,
48
+ al.name as albumName,
49
+ g.name as genreName,
50
+ k.name as keyName,
51
+ col.name as colorName,
52
+ lbl.name as labelName,
53
+ img.path as artworkPath,
54
+ remix.name as remixerName,
55
+ orig.name as originalArtistName,
56
+ comp.name as composerName
57
+ FROM content c
58
+ LEFT JOIN artist a ON c.artist_id_artist = a.artist_id
59
+ LEFT JOIN album al ON c.album_id = al.album_id
60
+ LEFT JOIN genre g ON c.genre_id = g.genre_id
61
+ LEFT JOIN key k ON c.key_id = k.key_id
62
+ LEFT JOIN color col ON c.color_id = col.color_id
63
+ LEFT JOIN label lbl ON c.label_id = lbl.label_id
64
+ LEFT JOIN image img ON c.image_id = img.image_id
65
+ LEFT JOIN artist remix ON c.artist_id_remixer = remix.artist_id
66
+ LEFT JOIN artist orig ON c.artist_id_originalArtist = orig.artist_id
67
+ LEFT JOIN artist comp ON c.artist_id_composer = comp.artist_id
68
+ WHERE c.content_id = ?
69
+ `).get(id);
70
+ if (!row) {
71
+ return null;
72
+ }
73
+ return this.#contentToTrack(row);
74
+ }
75
+ /**
76
+ * Find all tracks in the database
77
+ */
78
+ findAllTracks() {
79
+ const rows = this.#getStmt(`
80
+ SELECT c.*,
81
+ a.name as artistName,
82
+ al.name as albumName,
83
+ g.name as genreName,
84
+ k.name as keyName,
85
+ col.name as colorName,
86
+ lbl.name as labelName,
87
+ img.path as artworkPath,
88
+ remix.name as remixerName,
89
+ orig.name as originalArtistName,
90
+ comp.name as composerName
91
+ FROM content c
92
+ LEFT JOIN artist a ON c.artist_id_artist = a.artist_id
93
+ LEFT JOIN album al ON c.album_id = al.album_id
94
+ LEFT JOIN genre g ON c.genre_id = g.genre_id
95
+ LEFT JOIN key k ON c.key_id = k.key_id
96
+ LEFT JOIN color col ON c.color_id = col.color_id
97
+ LEFT JOIN label lbl ON c.label_id = lbl.label_id
98
+ LEFT JOIN image img ON c.image_id = img.image_id
99
+ LEFT JOIN artist remix ON c.artist_id_remixer = remix.artist_id
100
+ LEFT JOIN artist orig ON c.artist_id_originalArtist = orig.artist_id
101
+ LEFT JOIN artist comp ON c.artist_id_composer = comp.artist_id
102
+ `).all();
103
+ return rows.map(row => this.#contentToTrack(row));
104
+ }
105
+ /**
106
+ * Convert a content row to a Track entity
107
+ */
108
+ #contentToTrack(row) {
109
+ const track = {
110
+ id: row.content_id,
111
+ title: row.title ?? '',
112
+ duration: row.length ? row.length / 1000 : 0, // ms to seconds
113
+ bitrate: row.bitrate ?? undefined,
114
+ tempo: row.bpmx100 ? row.bpmx100 / 100 : 0,
115
+ rating: row.rating ?? 0,
116
+ comment: row.djComment ?? '',
117
+ filePath: row.path ?? '',
118
+ fileName: row.fileName ?? '',
119
+ trackNumber: row.trackNo ?? undefined,
120
+ discNumber: row.discNo ?? undefined,
121
+ sampleRate: row.samplingRate ?? undefined,
122
+ sampleDepth: row.bitDepth ?? undefined,
123
+ playCount: row.djPlayCount ?? undefined,
124
+ year: row.releaseYear ?? undefined,
125
+ mixName: row.subtitle ?? undefined,
126
+ autoloadHotcues: !!row.isHotCueAutoLoadOn,
127
+ kuvoPublic: !!row.isKuvoDeliverStatusOn,
128
+ fileSize: row.fileSize ?? undefined,
129
+ // Normalize analyzePath by trimming the .DAT extension (same as rekordbox.ts)
130
+ // loadAnlz() will append the appropriate extension (.DAT or .EXT) when loading
131
+ analyzePath: row.analysisDataFilePath
132
+ ? row.analysisDataFilePath.substring(0, row.analysisDataFilePath.length - 4)
133
+ : undefined,
134
+ releaseDate: row.releaseDate ?? undefined,
135
+ dateAdded: row.dateAdded ? new Date(row.dateAdded) : undefined,
136
+ cueAndLoops: null,
137
+ artwork: row.image_id
138
+ ? { id: row.image_id, path: row.artworkPath ?? undefined }
139
+ : null,
140
+ artist: row.artist_id_artist
141
+ ? { id: row.artist_id_artist, name: row.artistName ?? '' }
142
+ : null,
143
+ originalArtist: row.artist_id_originalArtist
144
+ ? {
145
+ id: row.artist_id_originalArtist,
146
+ name: row.originalArtistName ?? '',
147
+ }
148
+ : null,
149
+ remixer: row.artist_id_remixer
150
+ ? { id: row.artist_id_remixer, name: row.remixerName ?? '' }
151
+ : null,
152
+ composer: row.artist_id_composer
153
+ ? { id: row.artist_id_composer, name: row.composerName ?? '' }
154
+ : null,
155
+ album: row.album_id
156
+ ? { id: row.album_id, name: row.albumName ?? '' }
157
+ : null,
158
+ label: row.label_id
159
+ ? { id: row.label_id, name: row.labelName ?? '' }
160
+ : null,
161
+ genre: row.genre_id
162
+ ? { id: row.genre_id, name: row.genreName ?? '' }
163
+ : null,
164
+ color: row.color_id
165
+ ? { id: row.color_id, name: row.colorName ?? '' }
166
+ : null,
167
+ key: row.key_id ? { id: row.key_id, name: row.keyName ?? '' } : null,
168
+ };
169
+ return track;
170
+ }
171
+ // ==========================================================================
172
+ // Cue Queries
173
+ // ==========================================================================
174
+ /**
175
+ * Find cue points for a track
176
+ */
177
+ findCues(trackId) {
178
+ const rows = this.#getStmt(`
179
+ SELECT * FROM cue WHERE content_id = ?
180
+ `).all(trackId);
181
+ return rows.map(row => this.#cueToCueAndLoop(row));
182
+ }
183
+ /**
184
+ * Convert a cue row to a CueAndLoop entity
185
+ */
186
+ #cueToCueAndLoop(row) {
187
+ const offset = row.inUsec ? row.inUsec / 1000 : 0; // microseconds to ms
188
+ const outOffset = row.outUsec ?? null;
189
+ const isLoop = outOffset !== null && outOffset > 0;
190
+ const length = isLoop ? (outOffset - (row.inUsec ?? 0)) / 1000 : 0;
191
+ // Determine if this is a hot cue (kind value mapping may vary)
192
+ // Based on observation: kind 0 = memory cue, kind >= 1 may be hot cue
193
+ const isHotCue = (row.kind ?? 0) >= 1 && (row.kind ?? 0) <= 8;
194
+ const button = isHotCue ? (row.kind ?? 0) : undefined;
195
+ const label = row.cueComment ?? undefined;
196
+ const color = row.colorTableIndex;
197
+ if (isLoop && isHotCue) {
198
+ return {
199
+ type: 'hot_loop',
200
+ offset,
201
+ length,
202
+ button: button,
203
+ label,
204
+ color,
205
+ };
206
+ }
207
+ if (isLoop) {
208
+ return {
209
+ type: 'loop',
210
+ offset,
211
+ length,
212
+ label,
213
+ color,
214
+ };
215
+ }
216
+ if (isHotCue) {
217
+ return {
218
+ type: 'hot_cue',
219
+ offset,
220
+ button: button,
221
+ label,
222
+ color,
223
+ };
224
+ }
225
+ return {
226
+ type: 'cue_point',
227
+ offset,
228
+ label,
229
+ color,
230
+ };
231
+ }
232
+ // ==========================================================================
233
+ // Playlist Queries
234
+ // ==========================================================================
235
+ /**
236
+ * Find a playlist by ID
237
+ */
238
+ findPlaylistById(playlistId) {
239
+ const row = this.#getStmt(`
240
+ SELECT * FROM playlist WHERE playlist_id = ?
241
+ `).get(playlistId);
242
+ return row ? this.#playlistRowToPlaylist(row) : null;
243
+ }
244
+ /**
245
+ * Query for a list of {folders, playlists, tracks} given a playlist ID.
246
+ * If no ID is provided the root list is queried.
247
+ */
248
+ findPlaylist(playlistId) {
249
+ const parentCondition = playlistId === undefined ? 'playlist_id_parent IS NULL' : 'playlist_id_parent = ?';
250
+ // Lookup playlists / folders for this playlist ID
251
+ const playlistRows = (playlistId === undefined
252
+ ? this.#getStmt(`SELECT * FROM playlist WHERE ${parentCondition}`).all()
253
+ : this.#getStmt(`SELECT * FROM playlist WHERE ${parentCondition}`).all(playlistId));
254
+ const folders = [];
255
+ const playlists = [];
256
+ for (const row of playlistRows) {
257
+ const playlist = this.#playlistRowToPlaylist(row);
258
+ if (playlist.isFolder) {
259
+ folders.push(playlist);
260
+ }
261
+ else {
262
+ playlists.push(playlist);
263
+ }
264
+ }
265
+ // Get track entries for this playlist
266
+ const entryRows = playlistId === undefined
267
+ ? []
268
+ : this.#getStmt(`
269
+ SELECT * FROM playlist_content WHERE playlist_id = ? ORDER BY sequenceNo
270
+ `).all(playlistId);
271
+ const trackEntries = entryRows.map((row, index) => ({
272
+ id: index, // playlist_content doesn't have a unique ID, use index
273
+ sortIndex: row.sequenceNo,
274
+ playlistId: row.playlist_id,
275
+ trackId: row.content_id,
276
+ }));
277
+ return { folders, playlists, trackEntries };
278
+ }
279
+ /**
280
+ * Get track IDs for a playlist in order
281
+ */
282
+ findPlaylistContents(playlistId) {
283
+ const rows = this.#getStmt(`
284
+ SELECT content_id FROM playlist_content
285
+ WHERE playlist_id = ? ORDER BY sequenceNo
286
+ `).all(playlistId);
287
+ return rows.map(r => r.content_id);
288
+ }
289
+ /**
290
+ * Convert a playlist row to a Playlist entity
291
+ */
292
+ #playlistRowToPlaylist(row) {
293
+ return {
294
+ id: row.playlist_id,
295
+ name: row.name ?? '',
296
+ isFolder: row.attribute === PlaylistAttribute.FOLDER,
297
+ parentId: row.playlist_id_parent,
298
+ };
299
+ }
300
+ // ==========================================================================
301
+ // Reference Table Queries
302
+ // ==========================================================================
303
+ findArtist(artistId) {
304
+ const row = this.#getStmt(`
305
+ SELECT * FROM artist WHERE artist_id = ?
306
+ `).get(artistId);
307
+ return row ? { id: row.artist_id, name: row.name ?? '' } : null;
308
+ }
309
+ findAlbum(albumId) {
310
+ const row = this.#getStmt(`
311
+ SELECT * FROM album WHERE album_id = ?
312
+ `).get(albumId);
313
+ return row ? { id: row.album_id, name: row.name ?? '' } : null;
314
+ }
315
+ findGenre(genreId) {
316
+ const row = this.#getStmt(`
317
+ SELECT * FROM genre WHERE genre_id = ?
318
+ `).get(genreId);
319
+ return row ? { id: row.genre_id, name: row.name ?? '' } : null;
320
+ }
321
+ findKey(keyId) {
322
+ const row = this.#getStmt(`
323
+ SELECT * FROM key WHERE key_id = ?
324
+ `).get(keyId);
325
+ return row ? { id: row.key_id, name: row.name ?? '' } : null;
326
+ }
327
+ findColor(colorId) {
328
+ const row = this.#getStmt(`
329
+ SELECT * FROM color WHERE color_id = ?
330
+ `).get(colorId);
331
+ return row ? { id: row.color_id, name: row.name ?? '' } : null;
332
+ }
333
+ findLabel(labelId) {
334
+ const row = this.#getStmt(`
335
+ SELECT * FROM label WHERE label_id = ?
336
+ `).get(labelId);
337
+ return row ? { id: row.label_id, name: row.name ?? '' } : null;
338
+ }
339
+ findArtwork(imageId) {
340
+ const row = this.#getStmt(`
341
+ SELECT * FROM image WHERE image_id = ?
342
+ `).get(imageId);
343
+ return row ? { id: row.image_id, path: row.path ?? undefined } : null;
344
+ }
345
+ // ==========================================================================
346
+ // MyTag (User Tags) Queries
347
+ // ==========================================================================
348
+ /**
349
+ * Find all root-level MyTags (folders and tags with no parent)
350
+ */
351
+ findMyTags(parentId) {
352
+ const parentCondition = parentId === undefined
353
+ ? 'myTag_id_parent IS NULL OR myTag_id_parent = 0'
354
+ : 'myTag_id_parent = ?';
355
+ const rows = (parentId === undefined
356
+ ? this.#getStmt(`SELECT * FROM myTag WHERE ${parentCondition} ORDER BY sequenceNo`).all()
357
+ : this.#getStmt(`SELECT * FROM myTag WHERE ${parentCondition} ORDER BY sequenceNo`).all(parentId));
358
+ const folders = [];
359
+ const tags = [];
360
+ for (const row of rows) {
361
+ const tag = this.#myTagRowToMyTag(row);
362
+ if (tag.isFolder) {
363
+ folders.push(tag);
364
+ }
365
+ else {
366
+ tags.push(tag);
367
+ }
368
+ }
369
+ return { folders, tags };
370
+ }
371
+ /**
372
+ * Find a MyTag by ID
373
+ */
374
+ findMyTagById(myTagId) {
375
+ const row = this.#getStmt(`
376
+ SELECT * FROM myTag WHERE myTag_id = ?
377
+ `).get(myTagId);
378
+ return row ? this.#myTagRowToMyTag(row) : null;
379
+ }
380
+ /**
381
+ * Get track IDs for a MyTag
382
+ */
383
+ findMyTagContents(myTagId) {
384
+ const rows = this.#getStmt(`
385
+ SELECT content_id FROM myTag_content WHERE myTag_id = ?
386
+ `).all(myTagId);
387
+ return rows.map(r => r.content_id);
388
+ }
389
+ /**
390
+ * Get all MyTags assigned to a track
391
+ */
392
+ findMyTagsForTrack(trackId) {
393
+ const rows = this.#getStmt(`
394
+ SELECT t.* FROM myTag t
395
+ INNER JOIN myTag_content tc ON t.myTag_id = tc.myTag_id
396
+ WHERE tc.content_id = ?
397
+ `).all(trackId);
398
+ return rows.map(row => this.#myTagRowToMyTag(row));
399
+ }
400
+ #myTagRowToMyTag(row) {
401
+ return {
402
+ id: row.myTag_id,
403
+ name: row.name ?? '',
404
+ isFolder: row.attribute === MyTagAttribute.FOLDER,
405
+ parentId: row.myTag_id_parent,
406
+ };
407
+ }
408
+ // ==========================================================================
409
+ // History Queries
410
+ // ==========================================================================
411
+ /**
412
+ * Find all history sessions
413
+ */
414
+ findHistorySessions() {
415
+ const rows = this.#getStmt(`
416
+ SELECT * FROM history ORDER BY sequenceNo
417
+ `).all();
418
+ return rows.map(row => ({
419
+ id: row.history_id,
420
+ name: row.name ?? '',
421
+ parentId: row.history_id_parent,
422
+ }));
423
+ }
424
+ /**
425
+ * Get track IDs for a history session in order
426
+ */
427
+ findHistoryContents(historyId) {
428
+ const rows = this.#getStmt(`
429
+ SELECT content_id FROM history_content
430
+ WHERE history_id = ? ORDER BY sequenceNo
431
+ `).all(historyId);
432
+ return rows.map(r => r.content_id);
433
+ }
434
+ // ==========================================================================
435
+ // Hot Cue Bank Queries
436
+ // ==========================================================================
437
+ /**
438
+ * Find all hot cue bank lists
439
+ */
440
+ findHotCueBankLists() {
441
+ const rows = this.#getStmt(`
442
+ SELECT * FROM hotCueBankList ORDER BY sequenceNo
443
+ `).all();
444
+ return rows.map(row => ({
445
+ id: row.hotCueBankList_id,
446
+ name: row.name ?? '',
447
+ parentId: row.hotCueBankList_id_parent,
448
+ }));
449
+ }
450
+ /**
451
+ * Get cue IDs for a hot cue bank list
452
+ */
453
+ findHotCueBankListCues(bankListId) {
454
+ const rows = this.#getStmt(`
455
+ SELECT cue_id FROM hotCueBankList_cue
456
+ WHERE hotCueBankList_id = ? ORDER BY sequenceNo
457
+ `).all(bankListId);
458
+ return rows.map(r => r.cue_id);
459
+ }
460
+ // ==========================================================================
461
+ // Menu Configuration Queries
462
+ // ==========================================================================
463
+ /**
464
+ * Get all menu items (browse categories)
465
+ */
466
+ findMenuItems() {
467
+ const rows = this.#getStmt(`
468
+ SELECT * FROM menuItem ORDER BY menuItem_id
469
+ `).all();
470
+ return rows.map(row => ({
471
+ id: row.menuItem_id,
472
+ kind: row.kind ?? 0,
473
+ name: row.name ?? '',
474
+ }));
475
+ }
476
+ /**
477
+ * Get visible categories with their menu item info
478
+ */
479
+ findVisibleCategories() {
480
+ const rows = this.#getStmt(`
481
+ SELECT c.*, m.name as menuName, m.kind as menuKind
482
+ FROM category c
483
+ LEFT JOIN menuItem m ON c.menuItem_id = m.menuItem_id
484
+ WHERE c.isVisible = 1
485
+ ORDER BY c.sequenceNo
486
+ `).all();
487
+ return rows.map(row => ({
488
+ id: row.category_id,
489
+ menuItemId: row.menuItem_id ?? 0,
490
+ name: row.menuName ?? '',
491
+ kind: row.menuKind ?? 0,
492
+ isVisible: !!row.isVisible,
493
+ }));
494
+ }
495
+ /**
496
+ * Get visible sort options
497
+ */
498
+ findVisibleSortOptions() {
499
+ const rows = this.#getStmt(`
500
+ SELECT s.*, m.name as menuName, m.kind as menuKind
501
+ FROM sort s
502
+ LEFT JOIN menuItem m ON s.menuItem_id = m.menuItem_id
503
+ WHERE s.isVisible = 1
504
+ ORDER BY s.sequenceNo
505
+ `).all();
506
+ return rows.map(row => ({
507
+ id: row.sort_id,
508
+ menuItemId: row.menuItem_id ?? 0,
509
+ name: row.menuName ?? '',
510
+ kind: row.menuKind ?? 0,
511
+ isVisible: !!row.isVisible,
512
+ isSelectedAsSubColumn: !!row.isSelectedAsSubColumn,
513
+ }));
514
+ }
515
+ // ==========================================================================
516
+ // Device Property Queries
517
+ // ==========================================================================
518
+ /**
519
+ * Get device properties
520
+ */
521
+ getProperty() {
522
+ const row = this.#getStmt(`
523
+ SELECT * FROM property LIMIT 1
524
+ `).get();
525
+ if (!row) {
526
+ return null;
527
+ }
528
+ return {
529
+ deviceName: row.deviceName ?? '',
530
+ dbVersion: row.dbVersion ?? '',
531
+ numberOfContents: row.numberOfContents ?? 0,
532
+ createdDate: row.createdDate ?? '',
533
+ backgroundColorType: row.backGroundColorType ?? 0,
534
+ };
535
+ }
536
+ }
537
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../src/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * OneLibrary Database Connection
3
+ */
4
+ import Database from 'better-sqlite3-multiple-ciphers';
5
+ /**
6
+ * Open a OneLibrary database with SQLCipher decryption
7
+ */
8
+ export declare function openOneLibraryDb(dbPath: string): Database.Database;
9
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,QAAQ,MAAM,iCAAiC,CAAC;AAIvD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC,QAAQ,CASlE"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * OneLibrary Database Connection
3
+ */
4
+ import Database from 'better-sqlite3-multiple-ciphers';
5
+ import { getEncryptionKey } from './encryption.js';
6
+ /**
7
+ * Open a OneLibrary database with SQLCipher decryption
8
+ */
9
+ export function openOneLibraryDb(dbPath) {
10
+ const key = getEncryptionKey();
11
+ const db = new Database(dbPath, { readonly: true });
12
+ db.pragma('cipher = sqlcipher');
13
+ db.pragma('legacy = 4');
14
+ db.pragma(`key = '${key}'`);
15
+ return db;
16
+ }
17
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,QAAQ,MAAM,iCAAiC,CAAC;AAEvD,OAAO,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAC;AAEjD;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAC;IAE/B,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,EAAE,EAAC,QAAQ,EAAE,IAAI,EAAC,CAAC,CAAC;IAClD,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAChC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACxB,EAAE,CAAC,MAAM,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC;IAE5B,OAAO,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Common interface for database adapters.
3
+ *
4
+ * Both MetadataORM (for PDB files) and OneLibraryAdapter (for exportLibrary.db)
5
+ * implement this interface, allowing LocalDatabase to use either transparently.
6
+ */
7
+ import type { EntityFK, Playlist, PlaylistEntry, Track } from './entities.js';
8
+ /**
9
+ * Database format preference for loading rekordbox databases.
10
+ *
11
+ * - 'auto': Try OneLibrary first (rekordbox 7.x+), fall back to PDB (rekordbox 6.x)
12
+ * - 'oneLibrary': Only use OneLibrary format (exportLibrary.db)
13
+ * - 'pdb': Only use PDB format (export.pdb)
14
+ */
15
+ export type DatabasePreference = 'auto' | 'oneLibrary' | 'pdb';
16
+ /**
17
+ * Result of a playlist query
18
+ */
19
+ export interface PlaylistQueryResult {
20
+ folders: Playlist[];
21
+ playlists: Playlist[];
22
+ trackEntries: PlaylistEntry<EntityFK.WithFKs>[];
23
+ }
24
+ /**
25
+ * Database type identifier
26
+ */
27
+ export type DatabaseType = 'oneLibrary' | 'pdb';
28
+ /**
29
+ * Common interface for database adapters
30
+ */
31
+ export interface DatabaseAdapter {
32
+ /**
33
+ * The type of database (oneLibrary or pdb)
34
+ */
35
+ readonly type: DatabaseType;
36
+ /**
37
+ * Find a track by ID
38
+ */
39
+ findTrack(id: number): Track | null;
40
+ /**
41
+ * Query for a list of {folders, playlists, tracks} given a playlist ID.
42
+ * If no ID is provided the root list is queried.
43
+ */
44
+ findPlaylist(playlistId?: number): PlaylistQueryResult;
45
+ /**
46
+ * Close the database connection
47
+ */
48
+ close(): void;
49
+ }
50
+ //# sourceMappingURL=database-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-adapter.d.ts","sourceRoot":"","sources":["../src/database-adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAC,MAAM,eAAe,CAAC;AAE5E;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,YAAY,GAAG,KAAK,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;CACjD;AAED;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,YAAY,GAAG,KAAK,CAAC;AAEhD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAE5B;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAAC;IAEpC;;;OAGG;IACH,YAAY,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,mBAAmB,CAAC;IAEvD;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;CACf"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Common interface for database adapters.
3
+ *
4
+ * Both MetadataORM (for PDB files) and OneLibraryAdapter (for exportLibrary.db)
5
+ * implement this interface, allowing LocalDatabase to use either transparently.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=database-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-adapter.js","sourceRoot":"","sources":["../src/database-adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * OneLibrary Database Encryption
3
+ *
4
+ * The database is encrypted with SQLCipher 4. The encryption key is derived from
5
+ * a hardcoded obfuscated blob.
6
+ */
7
+ /**
8
+ * Get the SQLCipher encryption key for OneLibrary databases
9
+ */
10
+ export declare function getEncryptionKey(): string;
11
+ //# sourceMappingURL=encryption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../src/encryption.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAyEH;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAMzC"}