@supercheck/cli 0.1.0-beta.6 → 0.1.0-beta.8
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/dist/bin/supercheck.js +163 -72
- package/dist/bin/supercheck.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/supercheck.js
CHANGED
|
@@ -213,7 +213,7 @@ function requireTriggerKey() {
|
|
|
213
213
|
}
|
|
214
214
|
|
|
215
215
|
// src/version.ts
|
|
216
|
-
var CLI_VERSION = true ? "0.1.0-beta.
|
|
216
|
+
var CLI_VERSION = true ? "0.1.0-beta.7" : "0.0.0-dev";
|
|
217
217
|
|
|
218
218
|
// src/api/client.ts
|
|
219
219
|
import { ProxyAgent } from "undici";
|
|
@@ -643,6 +643,93 @@ function safeId(value) {
|
|
|
643
643
|
if (str === "undefined" || str === "null" || str === "") return void 0;
|
|
644
644
|
return str;
|
|
645
645
|
}
|
|
646
|
+
function normalizeAlertConfig(alert) {
|
|
647
|
+
const normalized = { ...alert };
|
|
648
|
+
if (normalized.customMessage === "" || normalized.customMessage === null) delete normalized.customMessage;
|
|
649
|
+
if (normalized.failureThreshold === 1) delete normalized.failureThreshold;
|
|
650
|
+
if (normalized.recoveryThreshold === 1) delete normalized.recoveryThreshold;
|
|
651
|
+
for (const key of ["alertOnFailure", "alertOnRecovery", "alertOnSslExpiration", "alertOnSuccess", "alertOnTimeout"]) {
|
|
652
|
+
if (normalized[key] === false) delete normalized[key];
|
|
653
|
+
}
|
|
654
|
+
if (Array.isArray(normalized.notificationProviders) && normalized.notificationProviders.length === 0) {
|
|
655
|
+
delete normalized.notificationProviders;
|
|
656
|
+
}
|
|
657
|
+
return Object.keys(normalized).length > 0 ? normalized : void 0;
|
|
658
|
+
}
|
|
659
|
+
function normalizeMonitorConfig(config) {
|
|
660
|
+
const normalized = { ...config };
|
|
661
|
+
delete normalized.sslLastCheckedAt;
|
|
662
|
+
if (normalized.playwrightOptions && typeof normalized.playwrightOptions === "object") {
|
|
663
|
+
const opts = { ...normalized.playwrightOptions };
|
|
664
|
+
if (opts.retries === 0) delete opts.retries;
|
|
665
|
+
if (opts.timeout === 3e5) delete opts.timeout;
|
|
666
|
+
if (opts.headless === true) delete opts.headless;
|
|
667
|
+
normalized.playwrightOptions = Object.keys(opts).length > 0 ? opts : void 0;
|
|
668
|
+
if (!normalized.playwrightOptions) delete normalized.playwrightOptions;
|
|
669
|
+
}
|
|
670
|
+
if (normalized.locationConfig && typeof normalized.locationConfig === "object") {
|
|
671
|
+
const loc = { ...normalized.locationConfig };
|
|
672
|
+
const hasLocations = Array.isArray(loc.locations) && loc.locations.length > 0;
|
|
673
|
+
if (!loc.enabled || !hasLocations) {
|
|
674
|
+
delete normalized.locationConfig;
|
|
675
|
+
} else {
|
|
676
|
+
if (loc.enabled === true) delete loc.enabled;
|
|
677
|
+
if (loc.strategy === "majority") delete loc.strategy;
|
|
678
|
+
if (loc.threshold === 50) delete loc.threshold;
|
|
679
|
+
normalized.locationConfig = Object.keys(loc).length > 0 ? loc : void 0;
|
|
680
|
+
if (!normalized.locationConfig) delete normalized.locationConfig;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
return Object.keys(normalized).length > 0 ? normalized : void 0;
|
|
684
|
+
}
|
|
685
|
+
function normalizeRemoteRaw(type, raw) {
|
|
686
|
+
const normalized = { ...raw };
|
|
687
|
+
delete normalized.createdAt;
|
|
688
|
+
delete normalized.updatedAt;
|
|
689
|
+
delete normalized.projectId;
|
|
690
|
+
delete normalized.organizationId;
|
|
691
|
+
delete normalized.createdByUserId;
|
|
692
|
+
if (type === "monitor") {
|
|
693
|
+
if (normalized.config && typeof normalized.config === "object") {
|
|
694
|
+
normalized.config = normalizeMonitorConfig(normalized.config);
|
|
695
|
+
if (!normalized.config) delete normalized.config;
|
|
696
|
+
}
|
|
697
|
+
if (normalized.alertConfig && typeof normalized.alertConfig === "object") {
|
|
698
|
+
normalized.alertConfig = normalizeAlertConfig(normalized.alertConfig);
|
|
699
|
+
if (!normalized.alertConfig) delete normalized.alertConfig;
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
if (type === "job") {
|
|
703
|
+
if (Array.isArray(normalized.tests)) {
|
|
704
|
+
normalized.tests = normalized.tests.map((t) => {
|
|
705
|
+
if (typeof t === "string") return t;
|
|
706
|
+
if (t && typeof t === "object" && t.id) {
|
|
707
|
+
const testType = t.type === "performance" || t.type === "k6" ? "k6" : "pw";
|
|
708
|
+
return `_supercheck_/tests/${t.id}.${testType}.ts`;
|
|
709
|
+
}
|
|
710
|
+
return t;
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
if (normalized.alertConfig && typeof normalized.alertConfig === "object") {
|
|
714
|
+
normalized.alertConfig = normalizeAlertConfig(normalized.alertConfig);
|
|
715
|
+
if (!normalized.alertConfig) delete normalized.alertConfig;
|
|
716
|
+
}
|
|
717
|
+
delete normalized.status;
|
|
718
|
+
}
|
|
719
|
+
if (type === "variable") {
|
|
720
|
+
if (normalized.value === void 0 || normalized.value === null) {
|
|
721
|
+
normalized.value = "";
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
if (type === "statusPage") {
|
|
725
|
+
if (normalized.pageDescription !== void 0 && normalized.description === void 0) {
|
|
726
|
+
normalized.description = normalized.pageDescription;
|
|
727
|
+
}
|
|
728
|
+
delete normalized.pageDescription;
|
|
729
|
+
if (!normalized.description) delete normalized.description;
|
|
730
|
+
}
|
|
731
|
+
return normalized;
|
|
732
|
+
}
|
|
646
733
|
async function fetchRemoteResources(client) {
|
|
647
734
|
const resources = [];
|
|
648
735
|
try {
|
|
@@ -653,7 +740,7 @@ async function fetchRemoteResources(client) {
|
|
|
653
740
|
logger.debug("Skipping job with missing id");
|
|
654
741
|
continue;
|
|
655
742
|
}
|
|
656
|
-
resources.push({ id, type: "job", name: String(job.name ?? ""), raw: job });
|
|
743
|
+
resources.push({ id, type: "job", name: String(job.name ?? ""), raw: normalizeRemoteRaw("job", job) });
|
|
657
744
|
}
|
|
658
745
|
} catch (err) {
|
|
659
746
|
logFetchError("jobs", err);
|
|
@@ -666,7 +753,7 @@ async function fetchRemoteResources(client) {
|
|
|
666
753
|
logger.debug("Skipping test with missing id");
|
|
667
754
|
continue;
|
|
668
755
|
}
|
|
669
|
-
resources.push({ id, type: "test", name: String(test.title ?? ""), raw: test });
|
|
756
|
+
resources.push({ id, type: "test", name: String(test.title ?? ""), raw: normalizeRemoteRaw("test", test) });
|
|
670
757
|
}
|
|
671
758
|
} catch (err) {
|
|
672
759
|
logFetchError("tests", err);
|
|
@@ -679,7 +766,7 @@ async function fetchRemoteResources(client) {
|
|
|
679
766
|
logger.debug("Skipping monitor with missing id");
|
|
680
767
|
continue;
|
|
681
768
|
}
|
|
682
|
-
resources.push({ id, type: "monitor", name: String(monitor.name ?? ""), raw: monitor });
|
|
769
|
+
resources.push({ id, type: "monitor", name: String(monitor.name ?? ""), raw: normalizeRemoteRaw("monitor", monitor) });
|
|
683
770
|
}
|
|
684
771
|
} catch (err) {
|
|
685
772
|
logFetchError("monitors", err);
|
|
@@ -692,7 +779,7 @@ async function fetchRemoteResources(client) {
|
|
|
692
779
|
logger.debug("Skipping variable with missing id");
|
|
693
780
|
continue;
|
|
694
781
|
}
|
|
695
|
-
resources.push({ id, type: "variable", name: String(v.key ?? ""), raw: v });
|
|
782
|
+
resources.push({ id, type: "variable", name: String(v.key ?? ""), raw: normalizeRemoteRaw("variable", v) });
|
|
696
783
|
}
|
|
697
784
|
} catch (err) {
|
|
698
785
|
logFetchError("variables", err);
|
|
@@ -705,7 +792,7 @@ async function fetchRemoteResources(client) {
|
|
|
705
792
|
logger.debug("Skipping tag with missing id");
|
|
706
793
|
continue;
|
|
707
794
|
}
|
|
708
|
-
resources.push({ id, type: "tag", name: String(t.name ?? ""), raw: t });
|
|
795
|
+
resources.push({ id, type: "tag", name: String(t.name ?? ""), raw: normalizeRemoteRaw("tag", t) });
|
|
709
796
|
}
|
|
710
797
|
} catch (err) {
|
|
711
798
|
logFetchError("tags", err);
|
|
@@ -718,7 +805,7 @@ async function fetchRemoteResources(client) {
|
|
|
718
805
|
logger.debug("Skipping status page with missing id");
|
|
719
806
|
continue;
|
|
720
807
|
}
|
|
721
|
-
resources.push({ id, type: "statusPage", name: String(sp.name ?? ""), raw: sp });
|
|
808
|
+
resources.push({ id, type: "statusPage", name: String(sp.name ?? ""), raw: normalizeRemoteRaw("statusPage", sp) });
|
|
722
809
|
}
|
|
723
810
|
} catch (err) {
|
|
724
811
|
logFetchError("status-pages", err);
|
|
@@ -1485,15 +1572,6 @@ Error: ${message}`,
|
|
|
1485
1572
|
{ successText: "Dependencies installed" }
|
|
1486
1573
|
);
|
|
1487
1574
|
}
|
|
1488
|
-
async function checkK6Binary() {
|
|
1489
|
-
const { execSync } = await import("child_process");
|
|
1490
|
-
try {
|
|
1491
|
-
execSync("k6 version", { stdio: "ignore" });
|
|
1492
|
-
return true;
|
|
1493
|
-
} catch {
|
|
1494
|
-
return false;
|
|
1495
|
-
}
|
|
1496
|
-
}
|
|
1497
1575
|
|
|
1498
1576
|
// src/commands/init.ts
|
|
1499
1577
|
var CONFIG_TEMPLATE = `import { defineConfig } from '@supercheck/cli'
|
|
@@ -2831,18 +2909,37 @@ var diffCommand = new Command11("diff").description("Preview changes between loc
|
|
|
2831
2909
|
// src/commands/deploy.ts
|
|
2832
2910
|
import { Command as Command12 } from "commander";
|
|
2833
2911
|
import pc4 from "picocolors";
|
|
2912
|
+
function prepareBodyForApi(type, body) {
|
|
2913
|
+
const payload = { ...body };
|
|
2914
|
+
if (type === "job") {
|
|
2915
|
+
if (Array.isArray(payload.tests)) {
|
|
2916
|
+
payload.tests = payload.tests.map((t) => {
|
|
2917
|
+
const match = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i.exec(t);
|
|
2918
|
+
return match ? match[1] : t;
|
|
2919
|
+
});
|
|
2920
|
+
}
|
|
2921
|
+
}
|
|
2922
|
+
if (type === "statusPage") {
|
|
2923
|
+
if (payload.description) {
|
|
2924
|
+
payload.pageDescription = payload.description;
|
|
2925
|
+
delete payload.description;
|
|
2926
|
+
}
|
|
2927
|
+
}
|
|
2928
|
+
return payload;
|
|
2929
|
+
}
|
|
2834
2930
|
async function applyChange(client, change) {
|
|
2835
2931
|
try {
|
|
2836
2932
|
const endpoint = getApiEndpoint(change.type);
|
|
2837
2933
|
switch (change.action) {
|
|
2838
2934
|
case "create": {
|
|
2839
|
-
const body =
|
|
2935
|
+
const body = prepareBodyForApi(change.type, change.local.definition);
|
|
2840
2936
|
await client.post(endpoint, body);
|
|
2841
2937
|
return { success: true };
|
|
2842
2938
|
}
|
|
2843
2939
|
case "update": {
|
|
2844
2940
|
const id = change.id ?? change.remote.id;
|
|
2845
|
-
const { id: _id, ...
|
|
2941
|
+
const { id: _id, ...rawBody } = change.local.definition;
|
|
2942
|
+
const body = prepareBodyForApi(change.type, rawBody);
|
|
2846
2943
|
await client.put(`${endpoint}/${id}`, body);
|
|
2847
2944
|
return { success: true };
|
|
2848
2945
|
}
|
|
@@ -3367,27 +3464,6 @@ function buildStatusPageDefinitions(pages) {
|
|
|
3367
3464
|
}
|
|
3368
3465
|
function generateConfigContent(opts) {
|
|
3369
3466
|
const parts = [];
|
|
3370
|
-
parts.push("/**");
|
|
3371
|
-
parts.push(" * Supercheck Configuration");
|
|
3372
|
-
parts.push(" * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
3373
|
-
parts.push(" *");
|
|
3374
|
-
parts.push(" * This file was generated by `supercheck pull`. It is the source of truth");
|
|
3375
|
-
parts.push(" * for your Supercheck project configuration.");
|
|
3376
|
-
parts.push(" *");
|
|
3377
|
-
parts.push(" * Getting Started:");
|
|
3378
|
-
parts.push(" * 1. Review the configuration below and make any changes you need.");
|
|
3379
|
-
parts.push(" * 2. Preview changes: supercheck diff");
|
|
3380
|
-
parts.push(" * 3. Deploy changes: supercheck deploy");
|
|
3381
|
-
parts.push(" * 4. Re-sync: supercheck pull");
|
|
3382
|
-
parts.push(" *");
|
|
3383
|
-
parts.push(" * Useful Commands:");
|
|
3384
|
-
parts.push(" * supercheck test validate Validate local test scripts");
|
|
3385
|
-
parts.push(" * supercheck config validate Validate this config file");
|
|
3386
|
-
parts.push(" * supercheck health Check API connectivity");
|
|
3387
|
-
parts.push(" * supercheck destroy Remove all managed resources from the cloud");
|
|
3388
|
-
parts.push(" *");
|
|
3389
|
-
parts.push(` * Documentation: https://supercheck.io/docs/app/welcome`);
|
|
3390
|
-
parts.push(" */");
|
|
3391
3467
|
parts.push(`import { defineConfig } from '@supercheck/cli'`);
|
|
3392
3468
|
parts.push("");
|
|
3393
3469
|
parts.push("export default defineConfig({");
|
|
@@ -3441,6 +3517,50 @@ function generateConfigContent(opts) {
|
|
|
3441
3517
|
}
|
|
3442
3518
|
parts.push("})");
|
|
3443
3519
|
parts.push("");
|
|
3520
|
+
parts.push("/**");
|
|
3521
|
+
parts.push(" * Supercheck \u2014 Getting Started");
|
|
3522
|
+
parts.push(" * \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
3523
|
+
parts.push(" *");
|
|
3524
|
+
parts.push(" * This file was generated by `supercheck pull`. It is the source of truth");
|
|
3525
|
+
parts.push(" * for your Supercheck project configuration.");
|
|
3526
|
+
parts.push(" *");
|
|
3527
|
+
parts.push(" * Getting Started:");
|
|
3528
|
+
parts.push(" * 1. Install dependencies:");
|
|
3529
|
+
parts.push(" * npm install -D @supercheck/cli typescript @types/node");
|
|
3530
|
+
parts.push(" * # If using Playwright tests, also install:");
|
|
3531
|
+
parts.push(" * npm install -D @playwright/test");
|
|
3532
|
+
parts.push(" * # If using k6 tests, install k6: https://grafana.com/docs/k6/latest/set-up/install-k6/");
|
|
3533
|
+
parts.push(" *");
|
|
3534
|
+
parts.push(" * 2. Review the configuration above and make any changes you need.");
|
|
3535
|
+
parts.push(" * 3. Preview what will change: npx supercheck diff");
|
|
3536
|
+
parts.push(" * 4. Deploy your changes: npx supercheck deploy");
|
|
3537
|
+
parts.push(" * 5. Re-sync from cloud: npx supercheck pull");
|
|
3538
|
+
parts.push(" *");
|
|
3539
|
+
parts.push(" * CLI Commands:");
|
|
3540
|
+
parts.push(" * supercheck pull Pull remote config & test scripts to local");
|
|
3541
|
+
parts.push(" * supercheck diff Compare local config vs remote");
|
|
3542
|
+
parts.push(" * supercheck deploy Deploy local config to the cloud");
|
|
3543
|
+
parts.push(" * supercheck destroy Remove all managed resources from the cloud");
|
|
3544
|
+
parts.push(" *");
|
|
3545
|
+
parts.push(" * supercheck test list List all tests");
|
|
3546
|
+
parts.push(" * supercheck test validate Validate a local test script");
|
|
3547
|
+
parts.push(" * supercheck test execute <id> Execute a test immediately");
|
|
3548
|
+
parts.push(" *");
|
|
3549
|
+
parts.push(" * supercheck monitor list List all monitors");
|
|
3550
|
+
parts.push(" * supercheck job list List all jobs");
|
|
3551
|
+
parts.push(" * supercheck job run --id <id> Run a job immediately");
|
|
3552
|
+
parts.push(" *");
|
|
3553
|
+
parts.push(" * supercheck config validate Validate this config file");
|
|
3554
|
+
parts.push(" * supercheck health Check API connectivity");
|
|
3555
|
+
parts.push(" * supercheck whoami Show current authentication info");
|
|
3556
|
+
parts.push(" *");
|
|
3557
|
+
parts.push(" * CI/CD Integration:");
|
|
3558
|
+
parts.push(" * Set the SUPERCHECK_TOKEN environment variable in your CI/CD pipeline");
|
|
3559
|
+
parts.push(" * and run `supercheck deploy` to push changes automatically.");
|
|
3560
|
+
parts.push(" *");
|
|
3561
|
+
parts.push(` * Documentation: https://supercheck.io/docs/app/welcome`);
|
|
3562
|
+
parts.push(" */");
|
|
3563
|
+
parts.push("");
|
|
3444
3564
|
return parts.join("\n");
|
|
3445
3565
|
}
|
|
3446
3566
|
function formatArray(arr, baseIndent) {
|
|
@@ -3686,41 +3806,12 @@ var pullCommand = new Command14("pull").description("Pull tests, monitors, jobs,
|
|
|
3686
3806
|
}
|
|
3687
3807
|
}
|
|
3688
3808
|
logger.newline();
|
|
3689
|
-
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
const shouldInstall = await confirmPrompt2("Install dependencies?", { default: true });
|
|
3694
|
-
if (shouldInstall) {
|
|
3695
|
-
const pm = detectPackageManager(cwd);
|
|
3696
|
-
const hasPlaywrightTests = tests.some((t) => t.type !== "performance" && t.type !== "k6");
|
|
3697
|
-
const packages = ["@supercheck/cli", "typescript", "@types/node"];
|
|
3698
|
-
if (hasPlaywrightTests) {
|
|
3699
|
-
packages.push("@playwright/test");
|
|
3700
|
-
}
|
|
3701
|
-
await installDependencies(cwd, pm, {
|
|
3702
|
-
packages,
|
|
3703
|
-
skipInstall: false
|
|
3704
|
-
});
|
|
3705
|
-
}
|
|
3706
|
-
}
|
|
3707
|
-
const hasK6Tests = tests.some((t) => t.type === "performance" || t.type === "k6");
|
|
3708
|
-
if (hasK6Tests) {
|
|
3709
|
-
const hasK6 = await checkK6Binary();
|
|
3710
|
-
if (!hasK6) {
|
|
3711
|
-
logger.warn("k6 binary not found in PATH.");
|
|
3712
|
-
logger.info("Please install k6 to run performance tests: https://grafana.com/docs/k6/latest/set-up/install-k6/");
|
|
3713
|
-
}
|
|
3714
|
-
}
|
|
3715
|
-
if (totalErrors > 0) {
|
|
3716
|
-
throw new CLIError(
|
|
3717
|
-
`Pull completed with ${totalErrors} error(s)`,
|
|
3718
|
-
1 /* GeneralError */
|
|
3719
|
-
);
|
|
3720
|
-
}
|
|
3809
|
+
logger.info("Next steps:");
|
|
3810
|
+
logger.info(" 1. Install dependencies: npm install -D @supercheck/cli typescript");
|
|
3811
|
+
logger.info(" 2. Preview changes: npx supercheck diff");
|
|
3812
|
+
logger.info(" 3. Deploy changes: npx supercheck deploy");
|
|
3721
3813
|
logger.newline();
|
|
3722
3814
|
logger.info("Tip: Review the changes, then commit to version control.");
|
|
3723
|
-
logger.info(" Run `supercheck diff` to compare local vs remote.");
|
|
3724
3815
|
logger.newline();
|
|
3725
3816
|
});
|
|
3726
3817
|
|