apple-notes-mcp 2.5.7 → 2.5.8
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 +8 -5
- package/build/index.js +42669 -1077
- package/package.json +3 -3
- package/build/index.test.js +0 -446
- package/build/services/__fixtures__/notesNormalizedHtml.js +0 -32
- package/build/services/appleNotesManager.js +0 -2634
- package/build/services/appleNotesManager.test.js +0 -2416
- package/build/services/attachmentSave.test.js +0 -85
- package/build/services/fileConfig.js +0 -51
- package/build/services/fileConfig.test.js +0 -48
- package/build/services/notesHtmlMarkdown.test.js +0 -55
- package/build/tools/doctor.js +0 -50
- package/build/tools/doctor.test.js +0 -42
- package/build/tools/resourcesAndPrompts.js +0 -70
- package/build/tools/resourcesAndPrompts.test.js +0 -63
- package/build/types.js +0 -13
- package/build/utils/applescript.js +0 -421
- package/build/utils/applescript.test.js +0 -342
- package/build/utils/attachmentFs.js +0 -97
- package/build/utils/attachmentFs.test.js +0 -69
- package/build/utils/checklistParser.js +0 -259
- package/build/utils/checklistParser.test.js +0 -230
- package/build/utils/contentWarnings.js +0 -44
- package/build/utils/contentWarnings.test.js +0 -52
- package/build/utils/hashtags.js +0 -56
- package/build/utils/hashtags.test.js +0 -45
- package/build/utils/jxa.js +0 -139
- package/build/utils/jxa.test.js +0 -134
- package/build/utils/noteMetadata.js +0 -135
- package/build/utils/noteMetadata.test.js +0 -106
- package/build/utils/protobuf.js +0 -151
- package/build/utils/protobuf.test.js +0 -138
- package/build/utils/syncDetection.js +0 -242
- package/build/utils/syncDetection.test.js +0 -228
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for iCloud Sync Detection Utilities
|
|
3
|
-
*/
|
|
4
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
5
|
-
import { getSyncStatus, logSyncWarning, withSyncAwareness, withSyncAwarenessSync, isSyncActive, getSyncStatusSummary, clearSyncStatusCache, } from "./syncDetection.js";
|
|
6
|
-
// Mock child_process
|
|
7
|
-
vi.mock("child_process", () => ({
|
|
8
|
-
execFileSync: vi.fn(),
|
|
9
|
-
}));
|
|
10
|
-
// Mock fs
|
|
11
|
-
vi.mock("fs", () => ({
|
|
12
|
-
existsSync: vi.fn(),
|
|
13
|
-
statSync: vi.fn(),
|
|
14
|
-
}));
|
|
15
|
-
import { execFileSync } from "child_process";
|
|
16
|
-
import * as fs from "fs";
|
|
17
|
-
const mockExecSync = vi.mocked(execFileSync);
|
|
18
|
-
const mockExistsSync = vi.mocked(fs.existsSync);
|
|
19
|
-
const mockStatSync = vi.mocked(fs.statSync);
|
|
20
|
-
describe("getSyncStatus", () => {
|
|
21
|
-
beforeEach(() => {
|
|
22
|
-
vi.clearAllMocks();
|
|
23
|
-
clearSyncStatusCache(); // Clear cache between tests
|
|
24
|
-
});
|
|
25
|
-
it("returns error when database not found", () => {
|
|
26
|
-
mockExistsSync.mockReturnValue(false);
|
|
27
|
-
const status = getSyncStatus();
|
|
28
|
-
expect(status.error).toBe("Notes database not found");
|
|
29
|
-
expect(status.syncDetected).toBe(false);
|
|
30
|
-
});
|
|
31
|
-
it("detects no sync activity when idle", () => {
|
|
32
|
-
mockExistsSync.mockReturnValue(true);
|
|
33
|
-
mockStatSync.mockReturnValue({
|
|
34
|
-
mtimeMs: Date.now() - 60000, // 60 seconds ago
|
|
35
|
-
});
|
|
36
|
-
mockExecSync.mockReturnValue("0\n");
|
|
37
|
-
const status = getSyncStatus();
|
|
38
|
-
expect(status.syncDetected).toBe(false);
|
|
39
|
-
expect(status.pendingUpload).toBe(0);
|
|
40
|
-
expect(status.recentActivity).toBe(false);
|
|
41
|
-
expect(status.warning).toBeUndefined();
|
|
42
|
-
});
|
|
43
|
-
it("detects pending uploads", () => {
|
|
44
|
-
mockExistsSync.mockReturnValue(true);
|
|
45
|
-
mockStatSync.mockReturnValue({
|
|
46
|
-
mtimeMs: Date.now() - 60000,
|
|
47
|
-
});
|
|
48
|
-
mockExecSync.mockReturnValue("5\n");
|
|
49
|
-
const status = getSyncStatus();
|
|
50
|
-
expect(status.syncDetected).toBe(true);
|
|
51
|
-
expect(status.pendingUpload).toBe(5);
|
|
52
|
-
expect(status.warning).toContain("5 item(s) pending upload");
|
|
53
|
-
});
|
|
54
|
-
it("detects recent database activity", () => {
|
|
55
|
-
mockExistsSync.mockReturnValue(true);
|
|
56
|
-
mockStatSync.mockReturnValue({
|
|
57
|
-
mtimeMs: Date.now() - 2000, // 2 seconds ago
|
|
58
|
-
});
|
|
59
|
-
mockExecSync.mockReturnValue("0\n");
|
|
60
|
-
const status = getSyncStatus();
|
|
61
|
-
expect(status.syncDetected).toBe(true);
|
|
62
|
-
expect(status.recentActivity).toBe(true);
|
|
63
|
-
expect(status.secondsSinceLastChange).toBeLessThan(5);
|
|
64
|
-
expect(status.warning).toContain("database modified");
|
|
65
|
-
});
|
|
66
|
-
it("detects both pending uploads and recent activity", () => {
|
|
67
|
-
mockExistsSync.mockReturnValue(true);
|
|
68
|
-
mockStatSync.mockReturnValue({
|
|
69
|
-
mtimeMs: Date.now() - 1000,
|
|
70
|
-
});
|
|
71
|
-
mockExecSync.mockReturnValue("3\n");
|
|
72
|
-
const status = getSyncStatus();
|
|
73
|
-
expect(status.syncDetected).toBe(true);
|
|
74
|
-
expect(status.pendingUpload).toBe(3);
|
|
75
|
-
expect(status.recentActivity).toBe(true);
|
|
76
|
-
expect(status.warning).toContain("3 item(s) pending upload");
|
|
77
|
-
expect(status.warning).toContain("database modified");
|
|
78
|
-
});
|
|
79
|
-
it("handles sqlite3 errors gracefully", () => {
|
|
80
|
-
mockExistsSync.mockReturnValue(true);
|
|
81
|
-
mockStatSync.mockReturnValue({
|
|
82
|
-
mtimeMs: Date.now() - 60000,
|
|
83
|
-
});
|
|
84
|
-
mockExecSync.mockImplementation(() => {
|
|
85
|
-
throw new Error("database is locked");
|
|
86
|
-
});
|
|
87
|
-
const status = getSyncStatus();
|
|
88
|
-
expect(status.error).toContain("database is locked");
|
|
89
|
-
expect(status.syncDetected).toBe(false);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
describe("logSyncWarning", () => {
|
|
93
|
-
beforeEach(() => {
|
|
94
|
-
vi.spyOn(console, "error").mockImplementation(() => { });
|
|
95
|
-
});
|
|
96
|
-
afterEach(() => {
|
|
97
|
-
vi.restoreAllMocks();
|
|
98
|
-
});
|
|
99
|
-
it("logs warning when sync detected", () => {
|
|
100
|
-
const status = {
|
|
101
|
-
syncDetected: true,
|
|
102
|
-
pendingUpload: 2,
|
|
103
|
-
secondsSinceLastChange: 3,
|
|
104
|
-
recentActivity: true,
|
|
105
|
-
warning: "iCloud sync in progress",
|
|
106
|
-
};
|
|
107
|
-
logSyncWarning(status, "test-operation");
|
|
108
|
-
expect(console.error).toHaveBeenCalledWith(expect.stringContaining("[Sync Warning]"));
|
|
109
|
-
expect(console.error).toHaveBeenCalledWith(expect.stringContaining("test-operation"));
|
|
110
|
-
});
|
|
111
|
-
it("does not log when no warning", () => {
|
|
112
|
-
const status = {
|
|
113
|
-
syncDetected: false,
|
|
114
|
-
pendingUpload: 0,
|
|
115
|
-
secondsSinceLastChange: 60,
|
|
116
|
-
recentActivity: false,
|
|
117
|
-
};
|
|
118
|
-
logSyncWarning(status, "test-operation");
|
|
119
|
-
expect(console.error).not.toHaveBeenCalled();
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
describe("withSyncAwareness", () => {
|
|
123
|
-
beforeEach(() => {
|
|
124
|
-
vi.clearAllMocks();
|
|
125
|
-
clearSyncStatusCache();
|
|
126
|
-
vi.spyOn(console, "error").mockImplementation(() => { });
|
|
127
|
-
});
|
|
128
|
-
afterEach(() => {
|
|
129
|
-
vi.restoreAllMocks();
|
|
130
|
-
});
|
|
131
|
-
it("executes operation and returns result with sync info", async () => {
|
|
132
|
-
mockExistsSync.mockReturnValue(true);
|
|
133
|
-
mockStatSync.mockReturnValue({
|
|
134
|
-
mtimeMs: Date.now() - 60000,
|
|
135
|
-
});
|
|
136
|
-
mockExecSync.mockReturnValue("0\n");
|
|
137
|
-
const result = await withSyncAwareness("test", async () => "success");
|
|
138
|
-
expect(result.result).toBe("success");
|
|
139
|
-
expect(result.syncBefore).toBeDefined();
|
|
140
|
-
expect(result.syncAfter).toBeDefined();
|
|
141
|
-
expect(result.syncInterference).toBe(false);
|
|
142
|
-
});
|
|
143
|
-
it("detects sync interference when pending count changes", async () => {
|
|
144
|
-
mockExistsSync.mockReturnValue(true);
|
|
145
|
-
mockStatSync.mockReturnValue({
|
|
146
|
-
mtimeMs: Date.now() - 1000,
|
|
147
|
-
});
|
|
148
|
-
// First call: 5 pending, second call: 3 pending
|
|
149
|
-
mockExecSync.mockReturnValueOnce("5\n").mockReturnValueOnce("3\n");
|
|
150
|
-
const result = await withSyncAwareness("test", async () => "data");
|
|
151
|
-
expect(result.syncBefore.pendingUpload).toBe(5);
|
|
152
|
-
expect(result.syncAfter?.pendingUpload).toBe(3);
|
|
153
|
-
expect(result.syncInterference).toBe(true);
|
|
154
|
-
expect(result.interferenceWarning).toContain("sync activity detected");
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
describe("withSyncAwarenessSync", () => {
|
|
158
|
-
beforeEach(() => {
|
|
159
|
-
vi.clearAllMocks();
|
|
160
|
-
clearSyncStatusCache();
|
|
161
|
-
vi.spyOn(console, "error").mockImplementation(() => { });
|
|
162
|
-
});
|
|
163
|
-
afterEach(() => {
|
|
164
|
-
vi.restoreAllMocks();
|
|
165
|
-
});
|
|
166
|
-
it("executes sync operation with sync awareness", () => {
|
|
167
|
-
mockExistsSync.mockReturnValue(true);
|
|
168
|
-
mockStatSync.mockReturnValue({
|
|
169
|
-
mtimeMs: Date.now() - 60000,
|
|
170
|
-
});
|
|
171
|
-
mockExecSync.mockReturnValue("0\n");
|
|
172
|
-
const result = withSyncAwarenessSync("test", () => 42);
|
|
173
|
-
expect(result.result).toBe(42);
|
|
174
|
-
expect(result.syncBefore).toBeDefined();
|
|
175
|
-
expect(result.syncAfter).toBeDefined();
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
describe("isSyncActive", () => {
|
|
179
|
-
beforeEach(() => {
|
|
180
|
-
vi.clearAllMocks();
|
|
181
|
-
clearSyncStatusCache();
|
|
182
|
-
});
|
|
183
|
-
it("returns true when sync is active", () => {
|
|
184
|
-
mockExistsSync.mockReturnValue(true);
|
|
185
|
-
mockStatSync.mockReturnValue({
|
|
186
|
-
mtimeMs: Date.now() - 2000,
|
|
187
|
-
});
|
|
188
|
-
mockExecSync.mockReturnValue("0\n");
|
|
189
|
-
expect(isSyncActive()).toBe(true);
|
|
190
|
-
});
|
|
191
|
-
it("returns false when sync is idle", () => {
|
|
192
|
-
mockExistsSync.mockReturnValue(true);
|
|
193
|
-
mockStatSync.mockReturnValue({
|
|
194
|
-
mtimeMs: Date.now() - 60000,
|
|
195
|
-
});
|
|
196
|
-
mockExecSync.mockReturnValue("0\n");
|
|
197
|
-
expect(isSyncActive()).toBe(false);
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
describe("getSyncStatusSummary", () => {
|
|
201
|
-
beforeEach(() => {
|
|
202
|
-
vi.clearAllMocks();
|
|
203
|
-
clearSyncStatusCache();
|
|
204
|
-
});
|
|
205
|
-
it("returns idle message when no sync activity", () => {
|
|
206
|
-
mockExistsSync.mockReturnValue(true);
|
|
207
|
-
mockStatSync.mockReturnValue({
|
|
208
|
-
mtimeMs: Date.now() - 60000,
|
|
209
|
-
});
|
|
210
|
-
mockExecSync.mockReturnValue("0\n");
|
|
211
|
-
expect(getSyncStatusSummary()).toBe("iCloud sync: Idle");
|
|
212
|
-
});
|
|
213
|
-
it("returns active message with details", () => {
|
|
214
|
-
mockExistsSync.mockReturnValue(true);
|
|
215
|
-
mockStatSync.mockReturnValue({
|
|
216
|
-
mtimeMs: Date.now() - 2000,
|
|
217
|
-
});
|
|
218
|
-
mockExecSync.mockReturnValue("3\n");
|
|
219
|
-
const summary = getSyncStatusSummary();
|
|
220
|
-
expect(summary).toContain("iCloud sync: Active");
|
|
221
|
-
expect(summary).toContain("3 pending upload(s)");
|
|
222
|
-
});
|
|
223
|
-
it("returns error message when detection fails", () => {
|
|
224
|
-
mockExistsSync.mockReturnValue(false);
|
|
225
|
-
const summary = getSyncStatusSummary();
|
|
226
|
-
expect(summary).toContain("Sync status unknown");
|
|
227
|
-
});
|
|
228
|
-
});
|