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,69 @@
1
+ import fs from "node:fs";
2
+ import * as p from "@clack/prompts";
3
+ import { program, trackCommandExecution } from "../../services/commander.js";
4
+ import { loadWorkflows } from "../../services/workflow-loader.js";
5
+ async function getNodeDependencyGraph() {
6
+ const { NodeDependencyGraph } = await import("@blok/runner");
7
+ return NodeDependencyGraph;
8
+ }
9
+ program
10
+ .command("graph")
11
+ .description("Visualize node dependencies across workflows")
12
+ .option("--format <format>", "Output format: ascii, mermaid, dot, json", "ascii")
13
+ .option("--workflow <name>", "Filter to a specific workflow")
14
+ .option("--node <name>", "Show dependencies for a specific node")
15
+ .option("--output <file>", "Write output to file instead of stdout")
16
+ .option("--direction <dir>", "Graph direction: TB, LR, BT, RL", "TB")
17
+ .option("-d, --directory [value]", "Project directory", process.cwd())
18
+ .action(async (options) => {
19
+ await trackCommandExecution({
20
+ command: "graph",
21
+ args: options,
22
+ execution: async () => {
23
+ const logger = p.spinner();
24
+ logger.start("Loading workflows...");
25
+ const workflows = await loadWorkflows(options.directory);
26
+ if (workflows.length === 0) {
27
+ logger.error("No workflow files found.");
28
+ p.log.warn("Make sure your project has workflow JSON files in the workflows/ directory.");
29
+ return;
30
+ }
31
+ logger.stop(`Found ${workflows.length} workflow(s).`);
32
+ const NodeDependencyGraph = await getNodeDependencyGraph();
33
+ const graph = new NodeDependencyGraph({
34
+ direction: options.direction || "TB",
35
+ filterWorkflow: options.workflow || "",
36
+ filterNode: options.node || "",
37
+ showWorkflowBoundaries: true,
38
+ showOrphanNodes: true,
39
+ });
40
+ for (const wf of workflows) {
41
+ graph.addWorkflow(wf.def);
42
+ }
43
+ let output;
44
+ const format = options.format;
45
+ switch (format) {
46
+ case "mermaid":
47
+ output = graph.toMermaid();
48
+ break;
49
+ case "dot":
50
+ output = graph.toDot();
51
+ break;
52
+ case "json":
53
+ output = graph.toJson();
54
+ break;
55
+ default:
56
+ output = graph.toAscii();
57
+ }
58
+ if (options.output) {
59
+ fs.writeFileSync(options.output, output, "utf-8");
60
+ p.log.success(`Graph written to ${options.output}`);
61
+ }
62
+ else {
63
+ console.log(output);
64
+ }
65
+ const stats = graph.getStats();
66
+ p.log.info(`Nodes: ${stats.totalNodes} | Edges: ${stats.totalEdges} | Shared: ${stats.sharedNodes} | Orphans: ${stats.orphanNodes}`);
67
+ },
68
+ });
69
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ import { program } from "../../services/commander.js";
2
+ import node from "./node.js";
3
+ import workflow from "./workflow.js";
4
+ program.command("install").description("Install commands").addCommand(node).addCommand(workflow);
@@ -0,0 +1,4 @@
1
+ import { Command, type OptionValues } from "../../services/commander.js";
2
+ export declare function install(opts: OptionValues): Promise<void>;
3
+ declare const _default: Command;
4
+ export default _default;
@@ -0,0 +1,136 @@
1
+ import child_process from "node:child_process";
2
+ import * as fs from "node:fs";
3
+ import path from "node:path";
4
+ import util from "node:util";
5
+ import * as p from "@clack/prompts";
6
+ import { Command, trackCommandExecution } from "../../services/commander.js";
7
+ import { tokenManager } from "../../services/local-token-manager.js";
8
+ import { isNonInteractive } from "../../services/non-interactive.js";
9
+ import { manager as pm } from "../../services/package-manager.js";
10
+ import { registryManager } from "../../services/registry-manager.js";
11
+ const discoveryNodeRuntime = async () => {
12
+ return "npm";
13
+ };
14
+ export async function install(opts) {
15
+ const token = tokenManager.getToken();
16
+ const npmrcFile = `${opts.directory}/.npmrc`;
17
+ const logger = p.spinner();
18
+ try {
19
+ if (!token)
20
+ throw new Error("Token is invalid.");
21
+ if (!opts.node)
22
+ throw new Error("Node name is required.");
23
+ const nodeFilePath = path.resolve(opts.directory, "./src/Nodes.ts");
24
+ if (!fs.existsSync(nodeFilePath)) {
25
+ throw new Error("Node.ts file does not exist in the specified directory.");
26
+ }
27
+ const packageJsonPath = path.resolve(opts.directory, "./package.json");
28
+ if (!fs.existsSync(packageJsonPath)) {
29
+ throw new Error("package.json file does not exist in the specified directory.");
30
+ }
31
+ const availableManagers = await pm.getAvailableManagers();
32
+ let manager = await pm.getManager();
33
+ logger.start("Installing node...");
34
+ const runtime = await discoveryNodeRuntime();
35
+ if (runtime === "npm" && availableManagers.length > 1) {
36
+ if (opts.packageManager) {
37
+ manager = await pm.getManager(opts.packageManager);
38
+ }
39
+ else if (isNonInteractive()) {
40
+ }
41
+ else {
42
+ logger.message("Multiple package managers detected. Please select one.");
43
+ const selectedManager = await p.select({
44
+ message: "Select the package manager",
45
+ options: availableManagers.map((manager) => ({
46
+ label: manager,
47
+ value: manager,
48
+ })),
49
+ });
50
+ manager = await pm.getManager(selectedManager);
51
+ }
52
+ }
53
+ const registry = await registryManager.getRegistryToken(token);
54
+ if (registry.error)
55
+ throw new Error("Failed to get registry token.");
56
+ const REGISTRY_URL = `https://${registry.url}`;
57
+ const npmrcContent = `@${registry.namespace}:registry=${REGISTRY_URL}\n//${registry.url}:_authToken=${registry.token}`;
58
+ fs.writeFileSync(npmrcFile, npmrcContent);
59
+ logger.message("Created .npmrc file for authentication.");
60
+ const nodeName = `@${registry.namespace}/${opts.node}`;
61
+ logger.message(`Installing node: ${opts.node}...`);
62
+ const exec = util.promisify(child_process.exec);
63
+ const { stdout, stderr } = await exec(manager.INSTALL_NODE({ node: nodeName, registry: REGISTRY_URL, npmrcDir: npmrcFile }), { cwd: opts.directory });
64
+ if (stdout)
65
+ p.log.info(stdout);
66
+ else if (stderr)
67
+ throw new Error(stderr);
68
+ updateNodeFile(nodeFilePath, {
69
+ importName: toPascalCase(opts.node),
70
+ importPath: nodeName,
71
+ });
72
+ logger.stop("Node installed successfully.");
73
+ }
74
+ catch (error) {
75
+ if (fs.existsSync(npmrcFile))
76
+ fs.unlinkSync(npmrcFile);
77
+ logger.error(error.message);
78
+ }
79
+ finally {
80
+ if (fs.existsSync(npmrcFile))
81
+ fs.unlinkSync(npmrcFile);
82
+ }
83
+ }
84
+ function toPascalCase(input) {
85
+ return input.replace(/[^a-zA-Z0-9]+(.)/g, (_, chr) => chr.toUpperCase()).replace(/^./, (s) => s.toLowerCase());
86
+ }
87
+ function updateNodeFile(filePath, newModule) {
88
+ let fileContent = fs.readFileSync(filePath, "utf-8");
89
+ const { importName, importPath } = newModule;
90
+ const importStatement = `import ${importName} from "${importPath}";`;
91
+ if (!fileContent.includes(importStatement)) {
92
+ const importLines = fileContent.match(/^import .*;$/gm) || [];
93
+ const lastImport = importLines[importLines.length - 1];
94
+ fileContent = fileContent.replace(lastImport, `${lastImport}\n${importStatement}`);
95
+ }
96
+ const nodesRegex = /const\s+nodes\s*:\s*\{[^}]+\}\s*=\s*\{([\s\S]*?)\n\};/;
97
+ const match = fileContent.match(nodesRegex);
98
+ if (!match)
99
+ throw new Error("Could not find the `nodes` object.");
100
+ const objectBody = match[1].trimEnd();
101
+ const entryKey = importPath.replace(/^@[^/]+\//, "");
102
+ const newEntry = `\t"${entryKey}": new ${importName}()`;
103
+ if (objectBody.includes(`"${entryKey}"`)) {
104
+ p.log.warn(`Node "${entryKey}" is already installed. Skipping...`);
105
+ return;
106
+ }
107
+ const lines = objectBody
108
+ .split("\n")
109
+ .filter(Boolean)
110
+ .map((line) => line.trimEnd());
111
+ if (lines.length > 0 && !lines[lines.length - 1].endsWith(",")) {
112
+ lines[lines.length - 1] += ",";
113
+ }
114
+ lines.push(newEntry);
115
+ const newObject = `const nodes: {\n\t[key: string]: NodeBase;\n} = {\n${lines.join("\n")}\n};`;
116
+ fileContent = fileContent.replace(nodesRegex, newObject);
117
+ fs.writeFileSync(filePath, `${fileContent.trimEnd()}\n`, "utf-8");
118
+ }
119
+ export default new Command()
120
+ .command("node")
121
+ .description("Install a node from the bloks registry")
122
+ .option("-d, --directory <value>", "Directory to publish")
123
+ .option("-m, --package-manager <value>", "Package manager to use (npm, yarn, pnpm, bun)")
124
+ .argument("<node>", "Node name")
125
+ .action(async (node, options) => {
126
+ await trackCommandExecution({
127
+ command: "install",
128
+ args: options,
129
+ execution: async () => {
130
+ options.node = node;
131
+ if (!options.directory)
132
+ options.directory = process.cwd();
133
+ await install(options);
134
+ },
135
+ });
136
+ });
@@ -0,0 +1,4 @@
1
+ import { Command, type OptionValues } from "../../services/commander.js";
2
+ export declare function install(opts: OptionValues): Promise<void>;
3
+ declare const _default: Command;
4
+ export default _default;
@@ -0,0 +1,62 @@
1
+ import * as fs from "node:fs";
2
+ import path from "node:path";
3
+ import * as p from "@clack/prompts";
4
+ import { Command, trackCommandExecution } from "../../services/commander.js";
5
+ import { BLOK_URL } from "../../services/constants.js";
6
+ import { tokenManager } from "../../services/local-token-manager.js";
7
+ async function searchWorkflow(opts) {
8
+ const response = await fetch(`${BLOK_URL}/published-workflow-by-id/${opts.workflow}`, {
9
+ method: "GET",
10
+ headers: {
11
+ Authorization: `Bearer ${opts.token}`,
12
+ },
13
+ });
14
+ if (!response.ok)
15
+ throw new Error(response.statusText);
16
+ const searchs = await response.json();
17
+ return searchs.documents;
18
+ }
19
+ export async function install(opts) {
20
+ const token = tokenManager.getToken();
21
+ const logger = p.spinner();
22
+ try {
23
+ if (!token)
24
+ throw new Error("Token is invalid.");
25
+ if (!opts.workflow)
26
+ throw new Error("Workflow name is required.");
27
+ opts.token = token;
28
+ const workflowInfo = await searchWorkflow(opts);
29
+ if (workflowInfo.length === 0) {
30
+ throw new Error("No workflow found.");
31
+ }
32
+ const workflow = workflowInfo[0].workflow;
33
+ logger.start("Installing workflow...");
34
+ const workflowsDir = path.join(opts.directory, "workflows/json");
35
+ if (!fs.existsSync(workflowsDir)) {
36
+ fs.mkdirSync(workflowsDir, { recursive: true });
37
+ }
38
+ const workflowPath = path.join(workflowsDir, `${opts.workflow}.json`);
39
+ fs.writeFileSync(workflowPath, JSON.stringify(workflow, null, 2));
40
+ logger.stop("Workflow installed successfully.");
41
+ }
42
+ catch (error) {
43
+ logger.error(error.message);
44
+ }
45
+ }
46
+ export default new Command()
47
+ .command("workflow")
48
+ .description("Install a workflow")
49
+ .option("-d, --directory <value>", "Directory to publish")
50
+ .argument("<workflow>", "Workflow name")
51
+ .action(async (workflow, options) => {
52
+ await trackCommandExecution({
53
+ command: "install",
54
+ args: options,
55
+ execution: async () => {
56
+ options.workflow = workflow;
57
+ if (!options.directory)
58
+ options.directory = process.cwd();
59
+ await install(options);
60
+ },
61
+ });
62
+ });
@@ -0,0 +1,2 @@
1
+ import { type OptionValues } from "../../services/commander.js";
2
+ export declare function login(opts: OptionValues): Promise<void>;
@@ -0,0 +1,77 @@
1
+ import * as p from "@clack/prompts";
2
+ import { program, trackCommandExecution } from "../../services/commander.js";
3
+ import { isNonInteractive } from "../../services/non-interactive.js";
4
+ import { BLOK_URL } from "../../services/constants.js";
5
+ import { tokenManager } from "../../services/local-token-manager.js";
6
+ async function verifyToken(token) {
7
+ const response = await fetch(`${BLOK_URL}/login`, {
8
+ method: "GET",
9
+ headers: {
10
+ Authorization: `Bearer ${token}`,
11
+ },
12
+ });
13
+ if (!response.ok)
14
+ throw new Error(response.statusText);
15
+ const responseJson = await response.json();
16
+ return responseJson;
17
+ }
18
+ export async function login(opts) {
19
+ let token = tokenManager.getToken();
20
+ const BLOKS_TOKEN = process.env.BLOKS_TOKEN;
21
+ const resolveToken = async () => {
22
+ let token = process.env.BLOKS_TOKEN;
23
+ if (token)
24
+ return token;
25
+ token = (await p.password({
26
+ message: "Please provide the token for authentication. You can create it on https://atomic.deskree.com/auth/access/token",
27
+ }));
28
+ if (p.isCancel(token)) {
29
+ p.cancel("Authentication cancelled.");
30
+ process.exit(0);
31
+ }
32
+ return token;
33
+ };
34
+ try {
35
+ if (!token && !BLOKS_TOKEN && !opts.token) {
36
+ if (isNonInteractive()) {
37
+ throw new Error("Missing required flag --token or BLOKS_TOKEN env var (non-interactive mode). " +
38
+ "Run without --non-interactive to use interactive prompts, or provide --token.");
39
+ }
40
+ token = await resolveToken();
41
+ }
42
+ else if (opts.token) {
43
+ token = opts.token;
44
+ }
45
+ else if (BLOKS_TOKEN) {
46
+ token = BLOKS_TOKEN;
47
+ }
48
+ if (!token)
49
+ throw new Error("Token is required.");
50
+ const isTokenValid = await verifyToken(token);
51
+ if (!isTokenValid.active)
52
+ throw new Error("Token is inactive.");
53
+ p.log.success("Login successful.");
54
+ const isStored = tokenManager.storeToken(token);
55
+ if (!isStored)
56
+ throw new Error("Failed to store the token.");
57
+ p.log.info("You can now use the CLI commands. For help, run: blokctl --help");
58
+ }
59
+ catch (error) {
60
+ p.log.error("Login failed. Please try again.");
61
+ p.log.error(error.message);
62
+ process.exit(1);
63
+ }
64
+ }
65
+ program
66
+ .command("login")
67
+ .description("Login to Bloks")
68
+ .option("-t, --token <value>", "Login with a token")
69
+ .action(async (options) => {
70
+ await trackCommandExecution({
71
+ command: "login",
72
+ args: options,
73
+ execution: async () => {
74
+ await login(options);
75
+ },
76
+ });
77
+ });
@@ -0,0 +1,2 @@
1
+ import { type OptionValues } from "../../services/commander.js";
2
+ export declare function logout(opts: OptionValues): Promise<void>;
@@ -0,0 +1,20 @@
1
+ import * as p from "@clack/prompts";
2
+ import { program, trackCommandExecution } from "../../services/commander.js";
3
+ import { tokenManager } from "../../services/local-token-manager.js";
4
+ export async function logout(opts) {
5
+ tokenManager.clearToken();
6
+ p.log.success("Logged out successfully.");
7
+ p.log.info("You can log in again using: blokctl login");
8
+ }
9
+ program
10
+ .command("logout")
11
+ .description("Logout from Bloks")
12
+ .action(async (options) => {
13
+ await trackCommandExecution({
14
+ command: "logout",
15
+ args: options,
16
+ execution: async () => {
17
+ await logout(options);
18
+ },
19
+ });
20
+ });
@@ -0,0 +1,54 @@
1
+ import type { CatalogStats, RuntimeKind, RuntimePackageManifest } from "@blok/runner";
2
+ import { Command } from "../../services/commander.js";
3
+ export interface MarketplaceConfig {
4
+ registryUrl: string;
5
+ cacheDir: string;
6
+ cacheTtlMs: number;
7
+ }
8
+ export interface MarketplaceListOptions {
9
+ runtime?: RuntimeKind;
10
+ query?: string;
11
+ tags?: string[];
12
+ verified?: boolean;
13
+ sortBy?: "name" | "downloads" | "rating" | "updated";
14
+ limit?: number;
15
+ format?: "table" | "json";
16
+ }
17
+ export interface MarketplaceInstallOptions {
18
+ name: string;
19
+ version?: string;
20
+ runtime?: RuntimeKind;
21
+ force?: boolean;
22
+ }
23
+ export interface MarketplacePublishOptions {
24
+ manifestPath: string;
25
+ dockerImage: string;
26
+ runtime: RuntimeKind;
27
+ tags?: string[];
28
+ description?: string;
29
+ }
30
+ export declare class RuntimeMarketplaceCommand {
31
+ private config;
32
+ constructor(config?: Partial<MarketplaceConfig>);
33
+ search(options: MarketplaceListOptions): Promise<RuntimePackageManifest[]>;
34
+ install(options: MarketplaceInstallOptions): Promise<{
35
+ success: boolean;
36
+ message: string;
37
+ }>;
38
+ publish(options: MarketplacePublishOptions): Promise<{
39
+ success: boolean;
40
+ packageId: string;
41
+ version: string;
42
+ }>;
43
+ info(name: string, version?: string): Promise<RuntimePackageManifest | null>;
44
+ stats(): Promise<CatalogStats>;
45
+ list(runtime: RuntimeKind): Promise<RuntimePackageManifest[]>;
46
+ formatTable(packages: RuntimePackageManifest[]): string;
47
+ formatJson(packages: RuntimePackageManifest[]): string;
48
+ private getCacheKey;
49
+ private readCache;
50
+ private writeCache;
51
+ private fetchFromApi;
52
+ }
53
+ declare const _default: Command;
54
+ export default _default;