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.
- package/dist/commands/build/index.d.ts +2 -0
- package/dist/commands/build/index.js +210 -0
- package/dist/commands/config/index.d.ts +1 -0
- package/dist/commands/config/index.js +46 -0
- package/dist/commands/cost/index.d.ts +1 -0
- package/dist/commands/cost/index.js +74 -0
- package/dist/commands/create/node.d.ts +2 -0
- package/dist/commands/create/node.js +541 -0
- package/dist/commands/create/project.d.ts +2 -0
- package/dist/commands/create/project.js +941 -0
- package/dist/commands/create/utils/Examples.d.ts +39 -0
- package/dist/commands/create/utils/Examples.js +983 -0
- package/dist/commands/create/workflow.d.ts +2 -0
- package/dist/commands/create/workflow.js +109 -0
- package/dist/commands/deploy/index.d.ts +2 -0
- package/dist/commands/deploy/index.js +176 -0
- package/dist/commands/dev/index.d.ts +2 -0
- package/dist/commands/dev/index.js +190 -0
- package/dist/commands/generate/GenerationAnalytics.d.ts +61 -0
- package/dist/commands/generate/GenerationAnalytics.js +162 -0
- package/dist/commands/generate/GenerationAnalytics.test.d.ts +1 -0
- package/dist/commands/generate/GenerationAnalytics.test.js +407 -0
- package/dist/commands/generate/NodeFileWriter.d.ts +5 -0
- package/dist/commands/generate/NodeFileWriter.js +240 -0
- package/dist/commands/generate/NodeGenerator.d.ts +20 -0
- package/dist/commands/generate/NodeGenerator.js +181 -0
- package/dist/commands/generate/NodeGenerator.test.d.ts +1 -0
- package/dist/commands/generate/NodeGenerator.test.js +101 -0
- package/dist/commands/generate/PromptVersioning.d.ts +25 -0
- package/dist/commands/generate/PromptVersioning.js +71 -0
- package/dist/commands/generate/PromptVersioning.test.d.ts +1 -0
- package/dist/commands/generate/PromptVersioning.test.js +120 -0
- package/dist/commands/generate/RegisterNode.d.ts +3 -0
- package/dist/commands/generate/RegisterNode.js +37 -0
- package/dist/commands/generate/RuntimeGenerator.d.ts +40 -0
- package/dist/commands/generate/RuntimeGenerator.js +369 -0
- package/dist/commands/generate/RuntimeGenerator.test.d.ts +1 -0
- package/dist/commands/generate/RuntimeGenerator.test.js +553 -0
- package/dist/commands/generate/TriggerGenerator.d.ts +22 -0
- package/dist/commands/generate/TriggerGenerator.js +220 -0
- package/dist/commands/generate/TriggerGenerator.test.d.ts +1 -0
- package/dist/commands/generate/TriggerGenerator.test.js +209 -0
- package/dist/commands/generate/WorkflowGenerator.d.ts +20 -0
- package/dist/commands/generate/WorkflowGenerator.js +131 -0
- package/dist/commands/generate/WorkflowGenerator.test.d.ts +1 -0
- package/dist/commands/generate/WorkflowGenerator.test.js +77 -0
- package/dist/commands/generate/e2e/NodeGenerator.e2e.test.d.ts +1 -0
- package/dist/commands/generate/e2e/NodeGenerator.e2e.test.js +216 -0
- package/dist/commands/generate/e2e/RuntimeGenerator.e2e.test.d.ts +1 -0
- package/dist/commands/generate/e2e/RuntimeGenerator.e2e.test.js +759 -0
- package/dist/commands/generate/e2e/TriggerGenerator.e2e.test.d.ts +1 -0
- package/dist/commands/generate/e2e/TriggerGenerator.e2e.test.js +295 -0
- package/dist/commands/generate/e2e/WorkflowGenerator.e2e.test.d.ts +1 -0
- package/dist/commands/generate/e2e/WorkflowGenerator.e2e.test.js +353 -0
- package/dist/commands/generate/index.d.ts +1 -0
- package/dist/commands/generate/index.js +418 -0
- package/dist/commands/generate/prompts/create-fn-node.system.d.ts +5 -0
- package/dist/commands/generate/prompts/create-fn-node.system.js +256 -0
- package/dist/commands/generate/prompts/create-node-manifest.system.d.ts +4 -0
- package/dist/commands/generate/prompts/create-node-manifest.system.js +41 -0
- package/dist/commands/generate/prompts/create-node.system.d.ts +5 -0
- package/dist/commands/generate/prompts/create-node.system.js +114 -0
- package/dist/commands/generate/prompts/create-readme.system.d.ts +4 -0
- package/dist/commands/generate/prompts/create-readme.system.js +83 -0
- package/dist/commands/generate/prompts/create-runtime.system.d.ts +5 -0
- package/dist/commands/generate/prompts/create-runtime.system.js +284 -0
- package/dist/commands/generate/prompts/create-trigger.system.d.ts +5 -0
- package/dist/commands/generate/prompts/create-trigger.system.js +293 -0
- package/dist/commands/generate/prompts/create-workflow.system.d.ts +5 -0
- package/dist/commands/generate/prompts/create-workflow.system.js +476 -0
- package/dist/commands/generate/prompts/register-node.system.d.ts +4 -0
- package/dist/commands/generate/prompts/register-node.system.js +26 -0
- package/dist/commands/generate/validators/CompilationValidator.d.ts +9 -0
- package/dist/commands/generate/validators/CompilationValidator.js +86 -0
- package/dist/commands/generate/validators/CompilationValidator.test.d.ts +1 -0
- package/dist/commands/generate/validators/CompilationValidator.test.js +161 -0
- package/dist/commands/generate/validators/NodeValidator.d.ts +18 -0
- package/dist/commands/generate/validators/NodeValidator.js +217 -0
- package/dist/commands/generate/validators/NodeValidator.test.d.ts +1 -0
- package/dist/commands/generate/validators/NodeValidator.test.js +281 -0
- package/dist/commands/generate/validators/WorkflowValidator.d.ts +6 -0
- package/dist/commands/generate/validators/WorkflowValidator.js +301 -0
- package/dist/commands/generate/validators/WorkflowValidator.test.d.ts +1 -0
- package/dist/commands/generate/validators/WorkflowValidator.test.js +647 -0
- package/dist/commands/generate/validators/index.d.ts +4 -0
- package/dist/commands/generate/validators/index.js +2 -0
- package/dist/commands/graph/index.d.ts +1 -0
- package/dist/commands/graph/index.js +69 -0
- package/dist/commands/install/index.d.ts +1 -0
- package/dist/commands/install/index.js +4 -0
- package/dist/commands/install/node.d.ts +4 -0
- package/dist/commands/install/node.js +136 -0
- package/dist/commands/install/workflow.d.ts +4 -0
- package/dist/commands/install/workflow.js +62 -0
- package/dist/commands/login/index.d.ts +2 -0
- package/dist/commands/login/index.js +77 -0
- package/dist/commands/logout/index.d.ts +2 -0
- package/dist/commands/logout/index.js +20 -0
- package/dist/commands/marketplace/runtime.d.ts +54 -0
- package/dist/commands/marketplace/runtime.js +350 -0
- package/dist/commands/migrate/index.d.ts +1 -0
- package/dist/commands/migrate/index.js +14 -0
- package/dist/commands/migrate/node.d.ts +2 -0
- package/dist/commands/migrate/node.js +110 -0
- package/dist/commands/monitor/index.d.ts +1 -0
- package/dist/commands/monitor/index.js +28 -0
- package/dist/commands/monitor/monitor-component.d.ts +1 -0
- package/dist/commands/monitor/monitor-component.js +271 -0
- package/dist/commands/monitor/static/index.html +2124 -0
- package/dist/commands/monitor/static-web-server.d.ts +1 -0
- package/dist/commands/monitor/static-web-server.js +89 -0
- package/dist/commands/profile/index.d.ts +1 -0
- package/dist/commands/profile/index.js +112 -0
- package/dist/commands/publish/index.d.ts +1 -0
- package/dist/commands/publish/index.js +4 -0
- package/dist/commands/publish/node.d.ts +4 -0
- package/dist/commands/publish/node.js +231 -0
- package/dist/commands/publish/workflow.d.ts +4 -0
- package/dist/commands/publish/workflow.js +165 -0
- package/dist/commands/search/docs.d.ts +17 -0
- package/dist/commands/search/docs.js +179 -0
- package/dist/commands/search/index.d.ts +1 -0
- package/dist/commands/search/index.js +5 -0
- package/dist/commands/search/indexer.d.ts +10 -0
- package/dist/commands/search/indexer.js +265 -0
- package/dist/commands/search/nodes.d.ts +4 -0
- package/dist/commands/search/nodes.js +101 -0
- package/dist/commands/search/workflow.d.ts +4 -0
- package/dist/commands/search/workflow.js +100 -0
- package/dist/commands/trace/index.d.ts +1 -0
- package/dist/commands/trace/index.js +26 -0
- package/dist/commands/trace/startStudio.d.ts +8 -0
- package/dist/commands/trace/startStudio.js +116 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +186 -0
- package/dist/services/commander.d.ts +9 -0
- package/dist/services/commander.js +20 -0
- package/dist/services/constants.d.ts +1 -0
- package/dist/services/constants.js +3 -0
- package/dist/services/local-token-manager.d.ts +14 -0
- package/dist/services/local-token-manager.js +99 -0
- package/dist/services/non-interactive.d.ts +5 -0
- package/dist/services/non-interactive.js +30 -0
- package/dist/services/package-manager.d.ts +35 -0
- package/dist/services/package-manager.js +111 -0
- package/dist/services/posthog.d.ts +31 -0
- package/dist/services/posthog.js +159 -0
- package/dist/services/registry-manager.d.ts +9 -0
- package/dist/services/registry-manager.js +26 -0
- package/dist/services/runtime-detector.d.ts +23 -0
- package/dist/services/runtime-detector.js +181 -0
- package/dist/services/runtime-setup.d.ts +36 -0
- package/dist/services/runtime-setup.js +250 -0
- package/dist/services/utils.d.ts +2 -0
- package/dist/services/utils.js +29 -0
- package/dist/services/workflow-loader.d.ts +30 -0
- package/dist/services/workflow-loader.js +46 -0
- package/dist/studio-dist/assets/charts-Dso0hPUR.js +68 -0
- package/dist/studio-dist/assets/graph-CsV2nWGn.js +23 -0
- package/dist/studio-dist/assets/icons-zP8LLgPh.js +311 -0
- package/dist/studio-dist/assets/index-CLyEkXMx.css +1 -0
- package/dist/studio-dist/assets/index-CNXFX_ar.js +27 -0
- package/dist/studio-dist/assets/react-vendor--Eh9ivFN.js +17 -0
- package/dist/studio-dist/assets/tanstack-query-CiM1U6F5.js +1 -0
- package/dist/studio-dist/assets/tanstack-router-Btjy0MKq.js +25 -0
- package/dist/studio-dist/assets/tanstack-table-DhwRvuH2.js +22 -0
- package/dist/studio-dist/favicon.svg +5 -0
- package/dist/studio-dist/index.html +21 -0
- package/package.json +75 -0
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
import child_process from "node:child_process";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import util from "node:util";
|
|
5
|
+
import * as p from "@clack/prompts";
|
|
6
|
+
import figlet from "figlet";
|
|
7
|
+
import fsExtra from "fs-extra";
|
|
8
|
+
import color from "picocolors";
|
|
9
|
+
import { isNonInteractive, resolveOrThrow } from "../../services/non-interactive.js";
|
|
10
|
+
import { manager as pm } from "../../services/package-manager.js";
|
|
11
|
+
import { csharp_csproj_file, csharp_dockerfile, csharp_node_file, function_first_node_file, go_dockerfile, go_mod_file, go_node_file, java_dockerfile, java_node_file, java_pom_file, php_composer_file, php_dockerfile, php_node_file, python3_file, ruby_dockerfile, ruby_gemfile, ruby_node_file, rust_cargo_file, rust_dockerfile, rust_node_file, } from "./utils/Examples.js";
|
|
12
|
+
const exec = util.promisify(child_process.exec);
|
|
13
|
+
const HOME_DIR = `${os.homedir()}/.blok`;
|
|
14
|
+
function toPascalCase(name) {
|
|
15
|
+
return name
|
|
16
|
+
.split(/[-_]/)
|
|
17
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
18
|
+
.join("");
|
|
19
|
+
}
|
|
20
|
+
const GITHUB_REPO_LOCAL = `${HOME_DIR}/blok`;
|
|
21
|
+
export async function createNode(opts, currentPath = false) {
|
|
22
|
+
const availableManagers = await pm.getAvailableManagers();
|
|
23
|
+
let manager = await pm.getManager();
|
|
24
|
+
const nonInteractive = isNonInteractive();
|
|
25
|
+
const isDefault = opts.name !== undefined;
|
|
26
|
+
const skipPrompts = isDefault || nonInteractive;
|
|
27
|
+
let nodeName = opts.name ? opts.name : "";
|
|
28
|
+
let nodeType = opts.nodeType || "";
|
|
29
|
+
let template = opts.template || "";
|
|
30
|
+
let nodeStyle = opts.style || "";
|
|
31
|
+
let node_runtime = opts.runtime || "";
|
|
32
|
+
let selectedManager = opts.packageManager || "npm";
|
|
33
|
+
if (!skipPrompts) {
|
|
34
|
+
console.log(figlet.textSync("Blok CLI".toUpperCase(), {
|
|
35
|
+
font: "Digital",
|
|
36
|
+
horizontalLayout: "default",
|
|
37
|
+
verticalLayout: "default",
|
|
38
|
+
width: 100,
|
|
39
|
+
whitespaceBreak: true,
|
|
40
|
+
}));
|
|
41
|
+
console.log("");
|
|
42
|
+
const resolveNodeName = async () => {
|
|
43
|
+
if (nodeName !== "") {
|
|
44
|
+
return nodeName;
|
|
45
|
+
}
|
|
46
|
+
return (await p.text({
|
|
47
|
+
message: "Please provide a name for the node",
|
|
48
|
+
placeholder: "node-name",
|
|
49
|
+
defaultValue: "",
|
|
50
|
+
}));
|
|
51
|
+
};
|
|
52
|
+
const resolveSelectedManager = async () => {
|
|
53
|
+
if (opts.packageManager) {
|
|
54
|
+
return opts.packageManager;
|
|
55
|
+
}
|
|
56
|
+
if (availableManagers.length === 1) {
|
|
57
|
+
return availableManagers[0];
|
|
58
|
+
}
|
|
59
|
+
return (await p.select({
|
|
60
|
+
message: "Select the package manager",
|
|
61
|
+
options: availableManagers.map((manager) => ({
|
|
62
|
+
label: manager,
|
|
63
|
+
value: manager,
|
|
64
|
+
})),
|
|
65
|
+
}));
|
|
66
|
+
};
|
|
67
|
+
p.intro(color.inverse(" Creating a new Node "));
|
|
68
|
+
const blokctlNode = await p.group({
|
|
69
|
+
nodeName: () => resolveNodeName(),
|
|
70
|
+
selectedManager: () => resolveSelectedManager(),
|
|
71
|
+
nodeRuntime: () => opts.runtime
|
|
72
|
+
? Promise.resolve(opts.runtime)
|
|
73
|
+
: p.select({
|
|
74
|
+
message: "Select the blok runtime",
|
|
75
|
+
options: [
|
|
76
|
+
{ label: "TypeScript/Node.js", value: "typescript", hint: "recommended" },
|
|
77
|
+
{ label: "Python 3", value: "python3", hint: "Production - gRPC" },
|
|
78
|
+
{ label: "Go", value: "go", hint: "Production - Docker" },
|
|
79
|
+
{ label: "Java", value: "java", hint: "Production - Docker" },
|
|
80
|
+
{ label: "Rust", value: "rust", hint: "Production - Docker" },
|
|
81
|
+
{ label: "C# / .NET", value: "csharp", hint: "Production - Docker" },
|
|
82
|
+
{ label: "PHP", value: "php", hint: "Production - Docker" },
|
|
83
|
+
{ label: "Ruby", value: "ruby", hint: "Production - Docker" },
|
|
84
|
+
],
|
|
85
|
+
}),
|
|
86
|
+
}, {
|
|
87
|
+
onCancel: () => {
|
|
88
|
+
p.cancel("Operation canceled.");
|
|
89
|
+
process.exit(0);
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
nodeName = blokctlNode.nodeName;
|
|
93
|
+
node_runtime = blokctlNode.nodeRuntime;
|
|
94
|
+
selectedManager = blokctlNode.selectedManager;
|
|
95
|
+
if (node_runtime === "python3") {
|
|
96
|
+
console.log(color.yellow("⚠️ Python3 runtime is currently in Alpha and is limited to MacOS and Linux. Please use Typescript for production."));
|
|
97
|
+
}
|
|
98
|
+
if (node_runtime === "typescript") {
|
|
99
|
+
const blokctlNodeExtension = await p.group({
|
|
100
|
+
nodeType: () => opts.nodeType
|
|
101
|
+
? Promise.resolve(opts.nodeType)
|
|
102
|
+
: p.select({
|
|
103
|
+
message: "Select the blok type",
|
|
104
|
+
options: [
|
|
105
|
+
{ label: "Module", value: "module", hint: "recommended" },
|
|
106
|
+
{ label: "Class", value: "class" },
|
|
107
|
+
],
|
|
108
|
+
}),
|
|
109
|
+
nodeStyle: () => opts.style
|
|
110
|
+
? Promise.resolve(opts.style)
|
|
111
|
+
: p.select({
|
|
112
|
+
message: "Select the node style",
|
|
113
|
+
options: [
|
|
114
|
+
{ label: "Function-First (defineNode)", value: "function", hint: "recommended" },
|
|
115
|
+
{ label: "Class-Based (extends BlokService)", value: "class" },
|
|
116
|
+
],
|
|
117
|
+
}),
|
|
118
|
+
template: () => opts.template
|
|
119
|
+
? Promise.resolve(opts.template === "standard" ? "class" : opts.template)
|
|
120
|
+
: p.select({
|
|
121
|
+
message: "Select the template",
|
|
122
|
+
options: [
|
|
123
|
+
{ label: "Standard", value: "class", hint: "recommended" },
|
|
124
|
+
{ label: "UI - EJS + ReactJS + TailwindCSS", value: "ui" },
|
|
125
|
+
],
|
|
126
|
+
}),
|
|
127
|
+
}, {
|
|
128
|
+
onCancel: () => {
|
|
129
|
+
p.cancel("Operation canceled.");
|
|
130
|
+
process.exit(0);
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
nodeType = blokctlNodeExtension.nodeType;
|
|
134
|
+
nodeStyle = blokctlNodeExtension.nodeStyle;
|
|
135
|
+
template = blokctlNodeExtension.template;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
else if (nonInteractive) {
|
|
139
|
+
nodeName = resolveOrThrow("name", opts.name);
|
|
140
|
+
node_runtime = opts.runtime || "typescript";
|
|
141
|
+
nodeStyle = opts.style || "function";
|
|
142
|
+
if (node_runtime === "typescript") {
|
|
143
|
+
nodeType = opts.nodeType || "module";
|
|
144
|
+
template = opts.template === "standard" ? "class" : opts.template || "class";
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const s = p.spinner();
|
|
148
|
+
if (!skipPrompts)
|
|
149
|
+
s.start(`Creating the ${node_runtime} node...`);
|
|
150
|
+
try {
|
|
151
|
+
const mainDirExists = fsExtra.existsSync(GITHUB_REPO_LOCAL);
|
|
152
|
+
if (!mainDirExists)
|
|
153
|
+
throw new Error("The blok repository was not found. Please run 'npx blokctl@latest create project' to clone the repository.");
|
|
154
|
+
if (node_runtime === "typescript") {
|
|
155
|
+
let dirPath = process.cwd();
|
|
156
|
+
if (!currentPath) {
|
|
157
|
+
const currentDir = `${process.cwd()}/src`;
|
|
158
|
+
const nodeProjectDirExists = fsExtra.existsSync(currentDir);
|
|
159
|
+
if (!nodeProjectDirExists)
|
|
160
|
+
throw new Error("ops1");
|
|
161
|
+
const currentNodesDir = `${currentDir}/nodes`;
|
|
162
|
+
if (!skipPrompts) {
|
|
163
|
+
fsExtra.ensureDirSync(currentNodesDir);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
const nodeDirExists = fsExtra.existsSync(currentNodesDir);
|
|
167
|
+
if (!nodeDirExists)
|
|
168
|
+
throw new Error("ops1");
|
|
169
|
+
}
|
|
170
|
+
dirPath = path.join(currentNodesDir, nodeName);
|
|
171
|
+
}
|
|
172
|
+
if (!skipPrompts)
|
|
173
|
+
s.message("Copying project files...");
|
|
174
|
+
if (!currentPath) {
|
|
175
|
+
const nodeDirExists = fsExtra.existsSync(dirPath);
|
|
176
|
+
if (nodeDirExists)
|
|
177
|
+
throw new Error("ops2");
|
|
178
|
+
}
|
|
179
|
+
if (nodeType === "module") {
|
|
180
|
+
if (nodeStyle === "function") {
|
|
181
|
+
fsExtra.copySync(`${GITHUB_REPO_LOCAL}/templates/node-function`, dirPath);
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
if (template === "class") {
|
|
185
|
+
fsExtra.copySync(`${GITHUB_REPO_LOCAL}/templates/node`, dirPath);
|
|
186
|
+
}
|
|
187
|
+
if (template === "ui") {
|
|
188
|
+
fsExtra.copySync(`${GITHUB_REPO_LOCAL}/templates/node-ui`, dirPath);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const packageJson = `${dirPath}/package.json`;
|
|
192
|
+
const packageJsonContent = JSON.parse(fsExtra.readFileSync(packageJson, "utf8"));
|
|
193
|
+
packageJsonContent.name = nodeName;
|
|
194
|
+
packageJsonContent.version = "1.0.0";
|
|
195
|
+
packageJsonContent.author = "";
|
|
196
|
+
fsExtra.writeFileSync(packageJson, JSON.stringify(packageJsonContent, null, 2));
|
|
197
|
+
if (nodeStyle === "function") {
|
|
198
|
+
const indexPath = `${dirPath}/index.ts`;
|
|
199
|
+
let indexContent = fsExtra.readFileSync(indexPath, "utf8");
|
|
200
|
+
indexContent = indexContent.replace(/node-name/g, nodeName);
|
|
201
|
+
fsExtra.writeFileSync(indexPath, indexContent);
|
|
202
|
+
}
|
|
203
|
+
manager = await pm.getManager(selectedManager);
|
|
204
|
+
s.message("Installing packages...");
|
|
205
|
+
await exec(manager.INSTALL, { cwd: dirPath });
|
|
206
|
+
s.message("Building the project...");
|
|
207
|
+
await exec(manager.BUILD, { cwd: dirPath });
|
|
208
|
+
}
|
|
209
|
+
if (nodeType === "class") {
|
|
210
|
+
fsExtra.ensureDirSync(dirPath);
|
|
211
|
+
if (nodeStyle === "function") {
|
|
212
|
+
const functionNodeContent = function_first_node_file.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
213
|
+
fsExtra.writeFileSync(`${dirPath}/index.ts`, functionNodeContent);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
if (template === "class") {
|
|
217
|
+
fsExtra.copyFileSync(`${GITHUB_REPO_LOCAL}/templates/node/index.ts`, `${dirPath}/index.ts`);
|
|
218
|
+
}
|
|
219
|
+
if (template === "ui") {
|
|
220
|
+
fsExtra.ensureDirSync(`${dirPath}/app`);
|
|
221
|
+
fsExtra.copySync(`${GITHUB_REPO_LOCAL}/templates/node-ui/app`, `${dirPath}/app`);
|
|
222
|
+
fsExtra.copyFileSync(`${GITHUB_REPO_LOCAL}/templates/node-ui/index.ts`, `${dirPath}/index.ts`);
|
|
223
|
+
fsExtra.copyFileSync(`${GITHUB_REPO_LOCAL}/templates/node-ui/inputSchema.ts`, `${dirPath}/inputSchema.ts`);
|
|
224
|
+
fsExtra.copyFileSync(`${GITHUB_REPO_LOCAL}/templates/node-ui/index.html`, `${dirPath}/index.html`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (node_runtime === "python3") {
|
|
230
|
+
let dirPath = process.cwd();
|
|
231
|
+
if (!currentPath) {
|
|
232
|
+
const currentDir = `${process.cwd()}/runtimes/python3`;
|
|
233
|
+
const nodeProjectDirExists = fsExtra.existsSync(currentDir);
|
|
234
|
+
if (!nodeProjectDirExists)
|
|
235
|
+
throw new Error("ops3");
|
|
236
|
+
const currentNodesDir = `${currentDir}/nodes`;
|
|
237
|
+
if (!skipPrompts) {
|
|
238
|
+
fsExtra.ensureDirSync(currentNodesDir);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
const nodeDirExists = fsExtra.existsSync(currentNodesDir);
|
|
242
|
+
if (!nodeDirExists)
|
|
243
|
+
throw new Error("ops3");
|
|
244
|
+
}
|
|
245
|
+
dirPath = path.join(currentNodesDir, nodeName);
|
|
246
|
+
}
|
|
247
|
+
if (!skipPrompts)
|
|
248
|
+
s.message("Copying project files...");
|
|
249
|
+
if (!currentPath) {
|
|
250
|
+
const nodeDirExists = fsExtra.existsSync(dirPath);
|
|
251
|
+
if (nodeDirExists)
|
|
252
|
+
throw new Error("ops2");
|
|
253
|
+
}
|
|
254
|
+
fsExtra.ensureDirSync(dirPath);
|
|
255
|
+
fsExtra.writeFileSync(`${dirPath}/node.py`, python3_file);
|
|
256
|
+
fsExtra.writeFileSync(`${dirPath}/__init__.py`, "");
|
|
257
|
+
}
|
|
258
|
+
if (node_runtime === "go") {
|
|
259
|
+
let dirPath = process.cwd();
|
|
260
|
+
if (!currentPath) {
|
|
261
|
+
const currentDir = `${process.cwd()}/runtimes/go`;
|
|
262
|
+
const nodeProjectDirExists = fsExtra.existsSync(currentDir);
|
|
263
|
+
if (!nodeProjectDirExists) {
|
|
264
|
+
fsExtra.ensureDirSync(currentDir);
|
|
265
|
+
}
|
|
266
|
+
const currentNodesDir = `${currentDir}/nodes`;
|
|
267
|
+
if (!skipPrompts) {
|
|
268
|
+
fsExtra.ensureDirSync(currentNodesDir);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
const nodeDirExists = fsExtra.existsSync(currentNodesDir);
|
|
272
|
+
if (!nodeDirExists) {
|
|
273
|
+
fsExtra.ensureDirSync(currentNodesDir);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
dirPath = path.join(currentNodesDir, nodeName);
|
|
277
|
+
}
|
|
278
|
+
if (!skipPrompts)
|
|
279
|
+
s.message("Creating Go node files...");
|
|
280
|
+
if (!currentPath) {
|
|
281
|
+
const nodeDirExists = fsExtra.existsSync(dirPath);
|
|
282
|
+
if (nodeDirExists)
|
|
283
|
+
throw new Error("ops2");
|
|
284
|
+
}
|
|
285
|
+
fsExtra.ensureDirSync(dirPath);
|
|
286
|
+
const goNodeContent = go_node_file.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
287
|
+
const goModContent = go_mod_file.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
288
|
+
const goDockerContent = go_dockerfile.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
289
|
+
fsExtra.writeFileSync(`${dirPath}/main.go`, goNodeContent);
|
|
290
|
+
fsExtra.writeFileSync(`${dirPath}/go.mod`, goModContent);
|
|
291
|
+
fsExtra.writeFileSync(`${dirPath}/go.sum`, "");
|
|
292
|
+
fsExtra.writeFileSync(`${dirPath}/Dockerfile`, goDockerContent);
|
|
293
|
+
const readmeContent = `# ${nodeName}\n\nGo-based Blok node.\n\n## Build\n\n\`\`\`bash\ndocker build -t blok-${nodeName}:latest .\n\`\`\`\n\n## Run\n\n\`\`\`bash\ndocker run -p 8080:8080 blok-${nodeName}:latest\n\`\`\`\n`;
|
|
294
|
+
fsExtra.writeFileSync(`${dirPath}/README.md`, readmeContent);
|
|
295
|
+
}
|
|
296
|
+
if (node_runtime === "java") {
|
|
297
|
+
let dirPath = process.cwd();
|
|
298
|
+
if (!currentPath) {
|
|
299
|
+
const currentDir = `${process.cwd()}/runtimes/java`;
|
|
300
|
+
const nodeProjectDirExists = fsExtra.existsSync(currentDir);
|
|
301
|
+
if (!nodeProjectDirExists) {
|
|
302
|
+
fsExtra.ensureDirSync(currentDir);
|
|
303
|
+
}
|
|
304
|
+
const currentNodesDir = `${currentDir}/nodes`;
|
|
305
|
+
if (!skipPrompts) {
|
|
306
|
+
fsExtra.ensureDirSync(currentNodesDir);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
const nodeDirExists = fsExtra.existsSync(currentNodesDir);
|
|
310
|
+
if (!nodeDirExists) {
|
|
311
|
+
fsExtra.ensureDirSync(currentNodesDir);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
dirPath = path.join(currentNodesDir, nodeName);
|
|
315
|
+
}
|
|
316
|
+
if (!skipPrompts)
|
|
317
|
+
s.message("Creating Java node files...");
|
|
318
|
+
if (!currentPath) {
|
|
319
|
+
const nodeDirExists = fsExtra.existsSync(dirPath);
|
|
320
|
+
if (nodeDirExists)
|
|
321
|
+
throw new Error("ops2");
|
|
322
|
+
}
|
|
323
|
+
fsExtra.ensureDirSync(dirPath);
|
|
324
|
+
const srcDir = `${dirPath}/src/main/java/com/blok/nodes`;
|
|
325
|
+
fsExtra.ensureDirSync(srcDir);
|
|
326
|
+
const javaNodeContent = java_node_file.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
327
|
+
const javaPomContent = java_pom_file.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
328
|
+
const javaDockerContent = java_dockerfile.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
329
|
+
fsExtra.writeFileSync(`${srcDir}/HelloWorldNode.java`, javaNodeContent);
|
|
330
|
+
fsExtra.writeFileSync(`${dirPath}/pom.xml`, javaPomContent);
|
|
331
|
+
fsExtra.writeFileSync(`${dirPath}/Dockerfile`, javaDockerContent);
|
|
332
|
+
const readmeContent = `# ${nodeName}\n\nJava-based Blok node.\n\n## Build\n\n\`\`\`bash\ndocker build -t blok-${nodeName}:latest .\n\`\`\`\n\n## Run\n\n\`\`\`bash\ndocker run -p 8080:8080 blok-${nodeName}:latest\n\`\`\`\n`;
|
|
333
|
+
fsExtra.writeFileSync(`${dirPath}/README.md`, readmeContent);
|
|
334
|
+
}
|
|
335
|
+
if (node_runtime === "rust") {
|
|
336
|
+
let dirPath = process.cwd();
|
|
337
|
+
if (!currentPath) {
|
|
338
|
+
const currentDir = `${process.cwd()}/runtimes/rust`;
|
|
339
|
+
const nodeProjectDirExists = fsExtra.existsSync(currentDir);
|
|
340
|
+
if (!nodeProjectDirExists) {
|
|
341
|
+
fsExtra.ensureDirSync(currentDir);
|
|
342
|
+
}
|
|
343
|
+
const currentNodesDir = `${currentDir}/nodes`;
|
|
344
|
+
if (!skipPrompts) {
|
|
345
|
+
fsExtra.ensureDirSync(currentNodesDir);
|
|
346
|
+
}
|
|
347
|
+
else {
|
|
348
|
+
const nodeDirExists = fsExtra.existsSync(currentNodesDir);
|
|
349
|
+
if (!nodeDirExists) {
|
|
350
|
+
fsExtra.ensureDirSync(currentNodesDir);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
dirPath = path.join(currentNodesDir, nodeName);
|
|
354
|
+
}
|
|
355
|
+
if (!skipPrompts)
|
|
356
|
+
s.message("Creating Rust node files...");
|
|
357
|
+
if (!currentPath) {
|
|
358
|
+
const nodeDirExists = fsExtra.existsSync(dirPath);
|
|
359
|
+
if (nodeDirExists)
|
|
360
|
+
throw new Error("ops2");
|
|
361
|
+
}
|
|
362
|
+
fsExtra.ensureDirSync(dirPath);
|
|
363
|
+
const srcDir = `${dirPath}/src`;
|
|
364
|
+
fsExtra.ensureDirSync(srcDir);
|
|
365
|
+
const pascalName = toPascalCase(nodeName);
|
|
366
|
+
const rustNodeContent = rust_node_file
|
|
367
|
+
.replace(/\{\{NODE_NAME\}\}/g, nodeName)
|
|
368
|
+
.replace(/\{\{NODE_NAME_PASCAL\}\}/g, pascalName);
|
|
369
|
+
const rustCargoContent = rust_cargo_file.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
370
|
+
const rustDockerContent = rust_dockerfile.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
371
|
+
fsExtra.writeFileSync(`${srcDir}/main.rs`, rustNodeContent);
|
|
372
|
+
fsExtra.writeFileSync(`${dirPath}/Cargo.toml`, rustCargoContent);
|
|
373
|
+
fsExtra.writeFileSync(`${dirPath}/Dockerfile`, rustDockerContent);
|
|
374
|
+
const readmeContent = `# ${nodeName}\n\nRust-based Blok node.\n\n## Build\n\n\`\`\`bash\ndocker build -t blok-${nodeName}:latest .\n\`\`\`\n\n## Run\n\n\`\`\`bash\ndocker run -p 8080:8080 blok-${nodeName}:latest\n\`\`\`\n`;
|
|
375
|
+
fsExtra.writeFileSync(`${dirPath}/README.md`, readmeContent);
|
|
376
|
+
}
|
|
377
|
+
if (node_runtime === "csharp") {
|
|
378
|
+
let dirPath = process.cwd();
|
|
379
|
+
if (!currentPath) {
|
|
380
|
+
const currentDir = `${process.cwd()}/runtimes/csharp`;
|
|
381
|
+
if (!fsExtra.existsSync(currentDir)) {
|
|
382
|
+
fsExtra.ensureDirSync(currentDir);
|
|
383
|
+
}
|
|
384
|
+
const currentNodesDir = `${currentDir}/nodes`;
|
|
385
|
+
fsExtra.ensureDirSync(currentNodesDir);
|
|
386
|
+
dirPath = path.join(currentNodesDir, nodeName);
|
|
387
|
+
}
|
|
388
|
+
if (!skipPrompts)
|
|
389
|
+
s.message("Creating C# node files...");
|
|
390
|
+
if (!currentPath) {
|
|
391
|
+
if (fsExtra.existsSync(dirPath))
|
|
392
|
+
throw new Error("ops2");
|
|
393
|
+
}
|
|
394
|
+
fsExtra.ensureDirSync(dirPath);
|
|
395
|
+
const srcDir = `${dirPath}/src/Nodes`;
|
|
396
|
+
fsExtra.ensureDirSync(srcDir);
|
|
397
|
+
const pascalName = toPascalCase(nodeName);
|
|
398
|
+
const csNodeContent = csharp_node_file.replace(/\{\{NODE_NAME_PASCAL\}\}/g, pascalName);
|
|
399
|
+
const csprojContent = csharp_csproj_file.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
400
|
+
const csDockerContent = csharp_dockerfile.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
401
|
+
fsExtra.writeFileSync(`${srcDir}/${pascalName}Node.cs`, csNodeContent);
|
|
402
|
+
fsExtra.writeFileSync(`${dirPath}/BlokRuntime.csproj`, csprojContent);
|
|
403
|
+
fsExtra.writeFileSync(`${dirPath}/Dockerfile`, csDockerContent);
|
|
404
|
+
const readmeContent = `# ${nodeName}\n\nC#/.NET-based Blok node.\n\n## Build\n\n\`\`\`bash\ndocker build -t blok-${nodeName}:latest .\n\`\`\`\n\n## Run\n\n\`\`\`bash\ndocker run -p 8080:8080 blok-${nodeName}:latest\n\`\`\`\n`;
|
|
405
|
+
fsExtra.writeFileSync(`${dirPath}/README.md`, readmeContent);
|
|
406
|
+
}
|
|
407
|
+
if (node_runtime === "php") {
|
|
408
|
+
let dirPath = process.cwd();
|
|
409
|
+
if (!currentPath) {
|
|
410
|
+
const currentDir = `${process.cwd()}/runtimes/php`;
|
|
411
|
+
if (!fsExtra.existsSync(currentDir)) {
|
|
412
|
+
fsExtra.ensureDirSync(currentDir);
|
|
413
|
+
}
|
|
414
|
+
const currentNodesDir = `${currentDir}/nodes`;
|
|
415
|
+
fsExtra.ensureDirSync(currentNodesDir);
|
|
416
|
+
dirPath = path.join(currentNodesDir, nodeName);
|
|
417
|
+
}
|
|
418
|
+
if (!skipPrompts)
|
|
419
|
+
s.message("Creating PHP node files...");
|
|
420
|
+
if (!currentPath) {
|
|
421
|
+
if (fsExtra.existsSync(dirPath))
|
|
422
|
+
throw new Error("ops2");
|
|
423
|
+
}
|
|
424
|
+
fsExtra.ensureDirSync(dirPath);
|
|
425
|
+
const srcDir = `${dirPath}/src/Nodes`;
|
|
426
|
+
fsExtra.ensureDirSync(srcDir);
|
|
427
|
+
const pascalName = toPascalCase(nodeName);
|
|
428
|
+
const phpNodeContent = php_node_file
|
|
429
|
+
.replace(/\{\{NODE_NAME\}\}/g, nodeName)
|
|
430
|
+
.replace(/\{\{NODE_NAME_PASCAL\}\}/g, pascalName);
|
|
431
|
+
const phpComposerContent = php_composer_file.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
432
|
+
const phpDockerContent = php_dockerfile.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
433
|
+
fsExtra.writeFileSync(`${srcDir}/${pascalName}Node.php`, phpNodeContent);
|
|
434
|
+
fsExtra.writeFileSync(`${dirPath}/composer.json`, phpComposerContent);
|
|
435
|
+
fsExtra.writeFileSync(`${dirPath}/Dockerfile`, phpDockerContent);
|
|
436
|
+
const readmeContent = `# ${nodeName}\n\nPHP-based Blok node.\n\n## Build\n\n\`\`\`bash\ndocker build -t blok-${nodeName}:latest .\n\`\`\`\n\n## Run\n\n\`\`\`bash\ndocker run -p 8080:8080 blok-${nodeName}:latest\n\`\`\`\n`;
|
|
437
|
+
fsExtra.writeFileSync(`${dirPath}/README.md`, readmeContent);
|
|
438
|
+
}
|
|
439
|
+
if (node_runtime === "ruby") {
|
|
440
|
+
let dirPath = process.cwd();
|
|
441
|
+
if (!currentPath) {
|
|
442
|
+
const currentDir = `${process.cwd()}/runtimes/ruby`;
|
|
443
|
+
if (!fsExtra.existsSync(currentDir)) {
|
|
444
|
+
fsExtra.ensureDirSync(currentDir);
|
|
445
|
+
}
|
|
446
|
+
const currentNodesDir = `${currentDir}/nodes`;
|
|
447
|
+
fsExtra.ensureDirSync(currentNodesDir);
|
|
448
|
+
dirPath = path.join(currentNodesDir, nodeName);
|
|
449
|
+
}
|
|
450
|
+
if (!skipPrompts)
|
|
451
|
+
s.message("Creating Ruby node files...");
|
|
452
|
+
if (!currentPath) {
|
|
453
|
+
if (fsExtra.existsSync(dirPath))
|
|
454
|
+
throw new Error("ops2");
|
|
455
|
+
}
|
|
456
|
+
fsExtra.ensureDirSync(dirPath);
|
|
457
|
+
const libDir = `${dirPath}/lib/nodes`;
|
|
458
|
+
fsExtra.ensureDirSync(libDir);
|
|
459
|
+
const pascalName = toPascalCase(nodeName);
|
|
460
|
+
const rubyNodeContent = ruby_node_file
|
|
461
|
+
.replace(/\{\{NODE_NAME\}\}/g, nodeName)
|
|
462
|
+
.replace(/\{\{NODE_NAME_PASCAL\}\}/g, pascalName);
|
|
463
|
+
const rubyGemContent = ruby_gemfile.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
464
|
+
const rubyDockerContent = ruby_dockerfile.replace(/\{\{NODE_NAME\}\}/g, nodeName);
|
|
465
|
+
fsExtra.writeFileSync(`${libDir}/${nodeName.replace(/-/g, "_")}.rb`, rubyNodeContent);
|
|
466
|
+
fsExtra.writeFileSync(`${dirPath}/Gemfile`, rubyGemContent);
|
|
467
|
+
fsExtra.writeFileSync(`${dirPath}/Dockerfile`, rubyDockerContent);
|
|
468
|
+
const readmeContent = `# ${nodeName}\n\nRuby-based Blok node.\n\n## Build\n\n\`\`\`bash\ndocker build -t blok-${nodeName}:latest .\n\`\`\`\n\n## Run\n\n\`\`\`bash\ndocker run -p 8080:8080 blok-${nodeName}:latest\n\`\`\`\n`;
|
|
469
|
+
fsExtra.writeFileSync(`${dirPath}/README.md`, readmeContent);
|
|
470
|
+
}
|
|
471
|
+
if (!skipPrompts)
|
|
472
|
+
s.stop(`Node "${nodeName}" created successfully.`);
|
|
473
|
+
if (!currentPath && node_runtime === "typescript") {
|
|
474
|
+
console.log(`\nNavigate to the node directory by running: cd src/nodes/${nodeName}`);
|
|
475
|
+
console.log(`${currentPath ? "\n" : ""}Run the command "npm run build" or "npm run build:dev" to build the project.`);
|
|
476
|
+
if (nodeStyle === "function") {
|
|
477
|
+
console.log(color.cyan("\n✨ Function-First Node Created!"));
|
|
478
|
+
console.log(" • Type-safe with Zod validation");
|
|
479
|
+
console.log(" • 60% less boilerplate than class-based");
|
|
480
|
+
console.log(" • AI-friendly for code generation");
|
|
481
|
+
console.log("\n📖 Learn more: https://blok.build/docs/nodes/function-first");
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (!currentPath && node_runtime === "python3") {
|
|
485
|
+
console.log(`\nNavigate to the node directory by running: cd runtimes/python3/nodes/${nodeName}`);
|
|
486
|
+
}
|
|
487
|
+
if (!currentPath && node_runtime === "go") {
|
|
488
|
+
console.log(`\nNavigate to the node directory by running: cd runtimes/go/nodes/${nodeName}`);
|
|
489
|
+
console.log(`\nBuild the Docker image: docker build -t blok-${nodeName}:latest .`);
|
|
490
|
+
console.log(`Run the container: docker run -p 8080:8080 blok-${nodeName}:latest`);
|
|
491
|
+
}
|
|
492
|
+
if (!currentPath && node_runtime === "java") {
|
|
493
|
+
console.log(`\nNavigate to the node directory by running: cd runtimes/java/nodes/${nodeName}`);
|
|
494
|
+
console.log(`\nBuild the Docker image: docker build -t blok-${nodeName}:latest .`);
|
|
495
|
+
console.log(`Run the container: docker run -p 8080:8080 blok-${nodeName}:latest`);
|
|
496
|
+
}
|
|
497
|
+
if (!currentPath && node_runtime === "rust") {
|
|
498
|
+
console.log(`\nNavigate to the node directory by running: cd runtimes/rust/nodes/${nodeName}`);
|
|
499
|
+
console.log(`\nBuild the Docker image: docker build -t blok-${nodeName}:latest .`);
|
|
500
|
+
console.log(`Run the container: docker run -p 8080:8080 blok-${nodeName}:latest`);
|
|
501
|
+
}
|
|
502
|
+
if (!currentPath && node_runtime === "csharp") {
|
|
503
|
+
console.log(`\nNavigate to the node directory by running: cd runtimes/csharp/nodes/${nodeName}`);
|
|
504
|
+
console.log(`\nBuild the Docker image: docker build -t blok-${nodeName}:latest .`);
|
|
505
|
+
console.log(`Run the container: docker run -p 8080:8080 blok-${nodeName}:latest`);
|
|
506
|
+
}
|
|
507
|
+
if (!currentPath && node_runtime === "php") {
|
|
508
|
+
console.log(`\nNavigate to the node directory by running: cd runtimes/php/nodes/${nodeName}`);
|
|
509
|
+
console.log(`\nBuild the Docker image: docker build -t blok-${nodeName}:latest .`);
|
|
510
|
+
console.log(`Run the container: docker run -p 8080:8080 blok-${nodeName}:latest`);
|
|
511
|
+
}
|
|
512
|
+
if (!currentPath && node_runtime === "ruby") {
|
|
513
|
+
console.log(`\nNavigate to the node directory by running: cd runtimes/ruby/nodes/${nodeName}`);
|
|
514
|
+
console.log(`\nBuild the Docker image: docker build -t blok-${nodeName}:latest .`);
|
|
515
|
+
console.log(`Run the container: docker run -p 8080:8080 blok-${nodeName}:latest`);
|
|
516
|
+
}
|
|
517
|
+
console.log("\nFor more documentation, visit https://blok.build/docs/d/core-concepts/nodes");
|
|
518
|
+
}
|
|
519
|
+
catch (error) {
|
|
520
|
+
if (!skipPrompts)
|
|
521
|
+
s.stop("An error occurred");
|
|
522
|
+
const message = error.message;
|
|
523
|
+
if (message === "ops1") {
|
|
524
|
+
console.log("Oops! It seems like you haven't created a project yet... or have you? 🤔\n" +
|
|
525
|
+
"If you already did, you can navigate to it using: cd project-name\n" +
|
|
526
|
+
"Otherwise, you can create a new project with: npx blokctl@latest create project");
|
|
527
|
+
}
|
|
528
|
+
if (message === "ops2") {
|
|
529
|
+
console.log("The node you are trying to create already exists in the project.\n" +
|
|
530
|
+
"Please use a different name, or delete the existing node to create a new one.");
|
|
531
|
+
}
|
|
532
|
+
if (message === "ops3") {
|
|
533
|
+
console.log("Oops! It seems like you haven't created a project with python3 support yet... or have you? 🤔\n" +
|
|
534
|
+
"If you already did, you can navigate to it using: cd project-name\n" +
|
|
535
|
+
"Otherwise, you can create a new project with: npx blokctl@latest create project");
|
|
536
|
+
}
|
|
537
|
+
if (message !== "ops1" && message !== "ops2") {
|
|
538
|
+
console.log(error.message);
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
}
|