@vibe-agent-toolkit/utils 0.1.4 → 0.1.5

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.
@@ -11,4 +11,28 @@
11
11
  * await copyDirectory('/source/dir', '/dest/dir');
12
12
  */
13
13
  export declare function copyDirectory(src: string, dest: string): Promise<void>;
14
+ /**
15
+ * Verify that a file exists with the exact case-sensitive filename.
16
+ *
17
+ * On case-insensitive filesystems (Windows, macOS), a file might be found even if
18
+ * the case doesn't match. This function checks that the actual filename on disk
19
+ * matches the requested path exactly (case-sensitive).
20
+ *
21
+ * @param filePath - Absolute path to the file to verify
22
+ * @returns Object with exists flag and actual filename (or null if not found)
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * // On case-insensitive filesystem with file "README.md"
27
+ * const result1 = await verifyCaseSensitiveFilename('/project/README.md');
28
+ * // { exists: true, actualName: 'README.md' }
29
+ *
30
+ * const result2 = await verifyCaseSensitiveFilename('/project/readme.md');
31
+ * // { exists: false, actualName: 'README.md' } - case mismatch!
32
+ * ```
33
+ */
34
+ export declare function verifyCaseSensitiveFilename(filePath: string): Promise<{
35
+ exists: boolean;
36
+ actualName: string | null;
37
+ }>;
14
38
  //# sourceMappingURL=fs-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fs-utils.d.ts","sourceRoot":"","sources":["../src/fs-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5E"}
1
+ {"version":3,"file":"fs-utils.d.ts","sourceRoot":"","sources":["../src/fs-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAmCzD"}
package/dist/fs-utils.js CHANGED
@@ -28,4 +28,54 @@ export async function copyDirectory(src, dest) {
28
28
  }
29
29
  }
30
30
  }
31
+ /**
32
+ * Verify that a file exists with the exact case-sensitive filename.
33
+ *
34
+ * On case-insensitive filesystems (Windows, macOS), a file might be found even if
35
+ * the case doesn't match. This function checks that the actual filename on disk
36
+ * matches the requested path exactly (case-sensitive).
37
+ *
38
+ * @param filePath - Absolute path to the file to verify
39
+ * @returns Object with exists flag and actual filename (or null if not found)
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * // On case-insensitive filesystem with file "README.md"
44
+ * const result1 = await verifyCaseSensitiveFilename('/project/README.md');
45
+ * // { exists: true, actualName: 'README.md' }
46
+ *
47
+ * const result2 = await verifyCaseSensitiveFilename('/project/readme.md');
48
+ * // { exists: false, actualName: 'README.md' } - case mismatch!
49
+ * ```
50
+ */
51
+ export async function verifyCaseSensitiveFilename(filePath) {
52
+ // Get parent directory and expected filename
53
+ const parentDir = path.dirname(filePath);
54
+ const expectedName = path.basename(filePath);
55
+ // Read actual directory entries
56
+ let entries;
57
+ try {
58
+ // eslint-disable-next-line security/detect-non-literal-fs-filename -- parentDir from validated path
59
+ entries = await fs.readdir(parentDir);
60
+ }
61
+ catch {
62
+ // Parent directory doesn't exist
63
+ return { exists: false, actualName: null };
64
+ }
65
+ // Find the actual filename (case-sensitive exact match)
66
+ const exactMatch = entries.find(entry => entry === expectedName);
67
+ if (exactMatch) {
68
+ // Found exact case match - file exists with correct case
69
+ return { exists: true, actualName: exactMatch };
70
+ }
71
+ // No exact match - check for case-insensitive match
72
+ const caseInsensitiveMatch = entries.find(entry => entry.toLowerCase() === expectedName.toLowerCase());
73
+ // Return result:
74
+ // - If case-insensitive match found: exists=false (wrong case), actualName=<actual>
75
+ // - If no match at all: exists=false, actualName=null
76
+ return {
77
+ exists: false,
78
+ actualName: caseInsensitiveMatch ?? null,
79
+ };
80
+ }
31
81
  //# sourceMappingURL=fs-utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fs-utils.js","sourceRoot":"","sources":["../src/fs-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,IAAY;IAC3D,mGAAmG;IACnG,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,mGAAmG;IACnG,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE7C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"fs-utils.js","sourceRoot":"","sources":["../src/fs-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,IAAY;IAC3D,mGAAmG;IACnG,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,mGAAmG;IACnG,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE7C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,QAAgB;IAEhB,6CAA6C;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAE7C,gCAAgC;IAChC,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,oGAAoG;QACpG,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,iCAAiC;QACjC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IAC7C,CAAC;IAED,wDAAwD;IACxD,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC;IAEjE,IAAI,UAAU,EAAE,CAAC;QACf,yDAAyD;QACzD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,CAAC;IAClD,CAAC;IAED,oDAAoD;IACpD,MAAM,oBAAoB,GAAG,OAAO,CAAC,IAAI,CACvC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,YAAY,CAAC,WAAW,EAAE,CAC5D,CAAC;IAEF,iBAAiB;IACjB,oFAAoF;IACpF,sDAAsD;IACtD,OAAO;QACL,MAAM,EAAE,KAAK;QACb,UAAU,EAAE,oBAAoB,IAAI,IAAI;KACzC,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-agent-toolkit/utils",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "description": "Core utility functions with no external dependencies",
6
6
  "keywords": [