kaimon-cli 0.1.43 → 0.1.44

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.
Files changed (59) hide show
  1. package/dist/__tests__/commands/pull.test.d.ts +2 -0
  2. package/dist/__tests__/commands/pull.test.d.ts.map +1 -0
  3. package/dist/__tests__/commands/pull.test.js +182 -0
  4. package/dist/__tests__/commands/pull.test.js.map +1 -0
  5. package/dist/__tests__/commands/push.test.d.ts +2 -0
  6. package/dist/__tests__/commands/push.test.d.ts.map +1 -0
  7. package/dist/__tests__/commands/push.test.js +255 -0
  8. package/dist/__tests__/commands/push.test.js.map +1 -0
  9. package/dist/__tests__/helpers.d.ts +49 -0
  10. package/dist/__tests__/helpers.d.ts.map +1 -0
  11. package/dist/__tests__/helpers.js +151 -0
  12. package/dist/__tests__/helpers.js.map +1 -0
  13. package/dist/__tests__/integration/full-workflow.test.d.ts +2 -0
  14. package/dist/__tests__/integration/full-workflow.test.d.ts.map +1 -0
  15. package/dist/__tests__/integration/full-workflow.test.js +213 -0
  16. package/dist/__tests__/integration/full-workflow.test.js.map +1 -0
  17. package/dist/__tests__/setup.d.ts +2 -0
  18. package/dist/__tests__/setup.d.ts.map +1 -0
  19. package/dist/__tests__/setup.js +24 -0
  20. package/dist/__tests__/setup.js.map +1 -0
  21. package/dist/__tests__/unit/utils/config.test.d.ts +2 -0
  22. package/dist/__tests__/unit/utils/config.test.d.ts.map +1 -0
  23. package/dist/__tests__/unit/utils/config.test.js +171 -0
  24. package/dist/__tests__/unit/utils/config.test.js.map +1 -0
  25. package/dist/__tests__/unit/utils/frontmatter.test.d.ts +2 -0
  26. package/dist/__tests__/unit/utils/frontmatter.test.d.ts.map +1 -0
  27. package/dist/__tests__/unit/utils/frontmatter.test.js +231 -0
  28. package/dist/__tests__/unit/utils/frontmatter.test.js.map +1 -0
  29. package/dist/__tests__/unit/utils/markdown.test.d.ts +2 -0
  30. package/dist/__tests__/unit/utils/markdown.test.d.ts.map +1 -0
  31. package/dist/__tests__/unit/utils/markdown.test.js +296 -0
  32. package/dist/__tests__/unit/utils/markdown.test.js.map +1 -0
  33. package/dist/__tests__/unit/utils/projectConfig.test.d.ts +2 -0
  34. package/dist/__tests__/unit/utils/projectConfig.test.d.ts.map +1 -0
  35. package/dist/__tests__/unit/utils/projectConfig.test.js +160 -0
  36. package/dist/__tests__/unit/utils/projectConfig.test.js.map +1 -0
  37. package/dist/__tests__/unit/utils/requireAuth.test.d.ts +2 -0
  38. package/dist/__tests__/unit/utils/requireAuth.test.d.ts.map +1 -0
  39. package/dist/__tests__/unit/utils/requireAuth.test.js +96 -0
  40. package/dist/__tests__/unit/utils/requireAuth.test.js.map +1 -0
  41. package/dist/__tests__/unit/utils/tokenRefresh.test.d.ts +2 -0
  42. package/dist/__tests__/unit/utils/tokenRefresh.test.d.ts.map +1 -0
  43. package/dist/__tests__/unit/utils/tokenRefresh.test.js +170 -0
  44. package/dist/__tests__/unit/utils/tokenRefresh.test.js.map +1 -0
  45. package/dist/__tests__/unit/utils/versionCheck.test.d.ts +2 -0
  46. package/dist/__tests__/unit/utils/versionCheck.test.d.ts.map +1 -0
  47. package/dist/__tests__/unit/utils/versionCheck.test.js +105 -0
  48. package/dist/__tests__/unit/utils/versionCheck.test.js.map +1 -0
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +9 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/utils/projectConfig.d.ts.map +1 -1
  53. package/dist/utils/projectConfig.js +9 -1
  54. package/dist/utils/projectConfig.js.map +1 -1
  55. package/dist/utils/versionCheck.d.ts +6 -0
  56. package/dist/utils/versionCheck.d.ts.map +1 -0
  57. package/dist/utils/versionCheck.js +61 -0
  58. package/dist/utils/versionCheck.js.map +1 -0
  59. package/package.json +2 -1
