opensecureconf-client 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/LICENSE +21 -0
- package/README.md +297 -0
- package/dist/index.d.mts +72 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.js +167 -0
- package/dist/index.mjs +141 -0
- package/package.json +68 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Alessandro Pioli
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
# OpenSecureConf JavaScript/TypeScript Client
|
|
2
|
+
|
|
3
|
+
JavaScript/TypeScript client library for [OpenSecureConf](https://github.com/yourusername/OpenSecureConf) - A secure, encrypted configuration management system with REST API.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/opensecureconf-client)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Features
|
|
9
|
+
|
|
10
|
+
- ๐ **Encrypted Configuration Management** - Create, read, update, and delete encrypted configurations
|
|
11
|
+
- ๐ **REST API Client** - Full-featured client for OpenSecureConf REST API
|
|
12
|
+
- ๐ฆ **TypeScript Support** - Written in TypeScript with full type definitions
|
|
13
|
+
- ๐ **Cluster Support** - Works with both REPLICA and FEDERATED cluster modes
|
|
14
|
+
- โก **Async/Await** - Modern promise-based API
|
|
15
|
+
- ๐ก๏ธ **Error Handling** - Comprehensive error handling with custom error types
|
|
16
|
+
- โฑ๏ธ **Timeout Control** - Configurable request timeouts
|
|
17
|
+
- ๐งช **Well Tested** - Comprehensive test suite with Jest
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install opensecureconf-client
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Quick Start
|
|
26
|
+
|
|
27
|
+
### JavaScript (CommonJS)
|
|
28
|
+
|
|
29
|
+
```javascript
|
|
30
|
+
const { OpenSecureConfClient } = require('opensecureconf-client');
|
|
31
|
+
|
|
32
|
+
const client = new OpenSecureConfClient({
|
|
33
|
+
baseUrl: 'http://localhost:9000',
|
|
34
|
+
userKey: 'my-secure-encryption-key',
|
|
35
|
+
apiKey: 'your-api-key', // Optional
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Create a configuration
|
|
39
|
+
await client.create('my-config', { setting: 'value' }, 'category');
|
|
40
|
+
|
|
41
|
+
// Read a configuration
|
|
42
|
+
const config = await client.read('my-config');
|
|
43
|
+
console.log(config.value); // { setting: 'value' }
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### TypeScript (ES Modules)
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import OpenSecureConfClient from 'opensecureconf-client';
|
|
50
|
+
|
|
51
|
+
const client = new OpenSecureConfClient({
|
|
52
|
+
baseUrl: 'http://localhost:9000',
|
|
53
|
+
userKey: 'my-secure-encryption-key',
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const config = await client.read('my-config');
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## API Reference
|
|
60
|
+
|
|
61
|
+
### Methods
|
|
62
|
+
|
|
63
|
+
- `create(key, value, category?)` - Create new configuration
|
|
64
|
+
- `read(key)` - Read configuration by key
|
|
65
|
+
- `update(key, value, category?)` - Update configuration
|
|
66
|
+
- `delete(key)` - Delete configuration
|
|
67
|
+
- `list(category?)` - List all configurations
|
|
68
|
+
- `getClusterStatus()` - Get cluster status
|
|
69
|
+
- `healthCheck()` - Perform health check
|
|
70
|
+
- `getMetrics()` - Get Prometheus metrics
|
|
71
|
+
- `getInfo()` - Get API information
|
|
72
|
+
|
|
73
|
+
## Error Handling
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { OpenSecureConfError } from 'opensecureconf-client';
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
await client.read('non-existent-key');
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (error instanceof OpenSecureConfError) {
|
|
82
|
+
console.error(`Error ${error.statusCode}: ${error.message}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Development
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npm install # Install dependencies
|
|
91
|
+
npm run build # Build for production
|
|
92
|
+
npm test # Run tests
|
|
93
|
+
npm run lint # Lint code
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT ยฉ OpenSecureConf Contributors
|
|
99
|
+
"
|
|
100
|
+
tests/client.test.ts,"import { OpenSecureConfClient, OpenSecureConfError } from '../src/index';
|
|
101
|
+
|
|
102
|
+
describe('OpenSecureConfClient', () => {
|
|
103
|
+
let client: OpenSecureConfClient;
|
|
104
|
+
|
|
105
|
+
beforeEach(() => {
|
|
106
|
+
client = new OpenSecureConfClient({
|
|
107
|
+
baseUrl: 'http://localhost:9000',
|
|
108
|
+
userKey: 'test-user-key-12345',
|
|
109
|
+
apiKey: 'your-super-secret-api-key-here',
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
describe('constructor', () => {
|
|
114
|
+
it('should create client with valid options', () => {
|
|
115
|
+
expect(client).toBeInstanceOf(OpenSecureConfClient);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it('should throw error if userKey is too short', () => {
|
|
119
|
+
expect(() => {
|
|
120
|
+
new OpenSecureConfClient({
|
|
121
|
+
baseUrl: 'http://localhost:9000',
|
|
122
|
+
userKey: 'short',
|
|
123
|
+
});
|
|
124
|
+
}).toThrow('userKey must be at least 8 characters long');
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
describe('CRUD operations', () => {
|
|
129
|
+
const testKey = 'test-config-key';
|
|
130
|
+
const testValue = { setting: 'value', number: 42 };
|
|
131
|
+
|
|
132
|
+
it('should create a configuration', async () => {
|
|
133
|
+
const result = await client.create(testKey, testValue, 'test-category');
|
|
134
|
+
expect(result).toHaveProperty('key', testKey);
|
|
135
|
+
expect(result).toHaveProperty('value');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should read a configuration', async () => {
|
|
139
|
+
const result = await client.read(testKey);
|
|
140
|
+
expect(result).toHaveProperty('key', testKey);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should list configurations', async () => {
|
|
144
|
+
const result = await client.list();
|
|
145
|
+
expect(Array.isArray(result)).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should delete a configuration', async () => {
|
|
149
|
+
const result = await client.delete(testKey);
|
|
150
|
+
expect(result).toHaveProperty('message');
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
"
|
|
155
|
+
examples/basic-usage.js,"/**
|
|
156
|
+
* Basic usage example for OpenSecureConf JavaScript Client
|
|
157
|
+
*/
|
|
158
|
+
|
|
159
|
+
const { OpenSecureConfClient } = require('opensecureconf-client');
|
|
160
|
+
|
|
161
|
+
async function main() {
|
|
162
|
+
// Initialize the client
|
|
163
|
+
const client = new OpenSecureConfClient({
|
|
164
|
+
baseUrl: 'http://localhost:9000',
|
|
165
|
+
userKey: 'my-secure-encryption-key',
|
|
166
|
+
apiKey: 'your-super-secret-api-key-here', // Optional
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
try {
|
|
170
|
+
// Create a new configuration
|
|
171
|
+
const created = await client.create(
|
|
172
|
+
'database-config',
|
|
173
|
+
{
|
|
174
|
+
host: 'localhost',
|
|
175
|
+
port: 5432,
|
|
176
|
+
database: 'myapp',
|
|
177
|
+
ssl: true,
|
|
178
|
+
},
|
|
179
|
+
'database'
|
|
180
|
+
);
|
|
181
|
+
console.log('Created:', created);
|
|
182
|
+
|
|
183
|
+
// Read a configuration
|
|
184
|
+
const config = await client.read('database-config');
|
|
185
|
+
console.log('Read:', config);
|
|
186
|
+
|
|
187
|
+
// List all configurations
|
|
188
|
+
const all = await client.list();
|
|
189
|
+
console.log('All configs:', all.length);
|
|
190
|
+
|
|
191
|
+
// Delete a configuration
|
|
192
|
+
await client.delete('database-config');
|
|
193
|
+
console.log('Deleted successfully');
|
|
194
|
+
|
|
195
|
+
} catch (error) {
|
|
196
|
+
if (error.name === 'OpenSecureConfError') {
|
|
197
|
+
console.error('API Error:', error.statusCode, error.message);
|
|
198
|
+
} else {
|
|
199
|
+
console.error('Error:', error);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
main();
|
|
205
|
+
"
|
|
206
|
+
examples/advanced-usage.ts,"/**
|
|
207
|
+
* Advanced usage example with TypeScript
|
|
208
|
+
*/
|
|
209
|
+
|
|
210
|
+
import OpenSecureConfClient, {
|
|
211
|
+
ConfigEntry,
|
|
212
|
+
OpenSecureConfError,
|
|
213
|
+
} from 'opensecureconf-client';
|
|
214
|
+
|
|
215
|
+
interface DatabaseConfig {
|
|
216
|
+
host: string;
|
|
217
|
+
port: number;
|
|
218
|
+
database: string;
|
|
219
|
+
ssl: boolean;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
class ConfigManager {
|
|
223
|
+
private client: OpenSecureConfClient;
|
|
224
|
+
|
|
225
|
+
constructor(baseUrl: string, userKey: string, apiKey?: string) {
|
|
226
|
+
this.client = new OpenSecureConfClient({
|
|
227
|
+
baseUrl,
|
|
228
|
+
userKey,
|
|
229
|
+
apiKey,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async getDatabaseConfig(key: string): Promise<DatabaseConfig> {
|
|
234
|
+
const config = await this.client.read(key);
|
|
235
|
+
return config.value as DatabaseConfig;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async setDatabaseConfig(key: string, config: DatabaseConfig): Promise<void> {
|
|
239
|
+
await this.client.create(key, config as Record<string, any>, 'database');
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async withRetry<T>(
|
|
243
|
+
operation: () => Promise<T>,
|
|
244
|
+
maxRetries: number = 3
|
|
245
|
+
): Promise<T> {
|
|
246
|
+
let lastError: Error | undefined;
|
|
247
|
+
|
|
248
|
+
for (let i = 0; i < maxRetries; i++) {
|
|
249
|
+
try {
|
|
250
|
+
return await operation();
|
|
251
|
+
} catch (error) {
|
|
252
|
+
lastError = error as Error;
|
|
253
|
+
|
|
254
|
+
if (error instanceof OpenSecureConfError) {
|
|
255
|
+
if (error.statusCode >= 400 && error.statusCode < 500) {
|
|
256
|
+
throw error;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
if (i < maxRetries - 1) {
|
|
261
|
+
await new Promise(resolve => setTimeout(resolve, Math.pow(2, i) * 1000));
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
throw lastError;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async function main() {
|
|
271
|
+
const manager = new ConfigManager(
|
|
272
|
+
'http://localhost:9000',
|
|
273
|
+
'my-secure-encryption-key',
|
|
274
|
+
'your-super-secret-api-key-here'
|
|
275
|
+
);
|
|
276
|
+
|
|
277
|
+
try {
|
|
278
|
+
await manager.setDatabaseConfig('prod-db', {
|
|
279
|
+
host: 'db.example.com',
|
|
280
|
+
port: 5432,
|
|
281
|
+
database: 'production',
|
|
282
|
+
ssl: true,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
const dbConfig = await manager.getDatabaseConfig('prod-db');
|
|
286
|
+
console.log('Database config:', dbConfig);
|
|
287
|
+
|
|
288
|
+
} catch (error) {
|
|
289
|
+
if (error instanceof OpenSecureConfError) {
|
|
290
|
+
console.error(`API Error [${error.statusCode}]:`, error.detail);
|
|
291
|
+
} else {
|
|
292
|
+
console.error('Error:', error);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
main();
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenSecureConf JavaScript/TypeScript Client
|
|
3
|
+
*
|
|
4
|
+
* A comprehensive REST API client for OpenSecureConf - Encrypted configuration
|
|
5
|
+
* management system with cluster support.
|
|
6
|
+
*
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
* @license MIT
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Configuration entry interface
|
|
12
|
+
*/
|
|
13
|
+
interface ConfigEntry {
|
|
14
|
+
id?: number;
|
|
15
|
+
key: string;
|
|
16
|
+
value: Record<string, any>;
|
|
17
|
+
category?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Cluster status information
|
|
21
|
+
*/
|
|
22
|
+
interface ClusterStatus {
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
mode?: string;
|
|
25
|
+
nodeid?: string;
|
|
26
|
+
totalnodes?: number;
|
|
27
|
+
healthynodes?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Client configuration options
|
|
31
|
+
*/
|
|
32
|
+
interface OpenSecureConfOptions {
|
|
33
|
+
baseUrl: string;
|
|
34
|
+
userKey: string;
|
|
35
|
+
apiKey?: string;
|
|
36
|
+
timeout?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Custom error class for OpenSecureConf API errors
|
|
40
|
+
*/
|
|
41
|
+
declare class OpenSecureConfError extends Error {
|
|
42
|
+
statusCode: number;
|
|
43
|
+
detail?: string;
|
|
44
|
+
constructor(statusCode: number, message: string, detail?: string);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* OpenSecureConf API Client
|
|
48
|
+
*/
|
|
49
|
+
declare class OpenSecureConfClient {
|
|
50
|
+
private baseUrl;
|
|
51
|
+
private userKey;
|
|
52
|
+
private apiKey?;
|
|
53
|
+
private timeout;
|
|
54
|
+
constructor(options: OpenSecureConfOptions);
|
|
55
|
+
private request;
|
|
56
|
+
getInfo(): Promise<any>;
|
|
57
|
+
create(key: string, value: Record<string, any>, category?: string): Promise<ConfigEntry>;
|
|
58
|
+
read(key: string): Promise<ConfigEntry>;
|
|
59
|
+
update(key: string, value: Record<string, any>, category?: string): Promise<ConfigEntry>;
|
|
60
|
+
delete(key: string): Promise<{
|
|
61
|
+
message: string;
|
|
62
|
+
}>;
|
|
63
|
+
list(category?: string): Promise<ConfigEntry[]>;
|
|
64
|
+
getClusterStatus(): Promise<ClusterStatus>;
|
|
65
|
+
healthCheck(): Promise<{
|
|
66
|
+
status: string;
|
|
67
|
+
nodeid: string;
|
|
68
|
+
}>;
|
|
69
|
+
getMetrics(): Promise<string>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { type ClusterStatus, type ConfigEntry, OpenSecureConfClient, OpenSecureConfError, type OpenSecureConfOptions, OpenSecureConfClient as default };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenSecureConf JavaScript/TypeScript Client
|
|
3
|
+
*
|
|
4
|
+
* A comprehensive REST API client for OpenSecureConf - Encrypted configuration
|
|
5
|
+
* management system with cluster support.
|
|
6
|
+
*
|
|
7
|
+
* @version 1.0.0
|
|
8
|
+
* @license MIT
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* Configuration entry interface
|
|
12
|
+
*/
|
|
13
|
+
interface ConfigEntry {
|
|
14
|
+
id?: number;
|
|
15
|
+
key: string;
|
|
16
|
+
value: Record<string, any>;
|
|
17
|
+
category?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Cluster status information
|
|
21
|
+
*/
|
|
22
|
+
interface ClusterStatus {
|
|
23
|
+
enabled: boolean;
|
|
24
|
+
mode?: string;
|
|
25
|
+
nodeid?: string;
|
|
26
|
+
totalnodes?: number;
|
|
27
|
+
healthynodes?: number;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Client configuration options
|
|
31
|
+
*/
|
|
32
|
+
interface OpenSecureConfOptions {
|
|
33
|
+
baseUrl: string;
|
|
34
|
+
userKey: string;
|
|
35
|
+
apiKey?: string;
|
|
36
|
+
timeout?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Custom error class for OpenSecureConf API errors
|
|
40
|
+
*/
|
|
41
|
+
declare class OpenSecureConfError extends Error {
|
|
42
|
+
statusCode: number;
|
|
43
|
+
detail?: string;
|
|
44
|
+
constructor(statusCode: number, message: string, detail?: string);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* OpenSecureConf API Client
|
|
48
|
+
*/
|
|
49
|
+
declare class OpenSecureConfClient {
|
|
50
|
+
private baseUrl;
|
|
51
|
+
private userKey;
|
|
52
|
+
private apiKey?;
|
|
53
|
+
private timeout;
|
|
54
|
+
constructor(options: OpenSecureConfOptions);
|
|
55
|
+
private request;
|
|
56
|
+
getInfo(): Promise<any>;
|
|
57
|
+
create(key: string, value: Record<string, any>, category?: string): Promise<ConfigEntry>;
|
|
58
|
+
read(key: string): Promise<ConfigEntry>;
|
|
59
|
+
update(key: string, value: Record<string, any>, category?: string): Promise<ConfigEntry>;
|
|
60
|
+
delete(key: string): Promise<{
|
|
61
|
+
message: string;
|
|
62
|
+
}>;
|
|
63
|
+
list(category?: string): Promise<ConfigEntry[]>;
|
|
64
|
+
getClusterStatus(): Promise<ClusterStatus>;
|
|
65
|
+
healthCheck(): Promise<{
|
|
66
|
+
status: string;
|
|
67
|
+
nodeid: string;
|
|
68
|
+
}>;
|
|
69
|
+
getMetrics(): Promise<string>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export { type ClusterStatus, type ConfigEntry, OpenSecureConfClient, OpenSecureConfError, type OpenSecureConfOptions, OpenSecureConfClient as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
OpenSecureConfClient: () => OpenSecureConfClient,
|
|
24
|
+
OpenSecureConfError: () => OpenSecureConfError,
|
|
25
|
+
default: () => index_default
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
var OpenSecureConfError = class _OpenSecureConfError extends Error {
|
|
29
|
+
constructor(statusCode, message, detail) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = "OpenSecureConfError";
|
|
32
|
+
this.statusCode = statusCode;
|
|
33
|
+
this.detail = detail;
|
|
34
|
+
if (Error.captureStackTrace) {
|
|
35
|
+
Error.captureStackTrace(this, _OpenSecureConfError);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var OpenSecureConfClient = class {
|
|
40
|
+
constructor(options) {
|
|
41
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
42
|
+
this.userKey = options.userKey;
|
|
43
|
+
this.apiKey = options.apiKey;
|
|
44
|
+
this.timeout = options.timeout || 3e4;
|
|
45
|
+
if (!this.userKey || this.userKey.length < 8) {
|
|
46
|
+
throw new Error("userKey must be at least 8 characters long");
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async request(method, endpoint, body) {
|
|
50
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
51
|
+
const headers = {
|
|
52
|
+
"Content-Type": "application/json",
|
|
53
|
+
"X-User-Key": this.userKey
|
|
54
|
+
};
|
|
55
|
+
if (this.apiKey) {
|
|
56
|
+
headers["X-API-Key"] = this.apiKey;
|
|
57
|
+
}
|
|
58
|
+
const controller = new AbortController();
|
|
59
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
60
|
+
try {
|
|
61
|
+
const response = await fetch(url, {
|
|
62
|
+
method,
|
|
63
|
+
headers,
|
|
64
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
65
|
+
signal: controller.signal
|
|
66
|
+
});
|
|
67
|
+
clearTimeout(timeoutId);
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
let errorDetail;
|
|
70
|
+
try {
|
|
71
|
+
const errorData = await response.json();
|
|
72
|
+
errorDetail = errorData.detail || errorData.message;
|
|
73
|
+
} catch {
|
|
74
|
+
errorDetail = response.statusText;
|
|
75
|
+
}
|
|
76
|
+
throw new OpenSecureConfError(
|
|
77
|
+
response.status,
|
|
78
|
+
`HTTP ${response.status}: ${response.statusText}`,
|
|
79
|
+
errorDetail
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
if (response.status === 204) {
|
|
83
|
+
return {};
|
|
84
|
+
}
|
|
85
|
+
const data = await response.json();
|
|
86
|
+
return data;
|
|
87
|
+
} catch (error) {
|
|
88
|
+
clearTimeout(timeoutId);
|
|
89
|
+
if (error instanceof OpenSecureConfError) {
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
if (error instanceof Error) {
|
|
93
|
+
if (error.name === "AbortError") {
|
|
94
|
+
throw new OpenSecureConfError(
|
|
95
|
+
408,
|
|
96
|
+
"Request timeout",
|
|
97
|
+
`Request exceeded ${this.timeout}ms`
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
throw new OpenSecureConfError(0, "Network error", error.message);
|
|
101
|
+
}
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async getInfo() {
|
|
106
|
+
return this.request("GET", "/");
|
|
107
|
+
}
|
|
108
|
+
async create(key, value, category) {
|
|
109
|
+
return this.request("POST", "/configs", {
|
|
110
|
+
key,
|
|
111
|
+
value,
|
|
112
|
+
category
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
async read(key) {
|
|
116
|
+
return this.request("GET", `/configs/${encodeURIComponent(key)}`);
|
|
117
|
+
}
|
|
118
|
+
async update(key, value, category) {
|
|
119
|
+
return this.request("PUT", `/configs/${encodeURIComponent(key)}`, {
|
|
120
|
+
value,
|
|
121
|
+
category
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
async delete(key) {
|
|
125
|
+
return this.request("DELETE", `/configs/${encodeURIComponent(key)}`);
|
|
126
|
+
}
|
|
127
|
+
async list(category) {
|
|
128
|
+
const endpoint = category ? `/configs?category=${encodeURIComponent(category)}` : "/configs";
|
|
129
|
+
return this.request("GET", endpoint);
|
|
130
|
+
}
|
|
131
|
+
async getClusterStatus() {
|
|
132
|
+
return this.request("GET", "/cluster/status");
|
|
133
|
+
}
|
|
134
|
+
async healthCheck() {
|
|
135
|
+
return this.request("GET", "/cluster/health");
|
|
136
|
+
}
|
|
137
|
+
async getMetrics() {
|
|
138
|
+
const url = `${this.baseUrl}/metrics`;
|
|
139
|
+
const headers = {};
|
|
140
|
+
if (this.apiKey) {
|
|
141
|
+
headers["X-API-Key"] = this.apiKey;
|
|
142
|
+
}
|
|
143
|
+
const response = await fetch(url, { headers });
|
|
144
|
+
if (!response.ok) {
|
|
145
|
+
throw new OpenSecureConfError(
|
|
146
|
+
response.status,
|
|
147
|
+
`Failed to fetch metrics: ${response.statusText}`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
return await response.text();
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
var index_default = OpenSecureConfClient;
|
|
154
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
155
|
+
0 && (module.exports = {
|
|
156
|
+
OpenSecureConfClient,
|
|
157
|
+
OpenSecureConfError
|
|
158
|
+
});
|
|
159
|
+
/**
|
|
160
|
+
* OpenSecureConf JavaScript/TypeScript Client
|
|
161
|
+
*
|
|
162
|
+
* A comprehensive REST API client for OpenSecureConf - Encrypted configuration
|
|
163
|
+
* management system with cluster support.
|
|
164
|
+
*
|
|
165
|
+
* @version 1.0.0
|
|
166
|
+
* @license MIT
|
|
167
|
+
*/
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
var OpenSecureConfError = class _OpenSecureConfError extends Error {
|
|
3
|
+
constructor(statusCode, message, detail) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "OpenSecureConfError";
|
|
6
|
+
this.statusCode = statusCode;
|
|
7
|
+
this.detail = detail;
|
|
8
|
+
if (Error.captureStackTrace) {
|
|
9
|
+
Error.captureStackTrace(this, _OpenSecureConfError);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
var OpenSecureConfClient = class {
|
|
14
|
+
constructor(options) {
|
|
15
|
+
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
16
|
+
this.userKey = options.userKey;
|
|
17
|
+
this.apiKey = options.apiKey;
|
|
18
|
+
this.timeout = options.timeout || 3e4;
|
|
19
|
+
if (!this.userKey || this.userKey.length < 8) {
|
|
20
|
+
throw new Error("userKey must be at least 8 characters long");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async request(method, endpoint, body) {
|
|
24
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
25
|
+
const headers = {
|
|
26
|
+
"Content-Type": "application/json",
|
|
27
|
+
"X-User-Key": this.userKey
|
|
28
|
+
};
|
|
29
|
+
if (this.apiKey) {
|
|
30
|
+
headers["X-API-Key"] = this.apiKey;
|
|
31
|
+
}
|
|
32
|
+
const controller = new AbortController();
|
|
33
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
34
|
+
try {
|
|
35
|
+
const response = await fetch(url, {
|
|
36
|
+
method,
|
|
37
|
+
headers,
|
|
38
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
39
|
+
signal: controller.signal
|
|
40
|
+
});
|
|
41
|
+
clearTimeout(timeoutId);
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
let errorDetail;
|
|
44
|
+
try {
|
|
45
|
+
const errorData = await response.json();
|
|
46
|
+
errorDetail = errorData.detail || errorData.message;
|
|
47
|
+
} catch {
|
|
48
|
+
errorDetail = response.statusText;
|
|
49
|
+
}
|
|
50
|
+
throw new OpenSecureConfError(
|
|
51
|
+
response.status,
|
|
52
|
+
`HTTP ${response.status}: ${response.statusText}`,
|
|
53
|
+
errorDetail
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
if (response.status === 204) {
|
|
57
|
+
return {};
|
|
58
|
+
}
|
|
59
|
+
const data = await response.json();
|
|
60
|
+
return data;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
clearTimeout(timeoutId);
|
|
63
|
+
if (error instanceof OpenSecureConfError) {
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
66
|
+
if (error instanceof Error) {
|
|
67
|
+
if (error.name === "AbortError") {
|
|
68
|
+
throw new OpenSecureConfError(
|
|
69
|
+
408,
|
|
70
|
+
"Request timeout",
|
|
71
|
+
`Request exceeded ${this.timeout}ms`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
throw new OpenSecureConfError(0, "Network error", error.message);
|
|
75
|
+
}
|
|
76
|
+
throw error;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async getInfo() {
|
|
80
|
+
return this.request("GET", "/");
|
|
81
|
+
}
|
|
82
|
+
async create(key, value, category) {
|
|
83
|
+
return this.request("POST", "/configs", {
|
|
84
|
+
key,
|
|
85
|
+
value,
|
|
86
|
+
category
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async read(key) {
|
|
90
|
+
return this.request("GET", `/configs/${encodeURIComponent(key)}`);
|
|
91
|
+
}
|
|
92
|
+
async update(key, value, category) {
|
|
93
|
+
return this.request("PUT", `/configs/${encodeURIComponent(key)}`, {
|
|
94
|
+
value,
|
|
95
|
+
category
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
async delete(key) {
|
|
99
|
+
return this.request("DELETE", `/configs/${encodeURIComponent(key)}`);
|
|
100
|
+
}
|
|
101
|
+
async list(category) {
|
|
102
|
+
const endpoint = category ? `/configs?category=${encodeURIComponent(category)}` : "/configs";
|
|
103
|
+
return this.request("GET", endpoint);
|
|
104
|
+
}
|
|
105
|
+
async getClusterStatus() {
|
|
106
|
+
return this.request("GET", "/cluster/status");
|
|
107
|
+
}
|
|
108
|
+
async healthCheck() {
|
|
109
|
+
return this.request("GET", "/cluster/health");
|
|
110
|
+
}
|
|
111
|
+
async getMetrics() {
|
|
112
|
+
const url = `${this.baseUrl}/metrics`;
|
|
113
|
+
const headers = {};
|
|
114
|
+
if (this.apiKey) {
|
|
115
|
+
headers["X-API-Key"] = this.apiKey;
|
|
116
|
+
}
|
|
117
|
+
const response = await fetch(url, { headers });
|
|
118
|
+
if (!response.ok) {
|
|
119
|
+
throw new OpenSecureConfError(
|
|
120
|
+
response.status,
|
|
121
|
+
`Failed to fetch metrics: ${response.statusText}`
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
return await response.text();
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
var index_default = OpenSecureConfClient;
|
|
128
|
+
export {
|
|
129
|
+
OpenSecureConfClient,
|
|
130
|
+
OpenSecureConfError,
|
|
131
|
+
index_default as default
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* OpenSecureConf JavaScript/TypeScript Client
|
|
135
|
+
*
|
|
136
|
+
* A comprehensive REST API client for OpenSecureConf - Encrypted configuration
|
|
137
|
+
* management system with cluster support.
|
|
138
|
+
*
|
|
139
|
+
* @version 1.0.0
|
|
140
|
+
* @license MIT
|
|
141
|
+
*/
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "opensecureconf-client",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "JavaScript/TypeScript client for OpenSecureConf - Encrypted configuration management REST API",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md",
|
|
11
|
+
"LICENSE"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
15
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
16
|
+
"test": "jest",
|
|
17
|
+
"test:watch": "jest --watch",
|
|
18
|
+
"test:coverage": "jest --coverage",
|
|
19
|
+
"lint": "eslint src --ext .ts",
|
|
20
|
+
"lint:fix": "eslint src --ext .ts --fix",
|
|
21
|
+
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
22
|
+
"prepublishOnly": "npm run build && npm test",
|
|
23
|
+
"prepare": "npm run build"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"opensecureconf",
|
|
27
|
+
"configuration",
|
|
28
|
+
"encryption",
|
|
29
|
+
"config-management",
|
|
30
|
+
"rest-api",
|
|
31
|
+
"client",
|
|
32
|
+
"typescript",
|
|
33
|
+
"encrypted-storage",
|
|
34
|
+
"cluster",
|
|
35
|
+
"distributed-config"
|
|
36
|
+
],
|
|
37
|
+
"author": "Apioli <alessandro.pioli+apioli-npm@gmail.com>",
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/lordraw77/OpenSecureConf.git",
|
|
42
|
+
"directory": "client-js"
|
|
43
|
+
},
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/lordraw77/OpenSecureConf/issues"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/lordraw77/OpenSecureConf/tree/main/client-js#readme",
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@types/jest": "^29.5.11",
|
|
50
|
+
"@types/node": "^20.10.6",
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^6.17.0",
|
|
52
|
+
"@typescript-eslint/parser": "^6.17.0",
|
|
53
|
+
"eslint": "^8.56.0",
|
|
54
|
+
"eslint-config-prettier": "^9.1.0",
|
|
55
|
+
"eslint-plugin-prettier": "^5.1.2",
|
|
56
|
+
"jest": "^29.7.0",
|
|
57
|
+
"prettier": "^3.1.1",
|
|
58
|
+
"ts-jest": "^29.1.1",
|
|
59
|
+
"tsup": "^8.0.1",
|
|
60
|
+
"typescript": "^5.3.3"
|
|
61
|
+
},
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=16.0.0"
|
|
64
|
+
},
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"opensecureconf-client": "file:opensecureconf-client-1.0.0.tgz"
|
|
67
|
+
}
|
|
68
|
+
}
|