1
+ import { homedir } from 'os' ;
2
+ import { join } from 'path' ;
3
+ import { existsSync , mkdirSync , readFileSync , writeFileSync } from 'fs' ;
4
+ import { Logger } from './logger.js' ;
5
+ import semver from 'semver' ;
6
+
7
+ const logger = new Logger ( { name : 'version-cache' } ) ;
8
+
9
+ /**
10
+ * Interface for the version cache data structure
11
+ */
12
+ export interface VersionCacheData {
13
+ /** The cached version string */
14
+ version : string ;
15
+ }
16
+
17
+ /**
18
+ * Class to manage version cache in the user's home directory
19
+ */
20
+ export class VersionCache {
21
+ private readonly cacheDir : string ;
22
+ private readonly cacheFile : string ;
23
+
24
+ constructor ( ) {
25
+ this . cacheDir = join ( homedir ( ) , '.mycoder' ) ;
26
+ this . cacheFile = join ( this . cacheDir , 'version-cache.json' ) ;
27
+
28
+ // Ensure cache directory exists
29
+ this . ensureCacheDir ( ) ;
30
+ }
31
+
32
+ /**
33
+ * Ensures the cache directory exists
34
+ */
35
+ private ensureCacheDir ( ) : void {
36
+ try {
37
+ if ( ! existsSync ( this . cacheDir ) ) {
38
+ mkdirSync ( this . cacheDir , { recursive : true } ) ;
39
+ }
40
+ } catch ( error ) {
41
+ logger . warn (
42
+ 'Failed to create cache directory ~/.mycoder:' ,
43
+ error instanceof Error ? error . message : String ( error )
44
+ ) ;
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Reads the cache data from disk
50
+ * @returns The cached data or null if not found/invalid
51
+ */
52
+ read ( ) : VersionCacheData | null {
53
+ try {
54
+ if ( ! existsSync ( this . cacheFile ) ) {
55
+ return null ;
56
+ }
57
+
58
+ const data = JSON . parse (
59
+ readFileSync ( this . cacheFile , 'utf-8' )
60
+ ) as VersionCacheData ;
61
+
62
+ // Validate required fields
63
+ if ( ! data || typeof data . version !== 'string' ) {
64
+ return null ;
65
+ }
66
+
67
+ return data ;
68
+ } catch ( error ) {
69
+ logger . warn (
70
+ 'Error reading version cache:' ,
71
+ error instanceof Error ? error . message : String ( error )
72
+ ) ;
73
+ return null ;
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Writes data to the cache file
79
+ * @param data The version cache data to write
80
+ */
81
+ write ( data : VersionCacheData ) : void {
82
+ try {
83
+ writeFileSync ( this . cacheFile , JSON . stringify ( data , null , 2 ) ) ;
84
+ } catch ( error ) {
85
+ logger . warn (
86
+ 'Error writing version cache:' ,
87
+ error instanceof Error ? error . message : String ( error )
88
+ ) ;
89
+ }
90
+ }
91
+
92
+ /**
93
+ * Checks if the cached version is greater than the current version
94
+ * @param currentVersion The current package version
95
+ * @returns true if cached version > current version, false otherwise
96
+ */
97
+ shouldCheckServer ( currentVersion : string ) : boolean {
98
+ try {
99
+ const data = this . read ( ) ;
100
+ if ( ! data ) {
101
+ return true ; // No cache, should check server
102
+ }
103
+
104
+ // If cached version is greater than current, we should check server
105
+ // as an upgrade is likely available
106
+ return semver . gt ( data . version , currentVersion ) ;
107
+ } catch ( error ) {
108
+ logger . warn (
109
+ 'Error comparing versions:' ,
110
+ error instanceof Error ? error . message : String ( error )
111
+ ) ;
112
+ return true ; // On error, check server to be safe
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Clears the cache file
118
+ */
119
+ clear ( ) : void {
120
+ try {
121
+ if ( existsSync ( this . cacheFile ) ) {
122
+ writeFileSync ( this . cacheFile , '' ) ;
123
+ }
124
+ } catch ( error ) {
125
+ logger . warn (
126
+ 'Error clearing version cache:' ,
127
+ error instanceof Error ? error . message : String ( error )
128
+ ) ;
129
+ }
130
+ }
131
+ }
0 commit comments