@positronic/cli 0.0.2

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 (193) hide show
  1. package/dist/src/cli.js +739 -0
  2. package/dist/src/commands/backend.js +199 -0
  3. package/dist/src/commands/brain.js +446 -0
  4. package/dist/src/commands/brain.test.js +2936 -0
  5. package/dist/src/commands/helpers.js +1315 -0
  6. package/dist/src/commands/helpers.test.js +832 -0
  7. package/dist/src/commands/project-config-manager.js +197 -0
  8. package/dist/src/commands/project.js +130 -0
  9. package/dist/src/commands/project.test.js +1201 -0
  10. package/dist/src/commands/resources.js +272 -0
  11. package/dist/src/commands/resources.test.js +2511 -0
  12. package/dist/src/commands/schedule.js +73 -0
  13. package/dist/src/commands/schedule.test.js +1235 -0
  14. package/dist/src/commands/secret.js +87 -0
  15. package/dist/src/commands/secret.test.d.js +1 -0
  16. package/dist/src/commands/secret.test.js +761 -0
  17. package/dist/src/commands/server.js +816 -0
  18. package/dist/src/commands/server.test.js +1237 -0
  19. package/dist/src/commands/test-utils.js +737 -0
  20. package/dist/src/components/brain-history.js +169 -0
  21. package/dist/src/components/brain-list.js +108 -0
  22. package/dist/src/components/brain-rerun.js +313 -0
  23. package/dist/src/components/brain-show.js +65 -0
  24. package/dist/src/components/error.js +19 -0
  25. package/dist/src/components/project-add.js +95 -0
  26. package/dist/src/components/project-create.js +276 -0
  27. package/dist/src/components/project-list.js +88 -0
  28. package/dist/src/components/project-remove.js +91 -0
  29. package/dist/src/components/project-select.js +224 -0
  30. package/dist/src/components/project-show.js +41 -0
  31. package/dist/src/components/resource-clear.js +152 -0
  32. package/dist/src/components/resource-delete.js +189 -0
  33. package/dist/src/components/resource-list.js +174 -0
  34. package/dist/src/components/resource-sync.js +386 -0
  35. package/dist/src/components/resource-types.js +243 -0
  36. package/dist/src/components/resource-upload.js +366 -0
  37. package/dist/src/components/schedule-create.js +259 -0
  38. package/dist/src/components/schedule-delete.js +161 -0
  39. package/dist/src/components/schedule-list.js +176 -0
  40. package/dist/src/components/schedule-runs.js +103 -0
  41. package/dist/src/components/secret-bulk.js +262 -0
  42. package/dist/src/components/secret-create.js +199 -0
  43. package/dist/src/components/secret-delete.js +190 -0
  44. package/dist/src/components/secret-list.js +190 -0
  45. package/dist/src/components/secret-sync.js +303 -0
  46. package/dist/src/components/watch.js +184 -0
  47. package/dist/src/hooks/useApi.js +512 -0
  48. package/dist/src/positronic.js +33 -0
  49. package/dist/src/test/mock-api-client.js +371 -0
  50. package/dist/src/test/test-dev-server.js +1376 -0
  51. package/dist/types/cli.d.ts +9 -0
  52. package/dist/types/cli.d.ts.map +1 -0
  53. package/dist/types/commands/backend.d.ts +6 -0
  54. package/dist/types/commands/backend.d.ts.map +1 -0
  55. package/dist/types/commands/brain.d.ts +35 -0
  56. package/dist/types/commands/brain.d.ts.map +1 -0
  57. package/dist/types/commands/helpers.d.ts +55 -0
  58. package/dist/types/commands/helpers.d.ts.map +1 -0
  59. package/dist/types/commands/project-config-manager.d.ts +37 -0
  60. package/dist/types/commands/project-config-manager.d.ts.map +1 -0
  61. package/dist/types/commands/project.d.ts +55 -0
  62. package/dist/types/commands/project.d.ts.map +1 -0
  63. package/dist/types/commands/resources.d.ts +13 -0
  64. package/dist/types/commands/resources.d.ts.map +1 -0
  65. package/dist/types/commands/schedule.d.ts +27 -0
  66. package/dist/types/commands/schedule.d.ts.map +1 -0
  67. package/dist/types/commands/secret.d.ts +23 -0
  68. package/dist/types/commands/secret.d.ts.map +1 -0
  69. package/dist/types/commands/server.d.ts +12 -0
  70. package/dist/types/commands/server.d.ts.map +1 -0
  71. package/dist/types/commands/test-utils.d.ts +45 -0
  72. package/dist/types/commands/test-utils.d.ts.map +1 -0
  73. package/dist/types/components/brain-history.d.ts +7 -0
  74. package/dist/types/components/brain-history.d.ts.map +1 -0
  75. package/dist/types/components/brain-list.d.ts +2 -0
  76. package/dist/types/components/brain-list.d.ts.map +1 -0
  77. package/dist/types/components/brain-rerun.d.ts +9 -0
  78. package/dist/types/components/brain-rerun.d.ts.map +1 -0
  79. package/dist/types/components/brain-show.d.ts +6 -0
  80. package/dist/types/components/brain-show.d.ts.map +1 -0
  81. package/dist/types/components/error.d.ts +10 -0
  82. package/dist/types/components/error.d.ts.map +1 -0
  83. package/dist/types/components/project-add.d.ts +9 -0
  84. package/dist/types/components/project-add.d.ts.map +1 -0
  85. package/dist/types/components/project-create.d.ts +6 -0
  86. package/dist/types/components/project-create.d.ts.map +1 -0
  87. package/dist/types/components/project-list.d.ts +7 -0
  88. package/dist/types/components/project-list.d.ts.map +1 -0
  89. package/dist/types/components/project-remove.d.ts +8 -0
  90. package/dist/types/components/project-remove.d.ts.map +1 -0
  91. package/dist/types/components/project-select.d.ts +8 -0
  92. package/dist/types/components/project-select.d.ts.map +1 -0
  93. package/dist/types/components/project-show.d.ts +7 -0
  94. package/dist/types/components/project-show.d.ts.map +1 -0
  95. package/dist/types/components/resource-clear.d.ts +2 -0
  96. package/dist/types/components/resource-clear.d.ts.map +1 -0
  97. package/dist/types/components/resource-delete.d.ts +9 -0
  98. package/dist/types/components/resource-delete.d.ts.map +1 -0
  99. package/dist/types/components/resource-list.d.ts +2 -0
  100. package/dist/types/components/resource-list.d.ts.map +1 -0
  101. package/dist/types/components/resource-sync.d.ts +8 -0
  102. package/dist/types/components/resource-sync.d.ts.map +1 -0
  103. package/dist/types/components/resource-types.d.ts +7 -0
  104. package/dist/types/components/resource-types.d.ts.map +1 -0
  105. package/dist/types/components/resource-upload.d.ts +8 -0
  106. package/dist/types/components/resource-upload.d.ts.map +1 -0
  107. package/dist/types/components/schedule-create.d.ts +7 -0
  108. package/dist/types/components/schedule-create.d.ts.map +1 -0
  109. package/dist/types/components/schedule-delete.d.ts +7 -0
  110. package/dist/types/components/schedule-delete.d.ts.map +1 -0
  111. package/dist/types/components/schedule-list.d.ts +6 -0
  112. package/dist/types/components/schedule-list.d.ts.map +1 -0
  113. package/dist/types/components/schedule-runs.d.ts +8 -0
  114. package/dist/types/components/schedule-runs.d.ts.map +1 -0
  115. package/dist/types/components/secret-bulk.d.ts +8 -0
  116. package/dist/types/components/secret-bulk.d.ts.map +1 -0
  117. package/dist/types/components/secret-create.d.ts +9 -0
  118. package/dist/types/components/secret-create.d.ts.map +1 -0
  119. package/dist/types/components/secret-delete.d.ts +8 -0
  120. package/dist/types/components/secret-delete.d.ts.map +1 -0
  121. package/dist/types/components/secret-list.d.ts +7 -0
  122. package/dist/types/components/secret-list.d.ts.map +1 -0
  123. package/dist/types/components/secret-sync.d.ts +9 -0
  124. package/dist/types/components/secret-sync.d.ts.map +1 -0
  125. package/dist/types/components/watch.d.ts +7 -0
  126. package/dist/types/components/watch.d.ts.map +1 -0
  127. package/dist/types/hooks/useApi.d.ts +29 -0
  128. package/dist/types/hooks/useApi.d.ts.map +1 -0
  129. package/dist/types/positronic.d.ts +3 -0
  130. package/dist/types/positronic.d.ts.map +1 -0
  131. package/dist/types/test/mock-api-client.d.ts +25 -0
  132. package/dist/types/test/mock-api-client.d.ts.map +1 -0
  133. package/dist/types/test/test-dev-server.d.ts +129 -0
  134. package/dist/types/test/test-dev-server.d.ts.map +1 -0
  135. package/package.json +37 -0
  136. package/src/cli.ts +981 -0
  137. package/src/commands/backend.ts +63 -0
  138. package/src/commands/brain.test.ts +1004 -0
  139. package/src/commands/brain.ts +215 -0
  140. package/src/commands/helpers.test.ts +487 -0
  141. package/src/commands/helpers.ts +870 -0
  142. package/src/commands/project-config-manager.ts +152 -0
  143. package/src/commands/project.test.ts +502 -0
  144. package/src/commands/project.ts +109 -0
  145. package/src/commands/resources.test.ts +1052 -0
  146. package/src/commands/resources.ts +97 -0
  147. package/src/commands/schedule.test.ts +481 -0
  148. package/src/commands/schedule.ts +65 -0
  149. package/src/commands/secret.test.ts +210 -0
  150. package/src/commands/secret.ts +50 -0
  151. package/src/commands/server.test.ts +493 -0
  152. package/src/commands/server.ts +353 -0
  153. package/src/commands/test-utils.ts +324 -0
  154. package/src/components/brain-history.tsx +198 -0
  155. package/src/components/brain-list.tsx +105 -0
  156. package/src/components/brain-rerun.tsx +111 -0
  157. package/src/components/brain-show.tsx +92 -0
  158. package/src/components/error.tsx +24 -0
  159. package/src/components/project-add.tsx +59 -0
  160. package/src/components/project-create.tsx +83 -0
  161. package/src/components/project-list.tsx +83 -0
  162. package/src/components/project-remove.tsx +55 -0
  163. package/src/components/project-select.tsx +200 -0
  164. package/src/components/project-show.tsx +58 -0
  165. package/src/components/resource-clear.tsx +127 -0
  166. package/src/components/resource-delete.tsx +160 -0
  167. package/src/components/resource-list.tsx +177 -0
  168. package/src/components/resource-sync.tsx +170 -0
  169. package/src/components/resource-types.tsx +55 -0
  170. package/src/components/resource-upload.tsx +182 -0
  171. package/src/components/schedule-create.tsx +90 -0
  172. package/src/components/schedule-delete.tsx +116 -0
  173. package/src/components/schedule-list.tsx +186 -0
  174. package/src/components/schedule-runs.tsx +151 -0
  175. package/src/components/secret-bulk.tsx +79 -0
  176. package/src/components/secret-create.tsx +49 -0
  177. package/src/components/secret-delete.tsx +41 -0
  178. package/src/components/secret-list.tsx +41 -0
  179. package/src/components/watch.tsx +155 -0
  180. package/src/hooks/useApi.ts +183 -0
  181. package/src/positronic.ts +40 -0
  182. package/src/test/data/resources/config.json +1 -0
  183. package/src/test/data/resources/data/config.json +1 -0
  184. package/src/test/data/resources/data/logo.png +2 -0
  185. package/src/test/data/resources/docs/api.md +3 -0
  186. package/src/test/data/resources/docs/readme.md +3 -0
  187. package/src/test/data/resources/example.md +3 -0
  188. package/src/test/data/resources/file with spaces.txt +1 -0
  189. package/src/test/data/resources/readme.md +3 -0
  190. package/src/test/data/resources/test.txt +1 -0
  191. package/src/test/mock-api-client.ts +145 -0
  192. package/src/test/test-dev-server.ts +1003 -0
  193. package/tsconfig.json +11 -0
