@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 +21 -0
- package/README.md +15 -13
- package/cli.js +17 -9
- package/commands/integration.js +172 -12
- package/commands/login.js +1 -1
- package/helper/env.js +1 -1
- package/helper/folder.js +19 -4
- package/helper/validation.js +260 -7
- package/llm.txt +295 -0
- package/package.json +11 -3
- package/templates/component-schemas.js +929 -0
- package/templates/schemas.js +36 -6
- package/utils/integration.js +1 -1
- package/.claude/settings.local.json +0 -15
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
|
[](https://www.npmjs.com/package/@boltic/cli)
|
|
6
|
+
[](https://github.com/<your-username>/<your-repo>)
|
|
6
7
|
[](./LICENSE)
|
|
8
|
+
[](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
|
-
### ๐
|
|
69
|
+
### ๐ Submit an Integration
|
|
68
70
|
|
|
69
71
|
```bash
|
|
70
|
-
boltic integration
|
|
72
|
+
boltic integration submit
|
|
71
73
|
```
|
|
72
74
|
|
|
73
75
|
---
|
|
74
76
|
|
|
75
77
|
## ๐ Command Reference
|
|
76
78
|
|
|
77
|
-
| Command
|
|
78
|
-
|
|
|
79
|
-
| `boltic login`
|
|
80
|
-
| `boltic integration create`
|
|
81
|
-
| `boltic integration sync`
|
|
82
|
-
| `boltic integration
|
|
83
|
-
| `boltic integration pull`
|
|
84
|
-
| `boltic integration edit`
|
|
85
|
-
| `boltic help`
|
|
86
|
-
| `boltic 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
|
|
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
|
|
144
|
+
let version = "1.0.0"; // default fallback
|
|
145
145
|
try {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
-
|
|
151
|
-
|
|
152
|
-
|
|
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
|
|
package/commands/integration.js
CHANGED
|
@@ -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
|
|
223
|
-
console.log(chalk.green("
|
|
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
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
-
[
|
|
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
|
-
[
|
|
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
|
-
[
|
|
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
package/helper/env.js
CHANGED
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 (
|
|
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
|
-
|
|
51
|
-
|
|
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
|
-
|
|
69
|
+
...(create_catalogue && {
|
|
70
|
+
"Authentication.mdx": `# ${name} Authentication`,
|
|
71
|
+
}),
|
|
57
72
|
"Documentation.mdx": `# ${name} Documentation`,
|
|
58
73
|
};
|
|
59
74
|
|