• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bandantonio / obsidian-apple-books-highlights-plugin / 21190337405

20 Jan 2026 10:55PM UTC coverage: 71.753%. Remained the same
21190337405

push

github

bandantonio
refactor: add debug timers

78 of 85 branches covered (91.76%)

Branch coverage included in aggregate %.

88 of 184 new or added lines in 8 files covered. (47.83%)

17 existing lines in 3 files now uncovered.

364 of 531 relevant lines covered (68.55%)

8.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.94
/src/saveHighlightsToVault.ts
1
import type { App, TFile } from 'obsidian';
1✔
2
import path from 'path';
3
import { DataService } from './services/dataService';
4
import { HighlightProcessingService } from './services/highlightProcessingService';
5
import { VaultService } from './services/vaultService';
6
import { defaultPluginSettings } from './settings';
7
import type { IBookHighlightsPluginSettings, ICombinedBooksAndHighlights, IRenderService } from './types';
8
import type { DiagnosticsCollector } from './utils/diagnostics';
9
import { Timer } from './utils/timing';
10

11
export default class SaveHighlights {
1✔
12
  private app: App;
13
  private settings: IBookHighlightsPluginSettings = defaultPluginSettings;
1✔
14
  private highlightProcessingService: HighlightProcessingService;
15
  private renderService: IRenderService;
16
  private vaultService: VaultService;
17
  private diagnosticsCollector?: DiagnosticsCollector;
18

19
  constructor(
1✔
20
    app: App,
11✔
21
    settings: IBookHighlightsPluginSettings,
11✔
22
    renderService: IRenderService,
11✔
23
    diagnosticsCollector?: DiagnosticsCollector,
11✔
24
  ) {
11✔
25
    this.app = app;
11✔
26
    this.settings = settings;
11✔
27
    this.diagnosticsCollector = diagnosticsCollector;
11✔
28
    this.highlightProcessingService = new HighlightProcessingService(new DataService(this.diagnosticsCollector), this.diagnosticsCollector);
11✔
29
    this.renderService = renderService;
11✔
30
    this.vaultService = new VaultService(this.app, this.settings, this.renderService, this.diagnosticsCollector);
11✔
31
  }
11✔
32

33
  async saveAllBooksHighlightsToVault(highlights: ICombinedBooksAndHighlights[]): Promise<void> {
1✔
34
    const cycleTimer = new Timer('Full Save Cycle (saveAllBooksHighlightsToVault)', this.diagnosticsCollector);
7✔
35
    cycleTimer.start();
7✔
36

37
    const highlightsFolder = this.vaultService.getHighlightsFolder();
7✔
38
    const doesHighlightsFolderExist = Boolean(highlightsFolder);
7✔
39

40
    const isBackupEnabled = this.settings.backup;
7✔
41

42
    if (doesHighlightsFolderExist) {
7✔
43
      if (isBackupEnabled) {
5✔
44
        await this.vaultService.backupAllHighlights(highlightsFolder);
1✔
45
      } else {
5✔
46
        await this.vaultService.recreateHighlightsFolder(highlightsFolder);
4✔
47
      }
4✔
48
    } else {
7✔
49
      await this.vaultService.createHighlightsFolder();
2✔
50
    }
2✔
51

52
    for (const combinedHighlight of highlights) {
7✔
53
      // Order highlights according to the value in settings
54
      const sortedHighlights = this.highlightProcessingService.sortHighlights(combinedHighlight, this.settings.highlightsSortingCriterion);
7✔
55

56
      // Render template for highlights and filename based on settings
57
      const renderedTemplate = this.renderService.renderTemplate(sortedHighlights, this.settings.template);
7✔
58
      const renderedFilenameTemplate = this.renderService.renderTemplate(sortedHighlights, this.settings.filenameTemplate);
7✔
59

60
      // Save highlights to vault
61
      const filePath = path.join(this.settings.highlightsFolder, `${renderedFilenameTemplate}.md`);
7✔
62

63
      await this.vaultService.createNewBookFile(filePath, renderedTemplate);
7✔
64
    }
7✔
65

66
    cycleTimer.end();
7✔
67

68
    // Write diagnostics to file if collector is available
69
    if (this.diagnosticsCollector) {
7!
NEW
70
      await this.diagnosticsCollector.writeDiagnosticsToFile();
×
NEW
71
    }
×
72
  }
7✔
73

74
  async saveSingleBookHighlightsToVault(highlights: ICombinedBooksAndHighlights[], shouldCreateFile: boolean): Promise<void> {
1✔
75
    const cycleTimer = new Timer('Full Save Cycle (saveSingleBookHighlightsToVault)', this.diagnosticsCollector);
4✔
76
    cycleTimer.start();
4✔
77

78
    const highlightsFolder = this.vaultService.getHighlightsFolder();
4✔
79
    const doesHighlightsFolderExist = Boolean(highlightsFolder);
4✔
80

81
    if (!doesHighlightsFolderExist) {
4✔
82
      await this.vaultService.createHighlightsFolder();
2✔
83
    }
2✔
84

85
    for (const combinedHighlight of highlights) {
4✔
86
      // Order highlights according to the value in settings
87
      const sortedHighlights = this.highlightProcessingService.sortHighlights(combinedHighlight, this.settings.highlightsSortingCriterion);
4✔
88

89
      // Render template for highlights and filename based on settings
90
      const renderedTemplate = this.renderService.renderTemplate(sortedHighlights, this.settings.template);
4✔
91
      const renderedFilenameTemplate = this.renderService.renderTemplate(sortedHighlights, this.settings.filenameTemplate);
4✔
92

93
      // Save highlights to vault
94
      const filePath = path.join(this.settings.highlightsFolder, `${renderedFilenameTemplate}.md`);
4✔
95

96
      if (shouldCreateFile) {
4✔
97
        await this.vaultService.createNewBookFile(filePath, renderedTemplate);
2✔
98
      } else {
2✔
99
        const isBackupEnabled = this.settings.backup;
2✔
100
        const vaultFile = this.vaultService.checkFileExistence(filePath) as TFile;
2✔
101

102
        if (isBackupEnabled) {
2✔
103
          await this.vaultService.backupSingleBookHighlights(renderedFilenameTemplate);
1✔
104
        }
1✔
105

106
        await this.vaultService.modifyExistingBookFile(vaultFile, renderedTemplate);
2✔
107
      }
2✔
108
    }
4✔
109

110
    cycleTimer.end();
4✔
111

112
    // Write diagnostics to file if collector is available
113
    if (this.diagnosticsCollector) {
4!
NEW
114
      await this.diagnosticsCollector.writeDiagnosticsToFile();
×
NEW
115
    }
×
116
  }
4✔
117
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc