@zapier/zapier-sdk-cli 0.13.16 → 0.14.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/CHANGELOG.md +12 -0
- package/dist/cli.cjs +296 -20
- package/dist/cli.mjs +296 -22
- package/dist/index.cjs +29 -5
- package/dist/index.mjs +30 -6
- package/dist/package.json +4 -1
- package/dist/src/cli.js +32 -2
- package/dist/src/plugins/login/index.js +0 -2
- package/dist/src/utils/auth/login.js +3 -2
- package/dist/src/utils/cli-generator.js +10 -2
- package/dist/src/utils/errors.d.ts +16 -0
- package/dist/src/utils/errors.js +19 -0
- package/dist/src/utils/log.d.ts +1 -0
- package/dist/src/utils/log.js +5 -0
- package/dist/src/utils/package-manager-detector.d.ts +16 -0
- package/dist/src/utils/package-manager-detector.js +77 -0
- package/dist/src/utils/parameter-resolver.js +6 -5
- package/dist/src/utils/spinner.js +9 -1
- package/dist/src/utils/version-checker.d.ts +17 -0
- package/dist/src/utils/version-checker.js +154 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +4 -1
- package/src/cli.ts +34 -2
- package/src/plugins/login/index.ts +0 -3
- package/src/utils/auth/login.ts +7 -3
- package/src/utils/cli-generator.ts +15 -2
- package/src/utils/errors.ts +26 -0
- package/src/utils/log.ts +5 -0
- package/src/utils/package-manager-detector.ts +83 -0
- package/src/utils/parameter-resolver.ts +6 -5
- package/src/utils/spinner.ts +8 -1
- package/src/utils/version-checker.test.ts +199 -0
- package/src/utils/version-checker.ts +236 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import packageJsonLib from "package-json";
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import log from "./log";
|
|
4
|
+
import Conf from "conf";
|
|
5
|
+
import { getUpdateCommand } from "./package-manager-detector";
|
|
6
|
+
|
|
7
|
+
interface VersionInfo {
|
|
8
|
+
hasUpdate: boolean;
|
|
9
|
+
latestVersion?: string;
|
|
10
|
+
currentVersion: string;
|
|
11
|
+
isDeprecated: boolean;
|
|
12
|
+
deprecationMessage?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface CachedPackageInfo {
|
|
16
|
+
version: string;
|
|
17
|
+
deprecated?: string | boolean;
|
|
18
|
+
fetched_at: string; // ISO date string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface VersionCache {
|
|
22
|
+
last_reset_timestamp: number; // Unix timestamp in milliseconds
|
|
23
|
+
packages: {
|
|
24
|
+
[packageName: string]: {
|
|
25
|
+
[version: string]: CachedPackageInfo;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let config: Conf | null = null;
|
|
31
|
+
|
|
32
|
+
function getConfig(): Conf {
|
|
33
|
+
if (!config) {
|
|
34
|
+
config = new Conf({ projectName: "zapier-sdk-cli" });
|
|
35
|
+
}
|
|
36
|
+
return config;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const ONE_DAY_MS = 24 * 60 * 60 * 1000;
|
|
40
|
+
|
|
41
|
+
const CACHE_RESET_INTERVAL_MS = (() => {
|
|
42
|
+
const { ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS = `${ONE_DAY_MS}` } = process.env;
|
|
43
|
+
const interval = parseInt(ZAPIER_SDK_UPDATE_CHECK_INTERVAL_MS);
|
|
44
|
+
if (isNaN(interval) || interval < 0) {
|
|
45
|
+
return -1;
|
|
46
|
+
}
|
|
47
|
+
return interval;
|
|
48
|
+
})();
|
|
49
|
+
|
|
50
|
+
function getVersionCache(): VersionCache {
|
|
51
|
+
try {
|
|
52
|
+
const cache = getConfig().get("version_cache") as VersionCache | undefined;
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
|
|
55
|
+
// If no cache, missing timestamp, or it's been more than a day, reset the cache
|
|
56
|
+
if (
|
|
57
|
+
!cache ||
|
|
58
|
+
!cache.last_reset_timestamp ||
|
|
59
|
+
now - cache.last_reset_timestamp >= CACHE_RESET_INTERVAL_MS
|
|
60
|
+
) {
|
|
61
|
+
const newCache: VersionCache = {
|
|
62
|
+
last_reset_timestamp: now,
|
|
63
|
+
packages: {},
|
|
64
|
+
};
|
|
65
|
+
getConfig().set("version_cache", newCache);
|
|
66
|
+
return newCache;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return cache;
|
|
70
|
+
} catch (error) {
|
|
71
|
+
log.debug(`Failed to read version cache: ${error}`);
|
|
72
|
+
return {
|
|
73
|
+
last_reset_timestamp: Date.now(),
|
|
74
|
+
packages: {},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function setCachedPackageInfo(
|
|
80
|
+
packageName: string,
|
|
81
|
+
version: string,
|
|
82
|
+
info: CachedPackageInfo,
|
|
83
|
+
): void {
|
|
84
|
+
try {
|
|
85
|
+
const cache = getVersionCache();
|
|
86
|
+
if (!cache.packages[packageName]) {
|
|
87
|
+
cache.packages[packageName] = {};
|
|
88
|
+
}
|
|
89
|
+
cache.packages[packageName][version] = info;
|
|
90
|
+
getConfig().set("version_cache", cache);
|
|
91
|
+
} catch (error) {
|
|
92
|
+
log.debug(`Failed to cache package info: ${error}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function getCachedPackageInfo(
|
|
97
|
+
packageName: string,
|
|
98
|
+
version: string,
|
|
99
|
+
): CachedPackageInfo | undefined {
|
|
100
|
+
try {
|
|
101
|
+
const cache = getVersionCache();
|
|
102
|
+
return cache.packages[packageName]?.[version];
|
|
103
|
+
} catch (error) {
|
|
104
|
+
log.debug(`Failed to get cached package info: ${error}`);
|
|
105
|
+
return undefined;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async function fetchCachedPackageInfo(
|
|
110
|
+
packageName: string,
|
|
111
|
+
version?: string,
|
|
112
|
+
): Promise<CachedPackageInfo> {
|
|
113
|
+
const cacheKey = version || "latest";
|
|
114
|
+
|
|
115
|
+
// Try cache first
|
|
116
|
+
let cachedInfo = getCachedPackageInfo(packageName, cacheKey);
|
|
117
|
+
if (cachedInfo) {
|
|
118
|
+
return cachedInfo;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Not in cache, fetch from npm
|
|
122
|
+
const packageInfo = await packageJsonLib(packageName, {
|
|
123
|
+
version,
|
|
124
|
+
fullMetadata: true,
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
const info: CachedPackageInfo = {
|
|
128
|
+
version: packageInfo.version,
|
|
129
|
+
deprecated: packageInfo.deprecated,
|
|
130
|
+
fetched_at: new Date().toISOString(),
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Cache for next time
|
|
134
|
+
setCachedPackageInfo(packageName, cacheKey, info);
|
|
135
|
+
|
|
136
|
+
return info;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export async function checkForUpdates({
|
|
140
|
+
packageName,
|
|
141
|
+
currentVersion,
|
|
142
|
+
}: {
|
|
143
|
+
packageName: string;
|
|
144
|
+
currentVersion: string;
|
|
145
|
+
}): Promise<VersionInfo> {
|
|
146
|
+
try {
|
|
147
|
+
// Get latest version info (with caching)
|
|
148
|
+
const latestPackageInfo = await fetchCachedPackageInfo(packageName);
|
|
149
|
+
const latestVersion = latestPackageInfo.version;
|
|
150
|
+
const hasUpdate = currentVersion !== latestVersion;
|
|
151
|
+
|
|
152
|
+
// Check deprecation status of the current version (with caching)
|
|
153
|
+
let currentPackageInfo: CachedPackageInfo;
|
|
154
|
+
try {
|
|
155
|
+
currentPackageInfo = await fetchCachedPackageInfo(
|
|
156
|
+
packageName,
|
|
157
|
+
currentVersion,
|
|
158
|
+
);
|
|
159
|
+
} catch (error) {
|
|
160
|
+
// If we can't fetch the current version info, use the latest version info
|
|
161
|
+
log.debug(`Failed to check deprecation for current version: ${error}`);
|
|
162
|
+
currentPackageInfo = latestPackageInfo;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const isDeprecated = Boolean(currentPackageInfo.deprecated);
|
|
166
|
+
const deprecationMessage = isDeprecated
|
|
167
|
+
? String(currentPackageInfo.deprecated)
|
|
168
|
+
: undefined;
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
hasUpdate,
|
|
172
|
+
latestVersion,
|
|
173
|
+
currentVersion,
|
|
174
|
+
isDeprecated,
|
|
175
|
+
deprecationMessage,
|
|
176
|
+
};
|
|
177
|
+
} catch (error) {
|
|
178
|
+
// If we can't check for updates (network issues, etc.), fail silently
|
|
179
|
+
log.debug(`Failed to check for updates: ${error}`);
|
|
180
|
+
return {
|
|
181
|
+
hasUpdate: false,
|
|
182
|
+
currentVersion,
|
|
183
|
+
isDeprecated: false,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function displayUpdateNotification(
|
|
189
|
+
versionInfo: VersionInfo,
|
|
190
|
+
packageName: string,
|
|
191
|
+
): void {
|
|
192
|
+
if (versionInfo.isDeprecated) {
|
|
193
|
+
console.error();
|
|
194
|
+
console.error(
|
|
195
|
+
chalk.red.bold("⚠️ DEPRECATION WARNING") +
|
|
196
|
+
chalk.red(
|
|
197
|
+
` - ${packageName} v${versionInfo.currentVersion} is deprecated.`,
|
|
198
|
+
),
|
|
199
|
+
);
|
|
200
|
+
if (versionInfo.deprecationMessage) {
|
|
201
|
+
console.error(chalk.red(` ${versionInfo.deprecationMessage}`));
|
|
202
|
+
}
|
|
203
|
+
console.error(chalk.red(` Please update to the latest version.`));
|
|
204
|
+
console.error();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (versionInfo.hasUpdate) {
|
|
208
|
+
console.log();
|
|
209
|
+
console.log(
|
|
210
|
+
chalk.yellow.bold("📦 Update available!") +
|
|
211
|
+
chalk.yellow(
|
|
212
|
+
` ${packageName} v${versionInfo.currentVersion} → v${versionInfo.latestVersion}`,
|
|
213
|
+
),
|
|
214
|
+
);
|
|
215
|
+
console.log(
|
|
216
|
+
chalk.yellow(
|
|
217
|
+
` Run ${chalk.bold(getUpdateCommand(packageName))} to update.`,
|
|
218
|
+
),
|
|
219
|
+
);
|
|
220
|
+
console.log();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export async function checkAndNotifyUpdates({
|
|
225
|
+
packageName,
|
|
226
|
+
currentVersion,
|
|
227
|
+
}: {
|
|
228
|
+
packageName: string;
|
|
229
|
+
currentVersion: string;
|
|
230
|
+
}): Promise<void> {
|
|
231
|
+
if (CACHE_RESET_INTERVAL_MS < 0) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const versionInfo = await checkForUpdates({ packageName, currentVersion });
|
|
235
|
+
displayUpdateNotification(versionInfo, packageName);
|
|
236
|
+
}
|