@wraps.dev/cli 2.11.3 → 2.11.4
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/cli.js
CHANGED
|
@@ -18,6 +18,54 @@ var init_esm_shims = __esm({
|
|
|
18
18
|
}
|
|
19
19
|
});
|
|
20
20
|
|
|
21
|
+
// src/utils/shared/ci-detection.ts
|
|
22
|
+
function isCI() {
|
|
23
|
+
if (process.env.CI === "true" || process.env.CI === "1") {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
const ciEnvVars = [
|
|
27
|
+
"GITHUB_ACTIONS",
|
|
28
|
+
// GitHub Actions
|
|
29
|
+
"GITLAB_CI",
|
|
30
|
+
// GitLab CI
|
|
31
|
+
"CIRCLECI",
|
|
32
|
+
// CircleCI
|
|
33
|
+
"TRAVIS",
|
|
34
|
+
// Travis CI
|
|
35
|
+
"JENKINS_URL",
|
|
36
|
+
// Jenkins
|
|
37
|
+
"BUILDKITE",
|
|
38
|
+
// Buildkite
|
|
39
|
+
"DRONE",
|
|
40
|
+
// Drone
|
|
41
|
+
"SEMAPHORE",
|
|
42
|
+
// Semaphore
|
|
43
|
+
"TEAMCITY_VERSION",
|
|
44
|
+
// TeamCity
|
|
45
|
+
"TF_BUILD",
|
|
46
|
+
// Azure Pipelines
|
|
47
|
+
"CODEBUILD_BUILD_ID",
|
|
48
|
+
// AWS CodeBuild
|
|
49
|
+
"NETLIFY",
|
|
50
|
+
// Netlify
|
|
51
|
+
"VERCEL",
|
|
52
|
+
// Vercel
|
|
53
|
+
"HEROKU_TEST_RUN_ID",
|
|
54
|
+
// Heroku CI
|
|
55
|
+
"BUDDY",
|
|
56
|
+
// Buddy
|
|
57
|
+
"BITBUCKET_BUILD_NUMBER"
|
|
58
|
+
// Bitbucket Pipelines
|
|
59
|
+
];
|
|
60
|
+
return ciEnvVars.some((envVar) => process.env[envVar] !== void 0);
|
|
61
|
+
}
|
|
62
|
+
var init_ci_detection = __esm({
|
|
63
|
+
"src/utils/shared/ci-detection.ts"() {
|
|
64
|
+
"use strict";
|
|
65
|
+
init_esm_shims();
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
21
69
|
// src/utils/shared/s3-state.ts
|
|
22
70
|
var s3_state_exports = {};
|
|
23
71
|
__export(s3_state_exports, {
|
|
@@ -369,414 +417,46 @@ var init_config = __esm({
|
|
|
369
417
|
}
|
|
370
418
|
});
|
|
371
419
|
|
|
372
|
-
// src/
|
|
373
|
-
import
|
|
374
|
-
import {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
}
|
|
395
|
-
function detectCredentialSource() {
|
|
396
|
-
if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {
|
|
397
|
-
return "environment";
|
|
398
|
-
}
|
|
399
|
-
if (process.env.AWS_SSO_ACCOUNT_ID || process.env.AWS_SSO_SESSION) {
|
|
400
|
-
return "sso";
|
|
401
|
-
}
|
|
402
|
-
if (process.env.AWS_PROFILE) {
|
|
403
|
-
return "profile";
|
|
404
|
-
}
|
|
405
|
-
const credentialsPath = join4(homedir2(), ".aws", "credentials");
|
|
406
|
-
if (existsSync4(credentialsPath)) {
|
|
407
|
-
const content = readFileSync(credentialsPath, "utf-8");
|
|
408
|
-
if (content.includes("[default]")) {
|
|
409
|
-
return "profile";
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
const ssoCachePath = join4(homedir2(), ".aws", "sso", "cache");
|
|
413
|
-
if (existsSync4(ssoCachePath)) {
|
|
414
|
-
return "sso";
|
|
415
|
-
}
|
|
416
|
-
if (process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI || process.env.AWS_EXECUTION_ENV) {
|
|
417
|
-
return "instance";
|
|
418
|
-
}
|
|
419
|
-
return null;
|
|
420
|
-
}
|
|
421
|
-
function detectHostingProvider() {
|
|
422
|
-
if (process.env.VERCEL || process.env.VERCEL_ENV) {
|
|
423
|
-
return "vercel";
|
|
424
|
-
}
|
|
425
|
-
if (process.env.RAILWAY_ENVIRONMENT || process.env.RAILWAY_PROJECT_ID) {
|
|
426
|
-
return "railway";
|
|
427
|
-
}
|
|
428
|
-
if (process.env.NETLIFY || process.env.NETLIFY_DEV) {
|
|
429
|
-
return "netlify";
|
|
430
|
-
}
|
|
431
|
-
if (process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.AWS_EXECUTION_ENV || process.env.ECS_CONTAINER_METADATA_URI || process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) {
|
|
432
|
-
return "aws";
|
|
433
|
-
}
|
|
434
|
-
return null;
|
|
435
|
-
}
|
|
436
|
-
async function validateCredentials() {
|
|
437
|
-
try {
|
|
438
|
-
const sts = new STSClient({ region: "us-east-1" });
|
|
439
|
-
const identity = await sts.send(new GetCallerIdentityCommand({}));
|
|
440
|
-
return identity.Account || null;
|
|
441
|
-
} catch {
|
|
442
|
-
return null;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
function getCurrentProfile() {
|
|
446
|
-
return process.env.AWS_PROFILE || "default";
|
|
447
|
-
}
|
|
448
|
-
function getCurrentRegion() {
|
|
449
|
-
if (process.env.AWS_REGION) {
|
|
450
|
-
return process.env.AWS_REGION;
|
|
451
|
-
}
|
|
452
|
-
if (process.env.AWS_DEFAULT_REGION) {
|
|
453
|
-
return process.env.AWS_DEFAULT_REGION;
|
|
454
|
-
}
|
|
455
|
-
try {
|
|
456
|
-
const region = execSync("aws configure get region", {
|
|
457
|
-
encoding: "utf-8",
|
|
458
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
459
|
-
}).trim();
|
|
460
|
-
return region || null;
|
|
461
|
-
} catch {
|
|
462
|
-
return null;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
function parseSSOProfiles() {
|
|
466
|
-
const configPath = join4(homedir2(), ".aws", "config");
|
|
467
|
-
if (!existsSync4(configPath)) {
|
|
468
|
-
return [];
|
|
469
|
-
}
|
|
470
|
-
const content = readFileSync(configPath, "utf-8");
|
|
471
|
-
const profiles = [];
|
|
472
|
-
const sessionMap = /* @__PURE__ */ new Map();
|
|
473
|
-
const sessionSections = content.split(/^\[/m).filter(Boolean);
|
|
474
|
-
for (const section of sessionSections) {
|
|
475
|
-
const lines = section.split("\n");
|
|
476
|
-
const header = lines[0]?.replace("]", "").trim();
|
|
477
|
-
if (header?.startsWith("sso-session ")) {
|
|
478
|
-
const sessionName = header.replace("sso-session ", "");
|
|
479
|
-
const config2 = {};
|
|
480
|
-
for (const line of lines.slice(1)) {
|
|
481
|
-
const match = line.match(/^\s*([^=\s]+)\s*=\s*(.+?)\s*$/);
|
|
482
|
-
if (match) {
|
|
483
|
-
config2[match[1]] = match[2];
|
|
484
|
-
}
|
|
420
|
+
// src/telemetry/config.ts
|
|
421
|
+
import Conf from "conf";
|
|
422
|
+
import { v4 as uuidv4 } from "uuid";
|
|
423
|
+
var CONFIG_DEFAULTS, TelemetryConfigManager;
|
|
424
|
+
var init_config2 = __esm({
|
|
425
|
+
"src/telemetry/config.ts"() {
|
|
426
|
+
"use strict";
|
|
427
|
+
init_esm_shims();
|
|
428
|
+
CONFIG_DEFAULTS = {
|
|
429
|
+
enabled: true,
|
|
430
|
+
anonymousId: uuidv4(),
|
|
431
|
+
notificationShown: false
|
|
432
|
+
};
|
|
433
|
+
TelemetryConfigManager = class {
|
|
434
|
+
config;
|
|
435
|
+
constructor(options) {
|
|
436
|
+
this.config = new Conf({
|
|
437
|
+
projectName: "wraps",
|
|
438
|
+
configName: "telemetry",
|
|
439
|
+
defaults: CONFIG_DEFAULTS,
|
|
440
|
+
cwd: options?.cwd
|
|
441
|
+
});
|
|
485
442
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
}
|
|
492
|
-
const sections = content.split(/^\[/m).filter(Boolean);
|
|
493
|
-
for (const section of sections) {
|
|
494
|
-
const lines = section.split("\n");
|
|
495
|
-
const header = lines[0]?.replace("]", "").trim();
|
|
496
|
-
if (!header?.startsWith("profile ") && header !== "default") {
|
|
497
|
-
continue;
|
|
498
|
-
}
|
|
499
|
-
const profileName = header === "default" ? "default" : header.replace("profile ", "");
|
|
500
|
-
const config2 = {};
|
|
501
|
-
for (const line of lines.slice(1)) {
|
|
502
|
-
const match = line.match(/^\s*([^=\s]+)\s*=\s*(.+?)\s*$/);
|
|
503
|
-
if (match) {
|
|
504
|
-
config2[match[1]] = match[2];
|
|
443
|
+
/**
|
|
444
|
+
* Check if telemetry is enabled
|
|
445
|
+
*/
|
|
446
|
+
isEnabled() {
|
|
447
|
+
return this.config.get("enabled");
|
|
505
448
|
}
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
const session = sessionMap.get(config2.sso_session);
|
|
512
|
-
if (session) {
|
|
513
|
-
ssoStartUrl = ssoStartUrl || session.startUrl;
|
|
514
|
-
ssoRegion = ssoRegion || session.region;
|
|
515
|
-
}
|
|
449
|
+
/**
|
|
450
|
+
* Enable or disable telemetry
|
|
451
|
+
*/
|
|
452
|
+
setEnabled(enabled) {
|
|
453
|
+
this.config.set("enabled", enabled);
|
|
516
454
|
}
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
ssoRoleName: config2.sso_role_name || "",
|
|
523
|
-
region: config2.region,
|
|
524
|
-
ssoSession: config2.sso_session
|
|
525
|
-
});
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
return profiles;
|
|
529
|
-
}
|
|
530
|
-
function parseSSOSessions() {
|
|
531
|
-
const configPath = join4(homedir2(), ".aws", "config");
|
|
532
|
-
if (!existsSync4(configPath)) {
|
|
533
|
-
return [];
|
|
534
|
-
}
|
|
535
|
-
const content = readFileSync(configPath, "utf-8");
|
|
536
|
-
const sessions = [];
|
|
537
|
-
const sections = content.split(/^\[/m).filter(Boolean);
|
|
538
|
-
for (const section of sections) {
|
|
539
|
-
const lines = section.split("\n");
|
|
540
|
-
const header = lines[0]?.replace("]", "").trim();
|
|
541
|
-
if (!header?.startsWith("sso-session ")) {
|
|
542
|
-
continue;
|
|
543
|
-
}
|
|
544
|
-
const sessionName = header.replace("sso-session ", "");
|
|
545
|
-
const config2 = {};
|
|
546
|
-
for (const line of lines.slice(1)) {
|
|
547
|
-
const match = line.match(/^\s*([^=\s]+)\s*=\s*(.+?)\s*$/);
|
|
548
|
-
if (match) {
|
|
549
|
-
config2[match[1]] = match[2];
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
sessions.push({
|
|
553
|
-
name: sessionName,
|
|
554
|
-
ssoStartUrl: config2.sso_start_url || "",
|
|
555
|
-
ssoRegion: config2.sso_region || "",
|
|
556
|
-
ssoRegistrationScopes: config2.sso_registration_scopes?.split(",").map((s) => s.trim())
|
|
557
|
-
});
|
|
558
|
-
}
|
|
559
|
-
return sessions;
|
|
560
|
-
}
|
|
561
|
-
function checkSSOTokenStatus(startUrl) {
|
|
562
|
-
const ssoCachePath = join4(homedir2(), ".aws", "sso", "cache");
|
|
563
|
-
if (!existsSync4(ssoCachePath)) {
|
|
564
|
-
return {
|
|
565
|
-
valid: false,
|
|
566
|
-
expiresAt: null,
|
|
567
|
-
expired: true,
|
|
568
|
-
minutesRemaining: null,
|
|
569
|
-
startUrl: null
|
|
570
|
-
};
|
|
571
|
-
}
|
|
572
|
-
try {
|
|
573
|
-
const cacheFiles = readdirSync(ssoCachePath).filter(
|
|
574
|
-
(f) => f.endsWith(".json")
|
|
575
|
-
);
|
|
576
|
-
for (const file of cacheFiles) {
|
|
577
|
-
const content = readFileSync(join4(ssoCachePath, file), "utf-8");
|
|
578
|
-
const token = JSON.parse(content);
|
|
579
|
-
if (!(token.accessToken && token.expiresAt)) {
|
|
580
|
-
continue;
|
|
581
|
-
}
|
|
582
|
-
if (startUrl && token.startUrl !== startUrl) {
|
|
583
|
-
continue;
|
|
584
|
-
}
|
|
585
|
-
const expiresAt = new Date(token.expiresAt);
|
|
586
|
-
const now = /* @__PURE__ */ new Date();
|
|
587
|
-
const expired = expiresAt <= now;
|
|
588
|
-
const minutesRemaining = Math.floor(
|
|
589
|
-
(expiresAt.getTime() - now.getTime()) / 6e4
|
|
590
|
-
);
|
|
591
|
-
return {
|
|
592
|
-
valid: !expired,
|
|
593
|
-
expiresAt,
|
|
594
|
-
expired,
|
|
595
|
-
minutesRemaining,
|
|
596
|
-
startUrl: token.startUrl || null
|
|
597
|
-
};
|
|
598
|
-
}
|
|
599
|
-
} catch {
|
|
600
|
-
}
|
|
601
|
-
return {
|
|
602
|
-
valid: false,
|
|
603
|
-
expiresAt: null,
|
|
604
|
-
expired: true,
|
|
605
|
-
minutesRemaining: null,
|
|
606
|
-
startUrl: null
|
|
607
|
-
};
|
|
608
|
-
}
|
|
609
|
-
function getActiveSSOProfile(profiles) {
|
|
610
|
-
const currentProfile = process.env.AWS_PROFILE || "default";
|
|
611
|
-
return profiles.find((p) => p.name === currentProfile) || null;
|
|
612
|
-
}
|
|
613
|
-
function getSSOLoginCommand(profile) {
|
|
614
|
-
if (profile && profile !== "default") {
|
|
615
|
-
return `aws sso login --profile ${profile}`;
|
|
616
|
-
}
|
|
617
|
-
return "aws sso login";
|
|
618
|
-
}
|
|
619
|
-
function formatSSOProfile(profile) {
|
|
620
|
-
return `${profile.name} (${profile.ssoAccountId} / ${profile.ssoRoleName})`;
|
|
621
|
-
}
|
|
622
|
-
async function detectAWSState() {
|
|
623
|
-
const [cliInstalled, cliVersion, accountId] = await Promise.all([
|
|
624
|
-
isAWSCLIInstalled(),
|
|
625
|
-
getAWSCLIVersion(),
|
|
626
|
-
validateCredentials()
|
|
627
|
-
]);
|
|
628
|
-
const credentialSource = detectCredentialSource();
|
|
629
|
-
const detectedProvider = detectHostingProvider();
|
|
630
|
-
const region = getCurrentRegion();
|
|
631
|
-
const profileName = getCurrentProfile();
|
|
632
|
-
const ssoProfiles = parseSSOProfiles();
|
|
633
|
-
const ssoSessions = parseSSOSessions();
|
|
634
|
-
const activeProfile = getActiveSSOProfile(ssoProfiles);
|
|
635
|
-
const tokenStatus = ssoProfiles.length > 0 ? checkSSOTokenStatus(activeProfile?.ssoStartUrl) : null;
|
|
636
|
-
const isUsingSSO = credentialSource === "sso" || activeProfile !== null && accountId !== null;
|
|
637
|
-
return {
|
|
638
|
-
cliInstalled,
|
|
639
|
-
cliVersion,
|
|
640
|
-
credentialsConfigured: accountId !== null,
|
|
641
|
-
credentialSource: isUsingSSO ? "sso" : accountId !== null ? credentialSource : null,
|
|
642
|
-
profileName,
|
|
643
|
-
accountId,
|
|
644
|
-
detectedProvider,
|
|
645
|
-
region,
|
|
646
|
-
sso: {
|
|
647
|
-
configured: ssoProfiles.length > 0,
|
|
648
|
-
profiles: ssoProfiles,
|
|
649
|
-
sessions: ssoSessions,
|
|
650
|
-
tokenStatus,
|
|
651
|
-
activeProfile: isUsingSSO ? activeProfile : null
|
|
652
|
-
}
|
|
653
|
-
};
|
|
654
|
-
}
|
|
655
|
-
function hasCredentialsFile() {
|
|
656
|
-
const credentialsPath = join4(homedir2(), ".aws", "credentials");
|
|
657
|
-
return existsSync4(credentialsPath);
|
|
658
|
-
}
|
|
659
|
-
function hasConfigFile() {
|
|
660
|
-
const configPath = join4(homedir2(), ".aws", "config");
|
|
661
|
-
return existsSync4(configPath);
|
|
662
|
-
}
|
|
663
|
-
function getConfiguredProfiles() {
|
|
664
|
-
const profiles = [];
|
|
665
|
-
const credentialsPath = join4(homedir2(), ".aws", "credentials");
|
|
666
|
-
if (existsSync4(credentialsPath)) {
|
|
667
|
-
const content = readFileSync(credentialsPath, "utf-8");
|
|
668
|
-
const matches = content.matchAll(/\[([^\]]+)\]/g);
|
|
669
|
-
for (const match of matches) {
|
|
670
|
-
profiles.push(match[1]);
|
|
671
|
-
}
|
|
672
|
-
}
|
|
673
|
-
const configPath = join4(homedir2(), ".aws", "config");
|
|
674
|
-
if (existsSync4(configPath)) {
|
|
675
|
-
const content = readFileSync(configPath, "utf-8");
|
|
676
|
-
const matches = content.matchAll(/\[profile ([^\]]+)\]/g);
|
|
677
|
-
for (const match of matches) {
|
|
678
|
-
if (!profiles.includes(match[1])) {
|
|
679
|
-
profiles.push(match[1]);
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
return profiles;
|
|
684
|
-
}
|
|
685
|
-
var init_aws_detection = __esm({
|
|
686
|
-
"src/utils/shared/aws-detection.ts"() {
|
|
687
|
-
"use strict";
|
|
688
|
-
init_esm_shims();
|
|
689
|
-
}
|
|
690
|
-
});
|
|
691
|
-
|
|
692
|
-
// src/utils/shared/ci-detection.ts
|
|
693
|
-
function isCI() {
|
|
694
|
-
if (process.env.CI === "true" || process.env.CI === "1") {
|
|
695
|
-
return true;
|
|
696
|
-
}
|
|
697
|
-
const ciEnvVars = [
|
|
698
|
-
"GITHUB_ACTIONS",
|
|
699
|
-
// GitHub Actions
|
|
700
|
-
"GITLAB_CI",
|
|
701
|
-
// GitLab CI
|
|
702
|
-
"CIRCLECI",
|
|
703
|
-
// CircleCI
|
|
704
|
-
"TRAVIS",
|
|
705
|
-
// Travis CI
|
|
706
|
-
"JENKINS_URL",
|
|
707
|
-
// Jenkins
|
|
708
|
-
"BUILDKITE",
|
|
709
|
-
// Buildkite
|
|
710
|
-
"DRONE",
|
|
711
|
-
// Drone
|
|
712
|
-
"SEMAPHORE",
|
|
713
|
-
// Semaphore
|
|
714
|
-
"TEAMCITY_VERSION",
|
|
715
|
-
// TeamCity
|
|
716
|
-
"TF_BUILD",
|
|
717
|
-
// Azure Pipelines
|
|
718
|
-
"CODEBUILD_BUILD_ID",
|
|
719
|
-
// AWS CodeBuild
|
|
720
|
-
"NETLIFY",
|
|
721
|
-
// Netlify
|
|
722
|
-
"VERCEL",
|
|
723
|
-
// Vercel
|
|
724
|
-
"HEROKU_TEST_RUN_ID",
|
|
725
|
-
// Heroku CI
|
|
726
|
-
"BUDDY",
|
|
727
|
-
// Buddy
|
|
728
|
-
"BITBUCKET_BUILD_NUMBER"
|
|
729
|
-
// Bitbucket Pipelines
|
|
730
|
-
];
|
|
731
|
-
return ciEnvVars.some((envVar) => process.env[envVar] !== void 0);
|
|
732
|
-
}
|
|
733
|
-
var init_ci_detection = __esm({
|
|
734
|
-
"src/utils/shared/ci-detection.ts"() {
|
|
735
|
-
"use strict";
|
|
736
|
-
init_esm_shims();
|
|
737
|
-
}
|
|
738
|
-
});
|
|
739
|
-
|
|
740
|
-
// src/telemetry/config.ts
|
|
741
|
-
import Conf from "conf";
|
|
742
|
-
import { v4 as uuidv4 } from "uuid";
|
|
743
|
-
var CONFIG_DEFAULTS, TelemetryConfigManager;
|
|
744
|
-
var init_config2 = __esm({
|
|
745
|
-
"src/telemetry/config.ts"() {
|
|
746
|
-
"use strict";
|
|
747
|
-
init_esm_shims();
|
|
748
|
-
CONFIG_DEFAULTS = {
|
|
749
|
-
enabled: true,
|
|
750
|
-
anonymousId: uuidv4(),
|
|
751
|
-
notificationShown: false
|
|
752
|
-
};
|
|
753
|
-
TelemetryConfigManager = class {
|
|
754
|
-
config;
|
|
755
|
-
constructor(options) {
|
|
756
|
-
this.config = new Conf({
|
|
757
|
-
projectName: "wraps",
|
|
758
|
-
configName: "telemetry",
|
|
759
|
-
defaults: CONFIG_DEFAULTS,
|
|
760
|
-
cwd: options?.cwd
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
/**
|
|
764
|
-
* Check if telemetry is enabled
|
|
765
|
-
*/
|
|
766
|
-
isEnabled() {
|
|
767
|
-
return this.config.get("enabled");
|
|
768
|
-
}
|
|
769
|
-
/**
|
|
770
|
-
* Enable or disable telemetry
|
|
771
|
-
*/
|
|
772
|
-
setEnabled(enabled) {
|
|
773
|
-
this.config.set("enabled", enabled);
|
|
774
|
-
}
|
|
775
|
-
/**
|
|
776
|
-
* Get the anonymous user ID
|
|
777
|
-
*/
|
|
778
|
-
getAnonymousId() {
|
|
779
|
-
return this.config.get("anonymousId");
|
|
455
|
+
/**
|
|
456
|
+
* Get the anonymous user ID
|
|
457
|
+
*/
|
|
458
|
+
getAnonymousId() {
|
|
459
|
+
return this.config.get("anonymousId");
|
|
780
460
|
}
|
|
781
461
|
/**
|
|
782
462
|
* Check if the first-run notification has been shown
|
|
@@ -811,10 +491,10 @@ var init_config2 = __esm({
|
|
|
811
491
|
});
|
|
812
492
|
|
|
813
493
|
// src/telemetry/client.ts
|
|
814
|
-
import { readFileSync
|
|
815
|
-
import { dirname, join as
|
|
494
|
+
import { readFileSync } from "fs";
|
|
495
|
+
import { dirname, join as join4 } from "path";
|
|
816
496
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
817
|
-
import
|
|
497
|
+
import pc from "picocolors";
|
|
818
498
|
function getTelemetryClient() {
|
|
819
499
|
if (!telemetryInstance) {
|
|
820
500
|
telemetryInstance = new TelemetryClient();
|
|
@@ -1043,12 +723,12 @@ var init_client = __esm({
|
|
|
1043
723
|
}
|
|
1044
724
|
this.hasShownFooter = true;
|
|
1045
725
|
console.log();
|
|
1046
|
-
console.log(
|
|
726
|
+
console.log(pc.dim("\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"));
|
|
1047
727
|
console.log("\u{1F4CA} Wraps Platform \u2014 analytics, templates, automations");
|
|
1048
|
-
console.log(` From $10/mo \u2192 ${
|
|
728
|
+
console.log(` From $10/mo \u2192 ${pc.cyan("https://wraps.dev/platform")}`);
|
|
1049
729
|
console.log();
|
|
1050
|
-
console.log(`\u{1F4AC} ${
|
|
1051
|
-
console.log(
|
|
730
|
+
console.log(`\u{1F4AC} ${pc.cyan("hey@wraps.sh")}`);
|
|
731
|
+
console.log(pc.dim("\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"));
|
|
1052
732
|
return true;
|
|
1053
733
|
}
|
|
1054
734
|
/**
|
|
@@ -1059,7 +739,7 @@ var init_client = __esm({
|
|
|
1059
739
|
const __filename3 = fileURLToPath2(import.meta.url);
|
|
1060
740
|
const __dirname4 = dirname(__filename3);
|
|
1061
741
|
const pkg = JSON.parse(
|
|
1062
|
-
|
|
742
|
+
readFileSync(join4(__dirname4, "../package.json"), "utf-8")
|
|
1063
743
|
);
|
|
1064
744
|
return pkg.version;
|
|
1065
745
|
} catch {
|
|
@@ -1067,65 +747,385 @@ var init_client = __esm({
|
|
|
1067
747
|
}
|
|
1068
748
|
}
|
|
1069
749
|
};
|
|
1070
|
-
telemetryInstance = null;
|
|
750
|
+
telemetryInstance = null;
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
|
|
754
|
+
// src/telemetry/events.ts
|
|
755
|
+
function trackCommand(command, metadata) {
|
|
756
|
+
const client = getTelemetryClient();
|
|
757
|
+
const sanitized = metadata ? { ...metadata } : {};
|
|
758
|
+
sanitized.domain = void 0;
|
|
759
|
+
sanitized.accountId = void 0;
|
|
760
|
+
sanitized.email = void 0;
|
|
761
|
+
client.track(`command:${command}`, sanitized);
|
|
762
|
+
}
|
|
763
|
+
function trackServiceInit(service, success, metadata) {
|
|
764
|
+
const client = getTelemetryClient();
|
|
765
|
+
client.track("service:init", {
|
|
766
|
+
service,
|
|
767
|
+
success,
|
|
768
|
+
...metadata
|
|
769
|
+
});
|
|
770
|
+
}
|
|
771
|
+
function trackServiceDeployed(service, metadata) {
|
|
772
|
+
const client = getTelemetryClient();
|
|
773
|
+
client.track("service:deployed", {
|
|
774
|
+
service,
|
|
775
|
+
...metadata
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
function trackError(errorCode, command, metadata) {
|
|
779
|
+
const client = getTelemetryClient();
|
|
780
|
+
client.track("error:occurred", {
|
|
781
|
+
error_code: errorCode,
|
|
782
|
+
command,
|
|
783
|
+
...metadata
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
function trackFeature(feature, metadata) {
|
|
787
|
+
const client = getTelemetryClient();
|
|
788
|
+
client.track(`feature:${feature}`, metadata || {});
|
|
789
|
+
}
|
|
790
|
+
function trackServiceUpgrade(service, metadata) {
|
|
791
|
+
const client = getTelemetryClient();
|
|
792
|
+
client.track("service:upgraded", {
|
|
793
|
+
service,
|
|
794
|
+
...metadata
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
function trackServiceRemoved(service, metadata) {
|
|
798
|
+
const client = getTelemetryClient();
|
|
799
|
+
client.track("service:removed", {
|
|
800
|
+
service,
|
|
801
|
+
...metadata
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
var init_events = __esm({
|
|
805
|
+
"src/telemetry/events.ts"() {
|
|
806
|
+
"use strict";
|
|
807
|
+
init_esm_shims();
|
|
808
|
+
init_client();
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
|
|
812
|
+
// src/utils/shared/aws-detection.ts
|
|
813
|
+
import { execSync } from "child_process";
|
|
814
|
+
import { existsSync as existsSync4, readdirSync, readFileSync as readFileSync2 } from "fs";
|
|
815
|
+
import { homedir as homedir2 } from "os";
|
|
816
|
+
import { join as join5 } from "path";
|
|
817
|
+
import { GetCallerIdentityCommand, STSClient } from "@aws-sdk/client-sts";
|
|
818
|
+
async function isAWSCLIInstalled() {
|
|
819
|
+
try {
|
|
820
|
+
execSync("aws --version", { stdio: "pipe" });
|
|
821
|
+
return true;
|
|
822
|
+
} catch {
|
|
823
|
+
return false;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
async function getAWSCLIVersion() {
|
|
827
|
+
try {
|
|
828
|
+
const output4 = execSync("aws --version", { encoding: "utf-8" });
|
|
829
|
+
const match = output4.match(/aws-cli\/(\d+\.\d+\.\d+)/);
|
|
830
|
+
return match ? match[1] : null;
|
|
831
|
+
} catch {
|
|
832
|
+
return null;
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
function detectCredentialSource() {
|
|
836
|
+
if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {
|
|
837
|
+
return "environment";
|
|
838
|
+
}
|
|
839
|
+
if (process.env.AWS_SSO_ACCOUNT_ID || process.env.AWS_SSO_SESSION) {
|
|
840
|
+
return "sso";
|
|
841
|
+
}
|
|
842
|
+
if (process.env.AWS_PROFILE) {
|
|
843
|
+
return "profile";
|
|
844
|
+
}
|
|
845
|
+
const credentialsPath = join5(homedir2(), ".aws", "credentials");
|
|
846
|
+
if (existsSync4(credentialsPath)) {
|
|
847
|
+
const content = readFileSync2(credentialsPath, "utf-8");
|
|
848
|
+
if (content.includes("[default]")) {
|
|
849
|
+
return "profile";
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
const ssoCachePath = join5(homedir2(), ".aws", "sso", "cache");
|
|
853
|
+
if (existsSync4(ssoCachePath)) {
|
|
854
|
+
return "sso";
|
|
855
|
+
}
|
|
856
|
+
if (process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI || process.env.AWS_EXECUTION_ENV) {
|
|
857
|
+
return "instance";
|
|
858
|
+
}
|
|
859
|
+
return null;
|
|
860
|
+
}
|
|
861
|
+
function detectHostingProvider() {
|
|
862
|
+
if (process.env.VERCEL || process.env.VERCEL_ENV) {
|
|
863
|
+
return "vercel";
|
|
864
|
+
}
|
|
865
|
+
if (process.env.RAILWAY_ENVIRONMENT || process.env.RAILWAY_PROJECT_ID) {
|
|
866
|
+
return "railway";
|
|
867
|
+
}
|
|
868
|
+
if (process.env.NETLIFY || process.env.NETLIFY_DEV) {
|
|
869
|
+
return "netlify";
|
|
870
|
+
}
|
|
871
|
+
if (process.env.AWS_LAMBDA_FUNCTION_NAME || process.env.AWS_EXECUTION_ENV || process.env.ECS_CONTAINER_METADATA_URI || process.env.AWS_CONTAINER_CREDENTIALS_RELATIVE_URI) {
|
|
872
|
+
return "aws";
|
|
873
|
+
}
|
|
874
|
+
return null;
|
|
875
|
+
}
|
|
876
|
+
async function validateCredentials() {
|
|
877
|
+
try {
|
|
878
|
+
const sts = new STSClient({ region: "us-east-1" });
|
|
879
|
+
const identity = await sts.send(new GetCallerIdentityCommand({}));
|
|
880
|
+
return identity.Account || null;
|
|
881
|
+
} catch {
|
|
882
|
+
return null;
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
function getCurrentProfile() {
|
|
886
|
+
return process.env.AWS_PROFILE || "default";
|
|
887
|
+
}
|
|
888
|
+
function getCurrentRegion() {
|
|
889
|
+
if (process.env.AWS_REGION) {
|
|
890
|
+
return process.env.AWS_REGION;
|
|
891
|
+
}
|
|
892
|
+
if (process.env.AWS_DEFAULT_REGION) {
|
|
893
|
+
return process.env.AWS_DEFAULT_REGION;
|
|
894
|
+
}
|
|
895
|
+
try {
|
|
896
|
+
const region = execSync("aws configure get region", {
|
|
897
|
+
encoding: "utf-8",
|
|
898
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
899
|
+
}).trim();
|
|
900
|
+
return region || null;
|
|
901
|
+
} catch {
|
|
902
|
+
return null;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
function parseSSOProfiles() {
|
|
906
|
+
const configPath = join5(homedir2(), ".aws", "config");
|
|
907
|
+
if (!existsSync4(configPath)) {
|
|
908
|
+
return [];
|
|
909
|
+
}
|
|
910
|
+
const content = readFileSync2(configPath, "utf-8");
|
|
911
|
+
const profiles = [];
|
|
912
|
+
const sessionMap = /* @__PURE__ */ new Map();
|
|
913
|
+
const sessionSections = content.split(/^\[/m).filter(Boolean);
|
|
914
|
+
for (const section of sessionSections) {
|
|
915
|
+
const lines = section.split("\n");
|
|
916
|
+
const header = lines[0]?.replace("]", "").trim();
|
|
917
|
+
if (header?.startsWith("sso-session ")) {
|
|
918
|
+
const sessionName = header.replace("sso-session ", "");
|
|
919
|
+
const config2 = {};
|
|
920
|
+
for (const line of lines.slice(1)) {
|
|
921
|
+
const match = line.match(/^\s*([^=\s]+)\s*=\s*(.+?)\s*$/);
|
|
922
|
+
if (match) {
|
|
923
|
+
config2[match[1]] = match[2];
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
sessionMap.set(sessionName, {
|
|
927
|
+
startUrl: config2.sso_start_url || "",
|
|
928
|
+
region: config2.sso_region || ""
|
|
929
|
+
});
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
const sections = content.split(/^\[/m).filter(Boolean);
|
|
933
|
+
for (const section of sections) {
|
|
934
|
+
const lines = section.split("\n");
|
|
935
|
+
const header = lines[0]?.replace("]", "").trim();
|
|
936
|
+
if (!header?.startsWith("profile ") && header !== "default") {
|
|
937
|
+
continue;
|
|
938
|
+
}
|
|
939
|
+
const profileName = header === "default" ? "default" : header.replace("profile ", "");
|
|
940
|
+
const config2 = {};
|
|
941
|
+
for (const line of lines.slice(1)) {
|
|
942
|
+
const match = line.match(/^\s*([^=\s]+)\s*=\s*(.+?)\s*$/);
|
|
943
|
+
if (match) {
|
|
944
|
+
config2[match[1]] = match[2];
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
if (config2.sso_start_url || config2.sso_session) {
|
|
948
|
+
let ssoStartUrl = config2.sso_start_url || "";
|
|
949
|
+
let ssoRegion = config2.sso_region || "";
|
|
950
|
+
if (config2.sso_session) {
|
|
951
|
+
const session = sessionMap.get(config2.sso_session);
|
|
952
|
+
if (session) {
|
|
953
|
+
ssoStartUrl = ssoStartUrl || session.startUrl;
|
|
954
|
+
ssoRegion = ssoRegion || session.region;
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
profiles.push({
|
|
958
|
+
name: profileName,
|
|
959
|
+
ssoStartUrl,
|
|
960
|
+
ssoRegion,
|
|
961
|
+
ssoAccountId: config2.sso_account_id || "",
|
|
962
|
+
ssoRoleName: config2.sso_role_name || "",
|
|
963
|
+
region: config2.region,
|
|
964
|
+
ssoSession: config2.sso_session
|
|
965
|
+
});
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
return profiles;
|
|
969
|
+
}
|
|
970
|
+
function parseSSOSessions() {
|
|
971
|
+
const configPath = join5(homedir2(), ".aws", "config");
|
|
972
|
+
if (!existsSync4(configPath)) {
|
|
973
|
+
return [];
|
|
974
|
+
}
|
|
975
|
+
const content = readFileSync2(configPath, "utf-8");
|
|
976
|
+
const sessions = [];
|
|
977
|
+
const sections = content.split(/^\[/m).filter(Boolean);
|
|
978
|
+
for (const section of sections) {
|
|
979
|
+
const lines = section.split("\n");
|
|
980
|
+
const header = lines[0]?.replace("]", "").trim();
|
|
981
|
+
if (!header?.startsWith("sso-session ")) {
|
|
982
|
+
continue;
|
|
983
|
+
}
|
|
984
|
+
const sessionName = header.replace("sso-session ", "");
|
|
985
|
+
const config2 = {};
|
|
986
|
+
for (const line of lines.slice(1)) {
|
|
987
|
+
const match = line.match(/^\s*([^=\s]+)\s*=\s*(.+?)\s*$/);
|
|
988
|
+
if (match) {
|
|
989
|
+
config2[match[1]] = match[2];
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
sessions.push({
|
|
993
|
+
name: sessionName,
|
|
994
|
+
ssoStartUrl: config2.sso_start_url || "",
|
|
995
|
+
ssoRegion: config2.sso_region || "",
|
|
996
|
+
ssoRegistrationScopes: config2.sso_registration_scopes?.split(",").map((s) => s.trim())
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
return sessions;
|
|
1000
|
+
}
|
|
1001
|
+
function checkSSOTokenStatus(startUrl) {
|
|
1002
|
+
const ssoCachePath = join5(homedir2(), ".aws", "sso", "cache");
|
|
1003
|
+
if (!existsSync4(ssoCachePath)) {
|
|
1004
|
+
return {
|
|
1005
|
+
valid: false,
|
|
1006
|
+
expiresAt: null,
|
|
1007
|
+
expired: true,
|
|
1008
|
+
minutesRemaining: null,
|
|
1009
|
+
startUrl: null
|
|
1010
|
+
};
|
|
1071
1011
|
}
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1012
|
+
try {
|
|
1013
|
+
const cacheFiles = readdirSync(ssoCachePath).filter(
|
|
1014
|
+
(f) => f.endsWith(".json")
|
|
1015
|
+
);
|
|
1016
|
+
for (const file of cacheFiles) {
|
|
1017
|
+
const content = readFileSync2(join5(ssoCachePath, file), "utf-8");
|
|
1018
|
+
const token = JSON.parse(content);
|
|
1019
|
+
if (!(token.accessToken && token.expiresAt)) {
|
|
1020
|
+
continue;
|
|
1021
|
+
}
|
|
1022
|
+
if (startUrl && token.startUrl !== startUrl) {
|
|
1023
|
+
continue;
|
|
1024
|
+
}
|
|
1025
|
+
const expiresAt = new Date(token.expiresAt);
|
|
1026
|
+
const now = /* @__PURE__ */ new Date();
|
|
1027
|
+
const expired = expiresAt <= now;
|
|
1028
|
+
const minutesRemaining = Math.floor(
|
|
1029
|
+
(expiresAt.getTime() - now.getTime()) / 6e4
|
|
1030
|
+
);
|
|
1031
|
+
return {
|
|
1032
|
+
valid: !expired,
|
|
1033
|
+
expiresAt,
|
|
1034
|
+
expired,
|
|
1035
|
+
minutesRemaining,
|
|
1036
|
+
startUrl: token.startUrl || null
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
} catch {
|
|
1040
|
+
}
|
|
1041
|
+
return {
|
|
1042
|
+
valid: false,
|
|
1043
|
+
expiresAt: null,
|
|
1044
|
+
expired: true,
|
|
1045
|
+
minutesRemaining: null,
|
|
1046
|
+
startUrl: null
|
|
1047
|
+
};
|
|
1082
1048
|
}
|
|
1083
|
-
function
|
|
1084
|
-
const
|
|
1085
|
-
|
|
1086
|
-
service,
|
|
1087
|
-
success,
|
|
1088
|
-
...metadata
|
|
1089
|
-
});
|
|
1049
|
+
function getActiveSSOProfile(profiles) {
|
|
1050
|
+
const currentProfile = process.env.AWS_PROFILE || "default";
|
|
1051
|
+
return profiles.find((p) => p.name === currentProfile) || null;
|
|
1090
1052
|
}
|
|
1091
|
-
function
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
});
|
|
1053
|
+
function getSSOLoginCommand(profile) {
|
|
1054
|
+
if (profile && profile !== "default") {
|
|
1055
|
+
return `aws sso login --profile ${profile}`;
|
|
1056
|
+
}
|
|
1057
|
+
return "aws sso login";
|
|
1097
1058
|
}
|
|
1098
|
-
function
|
|
1099
|
-
|
|
1100
|
-
client.track("error:occurred", {
|
|
1101
|
-
error_code: errorCode,
|
|
1102
|
-
command,
|
|
1103
|
-
...metadata
|
|
1104
|
-
});
|
|
1059
|
+
function formatSSOProfile(profile) {
|
|
1060
|
+
return `${profile.name} (${profile.ssoAccountId} / ${profile.ssoRoleName})`;
|
|
1105
1061
|
}
|
|
1106
|
-
function
|
|
1107
|
-
const
|
|
1108
|
-
|
|
1062
|
+
async function detectAWSState() {
|
|
1063
|
+
const [cliInstalled, cliVersion, accountId] = await Promise.all([
|
|
1064
|
+
isAWSCLIInstalled(),
|
|
1065
|
+
getAWSCLIVersion(),
|
|
1066
|
+
validateCredentials()
|
|
1067
|
+
]);
|
|
1068
|
+
const credentialSource = detectCredentialSource();
|
|
1069
|
+
const detectedProvider = detectHostingProvider();
|
|
1070
|
+
const region = getCurrentRegion();
|
|
1071
|
+
const profileName = getCurrentProfile();
|
|
1072
|
+
const ssoProfiles = parseSSOProfiles();
|
|
1073
|
+
const ssoSessions = parseSSOSessions();
|
|
1074
|
+
const activeProfile = getActiveSSOProfile(ssoProfiles);
|
|
1075
|
+
const tokenStatus = ssoProfiles.length > 0 ? checkSSOTokenStatus(activeProfile?.ssoStartUrl) : null;
|
|
1076
|
+
const isUsingSSO = credentialSource === "sso" || activeProfile !== null && accountId !== null;
|
|
1077
|
+
return {
|
|
1078
|
+
cliInstalled,
|
|
1079
|
+
cliVersion,
|
|
1080
|
+
credentialsConfigured: accountId !== null,
|
|
1081
|
+
credentialSource: isUsingSSO ? "sso" : accountId !== null ? credentialSource : null,
|
|
1082
|
+
profileName,
|
|
1083
|
+
accountId,
|
|
1084
|
+
detectedProvider,
|
|
1085
|
+
region,
|
|
1086
|
+
sso: {
|
|
1087
|
+
configured: ssoProfiles.length > 0,
|
|
1088
|
+
profiles: ssoProfiles,
|
|
1089
|
+
sessions: ssoSessions,
|
|
1090
|
+
tokenStatus,
|
|
1091
|
+
activeProfile: isUsingSSO ? activeProfile : null
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1109
1094
|
}
|
|
1110
|
-
function
|
|
1111
|
-
const
|
|
1112
|
-
|
|
1113
|
-
service,
|
|
1114
|
-
...metadata
|
|
1115
|
-
});
|
|
1095
|
+
function hasCredentialsFile() {
|
|
1096
|
+
const credentialsPath = join5(homedir2(), ".aws", "credentials");
|
|
1097
|
+
return existsSync4(credentialsPath);
|
|
1116
1098
|
}
|
|
1117
|
-
function
|
|
1118
|
-
const
|
|
1119
|
-
|
|
1120
|
-
service,
|
|
1121
|
-
...metadata
|
|
1122
|
-
});
|
|
1099
|
+
function hasConfigFile() {
|
|
1100
|
+
const configPath = join5(homedir2(), ".aws", "config");
|
|
1101
|
+
return existsSync4(configPath);
|
|
1123
1102
|
}
|
|
1124
|
-
|
|
1125
|
-
|
|
1103
|
+
function getConfiguredProfiles() {
|
|
1104
|
+
const profiles = [];
|
|
1105
|
+
const credentialsPath = join5(homedir2(), ".aws", "credentials");
|
|
1106
|
+
if (existsSync4(credentialsPath)) {
|
|
1107
|
+
const content = readFileSync2(credentialsPath, "utf-8");
|
|
1108
|
+
const matches = content.matchAll(/\[([^\]]+)\]/g);
|
|
1109
|
+
for (const match of matches) {
|
|
1110
|
+
profiles.push(match[1]);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
const configPath = join5(homedir2(), ".aws", "config");
|
|
1114
|
+
if (existsSync4(configPath)) {
|
|
1115
|
+
const content = readFileSync2(configPath, "utf-8");
|
|
1116
|
+
const matches = content.matchAll(/\[profile ([^\]]+)\]/g);
|
|
1117
|
+
for (const match of matches) {
|
|
1118
|
+
if (!profiles.includes(match[1])) {
|
|
1119
|
+
profiles.push(match[1]);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
return profiles;
|
|
1124
|
+
}
|
|
1125
|
+
var init_aws_detection = __esm({
|
|
1126
|
+
"src/utils/shared/aws-detection.ts"() {
|
|
1126
1127
|
"use strict";
|
|
1127
1128
|
init_esm_shims();
|
|
1128
|
-
init_client();
|
|
1129
1129
|
}
|
|
1130
1130
|
});
|
|
1131
1131
|
|
|
@@ -7269,6 +7269,7 @@ import pc49 from "picocolors";
|
|
|
7269
7269
|
|
|
7270
7270
|
// src/commands/auth/login.ts
|
|
7271
7271
|
init_esm_shims();
|
|
7272
|
+
init_events();
|
|
7272
7273
|
init_config();
|
|
7273
7274
|
import * as clack from "@clack/prompts";
|
|
7274
7275
|
import { createAuthClient } from "better-auth/client";
|
|
@@ -7277,7 +7278,7 @@ import {
|
|
|
7277
7278
|
organizationClient
|
|
7278
7279
|
} from "better-auth/client/plugins";
|
|
7279
7280
|
import open from "open";
|
|
7280
|
-
import
|
|
7281
|
+
import pc2 from "picocolors";
|
|
7281
7282
|
function createCliAuthClient(baseURL) {
|
|
7282
7283
|
return createAuthClient({
|
|
7283
7284
|
baseURL,
|
|
@@ -7305,6 +7306,7 @@ async function fetchOrganizations(baseURL, token) {
|
|
|
7305
7306
|
}
|
|
7306
7307
|
}
|
|
7307
7308
|
async function login(options) {
|
|
7309
|
+
const startTime = Date.now();
|
|
7308
7310
|
if (options.token) {
|
|
7309
7311
|
await saveAuthConfig({
|
|
7310
7312
|
auth: {
|
|
@@ -7312,6 +7314,11 @@ async function login(options) {
|
|
|
7312
7314
|
tokenType: "api-key"
|
|
7313
7315
|
}
|
|
7314
7316
|
});
|
|
7317
|
+
trackCommand("auth:login", {
|
|
7318
|
+
success: true,
|
|
7319
|
+
duration_ms: Date.now() - startTime,
|
|
7320
|
+
method: "api-key"
|
|
7321
|
+
});
|
|
7315
7322
|
if (options.json) {
|
|
7316
7323
|
console.log(JSON.stringify({ success: true, tokenType: "api-key" }));
|
|
7317
7324
|
} else {
|
|
@@ -7319,7 +7326,7 @@ async function login(options) {
|
|
|
7319
7326
|
}
|
|
7320
7327
|
return;
|
|
7321
7328
|
}
|
|
7322
|
-
clack.intro(
|
|
7329
|
+
clack.intro(pc2.bold("Wraps \u203A Sign In"));
|
|
7323
7330
|
const baseURL = process.env.WRAPS_API_URL || "https://app.wraps.dev";
|
|
7324
7331
|
const authClient = createCliAuthClient(baseURL);
|
|
7325
7332
|
const spinner8 = clack.spinner();
|
|
@@ -7327,6 +7334,8 @@ async function login(options) {
|
|
|
7327
7334
|
client_id: "wraps-cli"
|
|
7328
7335
|
});
|
|
7329
7336
|
if (codeError || !codeData) {
|
|
7337
|
+
trackCommand("auth:login", { success: false, duration_ms: Date.now() - startTime, method: "device" });
|
|
7338
|
+
trackError("DEVICE_AUTH_FAILED", "auth:login", { step: "request_code" });
|
|
7330
7339
|
clack.log.error("Failed to start device authorization.");
|
|
7331
7340
|
process.exit(1);
|
|
7332
7341
|
}
|
|
@@ -7338,8 +7347,8 @@ async function login(options) {
|
|
|
7338
7347
|
expires_in
|
|
7339
7348
|
} = codeData;
|
|
7340
7349
|
const formatted = `${user_code.slice(0, 4)}-${user_code.slice(4)}`;
|
|
7341
|
-
clack.log.info(`Your code: ${
|
|
7342
|
-
clack.log.info(`Visit: ${
|
|
7350
|
+
clack.log.info(`Your code: ${pc2.bold(pc2.cyan(formatted))}`);
|
|
7351
|
+
clack.log.info(`Visit: ${pc2.underline(`${baseURL}/device`)}`);
|
|
7343
7352
|
try {
|
|
7344
7353
|
await open(`${baseURL}/device?user_code=${user_code}`);
|
|
7345
7354
|
clack.log.info("Opening browser...");
|
|
@@ -7369,9 +7378,14 @@ async function login(options) {
|
|
|
7369
7378
|
organizations: organizations.length > 0 ? organizations : void 0
|
|
7370
7379
|
}
|
|
7371
7380
|
});
|
|
7381
|
+
trackCommand("auth:login", {
|
|
7382
|
+
success: true,
|
|
7383
|
+
duration_ms: Date.now() - startTime,
|
|
7384
|
+
method: "device"
|
|
7385
|
+
});
|
|
7372
7386
|
clack.log.success("Signed in successfully.");
|
|
7373
7387
|
if (organizations.length === 1) {
|
|
7374
|
-
clack.log.info(`Organization: ${
|
|
7388
|
+
clack.log.info(`Organization: ${pc2.cyan(organizations[0].name)}`);
|
|
7375
7389
|
} else if (organizations.length > 1) {
|
|
7376
7390
|
clack.log.info(`${organizations.length} organizations available`);
|
|
7377
7391
|
}
|
|
@@ -7396,6 +7410,8 @@ async function login(options) {
|
|
|
7396
7410
|
continue;
|
|
7397
7411
|
}
|
|
7398
7412
|
if (errorCode === "access_denied") {
|
|
7413
|
+
trackCommand("auth:login", { success: false, duration_ms: Date.now() - startTime, method: "device" });
|
|
7414
|
+
trackError("ACCESS_DENIED", "auth:login", { step: "poll_token" });
|
|
7399
7415
|
spinner8.stop("Denied.");
|
|
7400
7416
|
clack.log.error("Authorization was denied.");
|
|
7401
7417
|
process.exit(1);
|
|
@@ -7405,6 +7421,8 @@ async function login(options) {
|
|
|
7405
7421
|
}
|
|
7406
7422
|
}
|
|
7407
7423
|
}
|
|
7424
|
+
trackCommand("auth:login", { success: false, duration_ms: Date.now() - startTime, method: "device" });
|
|
7425
|
+
trackError("DEVICE_CODE_EXPIRED", "auth:login", { step: "poll_token" });
|
|
7408
7426
|
spinner8.stop("Expired.");
|
|
7409
7427
|
clack.log.error("Device code expired. Run `wraps auth login` to try again.");
|
|
7410
7428
|
process.exit(1);
|
|
@@ -7412,32 +7430,37 @@ async function login(options) {
|
|
|
7412
7430
|
|
|
7413
7431
|
// src/commands/auth/logout.ts
|
|
7414
7432
|
init_esm_shims();
|
|
7433
|
+
init_events();
|
|
7415
7434
|
init_config();
|
|
7416
7435
|
import * as clack2 from "@clack/prompts";
|
|
7417
|
-
import
|
|
7436
|
+
import pc3 from "picocolors";
|
|
7418
7437
|
async function logout() {
|
|
7419
|
-
clack2.intro(
|
|
7438
|
+
clack2.intro(pc3.bold("Wraps \u203A Sign Out"));
|
|
7420
7439
|
const config2 = await readAuthConfig();
|
|
7421
7440
|
if (!config2?.auth?.token) {
|
|
7441
|
+
trackCommand("auth:logout", { success: true, already_logged_out: true });
|
|
7422
7442
|
clack2.log.info("Not signed in.");
|
|
7423
7443
|
return;
|
|
7424
7444
|
}
|
|
7425
7445
|
await clearAuthConfig();
|
|
7446
|
+
trackCommand("auth:logout", { success: true });
|
|
7426
7447
|
clack2.log.success("Signed out. Token removed from ~/.wraps/config.json");
|
|
7427
7448
|
}
|
|
7428
7449
|
|
|
7429
7450
|
// src/commands/auth/status.ts
|
|
7430
7451
|
init_esm_shims();
|
|
7452
|
+
init_events();
|
|
7431
7453
|
init_config();
|
|
7432
7454
|
import * as clack3 from "@clack/prompts";
|
|
7433
|
-
import
|
|
7455
|
+
import pc4 from "picocolors";
|
|
7434
7456
|
async function authStatus(options) {
|
|
7435
7457
|
const config2 = await readAuthConfig();
|
|
7436
7458
|
if (!config2?.auth?.token) {
|
|
7459
|
+
trackCommand("auth:status", { success: true, authenticated: false });
|
|
7437
7460
|
if (options.json) {
|
|
7438
7461
|
console.log(JSON.stringify({ authenticated: false }));
|
|
7439
7462
|
} else {
|
|
7440
|
-
clack3.intro(
|
|
7463
|
+
clack3.intro(pc4.bold("Wraps \u203A Auth Status"));
|
|
7441
7464
|
clack3.log.info("Not signed in. Run `wraps auth login` to authenticate.");
|
|
7442
7465
|
}
|
|
7443
7466
|
return;
|
|
@@ -7454,16 +7477,18 @@ async function authStatus(options) {
|
|
|
7454
7477
|
})
|
|
7455
7478
|
);
|
|
7456
7479
|
} else {
|
|
7457
|
-
clack3.intro(
|
|
7480
|
+
clack3.intro(pc4.bold("Wraps \u203A Auth Status"));
|
|
7458
7481
|
clack3.log.info(`Token: ${masked} (${tokenType})`);
|
|
7459
7482
|
if (expiresAt) {
|
|
7460
7483
|
clack3.log.info(`Expires: ${new Date(expiresAt).toLocaleDateString()}`);
|
|
7461
7484
|
}
|
|
7462
7485
|
}
|
|
7486
|
+
trackCommand("auth:status", { success: true, authenticated: true });
|
|
7463
7487
|
}
|
|
7464
7488
|
|
|
7465
7489
|
// src/commands/aws/doctor.ts
|
|
7466
7490
|
init_esm_shims();
|
|
7491
|
+
init_events();
|
|
7467
7492
|
init_aws();
|
|
7468
7493
|
init_aws_detection();
|
|
7469
7494
|
import * as clack5 from "@clack/prompts";
|
|
@@ -7754,6 +7779,7 @@ function generateSuggestions(results, state) {
|
|
|
7754
7779
|
return suggestions;
|
|
7755
7780
|
}
|
|
7756
7781
|
async function doctor() {
|
|
7782
|
+
const startTime = Date.now();
|
|
7757
7783
|
clack5.intro(pc6.bold("AWS Setup Diagnostics"));
|
|
7758
7784
|
const spinner8 = clack5.spinner();
|
|
7759
7785
|
spinner8.start("Running diagnostics...");
|
|
@@ -7781,6 +7807,13 @@ async function doctor() {
|
|
|
7781
7807
|
console.log(` ${pc6.dim("-")} ${suggestion}`);
|
|
7782
7808
|
}
|
|
7783
7809
|
}
|
|
7810
|
+
trackCommand("aws:doctor", {
|
|
7811
|
+
success: true,
|
|
7812
|
+
duration_ms: Date.now() - startTime,
|
|
7813
|
+
pass_count: passCount,
|
|
7814
|
+
fail_count: failCount,
|
|
7815
|
+
warn_count: warnCount
|
|
7816
|
+
});
|
|
7784
7817
|
console.log();
|
|
7785
7818
|
clack5.outro(
|
|
7786
7819
|
failCount > 0 ? pc6.dim("Run `wraps aws setup` to fix issues") : pc6.dim("Ready to deploy: wraps email init")
|
|
@@ -7789,6 +7822,7 @@ async function doctor() {
|
|
|
7789
7822
|
|
|
7790
7823
|
// src/commands/aws/setup.ts
|
|
7791
7824
|
init_esm_shims();
|
|
7825
|
+
init_events();
|
|
7792
7826
|
init_aws_detection();
|
|
7793
7827
|
init_prompts();
|
|
7794
7828
|
import * as clack7 from "@clack/prompts";
|
|
@@ -8340,6 +8374,7 @@ function showNextSteps(_state) {
|
|
|
8340
8374
|
console.log();
|
|
8341
8375
|
}
|
|
8342
8376
|
async function setup(_options = {}) {
|
|
8377
|
+
const startTime = Date.now();
|
|
8343
8378
|
clack7.intro(pc8.bold("AWS Setup Wizard"));
|
|
8344
8379
|
const spinner8 = clack7.spinner();
|
|
8345
8380
|
spinner8.start("Checking your AWS setup...");
|
|
@@ -8359,6 +8394,10 @@ async function setup(_options = {}) {
|
|
|
8359
8394
|
await runCredentialSetup();
|
|
8360
8395
|
}
|
|
8361
8396
|
}
|
|
8397
|
+
trackCommand("aws:setup", {
|
|
8398
|
+
success: true,
|
|
8399
|
+
duration_ms: Date.now() - startTime
|
|
8400
|
+
});
|
|
8362
8401
|
clack7.outro(pc8.dim("Run `wraps aws doctor` to verify your setup"));
|
|
8363
8402
|
}
|
|
8364
8403
|
|
|
@@ -19262,6 +19301,7 @@ Run ${pc24.cyan("wraps email init")} to deploy email infrastructure.
|
|
|
19262
19301
|
|
|
19263
19302
|
// src/commands/email/templates/init.ts
|
|
19264
19303
|
init_esm_shims();
|
|
19304
|
+
init_events();
|
|
19265
19305
|
init_config();
|
|
19266
19306
|
init_errors();
|
|
19267
19307
|
import { existsSync as existsSync7 } from "fs";
|
|
@@ -19270,6 +19310,7 @@ import { join as join8 } from "path";
|
|
|
19270
19310
|
import * as clack24 from "@clack/prompts";
|
|
19271
19311
|
import pc25 from "picocolors";
|
|
19272
19312
|
async function templatesInit(options) {
|
|
19313
|
+
const startTime = Date.now();
|
|
19273
19314
|
const cwd = process.cwd();
|
|
19274
19315
|
const wrapsDir = join8(cwd, "wraps");
|
|
19275
19316
|
if (!options.json) {
|
|
@@ -19405,6 +19446,10 @@ wraps/.wraps/
|
|
|
19405
19446
|
);
|
|
19406
19447
|
return;
|
|
19407
19448
|
}
|
|
19449
|
+
trackCommand("email:templates:init", {
|
|
19450
|
+
success: true,
|
|
19451
|
+
duration_ms: Date.now() - startTime
|
|
19452
|
+
});
|
|
19408
19453
|
console.log();
|
|
19409
19454
|
clack24.log.success(pc25.green("Templates as Code initialized!"));
|
|
19410
19455
|
console.log();
|
|
@@ -19611,6 +19656,7 @@ const unsubscribeLink = {
|
|
|
19611
19656
|
|
|
19612
19657
|
// src/commands/email/templates/preview.ts
|
|
19613
19658
|
init_esm_shims();
|
|
19659
|
+
init_events();
|
|
19614
19660
|
import { existsSync as existsSync9, watch } from "fs";
|
|
19615
19661
|
import { join as join10 } from "path";
|
|
19616
19662
|
import * as clack25 from "@clack/prompts";
|
|
@@ -19857,6 +19903,10 @@ async function templatesPreview(options) {
|
|
|
19857
19903
|
const port = options.port || await getPort2({ port: [3333, 3334, 3335, 3336, 3337] });
|
|
19858
19904
|
const server = app.listen(port, () => {
|
|
19859
19905
|
const url = `http://localhost:${port}`;
|
|
19906
|
+
trackCommand("email:templates:preview", {
|
|
19907
|
+
success: true,
|
|
19908
|
+
template_count: templateFiles.length
|
|
19909
|
+
});
|
|
19860
19910
|
clack25.log.success(`Preview server running at ${pc26.cyan(url)}`);
|
|
19861
19911
|
if (options.template) {
|
|
19862
19912
|
clack25.log.info(`Previewing: ${pc26.cyan(options.template)}`);
|
|
@@ -20056,6 +20106,7 @@ function renderErrorPage(err) {
|
|
|
20056
20106
|
|
|
20057
20107
|
// src/commands/email/templates/push.ts
|
|
20058
20108
|
init_esm_shims();
|
|
20109
|
+
init_events();
|
|
20059
20110
|
import { createHash } from "crypto";
|
|
20060
20111
|
import { existsSync as existsSync10 } from "fs";
|
|
20061
20112
|
import { mkdir as mkdir4, readFile as readFile4, writeFile as writeFile6 } from "fs/promises";
|
|
@@ -20065,6 +20116,7 @@ import pc27 from "picocolors";
|
|
|
20065
20116
|
init_config();
|
|
20066
20117
|
init_errors();
|
|
20067
20118
|
async function templatesPush(options) {
|
|
20119
|
+
const startTime = Date.now();
|
|
20068
20120
|
const cwd = process.cwd();
|
|
20069
20121
|
const wrapsDir = join11(cwd, "wraps");
|
|
20070
20122
|
const configPath = join11(wrapsDir, "wraps.config.ts");
|
|
@@ -20230,6 +20282,13 @@ async function templatesPush(options) {
|
|
|
20230
20282
|
}
|
|
20231
20283
|
console.log();
|
|
20232
20284
|
}
|
|
20285
|
+
trackCommand("email:templates:push", {
|
|
20286
|
+
success: compileErrors.length === 0,
|
|
20287
|
+
duration_ms: Date.now() - startTime,
|
|
20288
|
+
pushed_count: compiled.length,
|
|
20289
|
+
unchanged_count: unchanged.length,
|
|
20290
|
+
error_count: compileErrors.length
|
|
20291
|
+
});
|
|
20233
20292
|
}
|
|
20234
20293
|
async function compileTemplate(filePath, slug, source, sourceHash, wrapsDir) {
|
|
20235
20294
|
const { build: build2 } = await import("esbuild");
|
|
@@ -22251,6 +22310,7 @@ ${pc28.green("\u2713")} ${pc28.bold("Upgrade complete!")}
|
|
|
22251
22310
|
|
|
22252
22311
|
// src/commands/email/workflows/push.ts
|
|
22253
22312
|
init_esm_shims();
|
|
22313
|
+
init_events();
|
|
22254
22314
|
import { existsSync as existsSync12 } from "fs";
|
|
22255
22315
|
import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile8 } from "fs/promises";
|
|
22256
22316
|
import { join as join13 } from "path";
|
|
@@ -22980,6 +23040,7 @@ function validateTemplateReferences(steps, localTemplateSlugs) {
|
|
|
22980
23040
|
init_config();
|
|
22981
23041
|
init_errors();
|
|
22982
23042
|
async function workflowsPush(options) {
|
|
23043
|
+
const startTime = Date.now();
|
|
22983
23044
|
const cwd = process.cwd();
|
|
22984
23045
|
const wrapsDir = join13(cwd, "wraps");
|
|
22985
23046
|
const configPath = join13(wrapsDir, "wraps.config.ts");
|
|
@@ -23224,6 +23285,13 @@ async function workflowsPush(options) {
|
|
|
23224
23285
|
}
|
|
23225
23286
|
console.log();
|
|
23226
23287
|
}
|
|
23288
|
+
trackCommand("email:workflows:push", {
|
|
23289
|
+
success: conflicts.length === 0 && pushed.length > 0,
|
|
23290
|
+
duration_ms: Date.now() - startTime,
|
|
23291
|
+
pushed_count: pushed.length,
|
|
23292
|
+
unchanged_count: unchanged.length,
|
|
23293
|
+
conflict_count: conflicts.length
|
|
23294
|
+
});
|
|
23227
23295
|
}
|
|
23228
23296
|
async function pushToAPI2(workflows, token, _org, progress, force) {
|
|
23229
23297
|
if (!token) {
|
|
@@ -23372,12 +23440,14 @@ async function saveLockfile2(path3, lockfile) {
|
|
|
23372
23440
|
|
|
23373
23441
|
// src/commands/email/workflows/validate.ts
|
|
23374
23442
|
init_esm_shims();
|
|
23443
|
+
init_events();
|
|
23375
23444
|
import { existsSync as existsSync13 } from "fs";
|
|
23376
23445
|
import { join as join14 } from "path";
|
|
23377
23446
|
import * as clack29 from "@clack/prompts";
|
|
23378
23447
|
import pc30 from "picocolors";
|
|
23379
23448
|
init_errors();
|
|
23380
23449
|
async function workflowsValidate(options) {
|
|
23450
|
+
const startTime = Date.now();
|
|
23381
23451
|
const cwd = process.cwd();
|
|
23382
23452
|
const wrapsDir = join14(cwd, "wraps");
|
|
23383
23453
|
const configPath = join14(wrapsDir, "wraps.config.ts");
|
|
@@ -23526,13 +23596,22 @@ async function workflowsValidate(options) {
|
|
|
23526
23596
|
}
|
|
23527
23597
|
console.log();
|
|
23528
23598
|
}
|
|
23599
|
+
trackCommand("email:workflows:validate", {
|
|
23600
|
+
success: parseErrors.length === 0 && validationResults.every((r) => r.valid),
|
|
23601
|
+
duration_ms: Date.now() - startTime,
|
|
23602
|
+
valid_count: validationResults.filter((r) => r.valid).length,
|
|
23603
|
+
invalid_count: validationResults.filter((r) => !r.valid).length,
|
|
23604
|
+
parse_error_count: parseErrors.length
|
|
23605
|
+
});
|
|
23529
23606
|
}
|
|
23530
23607
|
|
|
23531
23608
|
// src/commands/news.ts
|
|
23532
23609
|
init_esm_shims();
|
|
23610
|
+
init_events();
|
|
23533
23611
|
import * as clack30 from "@clack/prompts";
|
|
23534
23612
|
import pc31 from "picocolors";
|
|
23535
23613
|
async function news() {
|
|
23614
|
+
trackCommand("news", { success: true });
|
|
23536
23615
|
clack30.intro(pc31.bold("What's New in Wraps"));
|
|
23537
23616
|
console.log();
|
|
23538
23617
|
console.log(" See the latest updates, features, and improvements:");
|
|
@@ -28060,11 +28139,13 @@ async function dashboard(options) {
|
|
|
28060
28139
|
|
|
28061
28140
|
// src/commands/shared/destroy.ts
|
|
28062
28141
|
init_esm_shims();
|
|
28142
|
+
init_events();
|
|
28063
28143
|
init_aws();
|
|
28064
28144
|
init_metadata();
|
|
28065
28145
|
import * as clack34 from "@clack/prompts";
|
|
28066
28146
|
import pc37 from "picocolors";
|
|
28067
28147
|
async function destroy(options) {
|
|
28148
|
+
trackCommand("destroy", { success: true });
|
|
28068
28149
|
clack34.intro(pc37.bold("Wraps Infrastructure Teardown"));
|
|
28069
28150
|
const spinner8 = clack34.spinner();
|
|
28070
28151
|
spinner8.start("Validating AWS credentials");
|
|
@@ -30135,6 +30216,7 @@ ${pc40.yellow(pc40.bold("Important Notes:"))}`);
|
|
|
30135
30216
|
|
|
30136
30217
|
// src/commands/sms/register.ts
|
|
30137
30218
|
init_esm_shims();
|
|
30219
|
+
init_events();
|
|
30138
30220
|
init_aws();
|
|
30139
30221
|
init_metadata();
|
|
30140
30222
|
import * as clack38 from "@clack/prompts";
|
|
@@ -30176,6 +30258,7 @@ async function getRegistrationStatus(region, registrationId) {
|
|
|
30176
30258
|
}
|
|
30177
30259
|
}
|
|
30178
30260
|
async function smsRegister(options) {
|
|
30261
|
+
const startTime = Date.now();
|
|
30179
30262
|
clack38.intro(pc41.bold("Wraps SMS - Toll-Free Registration"));
|
|
30180
30263
|
const progress = new DeploymentProgress();
|
|
30181
30264
|
const identity = await progress.execute(
|
|
@@ -30294,6 +30377,10 @@ async function smsRegister(options) {
|
|
|
30294
30377
|
console.log("When you're ready, go to:");
|
|
30295
30378
|
console.log(` ${pc41.cyan(consoleUrl)}`);
|
|
30296
30379
|
}
|
|
30380
|
+
trackCommand("sms:register", {
|
|
30381
|
+
success: true,
|
|
30382
|
+
duration_ms: Date.now() - startTime
|
|
30383
|
+
});
|
|
30297
30384
|
clack38.outro(pc41.dim("Good luck with your registration!"));
|
|
30298
30385
|
}
|
|
30299
30386
|
|
|
@@ -32069,9 +32156,11 @@ Run ${pc46.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
32069
32156
|
|
|
32070
32157
|
// src/commands/support.ts
|
|
32071
32158
|
init_esm_shims();
|
|
32159
|
+
init_events();
|
|
32072
32160
|
import * as clack44 from "@clack/prompts";
|
|
32073
32161
|
import pc47 from "picocolors";
|
|
32074
32162
|
async function support() {
|
|
32163
|
+
trackCommand("support", { success: true });
|
|
32075
32164
|
clack44.intro(pc47.bold("Get Help with Wraps"));
|
|
32076
32165
|
console.log();
|
|
32077
32166
|
console.log(` ${pc47.bold("Email:")} ${pc47.cyan("hey@wraps.sh")}`);
|