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