@@ -0,0 +1,151 @@
1
+ import { vi } from 'vitest';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ /**
6
+ * Test helpers for mocking and utilities
7
+ */
8
+ // Mock Supabase client
9
+ export function createMockSupabaseClient() {
10
+ return {
11
+ auth: {
12
+ getUser: vi.fn().mockResolvedValue({
13
+ data: { user: { id: 'test-user-id', email: 'test@example.com' } },
14
+ error: null
15
+ }),
16
+ refreshSession: vi.fn().mockResolvedValue({
17
+ data: {
18
+ session: {
19
+ access_token: 'new-access-token',
20
+ refresh_token: 'new-refresh-token',
21
+ expires_in: 3600
22
+ }
23
+ },
24
+ error: null
25
+ })
26
+ },
27
+ from: vi.fn().mockReturnValue({
28
+ select: vi.fn().mockReturnThis(),
29
+ insert: vi.fn().mockReturnThis(),
30
+ update: vi.fn().mockReturnThis(),
31
+ eq: vi.fn().mockReturnThis(),
32
+ in: vi.fn().mockReturnThis(),
33
+ order: vi.fn().mockReturnThis(),
34
+ single: vi.fn().mockResolvedValue({ data: null, error: null })
35
+ }),
36
+ storage: {
37
+ from: vi.fn().mockReturnValue({
38
+ download: vi.fn().mockResolvedValue({ data: null, error: null }),
39
+ upload: vi.fn().mockResolvedValue({ data: null, error: null })
40
+ })
41
+ }
42
+ };
43
+ }
44
+ // Mock BlockNote document content
45
+ export function mockBlockNoteContent(title = 'Test Document') {
46
+ return {
47
+ type: 'blocknote',
48
+ content: [
49
+ {
50
+ type: 'heading',
51
+ props: { level: 1 },
52
+ content: [{ type: 'text', text: title }]
53
+ },
54
+ {
55
+ type: 'paragraph',
56
+ content: [{ type: 'text', text: 'This is a test document.' }]
57
+ },
58
+ {
59
+ type: 'bulletListItem',
60
+ content: [{ type: 'text', text: 'First item' }]
61
+ },
62
+ {
63
+ type: 'bulletListItem',
64
+ content: [{ type: 'text', text: 'Second item' }]
65
+ }
66
+ ]
67
+ };
68
+ }
69
+ // Mock document record
70
+ export function mockDocumentRecord(overrides = {}) {
71
+ return {
72
+ id: 'doc-123',
73
+ user_id: 'user-456',
74
+ title: 'Test Document',
75
+ created_at: '2024-01-01T00:00:00Z',
76
+ updated_at: '2024-01-02T00:00:00Z',
77
+ ...overrides
78
+ };
79
+ }
80
+ // Create temporary directory for testing
81
+ export function createTempDir(prefix = 'kaimon-test-') {
82
+ return fs.mkdtempSync(path.join(os.tmpdir(), prefix));
83
+ }
84
+ // Cleanup temporary directory
85
+ export function cleanupTempDir(dirPath) {
86
+ if (fs.existsSync(dirPath)) {
87
+ fs.rmSync(dirPath, { recursive: true, force: true });
88
+ }
89
+ }
90
+ // Mock config data
91
+ export function mockConfig(overrides = {}) {
92
+ return {
93
+ access_token: 'test-access-token',
94
+ refresh_token: 'test-refresh-token',
95
+ expires_at: new Date(Date.now() + 3600000).toISOString(), // 1 hour from now
96
+ user_email: 'test@example.com',
97
+ ...overrides
98
+ };
99
+ }
100
+ // Mock project config
101
+ export function mockProjectConfig(overrides = {}) {
102
+ return {
103
+ version: '1.0.0',
104
+ user_id: 'test@example.com',
105
+ sync_patterns: {
106
+ include: ['**/*.md'],
107
+ exclude: ['node_modules/**', '.git/**']
108
+ },
109
+ ...overrides
110
+ };
111
+ }
112
+ // Create a mock markdown file with frontmatter
113
+ export function createMockMarkdownFile(dirPath, filename, content, frontmatter = {}) {
114
+ const filePath = path.join(dirPath, filename);
115
+ const frontmatterStr = Object.keys(frontmatter).length > 0
116
+ ? `---\n${Object.entries(frontmatter)
117
+ .map(([key, value]) => `${key}: "${value}"`)
118
+ .join('\n')}\n---\n\n`
119
+ : '';
120
+ const fullContent = `${frontmatterStr}${content}`;
121
+ fs.writeFileSync(filePath, fullContent, 'utf-8');
122
+ return filePath;
123
+ }
124
+ // Mock readline for interactive prompts
125
+ export function mockReadline(answers) {
126
+ let currentAnswer = 0;
127
+ return {
128
+ createInterface: vi.fn().mockReturnValue({
129
+ question: vi.fn((prompt, callback) => {
130
+ callback(answers[currentAnswer++] || '');
131
+ }),
132
+ on: vi.fn(),
133
+ close: vi.fn()
134
+ })
135
+ };
136
+ }
137
+ // Mock stdin for password input
138
+ export function mockStdin(input) {
139
+ const mockStdin = {
140
+ on: vi.fn((event, handler) => {
141
+ if (event === 'line') {
142
+ process.nextTick(() => handler(input));
143
+ }
144
+ }),
145
+ setRawMode: vi.fn(),
146
+ resume: vi.fn(),
147
+ pause: vi.fn()
148
+ };
149
+ return mockStdin;
150
+ }
151
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/__tests__/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=full-workflow.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"full-workflow.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/integration/full-workflow.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,213 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { pullDocuments } from '../../utils/syncOperations.js';
6
+ import { pushDocuments } from '../../utils/pushOperations.js';
7
+ import * as config from '../../utils/config.js';
8
+ import * as supabaseClient from '../../utils/supabaseClient.js';
9
+ import * as tokenRefresh from '../../utils/tokenRefresh.js';
10
+ import { createTempDir, cleanupTempDir, mockConfig, mockDocumentRecord, mockBlockNoteContent, createMockSupabaseClient } from '../helpers.js';
11
+ describe('Full Workflow Integration Tests', () => {
12
+ let tempDir;
13
+ let docsDir;
14
+ beforeEach(() => {
15
+ tempDir = createTempDir();
16
+ docsDir = path.join(tempDir, 'KaimonDocs');
17
+ vi.spyOn(os, 'homedir').mockReturnValue(tempDir);
18
+ vi.spyOn(process, 'cwd').mockReturnValue(tempDir);
19
+ });
20
+ afterEach(() => {
21
+ cleanupTempDir(tempDir);
22
+ vi.restoreAllMocks();
23
+ });
24
+ describe('Pull → Modify → Push workflow', () => {
25
+ it('should complete full round-trip successfully', async () => {
26
+ config.saveConfig(mockConfig());
27
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
28
+ const mockSupabase = createMockSupabaseClient();
29
+ // STEP 1: Pull document
30
+ const originalDoc = mockDocumentRecord({
31
+ id: 'doc-123',
32
+ title: 'Test Document',
33
+ updated_at: new Date('2024-01-01T00:00:00Z').toISOString()
34
+ });
35
+ mockSupabase.from.mockReturnValue({
36
+ select: vi.fn().mockReturnThis(),
37
+ order: vi.fn().mockResolvedValue({ data: [originalDoc], error: null }),
38
+ in: vi.fn().mockResolvedValue({ data: [originalDoc], error: null }),
39
+ update: vi.fn().mockReturnThis(),
40
+ eq: vi.fn().mockResolvedValue({ error: null })
41
+ });
42
+ const mockContent = mockBlockNoteContent('Test Document');
43
+ const blob = new Blob([JSON.stringify(mockContent)], { type: 'application/json' });
44
+ mockSupabase.storage.from.mockReturnValue({
45
+ download: vi.fn().mockResolvedValue({ data: blob, error: null }),
46
+ upload: vi.fn().mockResolvedValue({ data: {}, error: null })
47
+ });
48
+ mockSupabase.auth.getUser.mockResolvedValue({
49
+ data: { user: { id: 'user-123' } },
50
+ error: null
51
+ });
52
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
53
+ await pullDocuments(false, true);
54
+ // Verify file was created
55
+ const files = fs.readdirSync(docsDir);
56
+ expect(files).toHaveLength(1);
57
+ const filePath = path.join(docsDir, files[0]);
58
+ // STEP 2: Modify the file
59
+ let content = fs.readFileSync(filePath, 'utf-8');
60
+ expect(content).toContain('kaimon_id: "doc-123"');
61
+ content = content.replace('This is a test document.', 'This is MODIFIED content.');
62
+ fs.writeFileSync(filePath, content, 'utf-8');
63
+ // Update mtime to be newer than remote
64
+ const newTime = new Date();
65
+ fs.utimesSync(filePath, newTime, newTime);
66
+ // STEP 3: Push changes back
67
+ await pushDocuments({ skipConfirmation: true });
68
+ // Verify upload was called
69
+ expect(mockSupabase.storage.from().upload).toHaveBeenCalled();
70
+ // Verify the uploaded content contains modifications
71
+ const uploadCall = mockSupabase.storage.from().upload.mock.calls[0];
72
+ const uploadedBlob = uploadCall[1];
73
+ const uploadedText = await uploadedBlob.text();
74
+ const uploadedData = JSON.parse(uploadedText);
75
+ expect(uploadedData.type).toBe('blocknote');
76
+ expect(Array.isArray(uploadedData.content)).toBe(true);
77
+ });
78
+ it('should not re-pull unchanged documents', async () => {
79
+ config.saveConfig(mockConfig());
80
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
81
+ const mockSupabase = createMockSupabaseClient();
82
+ const doc = mockDocumentRecord({
83
+ id: 'doc-123',
84
+ updated_at: new Date('2024-01-01T00:00:00Z').toISOString()
85
+ });
86
+ mockSupabase.from.mockReturnValue({
87
+ select: vi.fn().mockReturnThis(),
88
+ order: vi.fn().mockResolvedValue({ data: [doc], error: null })
89
+ });
90
+ const mockContent = mockBlockNoteContent();
91
+ const blob = new Blob([JSON.stringify(mockContent)], { type: 'application/json' });
92
+ const downloadSpy = vi.fn().mockResolvedValue({ data: blob, error: null });
93
+ mockSupabase.storage.from.mockReturnValue({
94
+ download: downloadSpy
95
+ });
96
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
97
+ // First pull
98
+ await pullDocuments(false, true);
99
+ expect(downloadSpy).toHaveBeenCalledTimes(1);
100
+ // Second pull (same data)
101
+ downloadSpy.mockClear();
102
+ await pullDocuments(false, true);
103
+ // Should not download again (file is up to date)
104
+ expect(downloadSpy).not.toHaveBeenCalled();
105
+ });
106
+ });
107
+ describe('Content integrity', () => {
108
+ it('should preserve markdown structure through round-trip', async () => {
109
+ config.saveConfig(mockConfig());
110
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
111
+ const mockSupabase = createMockSupabaseClient();
112
+ const doc = mockDocumentRecord();
113
+ // Complex BlockNote content
114
+ const complexContent = {
115
+ type: 'blocknote',
116
+ content: [
117
+ { type: 'heading', props: { level: 1 }, content: [{ type: 'text', text: 'Main Title' }] },
118
+ { type: 'paragraph', content: [
119
+ { type: 'text', text: 'Text with ' },
120
+ { type: 'text', text: 'bold', styles: { bold: true } },
121
+ { type: 'text', text: ' and ' },
122
+ { type: 'text', text: 'italic', styles: { italic: true } }
123
+ ] },
124
+ { type: 'bulletListItem', content: [{ type: 'text', text: 'Item 1' }] },
125
+ { type: 'bulletListItem', content: [{ type: 'text', text: 'Item 2' }] },
126
+ { type: 'codeBlock', props: { language: 'javascript' }, content: [{ type: 'text', text: 'const x = 42;' }] }
127
+ ]
128
+ };
129
+ mockSupabase.from.mockReturnValue({
130
+ select: vi.fn().mockReturnThis(),
131
+ order: vi.fn().mockResolvedValue({ data: [doc], error: null })
132
+ });
133
+ const blob = new Blob([JSON.stringify(complexContent)], { type: 'application/json' });
134
+ mockSupabase.storage.from.mockReturnValue({
135
+ download: vi.fn().mockResolvedValue({ data: blob, error: null })
136
+ });
137
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
138
+ await pullDocuments(false, true);
139
+ const files = fs.readdirSync(docsDir);
140
+ const content = fs.readFileSync(path.join(docsDir, files[0]), 'utf-8');
141
+ // Verify structure is preserved
142
+ expect(content).toContain('# Main Title');
143
+ expect(content).toContain('**bold**');
144
+ expect(content).toContain('*italic*');
145
+ expect(content).toContain('- Item 1');
146
+ expect(content).toContain('- Item 2');
147
+ expect(content).toContain('```javascript');
148
+ expect(content).toContain('const x = 42;');
149
+ });
150
+ it('should preserve frontmatter fields', async () => {
151
+ config.saveConfig(mockConfig());
152
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
153
+ const mockSupabase = createMockSupabaseClient();
154
+ const doc = mockDocumentRecord({
155
+ id: 'doc-123',
156
+ title: 'Test Document',
157
+ created_at: '2024-01-01T00:00:00Z',
158
+ updated_at: '2024-01-02T00:00:00Z'
159
+ });
160
+ mockSupabase.from.mockReturnValue({
161
+ select: vi.fn().mockReturnThis(),
162
+ order: vi.fn().mockResolvedValue({ data: [doc], error: null })
163
+ });
164
+ const mockContent = mockBlockNoteContent();
165
+ const blob = new Blob([JSON.stringify(mockContent)], { type: 'application/json' });
166
+ mockSupabase.storage.from.mockReturnValue({
167
+ download: vi.fn().mockResolvedValue({ data: blob, error: null })
168
+ });
169
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
170
+ await pullDocuments(false, true);
171
+ const files = fs.readdirSync(docsDir);
172
+ const content = fs.readFileSync(path.join(docsDir, files[0]), 'utf-8');
173
+ expect(content).toContain('title: "Test Document"');
174
+ expect(content).toContain('kaimon_id: "doc-123"');
175
+ expect(content).toContain('created_at: "2024-01-01T00:00:00Z"');
176
+ expect(content).toContain('updated_at: "2024-01-02T00:00:00Z"');
177
+ });
178
+ });
179
+ describe('Error recovery', () => {
180
+ it('should handle partial failures gracefully', async () => {
181
+ config.saveConfig(mockConfig());
182
+ vi.spyOn(tokenRefresh, 'ensureValidToken').mockResolvedValue(true);
183
+ const mockSupabase = createMockSupabaseClient();
184
+ const docs = [
185
+ mockDocumentRecord({ id: 'doc-1', title: 'Doc 1' }),
186
+ mockDocumentRecord({ id: 'doc-2', title: 'Doc 2' }),
187
+ mockDocumentRecord({ id: 'doc-3', title: 'Doc 3' })
188
+ ];
189
+ mockSupabase.from.mockReturnValue({
190
+ select: vi.fn().mockReturnThis(),
191
+ order: vi.fn().mockResolvedValue({ data: docs, error: null })
192
+ });
193
+ const blob = new Blob([JSON.stringify(mockBlockNoteContent())], { type: 'application/json' });
194
+ let callCount = 0;
195
+ mockSupabase.storage.from.mockReturnValue({
196
+ download: vi.fn().mockImplementation(() => {
197
+ callCount++;
198
+ if (callCount === 2) {
199
+ // Fail on second document
200
+ return Promise.resolve({ data: null, error: { message: 'Download failed' } });
201
+ }
202
+ return Promise.resolve({ data: blob, error: null });
203
+ })
204
+ });
205
+ vi.spyOn(supabaseClient, 'getSupabaseClient').mockReturnValue(mockSupabase);
206
+ await pullDocuments(false, true);
207
+ // Should have created files for successful downloads
208
+ const files = fs.readdirSync(docsDir);
209
+ expect(files.length).toBe(2); // 2 successful, 1 failed
210
+ });
211
+ });
212
+ });
213
+ //# sourceMappingURL=full-workflow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"full-workflow.test.js","sourceRoot":"","sources":["../../../src/__tests__/integration/full-workflow.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":""}
@@ -0,0 +1,24 @@
1
+ import { vi, afterEach, afterAll } from 'vitest';
2
+ // Mock environment variables
3
+ process.env.NODE_ENV = 'test';
4
+ // Suppress console output during tests (unless debugging)
5
+ global.console = {
6
+ ...console,
7
+ log: vi.fn(),
8
+ error: vi.fn(),
9
+ warn: vi.fn(),
10
+ info: vi.fn(),
11
+ debug: vi.fn()
12
+ };
13
+ // Mock process.exit to prevent tests from exiting
14
+ const originalExit = process.exit;
15
+ process.exit = vi.fn();
16
+ // Cleanup after each test
17
+ afterEach(() => {
18
+ vi.clearAllMocks();
19
+ });
20
+ // Restore process.exit after all tests
21
+ afterAll(() => {
22
+ process.exit = originalExit;
23
+ });
24
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/__tests__/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAEjD,6BAA6B;AAC7B,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC;AAE9B,0DAA0D;AAC1D,MAAM,CAAC,OAAO,GAAG;IACf,GAAG,OAAO;IACV,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE;IACZ,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;IACd,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;IACb,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;IACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;CACf,CAAC;AAEF,kDAAkD;AAClD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;AAClC,OAAO,CAAC,IAAI,GAAG,EAAE,CAAC,EAAE,EAAS,CAAC;AAE9B,0BAA0B;AAC1B,SAAS,CAAC,GAAG,EAAE;IACb,EAAE,CAAC,aAAa,EAAE,CAAC;AACrB,CAAC,CAAC,CAAC;AAEH,uCAAuC;AACvC,QAAQ,CAAC,GAAG,EAAE;IACZ,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC;AAC9B,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/unit/utils/config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,171 @@
1
+ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import os from 'os';
5
+ import { getConfigDir, getConfigPath, ensureConfigDir, loadConfig, saveConfig, clearConfig, isAuthenticated, getAccessToken } from '../../../utils/config.js';
6
+ import { createTempDir, cleanupTempDir, mockConfig } from '../../helpers.js';
7
+ describe('config.ts', () => {
8
+ let tempDir;
9
+ let originalHome;
10
+ beforeEach(() => {
11
+ tempDir = createTempDir();
12
+ originalHome = process.env.HOME;
13
+ // Mock home directory
14
+ vi.spyOn(os, 'homedir').mockReturnValue(tempDir);
15
+ });
16
+ afterEach(() => {
17
+ cleanupTempDir(tempDir);
18
+ if (originalHome !== undefined) {
19
+ process.env.HOME = originalHome;
20
+ }
21
+ vi.restoreAllMocks();
22
+ });
23
+ describe('getConfigDir', () => {
24
+ it('should return correct config directory path', () => {
25
+ const configDir = getConfigDir();
26
+ expect(configDir).toBe(path.join(tempDir, '.kaimon'));
27
+ });
28
+ });
29
+ describe('getConfigPath', () => {
30
+ it('should return correct config file path', () => {
31
+ const configPath = getConfigPath();
32
+ expect(configPath).toBe(path.join(tempDir, '.kaimon', 'config.json'));
33
+ });
34
+ });
35
+ describe('ensureConfigDir', () => {
36
+ it('should create config directory if it does not exist', () => {
37
+ const configDir = getConfigDir();
38
+ expect(fs.existsSync(configDir)).toBe(false);
39
+ ensureConfigDir();
40
+ expect(fs.existsSync(configDir)).toBe(true);
41
+ const stats = fs.statSync(configDir);
42
+ expect(stats.isDirectory()).toBe(true);
43
+ });
44
+ it('should not throw if directory already exists', () => {
45
+ ensureConfigDir();
46
+ expect(() => ensureConfigDir()).not.toThrow();
47
+ });
48
+ it('should create directory with restrictive permissions', () => {
49
+ ensureConfigDir();
50
+ const configDir = getConfigDir();
51
+ const stats = fs.statSync(configDir);
52
+ // On Unix-like systems, check permissions (0o700)
53
+ if (process.platform !== 'win32') {
54
+ expect(stats.mode & 0o777).toBe(0o700);
55
+ }
56
+ });
57
+ });
58
+ describe('loadConfig', () => {
59
+ it('should return empty object if config file does not exist', () => {
60
+ const config = loadConfig();
61
+ expect(config).toEqual({});
62
+ });
63
+ it('should parse and return valid config', () => {
64
+ const configData = mockConfig();
65
+ saveConfig(configData);
66
+ const loaded = loadConfig();
67
+ expect(loaded).toEqual(configData);
68
+ });
69
+ it('should handle corrupted JSON gracefully', () => {
70
+ ensureConfigDir();
71
+ const configPath = getConfigPath();
72
+ fs.writeFileSync(configPath, 'invalid json {]', 'utf-8');
73
+ const config = loadConfig();
74
+ expect(config).toEqual({});
75
+ });
76
+ it('should preserve all config fields', () => {
77
+ const configData = {
78
+ access_token: 'token123',
79
+ refresh_token: 'refresh456',
80
+ expires_at: '2024-12-31T23:59:59Z',
81
+ user_email: 'user@test.com',
82
+ custom_field: 'custom_value'
83
+ };
84
+ saveConfig(configData);
85
+ const loaded = loadConfig();
86
+ expect(loaded).toEqual(configData);
87
+ });
88
+ });
89
+ describe('saveConfig', () => {
90
+ it('should create config directory and save config', () => {
91
+ const configData = mockConfig();
92
+ saveConfig(configData);
93
+ const configPath = getConfigPath();
94
+ expect(fs.existsSync(configPath)).toBe(true);
95
+ const content = fs.readFileSync(configPath, 'utf-8');
96
+ expect(JSON.parse(content)).toEqual(configData);
97
+ });
98
+ it('should save with restrictive file permissions', () => {
99
+ const configData = mockConfig();
100
+ saveConfig(configData);
101
+ const configPath = getConfigPath();
102
+ const stats = fs.statSync(configPath);
103
+ // On Unix-like systems, check permissions (0o600)
104
+ if (process.platform !== 'win32') {
105
+ expect(stats.mode & 0o777).toBe(0o600);
106
+ }
107
+ });
108
+ it('should overwrite existing config', () => {
109
+ const firstConfig = mockConfig({ access_token: 'old-token' });
110
+ saveConfig(firstConfig);
111
+ const secondConfig = mockConfig({ access_token: 'new-token' });
112
+ saveConfig(secondConfig);
113
+ const loaded = loadConfig();
114
+ expect(loaded.access_token).toBe('new-token');
115
+ });
116
+ it('should format JSON with indentation', () => {
117
+ const configData = mockConfig();
118
+ saveConfig(configData);
119
+ const configPath = getConfigPath();
120
+ const content = fs.readFileSync(configPath, 'utf-8');
121
+ // Should have indentation (pretty-printed)
122
+ expect(content).toContain('\n');
123
+ expect(content).toMatch(/\s{2}/); // 2-space indentation
124
+ });
125
+ });
126
+ describe('clearConfig', () => {
127
+ it('should remove config file if it exists', () => {
128
+ const configData = mockConfig();
129
+ saveConfig(configData);
130
+ const configPath = getConfigPath();
131
+ expect(fs.existsSync(configPath)).toBe(true);
132
+ clearConfig();
133
+ expect(fs.existsSync(configPath)).toBe(false);
134
+ });
135
+ it('should not throw if config file does not exist', () => {
136
+ expect(() => clearConfig()).not.toThrow();
137
+ });
138
+ });
139
+ describe('isAuthenticated', () => {
140
+ it('should return false if no config exists', () => {
141
+ expect(isAuthenticated()).toBe(false);
142
+ });
143
+ it('should return false if access_token is missing', () => {
144
+ saveConfig({ user_email: 'test@example.com' });
145
+ expect(isAuthenticated()).toBe(false);
146
+ });
147
+ it('should return true if access_token exists', () => {
148
+ saveConfig(mockConfig());
149
+ expect(isAuthenticated()).toBe(true);
150
+ });
151
+ it('should return false if access_token is empty string', () => {
152
+ saveConfig(mockConfig({ access_token: '' }));
153
+ expect(isAuthenticated()).toBe(false);
154
+ });
155
+ });
156
+ describe('getAccessToken', () => {
157
+ it('should return null if no config exists', () => {
158
+ expect(getAccessToken()).toBeNull();
159
+ });
160
+ it('should return null if access_token is missing', () => {
161
+ saveConfig({ user_email: 'test@example.com' });
162
+ expect(getAccessToken()).toBeNull();
163
+ });
164
+ it('should return access token if it exists', () => {
165
+ const configData = mockConfig({ access_token: 'my-token-123' });
166
+ saveConfig(configData);
167
+ expect(getAccessToken()).toBe('my-token-123');
168
+ });
169
+ });
170
+ });
171
+ //# sourceMappingURL=config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.test.js","sourceRoot":"","sources":["../../../../src/__tests__/unit/utils/config.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AACzE,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,eAAe,EACf,UAAU,EACV,UAAU,EACV,WAAW,EACX,eAAe,EACf,cAAc,EACf,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE7E,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,IAAI,OAAe,CAAC;IACpB,IAAI,YAAgC,CAAC;IAErC,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,GAAG,aAAa,EAAE,CAAC;QAC1B,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;QAChC,sBAAsB;QACtB,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,cAAc,CAAC,OAAO,CAAC,CAAC;QACxB,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,YAAY,CAAC;QAClC,CAAC;QACD,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;YACjC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;YACnC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;YACjC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAE7C,eAAe,EAAE,CAAC;YAElB,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACrC,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,eAAe,EAAE,CAAC;YAClB,MAAM,CAAC,GAAG,EAAE,CAAC,eAAe,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;YAC9D,eAAe,EAAE,CAAC;YAClB,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YAErC,kDAAkD;YAClD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACjC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzC,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;YAClE,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;YAC9C,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC;YAChC,UAAU,CAAC,UAAU,CAAC,CAAC;YAEvB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,eAAe,EAAE,CAAC;YAClB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;YACnC,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,iBAAiB,EAAE,OAAO,CAAC,CAAC;YAEzD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;YAC3C,MAAM,UAAU,GAAG;gBACjB,YAAY,EAAE,UAAU;gBACxB,aAAa,EAAE,YAAY;gBAC3B,UAAU,EAAE,sBAAsB;gBAClC,UAAU,EAAE,eAAe;gBAC3B,YAAY,EAAE,cAAc;aAC7B,CAAC;YACF,UAAU,CAAC,UAAU,CAAC,CAAC;YAEvB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;QAC1B,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC;YAChC,UAAU,CAAC,UAAU,CAAC,CAAC;YAEvB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;YACnC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE7C,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACrD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC;YAChC,UAAU,CAAC,UAAU,CAAC,CAAC;YAEvB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;YACnC,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YAEtC,kDAAkD;YAClD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;gBACjC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACzC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,WAAW,GAAG,UAAU,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;YAC9D,UAAU,CAAC,WAAW,CAAC,CAAC;YAExB,MAAM,YAAY,GAAG,UAAU,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC,CAAC;YAC/D,UAAU,CAAC,YAAY,CAAC,CAAC;YAEzB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;YAC5B,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC;YAChC,UAAU,CAAC,UAAU,CAAC,CAAC;YAEvB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAErD,2CAA2C;YAC3C,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAChC,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,sBAAsB;QAC1D,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;QAC3B,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC;YAChC,UAAU,CAAC,UAAU,CAAC,CAAC;YAEvB,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;YACnC,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAE7C,WAAW,EAAE,CAAC;YACd,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QAC5C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,UAAU,CAAC,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC/C,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;YACzB,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;YAC7D,UAAU,CAAC,UAAU,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;YAC7C,MAAM,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;YACvD,UAAU,CAAC,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC/C,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,UAAU,GAAG,UAAU,CAAC,EAAE,YAAY,EAAE,cAAc,EAAE,CAAC,CAAC;YAChE,UAAU,CAAC,UAAU,CAAC,CAAC;YACvB,MAAM,CAAC,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=frontmatter.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.test.d.ts","sourceRoot":"","sources":["../../../../src/__tests__/unit/utils/frontmatter.test.ts"],"names":[],"mappings":""}