@boltic/cli 1.0.6-beta.1 โ†’ 1.0.6-beta.12

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Boltic.io
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -3,7 +3,9 @@
3
3
  > A powerful CLI tool for creating, managing, and publishing Boltic integrations.
4
4
 
5
5
  [![NPM Version](https://img.shields.io/npm/v/@boltic/cli)](https://www.npmjs.com/package/@boltic/cli)
6
+ [![GitHub Repo](https://img.shields.io/badge/GitHub-Repo-blue?logo=github)](https://github.com/<your-username>/<your-repo>)
6
7
  [![License](https://img.shields.io/npm/l/@boltic/cli)](./LICENSE)
8
+ [![Node.js Package](https://github.com/bolticio/cli/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/bolticio/cli/actions/workflows/npm-publish.yml)
7
9
 
8
10
  ---
9
11
 
@@ -64,26 +66,26 @@ boltic integration edit
64
66
  boltic integration sync
65
67
  ```
66
68
 
67
- ### ๐Ÿš€ Publish an Integration
69
+ ### ๐Ÿš€ Submit an Integration
68
70
 
69
71
  ```bash
70
- boltic integration publish
72
+ boltic integration submit
71
73
  ```
72
74
 
73
75
  ---
74
76
 
75
77
  ## ๐Ÿ“Œ Command Reference
76
78
 
77
- | Command | Description |
78
- | ---------------------------- | -------------------------------------------------------- |
79
- | `boltic login` | Authenticate with Boltic |
80
- | `boltic integration create` | Create a new integration |
81
- | `boltic integration sync` | Sync changes to your draft |
82
- | `boltic integration publish` | Submit integration for review |
83
- | `boltic integration pull` | Pull the latest changes of an integration from the Cloud |
84
- | `boltic integration edit` | Edit an existing integration |
85
- | `boltic help` | Show CLI help |
86
- | `boltic version` | Display CLI version |
79
+ | Command | Description |
80
+ | --------------------------- | -------------------------------------------------------- |
81
+ | `boltic login` | Authenticate with Boltic |
82
+ | `boltic integration create` | Create a new integration |
83
+ | `boltic integration sync` | Sync changes to your draft |
84
+ | `boltic integration submit` | Submit integration for review |
85
+ | `boltic integration pull` | Pull the latest changes of an integration from the Cloud |
86
+ | `boltic integration edit` | Edit an existing integration |
87
+ | `boltic help` | Show CLI help |
88
+ | `boltic version` | Display CLI version |
87
89
 
88
90
  ---
89
91
 
@@ -100,7 +102,7 @@ boltic integration create
100
102
  boltic integration sync
101
103
 
102
104
  # Step 5: Submit for publishing and review
103
- boltic integration publish
105
+ boltic integration submit
104
106
 
105
107
  # Step 6: Pull the latest changes of a integration. Please call this command inside a integration folder.
106
108
  boltic integration pull
package/cli.js CHANGED
@@ -114,7 +114,7 @@ async function showHelp(commands) {
114
114
  packageJson = JSON.parse(
115
115
  fs.readFileSync(path.join(process.cwd(), "package.json"))
116
116
  );
117
- } catch (_) {
117
+ } catch {
118
118
  // Fallback version if package.json not found
119
119
  packageJson = { version: "1.0.0" };
120
120
  }
@@ -141,17 +141,25 @@ async function handleEnvironment(args) {
141
141
  }
142
142
 
143
143
  async function showVersion() {
144
- let packageJson;
144
+ let version = "1.0.0"; // default fallback
145
145
  try {
146
- // Try to read package.json from current directory
147
- packageJson = JSON.parse(
148
- fs.readFileSync(path.join(process.cwd(), "package.json"))
146
+ let packageJsonPath;
147
+ if (typeof import.meta !== "undefined" && import.meta.url) {
148
+ // ES modules in Node.js
149
+ const currentDir = path.dirname(new URL(import.meta.url).pathname);
150
+ packageJsonPath = path.join(currentDir, "package.json");
151
+ } else {
152
+ // Jest or other environments
153
+ packageJsonPath = path.join(process.cwd(), "package.json");
154
+ }
155
+
156
+ const packageJson = JSON.parse(
157
+ fs.readFileSync(packageJsonPath, "utf-8")
149
158
  );
150
- } catch (_) {
151
- // Fallback version if package.json not found
152
- packageJson = { version: "1.0.0" };
159
+ version = packageJson.version;
160
+ } catch {
161
+ // fallback already defined
153
162
  }
154
- const version = packageJson.version;
155
163
  console.log(`Boltic CLI Version: ${version}`);
156
164
  }
157
165
 
@@ -34,8 +34,12 @@ const commands = {
34
34
  description: "Edit an existing integration",
35
35
  action: handleEdit,
36
36
  },
37
+ submit: {
38
+ description: "Submit an integration for review",
39
+ action: handleSubmit,
40
+ },
37
41
  publish: {
38
- description: "Publish an integration",
42
+ description: "Publish an integration (deprecated, use submit)",
39
43
  action: handlePublish,
40
44
  },
41
45
  sync: {
@@ -50,6 +54,10 @@ const commands = {
50
54
  description: "Show detailed information about an integration",
51
55
  action: handleStatus,
52
56
  },
57
+ test: {
58
+ description: "Run tests for the integration",
59
+ action: handleTest,
60
+ },
53
61
  help: {
54
62
  description: "Show help for integration commands",
55
63
  action: showHelp,
@@ -147,6 +155,19 @@ async function handleSync(args) {
147
155
  if (fs.existsSync(specPath)) {
148
156
  const specContent = JSON.parse(fs.readFileSync(specPath, "utf8"));
149
157
  // Update integration with spec.json content
158
+
159
+ if (
160
+ specContent.trigger_type &&
161
+ specContent.trigger_type !== "CloudTrigger"
162
+ ) {
163
+ console.error(
164
+ chalk.red(
165
+ `Error: Invalid trigger_type "${specContent.trigger_type}". It should be "CloudTrigger" or null.`
166
+ )
167
+ );
168
+ return;
169
+ }
170
+
150
171
  const updatedIntegration = await updateIntegration(
151
172
  apiUrl,
152
173
  token,
@@ -219,8 +240,8 @@ async function handleSync(args) {
219
240
  }
220
241
 
221
242
  // Publish an integration
222
- async function handlePublish(args) {
223
- console.log(chalk.green("Publishing integration...\n"));
243
+ async function handleSubmit(args) {
244
+ console.log(chalk.green("Submitting integration for review...\n"));
224
245
  // Parse command line arguments
225
246
  let currentDir = process.cwd();
226
247
  const pathIndex = args.indexOf("--path");
@@ -245,6 +266,19 @@ async function handlePublish(args) {
245
266
  if (fs.existsSync(specPath)) {
246
267
  const specContent = JSON.parse(fs.readFileSync(specPath, "utf8"));
247
268
  // Update integration with spec.json content
269
+
270
+ if (
271
+ specContent.trigger_type &&
272
+ specContent.trigger_type !== "CloudTrigger"
273
+ ) {
274
+ console.error(
275
+ chalk.red(
276
+ `Error: Invalid trigger_type "${specContent.trigger_type}". It should be "CloudTrigger" or null.`
277
+ )
278
+ );
279
+ return;
280
+ }
281
+
248
282
  const updatedIntegration = await updateIntegration(
249
283
  apiUrl,
250
284
  token,
@@ -317,18 +351,32 @@ async function handlePublish(args) {
317
351
  if (review) {
318
352
  console.log(
319
353
  chalk.green(
320
- "\nโœ… Integration sent to review successfully!\n"
354
+ "\nโœ… Integration submitted for review successfully!\n"
321
355
  )
322
356
  );
323
357
  }
324
358
  } else {
325
359
  console.error(
326
- chalk.red("\nโŒ Error publishing integration:", data.message)
360
+ chalk.red("\nโŒ Error submitting integration:", data.message)
327
361
  );
328
362
  }
329
363
  }
330
364
  }
331
365
 
366
+ async function handlePublish(args) {
367
+ console.log(
368
+ chalk.yellow(
369
+ "โš ๏ธ WARNING: The 'publish' command is deprecated and will be removed in a future version."
370
+ )
371
+ );
372
+ console.log(
373
+ chalk.yellow("Please use 'boltic integration submit' instead.\n")
374
+ );
375
+
376
+ // Call the new submit function
377
+ await handleSubmit(args);
378
+ }
379
+
332
380
  // Execute the integration command
333
381
  const execute = async (args) => {
334
382
  const subCommand = args[0];
@@ -574,17 +622,20 @@ async function handleCreate() {
574
622
  );
575
623
 
576
624
  // Create folder structure with the integration name
577
- await createIntegrationFolderStructure(integration);
625
+ await createIntegrationFolderStructure(
626
+ integration,
627
+ create_catalogue
628
+ );
578
629
 
579
- // Also share Documentation URL to the user: https://docs.boltic.io/docs/integration-builder/develop/boilerplate
580
630
  const documentationUrl =
581
631
  "https://docs.boltic.io/docs/integration-builder/develop/boilerplate";
632
+
582
633
  console.log(
583
634
  chalk.cyan(
584
- "\n๐Ÿ“„ Documentation URL: " +
585
- chalk.underline.blue(documentationUrl)
635
+ `๐Ÿ“„ For detailed instructions on next steps, refer to the official documentation:`
586
636
  )
587
637
  );
638
+ console.log(chalk.underline.blue(documentationUrl));
588
639
  }
589
640
  } catch (error) {
590
641
  console.error(
@@ -638,7 +689,12 @@ async function handleEdit() {
638
689
  const choices =
639
690
  integrations
640
691
  .filter((integration) =>
641
- ["customActivity", "CloudTrigger"].includes(
692
+ [
693
+ "customActivity",
694
+ "CloudTrigger",
695
+ "applicationFdkActivity",
696
+ "platformFdkActivity",
697
+ ].includes(
642
698
  integration.activity_type || integration.trigger_type
643
699
  )
644
700
  )
@@ -793,7 +849,12 @@ async function handlePull(args) {
793
849
  const choices =
794
850
  integrations
795
851
  .filter((integration) =>
796
- ["customActivity", "CloudTrigger"].includes(
852
+ [
853
+ "customActivity",
854
+ "CloudTrigger",
855
+ "applicationFdkActivity",
856
+ "platformFdkActivity",
857
+ ].includes(
797
858
  integration.activity_type ||
798
859
  integration.trigger_type
799
860
  )
@@ -899,7 +960,12 @@ async function handleStatus() {
899
960
  const choices =
900
961
  integrations
901
962
  .filter((integration) =>
902
- ["customActivity", "CloudTrigger"].includes(
963
+ [
964
+ "customActivity",
965
+ "CloudTrigger",
966
+ "applicationFdkActivity",
967
+ "platformFdkActivity",
968
+ ].includes(
903
969
  integration.activity_type || integration.trigger_type
904
970
  )
905
971
  )
@@ -985,6 +1051,100 @@ async function handleStatus() {
985
1051
  }
986
1052
  }
987
1053
 
1054
+ async function handleTest(args) {
1055
+ // Parse command line arguments
1056
+ let currentDir = process.cwd();
1057
+ const pathIndex = args.indexOf("--path");
1058
+
1059
+ if (pathIndex !== -1 && args[pathIndex + 1]) {
1060
+ currentDir = args[pathIndex + 1];
1061
+ // Validate the provided path
1062
+ if (!fs.existsSync(currentDir)) {
1063
+ console.error(
1064
+ chalk.red(
1065
+ `Error: The specified path does not exist: ${currentDir}`
1066
+ )
1067
+ );
1068
+ return;
1069
+ }
1070
+ }
1071
+
1072
+ const { spawn } = await import("child_process");
1073
+
1074
+ console.log(chalk.cyan.bold("\n๐Ÿงช Running integration tests...\n"));
1075
+
1076
+ // Look for test directory
1077
+ const testDirs = ["test", "tests", "__tests__"];
1078
+ let testDir = null;
1079
+
1080
+ for (const dir of testDirs) {
1081
+ if (fs.existsSync(dir)) {
1082
+ testDir = dir;
1083
+ break;
1084
+ }
1085
+ }
1086
+
1087
+ if (!testDir) {
1088
+ console.log(
1089
+ chalk.yellow(
1090
+ "โš ๏ธ No test directory found. Looked for: test, tests, __tests__"
1091
+ )
1092
+ );
1093
+ return;
1094
+ }
1095
+
1096
+ console.log(chalk.dim(`๐Ÿ“ Found test directory: ${testDir}`));
1097
+
1098
+ // Check if Jest is available
1099
+ const packageJsonPath = path.join(process.cwd(), "package.json");
1100
+ let hasJest = false;
1101
+
1102
+ if (fs.existsSync(packageJsonPath)) {
1103
+ try {
1104
+ const packageJson = JSON.parse(
1105
+ fs.readFileSync(packageJsonPath, "utf-8")
1106
+ );
1107
+ hasJest = !!(
1108
+ packageJson.devDependencies?.jest ||
1109
+ packageJson.dependencies?.jest
1110
+ );
1111
+ } catch (error) {
1112
+ console.log(chalk.yellow("โš ๏ธ Could not read package.json"));
1113
+ }
1114
+ }
1115
+
1116
+ if (!hasJest) {
1117
+ console.log(
1118
+ chalk.red(
1119
+ "โŒ Jest is not installed. Please install Jest to run tests."
1120
+ )
1121
+ );
1122
+ return;
1123
+ }
1124
+
1125
+ // Run Jest with the test directory
1126
+ return new Promise((resolve, reject) => {
1127
+ const jestProcess = spawn("npx", ["jest", testDir, "--verbose"], {
1128
+ stdio: "inherit",
1129
+ shell: true,
1130
+ });
1131
+
1132
+ jestProcess.on("close", (code) => {
1133
+ if (code === 0) {
1134
+ console.log(chalk.green.bold("\nโœ… All tests passed!"));
1135
+ } else {
1136
+ console.log(chalk.red.bold("\nโŒ Some tests failed."));
1137
+ }
1138
+ resolve(code);
1139
+ });
1140
+
1141
+ jestProcess.on("error", (error) => {
1142
+ console.error(chalk.red("โŒ Error running tests:"), error.message);
1143
+ reject(error);
1144
+ });
1145
+ });
1146
+ }
1147
+
988
1148
  export default {
989
1149
  execute,
990
1150
  };
package/commands/login.js CHANGED
@@ -40,7 +40,7 @@ function showHelp() {
40
40
  }
41
41
 
42
42
  // Handle login command
43
- async function handleLogin(args) {
43
+ async function handleLogin() {
44
44
  const { apiUrl, loginUrl, clientId, frontendUrl, name } =
45
45
  await getCurrentEnv();
46
46
 
package/helper/env.js CHANGED
@@ -11,7 +11,7 @@ export const getCurrentEnv = async () => {
11
11
 
12
12
  try {
13
13
  secrets = await getAllSecrets();
14
- } catch (_) {
14
+ } catch {
15
15
  // If getAllSecrets fails, use default bolt environment
16
16
  secrets = null;
17
17
  }
package/helper/folder.js CHANGED
@@ -9,7 +9,10 @@ import {
9
9
  webhook,
10
10
  } from "../templates/schemas.js";
11
11
 
12
- export const createIntegrationFolderStructure = async (integration) => {
12
+ export const createIntegrationFolderStructure = async (
13
+ integration,
14
+ create_catalogue
15
+ ) => {
13
16
  const { id, name, description, icon, activity_type, trigger_type, meta } =
14
17
  integration;
15
18
 
@@ -47,13 +50,25 @@ export const createIntegrationFolderStructure = async (integration) => {
47
50
  // Create template files
48
51
  const files = {
49
52
  "schemas/resources/resource1.json": JSON.stringify(resource1, null, 4),
50
- "schemas/authentication.json": JSON.stringify(authentication, null, 4),
51
- "schemas/base.json": JSON.stringify(base(name), null, 4),
53
+ ...(create_catalogue && {
54
+ "schemas/authentication.json": JSON.stringify(
55
+ authentication,
56
+ null,
57
+ 4
58
+ ),
59
+ }),
60
+ "schemas/base.json": JSON.stringify(
61
+ base(name, create_catalogue),
62
+ null,
63
+ 4
64
+ ),
52
65
  ...(!isEmpty(trigger_type) && {
53
66
  "schemas/webhook.json": JSON.stringify(webhook(name), null, 4),
54
67
  }),
55
68
  "spec.json": JSON.stringify(spec, null, 4),
56
- "Authentication.mdx": `# ${name} Authentication`,
69
+ ...(create_catalogue && {
70
+ "Authentication.mdx": `# ${name} Authentication`,
71
+ }),
57
72
  "Documentation.mdx": `# ${name} Documentation`,
58
73
  };
59
74