@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.
- package/CHANGELOG.md +38 -0
- package/LICENSE +21 -0
- package/README.md +743 -0
- package/index.d.ts +88 -0
- package/index.js +883 -0
- package/lib/cache/cache-manager.d.ts +86 -0
- package/lib/cache/cache.types.d.ts +105 -0
- package/lib/cache/index.d.ts +8 -0
- package/lib/cache/memory-cache.d.ts +86 -0
- package/lib/cache/storage-cache.d.ts +58 -0
- package/lib/config-api.d.ts +111 -0
- package/lib/dinoconfig-js-sdk.d.ts +140 -0
- package/lib/discovery-api.d.ts +174 -0
- package/lib/http-client.d.ts +245 -0
- package/lib/types.d.ts +364 -0
- package/package.json +77 -0
|
@@ -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
|
+
}
|