yargs-file-commands 0.0.20 → 1.0.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.
Files changed (57) hide show
  1. package/README.md +13 -13
  2. package/dist/index.js +1 -0
  3. package/dist/index.js.map +1 -0
  4. package/dist/lib/Command.js +1 -0
  5. package/dist/lib/Command.js.map +1 -0
  6. package/dist/lib/buildSegmentTree.d.ts +1 -1
  7. package/dist/lib/buildSegmentTree.js +7 -3
  8. package/dist/lib/buildSegmentTree.js.map +1 -0
  9. package/dist/lib/buildSegmentTree.test.js +279 -26
  10. package/dist/lib/buildSegmentTree.test.js.map +1 -0
  11. package/dist/lib/fileCommands.d.ts +2 -1
  12. package/dist/lib/fileCommands.js +39 -21
  13. package/dist/lib/fileCommands.js.map +1 -0
  14. package/dist/lib/fileCommands.test.js +107 -30
  15. package/dist/lib/fileCommands.test.js.map +1 -0
  16. package/dist/lib/fixtures/commands/$default.js +1 -0
  17. package/dist/lib/fixtures/commands/$default.js.map +1 -0
  18. package/dist/lib/fixtures/commands/create.js +1 -0
  19. package/dist/lib/fixtures/commands/create.js.map +1 -0
  20. package/dist/lib/fixtures/commands/db/health.d.ts +2 -1
  21. package/dist/lib/fixtures/commands/db/health.js +2 -3
  22. package/dist/lib/fixtures/commands/db/health.js.map +1 -0
  23. package/dist/lib/fixtures/commands/db/migration/command.d.ts +9 -2
  24. package/dist/lib/fixtures/commands/db/migration/command.js +6 -7
  25. package/dist/lib/fixtures/commands/db/migration/command.js.map +1 -0
  26. package/dist/lib/importCommand.d.ts +3 -3
  27. package/dist/lib/importCommand.js +39 -27
  28. package/dist/lib/importCommand.js.map +1 -0
  29. package/dist/lib/importCommand.test.js +157 -33
  30. package/dist/lib/importCommand.test.js.map +1 -0
  31. package/dist/lib/scanDirectory.js +54 -25
  32. package/dist/lib/scanDirectory.js.map +1 -0
  33. package/dist/lib/scanDirectory.test.js +148 -25
  34. package/dist/lib/scanDirectory.test.js.map +1 -0
  35. package/dist/lib/segmentPath.js +8 -6
  36. package/dist/lib/segmentPath.js.map +1 -0
  37. package/dist/lib/segmentPath.test.js +10 -38
  38. package/dist/lib/segmentPath.test.js.map +1 -0
  39. package/dist/tsconfig.tsbuildinfo +1 -0
  40. package/package.json +6 -9
  41. package/CHANGELOG.md +0 -62
  42. package/src/index.ts +0 -1
  43. package/src/lib/Command.ts +0 -16
  44. package/src/lib/buildSegmentTree.test.ts +0 -90
  45. package/src/lib/buildSegmentTree.ts +0 -149
  46. package/src/lib/fileCommands.test.ts +0 -55
  47. package/src/lib/fileCommands.ts +0 -149
  48. package/src/lib/fixtures/commands/$default.ts +0 -5
  49. package/src/lib/fixtures/commands/create.ts +0 -6
  50. package/src/lib/fixtures/commands/db/health.ts +0 -9
  51. package/src/lib/fixtures/commands/db/migration/command.ts +0 -12
  52. package/src/lib/importCommand.test.ts +0 -60
  53. package/src/lib/importCommand.ts +0 -196
  54. package/src/lib/scanDirectory.test.ts +0 -75
  55. package/src/lib/scanDirectory.ts +0 -109
  56. package/src/lib/segmentPath.test.ts +0 -71
  57. package/src/lib/segmentPath.ts +0 -38
