@cloudnux/cli 0.1.0 → 0.11.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} +108 -450
- 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 +31 -95
- 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/dist/types.d.ts +165 -0
- package/dist/types.mjs +1 -0
- package/package.json +20 -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,49 @@ 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({
|
|
447
|
+
format: ["esm"],
|
|
448
|
+
banner: {
|
|
449
|
+
js: `
|
|
450
|
+
import __node_module from 'node:module';
|
|
451
|
+
import __node_url from 'node:url';
|
|
452
|
+
import __node_path from 'node:path';
|
|
453
|
+
const require = __node_module.createRequire(import.meta.url);
|
|
454
|
+
const __filename = __node_url.fileURLToPath(import.meta.url);
|
|
455
|
+
const __dirname = __node_path.dirname(__filename);
|
|
456
|
+
`.trim()
|
|
457
|
+
},
|
|
458
|
+
outExtension: () => ({ js: ".mjs" }),
|
|
459
|
+
//========================================
|
|
422
460
|
entry: {
|
|
423
461
|
index: entryPath
|
|
424
462
|
},
|
|
425
|
-
external: [...externalPackages],
|
|
426
463
|
esbuildOptions: (options) => {
|
|
427
464
|
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
465
|
return options;
|
|
435
466
|
},
|
|
436
467
|
bundle: true,
|
|
468
|
+
noExternal: [],
|
|
437
469
|
sourcemap: true,
|
|
470
|
+
minify: false,
|
|
438
471
|
outDir: workingDir,
|
|
439
472
|
platform: "node",
|
|
473
|
+
cjsInterop: true,
|
|
474
|
+
shims: true,
|
|
440
475
|
dts: false,
|
|
441
476
|
watch: false,
|
|
442
477
|
env: {
|
|
443
|
-
__ENV_PATH__: '"' + path11.resolve(
|
|
478
|
+
__ENV_PATH__: '"' + path11.resolve(workingDir, "../../.env").replace(/\\/g, "\\\\") + '"',
|
|
479
|
+
__DEV__: process.env.__DEV__ || '"development"'
|
|
480
|
+
},
|
|
481
|
+
define: {
|
|
482
|
+
__ENV_PATH__: '"' + path11.resolve(workingDir, "../../.env").replace(/\\/g, "\\\\") + '"',
|
|
444
483
|
__DEV__: process.env.__DEV__ || '"development"'
|
|
445
484
|
},
|
|
446
485
|
esbuildPlugins: [
|
|
@@ -459,7 +498,6 @@ var devServerWatch = {
|
|
|
459
498
|
},
|
|
460
499
|
startServerPlugin(logger, eventEmitter)
|
|
461
500
|
]
|
|
462
|
-
// silent: true // Prevent console output
|
|
463
501
|
});
|
|
464
502
|
}
|
|
465
503
|
};
|
|
@@ -472,33 +510,22 @@ function startModule(main, execArgv, logger, eventEmitter) {
|
|
|
472
510
|
eventEmitter(message.type, message.payload);
|
|
473
511
|
break;
|
|
474
512
|
case "APP_REGISTERED":
|
|
475
|
-
eventEmitter(message.type, message.payload);
|
|
476
|
-
break;
|
|
477
513
|
case "ROUTE_REGISTERED":
|
|
478
|
-
eventEmitter(message.type, message.payload);
|
|
479
|
-
break;
|
|
480
514
|
case "LISTENING":
|
|
481
|
-
eventEmitter(message.type, message.payload);
|
|
482
|
-
break;
|
|
483
515
|
case "REQUEST":
|
|
484
|
-
eventEmitter(message.type, message.payload);
|
|
485
|
-
break;
|
|
486
516
|
case "RESPONSE":
|
|
487
|
-
eventEmitter(message.type, message.payload);
|
|
488
|
-
break;
|
|
489
517
|
case "LOG":
|
|
490
518
|
eventEmitter(message.type, message.payload);
|
|
491
|
-
|
|
492
|
-
eventEmitter(message.type, message.payload);
|
|
519
|
+
break;
|
|
493
520
|
default:
|
|
494
|
-
logger("Unknown message:", message);
|
|
495
521
|
break;
|
|
496
522
|
}
|
|
497
523
|
});
|
|
498
524
|
child.on("error", function(error) {
|
|
499
525
|
console.error(error);
|
|
526
|
+
child.kill("SIGINT");
|
|
500
527
|
});
|
|
501
|
-
child.on("close", function(
|
|
528
|
+
child.on("close", function() {
|
|
502
529
|
child.kill("SIGINT");
|
|
503
530
|
});
|
|
504
531
|
return child;
|
|
@@ -509,17 +536,18 @@ function startServerPlugin(logger, eventEmitter) {
|
|
|
509
536
|
name: "start servers",
|
|
510
537
|
setup(build) {
|
|
511
538
|
let child;
|
|
512
|
-
|
|
513
|
-
console.log(outdir, logLevel);
|
|
514
|
-
const main = path11.resolve(outdir, "index.cjs");
|
|
515
|
-
build.onEnd(async function({ errors }) {
|
|
539
|
+
build.onEnd(async function({ errors, outputFiles }) {
|
|
516
540
|
if (child) {
|
|
517
541
|
child.kill("SIGINT");
|
|
518
542
|
if (!child.killed) {
|
|
519
543
|
console.error(`cannot stop process ${child.pid}`);
|
|
520
544
|
}
|
|
521
545
|
}
|
|
522
|
-
if (errors && errors.length > 0)
|
|
546
|
+
if (errors && errors.length > 0) {
|
|
547
|
+
errors.forEach(logger);
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
const main = outputFiles?.find((file) => file.path.endsWith(".js") || file.path.endsWith(".mjs"))?.path;
|
|
523
551
|
child = startModule(main, ["--enable-source-maps"], logger, eventEmitter);
|
|
524
552
|
});
|
|
525
553
|
}
|
|
@@ -572,12 +600,12 @@ var transferTerraformModules = {
|
|
|
572
600
|
var defaultConfig = {
|
|
573
601
|
modulesPath: "./packages/modules/**/entrypoint.json",
|
|
574
602
|
cloudProvider: "aws",
|
|
575
|
-
workingDir: "./.
|
|
603
|
+
workingDir: "./.nux",
|
|
604
|
+
externalPackages: ["aws-sdk", "@aws-sdk/*"],
|
|
576
605
|
environments: {
|
|
577
606
|
develop: {
|
|
578
607
|
moduleTemplatePath: "./templates/local/module.ts.ejs",
|
|
579
608
|
devServerTemplatePath: "./templates/local/dev-server.ts.ejs",
|
|
580
|
-
externalPackages: ["sqlite3", "pino"],
|
|
581
609
|
tasks: [
|
|
582
610
|
loadModuleTemplate,
|
|
583
611
|
loadDevServerTemplate,
|
|
@@ -589,7 +617,6 @@ var defaultConfig = {
|
|
|
589
617
|
production: {
|
|
590
618
|
moduleTemplatePath: "./templates/cloud/entrypoint-build.ts.ejs",
|
|
591
619
|
triggerTemplatePath: "./templates/cloud/entrypoint-triggers.tf.ejs",
|
|
592
|
-
externalPackages: ["aws-sdk", "@aws-sdk/*"],
|
|
593
620
|
tasks: [
|
|
594
621
|
loadModuleTemplate,
|
|
595
622
|
loadTriggerTemplate,
|
|
@@ -657,7 +684,7 @@ function validateConfig(config2) {
|
|
|
657
684
|
}
|
|
658
685
|
|
|
659
686
|
// src/config/index.ts
|
|
660
|
-
var CONFIG_FILE_NAMES = ["
|
|
687
|
+
var CONFIG_FILE_NAMES = ["nux.config", "nuxrc"];
|
|
661
688
|
async function resolveConfig(config2, configContext) {
|
|
662
689
|
if (typeof config2 === "function") {
|
|
663
690
|
try {
|
|
@@ -723,13 +750,13 @@ function loadArgs() {
|
|
|
723
750
|
const args2 = meow(
|
|
724
751
|
`
|
|
725
752
|
Usage
|
|
726
|
-
$
|
|
753
|
+
$ nux <enviroment>
|
|
727
754
|
|
|
728
755
|
Options
|
|
729
756
|
--config Your config file path
|
|
730
757
|
|
|
731
758
|
Examples
|
|
732
|
-
$
|
|
759
|
+
$ nux develop --config=./config.json
|
|
733
760
|
`,
|
|
734
761
|
{
|
|
735
762
|
importMeta: import.meta,
|
|
@@ -752,379 +779,10 @@ function loadArgs() {
|
|
|
752
779
|
};
|
|
753
780
|
}
|
|
754
781
|
|
|
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
|
|
782
|
+
// src/cli.ts
|
|
1128
783
|
var args = loadArgs();
|
|
1129
784
|
var config = await loadConfig(args.flags.configFile);
|
|
1130
|
-
|
|
785
|
+
var builder = new BuildTaskManager(config, args.inputs.env);
|
|
786
|
+
await builder.execute();
|
|
787
|
+
var watcher = new WatchTaskManager(config, args.inputs.env);
|
|
788
|
+
await watcher.execute();
|