@truenas/api-client 2.0.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.
- package/dist/index.cjs +75 -15
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +434 -353
- package/dist/index.d.ts +434 -353
- package/dist/index.js +75 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2521,7 +2521,6 @@ __export(v26_0_0_exports, {
|
|
|
2521
2521
|
Aclmode: () => Aclmode,
|
|
2522
2522
|
Acltype: () => Acltype,
|
|
2523
2523
|
Advpowermgmt: () => Advpowermgmt,
|
|
2524
|
-
Algorithm: () => Algorithm,
|
|
2525
2524
|
AppContainerDetailsState: () => AppContainerDetailsState,
|
|
2526
2525
|
AppContainerDetailsStateInput: () => AppContainerDetailsStateInput,
|
|
2527
2526
|
Atime: () => Atime,
|
|
@@ -2659,11 +2658,13 @@ var ContainerNICDeviceTypeInput = {
|
|
|
2659
2658
|
};
|
|
2660
2659
|
var ContainerStatusState = {
|
|
2661
2660
|
Running: "RUNNING",
|
|
2662
|
-
Stopped: "STOPPED"
|
|
2661
|
+
Stopped: "STOPPED",
|
|
2662
|
+
Suspended: "SUSPENDED"
|
|
2663
2663
|
};
|
|
2664
2664
|
var ContainerStatusStateInput = {
|
|
2665
2665
|
Running: "RUNNING",
|
|
2666
|
-
Stopped: "STOPPED"
|
|
2666
|
+
Stopped: "STOPPED",
|
|
2667
|
+
Suspended: "SUSPENDED"
|
|
2667
2668
|
};
|
|
2668
2669
|
var Feature2 = {
|
|
2669
2670
|
Apps: "APPS",
|
|
@@ -2743,7 +2744,6 @@ __export(v27_0_0_exports, {
|
|
|
2743
2744
|
Aclmode: () => Aclmode,
|
|
2744
2745
|
Acltype: () => Acltype,
|
|
2745
2746
|
Advpowermgmt: () => Advpowermgmt,
|
|
2746
|
-
Algorithm: () => Algorithm,
|
|
2747
2747
|
AppContainerDetailsState: () => AppContainerDetailsState,
|
|
2748
2748
|
AppContainerDetailsStateInput: () => AppContainerDetailsStateInput,
|
|
2749
2749
|
Atime: () => Atime,
|
|
@@ -3066,6 +3066,10 @@ var AppState = /* @__PURE__ */ ((AppState2) => {
|
|
|
3066
3066
|
AppState2["Stopped"] = "STOPPED";
|
|
3067
3067
|
AppState2["Stopping"] = "STOPPING";
|
|
3068
3068
|
AppState2["Deploying"] = "DEPLOYING";
|
|
3069
|
+
AppState2["Suspended"] = "SUSPENDED";
|
|
3070
|
+
AppState2["Suspending"] = "SUSPENDING";
|
|
3071
|
+
AppState2["Error"] = "ERROR";
|
|
3072
|
+
AppState2["Unknown"] = "UNKNOWN";
|
|
3069
3073
|
return AppState2;
|
|
3070
3074
|
})(AppState || {});
|
|
3071
3075
|
|
|
@@ -3076,7 +3080,10 @@ function toAppState(state) {
|
|
|
3076
3080
|
return "RUNNING" /* Running */;
|
|
3077
3081
|
case "STOPPED":
|
|
3078
3082
|
return "STOPPED" /* Stopped */;
|
|
3083
|
+
// `ABORTING` is v25.10 only: the instance is being forced down, which ends
|
|
3084
|
+
// at `STOPPED` and is what `Stopping` already means.
|
|
3079
3085
|
case "STOPPING":
|
|
3086
|
+
case "ABORTING":
|
|
3080
3087
|
return "STOPPING" /* Stopping */;
|
|
3081
3088
|
// `STARTING` is v25.10 `virt.instance` only, and folding it into `Stopped`
|
|
3082
3089
|
// told callers a container that is coming up is at rest — enough for a UI
|
|
@@ -3085,8 +3092,35 @@ function toAppState(state) {
|
|
|
3085
3092
|
case "STARTING":
|
|
3086
3093
|
case "DEPLOYING":
|
|
3087
3094
|
return "DEPLOYING" /* Deploying */;
|
|
3095
|
+
// v25.10's freezer states are the same idea as v26's `SUSPENDED`: the
|
|
3096
|
+
// processes are paused, not exited. `FROZEN` is that pause completed, so it
|
|
3097
|
+
// and `SUSPENDED` are the same answer.
|
|
3098
|
+
case "SUSPENDED":
|
|
3099
|
+
case "FROZEN":
|
|
3100
|
+
return "SUSPENDED" /* Suspended */;
|
|
3101
|
+
// `FREEZING` is on the way there and not there yet. It used to answer
|
|
3102
|
+
// `Suspended`, defended by analogy with `STARTING` — but `STARTING` maps to
|
|
3103
|
+
// `Deploying`, which is itself an in-progress word, so the analogy ran the
|
|
3104
|
+
// wrong way. Answering `Suspended` tells a caller polling for "the memory
|
|
3105
|
+
// is quiesced" that it is, one poll before it is true: the same false
|
|
3106
|
+
// claim this mapping was rewritten to stop making, one state along.
|
|
3107
|
+
// `ABORTING` had `Stopping` to land on; the freeze path needed its own.
|
|
3108
|
+
case "FREEZING":
|
|
3109
|
+
return "SUSPENDING" /* Suspending */;
|
|
3110
|
+
// `THAWED` is the freezer lifted: the processes are scheduled again, so
|
|
3111
|
+
// this is `RUNNING` reported through the transition rather than a state a
|
|
3112
|
+
// caller should act on differently.
|
|
3113
|
+
case "THAWED":
|
|
3114
|
+
return "RUNNING" /* Running */;
|
|
3115
|
+
case "ERROR":
|
|
3116
|
+
return "ERROR" /* Error */;
|
|
3117
|
+
// `UNKNOWN` is middleware's own word for it, and anything unrecognised is
|
|
3118
|
+
// the same situation: a state this mapping has no word for. Neither is
|
|
3119
|
+
// evidence the container is stopped.
|
|
3120
|
+
case "UNKNOWN":
|
|
3121
|
+
return "UNKNOWN" /* Unknown */;
|
|
3088
3122
|
default:
|
|
3089
|
-
return "
|
|
3123
|
+
return "UNKNOWN" /* Unknown */;
|
|
3090
3124
|
}
|
|
3091
3125
|
}
|
|
3092
3126
|
|
|
@@ -3306,7 +3340,7 @@ var VersionDiscovery = class {
|
|
|
3306
3340
|
operators.map((versionStrings) => this.selectVersion(hostname, versionStrings)),
|
|
3307
3341
|
operators.catchError((error) => {
|
|
3308
3342
|
this.versionCache.delete(hostname);
|
|
3309
|
-
this.logger.
|
|
3343
|
+
this.logger.warn("Version discovery failed", { hostname, error });
|
|
3310
3344
|
return rxjs.throwError(() => this.classify(error, hostname));
|
|
3311
3345
|
}),
|
|
3312
3346
|
operators.shareReplay(1)
|
|
@@ -3377,7 +3411,7 @@ var VersionDiscovery = class {
|
|
|
3377
3411
|
});
|
|
3378
3412
|
const parsedVersions = versionStrings.map(parseApiVersion).filter((v) => v !== null);
|
|
3379
3413
|
if (parsedVersions.length === 0) {
|
|
3380
|
-
this.logger.
|
|
3414
|
+
this.logger.warn("No valid versions in response", {
|
|
3381
3415
|
hostname,
|
|
3382
3416
|
versionStrings
|
|
3383
3417
|
});
|
|
@@ -3479,29 +3513,34 @@ async function createTrueNasClient(opts) {
|
|
|
3479
3513
|
`Cannot create client for system ${uuid}: hostnames array is empty`
|
|
3480
3514
|
);
|
|
3481
3515
|
}
|
|
3482
|
-
const primaryHostname = hostnames[0];
|
|
3483
3516
|
const versionDiscovery = new VersionDiscovery(logger);
|
|
3484
3517
|
logger.info("Creating versioned API client", {
|
|
3485
3518
|
uuid: uuid.slice(0, 8),
|
|
3486
|
-
|
|
3519
|
+
hostnames: hostnames.join(", "),
|
|
3487
3520
|
systemName
|
|
3488
3521
|
});
|
|
3489
3522
|
let version;
|
|
3490
3523
|
try {
|
|
3491
|
-
|
|
3492
|
-
|
|
3524
|
+
const winner = await discoverVersionFromAnyHostname(
|
|
3525
|
+
hostnames,
|
|
3526
|
+
versionDiscovery
|
|
3493
3527
|
);
|
|
3528
|
+
version = winner.version;
|
|
3494
3529
|
logger.info("API version discovered, instantiating client", {
|
|
3495
3530
|
uuid: uuid.slice(0, 8),
|
|
3531
|
+
// Which hostname answered is log context only. The client is built with
|
|
3532
|
+
// the full hostname list regardless — the websocket connection races all
|
|
3533
|
+
// of them anyway.
|
|
3534
|
+
hostname: winner.hostname,
|
|
3496
3535
|
version: version.version,
|
|
3497
3536
|
websocketPath: version.websocketPath
|
|
3498
3537
|
});
|
|
3499
3538
|
} catch (error) {
|
|
3500
3539
|
const errorMessage = errorMessageOrDefault(error, "Unknown error");
|
|
3501
3540
|
if (!(error instanceof VersionDiscoveryNetworkError)) {
|
|
3502
|
-
logger.error("Version discovery failed", {
|
|
3541
|
+
logger.error("Version discovery failed on every hostname", {
|
|
3503
3542
|
uuid: uuid.slice(0, 8),
|
|
3504
|
-
|
|
3543
|
+
hostnames: hostnames.join(", "),
|
|
3505
3544
|
error: errorMessage,
|
|
3506
3545
|
errorType: error instanceof Error ? error.constructor.name : typeof error
|
|
3507
3546
|
});
|
|
@@ -3512,7 +3551,7 @@ async function createTrueNasClient(opts) {
|
|
|
3512
3551
|
if (!fallbackVersion) {
|
|
3513
3552
|
logger.error("Invalid fallback version configuration", {
|
|
3514
3553
|
uuid: uuid.slice(0, 8),
|
|
3515
|
-
|
|
3554
|
+
hostnames: hostnames.join(", "),
|
|
3516
3555
|
fallbackVersion: fallbackVersionString
|
|
3517
3556
|
});
|
|
3518
3557
|
throw error;
|
|
@@ -3521,7 +3560,7 @@ async function createTrueNasClient(opts) {
|
|
|
3521
3560
|
"Version discovery failed with a network error (possible CORS or network issue), falling back to assumed version",
|
|
3522
3561
|
{
|
|
3523
3562
|
uuid: uuid.slice(0, 8),
|
|
3524
|
-
|
|
3563
|
+
hostnames: hostnames.join(", "),
|
|
3525
3564
|
fallbackVersion: fallbackVersionString,
|
|
3526
3565
|
originalError: errorMessage,
|
|
3527
3566
|
warning: "A network error has multiple causes (CORS, network down, DNS failure). The connection may still fail during the WebSocket handshake."
|
|
@@ -3531,6 +3570,27 @@ async function createTrueNasClient(opts) {
|
|
|
3531
3570
|
}
|
|
3532
3571
|
return instantiateClientForVersion(version, opts, logger);
|
|
3533
3572
|
}
|
|
3573
|
+
async function discoverVersionFromAnyHostname(hostnames, versionDiscovery) {
|
|
3574
|
+
const attempts = hostnames.map(
|
|
3575
|
+
(hostname) => rxjs.firstValueFrom(versionDiscovery.discoverVersion(hostname)).then(
|
|
3576
|
+
(version) => ({ hostname, version })
|
|
3577
|
+
)
|
|
3578
|
+
);
|
|
3579
|
+
try {
|
|
3580
|
+
return await Promise.any(attempts);
|
|
3581
|
+
} catch (error) {
|
|
3582
|
+
const failures = error instanceof AggregateError ? error.errors : [error];
|
|
3583
|
+
throw selectRepresentativeFailure(failures);
|
|
3584
|
+
}
|
|
3585
|
+
}
|
|
3586
|
+
function selectRepresentativeFailure(failures) {
|
|
3587
|
+
const isVersionError = (error) => (
|
|
3588
|
+
// cases: valid response, but the given versions won't work for us
|
|
3589
|
+
error instanceof VersionTooOldError || error instanceof VersionTooNewError || error instanceof NoCompatibleVersionsError || error instanceof VersionEndpointNotFoundError
|
|
3590
|
+
);
|
|
3591
|
+
const isNetworkError = (error) => error instanceof VersionDiscoveryNetworkError;
|
|
3592
|
+
return failures.find(isVersionError) ?? failures.find(isNetworkError) ?? failures[0];
|
|
3593
|
+
}
|
|
3534
3594
|
var CLIENT_BY_VERSION_KEY = {
|
|
3535
3595
|
"25.10": TrueNasApiClientV2510,
|
|
3536
3596
|
"26": TrueNasApiClientV26
|