@@ -1,5 +1,23 @@
1
- import { readdir, stat } from 'fs/promises';
2
- import path, { join } from 'path';
1
+ import { readdir } from 'node:fs/promises';
2
+ import path, { join } from 'node:path';
3
+ /**
4
+ * System-level ignore patterns that ALWAYS apply regardless of user configuration.
5
+ * These patterns match system files and hidden files that should never be treated as command files.
6
+ * This ensures compatibility across macOS (.DS_Store), Linux, and Windows.
7
+ */
8
+ const SYSTEM_IGNORE_PATTERNS = [
9
+ /^[.].*/, // Any file or directory starting with a dot (hidden files)
10
+ ];
11
+ /**
12
+ * Default ignore patterns for directory scanning (optional, can be overridden).
13
+ * These patterns match common files that should not be treated as command files.
14
+ * System ignore patterns are always applied in addition to these defaults.
15
+ */
16
+ const DEFAULT_IGNORE_PATTERNS = [
17
+ /\.(?:test|spec)\.[jt]s$/, // Test files
18
+ /__(?:test|spec)__/, // Test directories
19
+ /\.d\.ts$/, // TypeScript declaration files
20
+ ];
3
21
  /**
4
22
  * Recursively scans a directory for command files
5
23
  * @async
@@ -14,49 +32,60 @@ import path, { join } from 'path';
14
32
  * The scan is performed in parallel for better performance.
15
33
  */
