@flowscripter/dynamic-cli-framework 2.4.0 → 3.0.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.
Files changed (143) hide show
  1. package/dist/index.d.ts +6 -2
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +4 -1
  4. package/dist/src/cli/BaseCLI.d.ts +1 -0
  5. package/dist/src/cli/BaseCLI.d.ts.map +1 -1
  6. package/dist/src/cli/BaseCLI.js +6 -0
  7. package/dist/src/cli/BaseCLIFeatureOptions.d.ts +1 -0
  8. package/dist/src/cli/BaseCLIFeatureOptions.d.ts.map +1 -1
  9. package/dist/src/command/MultiCommandCliHelpCommand.d.ts +4 -4
  10. package/dist/src/command/MultiCommandCliHelpCommand.d.ts.map +1 -1
  11. package/dist/src/command/MultiCommandCliHelpCommand.js +3 -3
  12. package/dist/src/runtime/command/CommandValidator.d.ts.map +1 -1
  13. package/dist/src/runtime/command/CommandValidator.js +14 -16
  14. package/dist/src/runtime/parser.d.ts +5 -5
  15. package/dist/src/runtime/parser.d.ts.map +1 -1
  16. package/dist/src/runtime/parser.js +2 -2
  17. package/dist/src/runtime/runner.d.ts.map +1 -1
  18. package/dist/src/runtime/values/ValuePopulationResult.d.ts +3 -3
  19. package/dist/src/runtime/values/ValuePopulationResult.d.ts.map +1 -1
  20. package/dist/src/runtime/values/argumentValueMerge.d.ts +2 -2
  21. package/dist/src/runtime/values/argumentValueMerge.d.ts.map +1 -1
  22. package/dist/src/runtime/values/argumentValueValidation.d.ts +4 -4
  23. package/dist/src/runtime/values/argumentValueValidation.d.ts.map +1 -1
  24. package/dist/src/runtime/values/argumentValueValidation.js +6 -6
  25. package/dist/src/runtime/values/globalCommandValuePopulation.d.ts +4 -4
  26. package/dist/src/runtime/values/globalCommandValuePopulation.d.ts.map +1 -1
  27. package/dist/src/runtime/values/globalCommandValuePopulation.js +5 -5
  28. package/dist/src/runtime/values/subCommandValuePopulation.d.ts +5 -5
  29. package/dist/src/runtime/values/subCommandValuePopulation.d.ts.map +1 -1
  30. package/dist/src/runtime/values/subCommandValuePopulation.js +8 -7
  31. package/dist/src/service/argumentPrompter/DefaultArgumentPrompterService.d.ts.map +1 -1
  32. package/dist/src/service/argumentPrompter/DefaultArgumentPrompterService.js +6 -6
  33. package/dist/src/service/banner/command/NoBannerCommand.d.ts +2 -2
  34. package/dist/src/service/banner/command/NoBannerCommand.d.ts.map +1 -1
  35. package/dist/src/service/banner/command/NoBannerCommand.js +2 -2
  36. package/dist/src/service/completion/command/CompletionCompleteSubCommand.d.ts +2 -2
  37. package/dist/src/service/completion/command/CompletionCompleteSubCommand.d.ts.map +1 -1
  38. package/dist/src/service/completion/command/CompletionCompleteSubCommand.js +3 -3
  39. package/dist/src/service/completion/command/CompletionIntegrationSubCommand.d.ts +2 -2
  40. package/dist/src/service/completion/command/CompletionIntegrationSubCommand.d.ts.map +1 -1
  41. package/dist/src/service/completion/command/CompletionIntegrationSubCommand.js +3 -3
  42. package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts +6 -6
  43. package/dist/src/service/configuration/ConfigurationServiceProvider.d.ts.map +1 -1
  44. package/dist/src/service/configuration/ConfigurationServiceProvider.js +4 -4
  45. package/dist/src/service/configuration/command/ConfigCommand.d.ts +2 -2
  46. package/dist/src/service/configuration/command/ConfigCommand.d.ts.map +1 -1
  47. package/dist/src/service/configuration/command/ConfigCommand.js +2 -2
  48. package/dist/src/service/fetch/DefaultFetchService.d.ts +7 -0
  49. package/dist/src/service/fetch/DefaultFetchService.d.ts.map +1 -0
  50. package/dist/src/service/fetch/DefaultFetchService.js +44 -0
  51. package/dist/src/service/fetch/FetchServiceProvider.d.ts +10 -0
  52. package/dist/src/service/fetch/FetchServiceProvider.d.ts.map +1 -0
  53. package/dist/src/service/fetch/FetchServiceProvider.js +22 -0
  54. package/dist/src/service/plugin/DefaultPluginServiceProvider.d.ts +2 -1
  55. package/dist/src/service/plugin/DefaultPluginServiceProvider.d.ts.map +1 -1
  56. package/dist/src/service/plugin/DefaultPluginServiceProvider.js +23 -8
  57. package/dist/src/service/plugin/FetchInterfaceAdapter.d.ts +17 -0
  58. package/dist/src/service/plugin/FetchInterfaceAdapter.d.ts.map +1 -0
  59. package/dist/src/service/plugin/FetchInterfaceAdapter.js +16 -0
  60. package/dist/src/service/plugin/SpawnInterfaceAdapter.js +1 -1
  61. package/dist/src/service/plugin/command/PluginAddSubCommand.d.ts +4 -4
  62. package/dist/src/service/plugin/command/PluginAddSubCommand.d.ts.map +1 -1
  63. package/dist/src/service/plugin/command/PluginAddSubCommand.js +2 -2
  64. package/dist/src/service/plugin/command/PluginListSubCommand.d.ts +2 -2
  65. package/dist/src/service/plugin/command/PluginListSubCommand.d.ts.map +1 -1
  66. package/dist/src/service/plugin/command/PluginRemoveSubCommand.d.ts +4 -4
  67. package/dist/src/service/plugin/command/PluginRemoveSubCommand.d.ts.map +1 -1
  68. package/dist/src/service/plugin/command/PluginRemoveSubCommand.js +2 -2
  69. package/dist/src/service/plugin/command/PluginSearchSubCommand.d.ts +4 -4
  70. package/dist/src/service/plugin/command/PluginSearchSubCommand.d.ts.map +1 -1
  71. package/dist/src/service/plugin/command/PluginSearchSubCommand.js +2 -2
  72. package/dist/src/service/plugin/command/PluginUpgradeSubCommand.d.ts +2 -2
  73. package/dist/src/service/plugin/command/PluginUpgradeSubCommand.d.ts.map +1 -1
  74. package/dist/src/service/printer/command/DarkModeCommand.d.ts +2 -2
  75. package/dist/src/service/printer/command/DarkModeCommand.d.ts.map +1 -1
  76. package/dist/src/service/printer/command/DarkModeCommand.js +2 -2
  77. package/dist/src/service/printer/command/LogLevelCommand.d.ts +2 -2
  78. package/dist/src/service/printer/command/LogLevelCommand.d.ts.map +1 -1
  79. package/dist/src/service/printer/command/LogLevelCommand.js +2 -2
  80. package/dist/src/service/printer/command/NoColorCommand.d.ts +2 -2
  81. package/dist/src/service/printer/command/NoColorCommand.d.ts.map +1 -1
  82. package/dist/src/service/printer/command/NoColorCommand.js +2 -2
  83. package/dist/src/service/printer/command/NoHyperlinksCommand.d.ts +2 -2
  84. package/dist/src/service/printer/command/NoHyperlinksCommand.d.ts.map +1 -1
  85. package/dist/src/service/printer/command/NoHyperlinksCommand.js +2 -2
  86. package/dist/src/service/prompter/command/NoPromptCommand.d.ts +2 -2
  87. package/dist/src/service/prompter/command/NoPromptCommand.d.ts.map +1 -1
  88. package/dist/src/service/prompter/command/NoPromptCommand.js +2 -2
  89. package/dist/src/service/spawn/DefaultSpawnService.js +6 -6
  90. package/dist/src/service/upgrade/DefaultUpgradeService.d.ts +2 -2
  91. package/dist/src/service/upgrade/DefaultUpgradeService.d.ts.map +1 -1
  92. package/dist/src/service/upgrade/DefaultUpgradeService.js +33 -51
  93. package/dist/src/service/upgrade/UpgradeServiceProvider.d.ts.map +1 -1
  94. package/dist/src/service/upgrade/UpgradeServiceProvider.js +12 -9
  95. package/dist/src/service/upgrade/command/UpgradeSubCommand.d.ts +2 -2
  96. package/dist/src/service/upgrade/command/UpgradeSubCommand.d.ts.map +1 -1
  97. package/dist/src/service/upgrade/command/UpgradeSubCommand.js +3 -3
  98. package/dist/src/util/envVarHelper.d.ts +3 -3
  99. package/dist/src/util/envVarHelper.d.ts.map +1 -1
  100. package/dist/src/util/envVarHelper.js +9 -12
  101. package/dist/src/util/helpHelper.d.ts.map +1 -1
  102. package/dist/src/util/helpHelper.js +27 -28
  103. package/index.ts +12 -10
  104. package/package.json +3 -3
  105. package/src/cli/BaseCLI.ts +7 -0
  106. package/src/cli/BaseCLIFeatureOptions.ts +1 -0
  107. package/src/command/MultiCommandCliHelpCommand.ts +7 -7
  108. package/src/runtime/command/CommandValidator.ts +17 -26
  109. package/src/runtime/parser.ts +8 -8
  110. package/src/runtime/runner.ts +16 -19
  111. package/src/runtime/values/ValuePopulationResult.ts +4 -4
  112. package/src/runtime/values/argumentValueMerge.ts +33 -50
  113. package/src/runtime/values/argumentValueValidation.ts +38 -52
  114. package/src/runtime/values/globalCommandValuePopulation.ts +7 -7
  115. package/src/runtime/values/subCommandValuePopulation.ts +42 -47
  116. package/src/service/argumentPrompter/DefaultArgumentPrompterService.ts +23 -26
  117. package/src/service/banner/command/NoBannerCommand.ts +3 -6
  118. package/src/service/completion/command/CompletionCompleteSubCommand.ts +4 -7
  119. package/src/service/completion/command/CompletionIntegrationSubCommand.ts +4 -7
  120. package/src/service/configuration/ConfigurationServiceProvider.ts +21 -21
  121. package/src/service/configuration/command/ConfigCommand.ts +3 -6
  122. package/src/service/fetch/DefaultFetchService.ts +55 -0
  123. package/src/service/fetch/FetchServiceProvider.ts +33 -0
  124. package/src/service/plugin/DefaultPluginServiceProvider.ts +29 -12
  125. package/src/service/plugin/FetchInterfaceAdapter.ts +28 -0
  126. package/src/service/plugin/SpawnInterfaceAdapter.ts +1 -1
  127. package/src/service/plugin/command/PluginAddSubCommand.ts +4 -4
  128. package/src/service/plugin/command/PluginListSubCommand.ts +2 -2
  129. package/src/service/plugin/command/PluginRemoveSubCommand.ts +4 -4
  130. package/src/service/plugin/command/PluginSearchSubCommand.ts +4 -4
  131. package/src/service/plugin/command/PluginUpgradeSubCommand.ts +2 -2
  132. package/src/service/printer/command/DarkModeCommand.ts +3 -6
  133. package/src/service/printer/command/LogLevelCommand.ts +3 -6
  134. package/src/service/printer/command/NoColorCommand.ts +3 -6
  135. package/src/service/printer/command/NoHyperlinksCommand.ts +3 -6
  136. package/src/service/prompter/command/NoPromptCommand.ts +3 -6
  137. package/src/service/prompter/prompt/promptText.ts +2 -2
  138. package/src/service/spawn/DefaultSpawnService.ts +6 -6
  139. package/src/service/upgrade/DefaultUpgradeService.ts +66 -65
  140. package/src/service/upgrade/UpgradeServiceProvider.ts +13 -9
  141. package/src/service/upgrade/command/UpgradeSubCommand.ts +4 -7
  142. package/src/util/envVarHelper.ts +23 -26
  143. package/src/util/helpHelper.ts +28 -36
