@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.
@@ -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 TaskManager = class {
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 && task.skip(taskParams)) {
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, logger, eventEmitter, executeSubTasks);
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
- async watch() {
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: false,
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, _logger, _eventEmitter, executeSubTasks) => {
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 ({ workingDir, cloudProvider, externalPackages, ...rest }, logger, eventEmitter) => {
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(__dirname, "../.env").replace(/\\/g, "\\\\") + '"',
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
- case "log":
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(code) {
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
- const { outdir, logLevel } = build.initialOptions;
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) return;
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: "./.epf",
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 = ["epf.config", "epfrc"];
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
- $ epf <enviroment>
753
+ $ nux <enviroment>
727
754
 
728
755
  Options
729
756
  --config Your config file path
730
757
 
731
758
  Examples
732
- $ epf develop --config=./config.json
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/app.tsx
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
- render(/* @__PURE__ */ React7.createElement(App, { args, config }));
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();