@cat-indev/catops-cli 0.0.1-alpha.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1254 -0
  3. package/dist/bin/devops-cli.d.ts +2 -0
  4. package/dist/bin/devops-cli.js +132 -0
  5. package/dist/bin/devops-cli.js.map +1 -0
  6. package/dist/core/Context.d.ts +56 -0
  7. package/dist/core/Context.js +197 -0
  8. package/dist/core/Context.js.map +1 -0
  9. package/dist/core/Menu.d.ts +23 -0
  10. package/dist/core/Menu.js +160 -0
  11. package/dist/core/Menu.js.map +1 -0
  12. package/dist/core/Notifier.d.ts +42 -0
  13. package/dist/core/Notifier.js +128 -0
  14. package/dist/core/Notifier.js.map +1 -0
  15. package/dist/core/classifiers.d.ts +45 -0
  16. package/dist/core/classifiers.js +90 -0
  17. package/dist/core/classifiers.js.map +1 -0
  18. package/dist/core/logger.d.ts +8 -0
  19. package/dist/core/logger.js +37 -0
  20. package/dist/core/logger.js.map +1 -0
  21. package/dist/core/messages.d.ts +102 -0
  22. package/dist/core/messages.js +163 -0
  23. package/dist/core/messages.js.map +1 -0
  24. package/dist/core/prompt.d.ts +10 -0
  25. package/dist/core/prompt.js +87 -0
  26. package/dist/core/prompt.js.map +1 -0
  27. package/dist/core/senders.d.ts +27 -0
  28. package/dist/core/senders.js +109 -0
  29. package/dist/core/senders.js.map +1 -0
  30. package/dist/core/types.d.ts +135 -0
  31. package/dist/core/types.js +33 -0
  32. package/dist/core/types.js.map +1 -0
  33. package/dist/index.d.ts +20 -0
  34. package/dist/index.js +66 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/services/ansible.d.ts +12 -0
  37. package/dist/services/ansible.js +35 -0
  38. package/dist/services/ansible.js.map +1 -0
  39. package/dist/services/archive.d.ts +4 -0
  40. package/dist/services/archive.js +16 -0
  41. package/dist/services/archive.js.map +1 -0
  42. package/dist/services/argocd.d.ts +23 -0
  43. package/dist/services/argocd.js +48 -0
  44. package/dist/services/argocd.js.map +1 -0
  45. package/dist/services/az.d.ts +38 -0
  46. package/dist/services/az.js +51 -0
  47. package/dist/services/az.js.map +1 -0
  48. package/dist/services/azdo-api.d.ts +213 -0
  49. package/dist/services/azdo-api.js +247 -0
  50. package/dist/services/azdo-api.js.map +1 -0
  51. package/dist/services/azdo.d.ts +13 -0
  52. package/dist/services/azdo.js +57 -0
  53. package/dist/services/azdo.js.map +1 -0
  54. package/dist/services/docker.d.ts +21 -0
  55. package/dist/services/docker.js +36 -0
  56. package/dist/services/docker.js.map +1 -0
  57. package/dist/services/git.d.ts +9 -0
  58. package/dist/services/git.js +36 -0
  59. package/dist/services/git.js.map +1 -0
  60. package/dist/services/helm.d.ts +4 -0
  61. package/dist/services/helm.js +24 -0
  62. package/dist/services/helm.js.map +1 -0
  63. package/dist/services/http-types.d.ts +57 -0
  64. package/dist/services/http-types.js +3 -0
  65. package/dist/services/http-types.js.map +1 -0
  66. package/dist/services/http.d.ts +64 -0
  67. package/dist/services/http.js +288 -0
  68. package/dist/services/http.js.map +1 -0
  69. package/dist/services/index.d.ts +37 -0
  70. package/dist/services/index.js +88 -0
  71. package/dist/services/index.js.map +1 -0
  72. package/dist/services/kubectl.d.ts +137 -0
  73. package/dist/services/kubectl.js +271 -0
  74. package/dist/services/kubectl.js.map +1 -0
  75. package/dist/services/npm.d.ts +5 -0
  76. package/dist/services/npm.js +20 -0
  77. package/dist/services/npm.js.map +1 -0
  78. package/dist/services/oc.d.ts +156 -0
  79. package/dist/services/oc.js +309 -0
  80. package/dist/services/oc.js.map +1 -0
  81. package/dist/services/pipeline.d.ts +116 -0
  82. package/dist/services/pipeline.js +474 -0
  83. package/dist/services/pipeline.js.map +1 -0
  84. package/dist/services/shell.d.ts +28 -0
  85. package/dist/services/shell.js +206 -0
  86. package/dist/services/shell.js.map +1 -0
  87. package/dist/services/tekton.d.ts +16 -0
  88. package/dist/services/tekton.js +46 -0
  89. package/dist/services/tekton.js.map +1 -0
  90. package/dist/services/terraform.d.ts +31 -0
  91. package/dist/services/terraform.js +63 -0
  92. package/dist/services/terraform.js.map +1 -0
  93. package/package.json +58 -0
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,132 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ const path = __importStar(require("path"));
38
+ const fs = __importStar(require("fs"));
39
+ const Context_1 = require("../core/Context");
40
+ const Menu_1 = require("../core/Menu");
41
+ const logger_1 = require("../core/logger");
42
+ const CONFIG_CANDIDATES = [
43
+ "devops.pipeline.js",
44
+ "devops.config.js",
45
+ ".catops-cli.js"
46
+ ];
47
+ function findConfig() {
48
+ const cwd = process.cwd();
49
+ for (const file of CONFIG_CANDIDATES) {
50
+ const fullPath = path.join(cwd, file);
51
+ if (fs.existsSync(fullPath)) {
52
+ return fullPath;
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+ function printHelp() {
58
+ console.log(`
59
+ catops-cli — framework CLI para pipelines DevOps
60
+
61
+ Uso:
62
+ catops-cli [--flag] [--param=valor]
63
+
64
+ Este comando busca, en el directorio actual, uno de estos archivos:
65
+ ${CONFIG_CANDIDATES.join("\n ")}
66
+
67
+ Ese archivo debe exportar una definición de menú, por ejemplo:
68
+
69
+ // devops.pipeline.js
70
+ module.exports = (ctx) => ({
71
+ title: "Pipeline",
72
+ "flag-selector": "--menu-selector",
73
+ options: {
74
+ Build: {
75
+ selector: "build",
76
+ action: async () => {
77
+ await ctx.services.docker.build({
78
+ image: "registry/app:v1",
79
+ dockerfile: "Dockerfile"
80
+ });
81
+ }
82
+ },
83
+ Deploy: {
84
+ selector: "deploy",
85
+ action: async () => {
86
+ await ctx.services.kubectl.apply("deployment.yaml");
87
+ }
88
+ }
89
+ }
90
+ });
91
+
92
+ Con esa definición, ambas formas funcionan:
93
+
94
+ catops-cli # menú interactivo
95
+ catops-cli --menu-selector=build # ejecuta "Build" directamente, sin prompts
96
+
97
+ Si "Deploy" fuera un submenú anidado con su propio "flag-selector", se puede
98
+ encadenar en un solo comando, por ejemplo:
99
+
100
+ catops-cli --menu-selector=deploy --deploy-target=staging
101
+
102
+ También puedes usar la librería directamente en tu código:
103
+
104
+ const { Context, Menu } = require("catops-cli");
105
+ import { Context, Menu } from "catops-cli"; // con tipados, en TS
106
+ `);
107
+ }
108
+ async function main() {
109
+ const configPath = findConfig();
110
+ if (!configPath) {
111
+ printHelp();
112
+ process.exit(0);
113
+ }
114
+ const ctx = Context_1.Context.parseArgv();
115
+ if (ctx.hasFlag("help") || ctx.hasFlag("h")) {
116
+ printHelp();
117
+ process.exit(0);
118
+ }
119
+ // eslint-disable-next-line @typescript-eslint/no-var-requires, global-require
120
+ const definitionFactory = require(configPath);
121
+ const definition = typeof definitionFactory === "function"
122
+ ? await definitionFactory(ctx)
123
+ : definitionFactory;
124
+ logger_1.logger.info(`Usando configuración: ${path.relative(process.cwd(), configPath)}`);
125
+ await Menu_1.Menu.render(definition, ctx);
126
+ }
127
+ main().catch(error => {
128
+ const message = error instanceof Error ? error.message : String(error);
129
+ logger_1.logger.error(message);
130
+ process.exit(1);
131
+ });
132
+ //# sourceMappingURL=devops-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devops-cli.js","sourceRoot":"","sources":["../../src/bin/devops-cli.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,2CAA6B;AAC7B,uCAAyB;AACzB,6CAA0C;AAC1C,uCAAoC;AACpC,2CAAwC;AAGxC,MAAM,iBAAiB,GAAG;IACtB,oBAAoB;IACpB,kBAAkB;IAClB,gBAAgB;CACnB,CAAC;AAEF,SAAS,UAAU;IAEf,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,KAAK,MAAM,IAAI,IAAI,iBAAiB,EAAE,CAAC;QAEnC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAEtC,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,OAAO,QAAQ,CAAC;QACpB,CAAC;IAEL,CAAC;IAED,OAAO,IAAI,CAAC;AAEhB,CAAC;AAED,SAAS,SAAS;IAEd,OAAO,CAAC,GAAG,CAAC;;;;;;;IAOZ,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCjC,CAAC,CAAC;AAEH,CAAC;AAMD,KAAK,UAAU,IAAI;IAEf,MAAM,UAAU,GAAG,UAAU,EAAE,CAAC;IAEhC,IAAI,CAAC,UAAU,EAAE,CAAC;QACd,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,GAAG,GAAG,iBAAO,CAAC,SAAS,EAAE,CAAC;IAEhC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,8EAA8E;IAC9E,MAAM,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAoC,CAAC;IAEjF,MAAM,UAAU,GAAG,OAAO,iBAAiB,KAAK,UAAU;QACtD,CAAC,CAAC,MAAM,iBAAiB,CAAC,GAAG,CAAC;QAC9B,CAAC,CAAC,iBAAiB,CAAC;IAExB,eAAM,CAAC,IAAI,CAAC,yBAAyB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;IAEjF,MAAM,WAAI,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AAEvC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACjB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,eAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { type Logger } from "./logger";
2
+ import { type ServicesRegistry } from "../services";
3
+ import { Notifier } from "./Notifier";
4
+ import type { AskOptions, ConfirmOptions, SelectChoices } from "./prompt";
5
+ import type { TaskHooks } from "./types";
6
+ export type FlagValue = boolean | string;
7
+ export declare class Context {
8
+ private static instance;
9
+ flags: Record<string, FlagValue>;
10
+ params: Record<string, string>;
11
+ env: NodeJS.ProcessEnv;
12
+ vars: Record<string, unknown>;
13
+ results: Record<string, unknown>;
14
+ logger: Logger;
15
+ services: ServicesRegistry;
16
+ notifier: Notifier;
17
+ config: Record<string, unknown>;
18
+ state: Record<string, unknown>;
19
+ static current(): Context;
20
+ /** Reinicia el singleton. Útil sobre todo en tests. */
21
+ static reset(): Context;
22
+ setFlag(name: string, value?: FlagValue): this;
23
+ getFlag(name: string): FlagValue | undefined;
24
+ hasFlag(name: string): boolean;
25
+ set<T = unknown>(name: string, value: T): this;
26
+ get<T = unknown>(name: string): T | undefined;
27
+ /**
28
+ * Ejecuta una task, guarda su resultado en `ctx.results[taskId]`, y
29
+ * dispara los callbacks de éxito/error correspondientes:
30
+ * 1. `hooks.onSuccess` / `hooks.onError` (si los pasaste), y
31
+ * 2. el `notifier` global (clasifica el error por área de TI y
32
+ * lo reporta a los canales registrados con `ctx.notifier.channel(...)`).
33
+ *
34
+ * Si la task lanza, el error se re-lanza después de notificar, para no
35
+ * esconder fallas silenciosamente.
36
+ */
37
+ run<T>(taskId: string, callback: (ctx: Context) => Promise<T> | T, hooks?: TaskHooks<T>): Promise<T>;
38
+ /**
39
+ * Envuelve un objeto de servicio (o cualquier objeto con métodos) en un
40
+ * Proxy que intercepta cada llamada a método. Si el método lanza un error,
41
+ * lo envuelve en un `ServiceError` con metadata del servicio (nombre,
42
+ * método, argumentos) y lo despacha al notifier antes de re-lanzarlo.
43
+ *
44
+ * Ejemplo:
45
+ * const docker = ctx.wrap(ctx.services.docker, "docker");
46
+ * await docker.push("myimage:latest");
47
+ * // Si falla, el notifier recibe:
48
+ * // taskId: 'docker.push("myimage:latest")'
49
+ * // error: ServiceError { service: "docker", method: "push", args: [...], cause: ExecResult }
50
+ */
51
+ wrap<T extends Record<string, (...args: any[]) => any>>(service: T, serviceName: string): T;
52
+ ask(question: string, options?: AskOptions): Promise<string | undefined>;
53
+ confirm(question: string, options?: ConfirmOptions): Promise<boolean>;
54
+ select(title: string, choices: SelectChoices): Promise<string>;
55
+ static parseArgv(argv?: string[]): Context;
56
+ }
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Context = void 0;
37
+ const logger_1 = require("./logger");
38
+ const prompt = __importStar(require("./prompt"));
39
+ const services_1 = require("../services");
40
+ const Notifier_1 = require("./Notifier");
41
+ const types_1 = require("./types");
42
+ class Context {
43
+ constructor() {
44
+ this.flags = {};
45
+ this.params = {};
46
+ this.env = { ...process.env };
47
+ this.vars = {};
48
+ this.results = {};
49
+ this.logger = logger_1.logger;
50
+ this.services = services_1.services;
51
+ this.notifier = new Notifier_1.Notifier();
52
+ this.config = {};
53
+ this.state = {};
54
+ }
55
+ static current() {
56
+ if (!Context.instance) {
57
+ Context.instance = new Context();
58
+ }
59
+ return Context.instance;
60
+ }
61
+ /** Reinicia el singleton. Útil sobre todo en tests. */
62
+ static reset() {
63
+ Context.instance = new Context();
64
+ return Context.instance;
65
+ }
66
+ // ---- flags ----
67
+ setFlag(name, value = true) {
68
+ this.flags[name] = value;
69
+ return this;
70
+ }
71
+ getFlag(name) {
72
+ return this.flags[name];
73
+ }
74
+ hasFlag(name) {
75
+ return Boolean(this.flags[name]);
76
+ }
77
+ // ---- vars ----
78
+ set(name, value) {
79
+ this.vars[name] = value;
80
+ return this;
81
+ }
82
+ get(name) {
83
+ return this.vars[name];
84
+ }
85
+ // ---- results del pipe ----
86
+ /**
87
+ * Ejecuta una task, guarda su resultado en `ctx.results[taskId]`, y
88
+ * dispara los callbacks de éxito/error correspondientes:
89
+ * 1. `hooks.onSuccess` / `hooks.onError` (si los pasaste), y
90
+ * 2. el `notifier` global (clasifica el error por área de TI y
91
+ * lo reporta a los canales registrados con `ctx.notifier.channel(...)`).
92
+ *
93
+ * Si la task lanza, el error se re-lanza después de notificar, para no
94
+ * esconder fallas silenciosamente.
95
+ */
96
+ async run(taskId, callback, hooks = {}) {
97
+ try {
98
+ const value = await callback(this);
99
+ this.results[taskId] = value;
100
+ await hooks.onSuccess?.(value, this);
101
+ await this.notifier.reportSuccess(taskId, value, this);
102
+ return value;
103
+ }
104
+ catch (error) {
105
+ await hooks.onError?.(error, this);
106
+ await this.notifier.reportError(taskId, error, this);
107
+ throw error;
108
+ }
109
+ }
110
+ /**
111
+ * Envuelve un objeto de servicio (o cualquier objeto con métodos) en un
112
+ * Proxy que intercepta cada llamada a método. Si el método lanza un error,
113
+ * lo envuelve en un `ServiceError` con metadata del servicio (nombre,
114
+ * método, argumentos) y lo despacha al notifier antes de re-lanzarlo.
115
+ *
116
+ * Ejemplo:
117
+ * const docker = ctx.wrap(ctx.services.docker, "docker");
118
+ * await docker.push("myimage:latest");
119
+ * // Si falla, el notifier recibe:
120
+ * // taskId: 'docker.push("myimage:latest")'
121
+ * // error: ServiceError { service: "docker", method: "push", args: [...], cause: ExecResult }
122
+ */
123
+ wrap(service, serviceName) {
124
+ const ctx = this;
125
+ return new Proxy(service, {
126
+ get(target, prop, receiver) {
127
+ const original = Reflect.get(target, prop, receiver);
128
+ if (typeof original !== "function")
129
+ return original;
130
+ return async function (...args) {
131
+ try {
132
+ return await original.apply(target, args);
133
+ }
134
+ catch (error) {
135
+ const methodName = String(prop);
136
+ const serializedArgs = args.map(a => {
137
+ try {
138
+ return JSON.stringify(a);
139
+ }
140
+ catch {
141
+ return String(a);
142
+ }
143
+ }).join(", ");
144
+ const taskId = `${serviceName}.${methodName}(${serializedArgs})`;
145
+ const wrapped = new types_1.ServiceError(serviceName, methodName, args, error);
146
+ await ctx.notifier.reportError(taskId, wrapped, ctx);
147
+ throw wrapped;
148
+ }
149
+ };
150
+ }
151
+ });
152
+ }
153
+ // ---- prompts ----
154
+ async ask(question, options) {
155
+ return prompt.ask(question, options);
156
+ }
157
+ async confirm(question, options) {
158
+ return prompt.confirm(question, options);
159
+ }
160
+ async select(title, choices) {
161
+ return prompt.select(title, choices);
162
+ }
163
+ // ---- inicialización desde argv ----
164
+ static parseArgv(argv = process.argv.slice(2)) {
165
+ const ctx = Context.current();
166
+ argv.forEach(arg => {
167
+ if (arg.startsWith("--")) {
168
+ const [key, value] = arg.slice(2).split("=");
169
+ if (value === undefined) {
170
+ ctx.setFlag(key, true);
171
+ }
172
+ else {
173
+ ctx.params[key] = value;
174
+ }
175
+ }
176
+ });
177
+ // Flags globales que reconfiguran shell.exec para todo el proceso,
178
+ // sin que ninguna task tenga que pasarlos manualmente.
179
+ const shellOptions = {};
180
+ if (ctx.hasFlag("dry-run") || ctx.hasFlag("dryRun")) {
181
+ shellOptions.dryRun = true;
182
+ }
183
+ if (ctx.params.retry !== undefined) {
184
+ shellOptions.retry = parseInt(ctx.params.retry, 10);
185
+ }
186
+ if (ctx.params.timeout !== undefined) {
187
+ shellOptions.timeout = parseInt(ctx.params.timeout, 10);
188
+ }
189
+ if (Object.keys(shellOptions).length) {
190
+ ctx.services.shell.configure(shellOptions);
191
+ }
192
+ return ctx;
193
+ }
194
+ }
195
+ exports.Context = Context;
196
+ Context.instance = null;
197
+ //# sourceMappingURL=Context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Context.js","sourceRoot":"","sources":["../../src/core/Context.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAA+C;AAC/C,iDAAmC;AACnC,0CAA8D;AAC9D,yCAAsC;AAGtC,mCAAuC;AAIvC,MAAa,OAAO;IAApB;QAII,UAAK,GAA8B,EAAE,CAAC;QACtC,WAAM,GAA2B,EAAE,CAAC;QACpC,QAAG,GAAsB,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC5C,SAAI,GAA4B,EAAE,CAAC;QACnC,YAAO,GAA4B,EAAE,CAAC;QACtC,WAAM,GAAW,eAAM,CAAC;QACxB,aAAQ,GAAqB,mBAAQ,CAAC;QACtC,aAAQ,GAAa,IAAI,mBAAQ,EAAE,CAAC;QACpC,WAAM,GAA4B,EAAE,CAAC;QACrC,UAAK,GAA4B,EAAE,CAAC;IAiLxC,CAAC;IA/KG,MAAM,CAAC,OAAO;QACV,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACpB,OAAO,CAAC,QAAQ,GAAG,IAAI,OAAO,EAAE,CAAC;QACrC,CAAC;QACD,OAAO,OAAO,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAED,uDAAuD;IACvD,MAAM,CAAC,KAAK;QACR,OAAO,CAAC,QAAQ,GAAG,IAAI,OAAO,EAAE,CAAC;QACjC,OAAO,OAAO,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAED,kBAAkB;IAElB,OAAO,CAAC,IAAY,EAAE,QAAmB,IAAI;QACzC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACzB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,CAAC,IAAY;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,CAAC,IAAY;QAChB,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACrC,CAAC;IAED,iBAAiB;IAEjB,GAAG,CAAc,IAAY,EAAE,KAAQ;QACnC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACxB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,GAAG,CAAc,IAAY;QACzB,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAkB,CAAC;IAC5C,CAAC;IAED,6BAA6B;IAE7B;;;;;;;;;OASG;IACH,KAAK,CAAC,GAAG,CACL,MAAc,EACd,QAA0C,EAC1C,QAAsB,EAAE;QAGxB,IAAI,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;YACnC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC;YAE7B,MAAM,KAAK,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACrC,MAAM,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAEvD,OAAO,KAAK,CAAC;QAEjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAEb,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACnC,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAErD,MAAM,KAAK,CAAC;QAEhB,CAAC;IAEL,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,IAAI,CAAoD,OAAU,EAAE,WAAmB;QACnF,MAAM,GAAG,GAAG,IAAI,CAAC;QACjB,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE;YACtB,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ;gBACtB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;gBACrD,IAAI,OAAO,QAAQ,KAAK,UAAU;oBAAE,OAAO,QAAQ,CAAC;gBACpD,OAAO,KAAK,WAA0B,GAAG,IAAe;oBACpD,IAAI,CAAC;wBACD,OAAO,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;oBAC9C,CAAC;oBAAC,OAAO,KAAK,EAAE,CAAC;wBACb,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;wBAChC,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;4BAChC,IAAI,CAAC;gCAAC,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;4BAAC,CAAC;4BAAC,MAAM,CAAC;gCAAC,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;4BAAC,CAAC;wBACjE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACd,MAAM,MAAM,GAAG,GAAG,WAAW,IAAI,UAAU,IAAI,cAAc,GAAG,CAAC;wBACjE,MAAM,OAAO,GAAG,IAAI,oBAAY,CAAC,WAAW,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;wBACvE,MAAM,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;wBACrD,MAAM,OAAO,CAAC;oBAClB,CAAC;gBACL,CAAC,CAAC;YACN,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAED,oBAAoB;IAEpB,KAAK,CAAC,GAAG,CAAC,QAAgB,EAAE,OAAoB;QAC5C,OAAO,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,QAAgB,EAAE,OAAwB;QACpD,OAAO,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,OAAsB;QAC9C,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC;IAED,sCAAsC;IAEtC,MAAM,CAAC,SAAS,CAAC,OAAiB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;QAEnD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QAE9B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YAEf,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBAEvB,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAE7C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACtB,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACJ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBAC5B,CAAC;YAEL,CAAC;QAEL,CAAC,CAAC,CAAC;QAEH,mEAAmE;QACnE,uDAAuD;QACvD,MAAM,YAAY,GAA2D,EAAE,CAAC;QAEhF,IAAI,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClD,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YACjC,YAAY,CAAC,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YACnC,YAAY,CAAC,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,CAAC;YACnC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO,GAAG,CAAC;IAEf,CAAC;;AA5LL,0BA8LC;AA5LkB,gBAAQ,GAAmB,IAAI,AAAvB,CAAwB"}
@@ -0,0 +1,23 @@
1
+ import { Context } from "./Context";
2
+ import type { MenuDefinition } from "./types";
3
+ export declare const EXIT: unique symbol;
4
+ export declare class Menu {
5
+ static readonly EXIT: symbol;
6
+ /**
7
+ * Ejecuta un item ya resuelto: si es una task, la corre, guarda su
8
+ * resultado en `ctx.results[label]`, dispara `onSuccess`/`onError`
9
+ * propios del item (si se pasaron) y reporta el resultado al
10
+ * `ctx.notifier` (clasificación por área de TI + canales). Si es un
11
+ * submenú, simplemente lo renderiza (y así hereda su propio manejo de
12
+ * flag-selector/hooks).
13
+ */
14
+ private static executeEntry;
15
+ /**
16
+ * Renderiza un menú. Si `definition["flag-selector"]` está presente y el
17
+ * Context trae un param que matchea el `selector` de alguno de los
18
+ * items, esa opción se ejecuta automáticamente sin pedir input al
19
+ * usuario (y, si es un submenú, este a su vez revisa su propio
20
+ * "flag-selector", permitiendo encadenar varios niveles).
21
+ */
22
+ static render(definition: MenuDefinition, ctx?: Context): Promise<typeof EXIT | void>;
23
+ }
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Menu = exports.EXIT = void 0;
37
+ const prompt = __importStar(require("./prompt"));
38
+ const logger_1 = require("./logger");
39
+ const Context_1 = require("./Context");
40
+ exports.EXIT = Symbol("exit");
41
+ function isMenuDefinition(value) {
42
+ return Boolean(value)
43
+ && typeof value === "object"
44
+ && "title" in value
45
+ && "options" in value;
46
+ }
47
+ function resolveEntry(value) {
48
+ if (typeof value === "function") {
49
+ return { kind: "task", run: value };
50
+ }
51
+ if (isMenuDefinition(value)) {
52
+ return { kind: "menu", menu: value };
53
+ }
54
+ if (value && typeof value === "object") {
55
+ const wrapped = value;
56
+ if (wrapped.menu) {
57
+ return { kind: "menu", menu: wrapped.menu, selector: wrapped.selector };
58
+ }
59
+ if (typeof wrapped.action === "function") {
60
+ return {
61
+ kind: "task",
62
+ run: wrapped.action,
63
+ selector: wrapped.selector,
64
+ onSuccess: wrapped.onSuccess,
65
+ onError: wrapped.onError
66
+ };
67
+ }
68
+ }
69
+ throw new Error(`Item de menú inválido: ${JSON.stringify(value)}`);
70
+ }
71
+ function normalizeFlagName(flagSelector) {
72
+ return flagSelector.replace(/^--?/, "");
73
+ }
74
+ function errorMessage(error) {
75
+ if (error instanceof Error)
76
+ return error.message;
77
+ const execError = error;
78
+ return execError?.stderr ?? execError?.stdout ?? String(error);
79
+ }
80
+ class Menu {
81
+ /**
82
+ * Ejecuta un item ya resuelto: si es una task, la corre, guarda su
83
+ * resultado en `ctx.results[label]`, dispara `onSuccess`/`onError`
84
+ * propios del item (si se pasaron) y reporta el resultado al
85
+ * `ctx.notifier` (clasificación por área de TI + canales). Si es un
86
+ * submenú, simplemente lo renderiza (y así hereda su propio manejo de
87
+ * flag-selector/hooks).
88
+ */
89
+ static async executeEntry(entry, label, ctx) {
90
+ if (entry.kind === "menu" && entry.menu) {
91
+ return Menu.render(entry.menu, ctx);
92
+ }
93
+ if (entry.kind === "task" && entry.run) {
94
+ try {
95
+ const result = await entry.run(ctx);
96
+ ctx.results[label] = result;
97
+ await entry.onSuccess?.(result, ctx);
98
+ await ctx.notifier.reportSuccess(label, result, ctx);
99
+ }
100
+ catch (error) {
101
+ await entry.onError?.(error, ctx);
102
+ await ctx.notifier.reportError(label, error, ctx);
103
+ logger_1.logger.error(errorMessage(error));
104
+ if (ctx.params.catch === "throw" || ctx.flags.catch === "throw")
105
+ throw error;
106
+ }
107
+ return;
108
+ }
109
+ logger_1.logger.warn(`Opción "${label}" no tiene acción definida.`);
110
+ }
111
+ /**
112
+ * Renderiza un menú. Si `definition["flag-selector"]` está presente y el
113
+ * Context trae un param que matchea el `selector` de alguno de los
114
+ * items, esa opción se ejecuta automáticamente sin pedir input al
115
+ * usuario (y, si es un submenú, este a su vez revisa su propio
116
+ * "flag-selector", permitiendo encadenar varios niveles).
117
+ */
118
+ static async render(definition, ctx) {
119
+ const activeCtx = ctx ?? Context_1.Context.current();
120
+ const { title, options } = definition;
121
+ const flagSelector = definition["flag-selector"];
122
+ if (flagSelector) {
123
+ const flagKey = normalizeFlagName(flagSelector);
124
+ const wantedValue = activeCtx.params[flagKey];
125
+ if (wantedValue !== undefined) {
126
+ const match = Object.entries(options).find(([, value]) => {
127
+ try {
128
+ return resolveEntry(value).selector === wantedValue;
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ });
134
+ if (match) {
135
+ const [label, value] = match;
136
+ const entry = resolveEntry(value);
137
+ logger_1.logger.info(`Selector automático: "${label}" (${flagSelector}=${wantedValue})`);
138
+ return Menu.executeEntry(entry, label, activeCtx);
139
+ }
140
+ logger_1.logger.warn(`Ningún item de "${title}" coincide con ${flagSelector}=${wantedValue}; se muestra el menú interactivo.`);
141
+ }
142
+ }
143
+ const labels = Object.keys(options);
144
+ labels.push("Salir");
145
+ while (true) {
146
+ const choiceKey = await prompt.select(title, labels);
147
+ const label = labels[Number(choiceKey)];
148
+ if (label === "Salir") {
149
+ return exports.EXIT;
150
+ }
151
+ const entry = resolveEntry(options[label]);
152
+ const result = await Menu.executeEntry(entry, label, activeCtx);
153
+ if (result === exports.EXIT)
154
+ continue;
155
+ }
156
+ }
157
+ }
158
+ exports.Menu = Menu;
159
+ Menu.EXIT = exports.EXIT;
160
+ //# sourceMappingURL=Menu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Menu.js","sourceRoot":"","sources":["../../src/core/Menu.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { Context } from "./Context";
2
+ import type { ErrorClassifier, ErrorMessageFormatter, Sender } from "./types";
3
+ export declare class Notifier {
4
+ private classifiers;
5
+ private messageFormatters;
6
+ private channels;
7
+ private successSenders;
8
+ private defaultArea;
9
+ /**
10
+ * Registra una función que decide a qué área de TI corresponde un
11
+ * error. Se prueban en el orden en que se registraron; gana la primera
12
+ * que devuelva un string. Si ninguna matchea, se usa el área "unclassified"
13
+ * (configurable con `setDefaultArea`).
14
+ */
15
+ classify(classifier: ErrorClassifier): this;
16
+ /**
17
+ * Registra una función que, dado el error, devuelve el mensaje
18
+ * personalizado a reportar (reemplaza el stderr/mensaje crudo). Se
19
+ * prueban en orden; gana la primera que devuelva un string. Si ninguna
20
+ * matchea, se usa el mensaje crudo del error (stderr/Error.message).
21
+ *
22
+ * Ejemplo:
23
+ * notifier.describeError(messages.byPattern([
24
+ * [/500 Internal Server Error/, "Se reportó a infraestructura: falta de espacio en el registry"],
25
+ * [/unauthorized|403/, "Credenciales inválidas contra el registry, revisa el secret"]
26
+ * ]));
27
+ */
28
+ describeError(formatter: ErrorMessageFormatter): this;
29
+ setDefaultArea(area: string): this;
30
+ /**
31
+ * Asocia uno o más senders a un área. Puedes registrar el mismo sender
32
+ * en varias áreas, o usar el área especial "*" para que reciba TODOS
33
+ * los errores sin importar la clasificación.
34
+ */
35
+ channel(area: string, ...senders: Sender[]): this;
36
+ /** Senders que se disparan en cada tarea exitosa, sin clasificación. */
37
+ onSuccess(...senders: Sender[]): this;
38
+ private resolveArea;
39
+ private resolveMessage;
40
+ reportSuccess(taskId: string, result: unknown, ctx: Context): Promise<void>;
41
+ reportError(taskId: string, error: unknown, ctx: Context): Promise<string>;
42
+ }