blokctl 0.2.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.
Files changed (169) hide show
  1. package/dist/commands/build/index.d.ts +2 -0
  2. package/dist/commands/build/index.js +210 -0
  3. package/dist/commands/config/index.d.ts +1 -0
  4. package/dist/commands/config/index.js +46 -0
  5. package/dist/commands/cost/index.d.ts +1 -0
  6. package/dist/commands/cost/index.js +74 -0
  7. package/dist/commands/create/node.d.ts +2 -0
  8. package/dist/commands/create/node.js +541 -0
  9. package/dist/commands/create/project.d.ts +2 -0
  10. package/dist/commands/create/project.js +941 -0
  11. package/dist/commands/create/utils/Examples.d.ts +39 -0
  12. package/dist/commands/create/utils/Examples.js +983 -0
  13. package/dist/commands/create/workflow.d.ts +2 -0
  14. package/dist/commands/create/workflow.js +109 -0
  15. package/dist/commands/deploy/index.d.ts +2 -0
  16. package/dist/commands/deploy/index.js +176 -0
  17. package/dist/commands/dev/index.d.ts +2 -0
  18. package/dist/commands/dev/index.js +190 -0
  19. package/dist/commands/generate/GenerationAnalytics.d.ts +61 -0
  20. package/dist/commands/generate/GenerationAnalytics.js +162 -0
  21. package/dist/commands/generate/GenerationAnalytics.test.d.ts +1 -0
  22. package/dist/commands/generate/GenerationAnalytics.test.js +407 -0
  23. package/dist/commands/generate/NodeFileWriter.d.ts +5 -0
  24. package/dist/commands/generate/NodeFileWriter.js +240 -0
  25. package/dist/commands/generate/NodeGenerator.d.ts +20 -0
  26. package/dist/commands/generate/NodeGenerator.js +181 -0
  27. package/dist/commands/generate/NodeGenerator.test.d.ts +1 -0
  28. package/dist/commands/generate/NodeGenerator.test.js +101 -0
  29. package/dist/commands/generate/PromptVersioning.d.ts +25 -0
  30. package/dist/commands/generate/PromptVersioning.js +71 -0
  31. package/dist/commands/generate/PromptVersioning.test.d.ts +1 -0
  32. package/dist/commands/generate/PromptVersioning.test.js +120 -0
  33. package/dist/commands/generate/RegisterNode.d.ts +3 -0
  34. package/dist/commands/generate/RegisterNode.js +37 -0
  35. package/dist/commands/generate/RuntimeGenerator.d.ts +40 -0
  36. package/dist/commands/generate/RuntimeGenerator.js +369 -0
  37. package/dist/commands/generate/RuntimeGenerator.test.d.ts +1 -0
  38. package/dist/commands/generate/RuntimeGenerator.test.js +553 -0
  39. package/dist/commands/generate/TriggerGenerator.d.ts +22 -0
  40. package/dist/commands/generate/TriggerGenerator.js +220 -0
  41. package/dist/commands/generate/TriggerGenerator.test.d.ts +1 -0
  42. package/dist/commands/generate/TriggerGenerator.test.js +209 -0
  43. package/dist/commands/generate/WorkflowGenerator.d.ts +20 -0
  44. package/dist/commands/generate/WorkflowGenerator.js +131 -0
  45. package/dist/commands/generate/WorkflowGenerator.test.d.ts +1 -0
  46. package/dist/commands/generate/WorkflowGenerator.test.js +77 -0
  47. package/dist/commands/generate/e2e/NodeGenerator.e2e.test.d.ts +1 -0
  48. package/dist/commands/generate/e2e/NodeGenerator.e2e.test.js +216 -0
  49. package/dist/commands/generate/e2e/RuntimeGenerator.e2e.test.d.ts +1 -0
  50. package/dist/commands/generate/e2e/RuntimeGenerator.e2e.test.js +759 -0
  51. package/dist/commands/generate/e2e/TriggerGenerator.e2e.test.d.ts +1 -0
  52. package/dist/commands/generate/e2e/TriggerGenerator.e2e.test.js +295 -0
  53. package/dist/commands/generate/e2e/WorkflowGenerator.e2e.test.d.ts +1 -0
  54. package/dist/commands/generate/e2e/WorkflowGenerator.e2e.test.js +353 -0
  55. package/dist/commands/generate/index.d.ts +1 -0
  56. package/dist/commands/generate/index.js +418 -0
  57. package/dist/commands/generate/prompts/create-fn-node.system.d.ts +5 -0
  58. package/dist/commands/generate/prompts/create-fn-node.system.js +256 -0
  59. package/dist/commands/generate/prompts/create-node-manifest.system.d.ts +4 -0
  60. package/dist/commands/generate/prompts/create-node-manifest.system.js +41 -0
  61. package/dist/commands/generate/prompts/create-node.system.d.ts +5 -0
  62. package/dist/commands/generate/prompts/create-node.system.js +114 -0
  63. package/dist/commands/generate/prompts/create-readme.system.d.ts +4 -0
  64. package/dist/commands/generate/prompts/create-readme.system.js +83 -0
  65. package/dist/commands/generate/prompts/create-runtime.system.d.ts +5 -0
  66. package/dist/commands/generate/prompts/create-runtime.system.js +284 -0
  67. package/dist/commands/generate/prompts/create-trigger.system.d.ts +5 -0
  68. package/dist/commands/generate/prompts/create-trigger.system.js +293 -0
  69. package/dist/commands/generate/prompts/create-workflow.system.d.ts +5 -0
  70. package/dist/commands/generate/prompts/create-workflow.system.js +476 -0
  71. package/dist/commands/generate/prompts/register-node.system.d.ts +4 -0
  72. package/dist/commands/generate/prompts/register-node.system.js +26 -0
  73. package/dist/commands/generate/validators/CompilationValidator.d.ts +9 -0
  74. package/dist/commands/generate/validators/CompilationValidator.js +86 -0
  75. package/dist/commands/generate/validators/CompilationValidator.test.d.ts +1 -0
  76. package/dist/commands/generate/validators/CompilationValidator.test.js +161 -0
  77. package/dist/commands/generate/validators/NodeValidator.d.ts +18 -0
  78. package/dist/commands/generate/validators/NodeValidator.js +217 -0
  79. package/dist/commands/generate/validators/NodeValidator.test.d.ts +1 -0
  80. package/dist/commands/generate/validators/NodeValidator.test.js +281 -0
  81. package/dist/commands/generate/validators/WorkflowValidator.d.ts +6 -0
  82. package/dist/commands/generate/validators/WorkflowValidator.js +301 -0
  83. package/dist/commands/generate/validators/WorkflowValidator.test.d.ts +1 -0
  84. package/dist/commands/generate/validators/WorkflowValidator.test.js +647 -0
  85. package/dist/commands/generate/validators/index.d.ts +4 -0
  86. package/dist/commands/generate/validators/index.js +2 -0
  87. package/dist/commands/graph/index.d.ts +1 -0
  88. package/dist/commands/graph/index.js +69 -0
  89. package/dist/commands/install/index.d.ts +1 -0
  90. package/dist/commands/install/index.js +4 -0
  91. package/dist/commands/install/node.d.ts +4 -0
  92. package/dist/commands/install/node.js +136 -0
  93. package/dist/commands/install/workflow.d.ts +4 -0
  94. package/dist/commands/install/workflow.js +62 -0
  95. package/dist/commands/login/index.d.ts +2 -0
  96. package/dist/commands/login/index.js +77 -0
  97. package/dist/commands/logout/index.d.ts +2 -0
  98. package/dist/commands/logout/index.js +20 -0
  99. package/dist/commands/marketplace/runtime.d.ts +54 -0
  100. package/dist/commands/marketplace/runtime.js +350 -0
  101. package/dist/commands/migrate/index.d.ts +1 -0
  102. package/dist/commands/migrate/index.js +14 -0
  103. package/dist/commands/migrate/node.d.ts +2 -0
  104. package/dist/commands/migrate/node.js +110 -0
  105. package/dist/commands/monitor/index.d.ts +1 -0
  106. package/dist/commands/monitor/index.js +28 -0
  107. package/dist/commands/monitor/monitor-component.d.ts +1 -0
  108. package/dist/commands/monitor/monitor-component.js +271 -0
  109. package/dist/commands/monitor/static/index.html +2124 -0
  110. package/dist/commands/monitor/static-web-server.d.ts +1 -0
  111. package/dist/commands/monitor/static-web-server.js +89 -0
  112. package/dist/commands/profile/index.d.ts +1 -0
  113. package/dist/commands/profile/index.js +112 -0
  114. package/dist/commands/publish/index.d.ts +1 -0
  115. package/dist/commands/publish/index.js +4 -0
  116. package/dist/commands/publish/node.d.ts +4 -0
  117. package/dist/commands/publish/node.js +231 -0
  118. package/dist/commands/publish/workflow.d.ts +4 -0
  119. package/dist/commands/publish/workflow.js +165 -0
  120. package/dist/commands/search/docs.d.ts +17 -0
  121. package/dist/commands/search/docs.js +179 -0
  122. package/dist/commands/search/index.d.ts +1 -0
  123. package/dist/commands/search/index.js +5 -0
  124. package/dist/commands/search/indexer.d.ts +10 -0
  125. package/dist/commands/search/indexer.js +265 -0
  126. package/dist/commands/search/nodes.d.ts +4 -0
  127. package/dist/commands/search/nodes.js +101 -0
  128. package/dist/commands/search/workflow.d.ts +4 -0
  129. package/dist/commands/search/workflow.js +100 -0
  130. package/dist/commands/trace/index.d.ts +1 -0
  131. package/dist/commands/trace/index.js +26 -0
  132. package/dist/commands/trace/startStudio.d.ts +8 -0
  133. package/dist/commands/trace/startStudio.js +116 -0
  134. package/dist/index.d.ts +17 -0
  135. package/dist/index.js +186 -0
  136. package/dist/services/commander.d.ts +9 -0
  137. package/dist/services/commander.js +20 -0
  138. package/dist/services/constants.d.ts +1 -0
  139. package/dist/services/constants.js +3 -0
  140. package/dist/services/local-token-manager.d.ts +14 -0
  141. package/dist/services/local-token-manager.js +99 -0
  142. package/dist/services/non-interactive.d.ts +5 -0
  143. package/dist/services/non-interactive.js +30 -0
  144. package/dist/services/package-manager.d.ts +35 -0
  145. package/dist/services/package-manager.js +111 -0
  146. package/dist/services/posthog.d.ts +31 -0
  147. package/dist/services/posthog.js +159 -0
  148. package/dist/services/registry-manager.d.ts +9 -0
  149. package/dist/services/registry-manager.js +26 -0
  150. package/dist/services/runtime-detector.d.ts +23 -0
  151. package/dist/services/runtime-detector.js +181 -0
  152. package/dist/services/runtime-setup.d.ts +36 -0
  153. package/dist/services/runtime-setup.js +250 -0
  154. package/dist/services/utils.d.ts +2 -0
  155. package/dist/services/utils.js +29 -0
  156. package/dist/services/workflow-loader.d.ts +30 -0
  157. package/dist/services/workflow-loader.js +46 -0
  158. package/dist/studio-dist/assets/charts-Dso0hPUR.js +68 -0
  159. package/dist/studio-dist/assets/graph-CsV2nWGn.js +23 -0
  160. package/dist/studio-dist/assets/icons-zP8LLgPh.js +311 -0
  161. package/dist/studio-dist/assets/index-CLyEkXMx.css +1 -0
  162. package/dist/studio-dist/assets/index-CNXFX_ar.js +27 -0
  163. package/dist/studio-dist/assets/react-vendor--Eh9ivFN.js +17 -0
  164. package/dist/studio-dist/assets/tanstack-query-CiM1U6F5.js +1 -0
  165. package/dist/studio-dist/assets/tanstack-router-Btjy0MKq.js +25 -0
  166. package/dist/studio-dist/assets/tanstack-table-DhwRvuH2.js +22 -0
  167. package/dist/studio-dist/favicon.svg +5 -0
  168. package/dist/studio-dist/index.html +21 -0
  169. package/package.json +75 -0
