@boltic/cli 1.0.6-beta.8 → 1.0.6
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/README.md +505 -60
- package/commands/integration.js +229 -33
- package/helper/validation.js +302 -26
- package/llm.txt +295 -0
- package/package.json +3 -3
- package/templates/component-schemas.js +929 -0
- package/templates/schemas.js +27 -15
- package/.claude/settings.local.json +0 -17
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: {
|
|
@@ -51,7 +55,7 @@ const commands = {
|
|
|
51
55
|
action: handleStatus,
|
|
52
56
|
},
|
|
53
57
|
test: {
|
|
54
|
-
description: "Run tests for the integration",
|
|
58
|
+
description: "Run tests for the integration with coverage",
|
|
55
59
|
action: handleTest,
|
|
56
60
|
},
|
|
57
61
|
help: {
|
|
@@ -236,8 +240,8 @@ async function handleSync(args) {
|
|
|
236
240
|
}
|
|
237
241
|
|
|
238
242
|
// Publish an integration
|
|
239
|
-
async function
|
|
240
|
-
console.log(chalk.green("
|
|
243
|
+
async function handleSubmit(args) {
|
|
244
|
+
console.log(chalk.green("Submitting integration for review...\n"));
|
|
241
245
|
// Parse command line arguments
|
|
242
246
|
let currentDir = process.cwd();
|
|
243
247
|
const pathIndex = args.indexOf("--path");
|
|
@@ -347,18 +351,32 @@ async function handlePublish(args) {
|
|
|
347
351
|
if (review) {
|
|
348
352
|
console.log(
|
|
349
353
|
chalk.green(
|
|
350
|
-
"\n✅ Integration
|
|
354
|
+
"\n✅ Integration submitted for review successfully!\n"
|
|
351
355
|
)
|
|
352
356
|
);
|
|
353
357
|
}
|
|
354
358
|
} else {
|
|
355
359
|
console.error(
|
|
356
|
-
chalk.red("\n❌ Error
|
|
360
|
+
chalk.red("\n❌ Error submitting integration:", data.message)
|
|
357
361
|
);
|
|
358
362
|
}
|
|
359
363
|
}
|
|
360
364
|
}
|
|
361
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
|
+
|
|
362
380
|
// Execute the integration command
|
|
363
381
|
const execute = async (args) => {
|
|
364
382
|
const subCommand = args[0];
|
|
@@ -609,15 +627,15 @@ async function handleCreate() {
|
|
|
609
627
|
create_catalogue
|
|
610
628
|
);
|
|
611
629
|
|
|
612
|
-
// Also share Documentation URL to the user: https://docs.boltic.io/docs/integration-builder/develop/boilerplate
|
|
613
630
|
const documentationUrl =
|
|
614
631
|
"https://docs.boltic.io/docs/integration-builder/develop/boilerplate";
|
|
632
|
+
|
|
615
633
|
console.log(
|
|
616
634
|
chalk.cyan(
|
|
617
|
-
|
|
618
|
-
chalk.underline.blue(documentationUrl)
|
|
635
|
+
`📄 For detailed instructions on next steps, refer to the official documentation:`
|
|
619
636
|
)
|
|
620
637
|
);
|
|
638
|
+
console.log(chalk.underline.blue(documentationUrl));
|
|
621
639
|
}
|
|
622
640
|
} catch (error) {
|
|
623
641
|
console.error(
|
|
@@ -909,6 +927,26 @@ function showHelp() {
|
|
|
909
927
|
Object.entries(commands).forEach(([cmd, details]) => {
|
|
910
928
|
console.log(chalk.bold(`${cmd}`) + ` - ${details.description}`);
|
|
911
929
|
});
|
|
930
|
+
|
|
931
|
+
console.log(chalk.cyan("\nTest Command Usage:"));
|
|
932
|
+
console.log(chalk.dim(" boltic integration test"));
|
|
933
|
+
console.log(chalk.dim(" boltic integration test --path /path/to/project"));
|
|
934
|
+
console.log(chalk.dim(" boltic integration test --config jest.config.js"));
|
|
935
|
+
console.log(chalk.dim(" boltic integration test --watchAll"));
|
|
936
|
+
console.log(chalk.dim(" boltic integration test --updateSnapshot"));
|
|
937
|
+
|
|
938
|
+
console.log(chalk.cyan("\nSupported Flags:"));
|
|
939
|
+
console.log(
|
|
940
|
+
chalk.dim(" --path <directory> Run tests in specific directory")
|
|
941
|
+
);
|
|
942
|
+
console.log(
|
|
943
|
+
chalk.dim(" --config <file> Use specific Jest config file")
|
|
944
|
+
);
|
|
945
|
+
console.log(
|
|
946
|
+
chalk.dim(" --watchAll Watch all files for changes")
|
|
947
|
+
);
|
|
948
|
+
console.log(chalk.dim(" --updateSnapshot Update snapshots"));
|
|
949
|
+
console.log(chalk.dim(" All other Jest CLI flags are supported"));
|
|
912
950
|
}
|
|
913
951
|
|
|
914
952
|
// Show detailed information about an integration
|
|
@@ -1036,7 +1074,9 @@ async function handleStatus() {
|
|
|
1036
1074
|
async function handleTest(args) {
|
|
1037
1075
|
// Parse command line arguments
|
|
1038
1076
|
let currentDir = process.cwd();
|
|
1077
|
+
let jestConfigFile = null;
|
|
1039
1078
|
const pathIndex = args.indexOf("--path");
|
|
1079
|
+
const configIndex = args.indexOf("--config");
|
|
1040
1080
|
|
|
1041
1081
|
if (pathIndex !== -1 && args[pathIndex + 1]) {
|
|
1042
1082
|
currentDir = args[pathIndex + 1];
|
|
@@ -1051,72 +1091,228 @@ async function handleTest(args) {
|
|
|
1051
1091
|
}
|
|
1052
1092
|
}
|
|
1053
1093
|
|
|
1094
|
+
if (configIndex !== -1 && args[configIndex + 1]) {
|
|
1095
|
+
jestConfigFile = args[configIndex + 1];
|
|
1096
|
+
// Validate the config file path
|
|
1097
|
+
const configPath = path.isAbsolute(jestConfigFile)
|
|
1098
|
+
? jestConfigFile
|
|
1099
|
+
: path.join(currentDir, jestConfigFile);
|
|
1100
|
+
|
|
1101
|
+
if (!fs.existsSync(configPath)) {
|
|
1102
|
+
console.error(
|
|
1103
|
+
chalk.red(
|
|
1104
|
+
`Error: Jest config file does not exist: ${configPath}`
|
|
1105
|
+
)
|
|
1106
|
+
);
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1054
1111
|
const { spawn } = await import("child_process");
|
|
1055
1112
|
|
|
1056
1113
|
console.log(chalk.cyan.bold("\n🧪 Running integration tests...\n"));
|
|
1057
1114
|
|
|
1058
|
-
// Look for test directory
|
|
1115
|
+
// Look for test directory and test files
|
|
1059
1116
|
const testDirs = ["test", "tests", "__tests__"];
|
|
1060
1117
|
let testDir = null;
|
|
1118
|
+
let testFiles = [];
|
|
1061
1119
|
|
|
1120
|
+
// Check for test directories
|
|
1062
1121
|
for (const dir of testDirs) {
|
|
1063
|
-
|
|
1122
|
+
const testPath = path.join(currentDir, dir);
|
|
1123
|
+
if (fs.existsSync(testPath)) {
|
|
1064
1124
|
testDir = dir;
|
|
1125
|
+
// Find all test files in the directory
|
|
1126
|
+
const files = fs.readdirSync(testPath);
|
|
1127
|
+
testFiles = files.filter(
|
|
1128
|
+
(file) =>
|
|
1129
|
+
file.endsWith(".test.js") ||
|
|
1130
|
+
file.endsWith(".spec.js") ||
|
|
1131
|
+
file.endsWith(".test.ts") ||
|
|
1132
|
+
file.endsWith(".spec.ts")
|
|
1133
|
+
);
|
|
1065
1134
|
break;
|
|
1066
1135
|
}
|
|
1067
1136
|
}
|
|
1068
1137
|
|
|
1138
|
+
// If no test directory found, look for test files in current directory
|
|
1069
1139
|
if (!testDir) {
|
|
1140
|
+
const currentDirFiles = fs.readdirSync(currentDir);
|
|
1141
|
+
testFiles = currentDirFiles.filter(
|
|
1142
|
+
(file) =>
|
|
1143
|
+
file.endsWith(".test.js") ||
|
|
1144
|
+
file.endsWith(".spec.js") ||
|
|
1145
|
+
file.endsWith(".test.ts") ||
|
|
1146
|
+
file.endsWith(".spec.ts")
|
|
1147
|
+
);
|
|
1148
|
+
|
|
1149
|
+
if (testFiles.length === 0) {
|
|
1150
|
+
console.log(
|
|
1151
|
+
chalk.yellow(
|
|
1152
|
+
"⚠️ No test files found. Looked for: test, tests, __tests__ directories and *.test.js, *.spec.js, *.test.ts, *.spec.ts files"
|
|
1153
|
+
)
|
|
1154
|
+
);
|
|
1155
|
+
return;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
|
|
1159
|
+
if (testFiles.length === 0 && testDir) {
|
|
1070
1160
|
console.log(
|
|
1071
1161
|
chalk.yellow(
|
|
1072
|
-
|
|
1162
|
+
`⚠️ No test files found in ${testDir} directory. Looking for: *.test.js, *.spec.js, *.test.ts, *.spec.ts files`
|
|
1073
1163
|
)
|
|
1074
1164
|
);
|
|
1075
1165
|
return;
|
|
1076
1166
|
}
|
|
1077
1167
|
|
|
1078
|
-
console.log(chalk.dim(`📁 Found test directory: ${testDir}`));
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1168
|
+
console.log(chalk.dim(`📁 Found test directory: ${testDir || currentDir}`));
|
|
1169
|
+
console.log(
|
|
1170
|
+
chalk.dim(
|
|
1171
|
+
`📋 Found ${testFiles.length} test file(s): ${testFiles.join(", ")}`
|
|
1172
|
+
)
|
|
1173
|
+
);
|
|
1174
|
+
|
|
1175
|
+
// Check for Jest configuration
|
|
1176
|
+
let jestConfigPath;
|
|
1177
|
+
if (jestConfigFile) {
|
|
1178
|
+
jestConfigPath = path.isAbsolute(jestConfigFile)
|
|
1179
|
+
? jestConfigFile
|
|
1180
|
+
: path.join(currentDir, jestConfigFile);
|
|
1181
|
+
} else {
|
|
1182
|
+
// Look for default config files
|
|
1183
|
+
const defaultConfigs = [
|
|
1184
|
+
"jest.config.cjs",
|
|
1185
|
+
"jest.config.js",
|
|
1186
|
+
"jest.config.json",
|
|
1187
|
+
];
|
|
1188
|
+
for (const configFile of defaultConfigs) {
|
|
1189
|
+
const configPath = path.join(currentDir, configFile);
|
|
1190
|
+
if (fs.existsSync(configPath)) {
|
|
1191
|
+
jestConfigPath = configPath;
|
|
1192
|
+
break;
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1083
1196
|
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1197
|
+
const jestConfigExists = !!jestConfigPath;
|
|
1198
|
+
const configFileName = jestConfigPath
|
|
1199
|
+
? path.basename(jestConfigPath)
|
|
1200
|
+
: null;
|
|
1201
|
+
|
|
1202
|
+
console.log(
|
|
1203
|
+
chalk.dim(
|
|
1204
|
+
`⚙️ Jest configuration: ${jestConfigExists ? `Found ${configFileName}` : "Using default configuration"}`
|
|
1205
|
+
)
|
|
1206
|
+
);
|
|
1207
|
+
|
|
1208
|
+
// Prepare Jest arguments
|
|
1209
|
+
const jestArgs = ["jest"];
|
|
1210
|
+
|
|
1211
|
+
// Add basic Jest flags
|
|
1212
|
+
jestArgs.push("--coverage");
|
|
1213
|
+
jestArgs.push("--verbose");
|
|
1214
|
+
jestArgs.push("--colors");
|
|
1215
|
+
jestArgs.push("--passWithNoTests");
|
|
1216
|
+
|
|
1217
|
+
// Add config file if exists, otherwise use simple patterns
|
|
1218
|
+
if (jestConfigExists) {
|
|
1219
|
+
jestArgs.push("--config", jestConfigPath);
|
|
1220
|
+
} else {
|
|
1221
|
+
// Use simple test matching patterns
|
|
1222
|
+
if (testDir) {
|
|
1223
|
+
jestArgs.push(
|
|
1224
|
+
"--testMatch",
|
|
1225
|
+
`**/${testDir}/**/*.{test,spec}.{js,ts}`
|
|
1092
1226
|
);
|
|
1093
|
-
}
|
|
1094
|
-
|
|
1227
|
+
} else {
|
|
1228
|
+
jestArgs.push("--testMatch", "**/*.{test,spec}.{js,ts}");
|
|
1095
1229
|
}
|
|
1230
|
+
jestArgs.push("--collectCoverageFrom", "lib/**/*.{js,ts}");
|
|
1231
|
+
jestArgs.push("--collectCoverageFrom", "src/**/*.{js,ts}");
|
|
1232
|
+
jestArgs.push("--collectCoverageFrom", "*.{js,ts}");
|
|
1233
|
+
jestArgs.push("--coveragePathIgnorePatterns", "/node_modules/");
|
|
1234
|
+
jestArgs.push("--coveragePathIgnorePatterns", "/tests/");
|
|
1096
1235
|
}
|
|
1097
1236
|
|
|
1098
|
-
|
|
1237
|
+
// Add any additional Jest arguments passed by user
|
|
1238
|
+
const additionalArgs = args.filter((arg, index) => {
|
|
1239
|
+
// Skip our custom flags and their values
|
|
1240
|
+
if (arg === "--path" || arg === "--config") return false;
|
|
1241
|
+
if (args[index - 1] === "--path" || args[index - 1] === "--config")
|
|
1242
|
+
return false;
|
|
1243
|
+
return true;
|
|
1244
|
+
});
|
|
1245
|
+
|
|
1246
|
+
if (additionalArgs.length > 0) {
|
|
1247
|
+
jestArgs.push(...additionalArgs);
|
|
1099
1248
|
console.log(
|
|
1100
|
-
chalk.
|
|
1101
|
-
|
|
1249
|
+
chalk.dim(
|
|
1250
|
+
`🔧 Additional Jest arguments: ${additionalArgs.join(" ")}`
|
|
1102
1251
|
)
|
|
1103
1252
|
);
|
|
1104
|
-
return;
|
|
1105
1253
|
}
|
|
1106
1254
|
|
|
1107
|
-
|
|
1255
|
+
console.log(chalk.dim(`🚀 Running command: npx ${jestArgs.join(" ")}`));
|
|
1256
|
+
console.log(chalk.cyan("─".repeat(50)));
|
|
1257
|
+
|
|
1258
|
+
// Run Jest with coverage
|
|
1108
1259
|
return new Promise((resolve, reject) => {
|
|
1109
|
-
const jestProcess = spawn("npx",
|
|
1260
|
+
const jestProcess = spawn("npx", jestArgs, {
|
|
1110
1261
|
stdio: "inherit",
|
|
1111
1262
|
shell: true,
|
|
1263
|
+
cwd: currentDir,
|
|
1112
1264
|
});
|
|
1113
1265
|
|
|
1114
1266
|
jestProcess.on("close", (code) => {
|
|
1267
|
+
console.log(chalk.cyan("─".repeat(50)));
|
|
1268
|
+
|
|
1115
1269
|
if (code === 0) {
|
|
1116
1270
|
console.log(chalk.green.bold("\n✅ All tests passed!"));
|
|
1271
|
+
|
|
1272
|
+
// Check for coverage directory
|
|
1273
|
+
const coverageDir = path.join(currentDir, "coverage");
|
|
1274
|
+
if (fs.existsSync(coverageDir)) {
|
|
1275
|
+
console.log(chalk.cyan("\n📊 Coverage Report Generated:"));
|
|
1276
|
+
console.log(chalk.dim(` Directory: ${coverageDir}`));
|
|
1277
|
+
|
|
1278
|
+
// Check for HTML report
|
|
1279
|
+
const htmlReportPath = path.join(
|
|
1280
|
+
coverageDir,
|
|
1281
|
+
"lcov-report",
|
|
1282
|
+
"index.html"
|
|
1283
|
+
);
|
|
1284
|
+
if (fs.existsSync(htmlReportPath)) {
|
|
1285
|
+
console.log(
|
|
1286
|
+
chalk.dim(` HTML Report: ${htmlReportPath}`)
|
|
1287
|
+
);
|
|
1288
|
+
}
|
|
1289
|
+
|
|
1290
|
+
// Check for text report
|
|
1291
|
+
const textReportPath = path.join(coverageDir, "lcov.info");
|
|
1292
|
+
if (fs.existsSync(textReportPath)) {
|
|
1293
|
+
console.log(
|
|
1294
|
+
chalk.dim(` LCOV Report: ${textReportPath}`)
|
|
1295
|
+
);
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
|
|
1299
|
+
// Show test summary
|
|
1300
|
+
console.log(chalk.cyan("\n📋 Test Summary:"));
|
|
1301
|
+
console.log(chalk.dim(` Test files: ${testFiles.length}`));
|
|
1302
|
+
console.log(
|
|
1303
|
+
chalk.dim(` Test directory: ${testDir || currentDir}`)
|
|
1304
|
+
);
|
|
1305
|
+
console.log(chalk.green(" Status: PASSED"));
|
|
1117
1306
|
} else {
|
|
1118
1307
|
console.log(chalk.red.bold("\n❌ Some tests failed."));
|
|
1308
|
+
console.log(chalk.red(` Exit code: ${code}`));
|
|
1119
1309
|
}
|
|
1310
|
+
|
|
1311
|
+
console.log(
|
|
1312
|
+
chalk.cyan(
|
|
1313
|
+
"\n💡 Tip: Check the coverage directory for detailed coverage reports"
|
|
1314
|
+
)
|
|
1315
|
+
);
|
|
1120
1316
|
resolve(code);
|
|
1121
1317
|
});
|
|
1122
1318
|
|