@dinoconfig/js-sdk 1.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.
@@ -0,0 +1,174 @@
1
+ import { HttpClient } from './http-client';
2
+ import { ApiResponse, RequestOptions } from './types';
3
+ /**
4
+ * Information about a brand in DinoConfig.
5
+ */
6
+ export interface BrandInfo {
7
+ readonly name: string;
8
+ readonly description?: string;
9
+ readonly configCount: number;
10
+ readonly createdAt: Date;
11
+ }
12
+ /**
13
+ * Information about a configuration in DinoConfig.
14
+ */
15
+ export interface ConfigInfo {
16
+ readonly name: string;
17
+ readonly description?: string;
18
+ readonly keys: readonly string[];
19
+ readonly version: number;
20
+ readonly createdAt: Date;
21
+ }
22
+ /** Supported field types in DinoConfig schemas */
23
+ export type FieldType = 'string' | 'number' | 'boolean' | 'object' | 'array';
24
+ /**
25
+ * Validation rules for a configuration field.
26
+ */
27
+ export interface FieldValidation {
28
+ readonly min?: number;
29
+ readonly max?: number;
30
+ readonly minLength?: number;
31
+ readonly maxLength?: number;
32
+ readonly pattern?: string;
33
+ readonly enum?: readonly unknown[];
34
+ }
35
+ /**
36
+ * Schema definition for a configuration field.
37
+ */
38
+ export interface FieldSchema {
39
+ readonly type: FieldType;
40
+ readonly description?: string;
41
+ readonly defaultValue?: unknown;
42
+ readonly required?: boolean;
43
+ readonly validation?: FieldValidation;
44
+ }
45
+ /**
46
+ * Complete schema for a configuration.
47
+ */
48
+ export interface ConfigSchema {
49
+ readonly configName: string;
50
+ readonly version: number;
51
+ readonly fields: Readonly<Record<string, FieldSchema>>;
52
+ }
53
+ /**
54
+ * Key information with type and value.
55
+ */
56
+ export interface KeyInfo {
57
+ readonly name: string;
58
+ readonly type: string;
59
+ readonly value: unknown;
60
+ }
61
+ /**
62
+ * Configuration information with key details.
63
+ */
64
+ export interface ConfigInfoDetail {
65
+ readonly name: string;
66
+ readonly description?: string;
67
+ readonly keys: readonly KeyInfo[];
68
+ readonly version: number;
69
+ }
70
+ /**
71
+ * Brand information with config details.
72
+ */
73
+ export interface BrandInfoDetail {
74
+ readonly name: string;
75
+ readonly description?: string;
76
+ readonly configs: readonly ConfigInfoDetail[];
77
+ }
78
+ /**
79
+ * Full introspection result containing all brands, configs, and keys.
80
+ */
81
+ export interface IntrospectionResult {
82
+ readonly company: string;
83
+ readonly brands: readonly BrandInfoDetail[];
84
+ readonly generatedAt: Date;
85
+ }
86
+ /**
87
+ * Discovery API class for interacting with DinoConfig discovery endpoints.
88
+ *
89
+ * @class DiscoveryAPI
90
+ * @example
91
+ * ```typescript
92
+ * const dinoconfig = await dinoconfigApi({ apiKey: 'dino_...' });
93
+ *
94
+ * // List all brands
95
+ * const brands = await dinoconfig.discovery.listBrands();
96
+ *
97
+ * // List configs for a brand
98
+ * const configs = await dinoconfig.discovery.listConfigs('MyBrand');
99
+ *
100
+ * // Get config schema
101
+ * const schema = await dinoconfig.discovery.getSchema('MyBrand', 'FeatureFlags');
102
+ * ```
103
+ */
104
+ export declare class DiscoveryAPI {
105
+ private readonly httpClient;
106
+ constructor(httpClient: HttpClient);
107
+ /**
108
+ * Lists all brands accessible by the current API key.
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * const response = await dinoconfig.discovery.listBrands();
113
+ * response.data.forEach(brand => {
114
+ * console.log(`${brand.name}: ${brand.configCount} configs`);
115
+ * });
116
+ * ```
117
+ */
118
+ listBrands(options?: RequestOptions): Promise<ApiResponse<BrandInfo[]>>;
119
+ /**
120
+ * Lists all configurations for a specific brand.
121
+ *
122
+ * @example
123
+ * ```typescript
124
+ * const response = await dinoconfig.discovery.listConfigs('MyBrand');
125
+ * response.data.forEach(config => {
126
+ * console.log(`${config.name}: ${config.keys.length} keys`);
127
+ * });
128
+ * ```
129
+ */
130
+ listConfigs(brandName: string, options?: RequestOptions): Promise<ApiResponse<ConfigInfo[]>>;
131
+ /**
132
+ * Gets the schema/structure for a specific configuration.
133
+ *
134
+ * @example
135
+ * ```typescript
136
+ * const response = await dinoconfig.discovery.getSchema('MyBrand', 'FeatureFlags');
137
+ * Object.entries(response.data.fields).forEach(([name, field]) => {
138
+ * console.log(`${name}: ${field.type}`);
139
+ * });
140
+ * ```
141
+ */
142
+ getSchema(brandName: string, configName: string, options?: RequestOptions): Promise<ApiResponse<ConfigSchema>>;
143
+ /**
144
+ * Performs full introspection, returning all brands, configs, and keys.
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * const response = await dinoconfig.discovery.introspect();
149
+ * response.data.brands.forEach(brand => {
150
+ * console.log(`Brand: ${brand.name}`);
151
+ * brand.configs.forEach(config => {
152
+ * console.log(` Config: ${config.name} (${config.keys.length} keys)`);
153
+ * });
154
+ * });
155
+ * ```
156
+ */
157
+ introspect(options?: RequestOptions): Promise<ApiResponse<IntrospectionResult>>;
158
+ /**
159
+ * Builds URL path for brand-level endpoints.
160
+ */
161
+ private buildBrandUrl;
162
+ /**
163
+ * Builds URL path for config-level endpoints.
164
+ */
165
+ private buildConfigUrl;
166
+ /**
167
+ * URL-encodes a path segment.
168
+ */
169
+ private encode;
170
+ /**
171
+ * Extracts and transforms response data.
172
+ */
173
+ private extractData;
174
+ }
@@ -0,0 +1,245 @@
1
+ import { ApiResponse, RequestOptions } from './types';
2
+ /**
3
+ * HTTP client for making requests to the DinoConfig API.
4
+ *
5
+ * This class handles:
6
+ * - API key to token exchange
7
+ * - Authorization header management
8
+ * - Request/response formatting
9
+ * - Timeout handling
10
+ * - Retry logic with exponential backoff
11
+ *
12
+ * @class HttpClient
13
+ * @internal This class is used internally by the SDK
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * // Internal usage - not typically used directly
18
+ * const client = new HttpClient('https://api.dinoconfig.com', 10000);
19
+ * await client.configureAuthorizationHeader({ 'X-API-Key': 'dino_...' });
20
+ * const response = await client.get('/api/endpoint');
21
+ * ```
22
+ */
23
+ export declare class HttpClient {
24
+ /**
25
+ * Base URL for all API requests.
26
+ * @private
27
+ */
28
+ private baseUrl;
29
+ /**
30
+ * Default timeout for requests in milliseconds.
31
+ * @private
32
+ */
33
+ private defaultTimeout;
34
+ /**
35
+ * Default headers included in every request.
36
+ * @private
37
+ */
38
+ private defaultHeaders;
39
+ /**
40
+ * Creates a new HttpClient instance.
41
+ *
42
+ * @param {string} baseUrl - The base URL of the DinoConfig API
43
+ * @param {number} [timeout=10000] - Default request timeout in milliseconds
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const client = new HttpClient('https://api.dinoconfig.com', 15000);
48
+ * ```
49
+ */
50
+ constructor(baseUrl: string, timeout?: number);
51
+ /**
52
+ * Configures authorization by exchanging the API key for an access token.
53
+ *
54
+ * This method:
55
+ * 1. Extracts the API key from the provided headers
56
+ * 2. Exchanges it for a JWT access token
57
+ * 3. Configures the Authorization header for subsequent requests
58
+ *
59
+ * @async
60
+ * @method configureAuthorizationHeader
61
+ * @param {Record<string, string>} headers - Headers containing the X-API-Key
62
+ * @returns {Promise<void>}
63
+ * @throws {Error} If token exchange fails
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * await client.configureAuthorizationHeader({
68
+ * 'X-API-Key': 'dino_your-api-key-here'
69
+ * });
70
+ * // Client is now authenticated
71
+ * ```
72
+ */
73
+ configureAuthorizationHeader(headers: Record<string, string>): Promise<void>;
74
+ /**
75
+ * Exchanges an API key for a JWT access token.
76
+ *
77
+ * Makes a POST request to the token exchange endpoint with the API key
78
+ * and returns the access token from the response.
79
+ *
80
+ * @async
81
+ * @private
82
+ * @method exchangeApiKeyForToken
83
+ * @param {string} apiKey - The API key to exchange
84
+ * @returns {Promise<string>} The JWT access token
85
+ * @throws {Error} If the exchange fails or the API key is invalid
86
+ *
87
+ * @remarks
88
+ * The API key is sent via HTTPS, which encrypts it in transit.
89
+ * The server validates the key and returns a short-lived access token.
90
+ */
91
+ private exchangeApiKeyForToken;
92
+ /**
93
+ * Makes an HTTP request to the API.
94
+ *
95
+ * Handles:
96
+ * - Request formatting and headers
97
+ * - Timeout via AbortController
98
+ * - Response parsing
99
+ * - Error handling
100
+ * - Retry logic with exponential backoff
101
+ *
102
+ * @async
103
+ * @private
104
+ * @method request
105
+ * @typeParam T - The expected response data type
106
+ * @param {string} method - HTTP method (GET, POST, PUT, PATCH, DELETE)
107
+ * @param {string} endpoint - API endpoint path (e.g., '/api/configs')
108
+ * @param {any} [data] - Request body data (for POST, PUT, PATCH)
109
+ * @param {RequestOptions} [options={}] - Request customization options
110
+ * @returns {Promise<ApiResponse<T>>} The API response
111
+ * @throws {ApiError} If the request fails after all retries
112
+ */
113
+ private request;
114
+ /**
115
+ * Makes a GET request to the specified endpoint.
116
+ *
117
+ * @async
118
+ * @method get
119
+ * @typeParam T - The expected response data type
120
+ * @param {string} endpoint - The API endpoint path
121
+ * @param {RequestOptions} [options] - Optional request configuration
122
+ * @returns {Promise<ApiResponse<T>>} The API response
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * const response = await client.get<Config>('/api/configs/123');
127
+ * console.log(response.data.name);
128
+ * ```
129
+ */
130
+ get<T>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>>;
131
+ /**
132
+ * Makes a POST request to the specified endpoint.
133
+ *
134
+ * @async
135
+ * @method post
136
+ * @typeParam T - The expected response data type
137
+ * @param {string} endpoint - The API endpoint path
138
+ * @param {any} [data] - The request body data
139
+ * @param {RequestOptions} [options] - Optional request configuration
140
+ * @returns {Promise<ApiResponse<T>>} The API response
141
+ *
142
+ * @example
143
+ * ```typescript
144
+ * const response = await client.post<Config>('/api/configs', {
145
+ * name: 'NewConfig',
146
+ * formData: { key: 'value' }
147
+ * });
148
+ * ```
149
+ */
150
+ post<T>(endpoint: string, data?: any, options?: RequestOptions): Promise<ApiResponse<T>>;
151
+ /**
152
+ * Makes a PUT request to the specified endpoint.
153
+ *
154
+ * @async
155
+ * @method put
156
+ * @typeParam T - The expected response data type
157
+ * @param {string} endpoint - The API endpoint path
158
+ * @param {any} [data] - The request body data
159
+ * @param {RequestOptions} [options] - Optional request configuration
160
+ * @returns {Promise<ApiResponse<T>>} The API response
161
+ *
162
+ * @example
163
+ * ```typescript
164
+ * const response = await client.put<Config>('/api/configs/123', {
165
+ * name: 'UpdatedConfig'
166
+ * });
167
+ * ```
168
+ */
169
+ put<T>(endpoint: string, data?: any, options?: RequestOptions): Promise<ApiResponse<T>>;
170
+ /**
171
+ * Makes a PATCH request to the specified endpoint.
172
+ *
173
+ * @async
174
+ * @method patch
175
+ * @typeParam T - The expected response data type
176
+ * @param {string} endpoint - The API endpoint path
177
+ * @param {any} [data] - The request body data (partial update)
178
+ * @param {RequestOptions} [options] - Optional request configuration
179
+ * @returns {Promise<ApiResponse<T>>} The API response
180
+ *
181
+ * @example
182
+ * ```typescript
183
+ * const response = await client.patch<Config>('/api/configs/123', {
184
+ * formData: { updatedKey: 'newValue' }
185
+ * });
186
+ * ```
187
+ */
188
+ patch<T>(endpoint: string, data?: any, options?: RequestOptions): Promise<ApiResponse<T>>;
189
+ /**
190
+ * Makes a DELETE request to the specified endpoint.
191
+ *
192
+ * @async
193
+ * @method delete
194
+ * @typeParam T - The expected response data type
195
+ * @param {string} endpoint - The API endpoint path
196
+ * @param {RequestOptions} [options] - Optional request configuration
197
+ * @returns {Promise<ApiResponse<T>>} The API response
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * const response = await client.delete('/api/configs/123');
202
+ * ```
203
+ */
204
+ delete<T>(endpoint: string, options?: RequestOptions): Promise<ApiResponse<T>>;
205
+ /**
206
+ * Updates the authorization token.
207
+ *
208
+ * Use this method if you need to manually update the token
209
+ * (e.g., after refreshing it externally).
210
+ *
211
+ * @method setToken
212
+ * @param {string} token - The new JWT access token
213
+ *
214
+ * @example
215
+ * ```typescript
216
+ * client.setToken('new-jwt-token');
217
+ * ```
218
+ */
219
+ setToken(token: string): void;
220
+ /**
221
+ * Sets a custom header for all subsequent requests.
222
+ *
223
+ * @method setHeader
224
+ * @param {string} key - The header name
225
+ * @param {string} value - The header value
226
+ *
227
+ * @example
228
+ * ```typescript
229
+ * client.setHeader('X-Custom-Header', 'custom-value');
230
+ * ```
231
+ */
232
+ setHeader(key: string, value: string): void;
233
+ /**
234
+ * Removes a custom header from subsequent requests.
235
+ *
236
+ * @method removeHeader
237
+ * @param {string} key - The header name to remove
238
+ *
239
+ * @example
240
+ * ```typescript
241
+ * client.removeHeader('X-Custom-Header');
242
+ * ```
243
+ */
244
+ removeHeader(key: string): void;
245
+ }