@@ -0,0 +1,2 @@
1
+ import { type OptionValues } from "../../services/commander.js";
2
+ export declare function build(opts: OptionValues): Promise<boolean>;
@@ -0,0 +1,210 @@
1
+ import child_process from "node:child_process";
2
+ import crypto from "node:crypto";
3
+ import * as p from "@clack/prompts";
4
+ import fs from "fs-extra";
5
+ import { program, trackCommandExecution } from "../../services/commander.js";
6
+ import { BLOK_URL } from "../../services/constants.js";
7
+ import { tokenManager } from "../../services/local-token-manager.js";
8
+ const blokJsonModel = {
9
+ name: "",
10
+ builds: [],
11
+ lastBuild: {},
12
+ deployments: [],
13
+ lastDeployment: {},
14
+ };
15
+ async function initBuild(opts) {
16
+ const initBuild = await fetch(`${BLOK_URL}/build-init`, {
17
+ method: "GET",
18
+ headers: {
19
+ Authorization: `Bearer ${opts.token}`,
20
+ },
21
+ });
22
+ if (!initBuild.ok)
23
+ throw new Error(initBuild.statusText);
24
+ const initBuildData = await initBuild.json();
25
+ return initBuildData;
26
+ }
27
+ async function exec(command, args) {
28
+ await new Promise((resolve, reject) => {
29
+ const tarProcess = child_process.spawn(command, args);
30
+ tarProcess.on("close", (code) => {
31
+ if (code === 0) {
32
+ resolve();
33
+ }
34
+ else {
35
+ reject(new Error(`Tar process exited with code ${code}`));
36
+ }
37
+ });
38
+ tarProcess.on("error", (err) => {
39
+ reject(err);
40
+ });
41
+ });
42
+ }
43
+ async function createTarBall(opts) {
44
+ const fileName = `${crypto.randomUUID()}.tar.gz`;
45
+ const args = [
46
+ "-czf",
47
+ `${opts.directory}/${fileName}`,
48
+ "-C",
49
+ opts.directory,
50
+ `--exclude=${fileName}`,
51
+ "--exclude=.blok.json",
52
+ "--exclude=.git",
53
+ "--exclude=node_modules",
54
+ "--exclude=package-lock.json",
55
+ "--exclude=README.md",
56
+ "--exclude=.blok/runtimes/python3/python3_runtime/lib",
57
+ ".",
58
+ ];
59
+ try {
60
+ await exec("tar", args);
61
+ }
62
+ catch (error) {
63
+ throw new Error(`Failed to create tarball: ${error}`);
64
+ }
65
+ return fileName;
66
+ }
67
+ async function storeFiles(opts) {
68
+ const file = await fs.readFile(`${opts.directory}/${opts.tarball}`);
69
+ const requestOptions = {
70
+ method: "PUT",
71
+ headers: {
72
+ "Content-Type": "application/x-gzip",
73
+ },
74
+ body: file,
75
+ redirect: "follow",
76
+ };
77
+ const storing = await fetch(opts.url, requestOptions);
78
+ if (!storing.ok)
79
+ throw new Error("Failed to store file in S3 bucket");
80
+ }
81
+ async function building(opts) {
82
+ const build = await fetch(`${BLOK_URL}/build/${opts.id}`, {
83
+ method: "POST",
84
+ headers: {
85
+ "Content-Type": "application/json",
86
+ Authorization: `Bearer ${opts.token}`,
87
+ },
88
+ body: JSON.stringify({
89
+ key: opts.key,
90
+ }),
91
+ });
92
+ if (!build.ok)
93
+ throw new Error(build.statusText);
94
+ const buildData = await build.json();
95
+ return buildData;
96
+ }
97
+ async function getBuildStatus(opts) {
98
+ const buildStatus = await fetch(`${BLOK_URL}/build-status/${opts.id}`, {
99
+ method: "GET",
100
+ headers: {
101
+ Authorization: `Bearer ${opts.token}`,
102
+ },
103
+ });
104
+ if (!buildStatus.ok)
105
+ throw new Error(buildStatus.statusText);
106
+ const buildStatusData = await buildStatus.json();
107
+ return buildStatusData;
108
+ }
109
+ export async function build(opts) {
110
+ const logger = p.spinner();
111
+ try {
112
+ logger.start(`Building blok in ${opts.directory}...`);
113
+ logger.message("Validating authentication...");
114
+ opts.token = tokenManager.getToken();
115
+ if (!opts.token)
116
+ throw new Error("No token found. Please login first.");
117
+ const blokFile = `${opts.directory}/.blok.json`;
118
+ logger.message("Checking files...");
119
+ if (!fs.existsSync(opts.directory))
120
+ throw new Error(`Directory ${opts.directory} does not exist`);
121
+ if (!fs.existsSync(`${opts.directory}/Dockerfile`))
122
+ throw new Error(`Dockerfile not found in ${opts.directory}`);
123
+ if (!fs.existsSync(blokFile)) {
124
+ fs.ensureFileSync(blokFile);
125
+ fs.writeJSONSync(blokFile, blokJsonModel, { spaces: 2 });
126
+ logger.message("Creating .blok.json file...");
127
+ }
128
+ logger.message("Loading .blok.json file...");
129
+ const json = fs.readJSONSync(blokFile);
130
+ logger.message("Creating tarball...");
131
+ opts.tarball = await createTarBall(opts);
132
+ fs.ensureFileSync(opts.tarball);
133
+ logger.message("Tarball created");
134
+ logger.message("Initializing build...");
135
+ const init = await initBuild(opts);
136
+ opts.id = init.id;
137
+ opts.url = init.data.url;
138
+ opts.key = init.data.key;
139
+ logger.message("Build initialized");
140
+ logger.message("Storing files...");
141
+ await storeFiles(opts);
142
+ fs.removeSync(opts.tarball);
143
+ logger.message("Files stored");
144
+ logger.message("Building blok...");
145
+ const build = await building(opts);
146
+ let status;
147
+ do {
148
+ await new Promise((resolve) => setTimeout(resolve, 2000));
149
+ status = await getBuildStatus(opts);
150
+ logger.message(`Build ${status?.status?.condition?.reason}`);
151
+ } while (status?.status?.condition?.status === "Unknown");
152
+ logger.message("Storing build result...");
153
+ const initBuildModel = {
154
+ id: opts.id,
155
+ tarball: opts.tarball,
156
+ key: opts.key,
157
+ buildMessage: build.data.message,
158
+ creationTimestamp: build.data.creationTimestamp,
159
+ startTime: status?.status?.startTime,
160
+ completionTime: status?.status?.completionTime,
161
+ reason: status?.status?.condition?.reason,
162
+ status: status?.status?.condition?.status,
163
+ statusMessage: status?.status?.condition?.message,
164
+ updatedAt: new Date().toISOString(),
165
+ };
166
+ json.builds.push(initBuildModel);
167
+ json.lastBuild = initBuildModel;
168
+ fs.writeJSONSync(blokFile, json, { spaces: 2 });
169
+ if (status?.status?.condition?.status !== "True")
170
+ throw new Error(status?.status?.condition?.message);
171
+ logger.stop("Build completed successfully");
172
+ return true;
173
+ }
174
+ catch (error) {
175
+ if (opts.tarball && fs.existsSync(opts.tarball))
176
+ fs.removeSync(opts.tarball);
177
+ if (opts.id)
178
+ logger.error(`Build Failed. ${error} - Build ID: ${opts.id}`);
179
+ else
180
+ logger.error(`Build Failed. ${error}`);
181
+ console.error(error);
182
+ return false;
183
+ }
184
+ }
185
+ const buildCmd = program
186
+ .command("build")
187
+ .option("-d, --directory [value]", "Directory of the blok (defaults to current directory)", process.cwd())
188
+ .description("Build blok")
189
+ .action(async (options) => {
190
+ await trackCommandExecution({
191
+ command: "build",
192
+ args: options,
193
+ execution: async () => {
194
+ await build(options);
195
+ },
196
+ });
197
+ });
198
+ buildCmd
199
+ .command(".")
200
+ .description("Build blok in the current directory")
201
+ .action(async (options) => {
202
+ await trackCommandExecution({
203
+ command: "build .",
204
+ args: options,
205
+ execution: async () => {
206
+ options.directory = process.cwd();
207
+ await build(options);
208
+ },
209
+ });
210
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,46 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import { Command } from "commander";
4
+ import { program } from "../../services/commander.js";
5
+ const create = new Command("config").description("Configure CLI settings");
6
+ create
7
+ .command("set")
8
+ .description("Configure CLI settings")
9
+ .option("--editor <editor>", "Set default editor 'Visual Studio Code', 'Cursor', 'Sublime Text', 'Atom', 'WebStorm'", (value) => {
10
+ const validEditors = ["Visual Studio Code", "Cursor", "Sublime Text", "Atom", "WebStorm"];
11
+ if (!validEditors.includes(value)) {
12
+ throw new Error(`Editor must be one of: ${validEditors.join(", ")}`);
13
+ }
14
+ return value;
15
+ })
16
+ .action(async (options) => {
17
+ const configDir = `${os.homedir()}/.blok`;
18
+ const configPath = `${configDir}/config.json`;
19
+ if (!fs.existsSync(configDir)) {
20
+ fs.mkdirSync(configDir, { recursive: true });
21
+ }
22
+ let config = {};
23
+ if (fs.existsSync(configPath)) {
24
+ config = JSON.parse(fs.readFileSync(configPath, "utf8"));
25
+ }
26
+ if (options.editor) {
27
+ config.defaultEditor = options.editor;
28
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
29
+ console.log(`Default editor set to: ${options.editor}`);
30
+ }
31
+ });
32
+ create
33
+ .command("list")
34
+ .description("Show current CLI configuration")
35
+ .action(() => {
36
+ const configPath = `${os.homedir()}/.blok/config.json`;
37
+ if (fs.existsSync(configPath)) {
38
+ const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
39
+ console.log("Current configuration:");
40
+ console.log(JSON.stringify(config, null, 2));
41
+ }
42
+ else {
43
+ console.log("No configuration file found. Using defaults.");
44
+ }
45
+ });
46
+ program.addCommand(create);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,74 @@
1
+ import fs from "node:fs";
2
+ import * as p from "@clack/prompts";
3
+ import { program, trackCommandExecution } from "../../services/commander.js";
4
+ import { loadWorkflow, loadWorkflows } from "../../services/workflow-loader.js";
5
+ async function getCostEstimator() {
6
+ const { CostEstimator } = await import("@blok/runner");
7
+ return CostEstimator;
8
+ }
9
+ program
10
+ .command("cost [workflow-name]")
11
+ .description("Estimate execution costs for workflows")
12
+ .option("--executions <count>", "Monthly execution count", "10000")
13
+ .option("--provider <provider>", "Cloud provider: aws, gcp, azure, local", "aws")
14
+ .option("--format <format>", "Output format: table, json", "table")
15
+ .option("--output <file>", "Write output to file")
16
+ .option("-d, --directory [value]", "Project directory", process.cwd())
17
+ .action(async (workflowName, options) => {
18
+ await trackCommandExecution({
19
+ command: "cost",
20
+ args: options,
21
+ execution: async () => {
22
+ const logger = p.spinner();
23
+ logger.start("Loading workflows...");
24
+ const directory = options.directory;
25
+ const provider = options.provider || "aws";
26
+ const executions = Number.parseInt(options.executions, 10) || 10_000;
27
+ let workflows = [];
28
+ if (workflowName) {
29
+ const wf = await loadWorkflow(directory, workflowName);
30
+ if (!wf) {
31
+ logger.error(`Workflow "${workflowName}" not found.`);
32
+ return;
33
+ }
34
+ workflows = [wf];
35
+ }
36
+ else {
37
+ workflows = await loadWorkflows(directory);
38
+ }
39
+ if (workflows.length === 0) {
40
+ logger.error("No workflow files found.");
41
+ p.log.warn("Make sure your project has workflow JSON files in the workflows/ directory.");
42
+ return;
43
+ }
44
+ logger.stop(`Found ${workflows.length} workflow(s).`);
45
+ const CostEstimator = await getCostEstimator();
46
+ const estimator = new CostEstimator({
47
+ provider: provider,
48
+ executionsPerMonth: executions,
49
+ });
50
+ for (const wf of workflows) {
51
+ estimator.estimateWorkflow(wf.def);
52
+ }
53
+ let output;
54
+ const format = options.format;
55
+ switch (format) {
56
+ case "json":
57
+ output = estimator.toJson();
58
+ break;
59
+ default:
60
+ output = estimator.toTable();
61
+ }
62
+ if (options.output) {
63
+ fs.writeFileSync(options.output, output, "utf-8");
64
+ p.log.success(`Cost estimate written to ${options.output}`);
65
+ }
66
+ else {
67
+ console.log(output);
68
+ }
69
+ const estimates = estimator.getEstimates();
70
+ const totalMonthly = estimates.reduce((sum, e) => sum + e.monthlyCost, 0);
71
+ p.log.info(`Total estimated monthly cost (${provider.toUpperCase()}, ${executions.toLocaleString()} exec/month): $${totalMonthly.toFixed(2)}`);
72
+ },
73
+ });
74
+ });
@@ -0,0 +1,2 @@
1
+ import type { OptionValues } from "commander";
2
+ export declare function createNode(opts: OptionValues, currentPath?: boolean): Promise<void>;