@boltic/cli 1.0.6-beta.1 → 1.0.6-beta.11

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,6 +3,7 @@
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)
7
8
 
8
9
  ---
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
 
@@ -50,6 +50,10 @@ const commands = {
50
50
  description: "Show detailed information about an integration",
51
51
  action: handleStatus,
52
52
  },
53
+ test: {
54
+ description: "Run tests for the integration",
55
+ action: handleTest,
56
+ },
53
57
  help: {
54
58
  description: "Show help for integration commands",
55
59
  action: showHelp,
@@ -147,6 +151,19 @@ async function handleSync(args) {
147
151
  if (fs.existsSync(specPath)) {
148
152
  const specContent = JSON.parse(fs.readFileSync(specPath, "utf8"));
149
153
  // Update integration with spec.json content
154
+
155
+ if (
156
+ specContent.trigger_type &&
157
+ specContent.trigger_type !== "CloudTrigger"
158
+ ) {
159
+ console.error(
160
+ chalk.red(
161
+ `Error: Invalid trigger_type "${specContent.trigger_type}". It should be "CloudTrigger" or null.`
162
+ )
163
+ );
164
+ return;
165
+ }
166
+
150
167
  const updatedIntegration = await updateIntegration(
151
168
  apiUrl,
152
169
  token,
@@ -245,6 +262,19 @@ async function handlePublish(args) {
245
262
  if (fs.existsSync(specPath)) {
246
263
  const specContent = JSON.parse(fs.readFileSync(specPath, "utf8"));
247
264
  // Update integration with spec.json content
265
+
266
+ if (
267
+ specContent.trigger_type &&
268
+ specContent.trigger_type !== "CloudTrigger"
269
+ ) {
270
+ console.error(
271
+ chalk.red(
272
+ `Error: Invalid trigger_type "${specContent.trigger_type}". It should be "CloudTrigger" or null.`
273
+ )
274
+ );
275
+ return;
276
+ }
277
+
248
278
  const updatedIntegration = await updateIntegration(
249
279
  apiUrl,
250
280
  token,
@@ -574,7 +604,10 @@ async function handleCreate() {
574
604
  );
575
605
 
576
606
  // Create folder structure with the integration name
577
- await createIntegrationFolderStructure(integration);
607
+ await createIntegrationFolderStructure(
608
+ integration,
609
+ create_catalogue
610
+ );
578
611
 
579
612
  // Also share Documentation URL to the user: https://docs.boltic.io/docs/integration-builder/develop/boilerplate
580
613
  const documentationUrl =
@@ -638,7 +671,12 @@ async function handleEdit() {
638
671
  const choices =
639
672
  integrations
640
673
  .filter((integration) =>
641
- ["customActivity", "CloudTrigger"].includes(
674
+ [
675
+ "customActivity",
676
+ "CloudTrigger",
677
+ "applicationFdkActivity",
678
+ "platformFdkActivity",
679
+ ].includes(
642
680
  integration.activity_type || integration.trigger_type
643
681
  )
644
682
  )
@@ -793,7 +831,12 @@ async function handlePull(args) {
793
831
  const choices =
794
832
  integrations
795
833
  .filter((integration) =>
796
- ["customActivity", "CloudTrigger"].includes(
834
+ [
835
+ "customActivity",
836
+ "CloudTrigger",
837
+ "applicationFdkActivity",
838
+ "platformFdkActivity",
839
+ ].includes(
797
840
  integration.activity_type ||
798
841
  integration.trigger_type
799
842
  )
@@ -899,7 +942,12 @@ async function handleStatus() {
899
942
  const choices =
900
943
  integrations
901
944
  .filter((integration) =>
902
- ["customActivity", "CloudTrigger"].includes(
945
+ [
946
+ "customActivity",
947
+ "CloudTrigger",
948
+ "applicationFdkActivity",
949
+ "platformFdkActivity",
950
+ ].includes(
903
951
  integration.activity_type || integration.trigger_type
904
952
  )
905
953
  )
@@ -985,6 +1033,100 @@ async function handleStatus() {
985
1033
  }
986
1034
  }
987
1035
 
1036
+ async function handleTest(args) {
1037
+ // Parse command line arguments
1038
+ let currentDir = process.cwd();
1039
+ const pathIndex = args.indexOf("--path");
1040
+
1041
+ if (pathIndex !== -1 && args[pathIndex + 1]) {
1042
+ currentDir = args[pathIndex + 1];
1043
+ // Validate the provided path
1044
+ if (!fs.existsSync(currentDir)) {
1045
+ console.error(
1046
+ chalk.red(
1047
+ `Error: The specified path does not exist: ${currentDir}`
1048
+ )
1049
+ );
1050
+ return;
1051
+ }
1052
+ }
1053
+
1054
+ const { spawn } = await import("child_process");
1055
+
1056
+ console.log(chalk.cyan.bold("\n🧪 Running integration tests...\n"));
1057
+
1058
+ // Look for test directory
1059
+ const testDirs = ["test", "tests", "__tests__"];
1060
+ let testDir = null;
1061
+
1062
+ for (const dir of testDirs) {
1063
+ if (fs.existsSync(dir)) {
1064
+ testDir = dir;
1065
+ break;
1066
+ }
1067
+ }
1068
+
1069
+ if (!testDir) {
1070
+ console.log(
1071
+ chalk.yellow(
1072
+ "⚠️ No test directory found. Looked for: test, tests, __tests__"
1073
+ )
1074
+ );
1075
+ return;
1076
+ }
1077
+
1078
+ console.log(chalk.dim(`📁 Found test directory: ${testDir}`));
1079
+
1080
+ // Check if Jest is available
1081
+ const packageJsonPath = path.join(process.cwd(), "package.json");
1082
+ let hasJest = false;
1083
+
1084
+ if (fs.existsSync(packageJsonPath)) {
1085
+ try {
1086
+ const packageJson = JSON.parse(
1087
+ fs.readFileSync(packageJsonPath, "utf-8")
1088
+ );
1089
+ hasJest = !!(
1090
+ packageJson.devDependencies?.jest ||
1091
+ packageJson.dependencies?.jest
1092
+ );
1093
+ } catch (error) {
1094
+ console.log(chalk.yellow("⚠️ Could not read package.json"));
1095
+ }
1096
+ }
1097
+
1098
+ if (!hasJest) {
1099
+ console.log(
1100
+ chalk.red(
1101
+ "❌ Jest is not installed. Please install Jest to run tests."
1102
+ )
1103
+ );
1104
+ return;
1105
+ }
1106
+
1107
+ // Run Jest with the test directory
1108
+ return new Promise((resolve, reject) => {
1109
+ const jestProcess = spawn("npx", ["jest", testDir, "--verbose"], {
1110
+ stdio: "inherit",
1111
+ shell: true,
1112
+ });
1113
+
1114
+ jestProcess.on("close", (code) => {
1115
+ if (code === 0) {
1116
+ console.log(chalk.green.bold("\n✅ All tests passed!"));
1117
+ } else {
1118
+ console.log(chalk.red.bold("\n❌ Some tests failed."));
1119
+ }
1120
+ resolve(code);
1121
+ });
1122
+
1123
+ jestProcess.on("error", (error) => {
1124
+ console.error(chalk.red("❌ Error running tests:"), error.message);
1125
+ reject(error);
1126
+ });
1127
+ });
1128
+ }
1129
+
988
1130
  export default {
989
1131
  execute,
990
1132
  };
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
 
@@ -154,6 +154,23 @@ const validateResources = (resourcesDir, resourceFields, errors) => {
154
154
  });
155
155
  };
156
156
 
157
+ // const validateParametersScema = (schema, errors) => {
158
+ // if (!schema || !Array.isArray(schema.parameters)) {
159
+ // errors.add(
160
+ // `Schema is missing or parameters are not defined as an array.`
161
+ // );
162
+ // return;
163
+ // }
164
+ // schema.parameters.forEach((param) => {
165
+ // const { meta } = param;
166
+ // if (!param.name) {
167
+ // errors.add(
168
+ // `Parameter in schema is missing a name. Ensure all parameters have a "name" field.`
169
+ // );
170
+ // }
171
+ // });
172
+ // };
173
+
157
174
  // ─────────────────────────────────────────────────────────────────────────────
158
175
  // MAIN FUNCTION
159
176
  // ─────────────────────────────────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,18 +1,26 @@
1
1
  {
2
2
  "name": "@boltic/cli",
3
- "version": "1.0.6-beta.1",
3
+ "version": "1.0.6-beta.11",
4
4
  "description": "A powerful CLI tool for managing Boltic Workflow integrations",
5
5
  "main": "index.js",
6
6
  "bin": {
7
7
  "boltic": "index.js"
8
8
  },
9
9
  "author": "Ahmed Sakri <ahmedsakri@gofynd.com>",
10
- "homepage": "https://www.boltic.io",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/bolticio/cli.git"
13
+ },
14
+ "homepage": "https://github.com/bolticio/cli#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/bolticio/cli/issues"
17
+ },
11
18
  "scripts": {
12
19
  "start": "node index.js",
13
20
  "dev": "nodemon index.js",
14
21
  "test": "jest",
15
- "prepare": "husky"
22
+ "prepare": "husky",
23
+ "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
16
24
  },
17
25
  "keywords": [
18
26
  "cli",
@@ -45,10 +45,24 @@ const authentication = {
45
45
  },
46
46
  };
47
47
 
48
- const base = (name) => {
49
- return {
50
- parameters: [
51
- {
48
+ const base = (name, create_catalogue) => {
49
+ const secretParameter = create_catalogue
50
+ ? {
51
+ name: "secret",
52
+ meta: {
53
+ displayName: "Service Account",
54
+ displayType: "hidden",
55
+ placeholder: "Select Service Account",
56
+ description:
57
+ "Your service account credentials are encrypted & can be removed at any time.",
58
+ options: [],
59
+ value: `__BOLTIC_INTEGRATION_${name.toUpperCase()}`,
60
+ validation: {
61
+ required: true,
62
+ },
63
+ },
64
+ }
65
+ : {
52
66
  name: "secret",
53
67
  meta: {
54
68
  displayName: "Service Account",
@@ -72,7 +86,11 @@ const base = (name) => {
72
86
  required: true,
73
87
  },
74
88
  },
75
- },
89
+ };
90
+
91
+ return {
92
+ parameters: [
93
+ secretParameter,
76
94
  {
77
95
  name: "resource",
78
96
  meta: {
@@ -39,7 +39,7 @@ async function pickSvgFile() {
39
39
  console.error("Unsupported platform for file picker");
40
40
  return null;
41
41
  }
42
- } catch (_) {
42
+ } catch {
43
43
  return null;
44
44
  }
45
45
  }
@@ -1,15 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Bash(mkdir:*)",
5
- "Bash(npm test)",
6
- "Bash(npm test:*)",
7
- "Bash(ls:*)",
8
- "Bash(npx jest:*)",
9
- "Bash(rm:*)",
10
- "Bash(grep:*)",
11
- "Bash(touch:*)"
12
- ],
13
- "deny": []
14
- }
15
- }