@truenas/api-client 3.0.3 → 3.0.5

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.d.cts CHANGED
@@ -12460,6 +12460,16 @@ declare class TrueNasSocket {
12460
12460
  complete(): void;
12461
12461
  }
12462
12462
 
12463
+ /**
12464
+ * The scheme used to reach the appliance, in `location.protocol` form.
12465
+ *
12466
+ * Colon included, so a caller served *by the appliance* can pass
12467
+ * `location.protocol` unchanged. That equivalence only holds same-origin: this
12468
+ * value is spliced onto the hostname the client connects to, so a page served
12469
+ * from somewhere else must say what the appliance uses, not what it uses.
12470
+ */
12471
+ type ApplianceProtocol = 'http:' | 'https:';
12472
+
12463
12473
  interface ActiveConnection {
12464
12474
  ws: TrueNasSocket;
12465
12475
  hostname: string;
@@ -12482,6 +12492,7 @@ declare class TrueNasConnection {
12482
12492
  readonly retryDelay: number;
12483
12493
  readonly maxRetry: number;
12484
12494
  readonly logger: Logger;
12495
+ readonly protocol: ApplianceProtocol;
12485
12496
  opened: BehaviorSubject<boolean>;
12486
12497
  closed: Subject<void>;
12487
12498
  hostname: BehaviorSubject<string>;
@@ -12544,7 +12555,7 @@ declare class TrueNasConnection {
12544
12555
  * observable which always emits messages from the current socket.
12545
12556
  */
12546
12557
  messages$: Observable<TrueNasMessage>;
12547
- constructor(initialEnabled: boolean, hostnames: string[], systemUuid: string, websocketPath: string, systemName?: string | undefined, retryDelay?: number, maxRetry?: number, logger?: Logger);
12558
+ constructor(initialEnabled: boolean, hostnames: string[], systemUuid: string, websocketPath: string, systemName?: string | undefined, retryDelay?: number, maxRetry?: number, logger?: Logger, protocol?: ApplianceProtocol);
12548
12559
  /**
12549
12560
  * whether the connection has exhausted its retries — the **cumulative** snapshot, read
12550
12561
  * synchronously. (Formerly `hasConnectionError()`; renamed to disambiguate it from the
@@ -12787,6 +12798,49 @@ declare class TrueNasApi<D extends ApiDirectoryShape = BaseApiDirectory> {
12787
12798
  private initializeJobEventsSubscription;
12788
12799
  }
12789
12800
 
12801
+ /**
12802
+ * Response from the /api/versions endpoint
12803
+ * Returns an array of version strings directly
12804
+ * Example: ["v25.10.0", "v25.10.1", "v26.0.0"]
12805
+ */
12806
+ type ApiVersionResponse = string[];
12807
+ /**
12808
+ * Parsed API version information
12809
+ *
12810
+ * Version format:
12811
+ * - Legacy (v25.x): vYY.MM.PATCH (e.g., v25.10.0 = October 2025, patch 0)
12812
+ * - New (v26+): vYY.MINOR.PATCH (e.g., v26.0.0 = 2026, minor 0, patch 0)
12813
+ *
12814
+ * Note: The second segment has different semantics based on the year:
12815
+ * - Year 25: month (1-12)
12816
+ * - Year 26+: minor version (0-99)
12817
+ */
12818
+ interface ApiVersion {
12819
+ /** Full version string (e.g., "v26.0.0") */
12820
+ version: string;
12821
+ /** Two-digit year (e.g., 26 = 2026) */
12822
+ year: number;
12823
+ /**
12824
+ * Second version segment (semantics depend on year):
12825
+ * - For v25.x: month (1-12, e.g., 10 = October)
12826
+ * - For v26+: minor version (0-99)
12827
+ */
12828
+ minor: number;
12829
+ /** Patch version number (e.g., 0, 1, 2) */
12830
+ patch: number;
12831
+ /** WebSocket path for this version (e.g., "/api/v26.0.0") */
12832
+ websocketPath: string;
12833
+ }
12834
+ /**
12835
+ * Version compatibility status
12836
+ */
12837
+ declare enum VersionCompatibility {
12838
+ Compatible = "compatible",
12839
+ TooOld = "too-old",
12840
+ TooNew = "too-new",
12841
+ Invalid = "invalid"
12842
+ }
12843
+
12790
12844
  interface ApiKeyCreate {
12791
12845
  id: number;
12792
12846
  key: string;
@@ -12813,6 +12867,24 @@ interface AuthResponse {
12813
12867
  response_type: AuthResponseType;
12814
12868
  username?: string;
12815
12869
  authenticator?: 'LEVEL_1' | 'LEVEL_2' | 'LEVEL_3';
12870
+ /**
12871
+ * A token for re-authenticating without credentials.
12872
+ *
12873
+ * Absent below v26: `AuthRespSuccess` there declares only `response_type`,
12874
+ * `user_info` and `authenticator`. From v26 it is always present and is
12875
+ * `null` when no token was minted — because none was asked for, or because
12876
+ * the session cannot have one. Middleware refuses for a session authenticated
12877
+ * by a one-time *password* (`auth.generate_onetime_password`), which is not
12878
+ * the same thing as 2FA despite this codebase spelling 2FA "OTP" throughout.
12879
+ *
12880
+ * A 2FA account gets `null` for a different reason, and it is this client's
12881
+ * doing rather than the server's: the password request carrying the option is
12882
+ * answered `OTP_REQUIRED` before anything is minted, and `loginWithOtp` does
12883
+ * not send `login_options` on the second step. Middleware would honour it
12884
+ * there — `auth.login_ex_continue` re-enters `login_ex`, and a 2FA session
12885
+ * may hold a token — so this is a gap to close, not a limit to work around.
12886
+ */
12887
+ reconnect_token?: string | null;
12816
12888
  max_session_age?: number;
12817
12889
  max_inactivity?: number;
12818
12890
  urls?: string[];
@@ -12866,6 +12938,7 @@ interface AuthResponse {
12866
12938
  */
12867
12939
  declare class TrueNasAuthenticator {
12868
12940
  private connection;
12941
+ private readonly version?;
12869
12942
  static readonly DefaultSessionLifetime = 300;
12870
12943
  /**
12871
12944
  * whether or not the system is currently authenticated and accessible.
@@ -12885,9 +12958,54 @@ declare class TrueNasAuthenticator {
12885
12958
  key: string;
12886
12959
  };
12887
12960
  sessionLifetime: number;
12888
- constructor(connection: TrueNasConnection);
12961
+ constructor(connection: TrueNasConnection, version?: ApiVersion | undefined);
12962
+ /**
12963
+ * `login_options` asking for a reconnect token, when the server understands it.
12964
+ *
12965
+ * Omitted below v26. `AuthCommonOptions` is `additionalProperties: false`
12966
+ * there and has only `user_info`, so sending the member is a validation
12967
+ * error, not an ignored field — it would fail login outright on the oldest
12968
+ * version this client supports.
12969
+ */
12970
+ /**
12971
+ * Two things this does not do, both deliberate and both worth knowing.
12972
+ *
12973
+ * There is no way for a consumer to decline: every v26+ password login now
12974
+ * mints a single-use credential carrying that session's roles, whether or not
12975
+ * the caller wants one. And the auto-relogin in the constructor subscribes
12976
+ * with no observer, so the token it mints is dropped — a caller reconnecting
12977
+ * repeatedly holds an ageing token while the appliance mints fresh ones
12978
+ * nobody reads. Tokens are single-use with a 600s TTL, so that is the
12979
+ * reconnect case the feature is named for.
12980
+ */
12981
+ private reconnectTokenOption;
12889
12982
  loginWithUserPass(username: string, password: string): rxjs.Observable<AuthResponse>;
12890
12983
  loginWithOtp(code: string): rxjs.Observable<AuthResponse>;
12984
+ /**
12985
+ * Re-authenticate with a token from a previous login's `reconnect_token`.
12986
+ *
12987
+ * This is what lets a second connection to the same appliance authenticate
12988
+ * without asking the user for a password again — middleware sessions are
12989
+ * per-connection, so a second socket has its own to establish.
12990
+ *
12991
+ * The token is single-use and short-lived. On v26+ a successful login mints
12992
+ * another on the response, so a caller keeping a session alive across
12993
+ * reconnects stores the newest each time; below v26 nothing is minted and
12994
+ * there is no chain to keep.
12995
+ *
12996
+ * Re-login is the caller's to drive. A token session is not covered by the
12997
+ * automatic reconnect this class does for password and api-key sessions,
12998
+ * which is deliberate — the token is single-use — but it means a dropped
12999
+ * socket needs the stored token spending explicitly. Middleware holds tokens
13000
+ * in memory, so a `middlewared` restart voids them, and that is a common
13001
+ * reason the socket dropped in the first place.
13002
+ */
13003
+ loginWithToken(token: string): rxjs.Observable<AuthResponse>;
13004
+ /**
13005
+ * No reconnect token is requested here, though v26+ would mint one: an
13006
+ * api-key session already reconnects without a prompt, since the key is held
13007
+ * and replayed. The token exists for the credential that cannot be.
13008
+ */
12891
13009
  loginWithApiKey(credentials: {
12892
13010
  username: string;
12893
13011
  key: string;
@@ -12896,49 +13014,6 @@ declare class TrueNasAuthenticator {
12896
13014
  logout(): rxjs.Observable<boolean>;
12897
13015
  }
12898
13016
 
12899
- /**
12900
- * Response from the /api/versions endpoint
12901
- * Returns an array of version strings directly
12902
- * Example: ["v25.10.0", "v25.10.1", "v26.0.0"]
12903
- */
12904
- type ApiVersionResponse = string[];
12905
- /**
12906
- * Parsed API version information
12907
- *
12908
- * Version format:
12909
- * - Legacy (v25.x): vYY.MM.PATCH (e.g., v25.10.0 = October 2025, patch 0)
12910
- * - New (v26+): vYY.MINOR.PATCH (e.g., v26.0.0 = 2026, minor 0, patch 0)
12911
- *
12912
- * Note: The second segment has different semantics based on the year:
12913
- * - Year 25: month (1-12)
12914
- * - Year 26+: minor version (0-99)
12915
- */
12916
- interface ApiVersion {
12917
- /** Full version string (e.g., "v26.0.0") */
12918
- version: string;
12919
- /** Two-digit year (e.g., 26 = 2026) */
12920
- year: number;
12921
- /**
12922
- * Second version segment (semantics depend on year):
12923
- * - For v25.x: month (1-12, e.g., 10 = October)
12924
- * - For v26+: minor version (0-99)
12925
- */
12926
- minor: number;
12927
- /** Patch version number (e.g., 0, 1, 2) */
12928
- patch: number;
12929
- /** WebSocket path for this version (e.g., "/api/v26.0.0") */
12930
- websocketPath: string;
12931
- }
12932
- /**
12933
- * Version compatibility status
12934
- */
12935
- declare enum VersionCompatibility {
12936
- Compatible = "compatible",
12937
- TooOld = "too-old",
12938
- TooNew = "too-new",
12939
- Invalid = "invalid"
12940
- }
12941
-
12942
13017
  /**
12943
13018
  * The state `Container.status` is narrowed to.
12944
13019
  *
@@ -13192,7 +13267,8 @@ declare abstract class TrueNasApiClient<D extends ApiDirectoryShape = BaseApiDir
13192
13267
  protected readonly systemName: string | undefined;
13193
13268
  /** Logger forwarded to the connection (defaults to a no-op). */
13194
13269
  protected readonly logger: Logger;
13195
- constructor(uuid: string, hostnames: string[], version: ApiVersion, enabled: boolean, systemName?: string, logger?: Logger);
13270
+ protected readonly protocol: ApplianceProtocol;
13271
+ constructor(uuid: string, hostnames: string[], version: ApiVersion, enabled: boolean, systemName?: string, logger?: Logger, protocol?: ApplianceProtocol);
13196
13272
  /**
13197
13273
  * Get current connection status.
13198
13274
  * @returns true if WebSocket is connected
@@ -27604,6 +27680,28 @@ interface CreateClientOptions {
27604
27680
  * without the caller asserting it through a type parameter.
27605
27681
  */
27606
27682
  version?: SupportedApiVersion;
27683
+ /**
27684
+ * The scheme to reach the appliance on, in `location.protocol` form.
27685
+ *
27686
+ * Selects both halves of the transport: `https:` gives `https` discovery and
27687
+ * a `wss` socket, `http:` gives `http` and `ws`. Defaults to `https:`, which
27688
+ * is what an appliance serves and what Connect uses.
27689
+ *
27690
+ * This describes the *appliance*, not the page. Passing
27691
+ * `location.protocol` is correct when the appliance serves the page — the
27692
+ * same-origin case this exists for — and wrong otherwise. A page on
27693
+ * `http://localhost:5173` talking to an https appliance gets both halves
27694
+ * wrong, but only one of them says so: `fetch` follows the redirect and
27695
+ * discovery appears to work, while the WebSocket has no such tolerance and
27696
+ * fails the handshake without naming the scheme.
27697
+ *
27698
+ * Omitting it against a plaintext appliance is the quieter failure and the
27699
+ * likelier one, since it is the case this option exists for. Discovery tries
27700
+ * `https`, `fetch` rejects, and that is indistinguishable from the CORS block
27701
+ * v25.10.0 has on `/api/versions` — so the fallback fires and the caller gets
27702
+ * a client pinned to v25.10.0, warned about only in the log.
27703
+ */
27704
+ protocol?: ApplianceProtocol;
27607
27705
  }
27608
27706
  /**
27609
27707
  * Creates a version-specific TrueNAS API client.
@@ -27883,12 +27981,14 @@ declare class TrueNasApiClientV27 extends TrueNasApiClient<ApiDirectory> {
27883
27981
  */
27884
27982
  declare class VersionDiscovery {
27885
27983
  private readonly logger;
27984
+ private readonly protocol;
27886
27985
  private versionCache;
27887
- constructor(logger?: Logger);
27986
+ constructor(logger?: Logger, protocol?: ApplianceProtocol);
27987
+ private versionsUrl;
27888
27988
  /**
27889
27989
  * Discovers the API version for a given hostname.
27890
27990
  *
27891
- * Makes a GET request to `https://{hostname}/api/versions` and returns the latest
27991
+ * Makes a GET request to `{protocol}//{hostname}/api/versions` and returns the latest
27892
27992
  * compatible version. Results are cached per hostname; the cache entry is removed
27893
27993
  * on failure so the next call retries.
27894
27994
  *
@@ -28007,6 +28107,7 @@ declare enum AuthErrorCode {
28007
28107
  PasswordAuthFailed = "PASSWORD_AUTH_FAILED",
28008
28108
  OtpAuthFailed = "OTP_AUTH_FAILED",
28009
28109
  ApiKeyAuthFailed = "API_KEY_AUTH_FAILED",
28110
+ TokenAuthFailed = "TOKEN_AUTH_FAILED",
28010
28111
  FullAdminRequired = "FULL_ADMIN_REQUIRED"
28011
28112
  }
28012
28113
  declare class AuthError extends Error {
@@ -28067,4 +28168,4 @@ type ApiError = JsonRpcError | TrueNasError;
28067
28168
  */
28068
28169
  declare function getApiErrorMessage(error: unknown, fallback?: string): string;
28069
28170
 
28070
- export { type ApiCallDirectory$7 as ApiCallDirectoryV25_10_0, type ApiCallDirectory$6 as ApiCallDirectoryV25_10_1, type ApiCallDirectory$5 as ApiCallDirectoryV25_10_2, type ApiCallDirectory$4 as ApiCallDirectoryV25_10_3, type ApiCallDirectory$3 as ApiCallDirectoryV25_10_4, type ApiCallDirectory$2 as ApiCallDirectoryV25_10_5, type ApiCallDirectory$1 as ApiCallDirectoryV26_0_0, type ApiCallDirectory as ApiCallDirectoryV27_0_0, type ApiDirectoryByVersion, type ApiDirectoryShape, type ApiDirectory$7 as ApiDirectoryV25_10_0, type ApiDirectory$6 as ApiDirectoryV25_10_1, type ApiDirectory$5 as ApiDirectoryV25_10_2, type ApiDirectory$4 as ApiDirectoryV25_10_3, type ApiDirectory$3 as ApiDirectoryV25_10_4, type ApiDirectory$2 as ApiDirectoryV25_10_5, type ApiDirectory$1 as ApiDirectoryV26_0_0, type ApiDirectory as ApiDirectoryV27_0_0, type ApiError, type ApiEventDirectory$7 as ApiEventDirectoryV25_10_0, type ApiEventDirectory$6 as ApiEventDirectoryV25_10_1, type ApiEventDirectory$5 as ApiEventDirectoryV25_10_2, type ApiEventDirectory$4 as ApiEventDirectoryV25_10_3, type ApiEventDirectory$3 as ApiEventDirectoryV25_10_4, type ApiEventDirectory$2 as ApiEventDirectoryV25_10_5, type ApiEventDirectory$1 as ApiEventDirectoryV26_0_0, type ApiEventDirectory as ApiEventDirectoryV27_0_0, type ApiJobDirectory$7 as ApiJobDirectoryV25_10_0, type ApiJobDirectory$6 as ApiJobDirectoryV25_10_1, type ApiJobDirectory$5 as ApiJobDirectoryV25_10_2, type ApiJobDirectory$4 as ApiJobDirectoryV25_10_3, type ApiJobDirectory$3 as ApiJobDirectoryV25_10_4, type ApiJobDirectory$2 as ApiJobDirectoryV25_10_5, type ApiJobDirectory$1 as ApiJobDirectoryV26_0_0, type ApiJobDirectory as ApiJobDirectoryV27_0_0, type ApiKeyCreate, type ApiVersion, type ApiVersionResponse, AppState, type ArgsOf, AuthError, AuthErrorCode, type AuthResponse, type BaseApiDirectory, type CallMethod, type CallParams, type CallResponse, type Container, type CreateClientOptions, type DefaultApiDirectory, type EventKind, type EventName, type EventUnion, InvalidVersionResponseError, type Job, type JobMethod, type JobParams, type JobProgress, type JobResult, JobState, type Logger, NoCompatibleVersionsError, type OperationMappings, type QueryDirectory, type QueryEntity, type QueryListOptions, type QueryMethod, type QuerySingleOptions, SUPPORTED_API_VERSIONS, type SupportedApiVersion, TrueNasApiClient, TrueNasApiClientV2510, TrueNasApiClientV26, TrueNasApiClientV27, TrueNasAuthMechanism, type TrueNasDate, VersionCompatibility, VersionDiscovery, VersionDiscoveryError, VersionDiscoveryNetworkError, VersionDiscoveryTimeoutError, VersionEndpointNotFoundError, VersionTooNewError, VersionTooOldError, consoleLogger, createTrueNasClient, getApiErrorMessage, isJobFinished, noopLogger, index$7 as v25_10_0, index$6 as v25_10_1, index$5 as v25_10_2, index$4 as v25_10_3, index$3 as v25_10_4, index$2 as v25_10_5, index$1 as v26_0_0, index as v27_0_0 };
28171
+ export { type ApiCallDirectory$7 as ApiCallDirectoryV25_10_0, type ApiCallDirectory$6 as ApiCallDirectoryV25_10_1, type ApiCallDirectory$5 as ApiCallDirectoryV25_10_2, type ApiCallDirectory$4 as ApiCallDirectoryV25_10_3, type ApiCallDirectory$3 as ApiCallDirectoryV25_10_4, type ApiCallDirectory$2 as ApiCallDirectoryV25_10_5, type ApiCallDirectory$1 as ApiCallDirectoryV26_0_0, type ApiCallDirectory as ApiCallDirectoryV27_0_0, type ApiDirectoryByVersion, type ApiDirectoryShape, type ApiDirectory$7 as ApiDirectoryV25_10_0, type ApiDirectory$6 as ApiDirectoryV25_10_1, type ApiDirectory$5 as ApiDirectoryV25_10_2, type ApiDirectory$4 as ApiDirectoryV25_10_3, type ApiDirectory$3 as ApiDirectoryV25_10_4, type ApiDirectory$2 as ApiDirectoryV25_10_5, type ApiDirectory$1 as ApiDirectoryV26_0_0, type ApiDirectory as ApiDirectoryV27_0_0, type ApiError, type ApiEventDirectory$7 as ApiEventDirectoryV25_10_0, type ApiEventDirectory$6 as ApiEventDirectoryV25_10_1, type ApiEventDirectory$5 as ApiEventDirectoryV25_10_2, type ApiEventDirectory$4 as ApiEventDirectoryV25_10_3, type ApiEventDirectory$3 as ApiEventDirectoryV25_10_4, type ApiEventDirectory$2 as ApiEventDirectoryV25_10_5, type ApiEventDirectory$1 as ApiEventDirectoryV26_0_0, type ApiEventDirectory as ApiEventDirectoryV27_0_0, type ApiJobDirectory$7 as ApiJobDirectoryV25_10_0, type ApiJobDirectory$6 as ApiJobDirectoryV25_10_1, type ApiJobDirectory$5 as ApiJobDirectoryV25_10_2, type ApiJobDirectory$4 as ApiJobDirectoryV25_10_3, type ApiJobDirectory$3 as ApiJobDirectoryV25_10_4, type ApiJobDirectory$2 as ApiJobDirectoryV25_10_5, type ApiJobDirectory$1 as ApiJobDirectoryV26_0_0, type ApiJobDirectory as ApiJobDirectoryV27_0_0, type ApiKeyCreate, type ApiVersion, type ApiVersionResponse, AppState, type ApplianceProtocol, type ArgsOf, AuthError, AuthErrorCode, type AuthResponse, type BaseApiDirectory, type CallMethod, type CallParams, type CallResponse, type Container, type CreateClientOptions, type DefaultApiDirectory, type EventKind, type EventName, type EventUnion, InvalidVersionResponseError, type Job, type JobMethod, type JobParams, type JobProgress, type JobResult, JobState, type Logger, NoCompatibleVersionsError, type OperationMappings, type QueryDirectory, type QueryEntity, type QueryListOptions, type QueryMethod, type QuerySingleOptions, SUPPORTED_API_VERSIONS, type SupportedApiVersion, TrueNasApiClient, TrueNasApiClientV2510, TrueNasApiClientV26, TrueNasApiClientV27, TrueNasAuthMechanism, type TrueNasDate, VersionCompatibility, VersionDiscovery, VersionDiscoveryError, VersionDiscoveryNetworkError, VersionDiscoveryTimeoutError, VersionEndpointNotFoundError, VersionTooNewError, VersionTooOldError, consoleLogger, createTrueNasClient, getApiErrorMessage, isJobFinished, noopLogger, index$7 as v25_10_0, index$6 as v25_10_1, index$5 as v25_10_2, index$4 as v25_10_3, index$3 as v25_10_4, index$2 as v25_10_5, index$1 as v26_0_0, index as v27_0_0 };
package/dist/index.d.ts CHANGED
@@ -12460,6 +12460,16 @@ declare class TrueNasSocket {
12460
12460
  complete(): void;
12461
12461
  }
12462
12462
 
12463
+ /**
12464
+ * The scheme used to reach the appliance, in `location.protocol` form.
12465
+ *
12466
+ * Colon included, so a caller served *by the appliance* can pass
12467
+ * `location.protocol` unchanged. That equivalence only holds same-origin: this
12468
+ * value is spliced onto the hostname the client connects to, so a page served
12469
+ * from somewhere else must say what the appliance uses, not what it uses.
12470
+ */
12471
+ type ApplianceProtocol = 'http:' | 'https:';
12472
+
12463
12473
  interface ActiveConnection {
12464
12474
  ws: TrueNasSocket;
12465
12475
  hostname: string;
@@ -12482,6 +12492,7 @@ declare class TrueNasConnection {
12482
12492
  readonly retryDelay: number;
12483
12493
  readonly maxRetry: number;
12484
12494
  readonly logger: Logger;
12495
+ readonly protocol: ApplianceProtocol;
12485
12496
  opened: BehaviorSubject<boolean>;
12486
12497
  closed: Subject<void>;
12487
12498
  hostname: BehaviorSubject<string>;
@@ -12544,7 +12555,7 @@ declare class TrueNasConnection {
12544
12555
  * observable which always emits messages from the current socket.
12545
12556
  */
12546
12557
  messages$: Observable<TrueNasMessage>;
12547
- constructor(initialEnabled: boolean, hostnames: string[], systemUuid: string, websocketPath: string, systemName?: string | undefined, retryDelay?: number, maxRetry?: number, logger?: Logger);
12558
+ constructor(initialEnabled: boolean, hostnames: string[], systemUuid: string, websocketPath: string, systemName?: string | undefined, retryDelay?: number, maxRetry?: number, logger?: Logger, protocol?: ApplianceProtocol);
12548
12559
  /**
12549
12560
  * whether the connection has exhausted its retries — the **cumulative** snapshot, read
12550
12561
  * synchronously. (Formerly `hasConnectionError()`; renamed to disambiguate it from the
@@ -12787,6 +12798,49 @@ declare class TrueNasApi<D extends ApiDirectoryShape = BaseApiDirectory> {
12787
12798
  private initializeJobEventsSubscription;
12788
12799
  }
12789
12800
 
12801
+ /**
12802
+ * Response from the /api/versions endpoint
12803
+ * Returns an array of version strings directly
12804
+ * Example: ["v25.10.0", "v25.10.1", "v26.0.0"]
12805
+ */
12806
+ type ApiVersionResponse = string[];
12807
+ /**
12808
+ * Parsed API version information
12809
+ *
12810
+ * Version format:
12811
+ * - Legacy (v25.x): vYY.MM.PATCH (e.g., v25.10.0 = October 2025, patch 0)
12812
+ * - New (v26+): vYY.MINOR.PATCH (e.g., v26.0.0 = 2026, minor 0, patch 0)
12813
+ *
12814
+ * Note: The second segment has different semantics based on the year:
12815
+ * - Year 25: month (1-12)
12816
+ * - Year 26+: minor version (0-99)
12817
+ */
12818
+ interface ApiVersion {
12819
+ /** Full version string (e.g., "v26.0.0") */
12820
+ version: string;
12821
+ /** Two-digit year (e.g., 26 = 2026) */
12822
+ year: number;
12823
+ /**
12824
+ * Second version segment (semantics depend on year):
12825
+ * - For v25.x: month (1-12, e.g., 10 = October)
12826
+ * - For v26+: minor version (0-99)
12827
+ */
12828
+ minor: number;
12829
+ /** Patch version number (e.g., 0, 1, 2) */
12830
+ patch: number;
12831
+ /** WebSocket path for this version (e.g., "/api/v26.0.0") */
12832
+ websocketPath: string;
12833
+ }
12834
+ /**
12835
+ * Version compatibility status
12836
+ */
12837
+ declare enum VersionCompatibility {
12838
+ Compatible = "compatible",
12839
+ TooOld = "too-old",
12840
+ TooNew = "too-new",
12841
+ Invalid = "invalid"
12842
+ }
12843
+
12790
12844
  interface ApiKeyCreate {
12791
12845
  id: number;
12792
12846
  key: string;
@@ -12813,6 +12867,24 @@ interface AuthResponse {
12813
12867
  response_type: AuthResponseType;
12814
12868
  username?: string;
12815
12869
  authenticator?: 'LEVEL_1' | 'LEVEL_2' | 'LEVEL_3';
12870
+ /**
12871
+ * A token for re-authenticating without credentials.
12872
+ *
12873
+ * Absent below v26: `AuthRespSuccess` there declares only `response_type`,
12874
+ * `user_info` and `authenticator`. From v26 it is always present and is
12875
+ * `null` when no token was minted — because none was asked for, or because
12876
+ * the session cannot have one. Middleware refuses for a session authenticated
12877
+ * by a one-time *password* (`auth.generate_onetime_password`), which is not
12878
+ * the same thing as 2FA despite this codebase spelling 2FA "OTP" throughout.
12879
+ *
12880
+ * A 2FA account gets `null` for a different reason, and it is this client's
12881
+ * doing rather than the server's: the password request carrying the option is
12882
+ * answered `OTP_REQUIRED` before anything is minted, and `loginWithOtp` does
12883
+ * not send `login_options` on the second step. Middleware would honour it
12884
+ * there — `auth.login_ex_continue` re-enters `login_ex`, and a 2FA session
12885
+ * may hold a token — so this is a gap to close, not a limit to work around.
12886
+ */
12887
+ reconnect_token?: string | null;
12816
12888
  max_session_age?: number;
12817
12889
  max_inactivity?: number;
12818
12890
  urls?: string[];
@@ -12866,6 +12938,7 @@ interface AuthResponse {
12866
12938
  */
12867
12939
  declare class TrueNasAuthenticator {
12868
12940
  private connection;
12941
+ private readonly version?;
12869
12942
  static readonly DefaultSessionLifetime = 300;
12870
12943
  /**
12871
12944
  * whether or not the system is currently authenticated and accessible.
@@ -12885,9 +12958,54 @@ declare class TrueNasAuthenticator {
12885
12958
  key: string;
12886
12959
  };
12887
12960
  sessionLifetime: number;
12888
- constructor(connection: TrueNasConnection);
12961
+ constructor(connection: TrueNasConnection, version?: ApiVersion | undefined);
12962
+ /**
12963
+ * `login_options` asking for a reconnect token, when the server understands it.
12964
+ *
12965
+ * Omitted below v26. `AuthCommonOptions` is `additionalProperties: false`
12966
+ * there and has only `user_info`, so sending the member is a validation
12967
+ * error, not an ignored field — it would fail login outright on the oldest
12968
+ * version this client supports.
12969
+ */
12970
+ /**
12971
+ * Two things this does not do, both deliberate and both worth knowing.
12972
+ *
12973
+ * There is no way for a consumer to decline: every v26+ password login now
12974
+ * mints a single-use credential carrying that session's roles, whether or not
12975
+ * the caller wants one. And the auto-relogin in the constructor subscribes
12976
+ * with no observer, so the token it mints is dropped — a caller reconnecting
12977
+ * repeatedly holds an ageing token while the appliance mints fresh ones
12978
+ * nobody reads. Tokens are single-use with a 600s TTL, so that is the
12979
+ * reconnect case the feature is named for.
12980
+ */
12981
+ private reconnectTokenOption;
12889
12982
  loginWithUserPass(username: string, password: string): rxjs.Observable<AuthResponse>;
12890
12983
  loginWithOtp(code: string): rxjs.Observable<AuthResponse>;
12984
+ /**
12985
+ * Re-authenticate with a token from a previous login's `reconnect_token`.
12986
+ *
12987
+ * This is what lets a second connection to the same appliance authenticate
12988
+ * without asking the user for a password again — middleware sessions are
12989
+ * per-connection, so a second socket has its own to establish.
12990
+ *
12991
+ * The token is single-use and short-lived. On v26+ a successful login mints
12992
+ * another on the response, so a caller keeping a session alive across
12993
+ * reconnects stores the newest each time; below v26 nothing is minted and
12994
+ * there is no chain to keep.
12995
+ *
12996
+ * Re-login is the caller's to drive. A token session is not covered by the
12997
+ * automatic reconnect this class does for password and api-key sessions,
12998
+ * which is deliberate — the token is single-use — but it means a dropped
12999
+ * socket needs the stored token spending explicitly. Middleware holds tokens
13000
+ * in memory, so a `middlewared` restart voids them, and that is a common
13001
+ * reason the socket dropped in the first place.
13002
+ */
13003
+ loginWithToken(token: string): rxjs.Observable<AuthResponse>;
13004
+ /**
13005
+ * No reconnect token is requested here, though v26+ would mint one: an
13006
+ * api-key session already reconnects without a prompt, since the key is held
13007
+ * and replayed. The token exists for the credential that cannot be.
13008
+ */
12891
13009
  loginWithApiKey(credentials: {
12892
13010
  username: string;
12893
13011
  key: string;
@@ -12896,49 +13014,6 @@ declare class TrueNasAuthenticator {
12896
13014
  logout(): rxjs.Observable<boolean>;
12897
13015
  }
12898
13016
 
12899
- /**
12900
- * Response from the /api/versions endpoint
12901
- * Returns an array of version strings directly
12902
- * Example: ["v25.10.0", "v25.10.1", "v26.0.0"]
12903
- */
12904
- type ApiVersionResponse = string[];
12905
- /**
12906
- * Parsed API version information
12907
- *
12908
- * Version format:
12909
- * - Legacy (v25.x): vYY.MM.PATCH (e.g., v25.10.0 = October 2025, patch 0)
12910
- * - New (v26+): vYY.MINOR.PATCH (e.g., v26.0.0 = 2026, minor 0, patch 0)
12911
- *
12912
- * Note: The second segment has different semantics based on the year:
12913
- * - Year 25: month (1-12)
12914
- * - Year 26+: minor version (0-99)
12915
- */
12916
- interface ApiVersion {
12917
- /** Full version string (e.g., "v26.0.0") */
12918
- version: string;
12919
- /** Two-digit year (e.g., 26 = 2026) */
12920
- year: number;
12921
- /**
12922
- * Second version segment (semantics depend on year):
12923
- * - For v25.x: month (1-12, e.g., 10 = October)
12924
- * - For v26+: minor version (0-99)
12925
- */
12926
- minor: number;
12927
- /** Patch version number (e.g., 0, 1, 2) */
12928
- patch: number;
12929
- /** WebSocket path for this version (e.g., "/api/v26.0.0") */
12930
- websocketPath: string;
12931
- }
12932
- /**
12933
- * Version compatibility status
12934
- */
12935
- declare enum VersionCompatibility {
12936
- Compatible = "compatible",
12937
- TooOld = "too-old",
12938
- TooNew = "too-new",
12939
- Invalid = "invalid"
12940
- }
12941
-
12942
13017
  /**
12943
13018
  * The state `Container.status` is narrowed to.
12944
13019
  *
@@ -13192,7 +13267,8 @@ declare abstract class TrueNasApiClient<D extends ApiDirectoryShape = BaseApiDir
13192
13267
  protected readonly systemName: string | undefined;
13193
13268
  /** Logger forwarded to the connection (defaults to a no-op). */
13194
13269
  protected readonly logger: Logger;
13195
- constructor(uuid: string, hostnames: string[], version: ApiVersion, enabled: boolean, systemName?: string, logger?: Logger);
13270
+ protected readonly protocol: ApplianceProtocol;
13271
+ constructor(uuid: string, hostnames: string[], version: ApiVersion, enabled: boolean, systemName?: string, logger?: Logger, protocol?: ApplianceProtocol);
13196
13272
  /**
13197
13273
  * Get current connection status.
13198
13274
  * @returns true if WebSocket is connected
@@ -27604,6 +27680,28 @@ interface CreateClientOptions {
27604
27680
  * without the caller asserting it through a type parameter.
27605
27681
  */
27606
27682
  version?: SupportedApiVersion;
27683
+ /**
27684
+ * The scheme to reach the appliance on, in `location.protocol` form.
27685
+ *
27686
+ * Selects both halves of the transport: `https:` gives `https` discovery and
27687
+ * a `wss` socket, `http:` gives `http` and `ws`. Defaults to `https:`, which
27688
+ * is what an appliance serves and what Connect uses.
27689
+ *
27690
+ * This describes the *appliance*, not the page. Passing
27691
+ * `location.protocol` is correct when the appliance serves the page — the
27692
+ * same-origin case this exists for — and wrong otherwise. A page on
27693
+ * `http://localhost:5173` talking to an https appliance gets both halves
27694
+ * wrong, but only one of them says so: `fetch` follows the redirect and
27695
+ * discovery appears to work, while the WebSocket has no such tolerance and
27696
+ * fails the handshake without naming the scheme.
27697
+ *
27698
+ * Omitting it against a plaintext appliance is the quieter failure and the
27699
+ * likelier one, since it is the case this option exists for. Discovery tries
27700
+ * `https`, `fetch` rejects, and that is indistinguishable from the CORS block
27701
+ * v25.10.0 has on `/api/versions` — so the fallback fires and the caller gets
27702
+ * a client pinned to v25.10.0, warned about only in the log.
27703
+ */
27704
+ protocol?: ApplianceProtocol;
27607
27705
  }
27608
27706
  /**
27609
27707
  * Creates a version-specific TrueNAS API client.
@@ -27883,12 +27981,14 @@ declare class TrueNasApiClientV27 extends TrueNasApiClient<ApiDirectory> {
27883
27981
  */
27884
27982
  declare class VersionDiscovery {
27885
27983
  private readonly logger;
27984
+ private readonly protocol;
27886
27985
  private versionCache;
27887
- constructor(logger?: Logger);
27986
+ constructor(logger?: Logger, protocol?: ApplianceProtocol);
27987
+ private versionsUrl;
27888
27988
  /**
27889
27989
  * Discovers the API version for a given hostname.
27890
27990
  *
27891
- * Makes a GET request to `https://{hostname}/api/versions` and returns the latest
27991
+ * Makes a GET request to `{protocol}//{hostname}/api/versions` and returns the latest
27892
27992
  * compatible version. Results are cached per hostname; the cache entry is removed
27893
27993
  * on failure so the next call retries.
27894
27994
  *
@@ -28007,6 +28107,7 @@ declare enum AuthErrorCode {
28007
28107
  PasswordAuthFailed = "PASSWORD_AUTH_FAILED",
28008
28108
  OtpAuthFailed = "OTP_AUTH_FAILED",
28009
28109
  ApiKeyAuthFailed = "API_KEY_AUTH_FAILED",
28110
+ TokenAuthFailed = "TOKEN_AUTH_FAILED",
28010
28111
  FullAdminRequired = "FULL_ADMIN_REQUIRED"
28011
28112
  }
28012
28113
  declare class AuthError extends Error {
@@ -28067,4 +28168,4 @@ type ApiError = JsonRpcError | TrueNasError;
28067
28168
  */
28068
28169
  declare function getApiErrorMessage(error: unknown, fallback?: string): string;
28069
28170
 
28070
- export { type ApiCallDirectory$7 as ApiCallDirectoryV25_10_0, type ApiCallDirectory$6 as ApiCallDirectoryV25_10_1, type ApiCallDirectory$5 as ApiCallDirectoryV25_10_2, type ApiCallDirectory$4 as ApiCallDirectoryV25_10_3, type ApiCallDirectory$3 as ApiCallDirectoryV25_10_4, type ApiCallDirectory$2 as ApiCallDirectoryV25_10_5, type ApiCallDirectory$1 as ApiCallDirectoryV26_0_0, type ApiCallDirectory as ApiCallDirectoryV27_0_0, type ApiDirectoryByVersion, type ApiDirectoryShape, type ApiDirectory$7 as ApiDirectoryV25_10_0, type ApiDirectory$6 as ApiDirectoryV25_10_1, type ApiDirectory$5 as ApiDirectoryV25_10_2, type ApiDirectory$4 as ApiDirectoryV25_10_3, type ApiDirectory$3 as ApiDirectoryV25_10_4, type ApiDirectory$2 as ApiDirectoryV25_10_5, type ApiDirectory$1 as ApiDirectoryV26_0_0, type ApiDirectory as ApiDirectoryV27_0_0, type ApiError, type ApiEventDirectory$7 as ApiEventDirectoryV25_10_0, type ApiEventDirectory$6 as ApiEventDirectoryV25_10_1, type ApiEventDirectory$5 as ApiEventDirectoryV25_10_2, type ApiEventDirectory$4 as ApiEventDirectoryV25_10_3, type ApiEventDirectory$3 as ApiEventDirectoryV25_10_4, type ApiEventDirectory$2 as ApiEventDirectoryV25_10_5, type ApiEventDirectory$1 as ApiEventDirectoryV26_0_0, type ApiEventDirectory as ApiEventDirectoryV27_0_0, type ApiJobDirectory$7 as ApiJobDirectoryV25_10_0, type ApiJobDirectory$6 as ApiJobDirectoryV25_10_1, type ApiJobDirectory$5 as ApiJobDirectoryV25_10_2, type ApiJobDirectory$4 as ApiJobDirectoryV25_10_3, type ApiJobDirectory$3 as ApiJobDirectoryV25_10_4, type ApiJobDirectory$2 as ApiJobDirectoryV25_10_5, type ApiJobDirectory$1 as ApiJobDirectoryV26_0_0, type ApiJobDirectory as ApiJobDirectoryV27_0_0, type ApiKeyCreate, type ApiVersion, type ApiVersionResponse, AppState, type ArgsOf, AuthError, AuthErrorCode, type AuthResponse, type BaseApiDirectory, type CallMethod, type CallParams, type CallResponse, type Container, type CreateClientOptions, type DefaultApiDirectory, type EventKind, type EventName, type EventUnion, InvalidVersionResponseError, type Job, type JobMethod, type JobParams, type JobProgress, type JobResult, JobState, type Logger, NoCompatibleVersionsError, type OperationMappings, type QueryDirectory, type QueryEntity, type QueryListOptions, type QueryMethod, type QuerySingleOptions, SUPPORTED_API_VERSIONS, type SupportedApiVersion, TrueNasApiClient, TrueNasApiClientV2510, TrueNasApiClientV26, TrueNasApiClientV27, TrueNasAuthMechanism, type TrueNasDate, VersionCompatibility, VersionDiscovery, VersionDiscoveryError, VersionDiscoveryNetworkError, VersionDiscoveryTimeoutError, VersionEndpointNotFoundError, VersionTooNewError, VersionTooOldError, consoleLogger, createTrueNasClient, getApiErrorMessage, isJobFinished, noopLogger, index$7 as v25_10_0, index$6 as v25_10_1, index$5 as v25_10_2, index$4 as v25_10_3, index$3 as v25_10_4, index$2 as v25_10_5, index$1 as v26_0_0, index as v27_0_0 };
28171
+ export { type ApiCallDirectory$7 as ApiCallDirectoryV25_10_0, type ApiCallDirectory$6 as ApiCallDirectoryV25_10_1, type ApiCallDirectory$5 as ApiCallDirectoryV25_10_2, type ApiCallDirectory$4 as ApiCallDirectoryV25_10_3, type ApiCallDirectory$3 as ApiCallDirectoryV25_10_4, type ApiCallDirectory$2 as ApiCallDirectoryV25_10_5, type ApiCallDirectory$1 as ApiCallDirectoryV26_0_0, type ApiCallDirectory as ApiCallDirectoryV27_0_0, type ApiDirectoryByVersion, type ApiDirectoryShape, type ApiDirectory$7 as ApiDirectoryV25_10_0, type ApiDirectory$6 as ApiDirectoryV25_10_1, type ApiDirectory$5 as ApiDirectoryV25_10_2, type ApiDirectory$4 as ApiDirectoryV25_10_3, type ApiDirectory$3 as ApiDirectoryV25_10_4, type ApiDirectory$2 as ApiDirectoryV25_10_5, type ApiDirectory$1 as ApiDirectoryV26_0_0, type ApiDirectory as ApiDirectoryV27_0_0, type ApiError, type ApiEventDirectory$7 as ApiEventDirectoryV25_10_0, type ApiEventDirectory$6 as ApiEventDirectoryV25_10_1, type ApiEventDirectory$5 as ApiEventDirectoryV25_10_2, type ApiEventDirectory$4 as ApiEventDirectoryV25_10_3, type ApiEventDirectory$3 as ApiEventDirectoryV25_10_4, type ApiEventDirectory$2 as ApiEventDirectoryV25_10_5, type ApiEventDirectory$1 as ApiEventDirectoryV26_0_0, type ApiEventDirectory as ApiEventDirectoryV27_0_0, type ApiJobDirectory$7 as ApiJobDirectoryV25_10_0, type ApiJobDirectory$6 as ApiJobDirectoryV25_10_1, type ApiJobDirectory$5 as ApiJobDirectoryV25_10_2, type ApiJobDirectory$4 as ApiJobDirectoryV25_10_3, type ApiJobDirectory$3 as ApiJobDirectoryV25_10_4, type ApiJobDirectory$2 as ApiJobDirectoryV25_10_5, type ApiJobDirectory$1 as ApiJobDirectoryV26_0_0, type ApiJobDirectory as ApiJobDirectoryV27_0_0, type ApiKeyCreate, type ApiVersion, type ApiVersionResponse, AppState, type ApplianceProtocol, type ArgsOf, AuthError, AuthErrorCode, type AuthResponse, type BaseApiDirectory, type CallMethod, type CallParams, type CallResponse, type Container, type CreateClientOptions, type DefaultApiDirectory, type EventKind, type EventName, type EventUnion, InvalidVersionResponseError, type Job, type JobMethod, type JobParams, type JobProgress, type JobResult, JobState, type Logger, NoCompatibleVersionsError, type OperationMappings, type QueryDirectory, type QueryEntity, type QueryListOptions, type QueryMethod, type QuerySingleOptions, SUPPORTED_API_VERSIONS, type SupportedApiVersion, TrueNasApiClient, TrueNasApiClientV2510, TrueNasApiClientV26, TrueNasApiClientV27, TrueNasAuthMechanism, type TrueNasDate, VersionCompatibility, VersionDiscovery, VersionDiscoveryError, VersionDiscoveryNetworkError, VersionDiscoveryTimeoutError, VersionEndpointNotFoundError, VersionTooNewError, VersionTooOldError, consoleLogger, createTrueNasClient, getApiErrorMessage, isJobFinished, noopLogger, index$7 as v25_10_0, index$6 as v25_10_1, index$5 as v25_10_2, index$4 as v25_10_3, index$3 as v25_10_4, index$2 as v25_10_5, index$1 as v26_0_0, index as v27_0_0 };