@cloudnux/cli 0.1.0 → 0.10.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/dist/{cli.js → cli.mjs} +99 -451
- package/dist/schema/entrypoint.schema.json +292 -2
- package/dist/schema/{epf.schema.json → nux.schema.json} +2 -2
- package/dist/templates/cloud/entrypoint-build.ts.ejs +59 -40
- package/dist/templates/cloud/entrypoint-triggers.tf.ejs +18 -0
- package/dist/templates/local/dev-server.ts.ejs +58 -85
- package/dist/templates/local/module.ts.ejs +40 -60
- package/dist/templates/local/triggers/event.ts.ejs +7 -0
- package/dist/templates/local/triggers/http.ts.ejs +2 -24
- package/dist/templates/local/triggers/schedule.ts.ejs +7 -15
- package/package.json +14 -16
- package/readme.md +7 -7
- package/dist/schema/schema.json +0 -134
- package/dist/templates/cloude/entrypoint-build.ts.ejs +0 -50
- package/dist/templates/cloude/entrypoint-triggers.tf.ejs +0 -67
- package/dist/templates/develop.ts.ejs +0 -63
- package/dist/templates/entrypoint-build.ts.ejs +0 -50
- package/dist/templates/entrypoint-develop.ts.ejs +0 -120
- package/dist/templates/entrypoint-triggers.tf.ejs +0 -67
package/dist/{cli.js → cli.mjs}
RENAMED
|
@@ -7,10 +7,6 @@ var getFilename = () => fileURLToPath(import.meta.url);
|
|
|
7
7
|
var getDirname = () => path.dirname(getFilename());
|
|
8
8
|
var __dirname = /* @__PURE__ */ getDirname();
|
|
9
9
|
|
|
10
|
-
// src/cli.tsx
|
|
11
|
-
import React7 from "react";
|
|
12
|
-
import { render } from "ink";
|
|
13
|
-
|
|
14
10
|
// src/config/index.ts
|
|
15
11
|
import fs9 from "node:fs";
|
|
16
12
|
import path14 from "node:path";
|
|
@@ -18,10 +14,11 @@ import rechoir from "rechoir";
|
|
|
18
14
|
import { extensions } from "interpret";
|
|
19
15
|
import findUp from "findup-sync";
|
|
20
16
|
|
|
21
|
-
// src/task-manager/task-manager.ts
|
|
17
|
+
// src/task-manager/base-task-manager.ts
|
|
22
18
|
import EventEmitter from "node:events";
|
|
23
19
|
import path2 from "node:path";
|
|
24
|
-
var
|
|
20
|
+
var BaseTaskManager = class {
|
|
21
|
+
_tasksCount;
|
|
25
22
|
config;
|
|
26
23
|
environment;
|
|
27
24
|
taskResults;
|
|
@@ -31,6 +28,13 @@ var TaskManager = class {
|
|
|
31
28
|
this.environment = environment;
|
|
32
29
|
this.taskResults = /* @__PURE__ */ new Map();
|
|
33
30
|
this.events = new EventEmitter();
|
|
31
|
+
const envConfig = this.config.environments[this.environment];
|
|
32
|
+
if (!envConfig) {
|
|
33
|
+
throw new Error(`Environment ${this.environment} not found in config`);
|
|
34
|
+
}
|
|
35
|
+
this._tasksCount = envConfig.tasks.reduce((count, task) => {
|
|
36
|
+
return count + (task.children ? task.children.length + 1 : 1);
|
|
37
|
+
}, 0);
|
|
34
38
|
}
|
|
35
39
|
generateTaskId() {
|
|
36
40
|
return Math.random().toString(36).substring(2, 11);
|
|
@@ -49,6 +53,7 @@ var TaskManager = class {
|
|
|
49
53
|
modulesPath: this.config.modulesPath,
|
|
50
54
|
cloudProvider: this.config.cloudProvider,
|
|
51
55
|
workingDir: path2.resolve(this.config.workingDir, this.environment),
|
|
56
|
+
externalPackages: this.config.externalPackages,
|
|
52
57
|
...this.taskResults
|
|
53
58
|
};
|
|
54
59
|
delete taskParams.tasks;
|
|
@@ -57,7 +62,7 @@ var TaskManager = class {
|
|
|
57
62
|
title: taskParams.title,
|
|
58
63
|
parentTaskId
|
|
59
64
|
});
|
|
60
|
-
if (task.skip
|
|
65
|
+
if (task.skip?.(taskParams)) {
|
|
61
66
|
this.events.emit("skip", {
|
|
62
67
|
id: taskId
|
|
63
68
|
});
|
|
@@ -99,8 +104,11 @@ var TaskManager = class {
|
|
|
99
104
|
data
|
|
100
105
|
});
|
|
101
106
|
};
|
|
107
|
+
taskParams.logger = logger;
|
|
108
|
+
taskParams.eventEmitter = eventEmitter;
|
|
109
|
+
taskParams.executeSubTasks = executeSubTasks;
|
|
102
110
|
try {
|
|
103
|
-
const result = await task.action(taskParams
|
|
111
|
+
const result = await task.action(taskParams);
|
|
104
112
|
if (!parentTaskId) {
|
|
105
113
|
this.taskResults = {
|
|
106
114
|
...this.taskResults,
|
|
@@ -119,6 +127,25 @@ var TaskManager = class {
|
|
|
119
127
|
throw new Error(`Task ${taskId} failed: ${error.message}`);
|
|
120
128
|
}
|
|
121
129
|
}
|
|
130
|
+
on(event, listener) {
|
|
131
|
+
this.events.on(event, listener);
|
|
132
|
+
}
|
|
133
|
+
off(event) {
|
|
134
|
+
if (event)
|
|
135
|
+
this.events.removeAllListeners(event);
|
|
136
|
+
else
|
|
137
|
+
this.events.removeAllListeners();
|
|
138
|
+
}
|
|
139
|
+
get tasksCount() {
|
|
140
|
+
return this._tasksCount;
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// src/task-manager/build-task-manager.ts
|
|
145
|
+
var BuildTaskManager = class extends BaseTaskManager {
|
|
146
|
+
constructor(config2, environment) {
|
|
147
|
+
super(config2, environment);
|
|
148
|
+
}
|
|
122
149
|
async execute() {
|
|
123
150
|
const envConfig = this.config.environments[this.environment];
|
|
124
151
|
if (!envConfig) {
|
|
@@ -128,28 +155,28 @@ var TaskManager = class {
|
|
|
128
155
|
try {
|
|
129
156
|
await this.executeTask(task, {});
|
|
130
157
|
} catch (error) {
|
|
158
|
+
console.error(error);
|
|
131
159
|
return;
|
|
132
160
|
}
|
|
133
161
|
}
|
|
134
162
|
}
|
|
135
|
-
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// src/task-manager/watch-task-manager.ts
|
|
166
|
+
var WatchTaskManager = class extends BaseTaskManager {
|
|
167
|
+
constructor(config2, environment) {
|
|
168
|
+
super(config2, environment);
|
|
169
|
+
}
|
|
170
|
+
async execute() {
|
|
136
171
|
const envConfig = this.config.environments[this.environment];
|
|
137
|
-
if (envConfig.watch)
|
|
172
|
+
if (envConfig.watch) {
|
|
138
173
|
try {
|
|
139
174
|
await this.executeTask(envConfig.watch, {});
|
|
140
175
|
} catch (error) {
|
|
141
176
|
console.error(error);
|
|
142
177
|
return;
|
|
143
178
|
}
|
|
144
|
-
|
|
145
|
-
on(event, listener) {
|
|
146
|
-
this.events.on(event, listener);
|
|
147
|
-
}
|
|
148
|
-
off(event) {
|
|
149
|
-
if (event)
|
|
150
|
-
this.events.removeAllListeners(event);
|
|
151
|
-
else
|
|
152
|
-
this.events.removeAllListeners();
|
|
179
|
+
}
|
|
153
180
|
}
|
|
154
181
|
};
|
|
155
182
|
|
|
@@ -206,13 +233,8 @@ var helpers = {
|
|
|
206
233
|
var transformModule = {
|
|
207
234
|
title: ({ moduleName }) => `Transform module ${moduleName}`,
|
|
208
235
|
skip: () => false,
|
|
209
|
-
action: async ({
|
|
210
|
-
moduleTemplateFunc
|
|
211
|
-
entrypointPath,
|
|
212
|
-
moduleName,
|
|
213
|
-
workingDir,
|
|
214
|
-
source
|
|
215
|
-
}) => {
|
|
236
|
+
action: async (params) => {
|
|
237
|
+
const { workingDir, moduleName, entrypointPath, source, moduleTemplateFunc } = params;
|
|
216
238
|
const entrypointContent = await fs3.readFile(entrypointPath, "utf-8");
|
|
217
239
|
const rendered = moduleTemplateFunc({
|
|
218
240
|
source: process.platform === "win32" ? source.replace(/\\/g, "/") : source,
|
|
@@ -313,7 +335,6 @@ var buildServer = {
|
|
|
313
335
|
return params.environment === "develop";
|
|
314
336
|
},
|
|
315
337
|
action: async ({ moduleDir, cloudProvider, externalPackages }) => {
|
|
316
|
-
debugger;
|
|
317
338
|
const modulePath = path8.resolve(moduleDir, "index.ts");
|
|
318
339
|
return await tsup.build({
|
|
319
340
|
entry: {
|
|
@@ -331,12 +352,26 @@ var buildServer = {
|
|
|
331
352
|
};
|
|
332
353
|
return options;
|
|
333
354
|
},
|
|
355
|
+
format: ["esm"],
|
|
356
|
+
banner: {
|
|
357
|
+
js: `
|
|
358
|
+
import __node_module from 'node:module';
|
|
359
|
+
import __node_url from 'node:url';
|
|
360
|
+
import __node_path from 'node:path';
|
|
361
|
+
const require = __node_module.createRequire(import.meta.url);
|
|
362
|
+
const __filename = __node_url.fileURLToPath(import.meta.url);
|
|
363
|
+
const __dirname = __node_path.dirname(__filename);
|
|
364
|
+
`.trim()
|
|
365
|
+
},
|
|
366
|
+
outExtension: () => ({ js: ".mjs" }),
|
|
334
367
|
bundle: true,
|
|
335
|
-
sourcemap:
|
|
368
|
+
sourcemap: true,
|
|
369
|
+
minify: false,
|
|
336
370
|
outDir: moduleDir,
|
|
337
371
|
platform: "node",
|
|
338
372
|
dts: false,
|
|
339
373
|
watch: false,
|
|
374
|
+
shims: false,
|
|
340
375
|
define: {
|
|
341
376
|
__DEV__: process.env.__DEV__ || "false"
|
|
342
377
|
},
|
|
@@ -349,7 +384,8 @@ var buildServer = {
|
|
|
349
384
|
var locateModules = {
|
|
350
385
|
title: "load all entrypoints.json",
|
|
351
386
|
skip: () => false,
|
|
352
|
-
action: async (params
|
|
387
|
+
action: async (params) => {
|
|
388
|
+
const { executeSubTasks } = params;
|
|
353
389
|
const entrypoints = await fg(params.modulesPath);
|
|
354
390
|
const moduleNames = entrypoints.map((entrypoint) => path9.basename(path9.dirname(entrypoint)));
|
|
355
391
|
let output = {
|
|
@@ -401,46 +437,37 @@ var transformDevServer = {
|
|
|
401
437
|
import path11 from "node:path";
|
|
402
438
|
import { fork } from "node:child_process";
|
|
403
439
|
import tsup2 from "tsup";
|
|
404
|
-
function mapCloud2(provider) {
|
|
405
|
-
switch (provider) {
|
|
406
|
-
case "aws":
|
|
407
|
-
return "@cloudnux/aws-cloud-provider";
|
|
408
|
-
case "azure":
|
|
409
|
-
return "@cloudnux/azure-cloud-provider";
|
|
410
|
-
case "gcp":
|
|
411
|
-
return "@cloudnux/gcp-cloud-provider";
|
|
412
|
-
default:
|
|
413
|
-
return provider;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
440
|
var devServerWatch = {
|
|
417
441
|
title: "Dev Server Watch",
|
|
418
442
|
skip: () => false,
|
|
419
|
-
action: async (
|
|
443
|
+
action: async (params) => {
|
|
444
|
+
const { workingDir, logger, eventEmitter } = params;
|
|
420
445
|
const entryPath = path11.resolve(workingDir, "app.ts");
|
|
421
446
|
await tsup2.build({
|
|
422
447
|
entry: {
|
|
423
448
|
index: entryPath
|
|
424
449
|
},
|
|
425
|
-
external: [...externalPackages],
|
|
426
450
|
esbuildOptions: (options) => {
|
|
427
451
|
options.absWorkingDir = workingDir;
|
|
428
|
-
options.alias = {
|
|
429
|
-
"@@cloudcore": "@cloudnux/cloud-core",
|
|
430
|
-
"@@cloud": mapCloud2(cloudProvider),
|
|
431
|
-
"@@datastore": "@cloudnux/datastore",
|
|
432
|
-
"@@utils": "@cloudnux/utils"
|
|
433
|
-
};
|
|
434
452
|
return options;
|
|
435
453
|
},
|
|
454
|
+
format: ["cjs"],
|
|
436
455
|
bundle: true,
|
|
456
|
+
noExternal: [],
|
|
437
457
|
sourcemap: true,
|
|
458
|
+
minify: false,
|
|
438
459
|
outDir: workingDir,
|
|
439
460
|
platform: "node",
|
|
461
|
+
cjsInterop: true,
|
|
462
|
+
shims: true,
|
|
440
463
|
dts: false,
|
|
441
464
|
watch: false,
|
|
442
465
|
env: {
|
|
443
|
-
__ENV_PATH__: '"' + path11.resolve(
|
|
466
|
+
__ENV_PATH__: '"' + path11.resolve(workingDir, "../../.env").replace(/\\/g, "\\\\") + '"',
|
|
467
|
+
__DEV__: process.env.__DEV__ || '"development"'
|
|
468
|
+
},
|
|
469
|
+
define: {
|
|
470
|
+
__ENV_PATH__: '"' + path11.resolve(workingDir, "../../.env").replace(/\\/g, "\\\\") + '"',
|
|
444
471
|
__DEV__: process.env.__DEV__ || '"development"'
|
|
445
472
|
},
|
|
446
473
|
esbuildPlugins: [
|
|
@@ -458,8 +485,9 @@ var devServerWatch = {
|
|
|
458
485
|
}
|
|
459
486
|
},
|
|
460
487
|
startServerPlugin(logger, eventEmitter)
|
|
461
|
-
]
|
|
462
|
-
|
|
488
|
+
],
|
|
489
|
+
silent: true
|
|
490
|
+
// Prevent console output
|
|
463
491
|
});
|
|
464
492
|
}
|
|
465
493
|
};
|
|
@@ -472,33 +500,22 @@ function startModule(main, execArgv, logger, eventEmitter) {
|
|
|
472
500
|
eventEmitter(message.type, message.payload);
|
|
473
501
|
break;
|
|
474
502
|
case "APP_REGISTERED":
|
|
475
|
-
eventEmitter(message.type, message.payload);
|
|
476
|
-
break;
|
|
477
503
|
case "ROUTE_REGISTERED":
|
|
478
|
-
eventEmitter(message.type, message.payload);
|
|
479
|
-
break;
|
|
480
504
|
case "LISTENING":
|
|
481
|
-
eventEmitter(message.type, message.payload);
|
|
482
|
-
break;
|
|
483
505
|
case "REQUEST":
|
|
484
|
-
eventEmitter(message.type, message.payload);
|
|
485
|
-
break;
|
|
486
506
|
case "RESPONSE":
|
|
487
|
-
eventEmitter(message.type, message.payload);
|
|
488
|
-
break;
|
|
489
507
|
case "LOG":
|
|
490
508
|
eventEmitter(message.type, message.payload);
|
|
491
|
-
|
|
492
|
-
eventEmitter(message.type, message.payload);
|
|
509
|
+
break;
|
|
493
510
|
default:
|
|
494
|
-
logger("Unknown message:", message);
|
|
495
511
|
break;
|
|
496
512
|
}
|
|
497
513
|
});
|
|
498
514
|
child.on("error", function(error) {
|
|
499
515
|
console.error(error);
|
|
516
|
+
child.kill("SIGINT");
|
|
500
517
|
});
|
|
501
|
-
child.on("close", function(
|
|
518
|
+
child.on("close", function() {
|
|
502
519
|
child.kill("SIGINT");
|
|
503
520
|
});
|
|
504
521
|
return child;
|
|
@@ -509,17 +526,18 @@ function startServerPlugin(logger, eventEmitter) {
|
|
|
509
526
|
name: "start servers",
|
|
510
527
|
setup(build) {
|
|
511
528
|
let child;
|
|
512
|
-
|
|
513
|
-
console.log(outdir, logLevel);
|
|
514
|
-
const main = path11.resolve(outdir, "index.cjs");
|
|
515
|
-
build.onEnd(async function({ errors }) {
|
|
529
|
+
build.onEnd(async function({ errors, outputFiles }) {
|
|
516
530
|
if (child) {
|
|
517
531
|
child.kill("SIGINT");
|
|
518
532
|
if (!child.killed) {
|
|
519
533
|
console.error(`cannot stop process ${child.pid}`);
|
|
520
534
|
}
|
|
521
535
|
}
|
|
522
|
-
if (errors && errors.length > 0)
|
|
536
|
+
if (errors && errors.length > 0) {
|
|
537
|
+
errors.forEach(logger);
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
const main = outputFiles?.find((file) => file.path.endsWith(".js") || file.path.endsWith(".cjs"))?.path;
|
|
523
541
|
child = startModule(main, ["--enable-source-maps"], logger, eventEmitter);
|
|
524
542
|
});
|
|
525
543
|
}
|
|
@@ -572,12 +590,12 @@ var transferTerraformModules = {
|
|
|
572
590
|
var defaultConfig = {
|
|
573
591
|
modulesPath: "./packages/modules/**/entrypoint.json",
|
|
574
592
|
cloudProvider: "aws",
|
|
575
|
-
workingDir: "./.
|
|
593
|
+
workingDir: "./.nux",
|
|
594
|
+
externalPackages: ["aws-sdk", "@aws-sdk/*"],
|
|
576
595
|
environments: {
|
|
577
596
|
develop: {
|
|
578
597
|
moduleTemplatePath: "./templates/local/module.ts.ejs",
|
|
579
598
|
devServerTemplatePath: "./templates/local/dev-server.ts.ejs",
|
|
580
|
-
externalPackages: ["sqlite3", "pino"],
|
|
581
599
|
tasks: [
|
|
582
600
|
loadModuleTemplate,
|
|
583
601
|
loadDevServerTemplate,
|
|
@@ -589,7 +607,6 @@ var defaultConfig = {
|
|
|
589
607
|
production: {
|
|
590
608
|
moduleTemplatePath: "./templates/cloud/entrypoint-build.ts.ejs",
|
|
591
609
|
triggerTemplatePath: "./templates/cloud/entrypoint-triggers.tf.ejs",
|
|
592
|
-
externalPackages: ["aws-sdk", "@aws-sdk/*"],
|
|
593
610
|
tasks: [
|
|
594
611
|
loadModuleTemplate,
|
|
595
612
|
loadTriggerTemplate,
|
|
@@ -657,7 +674,7 @@ function validateConfig(config2) {
|
|
|
657
674
|
}
|
|
658
675
|
|
|
659
676
|
// src/config/index.ts
|
|
660
|
-
var CONFIG_FILE_NAMES = ["
|
|
677
|
+
var CONFIG_FILE_NAMES = ["nux.config", "nuxrc"];
|
|
661
678
|
async function resolveConfig(config2, configContext) {
|
|
662
679
|
if (typeof config2 === "function") {
|
|
663
680
|
try {
|
|
@@ -723,13 +740,13 @@ function loadArgs() {
|
|
|
723
740
|
const args2 = meow(
|
|
724
741
|
`
|
|
725
742
|
Usage
|
|
726
|
-
$
|
|
743
|
+
$ nux <enviroment>
|
|
727
744
|
|
|
728
745
|
Options
|
|
729
746
|
--config Your config file path
|
|
730
747
|
|
|
731
748
|
Examples
|
|
732
|
-
$
|
|
749
|
+
$ nux develop --config=./config.json
|
|
733
750
|
`,
|
|
734
751
|
{
|
|
735
752
|
importMeta: import.meta,
|
|
@@ -752,379 +769,10 @@ function loadArgs() {
|
|
|
752
769
|
};
|
|
753
770
|
}
|
|
754
771
|
|
|
755
|
-
// src/
|
|
756
|
-
import React6, { useEffect, useMemo, useState as useState2 } from "react";
|
|
757
|
-
import { extendTheme, defaultTheme, ThemeProvider } from "@inkjs/ui";
|
|
758
|
-
import { Box as Box6, useStdout, Text as Text6 } from "ink";
|
|
759
|
-
|
|
760
|
-
// src/store/index.ts
|
|
761
|
-
import { create } from "zustand";
|
|
762
|
-
import { immer } from "zustand/middleware/immer";
|
|
763
|
-
var useTaskManager = create()(immer(
|
|
764
|
-
(set, get) => {
|
|
765
|
-
return {
|
|
766
|
-
tasks: {},
|
|
767
|
-
currentTaskId: null,
|
|
768
|
-
environment: "development",
|
|
769
|
-
isRunning: false,
|
|
770
|
-
isListening: false,
|
|
771
|
-
selectedModule: null,
|
|
772
|
-
selectedEndpoint: null,
|
|
773
|
-
modules: [],
|
|
774
|
-
port: "",
|
|
775
|
-
host: "",
|
|
776
|
-
logs: [],
|
|
777
|
-
pinoLogs: [],
|
|
778
|
-
start: async (config2, env) => {
|
|
779
|
-
const taskManager = new TaskManager(config2, env);
|
|
780
|
-
set(() => ({ isRunning: true, environment: env }));
|
|
781
|
-
taskManager.on("new", (task) => get().addTask(task));
|
|
782
|
-
taskManager.on("start", ({ id }) => get().updateTaskStatus(id, "running"));
|
|
783
|
-
taskManager.on("success", ({ id }) => get().updateTaskStatus(id, "completed"));
|
|
784
|
-
taskManager.on("failure", ({ id, error }) => get().updateTaskStatus(id, "error", error));
|
|
785
|
-
taskManager.on("skip", ({ id }) => get().updateTaskStatus(id, "skipped"));
|
|
786
|
-
taskManager.on("log", ({ id, log, data }) => get().addTaskLog(id, log, data));
|
|
787
|
-
taskManager.on("APP_REGISTERED", ({ id, data }) => get().addModule(id, data));
|
|
788
|
-
taskManager.on("ROUTE_REGISTERED", ({ id, data }) => get().addRoute(data));
|
|
789
|
-
taskManager.on("LISTENING", ({ id, data }) => get().startListening(data));
|
|
790
|
-
taskManager.on("ERROR", ({ id, data }) => get().addActionLog(id, data));
|
|
791
|
-
taskManager.on("REQUEST", ({ id, data }) => get().addActionLog(id, data));
|
|
792
|
-
taskManager.on("RESPONSE", ({ id, data }) => get().addActionLog(id, data));
|
|
793
|
-
taskManager.on("LOG", ({ id, data }) => get().addPinoLog(id, data));
|
|
794
|
-
await taskManager.execute();
|
|
795
|
-
set(() => ({ isRunning: false, currentTaskId: null }));
|
|
796
|
-
await taskManager.watch();
|
|
797
|
-
set(() => ({ isWatching: true }));
|
|
798
|
-
},
|
|
799
|
-
addTask: (task) => {
|
|
800
|
-
const newTask = {
|
|
801
|
-
id: task.id,
|
|
802
|
-
title: task.title,
|
|
803
|
-
status: "pending",
|
|
804
|
-
parentId: task.parentTaskId,
|
|
805
|
-
children: [],
|
|
806
|
-
logs: []
|
|
807
|
-
};
|
|
808
|
-
set((state) => {
|
|
809
|
-
state.tasks[task.id] = newTask;
|
|
810
|
-
if (task.parentTaskId) {
|
|
811
|
-
const parentTaskState = state.tasks[task.parentTaskId];
|
|
812
|
-
if (parentTaskState) {
|
|
813
|
-
state.tasks[task.parentTaskId].children = [
|
|
814
|
-
...parentTaskState.children,
|
|
815
|
-
task.id
|
|
816
|
-
];
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
state.currentTaskId = task.id;
|
|
820
|
-
});
|
|
821
|
-
},
|
|
822
|
-
updateTaskStatus: (taskId, status, error) => {
|
|
823
|
-
set((state) => {
|
|
824
|
-
const task = state.tasks[taskId];
|
|
825
|
-
if (!task) return state;
|
|
826
|
-
task.status = status;
|
|
827
|
-
task.error = error || task.error;
|
|
828
|
-
});
|
|
829
|
-
},
|
|
830
|
-
addTaskLog: (taskId, log, data) => {
|
|
831
|
-
set((state) => {
|
|
832
|
-
const task = state.tasks[taskId];
|
|
833
|
-
if (!task) return state;
|
|
834
|
-
if (data) log = { text: log, data };
|
|
835
|
-
task.logs = [...task.logs, log];
|
|
836
|
-
});
|
|
837
|
-
},
|
|
838
|
-
addModule: (id, opts) => {
|
|
839
|
-
set((state) => {
|
|
840
|
-
let modules = state.modules;
|
|
841
|
-
if (modules.length > 0) {
|
|
842
|
-
state.modules = [...modules, {
|
|
843
|
-
id: opts.prefix,
|
|
844
|
-
name: opts.prefix,
|
|
845
|
-
endpoints: [],
|
|
846
|
-
data: opts
|
|
847
|
-
}];
|
|
848
|
-
return state;
|
|
849
|
-
}
|
|
850
|
-
state.modules = [{
|
|
851
|
-
id: opts.prefix,
|
|
852
|
-
name: opts.prefix,
|
|
853
|
-
endpoints: [],
|
|
854
|
-
data: opts
|
|
855
|
-
}];
|
|
856
|
-
return state;
|
|
857
|
-
});
|
|
858
|
-
},
|
|
859
|
-
addRoute: (endpoint) => {
|
|
860
|
-
set((state) => {
|
|
861
|
-
let modules = state.modules;
|
|
862
|
-
if (modules.length < 0) {
|
|
863
|
-
return state;
|
|
864
|
-
}
|
|
865
|
-
state.modules[modules.length - 1].endpoints = [...modules[modules.length - 1].endpoints, endpoint];
|
|
866
|
-
return state;
|
|
867
|
-
});
|
|
868
|
-
},
|
|
869
|
-
addActionLog(id, data) {
|
|
870
|
-
const logs = get().logs;
|
|
871
|
-
if (logs.length >= 5) {
|
|
872
|
-
logs.shift();
|
|
873
|
-
}
|
|
874
|
-
set({ logs: [...logs, data] });
|
|
875
|
-
},
|
|
876
|
-
addPinoLog: (id, data) => {
|
|
877
|
-
const logs = get().pinoLogs;
|
|
878
|
-
if (logs.length >= 5) {
|
|
879
|
-
logs.shift();
|
|
880
|
-
}
|
|
881
|
-
set({ pinoLogs: [...logs, data] });
|
|
882
|
-
},
|
|
883
|
-
startListening: (data) => {
|
|
884
|
-
if (!data) return;
|
|
885
|
-
set({ isListening: true, port: data.port, host: data.host });
|
|
886
|
-
},
|
|
887
|
-
selectModule: (id) => set({ selectedModule: id }),
|
|
888
|
-
selectEndpoint: (endpoint) => set({ selectedEndpoint: endpoint }),
|
|
889
|
-
resetSelection: () => set({ selectedModule: null, selectedEndpoint: null })
|
|
890
|
-
// Reset both select
|
|
891
|
-
};
|
|
892
|
-
}
|
|
893
|
-
));
|
|
894
|
-
var selectTask = (taskId) => (state) => state.tasks[taskId];
|
|
895
|
-
var selectRootTasks = () => (state) => {
|
|
896
|
-
return Object.values(state.tasks).filter((task) => !task.parentId);
|
|
897
|
-
};
|
|
898
|
-
var selectProgress = () => (state) => {
|
|
899
|
-
const allTasks = Object.values(state.tasks);
|
|
900
|
-
const completedTasks = allTasks.filter((task) => task.status === "completed");
|
|
901
|
-
return completedTasks.length / allTasks.length;
|
|
902
|
-
};
|
|
903
|
-
|
|
904
|
-
// src/components/prepare-view.tsx
|
|
905
|
-
import React2 from "react";
|
|
906
|
-
import { useShallow } from "zustand/react/shallow";
|
|
907
|
-
import { Box as Box2, Text as Text2 } from "ink";
|
|
908
|
-
import { ProgressBar, StatusMessage, Spinner } from "@inkjs/ui";
|
|
909
|
-
|
|
910
|
-
// src/components/log-entry.tsx
|
|
911
|
-
import React from "react";
|
|
912
|
-
import { Box, Text } from "ink";
|
|
913
|
-
var LogEntry = ({ log }) => {
|
|
914
|
-
if (typeof log !== "string" && "text" in log && "data" in log) {
|
|
915
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: log.color || "white" }, log.text), log.data && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, JSON.stringify(log.data)));
|
|
916
|
-
}
|
|
917
|
-
if (typeof log !== "string" && "text" in log) {
|
|
918
|
-
const location = log.location ? `${log.location.file}:${log.location.line}:${log.location.column}` : "";
|
|
919
|
-
const details = log.detail ? `
|
|
920
|
-
${log.detail}` : "";
|
|
921
|
-
const notes = log.notes?.map((note) => note.text).join("\n");
|
|
922
|
-
const prefix = log.pluginName ? `[${log.pluginName}] ` : "";
|
|
923
|
-
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "\u26A0 ", prefix, log.text), location && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " at ", location), details && /* @__PURE__ */ React.createElement(Text, null, details), notes && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, notes));
|
|
924
|
-
}
|
|
925
|
-
const logLevelMatch = log.match(/^\[(info|error|warning)\]/i);
|
|
926
|
-
const level = logLevelMatch ? logLevelMatch[1].toLowerCase() : "info";
|
|
927
|
-
const message = logLevelMatch ? log.slice(logLevelMatch[0].length).trim() : log;
|
|
928
|
-
const getLogColor = () => {
|
|
929
|
-
switch (level) {
|
|
930
|
-
case "error":
|
|
931
|
-
return "red";
|
|
932
|
-
case "warning":
|
|
933
|
-
return "yellow";
|
|
934
|
-
case "info":
|
|
935
|
-
default:
|
|
936
|
-
return "white";
|
|
937
|
-
}
|
|
938
|
-
};
|
|
939
|
-
const getLogPrefix = () => {
|
|
940
|
-
switch (level) {
|
|
941
|
-
case "error":
|
|
942
|
-
return "\u2716";
|
|
943
|
-
case "warning":
|
|
944
|
-
return "\u26A0";
|
|
945
|
-
case "info":
|
|
946
|
-
default:
|
|
947
|
-
return "\u2139";
|
|
948
|
-
}
|
|
949
|
-
};
|
|
950
|
-
return /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: getLogColor() }, getLogPrefix(), " ", message));
|
|
951
|
-
};
|
|
952
|
-
|
|
953
|
-
// src/components/prepare-view.tsx
|
|
954
|
-
var TaskLogs = ({ taskId, maxLogs = 5 }) => {
|
|
955
|
-
const task = useTaskManager((state) => state.tasks[taskId]);
|
|
956
|
-
if (!task?.logs?.length) {
|
|
957
|
-
return null;
|
|
958
|
-
}
|
|
959
|
-
const displayLogs = maxLogs ? task.logs.slice(-maxLogs) : task.logs;
|
|
960
|
-
return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", marginLeft: 4 }, displayLogs.map((log, index) => /* @__PURE__ */ React2.createElement(LogEntry, { key: `${taskId}-log-${index}`, log })));
|
|
961
|
-
};
|
|
962
|
-
var TaskStatus = ({ taskId, isActive, indent = 0 }) => {
|
|
963
|
-
const task = useTaskManager(selectTask(taskId));
|
|
964
|
-
const currentTaskId = useTaskManager((state) => state.currentTaskId);
|
|
965
|
-
const getStatusVariant = () => {
|
|
966
|
-
if (task.error) return "error";
|
|
967
|
-
if (task.status === "completed" && !task.error) return "success";
|
|
968
|
-
if (task.status === "skipped") return "info";
|
|
969
|
-
if (task.status === "running") return "info";
|
|
970
|
-
return "warning";
|
|
971
|
-
};
|
|
972
|
-
const shouldShowLogs = isActive || task.status === "error";
|
|
973
|
-
return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column" }, /* @__PURE__ */ React2.createElement(Box2, null, /* @__PURE__ */ React2.createElement(Text2, null, " ".repeat(indent)), isActive ? /* @__PURE__ */ React2.createElement(Spinner, { label: task.title }) : /* @__PURE__ */ React2.createElement(StatusMessage, { variant: getStatusVariant() }, task.status === "skipped" ? "\u23ED" : void 0, " ", task.title, task.error && /* @__PURE__ */ React2.createElement(Text2, { color: "red" }, " - ", task.error))), shouldShowLogs && /* @__PURE__ */ React2.createElement(TaskLogs, { taskId: task.id }), task.children?.map((child, index) => /* @__PURE__ */ React2.createElement(
|
|
974
|
-
TaskStatus,
|
|
975
|
-
{
|
|
976
|
-
key: `${child}-${index}`,
|
|
977
|
-
taskId: child,
|
|
978
|
-
isActive: task.id === currentTaskId,
|
|
979
|
-
indent: indent + 1
|
|
980
|
-
}
|
|
981
|
-
)));
|
|
982
|
-
};
|
|
983
|
-
var BuildProgress = () => {
|
|
984
|
-
const progress = useTaskManager(selectProgress());
|
|
985
|
-
const tasks = useTaskManager(useShallow(selectRootTasks()));
|
|
986
|
-
const currentTaskId = useTaskManager((state) => state.currentTaskId);
|
|
987
|
-
return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React2.createElement(Box2, { marginBottom: 1 }, /* @__PURE__ */ React2.createElement(ProgressBar, { value: progress * 100 })), /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column" }, Object.values(tasks).map((task) => /* @__PURE__ */ React2.createElement(
|
|
988
|
-
TaskStatus,
|
|
989
|
-
{
|
|
990
|
-
key: task.id,
|
|
991
|
-
taskId: task.id,
|
|
992
|
-
isActive: task.id === currentTaskId
|
|
993
|
-
}
|
|
994
|
-
))));
|
|
995
|
-
};
|
|
996
|
-
function PrepareView() {
|
|
997
|
-
return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column" }, /* @__PURE__ */ React2.createElement(BuildProgress, null));
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
// src/components/side-bar.tsx
|
|
1001
|
-
import React3 from "react";
|
|
1002
|
-
import { Box as Box3, Text as Text3, useInput } from "ink";
|
|
1003
|
-
var Sidebar = () => {
|
|
1004
|
-
const { selectedModule, modules, selectEndpoint, selectedEndpoint, resetSelection, selectModule } = useTaskManager();
|
|
1005
|
-
const selectedIndex = modules.findIndex((module) => module.id === selectedModule);
|
|
1006
|
-
useInput((input, key) => {
|
|
1007
|
-
if (key.upArrow && !selectedEndpoint) {
|
|
1008
|
-
const newIndex = (selectedIndex - 1 + modules.length) % modules.length;
|
|
1009
|
-
selectModule(modules[newIndex].id);
|
|
1010
|
-
}
|
|
1011
|
-
if (key.downArrow && !selectedEndpoint) {
|
|
1012
|
-
const newIndex = (selectedIndex + 1) % modules.length;
|
|
1013
|
-
selectModule(modules[newIndex].id);
|
|
1014
|
-
}
|
|
1015
|
-
if (key.return && selectedModule) {
|
|
1016
|
-
selectEndpoint(modules[selectedIndex].endpoints[0]);
|
|
1017
|
-
}
|
|
1018
|
-
if (key.escape) {
|
|
1019
|
-
resetSelection();
|
|
1020
|
-
}
|
|
1021
|
-
});
|
|
1022
|
-
return /* @__PURE__ */ React3.createElement(Box3, { flexDirection: "column", width: "20%", borderStyle: "round", borderColor: "green" }, /* @__PURE__ */ React3.createElement(Text3, { bold: true, color: "yellow" }, "Modules"), modules.map((module) => /* @__PURE__ */ React3.createElement(
|
|
1023
|
-
Text3,
|
|
1024
|
-
{
|
|
1025
|
-
key: module.id,
|
|
1026
|
-
color: selectedModule === module.id ? "cyan" : "white"
|
|
1027
|
-
},
|
|
1028
|
-
module.name
|
|
1029
|
-
)));
|
|
1030
|
-
};
|
|
1031
|
-
var side_bar_default = Sidebar;
|
|
1032
|
-
|
|
1033
|
-
// src/components/content-view.tsx
|
|
1034
|
-
import React4, { useState } from "react";
|
|
1035
|
-
import { Box as Box4, Text as Text4, useInput as useInput2 } from "ink";
|
|
1036
|
-
var ContentView = () => {
|
|
1037
|
-
const { selectedModule, selectedEndpoint, modules, selectEndpoint } = useTaskManager();
|
|
1038
|
-
const module = modules.find((a) => a.id === selectedModule);
|
|
1039
|
-
const selectedIndex = module?.endpoints.findIndex((e) => e.url === selectedEndpoint?.url && e.method === selectedEndpoint?.method) ?? -1;
|
|
1040
|
-
const [logs, setLogs] = useState([
|
|
1041
|
-
"Log entry 1",
|
|
1042
|
-
"Log entry 2",
|
|
1043
|
-
"Log entry 3",
|
|
1044
|
-
"Log entry 4",
|
|
1045
|
-
"Log entry 5",
|
|
1046
|
-
"Log entry 6",
|
|
1047
|
-
"Log entry 7"
|
|
1048
|
-
]);
|
|
1049
|
-
const displayedLogs = logs.slice(-5);
|
|
1050
|
-
useInput2((input, key) => {
|
|
1051
|
-
if (key.upArrow && selectedModule && module && selectedIndex >= 0) {
|
|
1052
|
-
const newIndex = (selectedIndex - 1 + module.endpoints.length) % module.endpoints.length;
|
|
1053
|
-
selectEndpoint(module.endpoints[newIndex]);
|
|
1054
|
-
}
|
|
1055
|
-
if (key.downArrow && selectedModule && module && selectedIndex >= 0) {
|
|
1056
|
-
const newIndex = (selectedIndex + 1) % module.endpoints.length;
|
|
1057
|
-
selectEndpoint(module.endpoints[newIndex]);
|
|
1058
|
-
}
|
|
1059
|
-
if (key.rightArrow) {
|
|
1060
|
-
setLogs((logs2) => [...logs2, `Log entry ${logs2.length + 1}`]);
|
|
1061
|
-
}
|
|
1062
|
-
});
|
|
1063
|
-
return /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column", justifyContent: "space-between", width: "80%", borderStyle: "round", borderColor: "blue" }, /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React4.createElement(Text4, { bold: true, color: "yellow" }, "Endpoints"), module ? module.endpoints.map((endpoint, index) => /* @__PURE__ */ React4.createElement(
|
|
1064
|
-
Text4,
|
|
1065
|
-
{
|
|
1066
|
-
key: index,
|
|
1067
|
-
color: selectedEndpoint?.url === endpoint.url && endpoint.method === selectedEndpoint?.method ? "cyan" : "white"
|
|
1068
|
-
},
|
|
1069
|
-
endpoint.method,
|
|
1070
|
-
" - ",
|
|
1071
|
-
endpoint.url
|
|
1072
|
-
)) : /* @__PURE__ */ React4.createElement(Text4, null, "Select an app to view its endpoints")), selectedEndpoint && /* @__PURE__ */ React4.createElement(Box4, { flexDirection: "column", borderStyle: "round", borderColor: "gray" }, /* @__PURE__ */ React4.createElement(Text4, { bold: true, color: "yellow" }, "Logs for ", selectedEndpoint.method, " - ", selectedEndpoint.url, ":"), displayedLogs.map((log, index) => /* @__PURE__ */ React4.createElement(Text4, { key: index }, log))));
|
|
1073
|
-
};
|
|
1074
|
-
var content_view_default = ContentView;
|
|
1075
|
-
|
|
1076
|
-
// src/components/action-logs.tsx
|
|
1077
|
-
import React5 from "react";
|
|
1078
|
-
import { Box as Box5, Text as Text5 } from "ink";
|
|
1079
|
-
var ActionLogs = () => {
|
|
1080
|
-
const logs = useTaskManager((state) => state.logs);
|
|
1081
|
-
return /* @__PURE__ */ React5.createElement(Box5, { borderStyle: "round", flexDirection: "column", borderColor: "green", width: "100%", height: "60%" }, /* @__PURE__ */ React5.createElement(Text5, { bold: true, color: "yellow" }, "General Logs"), logs.map((log, index) => /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, { key: index, color: "greenBright" }, "[", log.method, "](", log.url, "): ", log.time), /* @__PURE__ */ React5.createElement(Text5, { key: index }, " - ", JSON.stringify(log)))));
|
|
1082
|
-
};
|
|
1083
|
-
var action_logs_default = ActionLogs;
|
|
1084
|
-
|
|
1085
|
-
// src/app.tsx
|
|
1086
|
-
function App({ config: config2, args: args2 }) {
|
|
1087
|
-
const { stdout } = useStdout();
|
|
1088
|
-
const theme = useMemo(() => {
|
|
1089
|
-
return extendTheme(defaultTheme, {
|
|
1090
|
-
components: {
|
|
1091
|
-
ProgressBar: {
|
|
1092
|
-
styles: {
|
|
1093
|
-
completed: () => {
|
|
1094
|
-
return {
|
|
1095
|
-
color: "green"
|
|
1096
|
-
};
|
|
1097
|
-
}
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
});
|
|
1102
|
-
}, []);
|
|
1103
|
-
useMemo(() => {
|
|
1104
|
-
const onResize = () => {
|
|
1105
|
-
setDimensions([stdout.columns, stdout.rows]);
|
|
1106
|
-
};
|
|
1107
|
-
stdout.on("resize", onResize);
|
|
1108
|
-
return () => {
|
|
1109
|
-
stdout.off("resize", onResize);
|
|
1110
|
-
};
|
|
1111
|
-
}, [stdout]);
|
|
1112
|
-
const [dimensions, setDimensions] = useState2([
|
|
1113
|
-
stdout.columns,
|
|
1114
|
-
stdout.rows
|
|
1115
|
-
]);
|
|
1116
|
-
const [width, height] = dimensions;
|
|
1117
|
-
const start = useTaskManager((state) => state.start);
|
|
1118
|
-
const isListening = useTaskManager((state) => state.isListening);
|
|
1119
|
-
const port = useTaskManager((state) => state.port);
|
|
1120
|
-
const host = useTaskManager((state) => state.host);
|
|
1121
|
-
useEffect(() => {
|
|
1122
|
-
start(config2, args2.inputs.env);
|
|
1123
|
-
}, []);
|
|
1124
|
-
return /* @__PURE__ */ React6.createElement(ThemeProvider, { theme }, /* @__PURE__ */ React6.createElement(PrepareView, null), isListening && /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column", width, height }, /* @__PURE__ */ React6.createElement(Text6, null, "Server Listening on http://[", host, "]:", port), /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "row", width: "100%", height: "40%" }, /* @__PURE__ */ React6.createElement(side_bar_default, null), /* @__PURE__ */ React6.createElement(content_view_default, null)), /* @__PURE__ */ React6.createElement(action_logs_default, null)));
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
// src/cli.tsx
|
|
772
|
+
// src/cli.ts
|
|
1128
773
|
var args = loadArgs();
|
|
1129
774
|
var config = await loadConfig(args.flags.configFile);
|
|
1130
|
-
|
|
775
|
+
var builder = new BuildTaskManager(config, args.inputs.env);
|
|
776
|
+
await builder.execute();
|
|
777
|
+
var watcher = new WatchTaskManager(config, args.inputs.env);
|
|
778
|
+
await watcher.execute();
|