spck 0.3.1
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/.oxlintrc.json +49 -0
- package/LICENSE +21 -0
- package/README.md +631 -0
- package/bin/cli.js +20 -0
- package/bin/validate-cwd.js +41 -0
- package/dist/config/__tests__/config.test.d.ts +2 -0
- package/dist/config/__tests__/config.test.js +262 -0
- package/dist/config/__tests__/credentials.test.d.ts +2 -0
- package/dist/config/__tests__/credentials.test.js +360 -0
- package/dist/config/config.d.ts +33 -0
- package/dist/config/config.js +185 -0
- package/dist/config/credentials.d.ts +75 -0
- package/dist/config/credentials.js +259 -0
- package/dist/config/server-selection.d.ts +40 -0
- package/dist/config/server-selection.js +130 -0
- package/dist/connection/__tests__/firebase-auth.test.d.ts +2 -0
- package/dist/connection/__tests__/firebase-auth.test.js +96 -0
- package/dist/connection/__tests__/hmac.test.d.ts +2 -0
- package/dist/connection/__tests__/hmac.test.js +372 -0
- package/dist/connection/auth.d.ts +13 -0
- package/dist/connection/auth.js +91 -0
- package/dist/connection/firebase-auth.d.ts +40 -0
- package/dist/connection/firebase-auth.js +429 -0
- package/dist/connection/hmac.d.ts +24 -0
- package/dist/connection/hmac.js +109 -0
- package/dist/i18n/index.d.ts +25 -0
- package/dist/i18n/index.js +101 -0
- package/dist/i18n/locales/en.json +313 -0
- package/dist/i18n/locales/es.json +302 -0
- package/dist/i18n/locales/fr.json +302 -0
- package/dist/i18n/locales/id.json +302 -0
- package/dist/i18n/locales/ja.json +302 -0
- package/dist/i18n/locales/ko.json +302 -0
- package/dist/i18n/locales/locales/en.json +309 -0
- package/dist/i18n/locales/locales/es.json +302 -0
- package/dist/i18n/locales/locales/fr.json +302 -0
- package/dist/i18n/locales/locales/id.json +302 -0
- package/dist/i18n/locales/locales/ja.json +302 -0
- package/dist/i18n/locales/locales/ko.json +302 -0
- package/dist/i18n/locales/locales/pt.json +302 -0
- package/dist/i18n/locales/locales/zh-Hans.json +302 -0
- package/dist/i18n/locales/pt.json +302 -0
- package/dist/i18n/locales/zh-Hans.json +302 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +493 -0
- package/dist/proxy/ProxyClient.d.ts +125 -0
- package/dist/proxy/ProxyClient.js +781 -0
- package/dist/proxy/ProxySocketWrapper.d.ts +43 -0
- package/dist/proxy/ProxySocketWrapper.js +98 -0
- package/dist/proxy/__tests__/ProxyClient.test.d.ts +2 -0
- package/dist/proxy/__tests__/ProxyClient.test.js +445 -0
- package/dist/proxy/__tests__/ProxySocketWrapper.test.d.ts +2 -0
- package/dist/proxy/__tests__/ProxySocketWrapper.test.js +190 -0
- package/dist/proxy/__tests__/handshake-validation.test.d.ts +2 -0
- package/dist/proxy/__tests__/handshake-validation.test.js +282 -0
- package/dist/proxy/__tests__/token-refresh-race.test.d.ts +14 -0
- package/dist/proxy/__tests__/token-refresh-race.test.js +173 -0
- package/dist/proxy/chunking.d.ts +53 -0
- package/dist/proxy/chunking.js +127 -0
- package/dist/proxy/handshake-validation.d.ts +21 -0
- package/dist/proxy/handshake-validation.js +49 -0
- package/dist/rpc/__tests__/router.test.d.ts +2 -0
- package/dist/rpc/__tests__/router.test.js +262 -0
- package/dist/rpc/router.d.ts +37 -0
- package/dist/rpc/router.js +132 -0
- package/dist/services/BrowserProxyService.d.ts +13 -0
- package/dist/services/BrowserProxyService.js +139 -0
- package/dist/services/FilesystemService.d.ts +99 -0
- package/dist/services/FilesystemService.js +742 -0
- package/dist/services/GitService.d.ts +243 -0
- package/dist/services/GitService.js +1439 -0
- package/dist/services/SearchService.d.ts +93 -0
- package/dist/services/SearchService.js +670 -0
- package/dist/services/TerminalService.d.ts +62 -0
- package/dist/services/TerminalService.js +337 -0
- package/dist/services/__tests__/BrowserProxyService.test.d.ts +2 -0
- package/dist/services/__tests__/BrowserProxyService.test.js +145 -0
- package/dist/services/__tests__/FilesystemService.test.d.ts +2 -0
- package/dist/services/__tests__/FilesystemService.test.js +609 -0
- package/dist/services/__tests__/GitService.test.d.ts +2 -0
- package/dist/services/__tests__/GitService.test.js +953 -0
- package/dist/services/__tests__/SearchService.test.d.ts +2 -0
- package/dist/services/__tests__/SearchService.test.js +384 -0
- package/dist/services/__tests__/TerminalService.test.d.ts +2 -0
- package/dist/services/__tests__/TerminalService.test.js +513 -0
- package/dist/setup/wizard.d.ts +10 -0
- package/dist/setup/wizard.js +172 -0
- package/dist/types.d.ts +196 -0
- package/dist/types.js +44 -0
- package/dist/utils/__tests__/gitignore.test.d.ts +2 -0
- package/dist/utils/__tests__/gitignore.test.js +127 -0
- package/dist/utils/gitignore.d.ts +24 -0
- package/dist/utils/gitignore.js +77 -0
- package/dist/utils/logger.d.ts +96 -0
- package/dist/utils/logger.js +456 -0
- package/dist/utils/project-dir.d.ts +51 -0
- package/dist/utils/project-dir.js +191 -0
- package/dist/utils/ripgrep.d.ts +34 -0
- package/dist/utils/ripgrep.js +148 -0
- package/dist/utils/tool-detection.d.ts +17 -0
- package/dist/utils/tool-detection.js +126 -0
- package/dist/watcher/FileWatcher.d.ts +10 -0
- package/dist/watcher/FileWatcher.js +42 -0
- package/package.json +70 -0
- package/src/config/__tests__/config.test.ts +318 -0
- package/src/config/__tests__/credentials.test.ts +494 -0
- package/src/config/config.ts +206 -0
- package/src/config/credentials.ts +302 -0
- package/src/config/server-selection.ts +150 -0
- package/src/connection/__tests__/firebase-auth.test.ts +121 -0
- package/src/connection/__tests__/hmac.test.ts +509 -0
- package/src/connection/auth.ts +140 -0
- package/src/connection/firebase-auth.ts +504 -0
- package/src/connection/hmac.ts +139 -0
- package/src/i18n/index.ts +119 -0
- package/src/i18n/locales/en.json +313 -0
- package/src/i18n/locales/es.json +302 -0
- package/src/i18n/locales/fr.json +302 -0
- package/src/i18n/locales/id.json +302 -0
- package/src/i18n/locales/ja.json +302 -0
- package/src/i18n/locales/ko.json +302 -0
- package/src/i18n/locales/pt.json +302 -0
- package/src/i18n/locales/zh-Hans.json +302 -0
- package/src/index.ts +542 -0
- package/src/proxy/ProxyClient.ts +968 -0
- package/src/proxy/ProxySocketWrapper.ts +113 -0
- package/src/proxy/__tests__/ProxyClient.test.ts +575 -0
- package/src/proxy/__tests__/ProxySocketWrapper.test.ts +251 -0
- package/src/proxy/__tests__/handshake-validation.test.ts +367 -0
- package/src/proxy/chunking.ts +162 -0
- package/src/proxy/handshake-validation.ts +64 -0
- package/src/rpc/__tests__/router.test.ts +400 -0
- package/src/rpc/router.ts +183 -0
- package/src/services/BrowserProxyService.ts +179 -0
- package/src/services/FilesystemService.ts +841 -0
- package/src/services/GitService.ts +1639 -0
- package/src/services/SearchService.ts +809 -0
- package/src/services/TerminalService.ts +413 -0
- package/src/services/__tests__/BrowserProxyService.test.ts +155 -0
- package/src/services/__tests__/FilesystemService.test.ts +1002 -0
- package/src/services/__tests__/GitService.test.ts +1552 -0
- package/src/services/__tests__/SearchService.test.ts +484 -0
- package/src/services/__tests__/TerminalService.test.ts +702 -0
- package/src/setup/wizard.ts +242 -0
- package/src/types/fossil-delta.d.ts +4 -0
- package/src/types.ts +287 -0
- package/src/utils/__tests__/gitignore.test.ts +174 -0
- package/src/utils/gitignore.ts +91 -0
- package/src/utils/logger.ts +578 -0
- package/src/utils/project-dir.ts +218 -0
- package/src/utils/ripgrep.ts +180 -0
- package/src/utils/tool-detection.ts +141 -0
- package/src/watcher/FileWatcher.ts +53 -0
- package/tsconfig.json +24 -0
- package/vitest.config.ts +19 -0
package/bin/cli.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CLI entry point - thin wrapper that executes the main TypeScript entry point
|
|
5
|
+
* All CLI logic is in dist/index.js (compiled from src/index.ts)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { validateCurrentWorkingDirectory } from './validate-cwd.js';
|
|
9
|
+
|
|
10
|
+
// CRITICAL: Validate CWD BEFORE importing any other modules
|
|
11
|
+
// Many Node.js modules call process.cwd() during initialization and will crash
|
|
12
|
+
// if the current directory doesn't exist (deleted, network fs unmounted, etc.)
|
|
13
|
+
validateCurrentWorkingDirectory();
|
|
14
|
+
|
|
15
|
+
import('../dist/index.js').then((module) => {
|
|
16
|
+
module.main().catch((error) => {
|
|
17
|
+
console.error('Error:', error.message);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Validate current working directory and recover if invalid
|
|
5
|
+
*
|
|
6
|
+
* This MUST be called before importing any modules that might call process.cwd()
|
|
7
|
+
* during initialization (e.g., yargs, graceful-fs, @npmcli/config).
|
|
8
|
+
*
|
|
9
|
+
* Handles edge case where:
|
|
10
|
+
* - User cd'd into a directory that was then deleted
|
|
11
|
+
* - Network filesystem became inaccessible
|
|
12
|
+
* - Directory permissions changed
|
|
13
|
+
*/
|
|
14
|
+
export function validateCurrentWorkingDirectory() {
|
|
15
|
+
try {
|
|
16
|
+
process.cwd();
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (error.code === 'ENOENT') {
|
|
19
|
+
// Current directory doesn't exist - fall back to home directory
|
|
20
|
+
const homeDir = os.homedir();
|
|
21
|
+
|
|
22
|
+
console.error('\n⚠️ Warning: Current working directory no longer exists');
|
|
23
|
+
console.error(` Changing to home directory: ${homeDir}\n`);
|
|
24
|
+
|
|
25
|
+
try {
|
|
26
|
+
process.chdir(homeDir);
|
|
27
|
+
console.log('✅ Successfully changed to home directory\n');
|
|
28
|
+
} catch (chdirError) {
|
|
29
|
+
console.error('\n❌ Fatal Error: Cannot access home directory');
|
|
30
|
+
console.error(' Your filesystem may be corrupted or inaccessible.');
|
|
31
|
+
console.error(` Error: ${chdirError.message}\n`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
} else {
|
|
35
|
+
// Some other error with process.cwd()
|
|
36
|
+
console.error('\n❌ Fatal Error: Cannot determine current working directory');
|
|
37
|
+
console.error(` Error: ${error.message}\n`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
2
|
+
/**
|
|
3
|
+
* Unit tests for config management
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import { loadConfig, saveConfig, ConfigNotFoundError, createDefaultConfig, parseFileSize, } from '../config.js';
|
|
7
|
+
// Mock fs module
|
|
8
|
+
vi.mock('fs');
|
|
9
|
+
const mockFs = fs;
|
|
10
|
+
describe('config', () => {
|
|
11
|
+
const mockCwd = '/mock/project';
|
|
12
|
+
beforeEach(() => {
|
|
13
|
+
vi.clearAllMocks();
|
|
14
|
+
vi.spyOn(process, 'cwd').mockReturnValue(mockCwd);
|
|
15
|
+
});
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
vi.restoreAllMocks();
|
|
18
|
+
});
|
|
19
|
+
describe('loadConfig()', () => {
|
|
20
|
+
const validConfig = {
|
|
21
|
+
version: 1,
|
|
22
|
+
root: '/mock/root',
|
|
23
|
+
terminal: {
|
|
24
|
+
enabled: true,
|
|
25
|
+
maxBufferedLines: 5000,
|
|
26
|
+
maxTerminals: 10,
|
|
27
|
+
},
|
|
28
|
+
security: {
|
|
29
|
+
userAuthenticationEnabled: false,
|
|
30
|
+
},
|
|
31
|
+
browserProxy: {
|
|
32
|
+
enabled: true
|
|
33
|
+
},
|
|
34
|
+
filesystem: {
|
|
35
|
+
maxFileSize: '100MB',
|
|
36
|
+
watchIgnorePatterns: ['node_modules/**'],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
beforeEach(() => {
|
|
40
|
+
// Mock root directory exists for validation
|
|
41
|
+
mockFs.existsSync.mockImplementation((path) => {
|
|
42
|
+
if (path === '/mock/root')
|
|
43
|
+
return true;
|
|
44
|
+
return false;
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
it('should throw ConfigNotFoundError if file does not exist', () => {
|
|
48
|
+
mockFs.existsSync.mockReturnValue(false);
|
|
49
|
+
expect(() => loadConfig()).toThrow(ConfigNotFoundError);
|
|
50
|
+
});
|
|
51
|
+
it('should load and return valid config', () => {
|
|
52
|
+
mockFs.existsSync.mockImplementation((_path) => {
|
|
53
|
+
// Config file and root directory exist
|
|
54
|
+
return true;
|
|
55
|
+
});
|
|
56
|
+
mockFs.readFileSync.mockReturnValue(JSON.stringify(validConfig));
|
|
57
|
+
const result = loadConfig();
|
|
58
|
+
expect(result).toEqual(validConfig);
|
|
59
|
+
});
|
|
60
|
+
it('should throw CORRUPTED error for invalid JSON', () => {
|
|
61
|
+
mockFs.existsSync.mockReturnValue(true);
|
|
62
|
+
mockFs.readFileSync.mockReturnValue('not valid json{');
|
|
63
|
+
expect(() => {
|
|
64
|
+
try {
|
|
65
|
+
loadConfig();
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
expect(error.code).toBe('CORRUPTED');
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
}).toThrow();
|
|
72
|
+
});
|
|
73
|
+
it('should throw CORRUPTED error for invalid version', () => {
|
|
74
|
+
const invalidConfig = {
|
|
75
|
+
...validConfig,
|
|
76
|
+
version: 999,
|
|
77
|
+
};
|
|
78
|
+
mockFs.existsSync.mockReturnValue(true);
|
|
79
|
+
mockFs.readFileSync.mockReturnValue(JSON.stringify(invalidConfig));
|
|
80
|
+
expect(() => {
|
|
81
|
+
try {
|
|
82
|
+
loadConfig();
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
expect(error.code).toBe('CORRUPTED');
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
}).toThrow();
|
|
89
|
+
});
|
|
90
|
+
it('should throw CORRUPTED error for missing root', () => {
|
|
91
|
+
const invalidConfig = {
|
|
92
|
+
...validConfig,
|
|
93
|
+
root: undefined,
|
|
94
|
+
};
|
|
95
|
+
mockFs.existsSync.mockReturnValue(true);
|
|
96
|
+
mockFs.readFileSync.mockReturnValue(JSON.stringify(invalidConfig));
|
|
97
|
+
expect(() => {
|
|
98
|
+
try {
|
|
99
|
+
loadConfig();
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
expect(error.code).toBe('CORRUPTED');
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
}).toThrow();
|
|
106
|
+
});
|
|
107
|
+
it('should throw error if root directory does not exist', () => {
|
|
108
|
+
mockFs.existsSync.mockImplementation((path) => {
|
|
109
|
+
// Config exists, but root doesn't
|
|
110
|
+
if (path.includes('.spck-editor'))
|
|
111
|
+
return true;
|
|
112
|
+
return false;
|
|
113
|
+
});
|
|
114
|
+
mockFs.readFileSync.mockReturnValue(JSON.stringify(validConfig));
|
|
115
|
+
expect(() => loadConfig()).toThrow('Root directory does not exist');
|
|
116
|
+
});
|
|
117
|
+
it('should use custom config path when provided', () => {
|
|
118
|
+
const customPath = 'custom/config.json';
|
|
119
|
+
mockFs.existsSync.mockReturnValue(false);
|
|
120
|
+
expect(() => loadConfig(customPath)).toThrow(ConfigNotFoundError);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
describe('saveConfig()', () => {
|
|
124
|
+
const validConfig = {
|
|
125
|
+
version: 1,
|
|
126
|
+
root: mockCwd,
|
|
127
|
+
terminal: {
|
|
128
|
+
enabled: true,
|
|
129
|
+
maxBufferedLines: 5000,
|
|
130
|
+
maxTerminals: 10,
|
|
131
|
+
},
|
|
132
|
+
security: {
|
|
133
|
+
userAuthenticationEnabled: false,
|
|
134
|
+
},
|
|
135
|
+
filesystem: {
|
|
136
|
+
maxFileSize: '100MB',
|
|
137
|
+
watchIgnorePatterns: [],
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
beforeEach(() => {
|
|
141
|
+
// Mock root directory exists for validation
|
|
142
|
+
mockFs.existsSync.mockImplementation((path) => {
|
|
143
|
+
if (path === mockCwd)
|
|
144
|
+
return true;
|
|
145
|
+
return false;
|
|
146
|
+
});
|
|
147
|
+
mockFs.mkdirSync.mockReturnValue(undefined);
|
|
148
|
+
mockFs.writeFileSync.mockReturnValue(undefined);
|
|
149
|
+
});
|
|
150
|
+
it('should create directory if it does not exist', () => {
|
|
151
|
+
mockFs.existsSync.mockImplementation((path) => {
|
|
152
|
+
// Root exists, but .spck-editor doesn't
|
|
153
|
+
if (path === mockCwd)
|
|
154
|
+
return true;
|
|
155
|
+
return false;
|
|
156
|
+
});
|
|
157
|
+
saveConfig(validConfig);
|
|
158
|
+
expect(mockFs.mkdirSync).toHaveBeenCalled();
|
|
159
|
+
});
|
|
160
|
+
it('should write config file', () => {
|
|
161
|
+
mockFs.existsSync.mockReturnValue(true);
|
|
162
|
+
saveConfig(validConfig);
|
|
163
|
+
expect(mockFs.writeFileSync).toHaveBeenCalledWith(expect.stringContaining('spck-cli.config.json'), JSON.stringify(validConfig, null, 2), 'utf8');
|
|
164
|
+
});
|
|
165
|
+
it('should validate config before saving', () => {
|
|
166
|
+
const invalidConfig = {
|
|
167
|
+
...validConfig,
|
|
168
|
+
version: 999, // Invalid version
|
|
169
|
+
};
|
|
170
|
+
expect(() => saveConfig(invalidConfig)).toThrow('Invalid config version');
|
|
171
|
+
});
|
|
172
|
+
it('should throw error with operation context on write failure', () => {
|
|
173
|
+
const mockError = new Error('ENOSPC');
|
|
174
|
+
mockError.code = 'ENOSPC';
|
|
175
|
+
mockFs.writeFileSync.mockImplementation(() => {
|
|
176
|
+
throw mockError;
|
|
177
|
+
});
|
|
178
|
+
mockFs.existsSync.mockReturnValue(true);
|
|
179
|
+
expect(() => {
|
|
180
|
+
try {
|
|
181
|
+
saveConfig(validConfig);
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
expect(error.operation).toBe('save config');
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
187
|
+
}).toThrow();
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
describe('createDefaultConfig()', () => {
|
|
191
|
+
it('should create config with default values', () => {
|
|
192
|
+
const config = createDefaultConfig();
|
|
193
|
+
expect(config.version).toBe(1);
|
|
194
|
+
expect(config.root).toBe(mockCwd);
|
|
195
|
+
expect(config.terminal.enabled).toBe(true);
|
|
196
|
+
expect(config.security.userAuthenticationEnabled).toBe(false);
|
|
197
|
+
});
|
|
198
|
+
it('should merge overrides with defaults', () => {
|
|
199
|
+
const overrides = {
|
|
200
|
+
root: '/custom/root',
|
|
201
|
+
terminal: {
|
|
202
|
+
enabled: false,
|
|
203
|
+
maxBufferedLines: 1000,
|
|
204
|
+
maxTerminals: 5,
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
const config = createDefaultConfig(overrides);
|
|
208
|
+
expect(config.root).toBe('/custom/root');
|
|
209
|
+
expect(config.terminal.enabled).toBe(false);
|
|
210
|
+
expect(config.terminal.maxBufferedLines).toBe(1000);
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
describe('parseFileSize()', () => {
|
|
214
|
+
it('should parse bytes correctly', () => {
|
|
215
|
+
expect(parseFileSize('100B')).toBe(100);
|
|
216
|
+
expect(parseFileSize('100')).toBe(100);
|
|
217
|
+
});
|
|
218
|
+
it('should parse kilobytes correctly', () => {
|
|
219
|
+
expect(parseFileSize('1KB')).toBe(1024);
|
|
220
|
+
expect(parseFileSize('10KB')).toBe(10240);
|
|
221
|
+
});
|
|
222
|
+
it('should parse megabytes correctly', () => {
|
|
223
|
+
expect(parseFileSize('1MB')).toBe(1024 * 1024);
|
|
224
|
+
expect(parseFileSize('100MB')).toBe(100 * 1024 * 1024);
|
|
225
|
+
});
|
|
226
|
+
it('should parse gigabytes correctly', () => {
|
|
227
|
+
expect(parseFileSize('1GB')).toBe(1024 * 1024 * 1024);
|
|
228
|
+
expect(parseFileSize('2GB')).toBe(2 * 1024 * 1024 * 1024);
|
|
229
|
+
});
|
|
230
|
+
it('should handle decimal values', () => {
|
|
231
|
+
expect(parseFileSize('1.5MB')).toBe(1.5 * 1024 * 1024);
|
|
232
|
+
expect(parseFileSize('0.5GB')).toBe(0.5 * 1024 * 1024 * 1024);
|
|
233
|
+
});
|
|
234
|
+
it('should be case insensitive', () => {
|
|
235
|
+
expect(parseFileSize('1mb')).toBe(1024 * 1024);
|
|
236
|
+
expect(parseFileSize('1MB')).toBe(1024 * 1024);
|
|
237
|
+
expect(parseFileSize('1Mb')).toBe(1024 * 1024);
|
|
238
|
+
});
|
|
239
|
+
it('should handle spaces', () => {
|
|
240
|
+
expect(parseFileSize('100 MB')).toBe(100 * 1024 * 1024);
|
|
241
|
+
});
|
|
242
|
+
it('should throw error for invalid format', () => {
|
|
243
|
+
expect(() => parseFileSize('invalid')).toThrow('Invalid file size format');
|
|
244
|
+
expect(() => parseFileSize('100XB')).toThrow('Invalid file size format');
|
|
245
|
+
expect(() => parseFileSize('')).toThrow('Invalid file size format');
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
describe('ConfigNotFoundError', () => {
|
|
249
|
+
it('should create error with config path', () => {
|
|
250
|
+
const error = new ConfigNotFoundError('/path/to/config.json');
|
|
251
|
+
expect(error.name).toBe('ConfigNotFoundError');
|
|
252
|
+
expect(error.message).toContain('/path/to/config.json');
|
|
253
|
+
expect(error.configPath).toBe('/path/to/config.json');
|
|
254
|
+
});
|
|
255
|
+
it('should be instance of Error', () => {
|
|
256
|
+
const error = new ConfigNotFoundError('/path');
|
|
257
|
+
expect(error).toBeInstanceOf(Error);
|
|
258
|
+
expect(error).toBeInstanceOf(ConfigNotFoundError);
|
|
259
|
+
});
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
//# sourceMappingURL=config.test.js.map
|