@@ -0,0 +1,1235 @@
1
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
2
+ try {
3
+ var info = gen[key](arg);
4
+ var value = info.value;
5
+ } catch (error) {
6
+ reject(error);
7
+ return;
8
+ }
9
+ if (info.done) {
10
+ resolve(value);
11
+ } else {
12
+ Promise.resolve(value).then(_next, _throw);
13
+ }
14
+ }
15
+ function _async_to_generator(fn) {
16
+ return function() {
17
+ var self = this, args = arguments;
18
+ return new Promise(function(resolve, reject) {
19
+ var gen = fn.apply(self, args);
20
+ function _next(value) {
21
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
22
+ }
23
+ function _throw(err) {
24
+ asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
25
+ }
26
+ _next(undefined);
27
+ });
28
+ };
29
+ }
30
+ function _ts_generator(thisArg, body) {
31
+ var f, y, t, _ = {
32
+ label: 0,
33
+ sent: function() {
34
+ if (t[0] & 1) throw t[1];
35
+ return t[1];
36
+ },
37
+ trys: [],
38
+ ops: []
39
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
40
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
41
+ return this;
42
+ }), g;
43
+ function verb(n) {
44
+ return function(v) {
45
+ return step([
46
+ n,
47
+ v
48
+ ]);
49
+ };
50
+ }
51
+ function step(op) {
52
+ if (f) throw new TypeError("Generator is already executing.");
53
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
54
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
55
+ if (y = 0, t) op = [
56
+ op[0] & 2,
57
+ t.value
58
+ ];
59
+ switch(op[0]){
60
+ case 0:
61
+ case 1:
62
+ t = op;
63
+ break;
64
+ case 4:
65
+ _.label++;
66
+ return {
67
+ value: op[1],
68
+ done: false
69
+ };
70
+ case 5:
71
+ _.label++;
72
+ y = op[1];
73
+ op = [
74
+ 0
75
+ ];
76
+ continue;
77
+ case 7:
78
+ op = _.ops.pop();
79
+ _.trys.pop();
80
+ continue;
81
+ default:
82
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
83
+ _ = 0;
84
+ continue;
85
+ }
86
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
87
+ _.label = op[1];
88
+ break;
89
+ }
90
+ if (op[0] === 6 && _.label < t[1]) {
91
+ _.label = t[1];
92
+ t = op;
93
+ break;
94
+ }
95
+ if (t && _.label < t[2]) {
96
+ _.label = t[2];
97
+ _.ops.push(op);
98
+ break;
99
+ }
100
+ if (t[2]) _.ops.pop();
101
+ _.trys.pop();
102
+ continue;
103
+ }
104
+ op = body.call(thisArg, _);
105
+ } catch (e) {
106
+ op = [
107
+ 6,
108
+ e
109
+ ];
110
+ y = 0;
111
+ } finally{
112
+ f = t = 0;
113
+ }
114
+ if (op[0] & 5) throw op[1];
115
+ return {
116
+ value: op[0] ? op[1] : void 0,
117
+ done: true
118
+ };
119
+ }
120
+ }
121
+ import { describe, it, expect, jest, beforeEach, afterEach } from '@jest/globals';
122
+ import { createTestEnv, px } from './test-utils.js';
123
+ describe('schedule command', function() {
124
+ describe('schedule create', function() {
125
+ it('should create a new schedule', function() {
126
+ return _async_to_generator(function() {
127
+ var env, px, _ref, waitForOutput, instance, foundSuccess, output, methodCalls, createCall;
128
+ return _ts_generator(this, function(_state) {
129
+ switch(_state.label){
130
+ case 0:
131
+ return [
132
+ 4,
133
+ createTestEnv()
134
+ ];
135
+ case 1:
136
+ env = _state.sent();
137
+ return [
138
+ 4,
139
+ env.start()
140
+ ];
141
+ case 2:
142
+ px = _state.sent();
143
+ _state.label = 3;
144
+ case 3:
145
+ _state.trys.push([
146
+ 3,
147
+ ,
148
+ 6,
149
+ 8
150
+ ]);
151
+ return [
152
+ 4,
153
+ px([
154
+ 'schedule',
155
+ 'create',
156
+ 'test-brain',
157
+ '0 3 * * *'
158
+ ])
159
+ ];
160
+ case 4:
161
+ _ref = _state.sent(), waitForOutput = _ref.waitForOutput, instance = _ref.instance;
162
+ return [
163
+ 4,
164
+ waitForOutput(/Schedule created successfully/i, 50)
165
+ ];
166
+ case 5:
167
+ foundSuccess = _state.sent();
168
+ expect(foundSuccess).toBe(true);
169
+ // Verify the output contains the brain name and cron expression
170
+ output = instance.lastFrame() || '';
171
+ expect(output).toContain('test-brain');
172
+ expect(output).toContain('0 3 * * *');
173
+ // Verify the API call was made
174
+ methodCalls = env.server.getLogs();
175
+ createCall = methodCalls.find(function(call) {
176
+ return call.method === 'createSchedule';
177
+ });
178
+ expect(createCall).toBeDefined();
179
+ expect(createCall.args[0]).toEqual({
180
+ brainName: 'test-brain',
181
+ cronExpression: '0 3 * * *'
182
+ });
183
+ return [
184
+ 3,
185
+ 8
186
+ ];
187
+ case 6:
188
+ return [
189
+ 4,
190
+ env.stopAndCleanup()
191
+ ];
192
+ case 7:
193
+ _state.sent();
194
+ return [
195
+ 7
196
+ ];
197
+ case 8:
198
+ return [
199
+ 2
200
+ ];
201
+ }
202
+ });
203
+ })();
204
+ });
205
+ it('should handle server connection errors gracefully', function() {
206
+ return _async_to_generator(function() {
207
+ var env, waitForOutput, foundError;
208
+ return _ts_generator(this, function(_state) {
209
+ switch(_state.label){
210
+ case 0:
211
+ return [
212
+ 4,
213
+ createTestEnv()
214
+ ];
215
+ case 1:
216
+ env = _state.sent();
217
+ _state.label = 2;
218
+ case 2:
219
+ _state.trys.push([
220
+ 2,
221
+ ,
222
+ 5,
223
+ 6
224
+ ]);
225
+ return [
226
+ 4,
227
+ px([
228
+ 'schedule',
229
+ 'create',
230
+ 'test-brain',
231
+ '0 3 * * *'
232
+ ], {
233
+ server: env.server
234
+ })
235
+ ];
236
+ case 3:
237
+ waitForOutput = _state.sent().waitForOutput;
238
+ return [
239
+ 4,
240
+ waitForOutput(/Error connecting to the local development server/i)
241
+ ];
242
+ case 4:
243
+ foundError = _state.sent();
244
+ expect(foundError).toBe(true);
245
+ return [
246
+ 3,
247
+ 6
248
+ ];
249
+ case 5:
250
+ env.cleanup();
251
+ return [
252
+ 7
253
+ ];
254
+ case 6:
255
+ return [
256
+ 2
257
+ ];
258
+ }
259
+ });
260
+ })();
261
+ });
262
+ });
263
+ describe('schedule list', function() {
264
+ var originalExit;
265
+ beforeEach(function() {
266
+ // Mock process.exit but don't throw - just track the call
267
+ originalExit = process.exit;
268
+ process.exit = jest.fn();
269
+ });
270
+ afterEach(function() {
271
+ process.exit = originalExit;
272
+ });
273
+ it('should list schedules when no schedules exist', function() {
274
+ return _async_to_generator(function() {
275
+ var env, px, waitForOutput, foundEmpty, calls, listCall;
276
+ return _ts_generator(this, function(_state) {
277
+ switch(_state.label){
278
+ case 0:
279
+ return [
280
+ 4,
281
+ createTestEnv()
282
+ ];
283
+ case 1:
284
+ env = _state.sent();
285
+ return [
286
+ 4,
287
+ env.start()
288
+ ];
289
+ case 2:
290
+ px = _state.sent();
291
+ _state.label = 3;
292
+ case 3:
293
+ _state.trys.push([
294
+ 3,
295
+ ,
296
+ 6,
297
+ 8
298
+ ]);
299
+ return [
300
+ 4,
301
+ px([
302
+ 'schedule',
303
+ '-l'
304
+ ])
305
+ ];
306
+ case 4:
307
+ waitForOutput = _state.sent().waitForOutput;
308
+ return [
309
+ 4,
310
+ waitForOutput(/No schedules found/i, 30)
311
+ ];
312
+ case 5:
313
+ foundEmpty = _state.sent();
314
+ expect(foundEmpty).toBe(true);
315
+ // Verify process.exit was called
316
+ expect(process.exit).toHaveBeenCalledWith(0);
317
+ // Verify API call was made
318
+ calls = env.server.getLogs();
319
+ listCall = calls.find(function(c) {
320
+ return c.method === 'getSchedules';
321
+ });
322
+ expect(listCall).toBeDefined();
323
+ return [
324
+ 3,
325
+ 8
326
+ ];
327
+ case 6:
328
+ return [
329
+ 4,
330
+ env.stopAndCleanup()
331
+ ];
332
+ case 7:
333
+ _state.sent();
334
+ return [
335
+ 7
336
+ ];
337
+ case 8:
338
+ return [
339
+ 2
340
+ ];
341
+ }
342
+ });
343
+ })();
344
+ });
345
+ it('should list schedules when schedules exist', function() {
346
+ return _async_to_generator(function() {
347
+ var env, server, px, _ref, waitForOutput, instance, foundSchedules, output, calls, listCall;
348
+ return _ts_generator(this, function(_state) {
349
+ switch(_state.label){
350
+ case 0:
351
+ return [
352
+ 4,
353
+ createTestEnv()
354
+ ];
355
+ case 1:
356
+ env = _state.sent();
357
+ server = env.server;
358
+ // Add test schedules
359
+ server.addSchedule({
360
+ id: 'schedule-1',
361
+ brainName: 'daily-report',
362
+ cronExpression: '0 9 * * *',
363
+ enabled: true,
364
+ createdAt: Date.now() - 86400000,
365
+ nextRunAt: Date.now() + 3600000
366
+ });
367
+ server.addSchedule({
368
+ id: 'schedule-2',
369
+ brainName: 'hourly-sync',
370
+ cronExpression: '0 * * * *',
371
+ enabled: true,
372
+ createdAt: Date.now() - 172800000,
373
+ nextRunAt: Date.now() + 1800000
374
+ });
375
+ return [
376
+ 4,
377
+ env.start()
378
+ ];
379
+ case 2:
380
+ px = _state.sent();
381
+ _state.label = 3;
382
+ case 3:
383
+ _state.trys.push([
384
+ 3,
385
+ ,
386
+ 6,
387
+ 8
388
+ ]);
389
+ return [
390
+ 4,
391
+ px([
392
+ 'schedule',
393
+ '-l'
394
+ ])
395
+ ];
396
+ case 4:
397
+ _ref = _state.sent(), waitForOutput = _ref.waitForOutput, instance = _ref.instance;
398
+ return [
399
+ 4,
400
+ waitForOutput(/daily-report/i, 30)
401
+ ];
402
+ case 5:
403
+ foundSchedules = _state.sent();
404
+ expect(foundSchedules).toBe(true);
405
+ // Check that both schedules are shown
406
+ output = instance.lastFrame() || '';
407
+ expect(output).toContain('daily-report');
408
+ expect(output).toContain('hourly-sync');
409
+ expect(output).toContain('0 9 * * *');
410
+ expect(output).toContain('0 * * * *');
411
+ // Verify process.exit was called
412
+ expect(process.exit).toHaveBeenCalledWith(0);
413
+ // Verify API call was made
414
+ calls = server.getLogs();
415
+ listCall = calls.find(function(c) {
416
+ return c.method === 'getSchedules';
417
+ });
418
+ expect(listCall).toBeDefined();
419
+ return [
420
+ 3,
421
+ 8
422
+ ];
423
+ case 6:
424
+ return [
425
+ 4,
426
+ env.stopAndCleanup()
427
+ ];
428
+ case 7:
429
+ _state.sent();
430
+ return [
431
+ 7
432
+ ];
433
+ case 8:
434
+ return [
435
+ 2
436
+ ];
437
+ }
438
+ });
439
+ })();
440
+ });
441
+ it('should filter schedules by brain name', function() {
442
+ return _async_to_generator(function() {
443
+ var env, server, px, _ref, waitForOutput, instance, foundSchedule, output, calls, listCall;
444
+ return _ts_generator(this, function(_state) {
445
+ switch(_state.label){
446
+ case 0:
447
+ return [
448
+ 4,
449
+ createTestEnv()
450
+ ];
451
+ case 1:
452
+ env = _state.sent();
453
+ server = env.server;
454
+ // Add test schedules
455
+ server.addSchedule({
456
+ id: 'schedule-1',
457
+ brainName: 'daily-report',
458
+ cronExpression: '0 9 * * *',
459
+ enabled: true,
460
+ createdAt: Date.now(),
461
+ nextRunAt: Date.now() + 3600000
462
+ });
463
+ server.addSchedule({
464
+ id: 'schedule-2',
465
+ brainName: 'hourly-sync',
466
+ cronExpression: '0 * * * *',
467
+ enabled: true,
468
+ createdAt: Date.now(),
469
+ nextRunAt: Date.now() + 1800000
470
+ });
471
+ return [
472
+ 4,
473
+ env.start()
474
+ ];
475
+ case 2:
476
+ px = _state.sent();
477
+ _state.label = 3;
478
+ case 3:
479
+ _state.trys.push([
480
+ 3,
481
+ ,
482
+ 6,
483
+ 8
484
+ ]);
485
+ return [
486
+ 4,
487
+ px([
488
+ 'schedule',
489
+ '-l',
490
+ '--brain',
491
+ 'daily-report'
492
+ ])
493
+ ];
494
+ case 4:
495
+ _ref = _state.sent(), waitForOutput = _ref.waitForOutput, instance = _ref.instance;
496
+ return [
497
+ 4,
498
+ waitForOutput(/daily-report/i, 30)
499
+ ];
500
+ case 5:
501
+ foundSchedule = _state.sent();
502
+ expect(foundSchedule).toBe(true);
503
+ // Verify only the filtered schedule is shown
504
+ output = instance.lastFrame() || '';
505
+ expect(output).toContain('daily-report');
506
+ expect(output).not.toContain('hourly-sync');
507
+ // Verify process.exit was called
508
+ expect(process.exit).toHaveBeenCalledWith(0);
509
+ // Verify API call was made
510
+ calls = server.getLogs();
511
+ listCall = calls.find(function(c) {
512
+ return c.method === 'getSchedules';
513
+ });
514
+ expect(listCall).toBeDefined();
515
+ return [
516
+ 3,
517
+ 8
518
+ ];
519
+ case 6:
520
+ return [
521
+ 4,
522
+ env.stopAndCleanup()
523
+ ];
524
+ case 7:
525
+ _state.sent();
526
+ return [
527
+ 7
528
+ ];
529
+ case 8:
530
+ return [
531
+ 2
532
+ ];
533
+ }
534
+ });
535
+ })();
536
+ });
537
+ it('should handle server connection errors', function() {
538
+ return _async_to_generator(function() {
539
+ var env, waitForOutput, foundError;
540
+ return _ts_generator(this, function(_state) {
541
+ switch(_state.label){
542
+ case 0:
543
+ return [
544
+ 4,
545
+ createTestEnv()
546
+ ];
547
+ case 1:
548
+ env = _state.sent();
549
+ _state.label = 2;
550
+ case 2:
551
+ _state.trys.push([
552
+ 2,
553
+ ,
554
+ 5,
555
+ 6
556
+ ]);
557
+ return [
558
+ 4,
559
+ px([
560
+ 'schedule',
561
+ '-l'
562
+ ], {
563
+ server: env.server
564
+ })
565
+ ];
566
+ case 3:
567
+ waitForOutput = _state.sent().waitForOutput;
568
+ return [
569
+ 4,
570
+ waitForOutput(/Error connecting to the local development server/i, 30)
571
+ ];
572
+ case 4:
573
+ foundError = _state.sent();
574
+ expect(foundError).toBe(true);
575
+ // Verify process.exit was called
576
+ expect(process.exit).toHaveBeenCalledWith(0);
577
+ return [
578
+ 3,
579
+ 6
580
+ ];
581
+ case 5:
582
+ env.cleanup();
583
+ return [
584
+ 7
585
+ ];
586
+ case 6:
587
+ return [
588
+ 2
589
+ ];
590
+ }
591
+ });
592
+ })();
593
+ });
594
+ });
595
+ describe('schedule delete', function() {
596
+ var originalExit;
597
+ beforeEach(function() {
598
+ // Mock process.exit but don't throw - just track the call
599
+ originalExit = process.exit;
600
+ process.exit = jest.fn();
601
+ });
602
+ afterEach(function() {
603
+ process.exit = originalExit;
604
+ });
605
+ it('should delete a schedule successfully', function() {
606
+ return _async_to_generator(function() {
607
+ var env, server, px, waitForOutput, foundSuccess, calls, deleteCall;
608
+ return _ts_generator(this, function(_state) {
609
+ switch(_state.label){
610
+ case 0:
611
+ return [
612
+ 4,
613
+ createTestEnv()
614
+ ];
615
+ case 1:
616
+ env = _state.sent();
617
+ server = env.server;
618
+ // Add a schedule to delete
619
+ server.addSchedule({
620
+ id: 'schedule-to-delete',
621
+ brainName: 'test-brain',
622
+ cronExpression: '0 * * * *',
623
+ enabled: true,
624
+ createdAt: Date.now(),
625
+ nextRunAt: Date.now() + 3600000
626
+ });
627
+ return [
628
+ 4,
629
+ env.start()
630
+ ];
631
+ case 2:
632
+ px = _state.sent();
633
+ _state.label = 3;
634
+ case 3:
635
+ _state.trys.push([
636
+ 3,
637
+ ,
638
+ 6,
639
+ 8
640
+ ]);
641
+ return [
642
+ 4,
643
+ px([
644
+ 'schedule',
645
+ '-d',
646
+ 'schedule-to-delete',
647
+ '--force'
648
+ ])
649
+ ];
650
+ case 4:
651
+ waitForOutput = _state.sent().waitForOutput;
652
+ return [
653
+ 4,
654
+ waitForOutput(/Schedule deleted successfully/i, 30)
655
+ ];
656
+ case 5:
657
+ foundSuccess = _state.sent();
658
+ expect(foundSuccess).toBe(true);
659
+ // Verify process.exit was called
660
+ expect(process.exit).toHaveBeenCalledWith(0);
661
+ // Verify API call was made
662
+ calls = server.getLogs();
663
+ deleteCall = calls.find(function(c) {
664
+ return c.method === 'deleteSchedule';
665
+ });
666
+ expect(deleteCall).toBeDefined();
667
+ expect(deleteCall.args[0]).toBe('schedule-to-delete');
668
+ // Verify schedule was removed from server
669
+ expect(server.getSchedules().length).toBe(0);
670
+ return [
671
+ 3,
672
+ 8
673
+ ];
674
+ case 6:
675
+ return [
676
+ 4,
677
+ env.stopAndCleanup()
678
+ ];
679
+ case 7:
680
+ _state.sent();
681
+ return [
682
+ 7
683
+ ];
684
+ case 8:
685
+ return [
686
+ 2
687
+ ];
688
+ }
689
+ });
690
+ })();
691
+ });
692
+ it('should handle deleting non-existent schedule', function() {
693
+ return _async_to_generator(function() {
694
+ var env, server, px, waitForOutput, foundError, calls;
695
+ return _ts_generator(this, function(_state) {
696
+ switch(_state.label){
697
+ case 0:
698
+ return [
699
+ 4,
700
+ createTestEnv()
701
+ ];
702
+ case 1:
703
+ env = _state.sent();
704
+ server = env.server;
705
+ return [
706
+ 4,
707
+ env.start()
708
+ ];
709
+ case 2:
710
+ px = _state.sent();
711
+ _state.label = 3;
712
+ case 3:
713
+ _state.trys.push([
714
+ 3,
715
+ ,
716
+ 6,
717
+ 8
718
+ ]);
719
+ return [
720
+ 4,
721
+ px([
722
+ 'schedule',
723
+ '-d',
724
+ 'non-existent-id',
725
+ '--force'
726
+ ])
727
+ ];
728
+ case 4:
729
+ waitForOutput = _state.sent().waitForOutput;
730
+ return [
731
+ 4,
732
+ waitForOutput(/not found/i, 30)
733
+ ];
734
+ case 5:
735
+ foundError = _state.sent();
736
+ expect(foundError).toBe(true);
737
+ // Verify process.exit was called
738
+ expect(process.exit).toHaveBeenCalledWith(0);
739
+ // Verify no deleteSchedule call was logged (404 handled by nock)
740
+ calls = server.getLogs();
741
+ // The server still logs the attempt, but nock returns 404
742
+ expect(calls.some(function(c) {
743
+ return c.method === 'start';
744
+ })).toBe(true);
745
+ return [
746
+ 3,
747
+ 8
748
+ ];
749
+ case 6:
750
+ return [
751
+ 4,
752
+ env.stopAndCleanup()
753
+ ];
754
+ case 7:
755
+ _state.sent();
756
+ return [
757
+ 7
758
+ ];
759
+ case 8:
760
+ return [
761
+ 2
762
+ ];
763
+ }
764
+ });
765
+ })();
766
+ });
767
+ // Skipping this test due to complexities with stdin handling in test environment
768
+ // The delete functionality is covered by the force flag test
769
+ it('should handle server connection errors', function() {
770
+ return _async_to_generator(function() {
771
+ var env, waitForOutput, foundError;
772
+ return _ts_generator(this, function(_state) {
773
+ switch(_state.label){
774
+ case 0:
775
+ return [
776
+ 4,
777
+ createTestEnv()
778
+ ];
779
+ case 1:
780
+ env = _state.sent();
781
+ _state.label = 2;
782
+ case 2:
783
+ _state.trys.push([
784
+ 2,
785
+ ,
786
+ 5,
787
+ 6
788
+ ]);
789
+ return [
790
+ 4,
791
+ px([
792
+ 'schedule',
793
+ '-d',
794
+ 'some-id',
795
+ '--force'
796
+ ], {
797
+ server: env.server
798
+ })
799
+ ];
800
+ case 3:
801
+ waitForOutput = _state.sent().waitForOutput;
802
+ return [
803
+ 4,
804
+ waitForOutput(/Error connecting to the local development server/i, 30)
805
+ ];
806
+ case 4:
807
+ foundError = _state.sent();
808
+ expect(foundError).toBe(true);
809
+ // Verify process.exit was called
810
+ expect(process.exit).toHaveBeenCalledWith(0);
811
+ return [
812
+ 3,
813
+ 6
814
+ ];
815
+ case 5:
816
+ env.cleanup();
817
+ return [
818
+ 7
819
+ ];
820
+ case 6:
821
+ return [
822
+ 2
823
+ ];
824
+ }
825
+ });
826
+ })();
827
+ });
828
+ });
829
+ describe('schedule runs', function() {
830
+ it('should show empty state when no runs exist', function() {
831
+ return _async_to_generator(function() {
832
+ var env, px, waitForOutput, foundMessage, calls, runsCall;
833
+ return _ts_generator(this, function(_state) {
834
+ switch(_state.label){
835
+ case 0:
836
+ return [
837
+ 4,
838
+ createTestEnv()
839
+ ];
840
+ case 1:
841
+ env = _state.sent();
842
+ return [
843
+ 4,
844
+ env.start()
845
+ ];
846
+ case 2:
847
+ px = _state.sent();
848
+ _state.label = 3;
849
+ case 3:
850
+ _state.trys.push([
851
+ 3,
852
+ ,
853
+ 6,
854
+ 8
855
+ ]);
856
+ return [
857
+ 4,
858
+ px([
859
+ 'schedule',
860
+ 'runs'
861
+ ])
862
+ ];
863
+ case 4:
864
+ waitForOutput = _state.sent().waitForOutput;
865
+ return [
866
+ 4,
867
+ waitForOutput(/No scheduled runs found/i, 30)
868
+ ];
869
+ case 5:
870
+ foundMessage = _state.sent();
871
+ expect(foundMessage).toBe(true);
872
+ // Verify API call was made
873
+ calls = env.server.getLogs();
874
+ runsCall = calls.find(function(c) {
875
+ return c.method === 'getScheduleRuns';
876
+ });
877
+ expect(runsCall).toBeDefined();
878
+ return [
879
+ 3,
880
+ 8
881
+ ];
882
+ case 6:
883
+ return [
884
+ 4,
885
+ env.stopAndCleanup()
886
+ ];
887
+ case 7:
888
+ _state.sent();
889
+ return [
890
+ 7
891
+ ];
892
+ case 8:
893
+ return [
894
+ 2
895
+ ];
896
+ }
897
+ });
898
+ })();
899
+ });
900
+ it('should list scheduled runs when they exist', function() {
901
+ return _async_to_generator(function() {
902
+ var env, server, px, waitForOutput, foundRuns, foundRun1, foundRun2;
903
+ return _ts_generator(this, function(_state) {
904
+ switch(_state.label){
905
+ case 0:
906
+ return [
907
+ 4,
908
+ createTestEnv()
909
+ ];
910
+ case 1:
911
+ env = _state.sent();
912
+ server = env.server;
913
+ // Add some scheduled runs
914
+ server.addScheduleRun({
915
+ id: 'run-1',
916
+ scheduleId: 'schedule-1',
917
+ status: 'triggered',
918
+ ranAt: Date.now() - 3600000
919
+ });
920
+ server.addScheduleRun({
921
+ id: 'run-2',
922
+ scheduleId: 'schedule-2',
923
+ status: 'failed',
924
+ ranAt: Date.now() - 7200000,
925
+ error: 'Connection timeout'
926
+ });
927
+ return [
928
+ 4,
929
+ env.start()
930
+ ];
931
+ case 2:
932
+ px = _state.sent();
933
+ _state.label = 3;
934
+ case 3:
935
+ _state.trys.push([
936
+ 3,
937
+ ,
938
+ 8,
939
+ 10
940
+ ]);
941
+ return [
942
+ 4,
943
+ px([
944
+ 'schedule',
945
+ 'runs'
946
+ ])
947
+ ];
948
+ case 4:
949
+ waitForOutput = _state.sent().waitForOutput;
950
+ return [
951
+ 4,
952
+ waitForOutput(/Found 2 scheduled runs/i, 30)
953
+ ];
954
+ case 5:
955
+ foundRuns = _state.sent();
956
+ expect(foundRuns).toBe(true);
957
+ return [
958
+ 4,
959
+ waitForOutput(/run-1/i, 30)
960
+ ];
961
+ case 6:
962
+ foundRun1 = _state.sent();
963
+ expect(foundRun1).toBe(true);
964
+ return [
965
+ 4,
966
+ waitForOutput(/run-2/i, 30)
967
+ ];
968
+ case 7:
969
+ foundRun2 = _state.sent();
970
+ expect(foundRun2).toBe(true);
971
+ return [
972
+ 3,
973
+ 10
974
+ ];
975
+ case 8:
976
+ return [
977
+ 4,
978
+ env.stopAndCleanup()
979
+ ];
980
+ case 9:
981
+ _state.sent();
982
+ return [
983
+ 7
984
+ ];
985
+ case 10:
986
+ return [
987
+ 2
988
+ ];
989
+ }
990
+ });
991
+ })();
992
+ });
993
+ it('should filter runs by schedule ID', function() {
994
+ return _async_to_generator(function() {
995
+ var env, server, px, _ref, waitForOutput, instance, foundMessage, output;
996
+ return _ts_generator(this, function(_state) {
997
+ switch(_state.label){
998
+ case 0:
999
+ return [
1000
+ 4,
1001
+ createTestEnv()
1002
+ ];
1003
+ case 1:
1004
+ env = _state.sent();
1005
+ server = env.server;
1006
+ // Add runs for different schedules
1007
+ server.addScheduleRun({
1008
+ id: 'run-1',
1009
+ scheduleId: 'schedule-abc',
1010
+ status: 'triggered',
1011
+ ranAt: Date.now() - 3600000
1012
+ });
1013
+ server.addScheduleRun({
1014
+ id: 'run-2',
1015
+ scheduleId: 'schedule-xyz',
1016
+ status: 'triggered',
1017
+ ranAt: Date.now() - 7200000
1018
+ });
1019
+ return [
1020
+ 4,
1021
+ env.start()
1022
+ ];
1023
+ case 2:
1024
+ px = _state.sent();
1025
+ _state.label = 3;
1026
+ case 3:
1027
+ _state.trys.push([
1028
+ 3,
1029
+ ,
1030
+ 6,
1031
+ 8
1032
+ ]);
1033
+ return [
1034
+ 4,
1035
+ px([
1036
+ 'schedule',
1037
+ 'runs',
1038
+ '--schedule-id',
1039
+ 'schedule-abc'
1040
+ ])
1041
+ ];
1042
+ case 4:
1043
+ _ref = _state.sent(), waitForOutput = _ref.waitForOutput, instance = _ref.instance;
1044
+ return [
1045
+ 4,
1046
+ waitForOutput(/Found 1 scheduled run for schedule schedule-abc/i, 30)
1047
+ ];
1048
+ case 5:
1049
+ foundMessage = _state.sent();
1050
+ expect(foundMessage).toBe(true);
1051
+ // Verify only the filtered run is shown
1052
+ output = instance.lastFrame() || '';
1053
+ expect(output).toContain('run-1');
1054
+ expect(output).not.toContain('run-2');
1055
+ return [
1056
+ 3,
1057
+ 8
1058
+ ];
1059
+ case 6:
1060
+ return [
1061
+ 4,
1062
+ env.stopAndCleanup()
1063
+ ];
1064
+ case 7:
1065
+ _state.sent();
1066
+ return [
1067
+ 7
1068
+ ];
1069
+ case 8:
1070
+ return [
1071
+ 2
1072
+ ];
1073
+ }
1074
+ });
1075
+ })();
1076
+ });
1077
+ it('should filter runs by status', function() {
1078
+ return _async_to_generator(function() {
1079
+ var env, server, px, _ref, waitForOutput, instance, foundMessage, output;
1080
+ return _ts_generator(this, function(_state) {
1081
+ switch(_state.label){
1082
+ case 0:
1083
+ return [
1084
+ 4,
1085
+ createTestEnv()
1086
+ ];
1087
+ case 1:
1088
+ env = _state.sent();
1089
+ server = env.server;
1090
+ // Add runs with different statuses
1091
+ server.addScheduleRun({
1092
+ id: 'run-1',
1093
+ scheduleId: 'schedule-1',
1094
+ status: 'triggered',
1095
+ ranAt: Date.now() - 3600000
1096
+ });
1097
+ server.addScheduleRun({
1098
+ id: 'run-2',
1099
+ scheduleId: 'schedule-1',
1100
+ status: 'failed',
1101
+ ranAt: Date.now() - 7200000
1102
+ });
1103
+ return [
1104
+ 4,
1105
+ env.start()
1106
+ ];
1107
+ case 2:
1108
+ px = _state.sent();
1109
+ _state.label = 3;
1110
+ case 3:
1111
+ _state.trys.push([
1112
+ 3,
1113
+ ,
1114
+ 6,
1115
+ 8
1116
+ ]);
1117
+ return [
1118
+ 4,
1119
+ px([
1120
+ 'schedule',
1121
+ 'runs',
1122
+ '--status',
1123
+ 'failed'
1124
+ ])
1125
+ ];
1126
+ case 4:
1127
+ _ref = _state.sent(), waitForOutput = _ref.waitForOutput, instance = _ref.instance;
1128
+ return [
1129
+ 4,
1130
+ waitForOutput(/Found 1 scheduled run with status failed/i, 30)
1131
+ ];
1132
+ case 5:
1133
+ foundMessage = _state.sent();
1134
+ expect(foundMessage).toBe(true);
1135
+ // Verify only failed run is shown
1136
+ output = instance.lastFrame() || '';
1137
+ expect(output).toContain('run-2');
1138
+ expect(output).not.toContain('run-1');
1139
+ return [
1140
+ 3,
1141
+ 8
1142
+ ];
1143
+ case 6:
1144
+ return [
1145
+ 4,
1146
+ env.stopAndCleanup()
1147
+ ];
1148
+ case 7:
1149
+ _state.sent();
1150
+ return [
1151
+ 7
1152
+ ];
1153
+ case 8:
1154
+ return [
1155
+ 2
1156
+ ];
1157
+ }
1158
+ });
1159
+ })();
1160
+ });
1161
+ it('should respect limit parameter', function() {
1162
+ return _async_to_generator(function() {
1163
+ var env, px, waitForOutput, found, calls, runsCall;
1164
+ return _ts_generator(this, function(_state) {
1165
+ switch(_state.label){
1166
+ case 0:
1167
+ return [
1168
+ 4,
1169
+ createTestEnv()
1170
+ ];
1171
+ case 1:
1172
+ env = _state.sent();
1173
+ return [
1174
+ 4,
1175
+ env.start()
1176
+ ];
1177
+ case 2:
1178
+ px = _state.sent();
1179
+ _state.label = 3;
1180
+ case 3:
1181
+ _state.trys.push([
1182
+ 3,
1183
+ ,
1184
+ 6,
1185
+ 8
1186
+ ]);
1187
+ return [
1188
+ 4,
1189
+ px([
1190
+ 'schedule',
1191
+ 'runs',
1192
+ '--limit',
1193
+ '50'
1194
+ ])
1195
+ ];
1196
+ case 4:
1197
+ waitForOutput = _state.sent().waitForOutput;
1198
+ return [
1199
+ 4,
1200
+ waitForOutput(/No scheduled runs found|Found \d+ scheduled run/i, 30)
1201
+ ];
1202
+ case 5:
1203
+ found = _state.sent();
1204
+ expect(found).toBe(true);
1205
+ // Just verify the API was called with the right limit
1206
+ calls = env.server.getLogs();
1207
+ runsCall = calls.find(function(c) {
1208
+ return c.method === 'getScheduleRuns';
1209
+ });
1210
+ expect(runsCall).toBeDefined();
1211
+ expect(runsCall === null || runsCall === void 0 ? void 0 : runsCall.args[0]).toContain('limit=50');
1212
+ return [
1213
+ 3,
1214
+ 8
1215
+ ];
1216
+ case 6:
1217
+ return [
1218
+ 4,
1219
+ env.stopAndCleanup()
1220
+ ];
1221
+ case 7:
1222
+ _state.sent();
1223
+ return [
1224
+ 7
1225
+ ];
1226
+ case 8:
1227
+ return [
1228
+ 2
1229
+ ];
1230
+ }
1231
+ });
1232
+ })();
1233
+ });
1234
+ });
1235
+ });