16
34
  export const scanDirectory = async (dirPath, commandDir, options = {}) => {
17
- const { ignorePatterns = [], extensions = ['.js', '.ts'], logLevel = 'info', logPrefix = '' } = options;
35
+ const { ignorePatterns = DEFAULT_IGNORE_PATTERNS, extensions = ['.js', '.ts'], logLevel = 'info', logPrefix = '', } = options;
36
+ // Always merge system ignore patterns with user-provided patterns
37
+ // System patterns are checked first to ensure system files are never included
38
+ const allIgnorePatterns = [...SYSTEM_IGNORE_PATTERNS, ...ignorePatterns];
18
39
  try {
19
- const entries = await readdir(dirPath);
20
- const commandPaths = [];
21
- for (const entry of entries) {
22
- const fullPath = join(dirPath, entry);
40
+ const entries = await readdir(dirPath, { withFileTypes: true });
41
+ // First, filter out entries that match ignore patterns
42
+ const entriesToProcess = entries.filter((entry) => {
43
+ const fullPath = join(dirPath, entry.name);
23
44
  const localPath = fullPath.replace(commandDir, '');
24
- // apply ignore pattern and early return if matched
25
- const shouldIgnore = ignorePatterns.some((pattern) => pattern.test(localPath));
26
- if (shouldIgnore) {
45
+ // Apply ignore patterns - system patterns are always checked first
46
+ const matchingPattern = allIgnorePatterns.find((pattern) => pattern.test(localPath));
47
+ if (matchingPattern) {
27
48
  if (logLevel === 'debug') {
28
- console.debug(`${logPrefix}${localPath} - ignoring because it matches ignorePattern: ${ignorePatterns
29
- .filter((pattern) => pattern.test(localPath))
30
- .join(', ')}`);
49
+ const isSystemPattern = SYSTEM_IGNORE_PATTERNS.some((pattern) => pattern.test(localPath));
50
+ // biome-ignore lint/security/noSecrets: This is not a secret, it's a descriptive string for logging
51
+ const patternType = isSystemPattern ? 'system ignore pattern' : 'ignorePattern';
52
+ console.debug(`${logPrefix}${localPath} - ignoring because it matches ${patternType}: ${matchingPattern.toString()}`);
31
53
  }
32
- continue;
54
+ return false;
33
55
  }
34
- const stats = await stat(fullPath);
35
- if (stats.isDirectory()) {
56
+ return true;
57
+ });
58
+ // Process all entries in parallel
59
+ const entryResults = await Promise.all(entriesToProcess.map(async (entry) => {
60
+ const fullPath = join(dirPath, entry.name);
61
+ const localPath = fullPath.replace(commandDir, '');
62
+ if (entry.isDirectory()) {
36
63
  if (logLevel === 'debug') {
37
64
  console.debug(`${logPrefix}${localPath} - directory, scanning for commands:`);
38
65
  }
39
- commandPaths.push(...(await scanDirectory(fullPath, commandDir, {
66
+ return scanDirectory(fullPath, commandDir, {
40
67
  ...options,
41
- logPrefix: `${logPrefix} `
42
- })));
43
- continue;
68
+ logPrefix: `${logPrefix} `,
69
+ });
44
70
  }
45
71
  const extension = path.extname(fullPath);
46
72
  if (!extensions.includes(extension)) {
47
73
  if (logLevel === 'debug') {
48
74
  console.debug(`${logPrefix}${localPath} - ignoring as its extension, ${extension}, doesn't match required extension: ${extensions.join(', ')}`);
49
75
  }
50
- continue;
76
+ return [];
51
77
  }
52
78
  if (logLevel === 'debug') {
53
79
  console.debug(`${logPrefix}${localPath} - possible command file`);
54
80
  }
55
- commandPaths.push(fullPath);
56
- }
57
- return commandPaths;
81
+ return [fullPath];
82
+ }));
83
+ // Flatten the results
84
+ return entryResults.flat();
58
85
  }
59
86
  catch (error) {
60
- throw new Error(`${logPrefix}Failed to scan directory ${dirPath}: ${error}`);
87
+ const errorMessage = error instanceof Error ? error.message : String(error);
88
+ throw new Error(`${logPrefix}Failed to scan directory ${dirPath}: ${errorMessage}. Ensure the directory exists and is accessible.`);
61
89
  }
62
90
  };
91
+ //# sourceMappingURL=scanDirectory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanDirectory.js","sourceRoot":"","sources":["../../src/lib/scanDirectory.ts"],"names":[],"mappings":"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"}
@@ -1,46 +1,169 @@
1
- import assert from 'node:assert/strict';
1
+ import { mkdir, rm, writeFile } from 'node:fs/promises';
2
+ import { tmpdir } from 'node:os';
2
3
  import path from 'node:path';
3
- import { describe, it } from 'node:test';
4
4
  import { fileURLToPath } from 'node:url';
5
+ import { describe, expect, it, vi } from 'vitest';
5
6
  import { scanDirectory } from '../lib/scanDirectory.js';
6
7
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
- describe('scanDirectory', async () => {
8
- await it('should find all command files in directory', async () => {
8
+ describe('scanDirectory', () => {
9
+ it('should find all command files in directory', async () => {
9
10
  const commandsDir = path.join(__dirname, 'fixtures', 'commands');
10
11
  console.log('Scan Directory: ', commandsDir);
11
12
  const files = await scanDirectory(commandsDir, commandsDir, {
12
- extensions: ['.js'],
13
- logLevel: 'debug'
13
+ extensions: ['.ts'],
14
+ logLevel: 'debug',
14
15
  });
15
- assert.equal(files.length, 4, `Should find two command files, instead found: ${files.join(', ')}`);
16
- assert(files.some((f) => f.includes('health.js')), `Should find health.js, instead found: ${files.join(', ')}`);
17
- assert(files.some((f) => f.includes('command.js')), `Should find command.js, instead found: ${files.join(', ')}`);
16
+ expect(files.length).toBe(4);
17
+ expect(files.some((f) => f.includes('health.ts'))).toBe(true);
18
+ expect(files.some((f) => f.includes('command.ts'))).toBe(true);
18
19
  });
19
- await it('should respect ignore patterns', async () => {
20
+ it('should respect ignore patterns', async () => {
20
21
  const commandsDir = path.join(__dirname, 'fixtures', 'commands');
21
22
  console.log('Scan Directory: ', commandsDir);
22
23
  const files = await scanDirectory(commandsDir, commandsDir, {
23
- extensions: ['.js'],
24
- ignorePatterns: [/health/, /.d.ts/],
25
- logLevel: 'debug'
24
+ extensions: ['.ts'],
25
+ ignorePatterns: [/health/, /\.d\.ts$/],
26
+ logLevel: 'debug',
26
27
  });
27
- assert.equal(files.length, 3, `Should find one command file, instead found: ${files.join(', ')}`);
28
- assert(files.some((f) => f.includes('command.js')), `Should find command.js, instead found: ${files.join(', ')}`);
29
- assert(!files.some((f) => f.includes('health.js')), `Should not find health.js, instead found: ${files.join(', ')}`);
28
+ expect(files.length).toBe(3);
29
+ expect(files.some((f) => f.includes('command.ts'))).toBe(true);
30
+ expect(files.some((f) => f.includes('health.ts'))).toBe(false);
30
31
  });
31
- await it('should handle non-existent directories', async () => {
32
+ it('should handle non-existent directories', async () => {
32
33
  const nonExistentDir = path.join(__dirname, 'fixtures', 'non-existent');
34
+ await expect(scanDirectory(nonExistentDir, nonExistentDir, {
35
+ extensions: ['.ts'],
36
+ logLevel: 'debug',
37
+ })).rejects.toThrow(/ENOENT/);
38
+ });
39
+ it('should ignore files with non-matching extensions', async () => {
40
+ // Create a temporary directory with mixed file types
41
+ const tempDir = path.join(tmpdir(), `yargs-test-${Date.now()}`);
42
+ await mkdir(tempDir, { recursive: true });
33
43
  try {
34
- console.log('Scan Directory: ', nonExistentDir);
35
- await scanDirectory(nonExistentDir, nonExistentDir, {
36
- extensions: ['.js'],
37
- logLevel: 'debug'
44
+ // Create files with different extensions
45
+ await writeFile(path.join(tempDir, 'valid.ts'), '// TS file');
46
+ await writeFile(path.join(tempDir, 'invalid.js'), '// JS file');
47
+ await writeFile(path.join(tempDir, 'invalid.txt'), '// TXT file');
48
+ const consoleSpy = vi.spyOn(console, 'debug').mockImplementation(() => { });
49
+ const files = await scanDirectory(tempDir, tempDir, {
50
+ extensions: ['.ts'], // Only .ts files
51
+ logLevel: 'debug',
38
52
  });
39
- assert.fail('Should have thrown an error');
53
+ // Should only find the .ts file
54
+ expect(files.length).toBe(1);
55
+ expect(files[0]).toContain('valid.ts');
56
+ expect(files.some((f) => f.includes('invalid.js'))).toBe(false);
57
+ expect(files.some((f) => f.includes('invalid.txt'))).toBe(false);
58
+ // Should log extension mismatch
59
+ const debugCalls = consoleSpy.mock.calls.map((call) => call[0]?.toString() || '');
60
+ expect(debugCalls.some((call) => call.includes("doesn't match required extension"))).toBe(true);
61
+ consoleSpy.mockRestore();
40
62
  }
41
- catch (error) {
42
- assert(error instanceof Error);
43
- assert(error.message.includes('ENOENT'), 'Error should indicate directory not found');
63
+ finally {
64
+ await rm(tempDir, { recursive: true, force: true });
44
65
  }
45
66
  });
67
+ it('should handle custom extensions', async () => {
68
+ // Create a temporary directory with .js files
69
+ const tempDir = path.join(tmpdir(), `yargs-test-${Date.now()}`);
70
+ await mkdir(tempDir, { recursive: true });
71
+ try {
72
+ await writeFile(path.join(tempDir, 'cmd.js'), '// JS file');
73
+ await writeFile(path.join(tempDir, 'cmd.ts'), '// TS file');
74
+ const files = await scanDirectory(tempDir, tempDir, {
75
+ extensions: ['.js'], // Only .js files
76
+ });
77
+ expect(files.length).toBe(1);
78
+ expect(files[0]).toContain('cmd.js');
79
+ expect(files.some((f) => f.includes('cmd.ts'))).toBe(false);
80
+ }
81
+ finally {
82
+ await rm(tempDir, { recursive: true, force: true });
83
+ }
84
+ });
85
+ it('should handle multiple extensions', async () => {
86
+ // Create a temporary directory with different file types
87
+ const tempDir = path.join(tmpdir(), `yargs-test-${Date.now()}`);
88
+ await mkdir(tempDir, { recursive: true });
89
+ try {
90
+ await writeFile(path.join(tempDir, 'cmd1.js'), '// JS file');
91
+ await writeFile(path.join(tempDir, 'cmd2.ts'), '// TS file');
92
+ await writeFile(path.join(tempDir, 'cmd3.txt'), '// TXT file');
93
+ const files = await scanDirectory(tempDir, tempDir, {
94
+ extensions: ['.js', '.ts'], // Both JS and TS files
95
+ // Note: Hidden files (starting with '.') are automatically ignored by system ignore patterns
96
+ });
97
+ // Should find exactly 2 files (cmd1.js and cmd2.ts)
98
+ const jsFiles = files.filter((f) => f.includes('cmd1.js'));
99
+ const tsFiles = files.filter((f) => f.includes('cmd2.ts'));
100
+ const txtFiles = files.filter((f) => f.includes('cmd3.txt'));
101
+ expect(jsFiles.length).toBe(1);
102
+ expect(tsFiles.length).toBe(1);
103
+ expect(txtFiles.length).toBe(0);
104
+ // Verify we have at least our expected files (there might be hidden files)
105
+ expect(files.some((f) => f.includes('cmd1.js'))).toBe(true);
106
+ expect(files.some((f) => f.includes('cmd2.ts'))).toBe(true);
107
+ expect(files.some((f) => f.includes('cmd3.txt'))).toBe(false);
108
+ }
109
+ finally {
110
+ await rm(tempDir, { recursive: true, force: true });
111
+ }
112
+ });
113
+ it('should handle nested directories with extension filtering', async () => {
114
+ // Create a temporary directory structure
115
+ const tempDir = path.join(tmpdir(), `yargs-test-${Date.now()}`);
116
+ const subDir = path.join(tempDir, 'subdir');
117
+ await mkdir(subDir, { recursive: true });
118
+ try {
119
+ await writeFile(path.join(tempDir, 'root.ts'), '// Root TS file');
120
+ await writeFile(path.join(tempDir, 'root.js'), '// Root JS file');
121
+ await writeFile(path.join(subDir, 'nested.ts'), '// Nested TS file');
122
+ await writeFile(path.join(subDir, 'nested.js'), '// Nested JS file');
123
+ const files = await scanDirectory(tempDir, tempDir, {
124
+ extensions: ['.ts'],
125
+ // Note: Hidden files (starting with '.') are automatically ignored by system ignore patterns
126
+ });
127
+ // Should find exactly 2 files (root.ts and nested.ts)
128
+ const rootFiles = files.filter((f) => f.includes('root.ts'));
129
+ const nestedFiles = files.filter((f) => f.includes('nested.ts'));
130
+ const jsFiles = files.filter((f) => f.includes('.js'));
131
+ expect(rootFiles.length).toBe(1);
132
+ expect(nestedFiles.length).toBe(1);
133
+ expect(jsFiles.length).toBe(0);
134
+ expect(files.some((f) => f.includes('root.ts'))).toBe(true);
135
+ expect(files.some((f) => f.includes('nested.ts'))).toBe(true);
136
+ }
137
+ finally {
138
+ await rm(tempDir, { recursive: true, force: true });
139
+ }
140
+ });
141
+ it('should use default options when not provided', async () => {
142
+ const commandsDir = path.join(__dirname, 'fixtures', 'commands');
143
+ const files = await scanDirectory(commandsDir, commandsDir);
144
+ // Should use default extensions (.js, .ts) and find files
145
+ expect(files.length).toBeGreaterThan(0);
146
+ });
147
+ it('should handle empty directories', async () => {
148
+ const tempDir = path.join(tmpdir(), `yargs-test-${Date.now()}`);
149
+ await mkdir(tempDir, { recursive: true });
150
+ try {
151
+ const files = await scanDirectory(tempDir, tempDir, {
152
+ extensions: ['.ts'],
153
+ // Note: Hidden files (starting with '.') are automatically ignored by system ignore patterns
154
+ });
155
+ expect(files.length).toBe(0);
156
+ }
157
+ finally {
158
+ await rm(tempDir, { recursive: true, force: true });
159
+ }
160
+ });
161
+ it('should handle error with proper message formatting', async () => {
162
+ const nonExistentDir = path.join(__dirname, 'fixtures', 'non-existent');
163
+ await expect(scanDirectory(nonExistentDir, nonExistentDir, {
164
+ extensions: ['.ts'],
165
+ logPrefix: ' ',
166
+ })).rejects.toThrow(/Failed to scan directory/);
167
+ });
46
168
  });
169
+ //# sourceMappingURL=scanDirectory.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanDirectory.test.js","sourceRoot":"","sources":["../../src/lib/scanDirectory.test.ts"],"names":[],"mappings":"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"}
@@ -16,18 +16,20 @@
16
16
  * segmentPath('/base/dir/hello/world.command.ts', '/base/dir')
17
17
  * // Returns: ['hello', 'world']
18
18
  */
19
+ // Top-level regex patterns for performance
20
+ const LEADING_SLASHES_REGEX = /^[/\\\\]+/;
21
+ const PATH_SEPARATOR_REGEX = /[/\\\\]/;
19
22
  export const segmentPath = (fullPath, baseDir) => {
20
23
  // Remove base directory and normalize slashes
21
- const relativePath = fullPath.replace(baseDir, '').replace(/^[/\\\\]+/, '');
24
+ const relativePath = fullPath.replace(baseDir, '').replace(LEADING_SLASHES_REGEX, '');
22
25
  // Split into path segments and filename
23
- const allSegments = relativePath.split(/[/\\\\]/);
24
- // Process all segments including filename (without extension)
26
+ const allSegments = relativePath.split(PATH_SEPARATOR_REGEX);
27
+ // Process all segments including filename
28
+ // Split segments containing periods (this will split the extension from the filename)
25
29
  const processedSegments = allSegments
26
- // Remove extension from the last segment (filename)
27
- .map((segment, index, array) => index === array.length - 1 ? segment.replace(/\\.[^/.]+$/, '') : segment)
28
- // Split segments containing periods
29
30
  .flatMap((segment) => segment.split('.'))
30
31
  // Filter out empty segments and 'command'
31
32
  .filter((segment) => segment !== '' && segment !== 'command');
32
33
  return processedSegments;
33
34
  };
35
+ //# sourceMappingURL=segmentPath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmentPath.js","sourceRoot":"","sources":["../../src/lib/segmentPath.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,2CAA2C;AAC3C,MAAM,qBAAqB,GAAG,WAAW,CAAC;AAC1C,MAAM,oBAAoB,GAAG,SAAS,CAAC;AAEvC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAAgB,EAAE,OAAe,EAAY,EAAE,CAAC;IAC1E,8CAA8C;IAC9C,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;IAEtF,wCAAwC;IACxC,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAE7D,0CAA0C;IAC1C,sFAAsF;IACtF,MAAM,iBAAiB,GAAG,WAAW;SAClC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACzC,0CAA0C;SACzC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,SAAS,CAAC,CAAC;IAEhE,OAAO,iBAAiB,CAAC;AAAA,CAC1B,CAAC"}
@@ -1,61 +1,33 @@
1
- import { describe, it } from 'node:test';
2
- import assert from 'assert';
1
+ import { describe, expect, it } from 'vitest';
3
2
  import { segmentPath } from './segmentPath.js';
4
3
  describe('segmentPath', () => {
5
4
  it('should segment a path correctly', () => {
6
5
  const fullPath = '/Users/username/Coding/Personal/yargs-file-commands/packages/yargs-file-commands/src/lib/segmentPath.ts';
7
6
  const baseDir = '/Users/username/Coding/Personal/yargs-file-commands/';
8
- const expected = [
9
- 'packages',
10
- 'yargs-file-commands',
11
- 'src',
12
- 'lib',
13
- 'segmentPath',
14
- 'ts'
15
- ];
7
+ const expected = ['packages', 'yargs-file-commands', 'src', 'lib', 'segmentPath', 'ts'];
16
8
  const result = segmentPath(fullPath, baseDir);
17
- assert.deepStrictEqual(result, expected);
9
+ expect(result).toEqual(expected);
18
10
  });
19
11
  it('should handle paths with periods correctly', () => {
20
12
  const fullPath = '/Users/username/Coding/Personal/yargs-file-commands/packages/yargs-file-commands/src/lib/segmentPath.test.ts';
21
13
  const baseDir = '/Users/username/Coding/Personal/yargs-file-commands/';
22
- const expected = [
23
- 'packages',
24
- 'yargs-file-commands',
25
- 'src',
26
- 'lib',
27
- 'segmentPath',
28
- 'test',
29
- 'ts'
30
- ];
14
+ const expected = ['packages', 'yargs-file-commands', 'src', 'lib', 'segmentPath', 'test', 'ts'];
31
15
  const result = segmentPath(fullPath, baseDir);
32
- assert.deepStrictEqual(result, expected);
16
+ expect(result).toEqual(expected);
33
17
  });
34
18
  it('should filter out "command" segments', () => {
35
19
  const fullPath = '/Users/username/Coding/Personal/yargs-file-commands/packages/yargs-file-commands/src/lib/commandPath.ts';
36
20
  const baseDir = '/Users/username/Coding/Personal/yargs-file-commands/';
37
- const expected = [
38
- 'packages',
39
- 'yargs-file-commands',
40
- 'src',
41
- 'lib',
42
- 'commandPath',
43
- 'ts'
44
- ];
21
+ const expected = ['packages', 'yargs-file-commands', 'src', 'lib', 'commandPath', 'ts'];
45
22
  const result = segmentPath(fullPath, baseDir);
46
- assert.deepStrictEqual(result, expected);
23
+ expect(result).toEqual(expected);
47
24
  });
48
25
  it('should handle empty segments correctly', () => {
49
26
  const fullPath = '/Users/username/Coding/Personal/yargs-file-commands/packages/yargs-file-commands/src/lib/.hiddenFile';
50
27
  const baseDir = '/Users/username/Coding/Personal/yargs-file-commands/';
51
- const expected = [
52
- 'packages',
53
- 'yargs-file-commands',
54
- 'src',
55
- 'lib',
56
- 'hiddenFile'
57
- ];
28
+ const expected = ['packages', 'yargs-file-commands', 'src', 'lib', 'hiddenFile'];
58
29
  const result = segmentPath(fullPath, baseDir);
59
- assert.deepStrictEqual(result, expected);
30
+ expect(result).toEqual(expected);
60
31
  });
61
32
  });
33
+ //# sourceMappingURL=segmentPath.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"segmentPath.test.js","sourceRoot":"","sources":["../../src/lib/segmentPath.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC;IAC5B,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE,CAAC;QAC1C,MAAM,QAAQ,GACZ,yGAAyG,CAAC;QAC5G,MAAM,OAAO,GAAG,sDAAsD,CAAC;QACvE,MAAM,QAAQ,GAAG,CAAC,UAAU,EAAE,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;QACxF,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAAA,CAClC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE,CAAC;QACrD,MAAM,QAAQ,GACZ,8GAA8G,CAAC;QACjH,MAAM,OAAO,GAAG,sDAAsD,CAAC;QACvE,MAAM,QAAQ,GAAG,CAAC,UAAU,EAAE,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;QAChG,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAAA,CAClC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE,CAAC;QAC/C,MAAM,QAAQ,GACZ,yGAAyG,CAAC;QAC5G,MAAM,OAAO,GAAG,sDAAsD,CAAC;QACvE,MAAM,QAAQ,GAAG,CAAC,UAAU,EAAE,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;QACxF,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAAA,CAClC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE,CAAC;QACjD,MAAM,QAAQ,GACZ,sGAAsG,CAAC;QACzG,MAAM,OAAO,GAAG,sDAAsD,CAAC;QACvE,MAAM,QAAQ,GAAG,CAAC,UAAU,EAAE,qBAAqB,EAAE,KAAK,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;QACjF,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAAA,CAClC,CAAC,CAAC;AAAA,CACJ,CAAC,CAAC"}