@fentz26/envcp 1.0.2 → 1.0.4

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.
Files changed (48) hide show
  1. package/README.md +13 -6
  2. package/dist/adapters/base.d.ts.map +1 -1
  3. package/dist/adapters/base.js +5 -1
  4. package/dist/adapters/base.js.map +1 -1
  5. package/dist/cli/index.js +462 -34
  6. package/dist/cli/index.js.map +1 -1
  7. package/dist/config/manager.d.ts +6 -0
  8. package/dist/config/manager.d.ts.map +1 -1
  9. package/dist/config/manager.js +243 -6
  10. package/dist/config/manager.js.map +1 -1
  11. package/dist/storage/index.d.ts +10 -1
  12. package/dist/storage/index.d.ts.map +1 -1
  13. package/dist/storage/index.js +89 -6
  14. package/dist/storage/index.js.map +1 -1
  15. package/dist/types.d.ts +31 -0
  16. package/dist/types.d.ts.map +1 -1
  17. package/dist/types.js +7 -0
  18. package/dist/types.js.map +1 -1
  19. package/dist/utils/crypto.d.ts +3 -0
  20. package/dist/utils/crypto.d.ts.map +1 -1
  21. package/dist/utils/crypto.js +12 -0
  22. package/dist/utils/crypto.js.map +1 -1
  23. package/package.json +6 -1
  24. package/.github/workflows/publish.yml +0 -48
  25. package/__tests__/config.test.ts +0 -65
  26. package/__tests__/crypto.test.ts +0 -76
  27. package/__tests__/http.test.ts +0 -49
  28. package/__tests__/storage.test.ts +0 -94
  29. package/jest.config.js +0 -11
  30. package/src/adapters/base.ts +0 -542
  31. package/src/adapters/gemini.ts +0 -228
  32. package/src/adapters/index.ts +0 -4
  33. package/src/adapters/openai.ts +0 -238
  34. package/src/adapters/rest.ts +0 -298
  35. package/src/cli/index.ts +0 -516
  36. package/src/cli.ts +0 -2
  37. package/src/config/manager.ts +0 -137
  38. package/src/index.ts +0 -4
  39. package/src/mcp/index.ts +0 -1
  40. package/src/mcp/server.ts +0 -67
  41. package/src/server/index.ts +0 -1
  42. package/src/server/unified.ts +0 -474
  43. package/src/storage/index.ts +0 -128
  44. package/src/types.ts +0 -183
  45. package/src/utils/crypto.ts +0 -100
  46. package/src/utils/http.ts +0 -119
  47. package/src/utils/session.ts +0 -146
  48. package/tsconfig.json +0 -20
