@highstate/cli 0.20.0 → 0.26.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.
@@ -1,49 +1,32 @@
1
- import { int32ToBytes } from './chunk-CMECLVT7.js';
2
- import { hostname } from 'node:os';
3
- import { loadConfig } from '@highstate/backend';
4
- import { identityToRecipient } from 'age-encryption';
5
- import { Command, Option, UsageError } from 'clipanion';
6
- import { writeFile, mkdir, access, readdir, rm, readFile, stat } from 'node:fs/promises';
7
- import { PassThrough } from 'node:stream';
8
- import { LogLevels, consola } from 'consola';
9
- import pino, { levels } from 'pino';
10
- import { resolve, relative, dirname, join } from 'node:path';
11
- import Handlebars from 'handlebars';
12
- import { readPackageJSON, resolvePackageJSON } from 'pkg-types';
13
- import { parse, stringify } from 'yaml';
14
- import { execFile } from 'node:child_process';
15
- import { promisify } from 'node:util';
16
- import MagicString from 'magic-string';
17
- import { parseAsync } from 'oxc-parser';
18
- import { walk } from 'oxc-walker';
19
- import { z } from 'zod';
20
- import { pathToFileURL, fileURLToPath } from 'node:url';
21
- import { crc32 } from '@aws-crypto/crc32';
22
- import { resolve as resolve$1 } from 'import-meta-resolve';
23
- import { existsSync } from 'node:fs';
24
- import { input, confirm, select } from '@inquirer/prompts';
25
- import { Table } from 'console-table-printer';
26
- import { encode } from '@msgpack/msgpack';
27
- import { mapValues } from 'remeda';
28
- import { build } from 'tsup';
29
- import { colorize } from 'consola/utils';
30
- import { getPort } from 'get-port-please';
31
- import { addDevDependency, detectPackageManager, installDependencies } from 'nypm';
32
- import semver from 'semver';
1
+ // @bun
2
+ import {
3
+ __require,
4
+ int32ToBytes
5
+ } from "./chunk-vcev74he.js";
33
6
 
34
- var logger = pino(
35
- {
36
- name: "highstate-cli",
37
- level: process.env.LOG_LEVEL ?? "info",
38
- serializers: {
39
- error: (value) => serializeError(value)
40
- }
41
- },
42
- createConsolaStream()
43
- );
7
+ // src/commands/backend/identity.ts
8
+ import { hostname } from "os";
9
+ import { loadConfig } from "@highstate/backend";
10
+ import { identityToRecipient } from "age-encryption";
11
+ import { Command } from "clipanion";
12
+
13
+ // src/shared/bin-transformer.ts
14
+ import { readFile } from "fs/promises";
15
+
16
+ // src/shared/logger.ts
17
+ import { PassThrough } from "stream";
18
+ import { consola, LogLevels } from "consola";
19
+ import pino, { levels } from "pino";
20
+ var logger = pino({
21
+ name: "highstate-cli",
22
+ level: process.env.LOG_LEVEL ?? "info",
23
+ serializers: {
24
+ error: (value) => serializeError(value)
25
+ }
26
+ }, createConsolaStream());
44
27
  consola.level = LogLevels[process.env.LOG_LEVEL ?? "info"];
