@wraps.dev/cli 2.12.2 → 2.12.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
|
@@ -46,10 +46,6 @@ function isCI() {
|
|
|
46
46
|
// Azure Pipelines
|
|
47
47
|
"CODEBUILD_BUILD_ID",
|
|
48
48
|
// AWS CodeBuild
|
|
49
|
-
"NETLIFY",
|
|
50
|
-
// Netlify
|
|
51
|
-
"VERCEL",
|
|
52
|
-
// Vercel
|
|
53
49
|
"HEROKU_TEST_RUN_ID",
|
|
54
50
|
// Heroku CI
|
|
55
51
|
"BUDDY",
|
|
@@ -399,7 +395,9 @@ async function readAuthConfig() {
|
|
|
399
395
|
async function saveAuthConfig(config2) {
|
|
400
396
|
await ensureWrapsDir();
|
|
401
397
|
const path3 = getConfigPath();
|
|
402
|
-
|
|
398
|
+
const existing = await readAuthConfig();
|
|
399
|
+
const merged = existing ? { ...existing, ...config2 } : config2;
|
|
400
|
+
await writeFile2(path3, JSON.stringify(merged, null, 2), "utf-8");
|
|
403
401
|
await chmod(path3, 384);
|
|
404
402
|
}
|
|
405
403
|
async function clearAuthConfig() {
|
|
@@ -418,7 +416,13 @@ async function resolveTokenAsync(flags2) {
|
|
|
418
416
|
return sync;
|
|
419
417
|
}
|
|
420
418
|
const config2 = await readAuthConfig();
|
|
421
|
-
|
|
419
|
+
if (!config2?.auth?.token) {
|
|
420
|
+
return null;
|
|
421
|
+
}
|
|
422
|
+
if (config2.auth.expiresAt && new Date(config2.auth.expiresAt) <= /* @__PURE__ */ new Date()) {
|
|
423
|
+
return null;
|
|
424
|
+
}
|
|
425
|
+
return config2.auth.token;
|
|
422
426
|
}
|
|
423
427
|
var CONFIG_FILE;
|
|
424
428
|
var init_config = __esm({
|
|
@@ -674,24 +678,34 @@ var init_client = __esm({
|
|
|
674
678
|
await this.flush();
|
|
675
679
|
}
|
|
676
680
|
/**
|
|
677
|
-
* Enable telemetry
|
|
678
|
-
*
|
|
681
|
+
* Enable telemetry.
|
|
682
|
+
* Returns null if enabled, or a string describing why an env override prevented it.
|
|
679
683
|
*/
|
|
680
684
|
enable() {
|
|
681
685
|
this.config.setEnabled(true);
|
|
682
|
-
|
|
686
|
+
const override = this.getEnvOverride();
|
|
687
|
+
if (override) {
|
|
683
688
|
this.enabled = false;
|
|
684
|
-
return;
|
|
689
|
+
return override;
|
|
690
|
+
}
|
|
691
|
+
this.enabled = true;
|
|
692
|
+
return null;
|
|
693
|
+
}
|
|
694
|
+
/**
|
|
695
|
+
* Check if an environment variable is overriding the config.
|
|
696
|
+
* Returns a human-readable reason, or null if no override.
|
|
697
|
+
*/
|
|
698
|
+
getEnvOverride() {
|
|
699
|
+
if (process.env.DO_NOT_TRACK === "1" || process.env.DO_NOT_TRACK === "true") {
|
|
700
|
+
return "DO_NOT_TRACK environment variable is set";
|
|
685
701
|
}
|
|
686
702
|
if (process.env.WRAPS_TELEMETRY_DISABLED === "1") {
|
|
687
|
-
|
|
688
|
-
return;
|
|
703
|
+
return "WRAPS_TELEMETRY_DISABLED environment variable is set";
|
|
689
704
|
}
|
|
690
705
|
if (isCI()) {
|
|
691
|
-
|
|
692
|
-
return;
|
|
706
|
+
return "CI environment detected";
|
|
693
707
|
}
|
|
694
|
-
|
|
708
|
+
return null;
|
|
695
709
|
}
|
|
696
710
|
/**
|
|
697
711
|
* Disable telemetry
|
|
@@ -8552,7 +8566,7 @@ async function login(options) {
|
|
|
8552
8566
|
});
|
|
8553
8567
|
trackError("DEVICE_AUTH_FAILED", "auth:login", { step: "request_code" });
|
|
8554
8568
|
clack.log.error("Failed to start device authorization.");
|
|
8555
|
-
|
|
8569
|
+
throw new Error("Failed to start device authorization.");
|
|
8556
8570
|
}
|
|
8557
8571
|
const {
|
|
8558
8572
|
device_code,
|
|
@@ -8603,6 +8617,10 @@ async function login(options) {
|
|
|
8603
8617
|
clack.log.info(`Organization: ${pc2.cyan(organizations[0].name)}`);
|
|
8604
8618
|
} else if (organizations.length > 1) {
|
|
8605
8619
|
clack.log.info(`${organizations.length} organizations available`);
|
|
8620
|
+
} else {
|
|
8621
|
+
clack.log.info(
|
|
8622
|
+
`No organizations found. Create one at ${pc2.underline(`${baseURL}/onboarding`)} and run ${pc2.cyan("wraps auth login")} again.`
|
|
8623
|
+
);
|
|
8606
8624
|
}
|
|
8607
8625
|
if (options.json) {
|
|
8608
8626
|
console.log(
|
|
@@ -8616,7 +8634,8 @@ async function login(options) {
|
|
|
8616
8634
|
return;
|
|
8617
8635
|
}
|
|
8618
8636
|
if (tokenError) {
|
|
8619
|
-
const
|
|
8637
|
+
const err = tokenError;
|
|
8638
|
+
const errorCode = err.error || err.code;
|
|
8620
8639
|
if (errorCode === "authorization_pending") {
|
|
8621
8640
|
continue;
|
|
8622
8641
|
}
|
|
@@ -8633,7 +8652,7 @@ async function login(options) {
|
|
|
8633
8652
|
trackError("ACCESS_DENIED", "auth:login", { step: "poll_token" });
|
|
8634
8653
|
spinner9.stop("Denied.");
|
|
8635
8654
|
clack.log.error("Authorization was denied.");
|
|
8636
|
-
|
|
8655
|
+
throw new Error("Authorization was denied.");
|
|
8637
8656
|
}
|
|
8638
8657
|
if (errorCode === "expired_token") {
|
|
8639
8658
|
break;
|
|
@@ -8648,7 +8667,7 @@ async function login(options) {
|
|
|
8648
8667
|
trackError("DEVICE_CODE_EXPIRED", "auth:login", { step: "poll_token" });
|
|
8649
8668
|
spinner9.stop("Expired.");
|
|
8650
8669
|
clack.log.error("Device code expired. Run `wraps auth login` to try again.");
|
|
8651
|
-
|
|
8670
|
+
throw new Error("Device code expired.");
|
|
8652
8671
|
}
|
|
8653
8672
|
|
|
8654
8673
|
// src/commands/auth/logout.ts
|
|
@@ -29497,8 +29516,12 @@ async function findExistingPhoneNumber(phoneNumberType) {
|
|
|
29497
29516
|
}
|
|
29498
29517
|
}
|
|
29499
29518
|
return null;
|
|
29500
|
-
} catch {
|
|
29501
|
-
|
|
29519
|
+
} catch (error) {
|
|
29520
|
+
const name = error instanceof Error ? error.name : "";
|
|
29521
|
+
if (name === "ResourceNotFoundException") {
|
|
29522
|
+
return null;
|
|
29523
|
+
}
|
|
29524
|
+
throw error;
|
|
29502
29525
|
}
|
|
29503
29526
|
}
|
|
29504
29527
|
async function createSMSPhoneNumber(phoneNumberType, optOutList) {
|
|
@@ -29885,7 +29908,12 @@ async function createSMSPhonePoolWithSDK(phoneNumberArn, region) {
|
|
|
29885
29908
|
}
|
|
29886
29909
|
}
|
|
29887
29910
|
}
|
|
29888
|
-
} catch {
|
|
29911
|
+
} catch (error) {
|
|
29912
|
+
const name = error instanceof Error ? error.name : "";
|
|
29913
|
+
if (name === "ResourceNotFoundException") {
|
|
29914
|
+
} else {
|
|
29915
|
+
throw error;
|
|
29916
|
+
}
|
|
29889
29917
|
}
|
|
29890
29918
|
try {
|
|
29891
29919
|
const response = await client.send(
|
|
@@ -29901,8 +29929,12 @@ async function createSMSPhonePoolWithSDK(phoneNumberArn, region) {
|
|
|
29901
29929
|
})
|
|
29902
29930
|
);
|
|
29903
29931
|
return response.PoolId;
|
|
29904
|
-
} catch {
|
|
29905
|
-
|
|
29932
|
+
} catch (error) {
|
|
29933
|
+
const name = error instanceof Error ? error.name : "";
|
|
29934
|
+
if (name === "ConflictException") {
|
|
29935
|
+
return;
|
|
29936
|
+
}
|
|
29937
|
+
throw error;
|
|
29906
29938
|
}
|
|
29907
29939
|
}
|
|
29908
29940
|
async function createSMSEventDestinationWithSDK(configurationSetName, snsTopicArn, region) {
|
|
@@ -29928,7 +29960,12 @@ async function createSMSEventDestinationWithSDK(configurationSetName, snsTopicAr
|
|
|
29928
29960
|
return existingDest.EventDestinationName;
|
|
29929
29961
|
}
|
|
29930
29962
|
}
|
|
29931
|
-
} catch {
|
|
29963
|
+
} catch (error) {
|
|
29964
|
+
const name = error instanceof Error ? error.name : "";
|
|
29965
|
+
if (name === "ResourceNotFoundException") {
|
|
29966
|
+
} else {
|
|
29967
|
+
throw error;
|
|
29968
|
+
}
|
|
29932
29969
|
}
|
|
29933
29970
|
try {
|
|
29934
29971
|
const response = await client.send(
|
|
@@ -29942,8 +29979,12 @@ async function createSMSEventDestinationWithSDK(configurationSetName, snsTopicAr
|
|
|
29942
29979
|
})
|
|
29943
29980
|
);
|
|
29944
29981
|
return response.EventDestination?.EventDestinationName || eventDestinationName;
|
|
29945
|
-
} catch {
|
|
29946
|
-
|
|
29982
|
+
} catch (error) {
|
|
29983
|
+
const name = error instanceof Error ? error.name : "";
|
|
29984
|
+
if (name === "ConflictException") {
|
|
29985
|
+
return eventDestinationName;
|
|
29986
|
+
}
|
|
29987
|
+
throw error;
|
|
29947
29988
|
}
|
|
29948
29989
|
}
|
|
29949
29990
|
async function deleteSMSPhonePoolWithSDK(region) {
|
|
@@ -29972,7 +30013,12 @@ async function deleteSMSPhonePoolWithSDK(region) {
|
|
|
29972
30013
|
}
|
|
29973
30014
|
}
|
|
29974
30015
|
}
|
|
29975
|
-
} catch {
|
|
30016
|
+
} catch (error) {
|
|
30017
|
+
const name = error instanceof Error ? error.name : "";
|
|
30018
|
+
if (name === "ResourceNotFoundException") {
|
|
30019
|
+
} else {
|
|
30020
|
+
throw error;
|
|
30021
|
+
}
|
|
29976
30022
|
}
|
|
29977
30023
|
}
|
|
29978
30024
|
async function deleteSMSEventDestinationWithSDK(configurationSetName, region) {
|
|
@@ -29986,7 +30032,12 @@ async function deleteSMSEventDestinationWithSDK(configurationSetName, region) {
|
|
|
29986
30032
|
EventDestinationName: eventDestinationName
|
|
29987
30033
|
})
|
|
29988
30034
|
);
|
|
29989
|
-
} catch {
|
|
30035
|
+
} catch (error) {
|
|
30036
|
+
const name = error instanceof Error ? error.name : "";
|
|
30037
|
+
if (name === "ResourceNotFoundException") {
|
|
30038
|
+
} else {
|
|
30039
|
+
throw error;
|
|
30040
|
+
}
|
|
29990
30041
|
}
|
|
29991
30042
|
}
|
|
29992
30043
|
async function createSMSProtectConfigurationWithSDK(configurationSetName, region, options) {
|
|
@@ -30021,7 +30072,12 @@ async function createSMSProtectConfigurationWithSDK(configurationSetName, region
|
|
|
30021
30072
|
break;
|
|
30022
30073
|
}
|
|
30023
30074
|
}
|
|
30024
|
-
} catch {
|
|
30075
|
+
} catch (error) {
|
|
30076
|
+
const name = error instanceof Error ? error.name : "";
|
|
30077
|
+
if (name === "ResourceNotFoundException") {
|
|
30078
|
+
} else {
|
|
30079
|
+
throw error;
|
|
30080
|
+
}
|
|
30025
30081
|
}
|
|
30026
30082
|
try {
|
|
30027
30083
|
let protectConfigId = existingProtectConfigId;
|
|
@@ -30087,8 +30143,12 @@ async function createSMSProtectConfigurationWithSDK(configurationSetName, region
|
|
|
30087
30143
|
);
|
|
30088
30144
|
}
|
|
30089
30145
|
return protectConfigId;
|
|
30090
|
-
} catch {
|
|
30091
|
-
|
|
30146
|
+
} catch (error) {
|
|
30147
|
+
const name = error instanceof Error ? error.name : "";
|
|
30148
|
+
if (name === "ConflictException") {
|
|
30149
|
+
return;
|
|
30150
|
+
}
|
|
30151
|
+
throw error;
|
|
30092
30152
|
}
|
|
30093
30153
|
}
|
|
30094
30154
|
async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
@@ -30125,7 +30185,12 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
|
30125
30185
|
}
|
|
30126
30186
|
}
|
|
30127
30187
|
}
|
|
30128
|
-
} catch {
|
|
30188
|
+
} catch (error) {
|
|
30189
|
+
const name = error instanceof Error ? error.name : "";
|
|
30190
|
+
if (name === "ResourceNotFoundException") {
|
|
30191
|
+
} else {
|
|
30192
|
+
throw error;
|
|
30193
|
+
}
|
|
30129
30194
|
}
|
|
30130
30195
|
}
|
|
30131
30196
|
|
|
@@ -30148,7 +30213,29 @@ async function smsDestroy(options) {
|
|
|
30148
30213
|
"Validating AWS credentials",
|
|
30149
30214
|
async () => validateAWSCredentials()
|
|
30150
30215
|
);
|
|
30151
|
-
|
|
30216
|
+
let region = options.region || await getAWSRegion();
|
|
30217
|
+
if (!(options.region || process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION)) {
|
|
30218
|
+
const smsConnections = await findConnectionsWithService(
|
|
30219
|
+
identity.accountId,
|
|
30220
|
+
"sms"
|
|
30221
|
+
);
|
|
30222
|
+
if (smsConnections.length === 1) {
|
|
30223
|
+
region = smsConnections[0].region;
|
|
30224
|
+
} else if (smsConnections.length > 1) {
|
|
30225
|
+
const selectedRegion = await clack38.select({
|
|
30226
|
+
message: "Multiple SMS deployments found. Which region to destroy?",
|
|
30227
|
+
options: smsConnections.map((conn) => ({
|
|
30228
|
+
value: conn.region,
|
|
30229
|
+
label: conn.region
|
|
30230
|
+
}))
|
|
30231
|
+
});
|
|
30232
|
+
if (clack38.isCancel(selectedRegion)) {
|
|
30233
|
+
clack38.cancel("Operation cancelled");
|
|
30234
|
+
process.exit(0);
|
|
30235
|
+
}
|
|
30236
|
+
region = selectedRegion;
|
|
30237
|
+
}
|
|
30238
|
+
}
|
|
30152
30239
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
30153
30240
|
const smsService = metadata?.services?.sms;
|
|
30154
30241
|
const storedStackName = smsService?.pulumiStackName;
|
|
@@ -30227,6 +30314,7 @@ async function smsDestroy(options) {
|
|
|
30227
30314
|
await progress.execute("Cleaning up protect configuration", async () => {
|
|
30228
30315
|
await deleteSMSProtectConfigurationWithSDK(region);
|
|
30229
30316
|
});
|
|
30317
|
+
let destroyFailed = false;
|
|
30230
30318
|
try {
|
|
30231
30319
|
await progress.execute(
|
|
30232
30320
|
"Destroying SMS infrastructure (this may take 2-3 minutes)",
|
|
@@ -30242,8 +30330,14 @@ async function smsDestroy(options) {
|
|
|
30242
30330
|
} catch (_error) {
|
|
30243
30331
|
throw new Error("No SMS infrastructure found to destroy");
|
|
30244
30332
|
}
|
|
30245
|
-
await stack.
|
|
30333
|
+
await stack.refresh({ onOutput: () => {
|
|
30246
30334
|
} });
|
|
30335
|
+
await withTimeout(
|
|
30336
|
+
stack.destroy({ onOutput: () => {
|
|
30337
|
+
}, continueOnError: true }),
|
|
30338
|
+
DEFAULT_PULUMI_TIMEOUT_MS,
|
|
30339
|
+
"Pulumi destroy"
|
|
30340
|
+
);
|
|
30247
30341
|
await stack.workspace.removeStack(stackName);
|
|
30248
30342
|
}
|
|
30249
30343
|
);
|
|
@@ -30263,21 +30357,29 @@ async function smsDestroy(options) {
|
|
|
30263
30357
|
throw errors.stackLocked();
|
|
30264
30358
|
}
|
|
30265
30359
|
trackError("DESTROY_FAILED", "sms destroy", { step: "destroy" });
|
|
30266
|
-
|
|
30267
|
-
|
|
30360
|
+
destroyFailed = true;
|
|
30361
|
+
clack38.log.warn(
|
|
30362
|
+
"Some resources may not have been fully removed. You can re-run this command or clean up manually in the AWS console."
|
|
30363
|
+
);
|
|
30268
30364
|
}
|
|
30269
30365
|
if (metadata) {
|
|
30270
30366
|
removeServiceFromConnection(metadata, "sms");
|
|
30271
30367
|
await saveConnectionMetadata(metadata);
|
|
30272
30368
|
}
|
|
30273
30369
|
progress.stop();
|
|
30274
|
-
|
|
30275
|
-
|
|
30370
|
+
if (destroyFailed) {
|
|
30371
|
+
clack38.outro(
|
|
30372
|
+
pc41.yellow("SMS infrastructure partially removed. Metadata cleaned up.")
|
|
30373
|
+
);
|
|
30374
|
+
} else {
|
|
30375
|
+
clack38.outro(pc41.green("SMS infrastructure has been removed"));
|
|
30376
|
+
console.log(`
|
|
30276
30377
|
${pc41.bold("Cleaned up:")}`);
|
|
30277
|
-
|
|
30278
|
-
|
|
30279
|
-
|
|
30280
|
-
|
|
30378
|
+
console.log(` ${pc41.green("\u2713")} Phone number released`);
|
|
30379
|
+
console.log(` ${pc41.green("\u2713")} Configuration set deleted`);
|
|
30380
|
+
console.log(` ${pc41.green("\u2713")} Event processing infrastructure removed`);
|
|
30381
|
+
console.log(` ${pc41.green("\u2713")} IAM role deleted`);
|
|
30382
|
+
}
|
|
30281
30383
|
console.log(
|
|
30282
30384
|
`
|
|
30283
30385
|
Run ${pc41.cyan("wraps sms init")} to deploy infrastructure again.
|
|
@@ -30285,6 +30387,7 @@ Run ${pc41.cyan("wraps sms init")} to deploy infrastructure again.
|
|
|
30285
30387
|
);
|
|
30286
30388
|
trackServiceRemoved("sms", {
|
|
30287
30389
|
reason: "user_initiated",
|
|
30390
|
+
partial_failure: destroyFailed,
|
|
30288
30391
|
duration_ms: Date.now() - startTime
|
|
30289
30392
|
});
|
|
30290
30393
|
}
|
|
@@ -30988,31 +31091,64 @@ ${pc42.yellow(pc42.bold("Important Notes:"))}`);
|
|
|
30988
31091
|
};
|
|
30989
31092
|
}
|
|
30990
31093
|
);
|
|
31094
|
+
let sdkResourceWarning = false;
|
|
30991
31095
|
if (outputs.phoneNumberArn) {
|
|
30992
|
-
|
|
30993
|
-
await
|
|
30994
|
-
|
|
31096
|
+
try {
|
|
31097
|
+
await progress.execute("Creating phone pool", async () => {
|
|
31098
|
+
await createSMSPhonePoolWithSDK(outputs.phoneNumberArn, region);
|
|
31099
|
+
});
|
|
31100
|
+
} catch (sdkError) {
|
|
31101
|
+
sdkResourceWarning = true;
|
|
31102
|
+
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
31103
|
+
clack39.log.warn(`Phone pool creation failed: ${msg}`);
|
|
31104
|
+
clack39.log.info(
|
|
31105
|
+
`Run ${pc42.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
31106
|
+
);
|
|
31107
|
+
}
|
|
30995
31108
|
}
|
|
30996
31109
|
if (smsConfig.eventTracking?.enabled && outputs.configSetName && outputs.snsTopicArn) {
|
|
30997
|
-
|
|
30998
|
-
await
|
|
30999
|
-
|
|
31000
|
-
|
|
31001
|
-
|
|
31110
|
+
try {
|
|
31111
|
+
await progress.execute("Configuring event destination", async () => {
|
|
31112
|
+
await createSMSEventDestinationWithSDK(
|
|
31113
|
+
outputs.configSetName,
|
|
31114
|
+
outputs.snsTopicArn,
|
|
31115
|
+
region
|
|
31116
|
+
);
|
|
31117
|
+
});
|
|
31118
|
+
} catch (sdkError) {
|
|
31119
|
+
sdkResourceWarning = true;
|
|
31120
|
+
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
31121
|
+
clack39.log.warn(`Event destination creation failed: ${msg}`);
|
|
31122
|
+
clack39.log.info(
|
|
31123
|
+
`Run ${pc42.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
31002
31124
|
);
|
|
31003
|
-
}
|
|
31125
|
+
}
|
|
31004
31126
|
}
|
|
31005
31127
|
if (smsConfig.protectConfiguration?.enabled && outputs.configSetName) {
|
|
31006
|
-
|
|
31007
|
-
await
|
|
31008
|
-
|
|
31009
|
-
|
|
31010
|
-
|
|
31011
|
-
|
|
31012
|
-
|
|
31013
|
-
|
|
31128
|
+
try {
|
|
31129
|
+
await progress.execute("Configuring fraud protection", async () => {
|
|
31130
|
+
await createSMSProtectConfigurationWithSDK(
|
|
31131
|
+
outputs.configSetName,
|
|
31132
|
+
region,
|
|
31133
|
+
{
|
|
31134
|
+
allowedCountries: smsConfig.protectConfiguration?.allowedCountries,
|
|
31135
|
+
aitFiltering: smsConfig.protectConfiguration?.aitFiltering
|
|
31136
|
+
}
|
|
31137
|
+
);
|
|
31138
|
+
});
|
|
31139
|
+
} catch (sdkError) {
|
|
31140
|
+
sdkResourceWarning = true;
|
|
31141
|
+
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
31142
|
+
clack39.log.warn(`Protect configuration creation failed: ${msg}`);
|
|
31143
|
+
clack39.log.info(
|
|
31144
|
+
`Run ${pc42.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
31014
31145
|
);
|
|
31015
|
-
}
|
|
31146
|
+
}
|
|
31147
|
+
}
|
|
31148
|
+
if (sdkResourceWarning) {
|
|
31149
|
+
clack39.log.warn(
|
|
31150
|
+
"Some SDK resources failed to create. Core infrastructure is deployed."
|
|
31151
|
+
);
|
|
31016
31152
|
}
|
|
31017
31153
|
} catch (error) {
|
|
31018
31154
|
trackServiceInit("sms", false, {
|
|
@@ -31141,7 +31277,8 @@ async function getPhoneNumberDetails(region) {
|
|
|
31141
31277
|
}
|
|
31142
31278
|
return null;
|
|
31143
31279
|
} catch (error) {
|
|
31144
|
-
|
|
31280
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
31281
|
+
clack40.log.error(`Error fetching phone number: ${errorMessage}`);
|
|
31145
31282
|
return null;
|
|
31146
31283
|
}
|
|
31147
31284
|
}
|
|
@@ -31535,7 +31672,7 @@ Run ${pc45.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
31535
31672
|
smsConfig.protectConfiguration = {
|
|
31536
31673
|
enabled: true,
|
|
31537
31674
|
allowedCountries: ["US"],
|
|
31538
|
-
aitFiltering:
|
|
31675
|
+
aitFiltering: false
|
|
31539
31676
|
};
|
|
31540
31677
|
}
|
|
31541
31678
|
}
|
|
@@ -31585,9 +31722,14 @@ import {
|
|
|
31585
31722
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
31586
31723
|
import * as clack43 from "@clack/prompts";
|
|
31587
31724
|
import pc46 from "picocolors";
|
|
31725
|
+
|
|
31726
|
+
// src/utils/sms/validation.ts
|
|
31727
|
+
init_esm_shims();
|
|
31588
31728
|
function isValidPhoneNumber(phone) {
|
|
31589
31729
|
return /^\+[1-9]\d{1,14}$/.test(phone);
|
|
31590
31730
|
}
|
|
31731
|
+
|
|
31732
|
+
// src/commands/sms/test.ts
|
|
31591
31733
|
var SIMULATOR_DESTINATIONS = [
|
|
31592
31734
|
{ number: "+14254147755", country: "United States (US)" },
|
|
31593
31735
|
{ number: "+447860019066", country: "United Kingdom (GB)" },
|
|
@@ -31757,18 +31899,39 @@ Run ${pc46.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
31757
31899
|
error: errorMessage,
|
|
31758
31900
|
duration_ms: Date.now() - startTime
|
|
31759
31901
|
});
|
|
31760
|
-
|
|
31902
|
+
const errorName = error instanceof Error ? error.name : "";
|
|
31903
|
+
if (errorName === "ConflictException" || errorMessage.includes("opt-out")) {
|
|
31904
|
+
clack43.log.error("Destination number has opted out of messages");
|
|
31905
|
+
console.log(
|
|
31906
|
+
`
|
|
31907
|
+
The recipient has opted out of receiving SMS messages.
|
|
31908
|
+
`
|
|
31909
|
+
);
|
|
31910
|
+
} else if (errorName === "ThrottlingException" || errorMessage.includes("spending limit")) {
|
|
31911
|
+
clack43.log.error("SMS rate or spending limit reached");
|
|
31912
|
+
console.log(
|
|
31913
|
+
`
|
|
31914
|
+
Check your AWS account SMS spending limits in the console.
|
|
31915
|
+
`
|
|
31916
|
+
);
|
|
31917
|
+
} else if (errorName === "ValidationException") {
|
|
31918
|
+
clack43.log.error(`Invalid request: ${errorMessage}`);
|
|
31919
|
+
} else if (errorMessage.includes("not verified") || errorMessage.includes("not registered")) {
|
|
31761
31920
|
clack43.log.error("Toll-free number registration is not complete");
|
|
31762
31921
|
console.log(
|
|
31763
31922
|
`
|
|
31764
|
-
Run ${pc46.cyan("wraps sms register")} to
|
|
31923
|
+
Run ${pc46.cyan("wraps sms register")} to check registration status.
|
|
31924
|
+
`
|
|
31925
|
+
);
|
|
31926
|
+
} else if (errorName === "AccessDeniedException") {
|
|
31927
|
+
clack43.log.error(
|
|
31928
|
+
"Permission denied \u2014 IAM role may be missing SMS send permissions"
|
|
31929
|
+
);
|
|
31930
|
+
console.log(
|
|
31931
|
+
`
|
|
31932
|
+
Run ${pc46.cyan("wraps sms upgrade")} to update IAM policies.
|
|
31765
31933
|
`
|
|
31766
31934
|
);
|
|
31767
|
-
} else if (errorMessage.includes("opt-out")) {
|
|
31768
|
-
clack43.log.error("Destination number has opted out of messages");
|
|
31769
|
-
} else if (errorMessage.includes("spending limit")) {
|
|
31770
|
-
clack43.log.error("AWS SMS spending limit reached");
|
|
31771
|
-
console.log("\nVisit the AWS console to increase your spending limit.\n");
|
|
31772
31935
|
} else {
|
|
31773
31936
|
clack43.log.error(`Failed to send SMS: ${errorMessage}`);
|
|
31774
31937
|
}
|
|
@@ -32721,9 +32884,6 @@ import {
|
|
|
32721
32884
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
32722
32885
|
import * as clack45 from "@clack/prompts";
|
|
32723
32886
|
import pc48 from "picocolors";
|
|
32724
|
-
function isValidPhoneNumber2(phone) {
|
|
32725
|
-
return /^\+[1-9]\d{1,14}$/.test(phone);
|
|
32726
|
-
}
|
|
32727
32887
|
async function smsVerifyNumber(options) {
|
|
32728
32888
|
const startTime = Date.now();
|
|
32729
32889
|
const progress = new DeploymentProgress();
|
|
@@ -32844,7 +33004,7 @@ Usage: ${pc48.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
32844
33004
|
if (!value) {
|
|
32845
33005
|
return "Phone number is required";
|
|
32846
33006
|
}
|
|
32847
|
-
if (!
|
|
33007
|
+
if (!isValidPhoneNumber(value)) {
|
|
32848
33008
|
return "Please enter a valid phone number in E.164 format (e.g., +14155551234)";
|
|
32849
33009
|
}
|
|
32850
33010
|
return;
|
|
@@ -32855,7 +33015,7 @@ Usage: ${pc48.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
32855
33015
|
process.exit(0);
|
|
32856
33016
|
}
|
|
32857
33017
|
phoneNumber = result;
|
|
32858
|
-
} else if (!
|
|
33018
|
+
} else if (!isValidPhoneNumber(phoneNumber)) {
|
|
32859
33019
|
progress.stop();
|
|
32860
33020
|
clack45.log.error(
|
|
32861
33021
|
`Invalid phone number format: ${phoneNumber}. Use E.164 format (e.g., +14155551234)`
|
|
@@ -33088,12 +33248,21 @@ import * as clack47 from "@clack/prompts";
|
|
|
33088
33248
|
import pc50 from "picocolors";
|
|
33089
33249
|
async function telemetryEnable() {
|
|
33090
33250
|
const client = getTelemetryClient();
|
|
33091
|
-
client.enable();
|
|
33092
|
-
|
|
33093
|
-
|
|
33094
|
-
|
|
33251
|
+
const override = client.enable();
|
|
33252
|
+
if (override) {
|
|
33253
|
+
clack47.log.warn(
|
|
33254
|
+
"Telemetry enabled in config, but overridden by environment"
|
|
33255
|
+
);
|
|
33256
|
+
console.log(` Reason: ${pc50.yellow(override)}`);
|
|
33257
|
+
console.log(` Config: ${pc50.dim(client.getConfigPath())}`);
|
|
33258
|
+
console.log();
|
|
33259
|
+
} else {
|
|
33260
|
+
clack47.log.success(pc50.green("Telemetry enabled"));
|
|
33261
|
+
console.log(` Config: ${pc50.dim(client.getConfigPath())}`);
|
|
33262
|
+
console.log(`
|
|
33095
33263
|
${pc50.dim("Thank you for helping improve Wraps!")}
|
|
33096
33264
|
`);
|
|
33265
|
+
}
|
|
33097
33266
|
}
|
|
33098
33267
|
async function telemetryDisable() {
|
|
33099
33268
|
const client = getTelemetryClient();
|
|
@@ -33109,9 +33278,13 @@ async function telemetryDisable() {
|
|
|
33109
33278
|
async function telemetryStatus() {
|
|
33110
33279
|
const client = getTelemetryClient();
|
|
33111
33280
|
clack47.intro(pc50.bold("Telemetry Status"));
|
|
33281
|
+
const override = client.getEnvOverride();
|
|
33112
33282
|
const status2 = client.isEnabled() ? pc50.green("Enabled") : pc50.red("Disabled");
|
|
33113
33283
|
console.log();
|
|
33114
33284
|
console.log(` ${pc50.bold("Status:")} ${status2}`);
|
|
33285
|
+
if (!client.isEnabled() && override) {
|
|
33286
|
+
console.log(` ${pc50.bold("Reason:")} ${pc50.yellow(override)}`);
|
|
33287
|
+
}
|
|
33115
33288
|
console.log(` ${pc50.bold("Config file:")} ${pc50.dim(client.getConfigPath())}`);
|
|
33116
33289
|
if (client.isEnabled()) {
|
|
33117
33290
|
console.log();
|
|
@@ -34108,7 +34281,8 @@ Run ${pc51.cyan("wraps --help")} for available commands.
|
|
|
34108
34281
|
case "destroy":
|
|
34109
34282
|
await smsDestroy({
|
|
34110
34283
|
force: flags.force,
|
|
34111
|
-
preview: flags.preview
|
|
34284
|
+
preview: flags.preview,
|
|
34285
|
+
region: flags.region
|
|
34112
34286
|
});
|
|
34113
34287
|
break;
|
|
34114
34288
|
case "verify-number":
|
|
@@ -34268,12 +34442,6 @@ Available commands: ${pc51.cyan("login")}, ${pc51.cyan("status")}, ${pc51.cyan("
|
|
|
34268
34442
|
);
|
|
34269
34443
|
throw new Error(`Unknown auth command: ${subCommand || "(none)"}`);
|
|
34270
34444
|
}
|
|
34271
|
-
const authDuration = Date.now() - startTime;
|
|
34272
|
-
const authCommandName = `auth:${subCommand}`;
|
|
34273
|
-
trackCommand(authCommandName, {
|
|
34274
|
-
success: true,
|
|
34275
|
-
duration_ms: authDuration
|
|
34276
|
-
});
|
|
34277
34445
|
return;
|
|
34278
34446
|
}
|
|
34279
34447
|
if (primaryCommand === "aws" && subCommand) {
|