@technomoron/apicore-client 1.0.0-beta.1

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.
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Copyright (c) 2025 Bjørn Erik Jacobsen / Technomoron
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ export type maybeFile = File | Blob | [string, File | Blob];
8
+ type JsonPrimitive = string | number | boolean | null;
9
+ type JsonValue = JsonPrimitive | JsonValue[] | {
10
+ [key: string]: JsonValue;
11
+ };
12
+ type SerializableBody = JsonValue;
13
+ export interface ApiResponseData<T = unknown> {
14
+ success: boolean;
15
+ code: number;
16
+ message: string;
17
+ data: T | null;
18
+ errors: Record<string, string>;
19
+ }
20
+ export type SafeUser = Record<string, unknown>;
21
+ export type AuthIdentifier = string | number;
22
+ export interface PingResponseData {
23
+ success: boolean;
24
+ status: string;
25
+ apiVersion: string;
26
+ minClientVersion: string;
27
+ uptimeSec: number;
28
+ startedAt: string;
29
+ timestamp: string;
30
+ }
31
+ export interface ApiClientConfig {
32
+ apiKey?: string | null;
33
+ timeout?: number;
34
+ maxRetries?: number;
35
+ debug?: boolean;
36
+ enableTokens?: boolean;
37
+ }
38
+ /**
39
+ * Authentication token response shape
40
+ */
41
+ export interface AuthTokenData<User = SafeUser> {
42
+ accessToken?: string;
43
+ refreshToken?: string;
44
+ user?: User;
45
+ }
46
+ export interface WhoAmIResponseData<User = SafeUser, UserId extends AuthIdentifier = AuthIdentifier> {
47
+ user: User;
48
+ isImpersonating: boolean;
49
+ realUser?: User | null;
50
+ realUserId?: UserId | null;
51
+ }
52
+ export interface LogoutResponseData {
53
+ revoked: number;
54
+ }
55
+ export declare class ApiResponse<T = unknown> implements ApiResponseData<T> {
56
+ success: boolean;
57
+ code: number;
58
+ message: string;
59
+ data: T | null;
60
+ errors: Record<string, string>;
61
+ constructor(response?: Partial<ApiResponseData<T>>);
62
+ /**
63
+ * Creates a successful response with the provided data
64
+ * @param {T} data - The response data
65
+ * @param {Partial<ApiResponseData<T>>} overrides - Optional overrides for response properties
66
+ * @returns {ApiResponse<T>} A configured successful response
67
+ */
68
+ static ok<T>(data: T, overrides?: Partial<Omit<ApiResponseData<T>, 'data'>>): ApiResponse<T>;
69
+ /**
70
+ * Creates an error response with the provided message
71
+ * @param {unknown} messageOrError - The error message, error object, or existing ApiResponse
72
+ * @param {Partial<ApiResponseData<T>>} overrides - Optional overrides for response properties
73
+ * @returns {ApiResponse<T>} A configured error response
74
+ */
75
+ static error<T>(messageOrError: unknown, overrides?: Partial<Omit<ApiResponseData<T>, 'data'>>): ApiResponse<T>;
76
+ /**
77
+ * Adds a named error to the errors collection
78
+ * @param {string} name - The name/key for the error
79
+ * @param {string} value - The error message
80
+ */
81
+ addError(name: string, value: string): void;
82
+ /**
83
+ * Type guard to check if the response is successful and contains data
84
+ * When this returns true, TypeScript narrows the type to ensure data is not null
85
+ * @returns {boolean} True if the response is successful and contains data
86
+ */
87
+ isSuccess(): this is ApiResponse<T> & {
88
+ data: T;
89
+ };
90
+ }
91
+ declare class ApiClient {
92
+ private apiKey;
93
+ private aToken;
94
+ private rToken;
95
+ private apiUrl;
96
+ private _refreshPromise;
97
+ private timeoutMs;
98
+ private maxRetries;
99
+ private debug;
100
+ private tokens;
101
+ constructor(apiUrl: string, config?: ApiClientConfig);
102
+ /**
103
+ * Updates the client configuration
104
+ * @param {Partial<ApiClientConfig>} config - Configuration updates
105
+ */
106
+ configure(config: Partial<ApiClientConfig>): void;
107
+ /**
108
+ * Gets the current configuration
109
+ * @returns {ApiClientConfig} Current configuration
110
+ */
111
+ getConfig(): ApiClientConfig;
112
+ private tryStringify;
113
+ /**
114
+ * Retrieves the stored access token
115
+ * Designed to be overridden in subclasses for custom token storage
116
+ * @returns {string|null} The current access token or null if not set
117
+ */
118
+ get_access_token(): string | null;
119
+ /**
120
+ * Stores the access token
121
+ * Designed to be overridden in subclasses for custom token storage
122
+ * @param {string|null} access - The access token to store, or null to clear
123
+ */
124
+ set_access_token(access: string | null): void;
125
+ /**
126
+ * Retrieves the stored refresh token
127
+ * Designed to be overridden in subclasses for custom token storage
128
+ * @returns {string|null} The current refresh token or null if not set
129
+ */
130
+ get_refresh_token(): string | null;
131
+ /**
132
+ * Stores the refresh token
133
+ * Designed to be overridden in subclasses for custom token storage
134
+ * @param {string|null} refresh - The refresh token to store, or null to clear
135
+ */
136
+ set_refresh_token(refresh: string | null): void;
137
+ /**
138
+ * Sets the API key for authentication
139
+ * Designed to be overridden in subclasses for custom API key storage
140
+ * @param {string|null} apikey - The API key to use for authentication, or null to clear
141
+ */
142
+ set_apikey(apikey: string | null): void;
143
+ /**
144
+ * Retrieves the stored API key
145
+ * Designed to be overridden in subclasses for custom API key storage
146
+ * @returns {string|null} The current API key or null if not set
147
+ */
148
+ get_apikey(): string | null;
149
+ /**
150
+ * Builds authentication headers based on current configuration
151
+ * @returns {Record<string, string>} Headers object with authentication if available
152
+ */
153
+ private buildAuthHeaders;
154
+ /**
155
+ * A drop‑in replacement for fetch() that handles timeouts and
156
+ * normalized network errors and throws an ApiResponse on failure.
157
+ * Uses the instance's configured timeout value.
158
+ */
159
+ private safeFetch;
160
+ /**
161
+ * Safely parses JSON response with proper error handling
162
+ * @param {Response} response - The fetch response
163
+ * @returns {Promise<RawApiResponse<T>>} The parsed JSON data
164
+ */
165
+ private parseJsonResponse;
166
+ login<T = AuthTokenData>(username: string, password: string, domain?: string, fingerprint?: string): Promise<ApiResponse<T>>;
167
+ logout<T = LogoutResponseData>(token?: string): Promise<ApiResponse<T>>;
168
+ private refreshAccessToken;
169
+ private performRefresh;
170
+ private fetchWithRetry;
171
+ /**
172
+ * Performs a generic HTTP request to the API
173
+ * @param {'GET'|'POST'|'PUT'|'DELETE'} method - The HTTP method to use
174
+ * @param {string} command - The API endpoint path
175
+ * @param {SerializableBody} [body] - Optional request body (for POST/PUT/DELETE requests)
176
+ * @returns {Promise<ApiResponse<T>>} A promise resolving to the API response
177
+ * @template T - The expected type of the response data
178
+ */
179
+ request<T>(method: 'GET' | 'POST' | 'PUT' | 'DELETE', command: string, body?: SerializableBody, files?: maybeFile[]): Promise<ApiResponse<T>>;
180
+ get<T>(command: string): Promise<ApiResponse<T>>;
181
+ post<T>(command: string, body?: SerializableBody, files?: maybeFile[]): Promise<ApiResponse<T>>;
182
+ put<T>(command: string, body?: SerializableBody): Promise<ApiResponse<T>>;
183
+ delete<T>(command: string, body?: SerializableBody): Promise<ApiResponse<T>>;
184
+ ping(): Promise<ApiResponse<PingResponseData>>;
185
+ }
186
+ export default ApiClient;