@positronic/cli 0.0.3 → 0.0.5
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/dist/src/commands/helpers.js +57 -27
- package/dist/types/commands/helpers.d.ts.map +1 -1
- package/package.json +5 -1
- package/dist/src/commands/brain.test.js +0 -2936
- package/dist/src/commands/helpers.test.js +0 -832
- package/dist/src/commands/project.test.js +0 -1201
- package/dist/src/commands/resources.test.js +0 -2511
- package/dist/src/commands/schedule.test.js +0 -1235
- package/dist/src/commands/secret.test.d.js +0 -1
- package/dist/src/commands/secret.test.js +0 -761
- package/dist/src/commands/server.test.js +0 -1237
- package/dist/src/commands/test-utils.js +0 -737
- package/dist/src/components/secret-sync.js +0 -303
- package/dist/src/test/mock-api-client.js +0 -371
- package/dist/src/test/test-dev-server.js +0 -1376
- package/dist/types/commands/test-utils.d.ts +0 -45
- package/dist/types/commands/test-utils.d.ts.map +0 -1
- package/dist/types/components/secret-sync.d.ts +0 -9
- package/dist/types/components/secret-sync.d.ts.map +0 -1
- package/dist/types/test/mock-api-client.d.ts +0 -25
- package/dist/types/test/mock-api-client.d.ts.map +0 -1
- package/dist/types/test/test-dev-server.d.ts +0 -129
- package/dist/types/test/test-dev-server.d.ts.map +0 -1
- package/src/cli.ts +0 -997
- package/src/commands/backend.ts +0 -63
- package/src/commands/brain.test.ts +0 -1004
- package/src/commands/brain.ts +0 -215
- package/src/commands/helpers.test.ts +0 -487
- package/src/commands/helpers.ts +0 -870
- package/src/commands/project-config-manager.ts +0 -152
- package/src/commands/project.test.ts +0 -502
- package/src/commands/project.ts +0 -109
- package/src/commands/resources.test.ts +0 -1052
- package/src/commands/resources.ts +0 -97
- package/src/commands/schedule.test.ts +0 -481
- package/src/commands/schedule.ts +0 -65
- package/src/commands/secret.test.ts +0 -210
- package/src/commands/secret.ts +0 -50
- package/src/commands/server.test.ts +0 -493
- package/src/commands/server.ts +0 -353
- package/src/commands/test-utils.ts +0 -324
- package/src/components/brain-history.tsx +0 -198
- package/src/components/brain-list.tsx +0 -105
- package/src/components/brain-rerun.tsx +0 -111
- package/src/components/brain-show.tsx +0 -92
- package/src/components/error.tsx +0 -24
- package/src/components/project-add.tsx +0 -59
- package/src/components/project-create.tsx +0 -83
- package/src/components/project-list.tsx +0 -83
- package/src/components/project-remove.tsx +0 -55
- package/src/components/project-select.tsx +0 -200
- package/src/components/project-show.tsx +0 -58
- package/src/components/resource-clear.tsx +0 -127
- package/src/components/resource-delete.tsx +0 -160
- package/src/components/resource-list.tsx +0 -177
- package/src/components/resource-sync.tsx +0 -170
- package/src/components/resource-types.tsx +0 -55
- package/src/components/resource-upload.tsx +0 -182
- package/src/components/schedule-create.tsx +0 -90
- package/src/components/schedule-delete.tsx +0 -116
- package/src/components/schedule-list.tsx +0 -186
- package/src/components/schedule-runs.tsx +0 -151
- package/src/components/secret-bulk.tsx +0 -79
- package/src/components/secret-create.tsx +0 -49
- package/src/components/secret-delete.tsx +0 -41
- package/src/components/secret-list.tsx +0 -41
- package/src/components/watch.tsx +0 -155
- package/src/hooks/useApi.ts +0 -183
- package/src/positronic.ts +0 -40
- package/src/test/data/resources/config.json +0 -1
- package/src/test/data/resources/data/config.json +0 -1
- package/src/test/data/resources/data/logo.png +0 -2
- package/src/test/data/resources/docs/api.md +0 -3
- package/src/test/data/resources/docs/readme.md +0 -3
- package/src/test/data/resources/example.md +0 -3
- package/src/test/data/resources/file with spaces.txt +0 -1
- package/src/test/data/resources/readme.md +0 -3
- package/src/test/data/resources/test.txt +0 -1
- package/src/test/mock-api-client.ts +0 -145
- package/src/test/test-dev-server.ts +0 -1003
- package/tsconfig.json +0 -11
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from '@jest/globals';
|
|
2
|
-
import { createTestEnv, px } from './test-utils.js';
|
|
3
|
-
import * as fs from 'fs';
|
|
4
|
-
import * as path from 'path';
|
|
5
|
-
|
|
6
|
-
describe('secret commands', () => {
|
|
7
|
-
describe('secret create', () => {
|
|
8
|
-
it('should pass through to backend', async () => {
|
|
9
|
-
const env = await createTestEnv();
|
|
10
|
-
const px = await env.start();
|
|
11
|
-
|
|
12
|
-
try {
|
|
13
|
-
// Just verify it runs without error
|
|
14
|
-
await px(['secret', 'create', 'TEST_SECRET', '--value=test-value']);
|
|
15
|
-
} finally {
|
|
16
|
-
await env.stopAndCleanup();
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
describe('secret list', () => {
|
|
22
|
-
it('should pass through to backend', async () => {
|
|
23
|
-
const env = await createTestEnv();
|
|
24
|
-
const px = await env.start();
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
// Just verify it runs without error
|
|
28
|
-
await px(['secret', 'list']);
|
|
29
|
-
} finally {
|
|
30
|
-
await env.stopAndCleanup();
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe('secret delete', () => {
|
|
36
|
-
it('should pass through to backend', async () => {
|
|
37
|
-
const env = await createTestEnv();
|
|
38
|
-
const px = await env.start();
|
|
39
|
-
|
|
40
|
-
try {
|
|
41
|
-
// Just verify it runs without error
|
|
42
|
-
await px(['secret', 'delete', 'TEST_SECRET']);
|
|
43
|
-
} finally {
|
|
44
|
-
await env.stopAndCleanup();
|
|
45
|
-
}
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
describe('secret bulk', () => {
|
|
50
|
-
it('should bulk upload secrets from .env file', async () => {
|
|
51
|
-
const env = await createTestEnv();
|
|
52
|
-
|
|
53
|
-
// Create a test .env file
|
|
54
|
-
env.setup((dir: string) => {
|
|
55
|
-
const envContent = `TEST_API_KEY=sk-test123
|
|
56
|
-
TEST_DATABASE_URL=postgres://user:pass@localhost:5432/db
|
|
57
|
-
TEST_REDIS_URL=redis://localhost:6379`;
|
|
58
|
-
fs.writeFileSync(path.join(dir, '.env'), envContent);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
const px = await env.start();
|
|
62
|
-
|
|
63
|
-
try {
|
|
64
|
-
const { waitForOutput, instance } = await px(['secret', 'bulk']);
|
|
65
|
-
|
|
66
|
-
// Since bulk command passes through to backend,
|
|
67
|
-
// we can't check for output. Just wait a bit for completion.
|
|
68
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
69
|
-
|
|
70
|
-
// Verify server method was called
|
|
71
|
-
const calls = env.server.getLogs();
|
|
72
|
-
const bulkCall = calls.find((c) => c.method === 'bulkSecrets');
|
|
73
|
-
expect(bulkCall).toBeDefined();
|
|
74
|
-
|
|
75
|
-
// Verify the server received the correct secret names
|
|
76
|
-
const secrets = env.server.getSecrets();
|
|
77
|
-
expect(secrets.length).toBe(3);
|
|
78
|
-
const secretNames = secrets.map((s) => s.name);
|
|
79
|
-
expect(secretNames).toContain('TEST_API_KEY');
|
|
80
|
-
expect(secretNames).toContain('TEST_DATABASE_URL');
|
|
81
|
-
expect(secretNames).toContain('TEST_REDIS_URL');
|
|
82
|
-
} finally {
|
|
83
|
-
await env.stopAndCleanup();
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should handle custom .env file path', async () => {
|
|
88
|
-
const env = await createTestEnv();
|
|
89
|
-
|
|
90
|
-
env.setup((dir: string) => {
|
|
91
|
-
const envContent = `SECRET_KEY=my-secret-key
|
|
92
|
-
API_TOKEN=token123`;
|
|
93
|
-
fs.writeFileSync(path.join(dir, '.env.production'), envContent);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
const px = await env.start();
|
|
97
|
-
|
|
98
|
-
try {
|
|
99
|
-
await px(['secret', 'bulk', '.env.production']);
|
|
100
|
-
|
|
101
|
-
// Since bulk command passes through to backend,
|
|
102
|
-
// we can't check for output. Just wait a bit for completion.
|
|
103
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
104
|
-
|
|
105
|
-
// Verify the server received the correct secret names
|
|
106
|
-
const secrets = env.server.getSecrets();
|
|
107
|
-
expect(secrets.length).toBe(2);
|
|
108
|
-
const secretNames = secrets.map((s) => s.name);
|
|
109
|
-
expect(secretNames).toContain('SECRET_KEY');
|
|
110
|
-
expect(secretNames).toContain('API_TOKEN');
|
|
111
|
-
} finally {
|
|
112
|
-
await env.stopAndCleanup();
|
|
113
|
-
}
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it('should handle successful bulk upload', async () => {
|
|
117
|
-
const env = await createTestEnv();
|
|
118
|
-
|
|
119
|
-
env.setup((dir: string) => {
|
|
120
|
-
const envContent = `KEY1=value1
|
|
121
|
-
KEY2=value2
|
|
122
|
-
KEY3=value3`;
|
|
123
|
-
fs.writeFileSync(path.join(dir, '.env'), envContent);
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
const px = await env.start();
|
|
127
|
-
|
|
128
|
-
try {
|
|
129
|
-
await px(['secret', 'bulk']);
|
|
130
|
-
|
|
131
|
-
// Since bulk command passes through to backend,
|
|
132
|
-
// we can't check for output. Just wait a bit for completion.
|
|
133
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
134
|
-
|
|
135
|
-
// Verify bulkSecrets was called
|
|
136
|
-
const calls = env.server.getLogs();
|
|
137
|
-
const bulkCall = calls.find((c) => c.method === 'bulkSecrets');
|
|
138
|
-
expect(bulkCall).toBeDefined();
|
|
139
|
-
} finally {
|
|
140
|
-
await env.stopAndCleanup();
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it('should handle file not found error', async () => {
|
|
145
|
-
const env = await createTestEnv();
|
|
146
|
-
const px = await env.start();
|
|
147
|
-
|
|
148
|
-
try {
|
|
149
|
-
const { waitForOutput } = await px([
|
|
150
|
-
'secret',
|
|
151
|
-
'bulk',
|
|
152
|
-
'nonexistent.env',
|
|
153
|
-
]);
|
|
154
|
-
|
|
155
|
-
const foundError = await waitForOutput(/No .env file found/i, 30);
|
|
156
|
-
expect(foundError).toBe(true);
|
|
157
|
-
} finally {
|
|
158
|
-
await env.stopAndCleanup();
|
|
159
|
-
}
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it('should handle empty .env file', async () => {
|
|
163
|
-
const env = await createTestEnv();
|
|
164
|
-
|
|
165
|
-
env.setup((dir: string) => {
|
|
166
|
-
// Create empty .env file
|
|
167
|
-
fs.writeFileSync(path.join(dir, '.env'), '');
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
const px = await env.start();
|
|
171
|
-
|
|
172
|
-
try {
|
|
173
|
-
const { waitForOutput } = await px(['secret', 'bulk']);
|
|
174
|
-
|
|
175
|
-
const foundError = await waitForOutput(
|
|
176
|
-
/No secrets found in the .env file/i,
|
|
177
|
-
30
|
|
178
|
-
);
|
|
179
|
-
expect(foundError).toBe(true);
|
|
180
|
-
} finally {
|
|
181
|
-
await env.stopAndCleanup();
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
it('should handle mixed create/update results', async () => {
|
|
186
|
-
const env = await createTestEnv();
|
|
187
|
-
|
|
188
|
-
// Pre-create a secret so we can test update behavior
|
|
189
|
-
env.server.addSecret('EXISTING_KEY', 'old-value');
|
|
190
|
-
|
|
191
|
-
env.setup((dir: string) => {
|
|
192
|
-
const envContent = `NEW_KEY=new-value
|
|
193
|
-
EXISTING_KEY=updated-value`;
|
|
194
|
-
fs.writeFileSync(path.join(dir, '.env'), envContent);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
const px = await env.start();
|
|
198
|
-
|
|
199
|
-
try {
|
|
200
|
-
const { waitForOutput } = await px(['secret', 'bulk']);
|
|
201
|
-
|
|
202
|
-
// Since bulk command passes through to backend,
|
|
203
|
-
// we can't check for output. Just wait a bit for completion.
|
|
204
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
205
|
-
} finally {
|
|
206
|
-
await env.stopAndCleanup();
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
});
|
package/src/commands/secret.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import type { ArgumentsCamelCase } from 'yargs';
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import type { PositronicDevServer } from '@positronic/spec';
|
|
4
|
-
import { SecretCreate } from '../components/secret-create.js';
|
|
5
|
-
import { SecretList } from '../components/secret-list.js';
|
|
6
|
-
import { SecretDelete } from '../components/secret-delete.js';
|
|
7
|
-
import { SecretBulk } from '../components/secret-bulk.js';
|
|
8
|
-
|
|
9
|
-
interface SecretCreateArgs {
|
|
10
|
-
name: string;
|
|
11
|
-
value?: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
interface SecretDeleteArgs {
|
|
15
|
-
name: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface SecretBulkArgs {
|
|
19
|
-
file?: string;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export class SecretCommand {
|
|
23
|
-
constructor(private server?: PositronicDevServer) {}
|
|
24
|
-
|
|
25
|
-
list(): React.ReactElement {
|
|
26
|
-
return React.createElement(SecretList, { server: this.server });
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
create({
|
|
30
|
-
name,
|
|
31
|
-
value,
|
|
32
|
-
}: ArgumentsCamelCase<SecretCreateArgs>): React.ReactElement {
|
|
33
|
-
return React.createElement(SecretCreate, {
|
|
34
|
-
name,
|
|
35
|
-
value,
|
|
36
|
-
server: this.server,
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
delete({ name }: ArgumentsCamelCase<SecretDeleteArgs>): React.ReactElement {
|
|
41
|
-
return React.createElement(SecretDelete, { name, server: this.server });
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
bulk({ file }: ArgumentsCamelCase<SecretBulkArgs>): React.ReactElement {
|
|
45
|
-
return React.createElement(SecretBulk, {
|
|
46
|
-
file,
|
|
47
|
-
server: this.server
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
}
|