@superblocksteam/sdk 2.0.3-next.162 → 2.0.3-next.163
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/dist/cli-replacement/automatic-upgrades.d.ts.map +1 -1
- package/dist/cli-replacement/automatic-upgrades.js +140 -122
- package/dist/cli-replacement/automatic-upgrades.js.map +1 -1
- package/package.json +3 -3
- package/src/cli-replacement/automatic-upgrades.ts +177 -158
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as child_process from "node:child_process";
|
|
2
2
|
import { promisify } from "node:util";
|
|
3
3
|
import { isNativeError } from "node:util/types";
|
|
4
|
-
import { isEqual, pickBy } from "lodash-es";
|
|
5
4
|
import { resolveCommand, type DetectResult } from "package-manager-detector";
|
|
6
5
|
import { detect } from "package-manager-detector/detect";
|
|
7
6
|
import gt from "semver/functions/gt.js";
|
|
@@ -18,6 +17,11 @@ interface Versions {
|
|
|
18
17
|
[pkg: string]: string;
|
|
19
18
|
}
|
|
20
19
|
|
|
20
|
+
interface PackageVersionInfo {
|
|
21
|
+
version: string;
|
|
22
|
+
alias?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
21
25
|
interface CheckVersionsErrorResponse {
|
|
22
26
|
responseMeta: ResponseMeta;
|
|
23
27
|
}
|
|
@@ -27,7 +31,7 @@ interface CheckVersionsSuccessResponse {
|
|
|
27
31
|
responseMeta: ResponseMeta;
|
|
28
32
|
}
|
|
29
33
|
|
|
30
|
-
async function
|
|
34
|
+
async function getRemoteVersions(
|
|
31
35
|
config: ApplicationConfig,
|
|
32
36
|
): Promise<Versions | undefined> {
|
|
33
37
|
const { token, superblocksBaseUrl, id } = config;
|
|
@@ -40,9 +44,7 @@ async function getRemoteCliLibraryVersions(
|
|
|
40
44
|
),
|
|
41
45
|
{
|
|
42
46
|
method: "GET",
|
|
43
|
-
headers: {
|
|
44
|
-
Authorization: `Bearer ${token}`,
|
|
45
|
-
},
|
|
47
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
46
48
|
},
|
|
47
49
|
);
|
|
48
50
|
|
|
@@ -64,57 +66,18 @@ async function getRemoteCliLibraryVersions(
|
|
|
64
66
|
}
|
|
65
67
|
}
|
|
66
68
|
|
|
67
|
-
async function
|
|
68
|
-
const installCommand = resolveCommand(
|
|
69
|
-
pm.agent,
|
|
70
|
-
"install",
|
|
71
|
-
Object.entries(versions).map(
|
|
72
|
-
([pkg, version]) => `@superblocksteam/${pkg}@${version}`,
|
|
73
|
-
),
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
if (!installCommand) {
|
|
77
|
-
console.error(
|
|
78
|
-
"We could not determine how to upgrade your Superblocks packages.",
|
|
79
|
-
);
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const { command, args } = installCommand;
|
|
84
|
-
|
|
85
|
-
// upgrade packages
|
|
86
|
-
return await exec(`${command} ${args.join(" ")}`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
async function findSuperblocksExecutable(): Promise<string | undefined> {
|
|
69
|
+
async function getCurrentCliVersion(): Promise<string | undefined> {
|
|
90
70
|
try {
|
|
91
|
-
// Use cross-platform approach to find superblocks executable
|
|
92
71
|
const command = process.platform === "win32" ? "where" : "which";
|
|
93
72
|
const { stdout } = await exec(`${command} superblocks`);
|
|
94
|
-
|
|
95
|
-
} catch {
|
|
96
|
-
return undefined;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
73
|
+
const superblocksPath = stdout.trim();
|
|
99
74
|
|
|
100
|
-
|
|
101
|
-
pm: DetectResult,
|
|
102
|
-
): Promise<Partial<Versions>> {
|
|
103
|
-
return {
|
|
104
|
-
cli: await getLocalCliVersion(),
|
|
105
|
-
library: await getLocalPackageVersion(pm, "library"),
|
|
106
|
-
};
|
|
107
|
-
}
|
|
75
|
+
if (!superblocksPath) return undefined;
|
|
108
76
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return undefined;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const { stdout } = await exec(`${superblocksPath} version --json`);
|
|
117
|
-
const json = JSON.parse(stdout) as Record<string, string>;
|
|
77
|
+
const { stdout: versionOutput } = await exec(
|
|
78
|
+
`${superblocksPath} version --json`,
|
|
79
|
+
);
|
|
80
|
+
const json = JSON.parse(versionOutput) as Record<string, string>;
|
|
118
81
|
// Extract version from string like "@superblocksteam/cli/2.0.0-next.1" or "@superblocksteam/cli-ephemeral/2.0.0-SNAPSHOT.1749077365"
|
|
119
82
|
return json.cliVersion?.replace(/@superblocksteam\/cli(-ephemeral)?\//, "");
|
|
120
83
|
} catch (error) {
|
|
@@ -125,99 +88,153 @@ async function getLocalCliVersion(): Promise<string | undefined> {
|
|
|
125
88
|
}
|
|
126
89
|
}
|
|
127
90
|
|
|
128
|
-
async function
|
|
91
|
+
async function getCurrentLibraryVersion(
|
|
129
92
|
pm: DetectResult,
|
|
130
|
-
|
|
131
|
-
global?: boolean,
|
|
132
|
-
) {
|
|
93
|
+
): Promise<PackageVersionInfo | undefined> {
|
|
133
94
|
try {
|
|
134
|
-
// Configure commands and parsing logic based on package manager type
|
|
135
95
|
switch (pm.agent) {
|
|
136
|
-
case "npm":
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
cwd: process.cwd(),
|
|
141
|
-
},
|
|
142
|
-
);
|
|
143
|
-
const parsed = JSON.parse(stdout);
|
|
144
|
-
return (
|
|
145
|
-
parsed.dependencies?.[`@superblocksteam/${pkg}`]?.version ??
|
|
146
|
-
parsed.devDependencies?.[`@superblocksteam/${pkg}`]?.version
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
case "pnpm": {
|
|
150
|
-
const { stdout } = await exec(
|
|
151
|
-
`pnpm list ${global ? "--global" : ""} @superblocksteam/${pkg} --json`,
|
|
152
|
-
{ cwd: process.cwd() },
|
|
153
|
-
);
|
|
154
|
-
const parsed = JSON.parse(stdout);
|
|
155
|
-
// Check the structure based on actual output
|
|
156
|
-
return (
|
|
157
|
-
parsed[0]?.dependencies?.[`@superblocksteam/${pkg}`]?.version ??
|
|
158
|
-
parsed[0]?.devDependencies?.[`@superblocksteam/${pkg}`]?.version
|
|
159
|
-
);
|
|
160
|
-
}
|
|
96
|
+
case "npm":
|
|
97
|
+
return await getNpmLibraryVersion();
|
|
98
|
+
case "pnpm":
|
|
99
|
+
return await getPnpmLibraryVersion();
|
|
161
100
|
default:
|
|
162
101
|
console.error(
|
|
163
|
-
`${pm.agent} is currently not supported
|
|
102
|
+
`${pm.agent} is currently not supported for automatic upgrades.`,
|
|
164
103
|
);
|
|
165
|
-
return;
|
|
104
|
+
return undefined;
|
|
166
105
|
}
|
|
167
|
-
} catch (
|
|
106
|
+
} catch (error) {
|
|
168
107
|
console.error(
|
|
169
|
-
"
|
|
108
|
+
"Could not resolve current library version. Skipping automatic upgrade.",
|
|
170
109
|
);
|
|
171
|
-
console.error(
|
|
172
|
-
return;
|
|
110
|
+
console.error(error);
|
|
111
|
+
return undefined;
|
|
173
112
|
}
|
|
174
113
|
}
|
|
175
114
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
115
|
+
async function getNpmLibraryVersion(): Promise<PackageVersionInfo | undefined> {
|
|
116
|
+
const { stdout } = await exec("npm list @superblocksteam/library --json", {
|
|
117
|
+
cwd: process.cwd(),
|
|
118
|
+
});
|
|
119
|
+
const parsed = JSON.parse(stdout);
|
|
120
|
+
const packageData =
|
|
121
|
+
parsed.dependencies?.["@superblocksteam/library"] ??
|
|
122
|
+
parsed.devDependencies?.["@superblocksteam/library"];
|
|
123
|
+
|
|
124
|
+
if (!packageData?.version) return undefined;
|
|
125
|
+
|
|
126
|
+
// Check if this is an alias by examining the resolved URL
|
|
127
|
+
const resolved = packageData.resolved;
|
|
128
|
+
if (resolved && resolved.includes("@superblocksteam/")) {
|
|
129
|
+
const aliasMatch = resolved.match(/@superblocksteam\/([^\/]+)/);
|
|
130
|
+
if (aliasMatch && aliasMatch[1] !== "library") {
|
|
131
|
+
return {
|
|
132
|
+
version: packageData.version,
|
|
133
|
+
alias: `@superblocksteam/${aliasMatch[1]}`,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return { version: packageData.version };
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
async function getPnpmLibraryVersion(): Promise<
|
|
142
|
+
{ version: string; alias?: string } | undefined
|
|
143
|
+
> {
|
|
144
|
+
// First try the original package name
|
|
145
|
+
let packageData: any;
|
|
146
|
+
|
|
181
147
|
try {
|
|
182
|
-
const
|
|
183
|
-
|
|
184
|
-
|
|
148
|
+
const result = await exec("pnpm list @superblocksteam/library --json", {
|
|
149
|
+
cwd: process.cwd(),
|
|
150
|
+
});
|
|
151
|
+
const parsed = JSON.parse(result.stdout);
|
|
152
|
+
packageData =
|
|
153
|
+
parsed[0]?.dependencies?.["@superblocksteam/library"] ??
|
|
154
|
+
parsed[0]?.devDependencies?.["@superblocksteam/library"];
|
|
155
|
+
} catch {
|
|
156
|
+
// Package not found with original name, might be aliased
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// If not found, try the ephemeral alias
|
|
160
|
+
if (!packageData?.version) {
|
|
161
|
+
try {
|
|
162
|
+
const aliasResult = await exec(
|
|
163
|
+
"pnpm list @superblocksteam/library-ephemeral --json",
|
|
164
|
+
{ cwd: process.cwd() },
|
|
165
|
+
);
|
|
166
|
+
const aliasParsed = JSON.parse(aliasResult.stdout);
|
|
167
|
+
packageData =
|
|
168
|
+
aliasParsed[0]?.dependencies?.["@superblocksteam/library"] ??
|
|
169
|
+
aliasParsed[0]?.devDependencies?.["@superblocksteam/library"];
|
|
170
|
+
} catch {
|
|
171
|
+
return undefined;
|
|
185
172
|
}
|
|
173
|
+
}
|
|
186
174
|
|
|
187
|
-
|
|
188
|
-
// We'll try running the update command with --version to see if it shows an updatable message
|
|
189
|
-
const { stdout } = await exec(
|
|
190
|
-
`${superblocksPath} update --version=${version}`,
|
|
191
|
-
);
|
|
175
|
+
if (!packageData?.version) return undefined;
|
|
192
176
|
|
|
193
|
-
|
|
194
|
-
|
|
177
|
+
// Check if this is an alias by looking at the 'from' field
|
|
178
|
+
const from = packageData.from;
|
|
179
|
+
if (from && from !== "@superblocksteam/library") {
|
|
180
|
+
return {
|
|
181
|
+
version: packageData.version,
|
|
182
|
+
alias: from,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return { version: packageData.version };
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function upgradeCliWithOclif(targetVersion: string): Promise<boolean> {
|
|
190
|
+
try {
|
|
191
|
+
const command = process.platform === "win32" ? "where" : "which";
|
|
192
|
+
const { stdout } = await exec(`${command} superblocks`);
|
|
193
|
+
const superblocksPath = stdout.trim();
|
|
194
|
+
|
|
195
|
+
if (!superblocksPath) return false;
|
|
196
|
+
|
|
197
|
+
const { stdout: updateOutput } = await exec(
|
|
198
|
+
`${superblocksPath} update --version=${targetVersion}`,
|
|
199
|
+
);
|
|
200
|
+
return !updateOutput.includes("not updatable");
|
|
195
201
|
} catch (error) {
|
|
196
202
|
if (isNativeError(error)) {
|
|
197
|
-
logger.error(`Error checking updatability: ${error.message}`);
|
|
203
|
+
logger.error(`Error checking CLI updatability: ${error.message}`);
|
|
198
204
|
}
|
|
199
205
|
return false;
|
|
200
206
|
}
|
|
201
207
|
}
|
|
202
208
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
209
|
+
async function upgradePackageWithPackageManager(
|
|
210
|
+
pm: DetectResult,
|
|
211
|
+
packageName: string,
|
|
212
|
+
targetVersion: string,
|
|
213
|
+
alias?: string,
|
|
214
|
+
): Promise<void> {
|
|
215
|
+
const packageSpec = alias
|
|
216
|
+
? `@superblocksteam/${packageName}@npm:${alias}@${targetVersion}`
|
|
217
|
+
: `@superblocksteam/${packageName}@${targetVersion}`;
|
|
218
|
+
|
|
219
|
+
const installCommand = resolveCommand(pm.agent, "install", [packageSpec]);
|
|
220
|
+
|
|
221
|
+
if (!installCommand) {
|
|
222
|
+
console.error("Could not determine how to upgrade Superblocks packages.");
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const { command, args } = installCommand;
|
|
227
|
+
await exec(`${command} ${args.join(" ")}`);
|
|
228
|
+
}
|
|
229
|
+
|
|
206
230
|
async function restartCli() {
|
|
207
|
-
// Get the args that were used to start the current process
|
|
208
231
|
const args = process.argv.slice(1);
|
|
209
|
-
|
|
210
|
-
// Create a new process with the same arguments
|
|
211
232
|
const child = child_process.spawn(process.execPath, [...args], {
|
|
212
233
|
detached: true,
|
|
213
234
|
stdio: "inherit",
|
|
214
235
|
env: process.env,
|
|
215
236
|
});
|
|
216
|
-
|
|
217
|
-
// Disconnect the child from the parent
|
|
218
237
|
child.unref();
|
|
219
|
-
|
|
220
|
-
// Exit the current process after the next tick to ensure any logs were written to stdout
|
|
221
238
|
process.nextTick(() => process.exit(0));
|
|
222
239
|
}
|
|
223
240
|
|
|
@@ -225,6 +242,7 @@ export async function checkVersionsAndUpgrade(
|
|
|
225
242
|
lockService: LockService,
|
|
226
243
|
config?: ApplicationConfig,
|
|
227
244
|
) {
|
|
245
|
+
// Detect package manager
|
|
228
246
|
const pm = await detect({
|
|
229
247
|
strategies: [
|
|
230
248
|
"packageManager-field",
|
|
@@ -235,70 +253,69 @@ export async function checkVersionsAndUpgrade(
|
|
|
235
253
|
cwd: process.cwd(),
|
|
236
254
|
});
|
|
237
255
|
|
|
238
|
-
if (!pm) return;
|
|
239
|
-
if (!config?.id) return;
|
|
256
|
+
if (!pm || !config?.id) return;
|
|
240
257
|
|
|
241
|
-
|
|
258
|
+
// Get current versions
|
|
259
|
+
const currentCliVersion = await getCurrentCliVersion();
|
|
260
|
+
const currentLibraryInfo = await getCurrentLibraryVersion(pm);
|
|
242
261
|
|
|
262
|
+
// Skip if we're in local development
|
|
243
263
|
if (
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
)
|
|
264
|
+
!currentCliVersion ||
|
|
265
|
+
!valid(currentCliVersion) ||
|
|
266
|
+
currentCliVersion.startsWith("file:") ||
|
|
267
|
+
currentCliVersion.startsWith("link:") ||
|
|
268
|
+
!currentLibraryInfo ||
|
|
269
|
+
!valid(currentLibraryInfo.version) ||
|
|
270
|
+
currentLibraryInfo.version.startsWith("file:") ||
|
|
271
|
+
currentLibraryInfo.version.startsWith("link:")
|
|
248
272
|
) {
|
|
249
273
|
return;
|
|
250
274
|
}
|
|
251
275
|
|
|
252
|
-
|
|
276
|
+
// Get target versions from server
|
|
277
|
+
const targetVersions = await getRemoteVersions(config);
|
|
278
|
+
if (!targetVersions) return;
|
|
253
279
|
|
|
254
|
-
//
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
!serverVersions ||
|
|
258
|
-
// we have a different # of libraries in server/local
|
|
259
|
-
Object.keys(localVersions).length !== Object.keys(serverVersions).length
|
|
260
|
-
) {
|
|
261
|
-
return;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
const isUpToDate = isEqual(localVersions, serverVersions);
|
|
265
|
-
|
|
266
|
-
if (isUpToDate) return;
|
|
280
|
+
// Check if CLI needs upgrade
|
|
281
|
+
const cliNeedsUpgrade =
|
|
282
|
+
targetVersions.cli && gt(targetVersions.cli, currentCliVersion);
|
|
267
283
|
|
|
268
|
-
//
|
|
269
|
-
const
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
} catch {
|
|
273
|
-
return false;
|
|
274
|
-
}
|
|
275
|
-
}) as Versions;
|
|
284
|
+
// Check if library needs upgrade
|
|
285
|
+
const libraryNeedsUpgrade =
|
|
286
|
+
targetVersions.library &&
|
|
287
|
+
gt(targetVersions.library, currentLibraryInfo.version);
|
|
276
288
|
|
|
277
|
-
if (
|
|
278
|
-
return;
|
|
289
|
+
if (!cliNeedsUpgrade && !libraryNeedsUpgrade) {
|
|
290
|
+
return; // Everything is up to date
|
|
279
291
|
}
|
|
280
292
|
|
|
281
293
|
let cliUpdated = false;
|
|
282
294
|
let libraryUpdated = false;
|
|
283
295
|
|
|
284
|
-
//
|
|
285
|
-
if (
|
|
286
|
-
|
|
287
|
-
const isUpdated = await tryCliUpdateCommand(serverVersions.cli);
|
|
296
|
+
// Upgrade CLI if needed
|
|
297
|
+
if (cliNeedsUpgrade) {
|
|
298
|
+
const oclifUpgradeSucceeded = await upgradeCliWithOclif(targetVersions.cli);
|
|
288
299
|
|
|
289
|
-
if (!
|
|
290
|
-
//
|
|
291
|
-
await
|
|
300
|
+
if (!oclifUpgradeSucceeded) {
|
|
301
|
+
// Fall back to package manager upgrade
|
|
302
|
+
await upgradePackageWithPackageManager(pm, "cli", targetVersions.cli);
|
|
292
303
|
cliUpdated = true;
|
|
293
304
|
}
|
|
294
305
|
}
|
|
295
306
|
|
|
296
|
-
//
|
|
297
|
-
if (
|
|
298
|
-
await
|
|
307
|
+
// Upgrade library if needed
|
|
308
|
+
if (libraryNeedsUpgrade) {
|
|
309
|
+
await upgradePackageWithPackageManager(
|
|
310
|
+
pm,
|
|
311
|
+
"library",
|
|
312
|
+
targetVersions.library,
|
|
313
|
+
currentLibraryInfo.alias,
|
|
314
|
+
);
|
|
299
315
|
libraryUpdated = true;
|
|
300
316
|
}
|
|
301
317
|
|
|
318
|
+
// Log what was updated
|
|
302
319
|
if (cliUpdated && libraryUpdated) {
|
|
303
320
|
logger.info(
|
|
304
321
|
"@superblocksteam/cli and @superblocksteam/library have been updated.",
|
|
@@ -309,8 +326,10 @@ export async function checkVersionsAndUpgrade(
|
|
|
309
326
|
logger.info("@superblocksteam/library has been updated.");
|
|
310
327
|
}
|
|
311
328
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
329
|
+
// Restart CLI if anything was updated
|
|
330
|
+
if (cliUpdated || libraryUpdated) {
|
|
331
|
+
logger.info("Restarting the CLI…");
|
|
332
|
+
await lockService.releaseLock();
|
|
333
|
+
await restartCli();
|
|
334
|
+
}
|
|
316
335
|
}
|