@@ -1,298 +0,0 @@
1
- import { BaseAdapter } from './base.js';
2
- import { EnvCPConfig, RESTResponse, ToolDefinition } from '../types.js';
3
- import { setCorsHeaders, sendJson, parseBody, validateApiKey, RateLimiter, rateLimitMiddleware } from '../utils/http.js';
4
- import * as http from 'http';
5
-
6
- export class RESTAdapter extends BaseAdapter {
7
- private server: http.Server | null = null;
8
- private rateLimiter = new RateLimiter(60, 60000);
9
-
10
- constructor(config: EnvCPConfig, projectPath: string, password?: string) {
11
- super(config, projectPath, password);
12
- }
13
-
14
- protected registerTools(): void {
15
- const tools: ToolDefinition[] = [
16
- {
17
- name: 'envcp_list',
18
- description: 'List all available environment variable names',
19
- parameters: {
20
- tags: { type: 'array', items: { type: 'string' }, description: 'Filter by tags' },
21
- },
22
- handler: async (params) => this.listVariables(params as { tags?: string[] }),
23
- },
24
- {
25
- name: 'envcp_get',
26
- description: 'Get an environment variable',
27
- parameters: {
28
- name: { type: 'string', required: true, description: 'Variable name' },
29
- show_value: { type: 'boolean', description: 'Show actual value' },
30
- },
31
- handler: async (params) => this.getVariable(params as { name: string; show_value?: boolean }),
32
- },
33
- {
34
- name: 'envcp_set',
35
- description: 'Create or update an environment variable',
36
- parameters: {
37
- name: { type: 'string', required: true, description: 'Variable name' },
38
- value: { type: 'string', required: true, description: 'Variable value' },
39
- tags: { type: 'array', items: { type: 'string' }, description: 'Tags' },
40
- description: { type: 'string', description: 'Description' },
41
- },
42
- handler: async (params) => this.setVariable(params as { name: string; value: string; tags?: string[]; description?: string }),
43
- },
44
- {
45
- name: 'envcp_delete',
46
- description: 'Delete an environment variable',
47
- parameters: {
48
- name: { type: 'string', required: true, description: 'Variable name' },
49
- },
50
- handler: async (params) => this.deleteVariable(params as { name: string }),
51
- },
52
- {
53
- name: 'envcp_sync',
54
- description: 'Sync variables to .env file',
55
- parameters: {},
56
- handler: async () => this.syncToEnv(),
57
- },
58
- {
59
- name: 'envcp_add_to_env',
60
- description: 'Add variable to .env file',
61
- parameters: {
62
- name: { type: 'string', required: true, description: 'Variable name' },
63
- env_file: { type: 'string', description: 'Path to .env file' },
64
- },
65
- handler: async (params) => this.addToEnv(params as { name: string; env_file?: string }),
66
- },
67
- {
68
- name: 'envcp_check_access',
69
- description: 'Check if a variable can be accessed',
70
- parameters: {
71
- name: { type: 'string', required: true, description: 'Variable name' },
72
- },
73
- handler: async (params) => this.checkAccess(params as { name: string }),
74
- },
75
- {
76
- name: 'envcp_run',
77
- description: 'Execute a command with environment variables',
78
- parameters: {
79
- command: { type: 'string', required: true, description: 'Command to execute' },
80
- variables: { type: 'array', items: { type: 'string' }, required: true, description: 'Variables to inject' },
81
- },
82
- handler: async (params) => this.runCommand(params as { command: string; variables: string[] }),
83
- },
84
- ];
85
-
86
- tools.forEach(tool => this.tools.set(tool.name, tool));
87
- }
88
-
89
- private createResponse<T>(success: boolean, data?: T, error?: string): RESTResponse<T> {
90
- return {
91
- success,
92
- data,
93
- error,
94
- timestamp: new Date().toISOString(),
95
- };
96
- }
97
-
98
-
99
- async startServer(port: number, host: string, apiKey?: string): Promise<void> {
100
- await this.init();
101
-
102
- this.server = http.createServer(async (req, res) => {
103
- setCorsHeaders(res, undefined, req.headers.origin);
104
-
105
- if (req.method === 'OPTIONS') {
106
- res.writeHead(204);
107
- res.end();
108
- return;
109
- }
110
-
111
- if (!rateLimitMiddleware(this.rateLimiter, req, res)) {
112
- return;
113
- }
114
-
115
- // API key validation
116
- if (apiKey) {
117
- const providedKey = (req.headers['x-api-key'] || req.headers['authorization']?.replace('Bearer ', '')) as string | undefined;
118
- if (!validateApiKey(providedKey, apiKey)) {
119
- sendJson(res, 401, this.createResponse(false, undefined, 'Invalid API key'));
120
- return;
121
- }
122
- }
123
-
124
- const parsedUrl = new URL(req.url || '/', `http://${req.headers.host || 'localhost'}`);
125
- const pathname = parsedUrl.pathname;
126
- const segments = pathname.split('/').filter(Boolean);
127
-
128
- try {
129
- // Routes:
130
- // GET /api/variables - List variables
131
- // GET /api/variables/:name - Get variable
132
- // POST /api/variables - Create variable
133
- // PUT /api/variables/:name - Update variable
134
- // DELETE /api/variables/:name - Delete variable
135
- // POST /api/sync - Sync to .env
136
- // POST /api/run - Run command
137
- // GET /api/tools - List available tools
138
- // POST /api/tools/:name - Call a tool
139
-
140
- if (segments[0] === 'api') {
141
- const resource = segments[1];
142
-
143
- // Health check
144
- if (pathname === '/api/health' || pathname === '/api') {
145
- sendJson(res, 200, this.createResponse(true, {
146
- status: 'ok',
147
- version: '1.0.0',
148
- mode: 'rest',
149
- }));
150
- return;
151
- }
152
-
153
- // List tools
154
- if (resource === 'tools' && !segments[2] && req.method === 'GET') {
155
- const tools = this.getToolDefinitions().map(t => ({
156
- name: t.name,
157
- description: t.description,
158
- parameters: t.parameters,
159
- }));
160
- sendJson(res, 200, this.createResponse(true, { tools }));
161
- return;
162
- }
163
-
164
- // Call tool
165
- if (resource === 'tools' && segments[2] && req.method === 'POST') {
166
- const toolName = segments[2];
167
- const body = await parseBody(req);
168
- const result = await this.callTool(toolName, body);
169
- sendJson(res, 200, this.createResponse(true, result));
170
- return;
171
- }
172
-
173
- // Variables
174
- if (resource === 'variables') {
175
- const varName = segments[2];
176
-
177
- if (!varName && req.method === 'GET') {
178
- const tagsParam = parsedUrl.searchParams.getAll('tags');
179
- const tags = tagsParam.length > 0 ? tagsParam : undefined;
180
- const result = await this.callTool('envcp_list', { tags });
181
- sendJson(res, 200, this.createResponse(true, result));
182
- return;
183
- }
184
-
185
- if (!varName && req.method === 'POST') {
186
- const body = await parseBody(req);
187
- const result = await this.callTool('envcp_set', body);
188
- sendJson(res, 201, this.createResponse(true, result));
189
- return;
190
- }
191
-
192
- if (varName && req.method === 'GET') {
193
- const showValue = parsedUrl.searchParams.get('show_value') === 'true';
194
- const result = await this.callTool('envcp_get', { name: varName, show_value: showValue });
195
- sendJson(res, 200, this.createResponse(true, result));
196
- return;
197
- }
198
-
199
- if (varName && req.method === 'PUT') {
200
- const body = await parseBody(req);
201
- const result = await this.callTool('envcp_set', { ...body, name: varName });
202
- sendJson(res, 200, this.createResponse(true, result));
203
- return;
204
- }
205
-
206
- if (varName && req.method === 'DELETE') {
207
- const result = await this.callTool('envcp_delete', { name: varName });
208
- sendJson(res, 200, this.createResponse(true, result));
209
- return;
210
- }
211
- }
212
-
213
- // Sync
214
- if (resource === 'sync' && req.method === 'POST') {
215
- const result = await this.callTool('envcp_sync', {});
216
- sendJson(res, 200, this.createResponse(true, result));
217
- return;
218
- }
219
-
220
- // Run
221
- if (resource === 'run' && req.method === 'POST') {
222
- const body = await parseBody(req);
223
- const result = await this.callTool('envcp_run', body);
224
- sendJson(res, 200, this.createResponse(true, result));
225
- return;
226
- }
227
-
228
- // Check access
229
- if (resource === 'access' && segments[2] && req.method === 'GET') {
230
- const result = await this.callTool('envcp_check_access', { name: segments[2] });
231
- sendJson(res, 200, this.createResponse(true, result));
232
- return;
233
- }
234
- }
235
-
236
- // 404
237
- sendJson(res, 404, this.createResponse(false, undefined, 'Not found'));
238
-
239
- } catch (error: unknown) {
240
- const message = error instanceof Error ? error.message : String(error);
241
- const status = message.includes('locked') ? 401 :
242
- message.includes('not found') ? 404 :
243
- message.includes('disabled') ? 403 : 500;
244
- sendJson(res, status, this.createResponse(false, undefined, message));
245
- }
246
- });
247
-
248
- return new Promise((resolve) => {
249
- this.server!.listen(port, host, () => {
250
- resolve();
251
- });
252
- });
253
- }
254
-
255
- stopServer(): void {
256
- if (this.server) {
257
- this.server.close();
258
- this.server = null;
259
- }
260
- }
261
-
262
- getApiDocs(): string {
263
- return `
264
- EnvCP REST API
265
- ==============
266
-
267
- Base URL: http://localhost:{port}/api
268
-
269
- Authentication:
270
- Header: X-API-Key: {your-api-key}
271
- Or: Authorization: Bearer {your-api-key}
272
-
273
- Endpoints:
274
-
275
- GET /api/health - Health check
276
- GET /api/tools - List available tools
277
- POST /api/tools/:name - Call a tool by name
278
-
279
- GET /api/variables - List all variables
280
- GET /api/variables/:name - Get a variable
281
- POST /api/variables - Create a variable
282
- PUT /api/variables/:name - Update a variable
283
- DELETE /api/variables/:name - Delete a variable
284
-
285
- POST /api/sync - Sync to .env file
286
- POST /api/run - Run command with variables
287
- GET /api/access/:name - Check variable access
288
-
289
- Response format:
290
- {
291
- "success": true/false,
292
- "data": { ... },
293
- "error": "Error message (if any)",
294
- "timestamp": "ISO timestamp"
295
- }
296
- `.trim();
297
- }
298
- }