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 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
+ [![npm version](https://badge.fury.io/js/opensecureconf-client.svg)](https://www.npmjs.com/package/opensecureconf-client)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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();
@@ -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 };
@@ -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
+ }