@highstate/cli 0.21.1 → 0.27.0
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/{chunk-n0q0pces.js → chunk-2s546hay.js} +118 -38
- package/dist/commands/index.js +1 -1
- package/dist/highstate.manifest.json +2 -2
- package/dist/main.js +1 -1
- package/package.json +3 -3
- package/src/commands/build.ts +28 -0
- package/src/commands/designer.ts +49 -16
- package/src/commands/update.ts +86 -31
|
@@ -1294,6 +1294,20 @@ import { resolve as resolve4 } from "path";
|
|
|
1294
1294
|
import { encode } from "@msgpack/msgpack";
|
|
1295
1295
|
import { Command as Command5, Option as Option3 } from "clipanion";
|
|
1296
1296
|
import { readPackageJSON as readPackageJSON3, resolvePackageJSON as resolvePackageJSON4 } from "pkg-types";
|
|
1297
|
+
function formatUnknownError(error) {
|
|
1298
|
+
if (error instanceof Error) {
|
|
1299
|
+
return error.stack ?? error.message;
|
|
1300
|
+
}
|
|
1301
|
+
if (typeof error === "string") {
|
|
1302
|
+
return error;
|
|
1303
|
+
}
|
|
1304
|
+
try {
|
|
1305
|
+
return JSON.stringify(error);
|
|
1306
|
+
} catch {
|
|
1307
|
+
return String(error);
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1297
1311
|
class BuildCommand extends Command5 {
|
|
1298
1312
|
static paths = [["build"]];
|
|
1299
1313
|
static usage = Command5.Usage({
|
|
@@ -1304,6 +1318,16 @@ class BuildCommand extends Command5 {
|
|
|
1304
1318
|
silent = Option3.Boolean("--silent", true);
|
|
1305
1319
|
noSourceHash = Option3.Boolean("--no-source-hash", false);
|
|
1306
1320
|
async execute() {
|
|
1321
|
+
try {
|
|
1322
|
+
await this.build();
|
|
1323
|
+
} catch (error) {
|
|
1324
|
+
if (error instanceof Error) {
|
|
1325
|
+
throw error;
|
|
1326
|
+
}
|
|
1327
|
+
throw new Error(`Build failed with non-error rejection: ${formatUnknownError(error)}`);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
async build() {
|
|
1307
1331
|
const packageJson = await readPackageJSON3();
|
|
1308
1332
|
const highstateConfig = highstateConfigSchema.parse(packageJson.highstate ?? {});
|
|
1309
1333
|
if (highstateConfig.type === "library") {
|
|
@@ -1383,10 +1407,12 @@ import { pathToFileURL as pathToFileURL2 } from "url";
|
|
|
1383
1407
|
import { Command as Command6, UsageError } from "clipanion";
|
|
1384
1408
|
import { consola as consola2 } from "consola";
|
|
1385
1409
|
import { colorize } from "consola/utils";
|
|
1386
|
-
import { getPort } from "get-port-please";
|
|
1410
|
+
import { checkPort, getPort } from "get-port-please";
|
|
1387
1411
|
import { resolve as importMetaResolve2 } from "import-meta-resolve";
|
|
1388
1412
|
import { addDevDependency } from "nypm";
|
|
1389
1413
|
import { readPackageJSON as readPackageJSON4, resolvePackageJSON as resolvePackageJSON5 } from "pkg-types";
|
|
1414
|
+
var shuttingDown = false;
|
|
1415
|
+
|
|
1390
1416
|
class DesignerCommand extends Command6 {
|
|
1391
1417
|
static paths = [["designer"]];
|
|
1392
1418
|
static usage = Command6.Usage({
|
|
@@ -1408,24 +1434,44 @@ class DesignerCommand extends Command6 {
|
|
|
1408
1434
|
logger.info("starting highstate designer...");
|
|
1409
1435
|
await getBackendServices();
|
|
1410
1436
|
const oldConsoleLog = console.log;
|
|
1411
|
-
const
|
|
1412
|
-
const
|
|
1437
|
+
const host = "127.0.0.1";
|
|
1438
|
+
const configuredPort = process.env.HIGHSTATE_DESIGNER_PORT;
|
|
1439
|
+
const port = configuredPort === undefined ? 7283 : Number(configuredPort);
|
|
1440
|
+
if (!/^\d+$/.test(configuredPort ?? port.toString()) || port < 1 || port > 65535) {
|
|
1441
|
+
throw new UsageError(`HIGHSTATE_DESIGNER_PORT must be an integer between "1" and "65535"`);
|
|
1442
|
+
}
|
|
1443
|
+
if (configuredPort !== undefined) {
|
|
1444
|
+
logger.warn(`using custom designer port "%s"; changing the port changes the WebAuthn origin and may require registering security keys again`, port);
|
|
1445
|
+
}
|
|
1446
|
+
const availablePort = await checkPort(port, host);
|
|
1447
|
+
if (!availablePort) {
|
|
1448
|
+
throw new UsageError(`Port "${port}" is already in use`);
|
|
1449
|
+
}
|
|
1450
|
+
const eventsPort = await getPort({ random: true, host });
|
|
1413
1451
|
const designerPackageJsonPath = importMetaResolve2("@highstate/designer/package.json", packageJsonUrl);
|
|
1414
1452
|
const designerPackageJson = await readPackageJSON4(designerPackageJsonPath);
|
|
1415
1453
|
process.env.NITRO_PORT = port.toString();
|
|
1416
|
-
process.env.NITRO_HOST =
|
|
1454
|
+
process.env.NITRO_HOST = host;
|
|
1455
|
+
process.env.NITRO_BUN_IDLE_TIMEOUT ??= "255";
|
|
1417
1456
|
process.env.NUXT_PUBLIC_VERSION = designerPackageJson.version;
|
|
1418
1457
|
process.env.NUXT_PUBLIC_EVENTS_PORT = eventsPort.toString();
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1458
|
+
try {
|
|
1459
|
+
await new Promise((resolve5, reject) => {
|
|
1460
|
+
console.log = (message) => {
|
|
1461
|
+
if (message.startsWith("Listening on")) {
|
|
1462
|
+
if (!message.includes(`http://${host}:${port}`)) {
|
|
1463
|
+
reject(new Error(`Designer started on an unexpected endpoint: ${message}`));
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1466
|
+
resolve5();
|
|
1467
|
+
}
|
|
1468
|
+
};
|
|
1469
|
+
const serverPath = importMetaResolve2("@highstate/designer/server", packageJsonUrl);
|
|
1470
|
+
import(serverPath).catch(reject);
|
|
1471
|
+
});
|
|
1472
|
+
} finally {
|
|
1473
|
+
console.log = oldConsoleLog;
|
|
1474
|
+
}
|
|
1429
1475
|
consola2.log([
|
|
1430
1476
|
`
|
|
1431
1477
|
`,
|
|
@@ -1433,11 +1479,15 @@ class DesignerCommand extends Command6 {
|
|
|
1433
1479
|
`
|
|
1434
1480
|
`,
|
|
1435
1481
|
colorize("greenBright", "\u279C Local: "),
|
|
1436
|
-
colorize("underline", colorize("cyanBright", `http://localhost:${port}`)),
|
|
1482
|
+
colorize("underline", colorize("cyanBright", `http://highstate.localhost:${port}`)),
|
|
1437
1483
|
`
|
|
1438
1484
|
`
|
|
1439
1485
|
].join(""));
|
|
1440
|
-
process.
|
|
1486
|
+
process.once("SIGINT", () => {
|
|
1487
|
+
if (shuttingDown) {
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
shuttingDown = true;
|
|
1441
1491
|
process.stdout.write("\r");
|
|
1442
1492
|
consola2.info("shutting down highstate designer...");
|
|
1443
1493
|
setTimeout(() => process.exit(0), 1000);
|
|
@@ -1683,34 +1733,22 @@ class UpdateCommand extends Command12 {
|
|
|
1683
1733
|
}
|
|
1684
1734
|
const updatePlatform = this.platformOnly || !this.stdlibOnly;
|
|
1685
1735
|
const updateStdlib = this.stdlibOnly || !this.platformOnly;
|
|
1736
|
+
let currentPlatformVersion;
|
|
1737
|
+
let resolvedStdlibVersion = this.stdlibVersion;
|
|
1686
1738
|
if (this.stdlibOnly) {
|
|
1687
|
-
const
|
|
1688
|
-
if (!
|
|
1739
|
+
const projectPlatformVersion = await getProjectPlatformVersion(projectRoot);
|
|
1740
|
+
if (!projectPlatformVersion) {
|
|
1689
1741
|
throw new Error('Current platform version is not set in overrides for "@highstate/pulumi"');
|
|
1690
1742
|
}
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
const stdlibManifest = await fetchManifest("@highstate/library", targetStdlibVersion);
|
|
1696
|
-
const supportedPlatformRange = getDependencyRange(stdlibManifest, "@highstate/pulumi");
|
|
1697
|
-
if (!supportedPlatformRange) {
|
|
1698
|
-
throw new Error(`Unable to infer "@highstate/pulumi" version from "@highstate/library@${targetStdlibVersion}"`);
|
|
1699
|
-
}
|
|
1700
|
-
const validPlatform = semver.valid(currentPlatformVersion);
|
|
1701
|
-
if (!validPlatform) {
|
|
1702
|
-
throw new Error(`Current platform version is not a valid semver "${currentPlatformVersion}"`);
|
|
1703
|
-
}
|
|
1704
|
-
const ok = semver.satisfies(validPlatform, supportedPlatformRange, {
|
|
1705
|
-
includePrerelease: true
|
|
1743
|
+
currentPlatformVersion = projectPlatformVersion;
|
|
1744
|
+
resolvedStdlibVersion = await resolveCompatibleStdlibVersion({
|
|
1745
|
+
currentPlatformVersion: projectPlatformVersion,
|
|
1746
|
+
stdlibVersion: this.stdlibVersion
|
|
1706
1747
|
});
|
|
1707
|
-
if (!ok) {
|
|
1708
|
-
throw new Error(`Current platform version "${currentPlatformVersion}" does not satisfy requirement "${supportedPlatformRange}"`);
|
|
1709
|
-
}
|
|
1710
1748
|
}
|
|
1711
1749
|
const bundle = await resolveVersionBundle({
|
|
1712
|
-
platformVersion: updatePlatform ? this.platformVersion :
|
|
1713
|
-
stdlibVersion: updateStdlib ?
|
|
1750
|
+
platformVersion: updatePlatform ? this.platformVersion : currentPlatformVersion,
|
|
1751
|
+
stdlibVersion: updateStdlib ? resolvedStdlibVersion : undefined
|
|
1714
1752
|
});
|
|
1715
1753
|
const overrides2 = buildOverrides(bundle);
|
|
1716
1754
|
await applyOverrides({
|
|
@@ -1734,6 +1772,48 @@ class UpdateCommand extends Command12 {
|
|
|
1734
1772
|
logger.info("update completed successfully");
|
|
1735
1773
|
}
|
|
1736
1774
|
}
|
|
1775
|
+
async function resolveCompatibleStdlibVersion(args) {
|
|
1776
|
+
const validPlatform = semver.valid(args.currentPlatformVersion);
|
|
1777
|
+
if (!validPlatform) {
|
|
1778
|
+
throw new Error(`Current platform version is not a valid semver "${args.currentPlatformVersion}"`);
|
|
1779
|
+
}
|
|
1780
|
+
const targetStdlibVersion = args.stdlibVersion?.trim();
|
|
1781
|
+
if (targetStdlibVersion) {
|
|
1782
|
+
await assertStdlibSupportsPlatform({
|
|
1783
|
+
currentPlatformVersion: validPlatform,
|
|
1784
|
+
stdlibVersion: targetStdlibVersion
|
|
1785
|
+
});
|
|
1786
|
+
return targetStdlibVersion;
|
|
1787
|
+
}
|
|
1788
|
+
const packument = await fetchNpmPackument("@highstate/library");
|
|
1789
|
+
const sortedVersions = Object.entries(packument.versions ?? {}).filter(([version]) => semver.valid(version)).sort(([a], [b]) => semver.rcompare(a, b));
|
|
1790
|
+
for (const [stdlibVersion, stdlibManifest] of sortedVersions) {
|
|
1791
|
+
const supportedPlatformRange = getDependencyRange(stdlibManifest, "@highstate/pulumi");
|
|
1792
|
+
if (!supportedPlatformRange) {
|
|
1793
|
+
continue;
|
|
1794
|
+
}
|
|
1795
|
+
const ok = semver.satisfies(validPlatform, supportedPlatformRange, {
|
|
1796
|
+
includePrerelease: true
|
|
1797
|
+
});
|
|
1798
|
+
if (ok) {
|
|
1799
|
+
return stdlibVersion;
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
throw new Error(`Unable to find "@highstate/library" version compatible with platform "${validPlatform}"`);
|
|
1803
|
+
}
|
|
1804
|
+
async function assertStdlibSupportsPlatform(args) {
|
|
1805
|
+
const stdlibManifest = await fetchManifest("@highstate/library", args.stdlibVersion);
|
|
1806
|
+
const supportedPlatformRange = getDependencyRange(stdlibManifest, "@highstate/pulumi");
|
|
1807
|
+
if (!supportedPlatformRange) {
|
|
1808
|
+
throw new Error(`Unable to infer "@highstate/pulumi" version from "@highstate/library@${args.stdlibVersion}"`);
|
|
1809
|
+
}
|
|
1810
|
+
const ok = semver.satisfies(args.currentPlatformVersion, supportedPlatformRange, {
|
|
1811
|
+
includePrerelease: true
|
|
1812
|
+
});
|
|
1813
|
+
if (!ok) {
|
|
1814
|
+
throw new Error(`Current platform version "${args.currentPlatformVersion}" does not satisfy requirement "${supportedPlatformRange}"`);
|
|
1815
|
+
}
|
|
1816
|
+
}
|
|
1737
1817
|
async function assertPackageJsonExists(projectRoot) {
|
|
1738
1818
|
try {
|
|
1739
1819
|
await readFile8(`${projectRoot}/package.json`, "utf8");
|
package/dist/commands/index.js
CHANGED
package/dist/main.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@highstate/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.27.0",
|
|
4
4
|
"description": "The CLI for the Highstate project.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@aws-crypto/crc32": "^5.2.0",
|
|
37
|
-
"@highstate/backend": "0.
|
|
38
|
-
"@highstate/contract": "0.
|
|
37
|
+
"@highstate/backend": "0.26.0",
|
|
38
|
+
"@highstate/contract": "0.26.0",
|
|
39
39
|
"@inquirer/prompts": "^7.8.6",
|
|
40
40
|
"@msgpack/msgpack": "^3.1.2",
|
|
41
41
|
"@pulumi/pulumi": "3.232.0",
|
package/src/commands/build.ts
CHANGED
|
@@ -12,6 +12,22 @@ import {
|
|
|
12
12
|
schemaTransformerPlugin,
|
|
13
13
|
} from "../shared"
|
|
14
14
|
|
|
15
|
+
function formatUnknownError(error: unknown): string {
|
|
16
|
+
if (error instanceof Error) {
|
|
17
|
+
return error.stack ?? error.message
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (typeof error === "string") {
|
|
21
|
+
return error
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
return JSON.stringify(error)
|
|
26
|
+
} catch {
|
|
27
|
+
return String(error)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
15
31
|
export class BuildCommand extends Command {
|
|
16
32
|
static paths = [["build"]]
|
|
17
33
|
|
|
@@ -25,6 +41,18 @@ export class BuildCommand extends Command {
|
|
|
25
41
|
noSourceHash = Option.Boolean("--no-source-hash", false)
|
|
26
42
|
|
|
27
43
|
async execute(): Promise<void> {
|
|
44
|
+
try {
|
|
45
|
+
await this.build()
|
|
46
|
+
} catch (error) {
|
|
47
|
+
if (error instanceof Error) {
|
|
48
|
+
throw error
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
throw new Error(`Build failed with non-error rejection: ${formatUnknownError(error)}`)
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private async build(): Promise<void> {
|
|
28
56
|
const packageJson = await readPackageJSON()
|
|
29
57
|
|
|
30
58
|
const highstateConfig = highstateConfigSchema.parse(packageJson.highstate ?? {})
|
package/src/commands/designer.ts
CHANGED
|
@@ -2,12 +2,14 @@ import { pathToFileURL } from "node:url"
|
|
|
2
2
|
import { Command, UsageError } from "clipanion"
|
|
3
3
|
import { consola } from "consola"
|
|
4
4
|
import { colorize } from "consola/utils"
|
|
5
|
-
import { getPort } from "get-port-please"
|
|
5
|
+
import { checkPort, getPort } from "get-port-please"
|
|
6
6
|
import { resolve as importMetaResolve } from "import-meta-resolve"
|
|
7
7
|
import { addDevDependency } from "nypm"
|
|
8
8
|
import { readPackageJSON, resolvePackageJSON } from "pkg-types"
|
|
9
9
|
import { getBackendServices, logger } from "../shared"
|
|
10
10
|
|
|
11
|
+
let shuttingDown = false
|
|
12
|
+
|
|
11
13
|
export class DesignerCommand extends Command {
|
|
12
14
|
static paths = [["designer"]]
|
|
13
15
|
|
|
@@ -39,8 +41,26 @@ export class DesignerCommand extends Command {
|
|
|
39
41
|
|
|
40
42
|
const oldConsoleLog = console.log
|
|
41
43
|
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
+
const host = "127.0.0.1"
|
|
45
|
+
const configuredPort = process.env.HIGHSTATE_DESIGNER_PORT
|
|
46
|
+
const port = configuredPort === undefined ? 7283 : Number(configuredPort)
|
|
47
|
+
if (!/^\d+$/.test(configuredPort ?? port.toString()) || port < 1 || port > 65535) {
|
|
48
|
+
throw new UsageError(`HIGHSTATE_DESIGNER_PORT must be an integer between "1" and "65535"`)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (configuredPort !== undefined) {
|
|
52
|
+
logger.warn(
|
|
53
|
+
`using custom designer port "%s"; changing the port changes the WebAuthn origin and may require registering security keys again`,
|
|
54
|
+
port,
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const availablePort = await checkPort(port, host)
|
|
59
|
+
if (!availablePort) {
|
|
60
|
+
throw new UsageError(`Port "${port}" is already in use`)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const eventsPort = await getPort({ random: true, host })
|
|
44
64
|
|
|
45
65
|
const designerPackageJsonPath = importMetaResolve(
|
|
46
66
|
"@highstate/designer/package.json",
|
|
@@ -49,22 +69,30 @@ export class DesignerCommand extends Command {
|
|
|
49
69
|
const designerPackageJson = await readPackageJSON(designerPackageJsonPath)
|
|
50
70
|
|
|
51
71
|
process.env.NITRO_PORT = port.toString()
|
|
52
|
-
process.env.NITRO_HOST =
|
|
72
|
+
process.env.NITRO_HOST = host
|
|
73
|
+
process.env.NITRO_BUN_IDLE_TIMEOUT ??= "255"
|
|
53
74
|
process.env.NUXT_PUBLIC_VERSION = designerPackageJson.version
|
|
54
75
|
process.env.NUXT_PUBLIC_EVENTS_PORT = eventsPort.toString()
|
|
55
76
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
77
|
+
try {
|
|
78
|
+
await new Promise<void>((resolve, reject) => {
|
|
79
|
+
console.log = (message: string) => {
|
|
80
|
+
if (message.startsWith("Listening on")) {
|
|
81
|
+
if (!message.includes(`http://${host}:${port}`)) {
|
|
82
|
+
reject(new Error(`Designer started on an unexpected endpoint: ${message}`))
|
|
83
|
+
return
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
resolve()
|
|
87
|
+
}
|
|
60
88
|
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const serverPath = importMetaResolve("@highstate/designer/server", packageJsonUrl)
|
|
64
|
-
void import(serverPath)
|
|
65
|
-
})
|
|
66
89
|
|
|
67
|
-
|
|
90
|
+
const serverPath = importMetaResolve("@highstate/designer/server", packageJsonUrl)
|
|
91
|
+
void import(serverPath).catch(reject)
|
|
92
|
+
})
|
|
93
|
+
} finally {
|
|
94
|
+
console.log = oldConsoleLog
|
|
95
|
+
}
|
|
68
96
|
|
|
69
97
|
consola.log(
|
|
70
98
|
[
|
|
@@ -72,12 +100,17 @@ export class DesignerCommand extends Command {
|
|
|
72
100
|
colorize("bold", colorize("cyanBright", "Highstate Designer")),
|
|
73
101
|
"\n ",
|
|
74
102
|
colorize("greenBright", "➜ Local: "),
|
|
75
|
-
colorize("underline", colorize("cyanBright", `http://localhost:${port}`)),
|
|
103
|
+
colorize("underline", colorize("cyanBright", `http://highstate.localhost:${port}`)),
|
|
76
104
|
"\n",
|
|
77
105
|
].join(""),
|
|
78
106
|
)
|
|
79
107
|
|
|
80
|
-
process.
|
|
108
|
+
process.once("SIGINT", () => {
|
|
109
|
+
if (shuttingDown) {
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
shuttingDown = true
|
|
113
|
+
|
|
81
114
|
process.stdout.write("\r")
|
|
82
115
|
consola.info("shutting down highstate designer...")
|
|
83
116
|
|
package/src/commands/update.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
applyOverrides,
|
|
7
7
|
buildOverrides,
|
|
8
8
|
fetchManifest,
|
|
9
|
+
fetchNpmPackument,
|
|
9
10
|
getDependencyRange,
|
|
10
11
|
getProjectPlatformVersion,
|
|
11
12
|
logger,
|
|
@@ -52,45 +53,25 @@ export class UpdateCommand extends Command {
|
|
|
52
53
|
const updatePlatform = this.platformOnly || !this.stdlibOnly
|
|
53
54
|
const updateStdlib = this.stdlibOnly || !this.platformOnly
|
|
54
55
|
|
|
56
|
+
let currentPlatformVersion: string | undefined
|
|
57
|
+
let resolvedStdlibVersion = this.stdlibVersion
|
|
58
|
+
|
|
55
59
|
if (this.stdlibOnly) {
|
|
56
|
-
const
|
|
57
|
-
if (!
|
|
60
|
+
const projectPlatformVersion = await getProjectPlatformVersion(projectRoot)
|
|
61
|
+
if (!projectPlatformVersion) {
|
|
58
62
|
throw new Error('Current platform version is not set in overrides for "@highstate/pulumi"')
|
|
59
63
|
}
|
|
60
64
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const stdlibManifest = await fetchManifest("@highstate/library", targetStdlibVersion)
|
|
67
|
-
const supportedPlatformRange = getDependencyRange(stdlibManifest, "@highstate/pulumi")
|
|
68
|
-
if (!supportedPlatformRange) {
|
|
69
|
-
throw new Error(
|
|
70
|
-
`Unable to infer "@highstate/pulumi" version from "@highstate/library@${targetStdlibVersion}"`,
|
|
71
|
-
)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const validPlatform = semver.valid(currentPlatformVersion)
|
|
75
|
-
if (!validPlatform) {
|
|
76
|
-
throw new Error(
|
|
77
|
-
`Current platform version is not a valid semver "${currentPlatformVersion}"`,
|
|
78
|
-
)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const ok = semver.satisfies(validPlatform, supportedPlatformRange, {
|
|
82
|
-
includePrerelease: true,
|
|
65
|
+
currentPlatformVersion = projectPlatformVersion
|
|
66
|
+
resolvedStdlibVersion = await resolveCompatibleStdlibVersion({
|
|
67
|
+
currentPlatformVersion: projectPlatformVersion,
|
|
68
|
+
stdlibVersion: this.stdlibVersion,
|
|
83
69
|
})
|
|
84
|
-
if (!ok) {
|
|
85
|
-
throw new Error(
|
|
86
|
-
`Current platform version "${currentPlatformVersion}" does not satisfy requirement "${supportedPlatformRange}"`,
|
|
87
|
-
)
|
|
88
|
-
}
|
|
89
70
|
}
|
|
90
71
|
|
|
91
72
|
const bundle = await resolveVersionBundle({
|
|
92
|
-
platformVersion: updatePlatform ? this.platformVersion :
|
|
93
|
-
stdlibVersion: updateStdlib ?
|
|
73
|
+
platformVersion: updatePlatform ? this.platformVersion : currentPlatformVersion,
|
|
74
|
+
stdlibVersion: updateStdlib ? resolvedStdlibVersion : undefined,
|
|
94
75
|
})
|
|
95
76
|
|
|
96
77
|
const overrides = buildOverrides(bundle)
|
|
@@ -126,6 +107,80 @@ export class UpdateCommand extends Command {
|
|
|
126
107
|
}
|
|
127
108
|
}
|
|
128
109
|
|
|
110
|
+
type ResolveCompatibleStdlibVersionArgs = {
|
|
111
|
+
currentPlatformVersion: string
|
|
112
|
+
stdlibVersion?: string
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async function resolveCompatibleStdlibVersion(
|
|
116
|
+
args: ResolveCompatibleStdlibVersionArgs,
|
|
117
|
+
): Promise<string> {
|
|
118
|
+
const validPlatform = semver.valid(args.currentPlatformVersion)
|
|
119
|
+
if (!validPlatform) {
|
|
120
|
+
throw new Error(
|
|
121
|
+
`Current platform version is not a valid semver "${args.currentPlatformVersion}"`,
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
const targetStdlibVersion = args.stdlibVersion?.trim()
|
|
126
|
+
if (targetStdlibVersion) {
|
|
127
|
+
await assertStdlibSupportsPlatform({
|
|
128
|
+
currentPlatformVersion: validPlatform,
|
|
129
|
+
stdlibVersion: targetStdlibVersion,
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
return targetStdlibVersion
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const packument = await fetchNpmPackument("@highstate/library")
|
|
136
|
+
const sortedVersions = Object.entries(packument.versions ?? {})
|
|
137
|
+
.filter(([version]) => semver.valid(version))
|
|
138
|
+
.sort(([a], [b]) => semver.rcompare(a, b))
|
|
139
|
+
|
|
140
|
+
for (const [stdlibVersion, stdlibManifest] of sortedVersions) {
|
|
141
|
+
const supportedPlatformRange = getDependencyRange(stdlibManifest, "@highstate/pulumi")
|
|
142
|
+
if (!supportedPlatformRange) {
|
|
143
|
+
continue
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const ok = semver.satisfies(validPlatform, supportedPlatformRange, {
|
|
147
|
+
includePrerelease: true,
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
if (ok) {
|
|
151
|
+
return stdlibVersion
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
throw new Error(
|
|
156
|
+
`Unable to find "@highstate/library" version compatible with platform "${validPlatform}"`,
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
type StdlibPlatformCompatibilityArgs = {
|
|
161
|
+
currentPlatformVersion: string
|
|
162
|
+
stdlibVersion: string
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async function assertStdlibSupportsPlatform(args: StdlibPlatformCompatibilityArgs): Promise<void> {
|
|
166
|
+
const stdlibManifest = await fetchManifest("@highstate/library", args.stdlibVersion)
|
|
167
|
+
const supportedPlatformRange = getDependencyRange(stdlibManifest, "@highstate/pulumi")
|
|
168
|
+
if (!supportedPlatformRange) {
|
|
169
|
+
throw new Error(
|
|
170
|
+
`Unable to infer "@highstate/pulumi" version from "@highstate/library@${args.stdlibVersion}"`,
|
|
171
|
+
)
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const ok = semver.satisfies(args.currentPlatformVersion, supportedPlatformRange, {
|
|
175
|
+
includePrerelease: true,
|
|
176
|
+
})
|
|
177
|
+
if (!ok) {
|
|
178
|
+
throw new Error(
|
|
179
|
+
`Current platform version "${args.currentPlatformVersion}" does not satisfy requirement "${supportedPlatformRange}"`,
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
129
184
|
async function assertPackageJsonExists(projectRoot: string): Promise<void> {
|
|
130
185
|
try {
|
|
131
186
|
await readFile(`${projectRoot}/package.json`, "utf8")
|