abapgit-agent 1.8.5 → 1.8.7

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.
@@ -3,8 +3,30 @@
3
3
  */
4
4
  const pathModule = require('path');
5
5
  const fs = require('fs');
6
+ const os = require('os');
6
7
  const https = require('https');
7
8
 
9
+ /**
10
+ * Get cache directory for abapgit-agent
11
+ * Follows OS-specific conventions:
12
+ * - Windows: %LOCALAPPDATA%\abapgit-agent\cache
13
+ * - Linux/macOS: ~/.cache/abapgit-agent (respects XDG_CACHE_HOME)
14
+ * @returns {string} Cache directory path
15
+ */
16
+ function getCacheDir() {
17
+ const homeDir = os.homedir();
18
+
19
+ // Windows: %LOCALAPPDATA%\abapgit-agent\cache
20
+ if (process.platform === 'win32') {
21
+ const localAppData = process.env.LOCALAPPDATA || pathModule.join(homeDir, 'AppData', 'Local');
22
+ return pathModule.join(localAppData, 'abapgit-agent', 'cache');
23
+ }
24
+
25
+ // Linux/macOS: respect XDG_CACHE_HOME or use ~/.cache
26
+ const xdgCache = process.env.XDG_CACHE_HOME || pathModule.join(homeDir, '.cache');
27
+ return pathModule.join(xdgCache, 'abapgit-agent');
28
+ }
29
+
8
30
  /**
9
31
  * Get CLI version from package.json
10
32
  * @returns {string} CLI version or '1.0.0' as default
@@ -74,7 +96,166 @@ async function checkCompatibility(config) {
74
96
  }
75
97
  }
76
98
 
99
+ /**
100
+ * Get configured npm registry URL
101
+ * Respects user's npm config (e.g., corporate mirrors, regional mirrors)
102
+ * @returns {string} Registry URL
103
+ */
104
+ function getNpmRegistry() {
105
+ try {
106
+ const { execSync } = require('child_process');
107
+ const registry = execSync('npm config get registry', {
108
+ encoding: 'utf8',
109
+ stdio: ['pipe', 'pipe', 'ignore'] // Suppress stderr
110
+ }).trim();
111
+
112
+ // Validate registry URL
113
+ if (registry && registry.startsWith('http')) {
114
+ return registry;
115
+ }
116
+ } catch (e) {
117
+ // Fall back to default if npm config fails
118
+ }
119
+
120
+ // Default npm registry
121
+ return 'https://registry.npmjs.org/';
122
+ }
123
+
124
+ /**
125
+ * Get latest version from npm registry
126
+ * Respects user's configured npm registry (mirrors, corporate proxies, etc.)
127
+ * @returns {Promise<string|null>} Latest version or null on error
128
+ */
129
+ async function getLatestNpmVersion() {
130
+ return new Promise((resolve) => {
131
+ try {
132
+ const registry = getNpmRegistry();
133
+ // Ensure registry ends with /
134
+ const baseUrl = registry.endsWith('/') ? registry : registry + '/';
135
+ const url = `${baseUrl}abapgit-agent/latest`;
136
+
137
+ https.get(url, (res) => {
138
+ let body = '';
139
+ res.on('data', chunk => body += chunk);
140
+ res.on('end', () => {
141
+ try {
142
+ const data = JSON.parse(body);
143
+ resolve(data.version || null);
144
+ } catch (e) {
145
+ resolve(null);
146
+ }
147
+ });
148
+ }).on('error', () => resolve(null));
149
+ } catch (e) {
150
+ resolve(null);
151
+ }
152
+ });
153
+ }
154
+
155
+ /**
156
+ * Compare two semver versions
157
+ * @param {string} a - Version A (e.g., "1.9.0")
158
+ * @param {string} b - Version B (e.g., "1.8.6")
159
+ * @returns {number} 1 if a > b, -1 if a < b, 0 if equal
160
+ */
161
+ function compareVersions(a, b) {
162
+ const aParts = a.split('.').map(Number);
163
+ const bParts = b.split('.').map(Number);
164
+
165
+ for (let i = 0; i < 3; i++) {
166
+ if (aParts[i] > bParts[i]) return 1;
167
+ if (aParts[i] < bParts[i]) return -1;
168
+ }
169
+ return 0;
170
+ }
171
+
172
+ /**
173
+ * Check for new version availability with daily caching
174
+ * Cache file location (OS-specific):
175
+ * - Linux/macOS: ~/.cache/abapgit-agent/version-check.json
176
+ * - Windows: %LOCALAPPDATA%\abapgit-agent\cache\version-check.json
177
+ * Format: { lastCheck: timestamp, latestVersion: "1.9.0" }
178
+ * @returns {Promise<object>} { hasNewVersion, latestVersion, currentVersion }
179
+ */
180
+ async function checkForNewVersion() {
181
+ const cliVersion = getCliVersion();
182
+ const cacheFile = pathModule.join(getCacheDir(), 'version-check.json');
183
+ const now = Date.now();
184
+ const ONE_DAY = 24 * 60 * 60 * 1000;
185
+
186
+ // Read cache if exists and less than 24 hours old
187
+ if (fs.existsSync(cacheFile)) {
188
+ try {
189
+ const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
190
+ if (now - cache.lastCheck < ONE_DAY && cache.latestVersion) {
191
+ // Use cached result
192
+ return {
193
+ hasNewVersion: compareVersions(cache.latestVersion, cliVersion) > 0,
194
+ latestVersion: cache.latestVersion,
195
+ currentVersion: cliVersion
196
+ };
197
+ }
198
+ } catch (e) {
199
+ // Invalid cache, continue to fetch
200
+ }
201
+ }
202
+
203
+ // Fetch latest version from npm
204
+ const latestVersion = await getLatestNpmVersion();
205
+
206
+ if (latestVersion) {
207
+ // Write cache
208
+ try {
209
+ const cacheDir = pathModule.dirname(cacheFile);
210
+ if (!fs.existsSync(cacheDir)) {
211
+ fs.mkdirSync(cacheDir, { recursive: true });
212
+ }
213
+ fs.writeFileSync(cacheFile, JSON.stringify({
214
+ lastCheck: now,
215
+ latestVersion: latestVersion
216
+ }));
217
+ } catch (e) {
218
+ // Ignore cache write errors
219
+ }
220
+
221
+ return {
222
+ hasNewVersion: compareVersions(latestVersion, cliVersion) > 0,
223
+ latestVersion: latestVersion,
224
+ currentVersion: cliVersion
225
+ };
226
+ }
227
+
228
+ // Failed to fetch, return no update
229
+ return {
230
+ hasNewVersion: false,
231
+ latestVersion: null,
232
+ currentVersion: cliVersion
233
+ };
234
+ }
235
+
236
+ /**
237
+ * Show new version reminder at end of command output
238
+ * Non-blocking, silent on error
239
+ */
240
+ async function showNewVersionReminder() {
241
+ try {
242
+ const { hasNewVersion, latestVersion, currentVersion } = await checkForNewVersion();
243
+
244
+ if (hasNewVersion) {
245
+ console.log('');
246
+ console.log(`💡 New version available: ${latestVersion} (current: ${currentVersion})`);
247
+ console.log(` Run: abapgit-agent upgrade`);
248
+ }
249
+ } catch (e) {
250
+ // Silent - don't interrupt user's workflow
251
+ }
252
+ }
253
+
77
254
  module.exports = {
78
255
  getCliVersion,
79
- checkCompatibility
256
+ checkCompatibility,
257
+ getLatestNpmVersion,
258
+ compareVersions,
259
+ checkForNewVersion,
260
+ showNewVersionReminder
80
261
  };