@boltic/cli 1.0.8 → 1.0.9
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/ahmed_test_cases_test/Authentication.mdx +1 -0
- package/ahmed_test_cases_test/Documentation.mdx +1 -0
- package/ahmed_test_cases_test/schemas/authentication.json +45 -0
- package/ahmed_test_cases_test/schemas/base.json +56 -0
- package/ahmed_test_cases_test/schemas/resources/resource1.json +134 -0
- package/ahmed_test_cases_test/spec.json +17 -0
- package/commands/integration.js +105 -51
- package/package.json +1 -1
- package/templates/component-schemas.js +15 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Ahmed_Test_Cases_Test Authentication
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Ahmed_Test_Cases_Test Documentation
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"parameters": [
|
|
3
|
+
{
|
|
4
|
+
"name": "type",
|
|
5
|
+
"meta": {
|
|
6
|
+
"displayName": "Authentication Type",
|
|
7
|
+
"displayType": "select",
|
|
8
|
+
"placeholder": "Select an authentication type",
|
|
9
|
+
"description": "Choose the type of authentication you want to use.",
|
|
10
|
+
"options": [
|
|
11
|
+
{
|
|
12
|
+
"label": "API Key",
|
|
13
|
+
"value": "api_key"
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"value": "api_key",
|
|
17
|
+
"validation": {
|
|
18
|
+
"required": true,
|
|
19
|
+
"requiredDetail": {
|
|
20
|
+
"errorMsg": "Authentication type is required"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"api_key": {
|
|
27
|
+
"parameters": [
|
|
28
|
+
{
|
|
29
|
+
"name": "api_key",
|
|
30
|
+
"meta": {
|
|
31
|
+
"displayName": "API Key",
|
|
32
|
+
"displayType": "password",
|
|
33
|
+
"placeholder": "Enter API Key",
|
|
34
|
+
"description": "Your API key for authentication",
|
|
35
|
+
"validation": {
|
|
36
|
+
"required": true,
|
|
37
|
+
"requiredDetail": {
|
|
38
|
+
"errorMsg": "API key is required"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"parameters": [
|
|
3
|
+
{
|
|
4
|
+
"name": "secret",
|
|
5
|
+
"meta": {
|
|
6
|
+
"displayName": "Service Account",
|
|
7
|
+
"displayType": "autocomplete",
|
|
8
|
+
"placeholder": "Select Service Account",
|
|
9
|
+
"description": "Your service account credentials are encrypted & can be removed at any time.",
|
|
10
|
+
"options": [],
|
|
11
|
+
"config": {
|
|
12
|
+
"urlType": "secret",
|
|
13
|
+
"method": "get",
|
|
14
|
+
"url": "/AHMED_TEST_CASES_TEST?current_page=1&page_size=999",
|
|
15
|
+
"labelKey": "name",
|
|
16
|
+
"valueKey": "_id"
|
|
17
|
+
},
|
|
18
|
+
"htmlProps": {
|
|
19
|
+
"showAddNew": true
|
|
20
|
+
},
|
|
21
|
+
"value": "",
|
|
22
|
+
"validation": {
|
|
23
|
+
"required": true
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"name": "resource",
|
|
29
|
+
"meta": {
|
|
30
|
+
"displayName": "Resource",
|
|
31
|
+
"displayType": "select",
|
|
32
|
+
"placeholder": "Select a resource",
|
|
33
|
+
"description": "Select the resource you want to work with.",
|
|
34
|
+
"options": [
|
|
35
|
+
{
|
|
36
|
+
"label": "Resource 1",
|
|
37
|
+
"value": "resource1",
|
|
38
|
+
"description": "Description for Resource 1"
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"value": "",
|
|
42
|
+
"validation": {
|
|
43
|
+
"required": true
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"conditions": [
|
|
47
|
+
{
|
|
48
|
+
"field": "secret",
|
|
49
|
+
"operator": "NOT_EMPTY"
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
{
|
|
2
|
+
"parameters": [
|
|
3
|
+
{
|
|
4
|
+
"name": "operation",
|
|
5
|
+
"meta": {
|
|
6
|
+
"displayName": "Operation",
|
|
7
|
+
"displayType": "select",
|
|
8
|
+
"placeholder": "Select an operation",
|
|
9
|
+
"description": "Select the operation you want to perform.",
|
|
10
|
+
"options": [
|
|
11
|
+
{
|
|
12
|
+
"label": "Create Account",
|
|
13
|
+
"value": "resource1.create",
|
|
14
|
+
"description": "Create a new account."
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"label": "Delete Account",
|
|
18
|
+
"value": "resource1.delete",
|
|
19
|
+
"description": "Delete an existing account."
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"validation": {
|
|
23
|
+
"required": true
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"conditions": [
|
|
27
|
+
{
|
|
28
|
+
"field": "resource",
|
|
29
|
+
"operator": "EQUALS",
|
|
30
|
+
"value": "resource1"
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"create": {
|
|
38
|
+
"definition": {
|
|
39
|
+
"method": "post",
|
|
40
|
+
"url": "https://dummyjson.com/products",
|
|
41
|
+
"headers": {
|
|
42
|
+
"ContentType": "application/json"
|
|
43
|
+
},
|
|
44
|
+
"body": "{{parameters}}",
|
|
45
|
+
"response": {
|
|
46
|
+
"output": "{{response.data}}",
|
|
47
|
+
"error": {
|
|
48
|
+
"message": "{{response.data.errors.message}}",
|
|
49
|
+
"code": "{{response.data.errors.code}}"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
"parameters": [
|
|
54
|
+
{
|
|
55
|
+
"name": "name",
|
|
56
|
+
"meta": {
|
|
57
|
+
"displayName": "Product Name",
|
|
58
|
+
"displayType": "text",
|
|
59
|
+
"placeholder": "Enter the name of the product",
|
|
60
|
+
"description": "Enter the name of the product you want to create.",
|
|
61
|
+
"validation": {
|
|
62
|
+
"required": true
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"name": "description",
|
|
68
|
+
"meta": {
|
|
69
|
+
"displayName": "Product Description",
|
|
70
|
+
"displayType": "text",
|
|
71
|
+
"placeholder": "Enter the description of the product",
|
|
72
|
+
"description": "Enter the description of the product you want to create.",
|
|
73
|
+
"validation": {
|
|
74
|
+
"required": true
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"name": "price",
|
|
80
|
+
"meta": {
|
|
81
|
+
"displayName": "Product Price",
|
|
82
|
+
"displayType": "number",
|
|
83
|
+
"placeholder": "Enter the price of the product",
|
|
84
|
+
"description": "Enter the price of the product you want to create.",
|
|
85
|
+
"validation": {
|
|
86
|
+
"required": true
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"name": "discountPercentage",
|
|
92
|
+
"meta": {
|
|
93
|
+
"displayName": "Discount Percentage",
|
|
94
|
+
"displayType": "number",
|
|
95
|
+
"placeholder": "Enter the discount percentage",
|
|
96
|
+
"description": "Enter the discount percentage for the product you want to create.",
|
|
97
|
+
"validation": {
|
|
98
|
+
"required": true
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
"delete": {
|
|
105
|
+
"parameters": [
|
|
106
|
+
{
|
|
107
|
+
"name": "id",
|
|
108
|
+
"meta": {
|
|
109
|
+
"displayName": "Account ID",
|
|
110
|
+
"displayType": "text",
|
|
111
|
+
"placeholder": "Enter the Account ID",
|
|
112
|
+
"description": "Enter the ID of the account you want to delete.",
|
|
113
|
+
"validation": {
|
|
114
|
+
"required": true
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
],
|
|
119
|
+
"definition": {
|
|
120
|
+
"method": "delete",
|
|
121
|
+
"url": "https://dummyjson.com/products/{{parameters.id}}",
|
|
122
|
+
"headers": {
|
|
123
|
+
"ContentType": "application/json"
|
|
124
|
+
},
|
|
125
|
+
"response": {
|
|
126
|
+
"output": "{{response.data}}",
|
|
127
|
+
"error": {
|
|
128
|
+
"message": "{{response.data.errors.message}}",
|
|
129
|
+
"code": "{{response.data.errors.code}}"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "766689c4-e6c9-4adf-8b21-f69c3a281307",
|
|
3
|
+
"name": "Ahmed_Test_Cases_Test",
|
|
4
|
+
"description": {
|
|
5
|
+
"trigger": "",
|
|
6
|
+
"integration": "Sample Test Case Integration"
|
|
7
|
+
},
|
|
8
|
+
"icon": "https://cdn.pixelbin.io/v2/fyndcloud/original/Temporal/Uploads/bolt/e8b51f71-6062-4c30-958e-f87351ed13bf/images/Paddle_1752734761014.svg",
|
|
9
|
+
"activity_type": "customActivity",
|
|
10
|
+
"trigger_type": null,
|
|
11
|
+
"meta": {
|
|
12
|
+
"ai_description": {
|
|
13
|
+
"trigger": "",
|
|
14
|
+
"integration": "Sample AI Test Case Integration"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
package/commands/integration.js
CHANGED
|
@@ -2,6 +2,7 @@ import { confirm, input, search } from "@inquirer/prompts";
|
|
|
2
2
|
import chalk from "chalk";
|
|
3
3
|
import fs from "fs";
|
|
4
4
|
import path from "path";
|
|
5
|
+
import { execSync } from "child_process";
|
|
5
6
|
|
|
6
7
|
import {
|
|
7
8
|
editIntegration,
|
|
@@ -54,6 +55,10 @@ const commands = {
|
|
|
54
55
|
description: "Show detailed information about an integration",
|
|
55
56
|
action: handleStatus,
|
|
56
57
|
},
|
|
58
|
+
test: {
|
|
59
|
+
description: "Test an integration using Jest",
|
|
60
|
+
action: handleTest,
|
|
61
|
+
},
|
|
57
62
|
help: {
|
|
58
63
|
description: "Show help for integration commands",
|
|
59
64
|
action: showHelp,
|
|
@@ -129,6 +134,7 @@ async function handleSync(args) {
|
|
|
129
134
|
// Parse command line arguments
|
|
130
135
|
let currentDir = process.cwd();
|
|
131
136
|
const pathIndex = args.indexOf("--path");
|
|
137
|
+
const skipValidation = args.includes("--no-verify");
|
|
132
138
|
|
|
133
139
|
if (pathIndex !== -1 && args[pathIndex + 1]) {
|
|
134
140
|
currentDir = args[pathIndex + 1];
|
|
@@ -189,27 +195,34 @@ async function handleSync(args) {
|
|
|
189
195
|
|
|
190
196
|
console.log(chalk.cyan(`\nSyncing integration: ${specContent.name}`));
|
|
191
197
|
|
|
192
|
-
|
|
198
|
+
if (skipValidation) {
|
|
199
|
+
console.log(
|
|
200
|
+
chalk.yellow(
|
|
201
|
+
"⚠️ Skipping validation (--no-verify flag detected)"
|
|
202
|
+
)
|
|
203
|
+
);
|
|
204
|
+
} else {
|
|
205
|
+
console.log("Validating schemas...");
|
|
193
206
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
207
|
+
// Validate resources
|
|
208
|
+
const { validateIntegrationSchemas } = await import(
|
|
209
|
+
"../helper/validation.js"
|
|
210
|
+
);
|
|
211
|
+
const validationResult = validateIntegrationSchemas(currentDir);
|
|
212
|
+
if (!validationResult.success) {
|
|
213
|
+
if (Array.isArray(validationResult.errors)) {
|
|
214
|
+
validationResult.errors.forEach((error) => {
|
|
215
|
+
console.error(chalk.red(`\n❌ ${error}`));
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
return;
|
|
204
219
|
}
|
|
205
|
-
|
|
220
|
+
console.log(chalk.green("Schemas validated successfully"));
|
|
206
221
|
}
|
|
207
222
|
|
|
208
223
|
const schemas = await readSchemaFiles(currentDir);
|
|
209
224
|
schemas.status = "draft";
|
|
210
225
|
|
|
211
|
-
console.log(chalk.green("Schemas validated successfully"));
|
|
212
|
-
|
|
213
226
|
const data = await syncIntegration(apiUrl, token, accountId, session, {
|
|
214
227
|
integration_id: specContent.id,
|
|
215
228
|
...schemas,
|
|
@@ -241,6 +254,7 @@ async function handleSubmit(args) {
|
|
|
241
254
|
// Parse command line arguments
|
|
242
255
|
let currentDir = process.cwd();
|
|
243
256
|
const pathIndex = args.indexOf("--path");
|
|
257
|
+
const skipValidation = args.includes("--no-verify");
|
|
244
258
|
|
|
245
259
|
if (pathIndex !== -1 && args[pathIndex + 1]) {
|
|
246
260
|
currentDir = args[pathIndex + 1];
|
|
@@ -300,28 +314,35 @@ async function handleSubmit(args) {
|
|
|
300
314
|
|
|
301
315
|
console.log(chalk.cyan(`\nSyncing integration: ${specContent.name}`));
|
|
302
316
|
|
|
303
|
-
|
|
317
|
+
if (skipValidation) {
|
|
318
|
+
console.log(
|
|
319
|
+
chalk.yellow(
|
|
320
|
+
"⚠️ Skipping validation (--no-verify flag detected)"
|
|
321
|
+
)
|
|
322
|
+
);
|
|
323
|
+
} else {
|
|
324
|
+
console.log("Validating schemas...");
|
|
304
325
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
326
|
+
// Validate resources
|
|
327
|
+
const { validateIntegrationSchemas } = await import(
|
|
328
|
+
"../helper/validation.js"
|
|
329
|
+
);
|
|
330
|
+
const validationResult = validateIntegrationSchemas(currentDir);
|
|
331
|
+
if (!validationResult.success) {
|
|
332
|
+
if (Array.isArray(validationResult.errors)) {
|
|
333
|
+
validationResult.errors.forEach((error) => {
|
|
334
|
+
console.error(chalk.red(`\n❌ ${error}`));
|
|
335
|
+
});
|
|
336
|
+
}
|
|
316
337
|
|
|
317
|
-
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
console.log(chalk.green("Schemas validated successfully"));
|
|
318
341
|
}
|
|
319
342
|
|
|
320
343
|
const schemas = await readSchemaFiles(currentDir);
|
|
321
344
|
schemas.status = "draft";
|
|
322
345
|
|
|
323
|
-
console.log(chalk.green("Schemas validated successfully"));
|
|
324
|
-
|
|
325
346
|
const data = await syncIntegration(apiUrl, token, accountId, session, {
|
|
326
347
|
integration_id: specContent.id,
|
|
327
348
|
...schemas,
|
|
@@ -917,35 +938,13 @@ async function handlePull(args) {
|
|
|
917
938
|
}
|
|
918
939
|
}
|
|
919
940
|
|
|
920
|
-
// Show help for integration commands
|
|
921
941
|
function showHelp() {
|
|
922
942
|
console.log(chalk.cyan("\nIntegration Commands:\n"));
|
|
923
943
|
Object.entries(commands).forEach(([cmd, details]) => {
|
|
924
944
|
console.log(chalk.bold(`${cmd}`) + ` - ${details.description}`);
|
|
925
945
|
});
|
|
926
|
-
|
|
927
|
-
console.log(chalk.cyan("\nTest Command Usage:"));
|
|
928
|
-
console.log(chalk.dim(" boltic integration test"));
|
|
929
|
-
console.log(chalk.dim(" boltic integration test --path /path/to/project"));
|
|
930
|
-
console.log(chalk.dim(" boltic integration test --config jest.config.js"));
|
|
931
|
-
console.log(chalk.dim(" boltic integration test --watchAll"));
|
|
932
|
-
console.log(chalk.dim(" boltic integration test --updateSnapshot"));
|
|
933
|
-
|
|
934
|
-
console.log(chalk.cyan("\nSupported Flags:"));
|
|
935
|
-
console.log(
|
|
936
|
-
chalk.dim(" --path <directory> Run tests in specific directory")
|
|
937
|
-
);
|
|
938
|
-
console.log(
|
|
939
|
-
chalk.dim(" --config <file> Use specific Jest config file")
|
|
940
|
-
);
|
|
941
|
-
console.log(
|
|
942
|
-
chalk.dim(" --watchAll Watch all files for changes")
|
|
943
|
-
);
|
|
944
|
-
console.log(chalk.dim(" --updateSnapshot Update snapshots"));
|
|
945
|
-
console.log(chalk.dim(" All other Jest CLI flags are supported"));
|
|
946
946
|
}
|
|
947
947
|
|
|
948
|
-
// Show detailed information about an integration
|
|
949
948
|
async function handleStatus() {
|
|
950
949
|
console.log(chalk.green("Fetching integration information...\n"));
|
|
951
950
|
|
|
@@ -1074,6 +1073,61 @@ async function handleStatus() {
|
|
|
1074
1073
|
}
|
|
1075
1074
|
}
|
|
1076
1075
|
|
|
1076
|
+
async function handleTest(args) {
|
|
1077
|
+
console.log(chalk.green("Running integration tests...\n"));
|
|
1078
|
+
|
|
1079
|
+
let currentDir = process.cwd();
|
|
1080
|
+
const pathIndex = args.indexOf("--path");
|
|
1081
|
+
|
|
1082
|
+
if (pathIndex !== -1 && args[pathIndex + 1]) {
|
|
1083
|
+
currentDir = args[pathIndex + 1];
|
|
1084
|
+
if (!fs.existsSync(currentDir)) {
|
|
1085
|
+
console.error(
|
|
1086
|
+
chalk.red(
|
|
1087
|
+
`Error: The specified path does not exist: ${currentDir}`
|
|
1088
|
+
)
|
|
1089
|
+
);
|
|
1090
|
+
return;
|
|
1091
|
+
}
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
const specPath = path.join(currentDir, "spec.json");
|
|
1095
|
+
if (!fs.existsSync(specPath)) {
|
|
1096
|
+
console.error(
|
|
1097
|
+
chalk.red(
|
|
1098
|
+
"Error: No spec.json file found in the current directory. Please ensure you're in an integration directory."
|
|
1099
|
+
)
|
|
1100
|
+
);
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
const testsDir = path.join(currentDir, "__tests__");
|
|
1105
|
+
if (!fs.existsSync(testsDir)) {
|
|
1106
|
+
console.error(
|
|
1107
|
+
chalk.red(
|
|
1108
|
+
"Error: No __tests__ directory found. Please create test files in a __tests__ directory."
|
|
1109
|
+
)
|
|
1110
|
+
);
|
|
1111
|
+
return;
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
try {
|
|
1115
|
+
console.log(chalk.cyan("Running Jest tests...\n"));
|
|
1116
|
+
|
|
1117
|
+
const testCommand = `npx jest "${testsDir}" --verbose`;
|
|
1118
|
+
execSync(testCommand, {
|
|
1119
|
+
stdio: "inherit",
|
|
1120
|
+
cwd: currentDir,
|
|
1121
|
+
});
|
|
1122
|
+
|
|
1123
|
+
console.log(chalk.green("\n✓ All tests completed successfully!"));
|
|
1124
|
+
} catch (error) {
|
|
1125
|
+
console.error(chalk.red("\n✗ Tests failed with errors:"));
|
|
1126
|
+
console.error(chalk.red(error.message));
|
|
1127
|
+
process.exit(1);
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1077
1131
|
export default {
|
|
1078
1132
|
execute,
|
|
1079
1133
|
};
|
package/package.json
CHANGED
|
@@ -679,6 +679,21 @@ const multiselect = {
|
|
|
679
679
|
requiredDetail: {
|
|
680
680
|
errorMsg: "Selection is required",
|
|
681
681
|
},
|
|
682
|
+
min: 1,
|
|
683
|
+
minDetail: {
|
|
684
|
+
errorMsg: "At least one option is required",
|
|
685
|
+
},
|
|
686
|
+
max: 10,
|
|
687
|
+
maxDetail: {
|
|
688
|
+
errorMsg: "Too many options",
|
|
689
|
+
},
|
|
690
|
+
pattern: "^[a-zA-Z]+$",
|
|
691
|
+
patternDetail: {
|
|
692
|
+
errorMsg: "Value must be a valid name",
|
|
693
|
+
},
|
|
694
|
+
},
|
|
695
|
+
htmlProps: {
|
|
696
|
+
allowDynamic: false,
|
|
682
697
|
},
|
|
683
698
|
dependencies: {
|
|
684
699
|
logic: "AND",
|