45
28
  function createConsolaStream() {
46
- const stream = new PassThrough();
29
+ const stream = new PassThrough;
47
30
  stream.on("data", (data) => {
48
31
  const { level, msg, error } = JSON.parse(String(data));
49
32
  const levelLabel = levels.labels[level];
@@ -74,7 +57,7 @@ function createConsolaStream() {
74
57
  });
75
58
  return stream;
76
59
  }
77
- function serializeError(value, seen = /* @__PURE__ */ new WeakSet()) {
60
+ function serializeError(value, seen = new WeakSet) {
78
61
  if (value instanceof Error) {
79
62
  const base = {
80
63
  name: value.name,
@@ -82,14 +65,12 @@ function serializeError(value, seen = /* @__PURE__ */ new WeakSet()) {
82
65
  stack: value.stack
83
66
  };
84
67
  const cause = value.cause;
85
- if (cause !== void 0) {
68
+ if (cause !== undefined) {
86
69
  base.cause = serializeError(cause, seen);
87
70
  }
88
71
  const extraEntries = Object.entries(value);
89
72
  if (extraEntries.length > 0) {
90
- base.details = Object.fromEntries(
91
- extraEntries.map(([key, entryValue]) => [key, serializeError(entryValue, seen)])
92
- );
73
+ base.details = Object.fromEntries(extraEntries.map(([key, entryValue]) => [key, serializeError(entryValue, seen)]));
93
74
  }
94
75
  return base;
95
76
  }
@@ -108,9 +89,7 @@ function serializeError(value, seen = /* @__PURE__ */ new WeakSet()) {
108
89
  message: String(value)
109
90
  };
110
91
  }
111
- return Object.fromEntries(
112
- entries.map(([key, entryValue]) => [key, serializeError(entryValue, seen)])
113
- );
92
+ return Object.fromEntries(entries.map(([key, entryValue]) => [key, serializeError(entryValue, seen)]));
114
93
  }
115
94
  return {
116
95
  type: typeof value,
@@ -124,11 +103,11 @@ function createBinTransformerPlugin(sourceFilePaths) {
124
103
  logger.debug("created bin transformer plugin with filter: %s", filter);
125
104
  return {
126
105
  name: "bin-transformer",
127
- setup(build2) {
128
- build2.onLoad({ filter }, async (args) => {
106
+ setup(build) {
107
+ build.onLoad({ filter }, async (args) => {
129
108
  const content = await readFile(args.path, "utf-8");
130
109
  return {
131
- contents: `#!/usr/bin/env node
110
+ contents: `#!/usr/bin/env bun
132
111
 
133
112
  ${content}`,
134
113
  loader: "ts"
@@ -137,27 +116,26 @@ ${content}`,
137
116
  }
138
117
  };
139
118
  }
140
-
141
119
  // src/shared/entry-points.ts
142
120
  function extractEntryPoints(packageJson) {
143
- const exports$1 = packageJson.exports;
121
+ const exports = packageJson.exports;
144
122
  let bin = packageJson.bin;
145
- if (!exports$1 && !bin) {
123
+ if (!exports && !bin) {
146
124
  logger.warn("no exports or bin found in package.json");
147
125
  return {};
148
126
  }
149
- if (exports$1 !== void 0 && (typeof exports$1 !== "object" || Array.isArray(exports$1))) {
127
+ if (exports !== undefined && (typeof exports !== "object" || Array.isArray(exports))) {
150
128
  throw new Error("Exports field in package.json must be an object");
151
129
  }
152
- if (bin !== void 0 && typeof bin !== "object") {
130
+ if (bin !== undefined && typeof bin !== "object") {
153
131
  if (!packageJson.name) {
154
132
  throw new Error("Package name is required when bin is a string");
155
133
  }
156
134
  bin = { [packageJson.name]: bin };
157
135
  }
158
136
  const result = {};
159
- if (exports$1) {
160
- for (const [key, value] of Object.entries(exports$1)) {
137
+ if (exports) {
138
+ for (const [key, value] of Object.entries(exports)) {
161
139
  let distPath;
162
140
  if (typeof value === "string") {
163
141
  distPath = value;
@@ -175,14 +153,10 @@ function extractEntryPoints(packageJson) {
175
153
  const isJsonExport = distPath.endsWith(".json");
176
154
  const isJsExport = distPath.endsWith(".js");
177
155
  if (!isJsonExport && !isJsExport) {
178
- throw new Error(
179
- `The default value of export "${key}" must end with ".js" or ".json" in package.json, got "${distPath}"`
180
- );
156
+ throw new Error(`The default value of export "${key}" must end with ".js" or ".json" in package.json, got "${distPath}"`);
181
157
  }
182
158
  if (isJsExport && !distPath.startsWith("./dist/")) {
183
- throw new Error(
184
- `The default value of export "${key}" must start with "./dist/" when exporting ".js" in package.json, got "${distPath}"`
185
- );
159
+ throw new Error(`The default value of export "${key}" must start with "./dist/" when exporting ".js" in package.json, got "${distPath}"`);
186
160
  }
187
161
  if (isJsonExport) {
188
162
  continue;
@@ -204,14 +178,10 @@ function extractEntryPoints(packageJson) {
204
178
  }
205
179
  const distPath = value;
206
180
  if (!distPath.startsWith("./dist/")) {
207
- throw new Error(
208
- `The value of bin entry "${key}" must start with "./dist/" in package.json, got "${distPath}"`
209
- );
181
+ throw new Error(`The value of bin entry "${key}" must start with "./dist/" in package.json, got "${distPath}"`);
210
182
  }
211
183
  if (!distPath.endsWith(".js")) {
212
- throw new Error(
213
- `The value of bin entry "${key}" must end with ".js" in package.json, got "${distPath}"`
214
- );
184
+ throw new Error(`The value of bin entry "${key}" must end with ".js" in package.json, got "${distPath}"`);
215
185
  }
216
186
  const targetName = distPath.slice(7).slice(0, -3);
217
187
  result[targetName] = {
@@ -225,6 +195,10 @@ function extractEntryPoints(packageJson) {
225
195
  }
226
196
  return result;
227
197
  }
198
+ // src/shared/generator.ts
199
+ import { mkdir, readdir, readFile as readFile2, stat, writeFile } from "fs/promises";
200
+ import { dirname, join, relative, resolve } from "path";
201
+ import Handlebars from "handlebars";
228
202
  async function generateFromTemplate(templatePath, destinationPath, variables) {
229
203
  const resolvedTemplatePath = resolve(templatePath);
230
204
  const resolvedDestinationPath = resolve(destinationPath);
@@ -259,7 +233,7 @@ async function generateFromTemplate(templatePath, destinationPath, variables) {
259
233
  const destinationRelativePath = relativeFilePath.replaceAll(".tpl", "");
260
234
  const destinationFilePath = join(resolvedDestinationPath, destinationRelativePath);
261
235
  await mkdir(dirname(destinationFilePath), { recursive: true });
262
- const contents = await readFile(absoluteSourcePath, "utf8");
236
+ const contents = await readFile2(absoluteSourcePath, "utf8");
263
237
  const rendered = renderTemplate(contents);
264
238
  if (rendered.trim().length === 0) {
265
239
  return;
@@ -268,16 +242,13 @@ async function generateFromTemplate(templatePath, destinationPath, variables) {
268
242
  };
269
243
  await visit(resolvedTemplatePath);
270
244
  }
271
-
272
245
  // src/shared/npm-registry.ts
273
246
  async function fetchNpmPackument(packageName) {
274
247
  const encoded = encodeURIComponent(packageName);
275
248
  const url = `https://registry.npmjs.org/${encoded}`;
276
249
  const response = await fetch(url);
277
250
  if (!response.ok) {
278
- throw new Error(
279
- `Failed to fetch package "${packageName}" from NPM registry (HTTP ${response.status})`
280
- );
251
+ throw new Error(`Failed to fetch package "${packageName}" from NPM registry (HTTP ${response.status})`);
281
252
  }
282
253
  return await response.json();
283
254
  }
@@ -285,9 +256,7 @@ async function fetchLatestVersion(packageName) {
285
256
  const packument = await fetchNpmPackument(packageName);
286
257
  const latest = packument["dist-tags"]?.latest;
287
258
  if (!latest) {
288
- throw new Error(
289
- `NPM registry response for package "${packageName}" does not include "dist-tags.latest"`
290
- );
259
+ throw new Error(`NPM registry response for package "${packageName}" does not include "dist-tags.latest"`);
291
260
  }
292
261
  return latest;
293
262
  }
@@ -295,34 +264,22 @@ async function fetchManifest(packageName, version) {
295
264
  const packument = await fetchNpmPackument(packageName);
296
265
  const manifest = packument.versions?.[version];
297
266
  if (!manifest) {
298
- throw new Error(
299
- `NPM registry response for package "${packageName}" does not include version "${version}"`
300
- );
267
+ throw new Error(`NPM registry response for package "${packageName}" does not include version "${version}"`);
301
268
  }
302
269
  return manifest;
303
270
  }
304
271
  function getDependencyRange(manifest, dependencyName) {
305
272
  return manifest.peerDependencies?.[dependencyName] ?? manifest.dependencies?.[dependencyName] ?? manifest.optionalDependencies?.[dependencyName] ?? null;
306
273
  }
274
+ // src/shared/overrides.ts
275
+ import { readPackageJSON, resolvePackageJSON } from "pkg-types";
276
+
277
+ // src/shared/package-json.ts
278
+ import { writeFile as writeFile2 } from "fs/promises";
307
279
  async function writeJsonFile(filePath, value) {
308
280
  const contents = `${JSON.stringify(value, null, 2)}
309
281
  `;
310
- await writeFile(filePath, contents, "utf8");
311
- }
312
- function resolvePnpmWorkspacePath(projectRoot) {
313
- return resolve(projectRoot, "pnpm-workspace.yaml");
314
- }
315
- async function readPnpmWorkspace(filePath) {
316
- const raw = await readFile(filePath, "utf8");
317
- const parsed = parse(raw);
318
- if (typeof parsed !== "object" || parsed === null) {
319
- return {};
320
- }
321
- return parsed;
322
- }
323
- async function writePnpmWorkspace(filePath, workspace) {
324
- const raw = stringify(workspace);
325
- await writeFile(filePath, raw, "utf8");
282
+ await writeFile2(filePath, contents, "utf8");
326
283
  }
327
284
 
328
285
  // src/shared/version-sets.ts
@@ -373,92 +330,46 @@ function buildOverrides(bundle) {
373
330
  return merged;
374
331
  }
375
332
  async function applyOverrides(args) {
376
- const { packageManager, overrides, projectRoot } = args;
377
- if (packageManager === "pnpm") {
378
- const pnpmWorkspacePath = resolvePnpmWorkspacePath(projectRoot);
379
- try {
380
- await access(pnpmWorkspacePath);
381
- } catch {
382
- throw new Error(`PNPM workspace file is missing: "${pnpmWorkspacePath}"`);
383
- }
384
- const workspace = await readPnpmWorkspace(pnpmWorkspacePath);
385
- const nextWorkspace = {
386
- ...workspace,
387
- overrides
388
- };
389
- await writePnpmWorkspace(pnpmWorkspacePath, nextWorkspace);
390
- return;
391
- }
333
+ const { overrides, projectRoot } = args;
392
334
  const packageJsonPath = await resolvePackageJSON(projectRoot);
393
335
  const packageJson = await readPackageJSON(projectRoot);
394
- if (packageManager === "npm") {
395
- await writeJsonFile(packageJsonPath, {
396
- ...packageJson,
397
- overrides
398
- });
399
- return;
400
- }
401
- if (packageManager === "yarn") {
402
- await writeJsonFile(packageJsonPath, {
403
- ...packageJson,
404
- resolutions: overrides
405
- });
406
- return;
407
- }
408
- await writeJsonFile(packageJsonPath, packageJson);
336
+ await writeJsonFile(packageJsonPath, {
337
+ ...packageJson,
338
+ overrides
339
+ });
409
340
  }
341
+ // src/shared/project-versions.ts
342
+ import { readFile as readFile3 } from "fs/promises";
343
+ import { resolvePackageJSON as resolvePackageJSON2 } from "pkg-types";
410
344
  async function getProjectOverrideVersion(projectRoot, args) {
411
- const { packageManager, packageName } = args;
412
- if (packageManager === "pnpm") {
413
- const path = resolvePnpmWorkspacePath(projectRoot);
414
- const workspace = await readPnpmWorkspace(path);
415
- return workspace.overrides?.[packageName] ?? null;
416
- }
417
- const packageJsonPath = await resolvePackageJSON(projectRoot);
418
- const rawPackageJson = await readFile(packageJsonPath, "utf8");
345
+ const { packageName } = args;
346
+ const packageJsonPath = await resolvePackageJSON2(projectRoot);
347
+ const rawPackageJson = await readFile3(packageJsonPath, "utf8");
419
348
  const packageJson = JSON.parse(rawPackageJson);
420
- if (packageManager === "npm") {
421
- const overrides = packageJson.overrides;
422
- return overrides?.[packageName] ?? null;
423
- }
424
- if (packageManager === "yarn") {
425
- const resolutions = packageJson.resolutions;
426
- return resolutions?.[packageName] ?? null;
427
- }
428
- return null;
349
+ const overrides = packageJson.overrides;
350
+ return overrides?.[packageName] ?? null;
429
351
  }
430
- async function getProjectPlatformVersion(projectRoot, args) {
352
+ async function getProjectPlatformVersion(projectRoot) {
431
353
  return await getProjectOverrideVersion(projectRoot, {
432
- packageManager: args.packageManager,
433
354
  packageName: "@highstate/pulumi"
434
355
  });
435
356
  }
436
- async function getProjectPulumiSdkVersion(projectRoot, args) {
437
- return await getProjectOverrideVersion(projectRoot, {
438
- packageManager: args.packageManager,
439
- packageName: "@pulumi/pulumi"
440
- });
441
- }
357
+ // src/shared/pulumi-cli.ts
358
+ import { execFile } from "child_process";
359
+ import { promisify } from "util";
442
360
  var execFileAsync = promisify(execFile);
443
- async function getPulumiCliVersion(cwd) {
444
- try {
445
- const { stdout } = await execFileAsync("pulumi", ["version"], {
446
- cwd
447
- });
448
- const raw = stdout.trim();
449
- if (raw.length === 0) {
450
- return null;
451
- }
452
- return raw.startsWith("v") ? raw.slice(1) : raw;
453
- } catch {
454
- return null;
455
- }
456
- }
361
+ // src/shared/schema-transformer.ts
362
+ import { readFile as readFile4 } from "fs/promises";
363
+ import MagicString from "magic-string";
364
+ import {
365
+ parseAsync
366
+ } from "oxc-parser";
367
+ import { walk } from "oxc-walker";
457
368
  var schemaTransformerPlugin = {
458
369
  name: "schema-transformer",
459
- setup(build2) {
460
- build2.onLoad({ filter: /src\/.*\.ts$/ }, async (args) => {
461
- const content = await readFile(args.path, "utf-8");
370
+ setup(build) {
371
+ build.onLoad({ filter: /src\/.*\.ts$/ }, async (args) => {
372
+ const content = await readFile4(args.path, "utf-8");
462
373
  return {
463
374
  contents: await applySchemaTransformations(content),
464
375
  loader: "ts"
@@ -518,7 +429,8 @@ async function applyZodMetaTransformations(content) {
518
429
  });
519
430
  let finalResult = result.toString();
520
431
  if (hasTransformations && !content.includes("__camelCaseToHumanReadable")) {
521
- finalResult = 'import { camelCaseToHumanReadable as __camelCaseToHumanReadable } from "@highstate/contract"\n' + finalResult;
432
+ finalResult = `import { camelCaseToHumanReadable as __camelCaseToHumanReadable } from "@highstate/contract"
433
+ ` + finalResult;
522
434
  }
523
435
  return finalResult;
524
436
  }
@@ -542,10 +454,7 @@ async function applyHelperFunctionTransformations(content) {
542
454
  if (!returnArgument) {
543
455
  return;
544
456
  }
545
- const originalReturnValue = content.substring(
546
- returnArgument.start,
547
- returnArgument.end
548
- );
457
+ const originalReturnValue = content.substring(returnArgument.start, returnArgument.end);
549
458
  if (originalReturnValue.trimStart().startsWith(`${helperFunction}(`)) {
550
459
  return;
551
460
  }
@@ -557,10 +466,7 @@ async function applyHelperFunctionTransformations(content) {
557
466
  if (!hasValue(propertyNode) || !hasSourceRange(propertyNode.value)) {
558
467
  return;
559
468
  }
560
- const originalValue = content.substring(
561
- propertyNode.value.start,
562
- propertyNode.value.end
563
- );
469
+ const originalValue = content.substring(propertyNode.value.start, propertyNode.value.end);
564
470
  const newValue = `${helperFunction}(${originalValue}, \`${description}\`)`;
565
471
  result.update(propertyNode.value.start, propertyNode.value.end, newValue);
566
472
  hasTransformations = true;
@@ -574,7 +480,8 @@ async function applyHelperFunctionTransformations(content) {
574
480
  });
575
481
  let finalResult = result.toString();
576
482
  if (hasTransformations && !content.includes("$addArgumentDescription")) {
577
- finalResult = 'import { $addArgumentDescription, $addInputDescription } from "@highstate/contract"\n' + finalResult;
483
+ finalResult = `import { $addArgumentDescription, $addInputDescription } from "@highstate/contract"
484
+ ` + finalResult;
578
485
  }
579
486
  return finalResult;
580
487
  }
@@ -588,7 +495,7 @@ async function applyDefineFunctionMetaTransformations(content) {
588
495
  if (node.type === "CallExpression" && "callee" in node && node.callee.type === "Identifier") {
589
496
  const callNode = node;
590
497
  const callee = callNode.callee;
591
- const functionName = "name" in callee && typeof callee.name === "string" ? callee.name : void 0;
498
+ const functionName = "name" in callee && typeof callee.name === "string" ? callee.name : undefined;
592
499
  if (functionName && ["defineUnit", "defineEntity", "defineComponent"].includes(functionName)) {
593
500
  const jsdoc = findJsdocForDefineFunction(content, parentStack, comments);
594
501
  if (jsdoc && callNode.arguments && callNode.arguments.length > 0) {
@@ -596,14 +503,9 @@ async function applyDefineFunctionMetaTransformations(content) {
596
503
  const firstArg = callNode.arguments[0];
597
504
  if (firstArg.type === "ObjectExpression" && "properties" in firstArg) {
598
505
  const properties = firstArg.properties;
599
- const metaProperty = properties?.find(
600
- (prop) => prop.type === "Property" && "key" in prop && prop.key?.type === "Identifier" && prop.key?.name === "meta"
601
- );
506
+ const metaProperty = properties?.find((prop) => prop.type === "Property" && ("key" in prop) && prop.key?.type === "Identifier" && prop.key?.name === "meta");
602
507
  if (metaProperty && "value" in metaProperty) {
603
- const originalMetaValue = content.substring(
604
- metaProperty.value.start,
605
- metaProperty.value.end
606
- );
508
+ const originalMetaValue = content.substring(metaProperty.value.start, metaProperty.value.end);
607
509
  const newMetaValue = injectDescriptionIntoMetaObject(originalMetaValue, description);
608
510
  result.update(metaProperty.value.start, metaProperty.value.end, newMetaValue);
609
511
  } else if (properties && properties.length > 0) {
@@ -630,19 +532,22 @@ async function applyDefineFunctionMetaTransformations(content) {
630
532
  return result.toString();
631
533
  }
632
534
  function findJsdocForDefineFunction(content, parentStack, comments) {
633
- for (let i = parentStack.length - 1; i >= 0; i--) {
535
+ for (let i = parentStack.length - 1;i >= 0; i--) {
634
536
  const node = parentStack[i];
635
537
  if (node.type === "VariableDeclarator" && "id" in node && node.id?.type === "Identifier") {
636
538
  const jsdoc = findLeadingComment(content, node, comments);
637
- if (jsdoc) return jsdoc;
539
+ if (jsdoc)
540
+ return jsdoc;
638
541
  }
639
542
  if (node.type === "VariableDeclaration") {
640
543
  const jsdoc = findLeadingComment(content, node, comments);
641
- if (jsdoc) return jsdoc;
544
+ if (jsdoc)
545
+ return jsdoc;
642
546
  }
643
547
  if (node.type === "ExportNamedDeclaration" && "declaration" in node && node.declaration) {
644
548
  const jsdoc = findLeadingComment(content, node, comments);
645
- if (jsdoc) return jsdoc;
549
+ if (jsdoc)
550
+ return jsdoc;
646
551
  }
647
552
  }
648
553
  return null;
@@ -714,7 +619,7 @@ function injectDescriptionIntoMetaObject(objectString, description) {
714
619
  }
715
620
  }
716
621
  function isInsideZodObject(parentStack) {
717
- for (let i = parentStack.length - 1; i >= 0; i--) {
622
+ for (let i = parentStack.length - 1;i >= 0; i--) {
718
623
  const node = parentStack[i];
719
624
  if (node.type === "CallExpression" && "callee" in node && node.callee.type === "MemberExpression" && isZodObjectCall(node.callee)) {
720
625
  return true;
@@ -759,7 +664,7 @@ function getHelperFunctionForProperty(parentStack) {
759
664
  return null;
760
665
  }
761
666
  function isDefinitionLikeContext(parentStack) {
762
- for (let i = parentStack.length - 1; i >= 0; i--) {
667
+ for (let i = parentStack.length - 1;i >= 0; i--) {
763
668
  const node = parentStack[i];
764
669
  if (node.type !== "CallExpression") {
765
670
  continue;
@@ -807,6 +712,8 @@ function startsWithZodCall(callExpression) {
807
712
  }
808
713
  return false;
809
714
  }
715
+ // src/shared/schemas.ts
716
+ import { z } from "zod";
810
717
  var sourceHashConfigSchema = z.discriminatedUnion("mode", [
811
718
  z.object({
812
719
  mode: z.literal("manual"),
@@ -829,7 +736,6 @@ var highstateConfigSchema = z.object({
829
736
  var highstateManifestSchema = z.object({
830
737
  sourceHashes: z.record(z.string(), z.number()).optional()
831
738
  });
832
-
833
739
  // src/shared/services.ts
834
740
  var services;
835
741
  var disposePromise;
@@ -837,7 +743,7 @@ function getBackendServices() {
837
743
  if (services) {
838
744
  return services;
839
745
  }
840
- services = import('@highstate/backend').then(({ getSharedServices }) => {
746
+ services = import("@highstate/backend").then(({ getSharedServices }) => {
841
747
  return getSharedServices({
842
748
  services: {
843
749
  logger: logger.child({}, { msgPrefix: "[backend] " })
@@ -853,9 +759,18 @@ function disposeServices() {
853
759
  if (disposePromise) {
854
760
  return disposePromise;
855
761
  }
856
- disposePromise = import('@highstate/backend').then(({ disposeServices: disposeServices2 }) => services.then((s) => disposeServices2(s)));
762
+ disposePromise = import("@highstate/backend").then(({ disposeServices: disposeServices2 }) => services.then((s) => disposeServices2(s)));
857
763
  return disposePromise;
858
764
  }
765
+ // src/shared/source-hash-calculator.ts
766
+ import { readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
767
+ import { builtinModules } from "module";
768
+ import { dirname as dirname2, isAbsolute, relative as relative2, resolve as resolve2 } from "path";
769
+ import { fileURLToPath, pathToFileURL } from "url";
770
+ import { crc32 } from "@aws-crypto/crc32";
771
+ import { resolve as importMetaResolve } from "import-meta-resolve";
772
+ import { readPackageJSON as readPackageJSON2, resolvePackageJSON as resolvePackageJSON3 } from "pkg-types";
773
+ import { z as z2 } from "zod";
859
774
  function parseFileDependencies(filePath, content) {
860
775
  const dependencyRegex = /^[ \t]*import\b[\s\S]*?\bfrom\s*["']((?<relativePath>\.\.?\/[^"']+)|(?<nodeBuiltin>node:[^"']+)|(?<npmPackage>[^"']+))["']/gm;
861
776
  const matches = content.matchAll(dependencyRegex);
@@ -863,39 +778,42 @@ function parseFileDependencies(filePath, content) {
863
778
  for (const match of matches) {
864
779
  const { nodeBuiltin, npmPackage, relativePath } = match.groups;
865
780
  if (relativePath) {
866
- const fullPath = resolve(dirname(filePath), relativePath);
781
+ const fullPath = resolve2(dirname2(filePath), relativePath);
867
782
  dependencies.push({
868
783
  type: "relative",
869
784
  id: `relative:${fullPath}`,
870
785
  fullPath
871
786
  });
872
787
  } else if (npmPackage) {
788
+ const normalizedPackageName = npmPackage.startsWith("node:") ? npmPackage.slice("node:".length) : npmPackage;
789
+ const builtinName = normalizedPackageName.split("/")[0];
790
+ if (builtinModules.includes(normalizedPackageName) || builtinModules.includes(builtinName) || builtinModules.includes(`node:${normalizedPackageName}`) || builtinModules.includes(`node:${builtinName}`)) {
791
+ continue;
792
+ }
873
793
  dependencies.push({
874
794
  type: "npm",
875
795
  id: `npm:${npmPackage}`,
876
796
  package: npmPackage
877
797
  });
878
- } else ;
798
+ } else if (nodeBuiltin) {}
879
799
  }
880
800
  return dependencies;
881
801
  }
882
- var SourceHashCalculator = class {
802
+
803
+ class SourceHashCalculator {
804
+ packageJsonPath;
805
+ packageJson;
806
+ logger;
807
+ dependencyHashes = new Map;
808
+ fileHashes = new Map;
883
809
  constructor(packageJsonPath, packageJson, logger2) {
884
810
  this.packageJsonPath = packageJsonPath;
885
811
  this.packageJson = packageJson;
886
812
  this.logger = logger2;
887
813
  }
888
- dependencyHashes = /* @__PURE__ */ new Map();
889
- fileHashes = /* @__PURE__ */ new Map();
890
- /**
891
- * Calculates CRC32 hash of a string.
892
- */
893
- hashString(input3) {
894
- return crc32(Buffer.from(input3));
895
- }
896
- /**
897
- * Gets the highstate configuration from package.json with defaults.
898
- */
814
+ hashString(input) {
815
+ return crc32(Buffer.from(input));
816
+ }
899
817
  getHighstateConfig(packageJson) {
900
818
  const rawConfig = packageJson.highstate;
901
819
  if (!rawConfig) {
@@ -904,23 +822,17 @@ var SourceHashCalculator = class {
904
822
  try {
905
823
  return highstateConfigSchema.parse(rawConfig);
906
824
  } catch (error) {
907
- this.logger.warn(
908
- { error, packageName: packageJson.name },
909
- "invalid highstate configuration, using defaults"
910
- );
825
+ this.logger.warn({ error, packageName: packageJson.name }, "invalid highstate configuration, using defaults");
911
826
  return { type: "source" };
912
827
  }
913
828
  }
914
- /**
915
- * Gets the effective source hash configuration with defaults for a specific output.
916
- */
917
829
  getSourceHashConfig(highstateConfig, exportKey) {
918
830
  if (highstateConfig.sourceHash) {
919
831
  const singleConfigResult = sourceHashConfigSchema.safeParse(highstateConfig.sourceHash);
920
832
  if (singleConfigResult.success) {
921
833
  return singleConfigResult.data;
922
834
  }
923
- const recordConfigResult = z.record(z.string(), sourceHashConfigSchema).safeParse(highstateConfig.sourceHash);
835
+ const recordConfigResult = z2.record(z2.string(), sourceHashConfigSchema).safeParse(highstateConfig.sourceHash);
924
836
  if (recordConfigResult.success && exportKey) {
925
837
  const perOutputConfig = recordConfigResult.data[exportKey];
926
838
  if (perOutputConfig) {
@@ -937,40 +849,32 @@ var SourceHashCalculator = class {
937
849
  const highstateConfig = this.getHighstateConfig(this.packageJson);
938
850
  const promises = [];
939
851
  for (const [distPath, exportKey] of distPathToExportKey) {
940
- const fullPath = resolve(distPath);
852
+ const fullPath = resolve2(distPath);
941
853
  const sourceHashConfig = this.getSourceHashConfig(highstateConfig, exportKey);
942
854
  switch (sourceHashConfig.mode) {
943
855
  case "manual":
944
- promises.push(
945
- Promise.resolve({
946
- distPath,
947
- hash: this.hashString(sourceHashConfig.version)
948
- })
949
- );
856
+ promises.push(Promise.resolve({
857
+ distPath,
858
+ hash: this.hashString(sourceHashConfig.version)
859
+ }));
950
860
  break;
951
861
  case "version":
952
- promises.push(
953
- Promise.resolve({
954
- distPath,
955
- hash: this.hashString(this.packageJson.version ?? "")
956
- })
957
- );
862
+ promises.push(Promise.resolve({
863
+ distPath,
864
+ hash: this.hashString(this.packageJson.version ?? "")
865
+ }));
958
866
  break;
959
867
  case "none":
960
- promises.push(
961
- Promise.resolve({
962
- distPath,
963
- hash: 0
964
- })
965
- );
868
+ promises.push(Promise.resolve({
869
+ distPath,
870
+ hash: 0
871
+ }));
966
872
  break;
967
873
  default:
968
- promises.push(
969
- this.getFileHash(fullPath).then((hash) => ({
970
- distPath,
971
- hash
972
- }))
973
- );
874
+ promises.push(this.getFileHash(fullPath).then((hash) => ({
875
+ distPath,
876
+ hash
877
+ })));
974
878
  break;
975
879
  }
976
880
  }
@@ -981,8 +885,8 @@ var SourceHashCalculator = class {
981
885
  for (const { distPath, hash } of hashes) {
982
886
  manifest.sourceHashes[distPath] = hash;
983
887
  }
984
- const manifestPath = resolve(distBasePath, "highstate.manifest.json");
985
- await writeFile(manifestPath, JSON.stringify(manifest, null, 2), "utf8");
888
+ const manifestPath = resolve2(distBasePath, "highstate.manifest.json");
889
+ await writeFile3(manifestPath, JSON.stringify(manifest, null, 2), "utf8");
986
890
  }
987
891
  async getFileHash(fullPath) {
988
892
  const existingHash = this.fileHashes.get(fullPath);
@@ -994,7 +898,7 @@ var SourceHashCalculator = class {
994
898
  return hash;
995
899
  }
996
900
  async calculateFileHash(fullPath) {
997
- const content = await readFile(fullPath, "utf8");
901
+ const content = await readFile5(fullPath, "utf8");
998
902
  const fileDeps = parseFileDependencies(fullPath, content);
999
903
  const hashes = await Promise.all([
1000
904
  this.hashString(content),
@@ -1020,39 +924,32 @@ var SourceHashCalculator = class {
1020
924
  let resolvedUrl;
1021
925
  try {
1022
926
  const baseUrl = pathToFileURL(this.packageJsonPath);
1023
- resolvedUrl = resolve$1(dependency.package, baseUrl.toString());
927
+ resolvedUrl = importMetaResolve(dependency.package, baseUrl.toString());
1024
928
  } catch (error) {
1025
929
  this.logger.error(`failed to resolve package "%s"`, dependency.package);
1026
930
  throw error;
1027
931
  }
1028
- const resolvedPath = fileURLToPath(resolvedUrl);
932
+ const resolvedPath = this.resolveDependencyPath(dependency.package, resolvedUrl);
933
+ if (!resolvedPath) {
934
+ this.logger.debug(`using package version as a fallback hash for "%s" due to unsupported resolver output "%s"`, dependency.package, resolvedUrl);
935
+ const [, depPackageJson2] = await this.getPackageJsonFromPackageName(dependency.package);
936
+ return this.hashString(depPackageJson2.version ?? "0.0.0");
937
+ }
1029
938
  const [depPackageJsonPath, depPackageJson] = await this.getPackageJson(resolvedPath);
1030
939
  const packageName = depPackageJson.name;
1031
- this.logger.debug(
1032
- `resolved package.json for "%s": "%s"`,
1033
- dependency.package,
1034
- depPackageJsonPath
1035
- );
940
+ this.logger.debug(`resolved package.json for "%s": "%s"`, dependency.package, depPackageJsonPath);
1036
941
  if (!this.packageJson.dependencies?.[packageName] && !this.packageJson.peerDependencies?.[packageName]) {
1037
942
  this.logger.warn(`package "%s" is not listed in package.json dependencies`, packageName);
1038
943
  }
1039
- let relativePath = relative(dirname(depPackageJsonPath), resolvedPath);
944
+ let relativePath = relative2(dirname2(depPackageJsonPath), resolvedPath);
1040
945
  relativePath = relativePath.startsWith(".") ? relativePath : `./${relativePath}`;
1041
- const highstateManifestPath = resolve(
1042
- dirname(depPackageJsonPath),
1043
- "dist",
1044
- "highstate.manifest.json"
1045
- );
946
+ const highstateManifestPath = resolve2(dirname2(depPackageJsonPath), "dist", "highstate.manifest.json");
1046
947
  let manifest;
1047
948
  try {
1048
- const manifestContent = await readFile(highstateManifestPath, "utf8");
949
+ const manifestContent = await readFile5(highstateManifestPath, "utf8");
1049
950
  manifest = highstateManifestSchema.parse(JSON.parse(manifestContent));
1050
951
  } catch (error) {
1051
- this.logger.debug(
1052
- { error },
1053
- `failed to read highstate manifest for package "%s"`,
1054
- packageName
1055
- );
952
+ this.logger.debug({ error }, `failed to read highstate manifest for package "%s"`, packageName);
1056
953
  }
1057
954
  const sourceHash = manifest?.sourceHashes?.[relativePath];
1058
955
  if (sourceHash) {
@@ -1064,18 +961,38 @@ var SourceHashCalculator = class {
1064
961
  }
1065
962
  }
1066
963
  }
964
+ resolveDependencyPath(packageName, resolvedUrl) {
965
+ if (resolvedUrl.startsWith("file:")) {
966
+ return fileURLToPath(resolvedUrl);
967
+ }
968
+ if (isAbsolute(resolvedUrl)) {
969
+ return resolvedUrl;
970
+ }
971
+ if (resolvedUrl.startsWith("node:")) {
972
+ return null;
973
+ }
974
+ if (resolvedUrl.includes(":")) {
975
+ return null;
976
+ }
977
+ const baseDir = dirname2(this.packageJsonPath);
978
+ return resolve2(baseDir, "node_modules", packageName);
979
+ }
980
+ async getPackageJsonFromPackageName(packageName) {
981
+ const baseDir = dirname2(this.packageJsonPath);
982
+ const packagePath = resolve2(baseDir, "node_modules", packageName);
983
+ return await this.getPackageJson(packagePath);
984
+ }
1067
985
  async getPackageJson(basePath) {
1068
986
  while (true) {
1069
- const packageJson = await readPackageJSON(basePath);
987
+ const packageJson = await readPackageJSON2(basePath);
1070
988
  if (packageJson.name) {
1071
- const packageJsonPath = await resolvePackageJSON(basePath);
989
+ const packageJsonPath = await resolvePackageJSON3(basePath);
1072
990
  return [packageJsonPath, packageJson];
1073
991
  }
1074
- basePath = resolve(dirname(basePath), "..");
992
+ basePath = resolve2(dirname2(basePath), "..");
1075
993
  }
1076
994
  }
1077
- };
1078
-
995
+ }
1079
996
  // src/shared/version-bundle.ts
1080
997
  var platformSourcePackage = "@highstate/pulumi";
1081
998
  var stdlibSourcePackage = "@highstate/library";
@@ -1087,9 +1004,7 @@ async function resolveVersionBundle(args) {
1087
1004
  const platformManifest = await fetchManifest(platformSourcePackage, resolvedPlatformVersion);
1088
1005
  const inferredPulumi = getDependencyRange(platformManifest, "@pulumi/pulumi");
1089
1006
  if (!inferredPulumi) {
1090
- throw new Error(
1091
- `Unable to infer "@pulumi/pulumi" version from "${platformSourcePackage}@${resolvedPlatformVersion}"`
1092
- );
1007
+ throw new Error(`Unable to infer "@pulumi/pulumi" version from "${platformSourcePackage}@${resolvedPlatformVersion}"`);
1093
1008
  }
1094
1009
  return {
1095
1010
  platformVersion: resolvedPlatformVersion,
@@ -1098,8 +1013,8 @@ async function resolveVersionBundle(args) {
1098
1013
  };
1099
1014
  }
1100
1015
  function normalizeProvidedVersion(value, label) {
1101
- if (value === void 0) {
1102
- return void 0;
1016
+ if (value === undefined) {
1017
+ return;
1103
1018
  }
1104
1019
  const trimmed = value.trim();
1105
1020
  if (trimmed.length === 0) {
@@ -1107,12 +1022,17 @@ function normalizeProvidedVersion(value, label) {
1107
1022
  }
1108
1023
  return trimmed;
1109
1024
  }
1110
- var packageJsonSchema = z.object({
1111
- name: z.string(),
1025
+ // src/shared/workspace.ts
1026
+ import { existsSync } from "fs";
1027
+ import { mkdir as mkdir2, readdir as readdir2, readFile as readFile6, writeFile as writeFile4 } from "fs/promises";
1028
+ import { join as join2, relative as relative3, resolve as resolve3 } from "path";
1029
+ import { z as z3 } from "zod";
1030
+ var packageJsonSchema = z3.object({
1031
+ name: z3.string(),
1112
1032
  highstate: highstateConfigSchema.optional()
1113
1033
  });
1114
1034
  function generateTsconfigContent(workspaceRoot, packagePath) {
1115
- const relativePath = relative(workspaceRoot, packagePath);
1035
+ const relativePath = relative3(workspaceRoot, packagePath);
1116
1036
  const depth = relativePath.split("/").length;
1117
1037
  const relativeNodeModules = `${"../".repeat(depth)}node_modules/@highstate/cli/assets/tsconfig.base.json`;
1118
1038
  return {
@@ -1121,49 +1041,50 @@ function generateTsconfigContent(workspaceRoot, packagePath) {
1121
1041
  };
1122
1042
  }
1123
1043
  async function findWorkspaceRoot(startPath = process.cwd()) {
1124
- let currentPath = resolve(startPath);
1044
+ let currentPath = resolve3(startPath);
1125
1045
  while (currentPath !== "/") {
1126
- const packageJsonPath = join(currentPath, "package.json");
1046
+ const packageJsonPath = join2(currentPath, "package.json");
1127
1047
  if (existsSync(packageJsonPath)) {
1128
1048
  try {
1129
- const content = await readFile(packageJsonPath, "utf-8");
1049
+ const content = await readFile6(packageJsonPath, "utf-8");
1130
1050
  const packageJson = JSON.parse(content);
1131
1051
  if (packageJson.workspaces) {
1132
1052
  return currentPath;
1133
1053
  }
1134
- } catch {
1135
- }
1054
+ } catch {}
1136
1055
  }
1137
- const parentPath = resolve(currentPath, "..");
1138
- if (parentPath === currentPath) break;
1056
+ const parentPath = resolve3(currentPath, "..");
1057
+ if (parentPath === currentPath)
1058
+ break;
1139
1059
  currentPath = parentPath;
1140
1060
  }
1141
1061
  throw new Error("Could not find workspace root (no package.json with workspaces found)");
1142
1062
  }
1143
1063
  async function scanWorkspacePackages(workspaceRoot) {
1144
1064
  const packages = [];
1145
- const packagesDir = join(workspaceRoot, "packages");
1065
+ const packagesDir = join2(workspaceRoot, "packages");
1146
1066
  if (!existsSync(packagesDir)) {
1147
1067
  return packages;
1148
1068
  }
1149
1069
  async function scanDirectory(dirPath, depth = 0) {
1150
- const dirName = relative(packagesDir, dirPath).split("/").pop();
1070
+ const dirName = relative3(packagesDir, dirPath).split("/").pop();
1151
1071
  if (dirName?.startsWith(".") || dirName === "node_modules") {
1152
1072
  return;
1153
1073
  }
1154
- const entries = await readdir(dirPath, { withFileTypes: true });
1074
+ const entries = await readdir2(dirPath, { withFileTypes: true });
1155
1075
  for (const entry of entries) {
1156
- if (!entry.isDirectory()) continue;
1157
- const entryPath = join(dirPath, entry.name);
1076
+ if (!entry.isDirectory())
1077
+ continue;
1078
+ const entryPath = join2(dirPath, entry.name);
1158
1079
  if (entry.name.startsWith(".") || entry.name === "node_modules") {
1159
1080
  continue;
1160
1081
  }
1161
- const packageJsonPath = join(entryPath, "package.json");
1082
+ const packageJsonPath = join2(entryPath, "package.json");
1162
1083
  if (existsSync(packageJsonPath)) {
1163
1084
  try {
1164
- const content = await readFile(packageJsonPath, "utf-8");
1085
+ const content = await readFile6(packageJsonPath, "utf-8");
1165
1086
  const packageJson = packageJsonSchema.parse(JSON.parse(content));
1166
- const relativePath = relative(workspaceRoot, entryPath);
1087
+ const relativePath = relative3(workspaceRoot, entryPath);
1167
1088
  const type = packageJson.highstate?.type ?? "source";
1168
1089
  packages.push({
1169
1090
  path: entryPath,
@@ -1171,8 +1092,7 @@ async function scanWorkspacePackages(workspaceRoot) {
1171
1092
  name: packageJson.name,
1172
1093
  type
1173
1094
  });
1174
- } catch {
1175
- }
1095
+ } catch {}
1176
1096
  }
1177
1097
  if (depth < 3) {
1178
1098
  await scanDirectory(entryPath, depth + 1);
@@ -1183,13 +1103,9 @@ async function scanWorkspacePackages(workspaceRoot) {
1183
1103
  return packages.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
1184
1104
  }
1185
1105
  async function updateTsconfigReferences(workspaceRoot, packages, ensureTsconfigs = false) {
1186
- const tsconfigPath = join(workspaceRoot, "tsconfig.json");
1106
+ const tsconfigPath = join2(workspaceRoot, "tsconfig.json");
1187
1107
  if (ensureTsconfigs) {
1188
- await ensurePackageTsconfigs(
1189
- workspaceRoot,
1190
- // only udate for Highstate-managed packages
1191
- packages.filter((pkg) => pkg.type !== void 0)
1192
- );
1108
+ await ensurePackageTsconfigs(workspaceRoot, packages.filter((pkg) => pkg.type !== undefined));
1193
1109
  }
1194
1110
  const references = packages.map((pkg) => ({
1195
1111
  path: `./${pkg.relativePath}/tsconfig.json`
@@ -1198,22 +1114,22 @@ async function updateTsconfigReferences(workspaceRoot, packages, ensureTsconfigs
1198
1114
  files: [],
1199
1115
  references
1200
1116
  };
1201
- await writeFile(tsconfigPath, `${JSON.stringify(tsconfigContent, null, 2)}
1117
+ await writeFile4(tsconfigPath, `${JSON.stringify(tsconfigContent, null, 2)}
1202
1118
  `, "utf-8");
1203
1119
  }
1204
1120
  async function ensurePackageTsconfigs(workspaceRoot, packages) {
1205
1121
  for (const pkg of packages) {
1206
- const tsconfigPath = join(pkg.path, "tsconfig.json");
1122
+ const tsconfigPath = join2(pkg.path, "tsconfig.json");
1207
1123
  const tsconfigContent = generateTsconfigContent(workspaceRoot, pkg.path);
1208
- await writeFile(tsconfigPath, `${JSON.stringify(tsconfigContent, null, 2)}
1124
+ await writeFile4(tsconfigPath, `${JSON.stringify(tsconfigContent, null, 2)}
1209
1125
  `, "utf-8");
1210
1126
  }
1211
1127
  }
1212
1128
  async function createPackage(workspaceRoot, name, type) {
1213
- const packagePath = join(workspaceRoot, "packages", name);
1214
- const srcPath = join(packagePath, "src");
1215
- await mkdir(packagePath, { recursive: true });
1216
- await mkdir(srcPath, { recursive: true });
1129
+ const packagePath = join2(workspaceRoot, "packages", name);
1130
+ const srcPath = join2(packagePath, "src");
1131
+ await mkdir2(packagePath, { recursive: true });
1132
+ await mkdir2(srcPath, { recursive: true });
1217
1133
  const packageJson = {
1218
1134
  name: `@highstate/${name}`,
1219
1135
  version: "0.0.1",
@@ -1222,20 +1138,12 @@ async function createPackage(workspaceRoot, name, type) {
1222
1138
  type
1223
1139
  }
1224
1140
  };
1225
- await writeFile(
1226
- join(packagePath, "package.json"),
1227
- `${JSON.stringify(packageJson, null, 2)}
1228
- `,
1229
- "utf-8"
1230
- );
1141
+ await writeFile4(join2(packagePath, "package.json"), `${JSON.stringify(packageJson, null, 2)}
1142
+ `, "utf-8");
1231
1143
  const tsconfigContent = generateTsconfigContent(workspaceRoot, packagePath);
1232
- await writeFile(
1233
- join(packagePath, "tsconfig.json"),
1234
- `${JSON.stringify(tsconfigContent, null, 2)}
1235
- `,
1236
- "utf-8"
1237
- );
1238
- await writeFile(join(srcPath, "index.ts"), `// ${name} package
1144
+ await writeFile4(join2(packagePath, "tsconfig.json"), `${JSON.stringify(tsconfigContent, null, 2)}
1145
+ `, "utf-8");
1146
+ await writeFile4(join2(srcPath, "index.ts"), `// ${name} package
1239
1147
  `, "utf-8");
1240
1148
  return {
1241
1149
  path: packagePath,
@@ -1244,16 +1152,15 @@ async function createPackage(workspaceRoot, name, type) {
1244
1152
  type
1245
1153
  };
1246
1154
  }
1247
-
1248
1155
  // src/commands/backend/identity.ts
1249
- var BackendIdentityCommand = class extends Command {
1156
+ class BackendIdentityCommand extends Command {
1250
1157
  static paths = [["backend", "identity"]];
1251
1158
  static usage = Command.Usage({
1252
1159
  category: "Backend",
1253
1160
  description: "Ensures the backend identity is set up and returns the recipient."
1254
1161
  });
1255
1162
  async execute() {
1256
- const { getOrCreateBackendIdentity } = await import('@highstate/backend');
1163
+ const { getOrCreateBackendIdentity } = await import("@highstate/backend");
1257
1164
  const config = await loadConfig();
1258
1165
  const backendIdentity = await getOrCreateBackendIdentity(config, logger);
1259
1166
  const recipient = await identityToRecipient(backendIdentity);
@@ -1263,16 +1170,15 @@ var BackendIdentityCommand = class extends Command {
1263
1170
  logger.info(`run "highstate backend unlock-method add %s" on a trusted device`, recipient);
1264
1171
  return;
1265
1172
  }
1266
- logger.info(
1267
- `run "highstate backend unlock-method add %s --title %s" on a trusted device`,
1268
- recipient,
1269
- suggestedTitle
1270
- );
1173
+ logger.info(`run "highstate backend unlock-method add %s --title %s" on a trusted device`, recipient, suggestedTitle);
1271
1174
  }
1272
- };
1273
- var BackendUnlockMethodAddCommand = class extends Command {
1175
+ }
1176
+ // src/commands/backend/unlock-method/add.ts
1177
+ import { input } from "@inquirer/prompts";
1178
+ import { Command as Command2, Option } from "clipanion";
1179
+ class BackendUnlockMethodAddCommand extends Command2 {
1274
1180
  static paths = [["backend", "unlock-method", "add"]];
1275
- static usage = Command.Usage({
1181
+ static usage = Command2.Usage({
1276
1182
  category: "Backend",
1277
1183
  description: "Adds a new backend unlock method for the current workspace.",
1278
1184
  examples: [["Add recipient", "highstate backend unlock-method add age1example --title Laptop"]]
@@ -1290,15 +1196,15 @@ var BackendUnlockMethodAddCommand = class extends Command {
1290
1196
  });
1291
1197
  }
1292
1198
  let description = this.description;
1293
- if (description === void 0) {
1199
+ if (description === undefined) {
1294
1200
  description = await input({
1295
1201
  message: "Description (optional)",
1296
1202
  default: ""
1297
1203
  });
1298
1204
  }
1299
- const services2 = await getBackendServices();
1205
+ const services3 = await getBackendServices();
1300
1206
  try {
1301
- const result = await services2.backendUnlockService.addUnlockMethod({
1207
+ const result = await services3.backendUnlockService.addUnlockMethod({
1302
1208
  recipient: this.recipient,
1303
1209
  meta: description ? { title: title.trim(), description: description.trim() } : { title: title.trim() }
1304
1210
  });
@@ -1308,15 +1214,18 @@ var BackendUnlockMethodAddCommand = class extends Command {
1308
1214
  }
1309
1215
  process.exit(0);
1310
1216
  }
1311
- };
1312
- var BackendUnlockMethodDeleteCommand = class extends Command {
1217
+ }
1218
+ // src/commands/backend/unlock-method/delete.ts
1219
+ import { confirm } from "@inquirer/prompts";
1220
+ import { Command as Command3, Option as Option2 } from "clipanion";
1221
+ class BackendUnlockMethodDeleteCommand extends Command3 {
1313
1222
  static paths = [["backend", "unlock-method", "delete"]];
1314
- static usage = Command.Usage({
1223
+ static usage = Command3.Usage({
1315
1224
  category: "Backend",
1316
1225
  description: "Removes a backend unlock method by its identifier."
1317
1226
  });
1318
- id = Option.String();
1319
- force = Option.Boolean("--force", false);
1227
+ id = Option2.String();
1228
+ force = Option2.Boolean("--force", false);
1320
1229
  async execute() {
1321
1230
  if (!this.force) {
1322
1231
  const answer = await confirm({
@@ -1328,26 +1237,29 @@ var BackendUnlockMethodDeleteCommand = class extends Command {
1328
1237
  return;
1329
1238
  }
1330
1239
  }
1331
- const services2 = await getBackendServices();
1240
+ const services3 = await getBackendServices();
1332
1241
  try {
1333
- await services2.backendUnlockService.deleteUnlockMethod(this.id);
1242
+ await services3.backendUnlockService.deleteUnlockMethod(this.id);
1334
1243
  logger.info(`deleted backend unlock method "%s"`, this.id);
1335
1244
  } finally {
1336
1245
  await disposeServices();
1337
1246
  }
1338
1247
  process.exit(0);
1339
1248
  }
1340
- };
1341
- var BackendUnlockMethodListCommand = class extends Command {
1249
+ }
1250
+ // src/commands/backend/unlock-method/list.ts
1251
+ import { Command as Command4 } from "clipanion";
1252
+ import { Table } from "console-table-printer";
1253
+ class BackendUnlockMethodListCommand extends Command4 {
1342
1254
  static paths = [["backend", "unlock-method", "list"]];
1343
- static usage = Command.Usage({
1255
+ static usage = Command4.Usage({
1344
1256
  category: "Backend",
1345
1257
  description: "Lists backend unlock methods registered for the current workspace."
1346
1258
  });
1347
1259
  async execute() {
1348
- const services2 = await getBackendServices();
1260
+ const services3 = await getBackendServices();
1349
1261
  try {
1350
- const methods = await services2.backendUnlockService.listUnlockMethods();
1262
+ const methods = await services3.backendUnlockService.listUnlockMethods();
1351
1263
  if (methods.length === 0) {
1352
1264
  logger.warn("no backend unlock methods configured");
1353
1265
  return;
@@ -1363,33 +1275,60 @@ var BackendUnlockMethodListCommand = class extends Command {
1363
1275
  alignment: "left"
1364
1276
  }
1365
1277
  });
1366
- table.addRows(
1367
- methods.map((method) => ({
1368
- title: method.meta.title,
1369
- id: method.id,
1370
- recipient: method.recipient,
1371
- description: method.meta.description ?? ""
1372
- }))
1373
- );
1278
+ table.addRows(methods.map((method) => ({
1279
+ title: method.meta.title,
1280
+ id: method.id,
1281
+ recipient: method.recipient,
1282
+ description: method.meta.description ?? ""
1283
+ })));
1374
1284
  table.printTable();
1375
1285
  } finally {
1376
1286
  await disposeServices();
1377
1287
  }
1378
1288
  process.exit(0);
1379
1289
  }
1380
- };
1381
- var BuildCommand = class extends Command {
1290
+ }
1291
+ // src/commands/build.ts
1292
+ import { chmod, readFile as readFile7, rm, writeFile as writeFile5 } from "fs/promises";
1293
+ import { resolve as resolve4 } from "path";
1294
+ import { encode } from "@msgpack/msgpack";
1295
+ import { Command as Command5, Option as Option3 } from "clipanion";
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
+
1311
+ class BuildCommand extends Command5 {
1382
1312
  static paths = [["build"]];
1383
- static usage = Command.Usage({
1313
+ static usage = Command5.Usage({
1384
1314
  category: "Builder",
1385
1315
  description: "Builds the Highstate library or unit package."
1386
1316
  });
1387
- watch = Option.Boolean("--watch", false);
1388
- library = Option.Boolean("--library", false);
1389
- silent = Option.Boolean("--silent", true);
1390
- noSourceHash = Option.Boolean("--no-source-hash", false);
1317
+ library = Option3.Boolean("--library", false);
1318
+ silent = Option3.Boolean("--silent", true);
1319
+ noSourceHash = Option3.Boolean("--no-source-hash", false);
1391
1320
  async execute() {
1392
- const packageJson = await readPackageJSON();
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() {
1331
+ const packageJson = await readPackageJSON3();
1393
1332
  const highstateConfig = highstateConfigSchema.parse(packageJson.highstate ?? {});
1394
1333
  if (highstateConfig.type === "library") {
1395
1334
  this.library = true;
@@ -1404,168 +1343,194 @@ var BuildCommand = class extends Command {
1404
1343
  if (Object.keys(entryPoints).length === 0) {
1405
1344
  return;
1406
1345
  }
1407
- const esbuildPlugins = [];
1346
+ const bunPlugins = [];
1408
1347
  const binSourceFilePaths = Object.values(entryPoints).filter((value) => value.isBin).map((value) => value.entryPoint.slice(2));
1409
1348
  if (this.library) {
1410
- esbuildPlugins.push(schemaTransformerPlugin);
1349
+ bunPlugins.push(schemaTransformerPlugin);
1411
1350
  }
1412
1351
  if (binSourceFilePaths.length > 0) {
1413
- esbuildPlugins.push(createBinTransformerPlugin(binSourceFilePaths));
1414
- }
1415
- await build({
1416
- entry: mapValues(entryPoints, (value) => value.entryPoint),
1417
- outDir: "dist",
1418
- watch: this.watch,
1419
- sourcemap: true,
1420
- clean: true,
1352
+ bunPlugins.push(createBinTransformerPlugin(binSourceFilePaths));
1353
+ }
1354
+ await rm("dist", { recursive: true, force: true });
1355
+ const bunEntryPoints = Object.values(entryPoints).map((value) => value.entryPoint);
1356
+ const result = await Bun.build({
1357
+ entrypoints: bunEntryPoints,
1358
+ outdir: "dist",
1359
+ root: "./src",
1421
1360
  format: "esm",
1422
- target: "es2024",
1423
- platform: "node",
1361
+ target: "bun",
1424
1362
  external: ["@pulumi/pulumi"],
1425
- esbuildPlugins,
1426
- treeshake: true,
1427
- removeNodeProtocol: false,
1428
- silent: this.silent || ["warn", "error", "fatal"].includes(logger.level)
1363
+ packages: "external",
1364
+ splitting: true,
1365
+ plugins: bunPlugins
1429
1366
  });
1430
- const packageJsonPath = await resolvePackageJSON();
1431
- const upToDatePackageJson = await readPackageJSON();
1367
+ if (!result.success) {
1368
+ for (const log of result.logs) {
1369
+ logger.error(log.message);
1370
+ }
1371
+ throw new Error("build failed");
1372
+ }
1373
+ const binEntryPoints = Object.values(entryPoints).filter((value) => value.isBin);
1374
+ for (const binEntryPoint of binEntryPoints) {
1375
+ const binPath = resolve4(binEntryPoint.distPath);
1376
+ const binContent = await readFile7(binPath, "utf8");
1377
+ if (!binContent.startsWith(`#!/usr/bin/env bun
1378
+ `)) {
1379
+ await writeFile5(binPath, `#!/usr/bin/env bun
1380
+ ${binContent}`, "utf8");
1381
+ }
1382
+ await chmod(binPath, 493);
1383
+ }
1384
+ const packageJsonPath = await resolvePackageJSON4();
1385
+ const upToDatePackageJson = await readPackageJSON3();
1432
1386
  if (!this.noSourceHash) {
1433
- const sourceHashCalculator = new SourceHashCalculator(
1434
- packageJsonPath,
1435
- upToDatePackageJson,
1436
- logger
1437
- );
1438
- const distPathToExportKey = /* @__PURE__ */ new Map();
1387
+ const sourceHashCalculator = new SourceHashCalculator(packageJsonPath, upToDatePackageJson, logger);
1388
+ const distPathToExportKey = new Map;
1439
1389
  for (const value of Object.values(entryPoints)) {
1440
1390
  distPathToExportKey.set(value.distPath, value.key);
1441
1391
  }
1442
1392
  await sourceHashCalculator.writeHighstateManifest("./dist", distPathToExportKey);
1443
1393
  }
1444
1394
  if (this.library) {
1445
- const { loadLibrary } = await import('./library-loader-PZWYMBAE.js');
1446
- const fullModulePaths = Object.values(entryPoints).map((value) => resolve(value.distPath));
1395
+ const { loadLibrary } = await import("./chunk-sxh2gdkm.js");
1396
+ const fullModulePaths = Object.values(entryPoints).map((value) => resolve4(value.distPath));
1447
1397
  logger.info("evaluating library components from modules: %s", fullModulePaths.join(", "));
1448
1398
  const library = await loadLibrary(logger, fullModulePaths);
1449
- const libraryPath = resolve("./dist", "highstate.library.msgpack");
1450
- await writeFile(libraryPath, encode(library), "utf8");
1399
+ const libraryPath = resolve4("./dist", "highstate.library.msgpack");
1400
+ await writeFile5(libraryPath, encode(library), "utf8");
1451
1401
  }
1452
1402
  logger.info("build completed successfully");
1453
1403
  }
1454
- };
1455
- var DesignerCommand = class extends Command {
1404
+ }
1405
+ // src/commands/designer.ts
1406
+ import { pathToFileURL as pathToFileURL2 } from "url";
1407
+ import { Command as Command6, UsageError } from "clipanion";
1408
+ import { consola as consola2 } from "consola";
1409
+ import { colorize } from "consola/utils";
1410
+ import { checkPort, getPort } from "get-port-please";
1411
+ import { resolve as importMetaResolve2 } from "import-meta-resolve";
1412
+ import { addDevDependency } from "nypm";
1413
+ import { readPackageJSON as readPackageJSON4, resolvePackageJSON as resolvePackageJSON5 } from "pkg-types";
1414
+ var shuttingDown = false;
1415
+
1416
+ class DesignerCommand extends Command6 {
1456
1417
  static paths = [["designer"]];
1457
- static usage = Command.Usage({
1418
+ static usage = Command6.Usage({
1458
1419
  category: "Designer",
1459
1420
  description: "Starts the Highstate designer in the current project."
1460
1421
  });
1461
1422
  async execute() {
1462
- const packageJsonPath = await resolvePackageJSON();
1463
- const packageJsonUrl = pathToFileURL(packageJsonPath).toString();
1464
- const packageJson = await readPackageJSON(packageJsonPath);
1423
+ const packageJsonPath = await resolvePackageJSON5();
1424
+ const packageJsonUrl = pathToFileURL2(packageJsonPath).toString();
1425
+ const packageJson = await readPackageJSON4(packageJsonPath);
1465
1426
  if (!packageJson.devDependencies?.["@highstate/cli"]) {
1466
- throw new UsageError(
1467
- "This project is not a Highstate project.\n@highstate/cli must be installed as a devDependency."
1468
- );
1427
+ throw new UsageError(`This project is not a Highstate project.
1428
+ @highstate/cli must be installed as a devDependency.`);
1469
1429
  }
1470
1430
  if (!packageJson.devDependencies?.["@highstate/designer"]) {
1471
1431
  logger.info("Installing @highstate/designer...");
1472
1432
  await addDevDependency(["@highstate/designer", "classic-level"]);
1473
1433
  }
1474
- const projectRoot = process.cwd();
1475
- const detected = await detectPackageManager(projectRoot);
1476
- const packageManager = detected?.name;
1477
- if (packageManager === "npm" || packageManager === "pnpm" || packageManager === "yarn") {
1478
- const expectedPulumiSdk = await getProjectPulumiSdkVersion(projectRoot, { packageManager });
1479
- const actualPulumiCli = await getPulumiCliVersion(projectRoot);
1480
- if (expectedPulumiSdk && actualPulumiCli && expectedPulumiSdk !== actualPulumiCli) {
1481
- logger.warn(
1482
- `pulumi version mismatch detected, this may cause incompatibilities
1483
- expected "%s" (from overrides for "@pulumi/pulumi"), got "%s" (from "pulumi version")
1484
- recommended: run "highstate update" or downgrade your Pulumi CLI to "%s"`,
1485
- expectedPulumiSdk,
1486
- actualPulumiCli,
1487
- expectedPulumiSdk
1488
- );
1489
- }
1490
- }
1491
1434
  logger.info("starting highstate designer...");
1492
1435
  await getBackendServices();
1493
1436
  const oldConsoleLog = console.log;
1494
- const port = await getPort({ port: 3e3 });
1495
- const eventsPort = await getPort({ port: 3001 });
1496
- const designerPackageJsonPath = resolve$1(
1497
- "@highstate/designer/package.json",
1498
- packageJsonUrl
1499
- );
1500
- const designerPackageJson = await readPackageJSON(designerPackageJsonPath);
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 });
1451
+ const designerPackageJsonPath = importMetaResolve2("@highstate/designer/package.json", packageJsonUrl);
1452
+ const designerPackageJson = await readPackageJSON4(designerPackageJsonPath);
1501
1453
  process.env.NITRO_PORT = port.toString();
1502
- process.env.NITRO_HOST = "0.0.0.0";
1454
+ process.env.NITRO_HOST = host;
1455
+ process.env.NITRO_BUN_IDLE_TIMEOUT ??= "255";
1503
1456
  process.env.NUXT_PUBLIC_VERSION = designerPackageJson.version;
1504
1457
  process.env.NUXT_PUBLIC_EVENTS_PORT = eventsPort.toString();
1505
- await new Promise((resolve7) => {
1506
- console.log = (message) => {
1507
- if (message.startsWith("Listening on")) {
1508
- resolve7();
1509
- }
1510
- };
1511
- const serverPath = resolve$1("@highstate/designer/server", packageJsonUrl);
1512
- void import(serverPath);
1513
- });
1514
- console.log = oldConsoleLog;
1515
- consola.log(
1516
- [
1517
- "\n ",
1518
- colorize("bold", colorize("cyanBright", "Highstate Designer")),
1519
- "\n ",
1520
- colorize("greenBright", "\u279C Local: "),
1521
- colorize("underline", colorize("cyanBright", `http://localhost:${port}`)),
1522
- "\n"
1523
- ].join("")
1524
- );
1525
- process.on("SIGINT", () => {
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
+ }
1475
+ consola2.log([
1476
+ `
1477
+ `,
1478
+ colorize("bold", colorize("cyanBright", "Highstate Designer")),
1479
+ `
1480
+ `,
1481
+ colorize("greenBright", "\u279C Local: "),
1482
+ colorize("underline", colorize("cyanBright", `http://highstate.localhost:${port}`)),
1483
+ `
1484
+ `
1485
+ ].join(""));
1486
+ process.once("SIGINT", () => {
1487
+ if (shuttingDown) {
1488
+ return;
1489
+ }
1490
+ shuttingDown = true;
1526
1491
  process.stdout.write("\r");
1527
- consola.info("shutting down highstate designer...");
1528
- setTimeout(() => process.exit(0), 1e3);
1492
+ consola2.info("shutting down highstate designer...");
1493
+ setTimeout(() => process.exit(0), 1000);
1529
1494
  });
1530
1495
  }
1531
- };
1532
- var InitCommand = class extends Command {
1496
+ }
1497
+ // src/commands/init.ts
1498
+ import { access, mkdir as mkdir3, readdir as readdir3 } from "fs/promises";
1499
+ import { resolve as resolve5 } from "path";
1500
+ import { fileURLToPath as fileURLToPath2 } from "url";
1501
+ import { input as input2 } from "@inquirer/prompts";
1502
+ import { Command as Command7, Option as Option4 } from "clipanion";
1503
+ import { installDependencies } from "nypm";
1504
+ class InitCommand extends Command7 {
1533
1505
  static paths = [["init"]];
1534
- static usage = Command.Usage({
1506
+ static usage = Command7.Usage({
1535
1507
  description: "Initializes a new Highstate project."
1536
1508
  });
1537
- pathOption = Option.String("--path,-p", {
1509
+ pathOption = Option4.String("--path,-p", {
1538
1510
  description: "The path where the project should be initialized."
1539
1511
  });
1540
- packageManager = Option.String("--package-manager", {
1541
- description: "The package manager to use (npm, yarn, pnpm)."
1542
- });
1543
- name = Option.String("--name", {
1512
+ name = Option4.String("--name", {
1544
1513
  description: "The project name."
1545
1514
  });
1546
- platformVersion = Option.String("--platform-version", {
1515
+ platformVersion = Option4.String("--platform-version", {
1547
1516
  description: "The Highstate platform version to use."
1548
1517
  });
1549
- stdlibVersion = Option.String("--stdlib-version", {
1518
+ stdlibVersion = Option4.String("--stdlib-version", {
1550
1519
  description: "The Highstate standard library version to use."
1551
1520
  });
1552
1521
  async execute() {
1553
- const availablePackageManagers = await detectAvailablePackageManagers(["npm", "pnpm", "yarn"]);
1554
- if (availablePackageManagers.length === 0) {
1555
- throw new Error('No supported package managers found in PATH ("npm", "pnpm", "yarn")');
1522
+ const isBunAvailable = await isExecutableInPath("bun");
1523
+ if (!isBunAvailable) {
1524
+ throw new Error('Required package manager "bun" was not found in PATH');
1556
1525
  }
1557
1526
  const projectName = await resolveProjectName(this.name);
1558
1527
  const destinationPath = await resolveDestinationPath(this.pathOption, projectName);
1559
- const selectedPackageManager = await resolvePackageManager(
1560
- this.packageManager,
1561
- availablePackageManagers
1562
- );
1563
1528
  const templatePath = resolveTemplatePath();
1564
1529
  const versionBundle = await resolveVersionBundle({
1565
1530
  platformVersion: this.platformVersion,
1566
1531
  stdlibVersion: this.stdlibVersion
1567
1532
  });
1568
- await mkdir(destinationPath, { recursive: true });
1533
+ await mkdir3(destinationPath, { recursive: true });
1569
1534
  const isEmptyOrMissing = await isEmptyDirectory(destinationPath);
1570
1535
  if (!isEmptyOrMissing) {
1571
1536
  throw new Error(`Destination path is not empty: "${destinationPath}"`);
@@ -1575,85 +1540,49 @@ var InitCommand = class extends Command {
1575
1540
  projectName,
1576
1541
  packageName: projectName,
1577
1542
  platformVersion: versionBundle.platformVersion,
1578
- libraryVersion: versionBundle.stdlibVersion,
1579
- isPnpm: selectedPackageManager === "pnpm" ? "true" : "",
1580
- isYarn: selectedPackageManager === "yarn" ? "true" : "",
1581
- isNpm: selectedPackageManager === "npm" ? "true" : ""
1543
+ libraryVersion: versionBundle.stdlibVersion
1582
1544
  });
1583
- const overrides = buildOverrides(versionBundle);
1545
+ const overrides2 = buildOverrides(versionBundle);
1584
1546
  await applyOverrides({
1585
1547
  projectRoot: destinationPath,
1586
- packageManager: selectedPackageManager,
1587
- overrides
1548
+ overrides: overrides2
1588
1549
  });
1589
- logger.info("installing dependencies using %s...", selectedPackageManager);
1550
+ logger.info("installing dependencies using bun...");
1590
1551
  await installDependencies({
1591
1552
  cwd: destinationPath,
1592
- packageManager: selectedPackageManager,
1553
+ packageManager: "bun",
1593
1554
  silent: false
1594
1555
  });
1595
1556
  logger.info("project initialized successfully");
1596
1557
  }
1597
- };
1558
+ }
1598
1559
  async function resolveDestinationPath(pathOption, projectName) {
1599
1560
  if (pathOption) {
1600
- return resolve(pathOption);
1561
+ return resolve5(pathOption);
1601
1562
  }
1602
- const defaultPath = resolve(process.cwd(), projectName);
1603
- const pathValue = await input({
1563
+ const defaultPath = resolve5(process.cwd(), projectName);
1564
+ const pathValue = await input2({
1604
1565
  message: "Project path",
1605
1566
  default: defaultPath,
1606
1567
  validate: (value) => value.trim().length > 0 ? true : "Path is required"
1607
1568
  });
1608
- return resolve(pathValue);
1569
+ return resolve5(pathValue);
1609
1570
  }
1610
1571
  async function resolveProjectName(nameOption) {
1611
- if (nameOption !== void 0) {
1572
+ if (nameOption !== undefined) {
1612
1573
  const trimmed = nameOption.trim();
1613
1574
  if (trimmed.length === 0) {
1614
1575
  throw new Error('Flag "--name" must not be empty');
1615
1576
  }
1616
1577
  return trimmed;
1617
1578
  }
1618
- const value = await input({
1579
+ const value = await input2({
1619
1580
  message: "Project name",
1620
1581
  default: "my-project",
1621
1582
  validate: (inputValue) => inputValue.trim().length > 0 ? true : "Name is required"
1622
1583
  });
1623
1584
  return value.trim();
1624
1585
  }
1625
- async function resolvePackageManager(packageManagerOption, available) {
1626
- if (packageManagerOption) {
1627
- if (!isSupportedPackageManagerName(packageManagerOption)) {
1628
- throw new Error(`Unsupported package manager: "${packageManagerOption}"`);
1629
- }
1630
- const name = packageManagerOption;
1631
- if (!available.includes(name)) {
1632
- throw new Error(`Package manager not found in PATH: "${name}"`);
1633
- }
1634
- return name;
1635
- }
1636
- const preferredOrder = ["pnpm", "yarn", "npm"];
1637
- const defaultValue = preferredOrder.find((value) => available.includes(value)) ?? available[0];
1638
- return await select({
1639
- message: "Package manager",
1640
- default: defaultValue,
1641
- choices: available.map((value) => ({ name: value, value }))
1642
- });
1643
- }
1644
- function isSupportedPackageManagerName(value) {
1645
- return value === "npm" || value === "pnpm" || value === "yarn";
1646
- }
1647
- async function detectAvailablePackageManagers(candidates) {
1648
- const results = [];
1649
- for (const candidate of candidates) {
1650
- const exists = await isExecutableInPath(candidate);
1651
- if (exists) {
1652
- results.push(candidate);
1653
- }
1654
- }
1655
- return results;
1656
- }
1657
1586
  async function isExecutableInPath(command) {
1658
1587
  const pathValue = process.env.PATH;
1659
1588
  if (!pathValue) {
@@ -1661,35 +1590,36 @@ async function isExecutableInPath(command) {
1661
1590
  }
1662
1591
  const parts = pathValue.split(":").filter(Boolean);
1663
1592
  for (const part of parts) {
1664
- const candidate = resolve(part, command);
1593
+ const candidate = resolve5(part, command);
1665
1594
  try {
1666
1595
  await access(candidate);
1667
1596
  return true;
1668
- } catch {
1669
- }
1597
+ } catch {}
1670
1598
  }
1671
1599
  return false;
1672
1600
  }
1673
1601
  async function isEmptyDirectory(path) {
1674
1602
  try {
1675
- const entries = await readdir(path);
1603
+ const entries = await readdir3(path);
1676
1604
  return entries.length === 0;
1677
1605
  } catch {
1678
1606
  return true;
1679
1607
  }
1680
1608
  }
1681
1609
  function resolveTemplatePath() {
1682
- const here = fileURLToPath(new URL(import.meta.url));
1683
- return resolve(here, "..", "..", "assets", "template");
1610
+ const here = fileURLToPath2(new URL(import.meta.url));
1611
+ return resolve5(here, "..", "..", "assets", "template");
1684
1612
  }
1685
- var PackageCreateCommand = class extends Command {
1613
+ // src/commands/package/create.ts
1614
+ import { Command as Command8, Option as Option5 } from "clipanion";
1615
+ class PackageCreateCommand extends Command8 {
1686
1616
  static paths = [["package", "create"]];
1687
- static usage = Command.Usage({
1617
+ static usage = Command8.Usage({
1688
1618
  category: "Package",
1689
1619
  description: "Creates a new package in the workspace."
1690
1620
  });
1691
- name = Option.String({ required: true });
1692
- type = Option.String("--type,-t", {
1621
+ name = Option5.String({ required: true });
1622
+ type = Option5.String("--type,-t", {
1693
1623
  description: "Package type (source, library, worker)"
1694
1624
  });
1695
1625
  async execute() {
@@ -1700,10 +1630,13 @@ var PackageCreateCommand = class extends Command {
1700
1630
  await updateTsconfigReferences(workspaceRoot, packages);
1701
1631
  logger.info(`created package: @highstate/${this.name} (${packageType})`);
1702
1632
  }
1703
- };
1704
- var PackageListCommand = class extends Command {
1633
+ }
1634
+ // src/commands/package/list.ts
1635
+ import { Command as Command9 } from "clipanion";
1636
+ import { Table as Table2 } from "console-table-printer";
1637
+ class PackageListCommand extends Command9 {
1705
1638
  static paths = [["package", "list"]];
1706
- static usage = Command.Usage({
1639
+ static usage = Command9.Usage({
1707
1640
  category: "Package",
1708
1641
  description: "Lists all packages in the workspace with their types."
1709
1642
  });
@@ -1714,49 +1647,50 @@ var PackageListCommand = class extends Command {
1714
1647
  logger.info("no packages found in workspace");
1715
1648
  return;
1716
1649
  }
1717
- const table = new Table({
1650
+ const table = new Table2({
1718
1651
  columns: [
1719
1652
  { name: "name", title: "Name" },
1720
1653
  { name: "type", title: "Type" },
1721
1654
  { name: "path", title: "Path" }
1722
1655
  ]
1723
1656
  });
1724
- table.addRows(
1725
- packages.map((pkg) => ({
1726
- name: pkg.name,
1727
- type: pkg.type ?? "unknown",
1728
- path: pkg.relativePath
1729
- }))
1730
- );
1657
+ table.addRows(packages.map((pkg) => ({
1658
+ name: pkg.name,
1659
+ type: pkg.type ?? "unknown",
1660
+ path: pkg.relativePath
1661
+ })));
1731
1662
  table.printTable();
1732
1663
  }
1733
- };
1734
- var PackageRemoveCommand = class extends Command {
1664
+ }
1665
+ // src/commands/package/remove.ts
1666
+ import { rm as rm2 } from "fs/promises";
1667
+ import { Command as Command10, Option as Option6 } from "clipanion";
1668
+ class PackageRemoveCommand extends Command10 {
1735
1669
  static paths = [["package", "remove"]];
1736
- static usage = Command.Usage({
1670
+ static usage = Command10.Usage({
1737
1671
  category: "Package",
1738
1672
  description: "Removes a package from the workspace."
1739
1673
  });
1740
- name = Option.String({ required: true });
1674
+ name = Option6.String({ required: true });
1741
1675
  async execute() {
1742
1676
  const workspaceRoot = await findWorkspaceRoot();
1743
1677
  const packages = await scanWorkspacePackages(workspaceRoot);
1744
- const targetPackage = packages.find(
1745
- (pkg) => pkg.name === this.name || pkg.name === `@highstate/${this.name}` || pkg.relativePath.endsWith(this.name)
1746
- );
1678
+ const targetPackage = packages.find((pkg) => pkg.name === this.name || pkg.name === `@highstate/${this.name}` || pkg.relativePath.endsWith(this.name));
1747
1679
  if (!targetPackage) {
1748
1680
  logger.error(`package not found: ${this.name}`);
1749
1681
  process.exit(1);
1750
1682
  }
1751
- await rm(targetPackage.path, { recursive: true, force: true });
1683
+ await rm2(targetPackage.path, { recursive: true, force: true });
1752
1684
  const remainingPackages = await scanWorkspacePackages(workspaceRoot);
1753
1685
  await updateTsconfigReferences(workspaceRoot, remainingPackages);
1754
1686
  logger.info(`removed package: ${targetPackage.name}`);
1755
1687
  }
1756
- };
1757
- var PackageUpdateReferencesCommand = class extends Command {
1688
+ }
1689
+ // src/commands/package/update-references.ts
1690
+ import { Command as Command11 } from "clipanion";
1691
+ class PackageUpdateReferencesCommand extends Command11 {
1758
1692
  static paths = [["package", "update-references"]];
1759
- static usage = Command.Usage({
1693
+ static usage = Command11.Usage({
1760
1694
  category: "Package",
1761
1695
  description: "Updates the root tsconfig.json with references to all packages in the workspace."
1762
1696
  });
@@ -1765,121 +1699,137 @@ var PackageUpdateReferencesCommand = class extends Command {
1765
1699
  const packages = await scanWorkspacePackages(workspaceRoot);
1766
1700
  await updateTsconfigReferences(workspaceRoot, packages, true);
1767
1701
  }
1768
- };
1769
- var UpdateCommand = class extends Command {
1702
+ }
1703
+ // src/commands/update.ts
1704
+ import { readFile as readFile8 } from "fs/promises";
1705
+ import { Command as Command12, Option as Option7 } from "clipanion";
1706
+ import { readPackageJSON as readPackageJSON5, resolvePackageJSON as resolvePackageJSON6 } from "pkg-types";
1707
+ import semver from "semver";
1708
+ class UpdateCommand extends Command12 {
1770
1709
  static paths = [["update"]];
1771
- static usage = Command.Usage({
1710
+ static usage = Command12.Usage({
1772
1711
  description: "Updates version overrides in an existing Highstate project."
1773
1712
  });
1774
- platformVersion = Option.String("--platform-version", {
1713
+ platformVersion = Option7.String("--platform-version", {
1775
1714
  description: "The Highstate platform version to set."
1776
1715
  });
1777
- stdlibVersion = Option.String("--stdlib-version", {
1716
+ stdlibVersion = Option7.String("--stdlib-version", {
1778
1717
  description: "The Highstate standard library version to set."
1779
1718
  });
1780
- platformOnly = Option.Boolean("--platform", false, {
1719
+ platformOnly = Option7.Boolean("--platform", false, {
1781
1720
  description: "Update only platform versions."
1782
1721
  });
1783
- stdlibOnly = Option.Boolean("--stdlib", false, {
1722
+ stdlibOnly = Option7.Boolean("--stdlib", false, {
1784
1723
  description: "Update only standard library versions."
1785
1724
  });
1786
- install = Option.Boolean("--install", true, {
1725
+ install = Option7.Boolean("--install", true, {
1787
1726
  description: "Install dependencies after updating overrides."
1788
1727
  });
1789
1728
  async execute() {
1790
1729
  const projectRoot = process.cwd();
1791
- const packageManager = await resolveProjectPackageManager(projectRoot);
1730
+ await assertPackageJsonExists(projectRoot);
1792
1731
  if (this.platformOnly && this.stdlibOnly) {
1793
1732
  throw new Error('Flags "--platform" and "--stdlib" cannot be used together');
1794
1733
  }
1795
1734
  const updatePlatform = this.platformOnly || !this.stdlibOnly;
1796
1735
  const updateStdlib = this.stdlibOnly || !this.platformOnly;
1736
+ let currentPlatformVersion;
1737
+ let resolvedStdlibVersion = this.stdlibVersion;
1797
1738
  if (this.stdlibOnly) {
1798
- const currentPlatformVersion = await getProjectPlatformVersion(projectRoot, {
1799
- packageManager
1800
- });
1801
- if (!currentPlatformVersion) {
1739
+ const projectPlatformVersion = await getProjectPlatformVersion(projectRoot);
1740
+ if (!projectPlatformVersion) {
1802
1741
  throw new Error('Current platform version is not set in overrides for "@highstate/pulumi"');
1803
1742
  }
1804
- const targetStdlibVersion = (this.stdlibVersion ?? "").trim();
1805
- if (targetStdlibVersion.length === 0) {
1806
- throw new Error('Flag "--stdlib-version" must be provided when using "--stdlib"');
1807
- }
1808
- const stdlibManifest = await fetchManifest("@highstate/library", targetStdlibVersion);
1809
- const supportedPlatformRange = getDependencyRange(stdlibManifest, "@highstate/pulumi");
1810
- if (!supportedPlatformRange) {
1811
- throw new Error(
1812
- `Unable to infer "@highstate/pulumi" version from "@highstate/library@${targetStdlibVersion}"`
1813
- );
1814
- }
1815
- const validPlatform = semver.valid(currentPlatformVersion);
1816
- if (!validPlatform) {
1817
- throw new Error(
1818
- `Current platform version is not a valid semver "${currentPlatformVersion}"`
1819
- );
1820
- }
1821
- const ok = semver.satisfies(validPlatform, supportedPlatformRange, {
1822
- includePrerelease: true
1743
+ currentPlatformVersion = projectPlatformVersion;
1744
+ resolvedStdlibVersion = await resolveCompatibleStdlibVersion({
1745
+ currentPlatformVersion: projectPlatformVersion,
1746
+ stdlibVersion: this.stdlibVersion
1823
1747
  });
1824
- if (!ok) {
1825
- throw new Error(
1826
- `Current platform version "${currentPlatformVersion}" does not satisfy requirement "${supportedPlatformRange}"`
1827
- );
1828
- }
1829
1748
  }
1830
1749
  const bundle = await resolveVersionBundle({
1831
- platformVersion: updatePlatform ? this.platformVersion : void 0,
1832
- stdlibVersion: updateStdlib ? this.stdlibVersion : void 0
1750
+ platformVersion: updatePlatform ? this.platformVersion : currentPlatformVersion,
1751
+ stdlibVersion: updateStdlib ? resolvedStdlibVersion : undefined
1833
1752
  });
1834
- const overrides = buildOverrides(bundle);
1753
+ const overrides2 = buildOverrides(bundle);
1835
1754
  await applyOverrides({
1836
1755
  projectRoot,
1837
- packageManager,
1838
- overrides
1756
+ overrides: overrides2
1757
+ });
1758
+ await syncRootPulumiDependency({
1759
+ projectRoot,
1760
+ pulumiVersion: bundle.pulumiVersion
1839
1761
  });
1840
- logger.info(
1841
- "updated overrides: platform=%s stdlib=%s pulumi=%s",
1842
- bundle.platformVersion,
1843
- bundle.stdlibVersion,
1844
- bundle.pulumiVersion
1845
- );
1762
+ logger.info("updated overrides: platform=%s stdlib=%s pulumi=%s", bundle.platformVersion, bundle.stdlibVersion, bundle.pulumiVersion);
1846
1763
  if (this.install) {
1847
- const { installDependencies: installDependencies2 } = await import('nypm');
1848
- logger.info("installing dependencies using %s...", packageManager);
1764
+ const { installDependencies: installDependencies2 } = await import("nypm");
1765
+ logger.info("installing dependencies using bun...");
1849
1766
  await installDependencies2({
1850
1767
  cwd: projectRoot,
1851
- packageManager,
1768
+ packageManager: "bun",
1852
1769
  silent: false
1853
1770
  });
1854
1771
  }
1855
1772
  logger.info("update completed successfully");
1856
1773
  }
1857
- };
1858
- async function resolveProjectPackageManager(projectRoot) {
1859
- const detected = await detectPackageManager(projectRoot);
1860
- if (!detected?.name) {
1861
- throw new Error("Unable to detect package manager for this project");
1862
- }
1863
- if (detected.name === "bun") {
1864
- throw new Error('Package manager "bun" is not supported');
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;
1865
1787
  }
1866
- if (detected.name === "deno") {
1867
- throw new Error('Package manager "deno" is not supported');
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
+ }
1868
1801
  }
1869
- if (detected.name !== "npm" && detected.name !== "pnpm" && detected.name !== "yarn") {
1870
- throw new Error(`Unsupported package manager: "${detected.name}"`);
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}"`);
1871
1815
  }
1872
- await assertPackageJsonExists(projectRoot);
1873
- return detected.name;
1874
1816
  }
1875
1817
  async function assertPackageJsonExists(projectRoot) {
1876
1818
  try {
1877
- await readFile(`${projectRoot}/package.json`, "utf8");
1819
+ await readFile8(`${projectRoot}/package.json`, "utf8");
1878
1820
  } catch {
1879
1821
  throw new Error(`File "package.json" not found in "${projectRoot}"`);
1880
1822
  }
1881
1823
  }
1882
-
1824
+ async function syncRootPulumiDependency(args) {
1825
+ const packageJsonPath = await resolvePackageJSON6(args.projectRoot);
1826
+ const packageJson = await readPackageJSON5(packageJsonPath);
1827
+ await writeJsonFile(packageJsonPath, {
1828
+ ...packageJson,
1829
+ dependencies: {
1830
+ ...packageJson.dependencies ?? {},
1831
+ "@pulumi/pulumi": args.pulumiVersion
1832
+ }
1833
+ });
1834
+ }
1883
1835
  export { BackendIdentityCommand, BackendUnlockMethodAddCommand, BackendUnlockMethodDeleteCommand, BackendUnlockMethodListCommand, BuildCommand, DesignerCommand, InitCommand, PackageCreateCommand, PackageListCommand, PackageRemoveCommand, PackageUpdateReferencesCommand, UpdateCommand };
1884
- //# sourceMappingURL=chunk-KA6ZC6BV.js.map
1885
- //# sourceMappingURL=chunk-KA6ZC6BV.js.map