@@ -4,7 +4,7 @@ import { tmpdir } from "node:os";
4
4
  import { join } from "node:path";
5
5
  import type {
6
6
  CLIConfig,
7
- ShutdownService,
7
+ FetchService,
8
8
  SpawnResult,
9
9
  SpawnService,
10
10
  UpgradeCheckResult,
@@ -40,7 +40,7 @@ const OS_LABELS: Record<SupportedOs, string> = {
40
40
 
41
41
  export default class DefaultUpgradeService implements UpgradeService {
42
42
  #spawnService: SpawnService | undefined;
43
- #shutdownService: ShutdownService | undefined;
43
+ #fetchService: FetchService | undefined;
44
44
  #upgradeCheckPromise: Promise<UpgradeCheckResult | undefined> | undefined;
45
45
  readonly #config: UpgradeLocationsConfig;
46
46
  readonly #cliConfig: CLIConfig;
@@ -50,9 +50,12 @@ export default class DefaultUpgradeService implements UpgradeService {
50
50
  this.#cliConfig = cliConfig;
51
51
  }
52
52
 
53
- public setDependencies(spawnService: SpawnService, shutdownService?: ShutdownService): void {
53
+ public setDependencies(
54
+ spawnService: SpawnService | undefined,
55
+ fetchService: FetchService | undefined,
56
+ ): void {
54
57
  this.#spawnService = spawnService;
55
- this.#shutdownService = shutdownService;
58
+ this.#fetchService = fetchService;
56
59
  }
57
60
 
58
61
  public getUpgradeCheckResult(waitForResult = false): Promise<UpgradeCheckResult | undefined> {
@@ -170,6 +173,9 @@ export default class DefaultUpgradeService implements UpgradeService {
170
173
  if (!this.#spawnService) {
171
174
  return { ok: false, oldVersion, error: new Error("SpawnService is not available") };
172
175
  }
176
+ if (checkResult.installMethod === InstallMethod.GITHUB_RELEASE && !this.#fetchService) {
177
+ return { ok: false, oldVersion, error: new Error("FetchService is not available") };
178
+ }
173
179
 
174
180
  try {
175
181
  switch (checkResult.installMethod) {
@@ -204,7 +210,7 @@ export default class DefaultUpgradeService implements UpgradeService {
204
210
  }
205
211
  const result = await this.#spawnService.spawn(
206
212
  ["brew", "list", "--versions", this.#config.homebrew.formula],
207
- { stdio: "wrapped", longRunning: false, timeoutMs: VERSION_CHECK_TIMEOUT_MS },
213
+ { mode: "ignore", longRunning: false, timeoutMs: VERSION_CHECK_TIMEOUT_MS },
208
214
  );
209
215
  return result.ok;
210
216
  }
@@ -215,7 +221,7 @@ export default class DefaultUpgradeService implements UpgradeService {
215
221
  }
216
222
  const result = await this.#spawnService.spawn(
217
223
  ["winget", "list", "--id", this.#config.winget.packageId],
218
- { stdio: "wrapped", longRunning: false, timeoutMs: VERSION_CHECK_TIMEOUT_MS },
224
+ { mode: "ignore", longRunning: false, timeoutMs: VERSION_CHECK_TIMEOUT_MS },
219
225
  );
220
226
  return result.ok;
221
227
  }
@@ -239,14 +245,14 @@ export default class DefaultUpgradeService implements UpgradeService {
239
245
  }
240
246
 
241
247
  async #getLatestGithubReleaseVersion(): Promise<string | undefined> {
242
- if (!this.#config.githubRelease) {
248
+ if (!this.#config.githubRelease || !this.#fetchService) {
243
249
  return undefined;
244
250
  }
245
251
  const { owner, repo } = this.#config.githubRelease;
246
252
  try {
247
- const response = await fetch(
253
+ const response = await this.#fetchService.fetch(
248
254
  `https://api.github.com/repos/${owner}/${repo}/releases/latest`,
249
- { signal: AbortSignal.timeout(VERSION_CHECK_TIMEOUT_MS) },
255
+ { timeoutMs: VERSION_CHECK_TIMEOUT_MS },
250
256
  );
251
257
  if (!response.ok) {
252
258
  return undefined;
@@ -260,7 +266,7 @@ export default class DefaultUpgradeService implements UpgradeService {
260
266
  }
261
267
 
262
268
  async #getLatestHomebrewVersion(): Promise<string | undefined> {
263
- if (!this.#config.homebrew) {
269
+ if (!this.#config.homebrew || !this.#fetchService) {
264
270
  return undefined;
265
271
  }
266
272
  const { tap, formula } = this.#config.homebrew;
@@ -269,9 +275,9 @@ export default class DefaultUpgradeService implements UpgradeService {
269
275
  return undefined;
270
276
  }
271
277
  try {
272
- const response = await fetch(
278
+ const response = await this.#fetchService.fetch(
273
279
  `https://raw.githubusercontent.com/${tapOwner}/homebrew-${tapName}/main/${formula}.rb`,
274
- { signal: AbortSignal.timeout(VERSION_CHECK_TIMEOUT_MS) },
280
+ { timeoutMs: VERSION_CHECK_TIMEOUT_MS },
275
281
  );
276
282
  if (!response.ok) {
277
283
  return undefined;
@@ -292,7 +298,7 @@ export default class DefaultUpgradeService implements UpgradeService {
292
298
  const result = await this.#spawnService.spawn(
293
299
  ["winget", "show", "--id", this.#config.winget.packageId],
294
300
  {
295
- stdio: "wrapped",
301
+ mode: "wrapped",
296
302
  longRunning: false,
297
303
  timeoutMs: VERSION_CHECK_TIMEOUT_MS,
298
304
  onOutput: (line) => lines.push(line),
@@ -312,7 +318,9 @@ export default class DefaultUpgradeService implements UpgradeService {
312
318
 
313
319
  async #upgradeViaLinuxScript(): Promise<void> {
314
320
  const { scriptUrl } = this.#config.linuxScript!;
315
- const result = await this.#spawnService!.spawn(["sh", "-c", `curl -fsSL ${scriptUrl} | sh`]);
321
+ const result = await this.#spawnService!.spawn(["sh", "-c", `curl -fsSL ${scriptUrl} | sh`], {
322
+ mode: "ignore",
323
+ });
316
324
  if (!result.ok) {
317
325
  throw new Error(`Install script failed: ${describeSpawnFailure(result)}`);
318
326
  }
@@ -320,7 +328,9 @@ export default class DefaultUpgradeService implements UpgradeService {
320
328
 
321
329
  async #upgradeViaHomebrew(): Promise<void> {
322
330
  const { tap, formula } = this.#config.homebrew!;
323
- const result = await this.#spawnService!.spawn(["brew", "upgrade", `${tap}/${formula}`]);
331
+ const result = await this.#spawnService!.spawn(["brew", "upgrade", `${tap}/${formula}`], {
332
+ mode: "ignore",
333
+ });
324
334
  if (!result.ok) {
325
335
  throw new Error(`brew upgrade failed: ${describeSpawnFailure(result)}`);
326
336
  }
@@ -328,15 +338,18 @@ export default class DefaultUpgradeService implements UpgradeService {
328
338
 
329
339
  async #upgradeViaWinget(): Promise<void> {
330
340
  const { packageId } = this.#config.winget!;
331
- const result = await this.#spawnService!.spawn([
332
- "winget",
333
- "upgrade",
334
- "--id",
335
- packageId,
336
- "--silent",
337
- "--accept-package-agreements",
338
- "--accept-source-agreements",
339
- ]);
341
+ const result = await this.#spawnService!.spawn(
342
+ [
343
+ "winget",
344
+ "upgrade",
345
+ "--id",
346
+ packageId,
347
+ "--silent",
348
+ "--accept-package-agreements",
349
+ "--accept-source-agreements",
350
+ ],
351
+ { mode: "ignore" },
352
+ );
340
353
  if (!result.ok) {
341
354
  throw new Error(`winget upgrade failed: ${describeSpawnFailure(result)}`);
342
355
  }
@@ -349,19 +362,13 @@ export default class DefaultUpgradeService implements UpgradeService {
349
362
  const assetName = assetPattern.replace("{os}", OS_LABELS[os]).replace("{arch}", archLabel);
350
363
  const url = `https://github.com/${owner}/${repo}/releases/latest/download/${assetName}`;
351
364
 
352
- // Downloading the release asset but enter long-running mode to get cooperative
353
- // Ctrl-C handling during what can be the slowest step of the upgrade.
354
- this.#shutdownService?.enterLongRunningMode();
355
- let archiveData: ArrayBuffer;
356
- try {
357
- const response = await fetch(url);
358
- if (!response.ok) {
359
- throw new Error(`Failed to download release asset '${assetName}': HTTP ${response.status}`);
360
- }
361
- archiveData = await response.arrayBuffer();
362
- } finally {
363
- this.#shutdownService?.leaveLongRunningMode();
365
+ // longRunning: true gets cooperative Ctrl-C handling during what can be the slowest step of
366
+ // the upgrade.
367
+ const response = await this.#fetchService!.fetch(url, { longRunning: true });
368
+ if (!response.ok) {
369
+ throw new Error(`Failed to download release asset '${assetName}': HTTP ${response.status}`);
364
370
  }
371
+ const archiveData = await response.arrayBuffer();
365
372
 
366
373
  const tmpDir = await mkdtemp(join(tmpdir(), "upgrade-"));
367
374
  const archivePath = join(tmpDir, assetName);
@@ -370,52 +377,46 @@ export default class DefaultUpgradeService implements UpgradeService {
370
377
  const currentExecutable = process.execPath;
371
378
 
372
379
  if (os === SupportedOs.WINDOWS) {
373
- const extractResult = await this.#spawnService!.spawn([
374
- "powershell",
375
- "-Command",
376
- `Expand-Archive -Path '${archivePath}' -DestinationPath '${tmpDir}' -Force`,
377
- ]);
380
+ const extractResult = await this.#spawnService!.spawn(
381
+ [
382
+ "powershell",
383
+ "-Command",
384
+ `Expand-Archive -Path '${archivePath}' -DestinationPath '${tmpDir}' -Force`,
385
+ ],
386
+ { mode: "ignore" },
387
+ );
378
388
  if (!extractResult.ok) {
379
389
  throw new Error("Failed to extract release archive");
380
390
  }
381
391
  const extractedBinary = join(tmpDir, `${this.#cliConfig.name}.exe`);
382
392
  const oldPath = `${currentExecutable}.old.exe`;
383
- const moveResult = await this.#spawnService!.spawn([
384
- "cmd",
385
- "/c",
386
- "move",
387
- "/y",
388
- currentExecutable,
389
- oldPath,
390
- ]);
393
+ const moveResult = await this.#spawnService!.spawn(
394
+ ["cmd", "/c", "move", "/y", currentExecutable, oldPath],
395
+ { mode: "ignore" },
396
+ );
391
397
  if (!moveResult.ok) {
392
398
  throw new Error("Failed to move current executable aside");
393
399
  }
394
- const copyResult = await this.#spawnService!.spawn([
395
- "cmd",
396
- "/c",
397
- "copy",
398
- "/y",
399
- extractedBinary,
400
- currentExecutable,
401
- ]);
400
+ const copyResult = await this.#spawnService!.spawn(
401
+ ["cmd", "/c", "copy", "/y", extractedBinary, currentExecutable],
402
+ { mode: "ignore" },
403
+ );
402
404
  if (!copyResult.ok) {
403
405
  throw new Error("Failed to copy new executable into place");
404
406
  }
405
407
  } else {
406
- const extractResult = await this.#spawnService!.spawn([
407
- "unzip",
408
- "-o",
409
- archivePath,
410
- "-d",
411
- tmpDir,
412
- ]);
408
+ const extractResult = await this.#spawnService!.spawn(
409
+ ["unzip", "-o", archivePath, "-d", tmpDir],
410
+ {
411
+ mode: "ignore",
412
+ },
413
+ );
413
414
  if (!extractResult.ok) {
414
415
  throw new Error("Failed to extract release archive");
415
416
  }
416
417
  const extractedBinary = join(tmpDir, this.#cliConfig.name);
417
418
  await Bun.write(currentExecutable, Bun.file(extractedBinary));
418
- await this.#spawnService!.spawn(["chmod", "+x", currentExecutable]);
419
+ await this.#spawnService!.spawn(["chmod", "+x", currentExecutable], { mode: "ignore" });
419
420
  }
420
421
  }
421
422
  }
@@ -8,8 +8,8 @@ import { KEY_VALUE_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
8
8
  import type { KeyValueService } from "@flowscripter/dynamic-cli-framework-api";
9
9
  import { SPAWN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
10
10
  import type { SpawnService } from "@flowscripter/dynamic-cli-framework-api";
11
- import { SHUTDOWN_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
12
- import type { ShutdownService } from "@flowscripter/dynamic-cli-framework-api";
11
+ import { FETCH_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
12
+ import type { FetchService } from "@flowscripter/dynamic-cli-framework-api";
13
13
  import { Icon, PRINTER_SERVICE_ID } from "@flowscripter/dynamic-cli-framework-api";
14
14
  import type { PrinterService } from "@flowscripter/dynamic-cli-framework-api";
15
15
  import DefaultUpgradeService from "./DefaultUpgradeService.ts";
@@ -44,15 +44,19 @@ export default class UpgradeServiceProvider implements ServiceProvider {
44
44
  const upgradeService = this.#upgradeService!;
45
45
  const cliConfig = this.#cliConfig!;
46
46
 
47
- if (context.doesServiceExist(SPAWN_SERVICE_ID)) {
48
- const spawnService = context.getServiceById(SPAWN_SERVICE_ID) as SpawnService;
49
- const shutdownService = context.doesServiceExist(SHUTDOWN_SERVICE_ID)
50
- ? (context.getServiceById(SHUTDOWN_SERVICE_ID) as ShutdownService)
51
- : undefined;
52
- upgradeService.setDependencies(spawnService, shutdownService);
53
- } else {
47
+ const spawnService = context.doesServiceExist(SPAWN_SERVICE_ID)
48
+ ? (context.getServiceById(SPAWN_SERVICE_ID) as SpawnService)
49
+ : undefined;
50
+ const fetchService = context.doesServiceExist(FETCH_SERVICE_ID)
51
+ ? (context.getServiceById(FETCH_SERVICE_ID) as FetchService)
52
+ : undefined;
53
+ if (spawnService === undefined) {
54
54
  logger.debug(() => "SpawnService not available, upgrade install methods will be unavailable");
55
55
  }
56
+ if (fetchService === undefined) {
57
+ logger.debug(() => "FetchService not available, upgrade version checks will be unavailable");
58
+ }
59
+ upgradeService.setDependencies(spawnService, fetchService);
56
60
 
57
61
  void upgradeService.getUpgradeCheckResult();
58
62
 
@@ -1,10 +1,7 @@
1
1
  import type { SubCommand } from "@flowscripter/dynamic-cli-framework-api";
2
2
  import type { Option } from "@flowscripter/dynamic-cli-framework-api";
3
3
  import type { Context } from "@flowscripter/dynamic-cli-framework-api";
4
- import {
5
- type ArgumentValues,
6
- ArgumentValueTypeName,
7
- } from "@flowscripter/dynamic-cli-framework-api";
4
+ import { type Values, ValueTypeName } from "@flowscripter/dynamic-cli-framework-api";
8
5
  import {
9
6
  Icon,
10
7
  InstallMethod,
@@ -24,14 +21,14 @@ export class UpgradeSubCommand implements SubCommand {
24
21
  readonly options: ReadonlyArray<Option> = [
25
22
  {
26
23
  name: "os",
27
- type: ArgumentValueTypeName.STRING,
24
+ type: ValueTypeName.STRING,
28
25
  isOptional: true,
29
26
  allowableValues: Object.values(SupportedOs),
30
27
  description: "Override the detected operating system",
31
28
  },
32
29
  {
33
30
  name: "install-method",
34
- type: ArgumentValueTypeName.STRING,
31
+ type: ValueTypeName.STRING,
35
32
  isOptional: true,
36
33
  allowableValues: Object.values(InstallMethod),
37
34
  description: "Override the detected install method",
@@ -44,7 +41,7 @@ export class UpgradeSubCommand implements SubCommand {
44
41
  this.#upgradeService = upgradeService;
45
42
  }
46
43
 
47
- public async execute(context: Context, argumentValues: ArgumentValues): Promise<void> {
44
+ public async execute(context: Context, argumentValues: Values): Promise<void> {
48
45
  const printerService = context.getServiceById(PRINTER_SERVICE_ID) as PrinterService;
49
46
  const cliName = context.cliConfig.name;
50
47
 
@@ -2,10 +2,10 @@ import process from "node:process";
2
2
  import type { Command } from "@flowscripter/dynamic-cli-framework-api";
3
3
  import type { CLIConfig } from "@flowscripter/dynamic-cli-framework-api";
4
4
  import {
5
- ArgumentValueTypeName,
5
+ ValueTypeName,
6
6
  ComplexValueTypeName,
7
- type PopulatedArgumentSingleValueType,
8
- type PopulatedArgumentValues,
7
+ type PopulatedSingleValueType,
8
+ type PopulatedValues,
9
9
  } from "@flowscripter/dynamic-cli-framework-api";
10
10
  type ProcessEnv = NodeJS.ProcessEnv;
11
11
 
@@ -59,7 +59,7 @@ function getGlobalArgumentKeyPrefix(
59
59
  export function getGlobalCommandValueFromEnvVars(
60
60
  cliConfig: CLIConfig,
61
61
  command: GlobalCommand,
62
- ): PopulatedArgumentSingleValueType {
62
+ ): PopulatedSingleValueType {
63
63
  const { argument } = command;
64
64
  if (argument === undefined) {
65
65
  return undefined;
@@ -67,7 +67,7 @@ export function getGlobalCommandValueFromEnvVars(
67
67
 
68
68
  // simple check for a specific env var name
69
69
  let envVarValue = process.env[getGlobalArgumentKeyPrefix(cliConfig, command, argument)];
70
- if (envVarValue != undefined && argument.type === ArgumentValueTypeName.BOOLEAN) {
70
+ if (envVarValue != undefined && argument.type === ValueTypeName.BOOLEAN) {
71
71
  envVarValue = envVarValue.length > 0 ? "true" : "false";
72
72
  }
73
73
 
@@ -75,7 +75,7 @@ export function getGlobalCommandValueFromEnvVars(
75
75
  }
76
76
 
77
77
  function getOptionValuesFromEnvVars(
78
- envVarValues: PopulatedArgumentValues,
78
+ envVarValues: PopulatedValues,
79
79
  potentialEnvVarNames: Array<string>,
80
80
  env: ProcessEnv,
81
81
  option: Option | ComplexOption,
@@ -126,17 +126,16 @@ function getOptionValuesFromEnvVars(
126
126
  if (suffix.length > 0) {
127
127
  if (option.type === ComplexValueTypeName.COMPLEX) {
128
128
  if (
129
- (envVarValues[option.name] as Array<PopulatedArgumentSingleValueType>)[index] ===
130
- undefined
129
+ (envVarValues[option.name] as Array<PopulatedSingleValueType>)[index] === undefined
131
130
  ) {
132
- (envVarValues[option.name] as Array<PopulatedArgumentValues>)[index] = Object.create(
131
+ (envVarValues[option.name] as Array<PopulatedValues>)[index] = Object.create(
133
132
  null,
134
- ) as PopulatedArgumentValues;
133
+ ) as PopulatedValues;
135
134
  }
136
135
  (option as ComplexOption).properties.forEach((property) => {
137
136
  const propertySegment = property.configurationKey || getKeySegment(property.name);
138
137
  getOptionValuesFromEnvVars(
139
- (envVarValues[option.name] as Array<PopulatedArgumentValues>)[index]!,
138
+ (envVarValues[option.name] as Array<PopulatedValues>)[index]!,
140
139
  matches,
141
140
  env,
142
141
  property,
@@ -145,13 +144,13 @@ function getOptionValuesFromEnvVars(
145
144
  });
146
145
  if (
147
146
  Object.keys(
148
- (envVarValues[option.name] as Array<PopulatedArgumentValues>)[index] as Record<
147
+ (envVarValues[option.name] as Array<PopulatedValues>)[index] as Record<
149
148
  string,
150
149
  string
151
150
  >,
152
151
  ).length === 0
153
152
  ) {
154
- delete (envVarValues[option.name] as Array<PopulatedArgumentValues>)[index];
153
+ delete (envVarValues[option.name] as Array<PopulatedValues>)[index];
155
154
  }
156
155
  } else {
157
156
  throw new Error(`Unidentified suffix ${suffix} in env var: ${match}`);
@@ -161,14 +160,13 @@ function getOptionValuesFromEnvVars(
161
160
  } else {
162
161
  // set primitive value
163
162
  let envVarValue = env[match];
164
- if (envVarValue != undefined && option.type === ArgumentValueTypeName.BOOLEAN) {
163
+ if (envVarValue != undefined && option.type === ValueTypeName.BOOLEAN) {
165
164
  envVarValue = envVarValue.length > 1 ? "true" : "false";
166
165
  }
167
- (envVarValues[option.name] as Array<PopulatedArgumentSingleValueType>)[index] =
168
- envVarValue;
166
+ (envVarValues[option.name] as Array<PopulatedSingleValueType>)[index] = envVarValue;
169
167
  }
170
168
 
171
- const elements = envVarValues[option.name] as Array<PopulatedArgumentSingleValueType>;
169
+ const elements = envVarValues[option.name] as Array<PopulatedSingleValueType>;
172
170
  for (let i = elements.length - 1; i > -1; i--) {
173
171
  if (elements[i] === undefined) {
174
172
  elements.length = i;
@@ -182,11 +180,11 @@ function getOptionValuesFromEnvVars(
182
180
  } else if (option.type === ComplexValueTypeName.COMPLEX) {
183
181
  (option as ComplexOption).properties.forEach((property) => {
184
182
  if (envVarValues[option.name] === undefined) {
185
- envVarValues[option.name] = Object.create(null) as PopulatedArgumentValues;
183
+ envVarValues[option.name] = Object.create(null) as PopulatedValues;
186
184
  }
187
185
  const propertySegment = property.configurationKey || getKeySegment(property.name);
188
186
  getOptionValuesFromEnvVars(
189
- envVarValues[option.name] as PopulatedArgumentValues,
187
+ envVarValues[option.name] as PopulatedValues,
190
188
  potentialEnvVarNames,
191
189
  env,
192
190
  property,
@@ -202,7 +200,7 @@ function getOptionValuesFromEnvVars(
202
200
  if (value === undefined) {
203
201
  return undefined;
204
202
  }
205
- if (option.type === ArgumentValueTypeName.BOOLEAN) {
203
+ if (option.type === ValueTypeName.BOOLEAN) {
206
204
  value = value.length > 1 ? "true" : "false";
207
205
  }
208
206
  // set primitive value
@@ -220,8 +218,8 @@ function getOptionValuesFromEnvVars(
220
218
  export function getSubCommandValuesFromEnvVars(
221
219
  cliConfig: CLIConfig,
222
220
  command: SubCommand,
223
- ): PopulatedArgumentValues | undefined {
224
- const envVarValues = Object.create(null) as PopulatedArgumentValues;
221
+ ): PopulatedValues | undefined {
222
+ const envVarValues = Object.create(null) as PopulatedValues;
225
223
  if (command.options) {
226
224
  for (const option of command.options) {
227
225
  const potentialEnvVarNames = Object.keys(process.env);
@@ -270,11 +268,10 @@ export function getSubCommandValuesFromEnvVars(
270
268
  }
271
269
  // set primitive value
272
270
  let envVarValue = process.env[match];
273
- if (envVarValue != undefined && positional.type === ArgumentValueTypeName.BOOLEAN) {
271
+ if (envVarValue != undefined && positional.type === ValueTypeName.BOOLEAN) {
274
272
  envVarValue = envVarValue.length > 1 ? "true" : "false";
275
273
  }
276
- (envVarValues[positional.name] as Array<PopulatedArgumentSingleValueType>)[index] =
277
- envVarValue;
274
+ (envVarValues[positional.name] as Array<PopulatedSingleValueType>)[index] = envVarValue;
278
275
  }
279
276
  });
280
277
  } else {
@@ -283,7 +280,7 @@ export function getSubCommandValuesFromEnvVars(
283
280
  if (value === undefined) {
284
281
  return undefined;
285
282
  }
286
- if (positional.type === ArgumentValueTypeName.BOOLEAN) {
283
+ if (positional.type === ValueTypeName.BOOLEAN) {
287
284
  value = value.length > 1 ? "true" : "false";
288
285
  }
289
286
  // set primitive value
@@ -1,10 +1,7 @@
1
1
  import { distance } from "fastest-levenshtein";
2
2
  import type { GlobalCommand } from "@flowscripter/dynamic-cli-framework-api";
3
3
  import type { GlobalCommandArgument } from "@flowscripter/dynamic-cli-framework-api";
4
- import {
5
- ArgumentValueTypeName,
6
- ComplexValueTypeName,
7
- } from "@flowscripter/dynamic-cli-framework-api";
4
+ import { ValueTypeName, ComplexValueTypeName } from "@flowscripter/dynamic-cli-framework-api";
8
5
  import type { SubCommand } from "@flowscripter/dynamic-cli-framework-api";
9
6
  import type { Context } from "@flowscripter/dynamic-cli-framework-api";
10
7
  import type { UsageExample } from "@flowscripter/dynamic-cli-framework-api";
@@ -144,24 +141,21 @@ function getGlobalCommandArgumentForm(globalCommandArgument: GlobalCommandArgume
144
141
  let argumentSyntax = "";
145
142
 
146
143
  switch (globalCommandArgument.type) {
147
- case ArgumentValueTypeName.BOOLEAN:
144
+ case ValueTypeName.BOOLEAN:
148
145
  argumentSyntax = "true|false";
149
146
  break;
150
- case ArgumentValueTypeName.INTEGER:
147
+ case ValueTypeName.INTEGER:
151
148
  argumentSyntax = "<integer_value>";
152
149
  break;
153
- case ArgumentValueTypeName.NUMBER:
150
+ case ValueTypeName.NUMBER:
154
151
  argumentSyntax = "<number_value>";
155
152
  break;
156
- case ArgumentValueTypeName.STRING:
153
+ case ValueTypeName.STRING:
157
154
  argumentSyntax = "<string_value>";
158
155
  break;
159
156
  }
160
157
 
161
- if (
162
- globalCommandArgument.isOptional ||
163
- globalCommandArgument.type === ArgumentValueTypeName.BOOLEAN
164
- ) {
158
+ if (globalCommandArgument.isOptional || globalCommandArgument.type === ValueTypeName.BOOLEAN) {
165
159
  argumentSyntax = `[${argumentSyntax}]`;
166
160
  }
167
161
 
@@ -187,13 +181,13 @@ export function getGlobalArgumentHelpEntry(
187
181
  notesItems.push(`valid values: ${argument.allowableValues.join("|")}`);
188
182
  } else {
189
183
  switch (argument.type) {
190
- case ArgumentValueTypeName.STRING:
184
+ case ValueTypeName.STRING:
191
185
  notesItems.push("string value");
192
186
  break;
193
- case ArgumentValueTypeName.INTEGER:
187
+ case ValueTypeName.INTEGER:
194
188
  notesItems.push("integer value");
195
189
  break;
196
- case ArgumentValueTypeName.NUMBER:
190
+ case ValueTypeName.NUMBER:
197
191
  notesItems.push("number value");
198
192
  break;
199
193
  }
@@ -240,17 +234,17 @@ export function getSubCommandArgumentsSyntax(subCommand: SubCommand): string {
240
234
 
241
235
  subCommand.options.forEach((option) => {
242
236
  let optionSyntax = `--${option.name}`;
243
- switch (option.type as ArgumentValueTypeName | ComplexValueTypeName) {
244
- case ArgumentValueTypeName.BOOLEAN:
237
+ switch (option.type as ValueTypeName | ComplexValueTypeName) {
238
+ case ValueTypeName.BOOLEAN:
245
239
  optionSyntax = `${optionSyntax} [true|false]`;
246
240
  break;
247
- case ArgumentValueTypeName.INTEGER:
241
+ case ValueTypeName.INTEGER:
248
242
  optionSyntax = `${optionSyntax} <integer_value>`;
249
243
  break;
250
- case ArgumentValueTypeName.NUMBER:
244
+ case ValueTypeName.NUMBER:
251
245
  optionSyntax = `${optionSyntax} <number_value>`;
252
246
  break;
253
- case ArgumentValueTypeName.STRING:
247
+ case ValueTypeName.STRING:
254
248
  optionSyntax = `${optionSyntax} <string_value>`;
255
249
  break;
256
250
  case ComplexValueTypeName.COMPLEX:
@@ -318,16 +312,16 @@ function getOptionHelpEntry(
318
312
  notesItems.push(`valid values: ${option.allowableValues.join("|")}`);
319
313
  } else {
320
314
  switch (option.type) {
321
- case ArgumentValueTypeName.STRING:
315
+ case ValueTypeName.STRING:
322
316
  notesItems.push(`string value`);
323
317
  break;
324
- case ArgumentValueTypeName.INTEGER:
318
+ case ValueTypeName.INTEGER:
325
319
  notesItems.push(`integer value`);
326
320
  break;
327
- case ArgumentValueTypeName.NUMBER:
321
+ case ValueTypeName.NUMBER:
328
322
  notesItems.push(`number value`);
329
323
  break;
330
- case ArgumentValueTypeName.BOOLEAN:
324
+ case ValueTypeName.BOOLEAN:
331
325
  notesItems.push(`boolean value`);
332
326
  break;
333
327
  }
@@ -403,16 +397,16 @@ function getPositionalHelpEntry(
403
397
  notesItems.push(`valid values: ${positional.allowableValues.join("|")}`);
404
398
  } else {
405
399
  switch (positional.type) {
406
- case ArgumentValueTypeName.STRING:
400
+ case ValueTypeName.STRING:
407
401
  notesItems.push(`string value`);
408
402
  break;
409
- case ArgumentValueTypeName.INTEGER:
403
+ case ValueTypeName.INTEGER:
410
404
  notesItems.push(`integer value`);
411
405
  break;
412
- case ArgumentValueTypeName.NUMBER:
406
+ case ValueTypeName.NUMBER:
413
407
  notesItems.push(`number value`);
414
408
  break;
415
- case ArgumentValueTypeName.BOOLEAN:
409
+ case ValueTypeName.BOOLEAN:
416
410
  notesItems.push(`boolean value`);
417
411
  break;
418
412
  }
@@ -544,7 +538,7 @@ export function getMultiCommandAppSyntax(
544
538
  modifier.argument !== undefined &&
545
539
  !modifier.argument.isOptional &&
546
540
  modifier.argument.defaultValue === undefined &&
547
- modifier.argument.type !== ArgumentValueTypeName.BOOLEAN,
541
+ modifier.argument.type !== ValueTypeName.BOOLEAN,
548
542
  );
549
543
  syntax += optionArgMandatory ? " <value>" : " [<value>]";
550
544
  }
@@ -571,7 +565,7 @@ export function getMultiCommandAppSyntax(
571
565
  argValueOptional = globalCommands.some(
572
566
  (globalCommand) =>
573
567
  globalCommand.argument !== undefined &&
574
- globalCommand.argument.type === ArgumentValueTypeName.BOOLEAN,
568
+ globalCommand.argument.type === ValueTypeName.BOOLEAN,
575
569
  );
576
570
  }
577
571
  }
@@ -623,19 +617,17 @@ export function getMultiCommandAppSyntax(
623
617
  groupCommand.memberSubCommands.some((memberCommand) =>
624
618
  memberCommand.options.some(
625
619
  (option) =>
626
- option.type === ArgumentValueTypeName.BOOLEAN ||
620
+ option.type === ValueTypeName.BOOLEAN ||
627
621
  memberCommand.positionals.some(
628
- (positional) => positional.type === ArgumentValueTypeName.BOOLEAN,
622
+ (positional) => positional.type === ValueTypeName.BOOLEAN,
629
623
  ),
630
624
  ),
631
625
  ),
632
626
  ) ||
633
627
  subCommands.some(
634
628
  (subCommand) =>
635
- subCommand.options.some((option) => option.type === ArgumentValueTypeName.BOOLEAN) ||
636
- subCommand.positionals.some(
637
- (positional) => positional.type === ArgumentValueTypeName.BOOLEAN,
638
- ),
629
+ subCommand.options.some((option) => option.type === ValueTypeName.BOOLEAN) ||
630
+ subCommand.positionals.some((positional) => positional.type === ValueTypeName.BOOLEAN),
639
631
  );
640
632
  multipleArg =
641
633
  multipleArg ||