@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.
@@ -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,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 ({ 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({
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(__dirname, "../.env").replace(/\\/g, "\\\\") + '"',
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
- // silent: true // Prevent console output
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
- case "log":
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(code) {
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
- const { outdir, logLevel } = build.initialOptions;
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) return;
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: "./.epf",
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 = ["epf.config", "epfrc"];
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
- $ epf <enviroment>
743
+ $ nux <enviroment>
727
744
 
728
745
  Options
729
746
  --config Your config file path
730
747
 
731
748
  Examples
732
- $ epf develop --config=./config.json
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/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
772
+ // src/cli.ts
1128
773
  var args = loadArgs();
1129
774
  var config = await loadConfig(args.flags.configFile);
1130
- render(/* @__PURE__ */ React7.createElement(App, { args, config }));
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();