@wraps.dev/cli 2.14.5 → 2.14.7
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 +619 -973
- package/dist/cli.js.map +1 -1
- package/dist/console/assets/index-DYY5rtzO.css +1 -0
- package/dist/console/index.html +2 -2
- package/dist/lambda/event-processor/.bundled +1 -1
- package/dist/lambda/inbound-processor/.bundled +1 -1
- package/dist/lambda/sms-event-processor/.bundled +1 -1
- package/package.json +1 -1
- package/dist/console/assets/index-B8Dwj3Ia.css +0 -1
- /package/dist/console/assets/{index-DdJUFEU6.js → index-Wy-UKvho.js} +0 -0
package/dist/cli.js
CHANGED
|
@@ -8703,11 +8703,11 @@ var init_dynamodb_metrics = __esm({
|
|
|
8703
8703
|
// src/cli.ts
|
|
8704
8704
|
init_esm_shims();
|
|
8705
8705
|
import { readFileSync as readFileSync3 } from "fs";
|
|
8706
|
-
import { dirname as dirname3, join as
|
|
8706
|
+
import { dirname as dirname3, join as join19 } from "path";
|
|
8707
8707
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
8708
8708
|
import * as clack50 from "@clack/prompts";
|
|
8709
8709
|
import args from "args";
|
|
8710
|
-
import
|
|
8710
|
+
import pc53 from "picocolors";
|
|
8711
8711
|
|
|
8712
8712
|
// src/commands/auth/login.ts
|
|
8713
8713
|
init_esm_shims();
|
|
@@ -9903,9 +9903,8 @@ init_esm_shims();
|
|
|
9903
9903
|
init_errors();
|
|
9904
9904
|
import { exec } from "child_process";
|
|
9905
9905
|
import { promisify } from "util";
|
|
9906
|
-
import
|
|
9906
|
+
import { PulumiCommand } from "@pulumi/pulumi/automation/index.js";
|
|
9907
9907
|
var execAsync = promisify(exec);
|
|
9908
|
-
var installPulumiCli2 = automation.installPulumiCli;
|
|
9909
9908
|
async function checkPulumiInstalled() {
|
|
9910
9909
|
try {
|
|
9911
9910
|
await execAsync("pulumi version");
|
|
@@ -9918,7 +9917,7 @@ async function ensurePulumiInstalled() {
|
|
|
9918
9917
|
const isInstalled = await checkPulumiInstalled();
|
|
9919
9918
|
if (!isInstalled) {
|
|
9920
9919
|
try {
|
|
9921
|
-
await
|
|
9920
|
+
await PulumiCommand.install();
|
|
9922
9921
|
return true;
|
|
9923
9922
|
} catch (_error) {
|
|
9924
9923
|
throw errors.pulumiNotInstalled();
|
|
@@ -24720,349 +24719,16 @@ ${pc30.green("\u2713")} ${pc30.bold("Upgrade complete!")}
|
|
|
24720
24719
|
});
|
|
24721
24720
|
}
|
|
24722
24721
|
|
|
24723
|
-
// src/commands/email/workflows/generate.ts
|
|
24724
|
-
init_esm_shims();
|
|
24725
|
-
init_events();
|
|
24726
|
-
init_json_output();
|
|
24727
|
-
import { existsSync as existsSync13, mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
24728
|
-
import { join as join14 } from "path";
|
|
24729
|
-
import { intro as intro27, log as log29 } from "@clack/prompts";
|
|
24730
|
-
import pc31 from "picocolors";
|
|
24731
|
-
var TEMPLATES = {
|
|
24732
|
-
welcome: `import {
|
|
24733
|
-
defineWorkflow,
|
|
24734
|
-
sendEmail,
|
|
24735
|
-
delay,
|
|
24736
|
-
condition,
|
|
24737
|
-
exit,
|
|
24738
|
-
} from '@wraps.dev/client';
|
|
24739
|
-
|
|
24740
|
-
/**
|
|
24741
|
-
* Welcome Sequence
|
|
24742
|
-
*
|
|
24743
|
-
* Send a welcome email when a contact is created,
|
|
24744
|
-
* wait 1 day, then check if they activated.
|
|
24745
|
-
* If not, send a follow-up with tips.
|
|
24746
|
-
*/
|
|
24747
|
-
export default defineWorkflow({
|
|
24748
|
-
name: 'Welcome Sequence',
|
|
24749
|
-
trigger: {
|
|
24750
|
-
type: 'contact_created',
|
|
24751
|
-
},
|
|
24752
|
-
|
|
24753
|
-
steps: [
|
|
24754
|
-
sendEmail('send-welcome', { template: 'welcome-email' }),
|
|
24755
|
-
delay('wait-1-day', { days: 1 }),
|
|
24756
|
-
condition('check-activated', {
|
|
24757
|
-
field: 'contact.hasActivated',
|
|
24758
|
-
operator: 'equals',
|
|
24759
|
-
value: true,
|
|
24760
|
-
branches: {
|
|
24761
|
-
yes: [exit('already-active')],
|
|
24762
|
-
no: [
|
|
24763
|
-
sendEmail('send-tips', { template: 'getting-started-tips' }),
|
|
24764
|
-
],
|
|
24765
|
-
},
|
|
24766
|
-
}),
|
|
24767
|
-
],
|
|
24768
|
-
});
|
|
24769
|
-
`,
|
|
24770
|
-
"cart-recovery": `import {
|
|
24771
|
-
defineWorkflow,
|
|
24772
|
-
sendEmail,
|
|
24773
|
-
sendSms,
|
|
24774
|
-
delay,
|
|
24775
|
-
cascade,
|
|
24776
|
-
exit,
|
|
24777
|
-
} from '@wraps.dev/client';
|
|
24778
|
-
|
|
24779
|
-
/**
|
|
24780
|
-
* Cart Recovery Cascade
|
|
24781
|
-
*
|
|
24782
|
-
* When a cart is abandoned, wait 30 minutes, then try
|
|
24783
|
-
* email first. If not opened after 2 hours, fall back to SMS.
|
|
24784
|
-
*/
|
|
24785
|
-
export default defineWorkflow({
|
|
24786
|
-
name: 'Cart Recovery Cascade',
|
|
24787
|
-
trigger: {
|
|
24788
|
-
type: 'event',
|
|
24789
|
-
eventName: 'cart.abandoned',
|
|
24790
|
-
},
|
|
24791
|
-
|
|
24792
|
-
steps: [
|
|
24793
|
-
delay('initial-wait', { minutes: 30 }),
|
|
24794
|
-
|
|
24795
|
-
...cascade('recover-cart', {
|
|
24796
|
-
channels: [
|
|
24797
|
-
{
|
|
24798
|
-
type: 'email',
|
|
24799
|
-
template: 'cart-recovery',
|
|
24800
|
-
waitFor: { hours: 2 },
|
|
24801
|
-
engagement: 'opened',
|
|
24802
|
-
},
|
|
24803
|
-
{
|
|
24804
|
-
type: 'sms',
|
|
24805
|
-
template: 'cart-sms-reminder',
|
|
24806
|
-
},
|
|
24807
|
-
],
|
|
24808
|
-
}),
|
|
24809
|
-
|
|
24810
|
-
exit('cascade-complete'),
|
|
24811
|
-
],
|
|
24812
|
-
});
|
|
24813
|
-
`,
|
|
24814
|
-
"trial-conversion": `import {
|
|
24815
|
-
defineWorkflow,
|
|
24816
|
-
sendEmail,
|
|
24817
|
-
delay,
|
|
24818
|
-
condition,
|
|
24819
|
-
exit,
|
|
24820
|
-
} from '@wraps.dev/client';
|
|
24821
|
-
|
|
24822
|
-
/**
|
|
24823
|
-
* Trial Conversion
|
|
24824
|
-
*
|
|
24825
|
-
* Remind users 3 days before their trial ends.
|
|
24826
|
-
* If they haven't upgraded after 1 day, send a final nudge.
|
|
24827
|
-
*/
|
|
24828
|
-
export default defineWorkflow({
|
|
24829
|
-
name: 'Trial Conversion',
|
|
24830
|
-
trigger: {
|
|
24831
|
-
type: 'event',
|
|
24832
|
-
eventName: 'trial.ending',
|
|
24833
|
-
},
|
|
24834
|
-
|
|
24835
|
-
steps: [
|
|
24836
|
-
sendEmail('send-reminder', { template: 'trial-ending-reminder' }),
|
|
24837
|
-
delay('wait-1-day', { days: 1 }),
|
|
24838
|
-
condition('check-upgraded', {
|
|
24839
|
-
field: 'contact.plan',
|
|
24840
|
-
operator: 'not_equals',
|
|
24841
|
-
value: 'free',
|
|
24842
|
-
branches: {
|
|
24843
|
-
yes: [exit('already-upgraded')],
|
|
24844
|
-
no: [
|
|
24845
|
-
sendEmail('send-upgrade-nudge', { template: 'upgrade-offer' }),
|
|
24846
|
-
],
|
|
24847
|
-
},
|
|
24848
|
-
}),
|
|
24849
|
-
],
|
|
24850
|
-
});
|
|
24851
|
-
`,
|
|
24852
|
-
"re-engagement": `import {
|
|
24853
|
-
defineWorkflow,
|
|
24854
|
-
sendEmail,
|
|
24855
|
-
delay,
|
|
24856
|
-
condition,
|
|
24857
|
-
exit,
|
|
24858
|
-
} from '@wraps.dev/client';
|
|
24859
|
-
|
|
24860
|
-
/**
|
|
24861
|
-
* Re-engagement Campaign
|
|
24862
|
-
*
|
|
24863
|
-
* Win back inactive users with a personalized email.
|
|
24864
|
-
* Wait 3 days for engagement, then send a final offer.
|
|
24865
|
-
*/
|
|
24866
|
-
export default defineWorkflow({
|
|
24867
|
-
name: 'Re-engagement Campaign',
|
|
24868
|
-
trigger: {
|
|
24869
|
-
type: 'event',
|
|
24870
|
-
eventName: 'contact.inactive',
|
|
24871
|
-
},
|
|
24872
|
-
|
|
24873
|
-
steps: [
|
|
24874
|
-
sendEmail('send-win-back', { template: 'we-miss-you' }),
|
|
24875
|
-
delay('wait-3-days', { days: 3 }),
|
|
24876
|
-
condition('check-engaged', {
|
|
24877
|
-
field: 'contact.lastActiveAt',
|
|
24878
|
-
operator: 'is_set',
|
|
24879
|
-
value: true,
|
|
24880
|
-
branches: {
|
|
24881
|
-
yes: [exit('re-engaged')],
|
|
24882
|
-
no: [
|
|
24883
|
-
sendEmail('send-final-offer', { template: 'final-offer' }),
|
|
24884
|
-
],
|
|
24885
|
-
},
|
|
24886
|
-
}),
|
|
24887
|
-
],
|
|
24888
|
-
});
|
|
24889
|
-
`,
|
|
24890
|
-
onboarding: `import {
|
|
24891
|
-
defineWorkflow,
|
|
24892
|
-
sendEmail,
|
|
24893
|
-
delay,
|
|
24894
|
-
condition,
|
|
24895
|
-
exit,
|
|
24896
|
-
} from '@wraps.dev/client';
|
|
24897
|
-
|
|
24898
|
-
/**
|
|
24899
|
-
* Multi-step Onboarding
|
|
24900
|
-
*
|
|
24901
|
-
* Guide new users through setup with a series of emails.
|
|
24902
|
-
* Check progress at each step and skip ahead if they're done.
|
|
24903
|
-
*/
|
|
24904
|
-
export default defineWorkflow({
|
|
24905
|
-
name: 'Onboarding Sequence',
|
|
24906
|
-
trigger: {
|
|
24907
|
-
type: 'contact_created',
|
|
24908
|
-
},
|
|
24909
|
-
|
|
24910
|
-
steps: [
|
|
24911
|
-
sendEmail('send-welcome', { template: 'onboarding-welcome' }),
|
|
24912
|
-
delay('wait-1-day', { days: 1 }),
|
|
24913
|
-
|
|
24914
|
-
condition('check-profile-complete', {
|
|
24915
|
-
field: 'contact.profileComplete',
|
|
24916
|
-
operator: 'equals',
|
|
24917
|
-
value: true,
|
|
24918
|
-
branches: {
|
|
24919
|
-
yes: [
|
|
24920
|
-
sendEmail('send-next-steps', { template: 'onboarding-next-steps' }),
|
|
24921
|
-
],
|
|
24922
|
-
no: [
|
|
24923
|
-
sendEmail('send-profile-reminder', { template: 'complete-your-profile' }),
|
|
24924
|
-
delay('wait-2-days', { days: 2 }),
|
|
24925
|
-
sendEmail('send-next-steps-delayed', { template: 'onboarding-next-steps' }),
|
|
24926
|
-
],
|
|
24927
|
-
},
|
|
24928
|
-
}),
|
|
24929
|
-
|
|
24930
|
-
delay('wait-3-days', { days: 3 }),
|
|
24931
|
-
|
|
24932
|
-
condition('check-first-action', {
|
|
24933
|
-
field: 'contact.hasCompletedFirstAction',
|
|
24934
|
-
operator: 'equals',
|
|
24935
|
-
value: true,
|
|
24936
|
-
branches: {
|
|
24937
|
-
yes: [exit('onboarding-complete')],
|
|
24938
|
-
no: [
|
|
24939
|
-
sendEmail('send-help', { template: 'need-help' }),
|
|
24940
|
-
],
|
|
24941
|
-
},
|
|
24942
|
-
}),
|
|
24943
|
-
],
|
|
24944
|
-
});
|
|
24945
|
-
`
|
|
24946
|
-
};
|
|
24947
|
-
var TEMPLATE_NAMES = Object.keys(TEMPLATES);
|
|
24948
|
-
async function workflowsGenerate(options) {
|
|
24949
|
-
const startTime = Date.now();
|
|
24950
|
-
if (options.template) {
|
|
24951
|
-
generateFromTemplate(options);
|
|
24952
|
-
} else {
|
|
24953
|
-
showUsage();
|
|
24954
|
-
return;
|
|
24955
|
-
}
|
|
24956
|
-
trackCommand("email:workflows:generate", {
|
|
24957
|
-
success: true,
|
|
24958
|
-
duration_ms: Date.now() - startTime,
|
|
24959
|
-
mode: "template"
|
|
24960
|
-
});
|
|
24961
|
-
}
|
|
24962
|
-
function showUsage() {
|
|
24963
|
-
if (isJsonMode()) {
|
|
24964
|
-
jsonError("email.workflows.generate", {
|
|
24965
|
-
code: "MISSING_INPUT",
|
|
24966
|
-
message: "Provide a --template name to generate a workflow"
|
|
24967
|
-
});
|
|
24968
|
-
return;
|
|
24969
|
-
}
|
|
24970
|
-
log29.error("Provide a --template to generate a workflow.");
|
|
24971
|
-
console.log();
|
|
24972
|
-
console.log(` ${pc31.bold("Usage:")}`);
|
|
24973
|
-
console.log(
|
|
24974
|
-
` ${pc31.cyan("wraps email workflows generate --template welcome")}`
|
|
24975
|
-
);
|
|
24976
|
-
console.log();
|
|
24977
|
-
console.log(
|
|
24978
|
-
` ${pc31.bold("Available templates:")} ${TEMPLATE_NAMES.join(", ")}`
|
|
24979
|
-
);
|
|
24980
|
-
console.log();
|
|
24981
|
-
console.log(` ${pc31.bold("Want a custom workflow?")}`);
|
|
24982
|
-
console.log(
|
|
24983
|
-
" Describe what you need to your AI coding assistant (Claude Code, Cursor, etc.)"
|
|
24984
|
-
);
|
|
24985
|
-
console.log(
|
|
24986
|
-
` and it will generate a workflow file using the ${pc31.cyan("@wraps.dev/client")} DSL.`
|
|
24987
|
-
);
|
|
24988
|
-
console.log();
|
|
24989
|
-
}
|
|
24990
|
-
function generateFromTemplate(options) {
|
|
24991
|
-
const templateName = options.template ?? "";
|
|
24992
|
-
const templateCode = TEMPLATES[templateName];
|
|
24993
|
-
if (!templateCode) {
|
|
24994
|
-
if (isJsonMode()) {
|
|
24995
|
-
jsonError("email.workflows.generate", {
|
|
24996
|
-
code: "UNKNOWN_TEMPLATE",
|
|
24997
|
-
message: `Unknown template: ${templateName}. Available: ${TEMPLATE_NAMES.join(", ")}`
|
|
24998
|
-
});
|
|
24999
|
-
} else {
|
|
25000
|
-
log29.error(`Unknown template: ${pc31.red(templateName)}`);
|
|
25001
|
-
console.log(
|
|
25002
|
-
`
|
|
25003
|
-
Available templates: ${TEMPLATE_NAMES.map((t) => pc31.cyan(t)).join(", ")}
|
|
25004
|
-
`
|
|
25005
|
-
);
|
|
25006
|
-
}
|
|
25007
|
-
return;
|
|
25008
|
-
}
|
|
25009
|
-
const slug = options.name || templateName;
|
|
25010
|
-
const cwd = process.cwd();
|
|
25011
|
-
const workflowsDir = join14(cwd, "wraps", "workflows");
|
|
25012
|
-
const filePath = join14(workflowsDir, `${slug}.ts`);
|
|
25013
|
-
if (existsSync13(filePath) && !options.force) {
|
|
25014
|
-
if (isJsonMode()) {
|
|
25015
|
-
jsonError("email.workflows.generate", {
|
|
25016
|
-
code: "FILE_EXISTS",
|
|
25017
|
-
message: `wraps/workflows/${slug}.ts already exists. Use --force to overwrite.`
|
|
25018
|
-
});
|
|
25019
|
-
} else {
|
|
25020
|
-
log29.error(
|
|
25021
|
-
`${pc31.cyan(`wraps/workflows/${slug}.ts`)} already exists. Use ${pc31.bold("--force")} to overwrite.`
|
|
25022
|
-
);
|
|
25023
|
-
}
|
|
25024
|
-
return;
|
|
25025
|
-
}
|
|
25026
|
-
mkdirSync2(workflowsDir, { recursive: true });
|
|
25027
|
-
writeFileSync(filePath, templateCode, "utf-8");
|
|
25028
|
-
if (isJsonMode()) {
|
|
25029
|
-
jsonSuccess("email.workflows.generate", {
|
|
25030
|
-
mode: "template",
|
|
25031
|
-
template: templateName,
|
|
25032
|
-
slug,
|
|
25033
|
-
path: `wraps/workflows/${slug}.ts`
|
|
25034
|
-
});
|
|
25035
|
-
} else {
|
|
25036
|
-
intro27(pc31.bold("Generate Workflow"));
|
|
25037
|
-
log29.success(
|
|
25038
|
-
`Created ${pc31.cyan(`wraps/workflows/${slug}.ts`)} from ${pc31.bold(templateName)} template`
|
|
25039
|
-
);
|
|
25040
|
-
showNextSteps2(slug);
|
|
25041
|
-
}
|
|
25042
|
-
}
|
|
25043
|
-
function showNextSteps2(slug) {
|
|
25044
|
-
console.log();
|
|
25045
|
-
console.log(` ${pc31.bold("Next steps:")}`);
|
|
25046
|
-
console.log(
|
|
25047
|
-
` 1. Edit template references in ${pc31.cyan(`wraps/workflows/${slug}.ts`)}`
|
|
25048
|
-
);
|
|
25049
|
-
console.log(
|
|
25050
|
-
` 2. Validate: ${pc31.cyan(`wraps email workflows validate --workflow ${slug}`)}`
|
|
25051
|
-
);
|
|
25052
|
-
console.log(` 3. Push: ${pc31.cyan("wraps email workflows push")}`);
|
|
25053
|
-
console.log();
|
|
25054
|
-
}
|
|
25055
|
-
|
|
25056
24722
|
// src/commands/email/workflows/init.ts
|
|
25057
24723
|
init_esm_shims();
|
|
25058
24724
|
init_events();
|
|
25059
24725
|
init_json_output();
|
|
25060
24726
|
init_output();
|
|
25061
|
-
import { existsSync as
|
|
24727
|
+
import { existsSync as existsSync13 } from "fs";
|
|
25062
24728
|
import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile9 } from "fs/promises";
|
|
25063
|
-
import { join as
|
|
24729
|
+
import { join as join14 } from "path";
|
|
25064
24730
|
import * as clack30 from "@clack/prompts";
|
|
25065
|
-
import
|
|
24731
|
+
import pc31 from "picocolors";
|
|
25066
24732
|
|
|
25067
24733
|
// src/commands/email/workflows/claude-content.ts
|
|
25068
24734
|
init_esm_shims();
|
|
@@ -25075,8 +24741,6 @@ Workflow automation files live at \`wraps/workflows/*.ts\` and are written using
|
|
|
25075
24741
|
|
|
25076
24742
|
- \`wraps email workflows validate\` \u2014 Validate workflow files locally
|
|
25077
24743
|
- \`wraps email workflows push\` \u2014 Push workflows to the Wraps dashboard
|
|
25078
|
-
- \`wraps email workflows generate --template <name>\` \u2014 Generate from a built-in template
|
|
25079
|
-
- \`wraps email workflows generate "description"\` \u2014 Generate from a natural language description
|
|
25080
24744
|
|
|
25081
24745
|
### Quick Reference
|
|
25082
24746
|
|
|
@@ -25408,8 +25072,6 @@ export default defineWorkflow({
|
|
|
25408
25072
|
wraps email workflows validate # Validate all workflow files
|
|
25409
25073
|
wraps email workflows validate --workflow welcome # Validate a specific workflow
|
|
25410
25074
|
wraps email workflows push # Push workflows to dashboard
|
|
25411
|
-
wraps email workflows generate --template welcome # Generate from built-in template
|
|
25412
|
-
wraps email workflows generate "description..." # Generate from AI description
|
|
25413
25075
|
\`\`\`
|
|
25414
25076
|
`;
|
|
25415
25077
|
|
|
@@ -25455,12 +25117,12 @@ export default defineWorkflow({
|
|
|
25455
25117
|
async function workflowsInit(options) {
|
|
25456
25118
|
const startTime = Date.now();
|
|
25457
25119
|
const cwd = process.cwd();
|
|
25458
|
-
const workflowsDir =
|
|
25120
|
+
const workflowsDir = join14(cwd, "wraps", "workflows");
|
|
25459
25121
|
if (!isJsonMode()) {
|
|
25460
|
-
clack30.intro(
|
|
25122
|
+
clack30.intro(pc31.bold("Workflows as Code"));
|
|
25461
25123
|
}
|
|
25462
25124
|
const progress = new DeploymentProgress();
|
|
25463
|
-
if (
|
|
25125
|
+
if (existsSync13(workflowsDir) && !options.force) {
|
|
25464
25126
|
const { readdir: readdir4 } = await import("fs/promises");
|
|
25465
25127
|
const files = await readdir4(workflowsDir);
|
|
25466
25128
|
const tsFiles = files.filter(
|
|
@@ -25468,14 +25130,14 @@ async function workflowsInit(options) {
|
|
|
25468
25130
|
);
|
|
25469
25131
|
if (tsFiles.length > 0 && !options.force && !isJsonMode()) {
|
|
25470
25132
|
clack30.log.warn(
|
|
25471
|
-
`${
|
|
25133
|
+
`${pc31.cyan("wraps/workflows/")} already contains ${tsFiles.length} workflow file(s). Use ${pc31.bold("--force")} to overwrite.`
|
|
25472
25134
|
);
|
|
25473
25135
|
}
|
|
25474
25136
|
}
|
|
25475
25137
|
progress.start("Creating wraps/workflows/ directory");
|
|
25476
25138
|
await mkdir7(workflowsDir, { recursive: true });
|
|
25477
|
-
const configPath =
|
|
25478
|
-
if (
|
|
25139
|
+
const configPath = join14(cwd, "wraps", "wraps.config.ts");
|
|
25140
|
+
if (existsSync13(configPath)) {
|
|
25479
25141
|
const configContent = await readFile7(configPath, "utf-8");
|
|
25480
25142
|
if (!configContent.includes("workflowsDir")) {
|
|
25481
25143
|
const updated = configContent.replace(
|
|
@@ -25492,8 +25154,8 @@ async function workflowsInit(options) {
|
|
|
25492
25154
|
}
|
|
25493
25155
|
const filesCreated = [];
|
|
25494
25156
|
if (!options.noExample) {
|
|
25495
|
-
const examplePath =
|
|
25496
|
-
if (!
|
|
25157
|
+
const examplePath = join14(workflowsDir, "welcome.ts");
|
|
25158
|
+
if (!existsSync13(examplePath) || options.force) {
|
|
25497
25159
|
await writeFile9(examplePath, EXAMPLE_WORKFLOW, "utf-8");
|
|
25498
25160
|
filesCreated.push("wraps/workflows/welcome.ts");
|
|
25499
25161
|
}
|
|
@@ -25534,26 +25196,26 @@ async function workflowsInit(options) {
|
|
|
25534
25196
|
return;
|
|
25535
25197
|
}
|
|
25536
25198
|
console.log();
|
|
25537
|
-
clack30.log.success(
|
|
25199
|
+
clack30.log.success(pc31.green("Workflows as Code initialized!"));
|
|
25538
25200
|
console.log();
|
|
25539
|
-
console.log(` ${
|
|
25201
|
+
console.log(` ${pc31.dim("Directory:")} ${pc31.cyan("wraps/workflows/")}`);
|
|
25540
25202
|
if (!options.noExample) {
|
|
25541
25203
|
console.log(
|
|
25542
|
-
` ${
|
|
25204
|
+
` ${pc31.dim("Example:")} ${pc31.cyan("wraps/workflows/welcome.ts")}`
|
|
25543
25205
|
);
|
|
25544
25206
|
}
|
|
25545
25207
|
if (!options.noClaude) {
|
|
25546
25208
|
console.log(
|
|
25547
|
-
` ${
|
|
25209
|
+
` ${pc31.dim("AI Context:")} ${pc31.cyan(".claude/skills/wraps-workflows/")}`
|
|
25548
25210
|
);
|
|
25549
25211
|
}
|
|
25550
25212
|
console.log();
|
|
25551
|
-
console.log(`${
|
|
25213
|
+
console.log(`${pc31.bold("Next steps:")}`);
|
|
25552
25214
|
console.log(
|
|
25553
|
-
` 1. Edit or create workflows in ${
|
|
25215
|
+
` 1. Edit or create workflows in ${pc31.cyan("wraps/workflows/")}`
|
|
25554
25216
|
);
|
|
25555
|
-
console.log(` 2. Validate: ${
|
|
25556
|
-
console.log(` 3. Push: ${
|
|
25217
|
+
console.log(` 2. Validate: ${pc31.cyan("wraps email workflows validate")}`);
|
|
25218
|
+
console.log(` 3. Push: ${pc31.cyan("wraps email workflows push")}`);
|
|
25557
25219
|
if (!options.noClaude) {
|
|
25558
25220
|
console.log(" 4. Use Claude Code to generate workflows from descriptions");
|
|
25559
25221
|
}
|
|
@@ -25575,10 +25237,10 @@ export default defineConfig({
|
|
|
25575
25237
|
// src/commands/email/workflows/push.ts
|
|
25576
25238
|
init_esm_shims();
|
|
25577
25239
|
init_events();
|
|
25578
|
-
import { existsSync as
|
|
25579
|
-
import { join as
|
|
25240
|
+
import { existsSync as existsSync15 } from "fs";
|
|
25241
|
+
import { join as join16 } from "path";
|
|
25580
25242
|
import * as clack31 from "@clack/prompts";
|
|
25581
|
-
import
|
|
25243
|
+
import pc32 from "picocolors";
|
|
25582
25244
|
|
|
25583
25245
|
// src/utils/email/workflow-transform.ts
|
|
25584
25246
|
init_esm_shims();
|
|
@@ -25795,11 +25457,11 @@ function assignPositions(steps, transitions) {
|
|
|
25795
25457
|
// src/utils/email/workflow-ts.ts
|
|
25796
25458
|
init_esm_shims();
|
|
25797
25459
|
import { createHash as createHash2 } from "crypto";
|
|
25798
|
-
import { existsSync as
|
|
25460
|
+
import { existsSync as existsSync14 } from "fs";
|
|
25799
25461
|
import { mkdir as mkdir8, readdir as readdir3, readFile as readFile8, writeFile as writeFile10 } from "fs/promises";
|
|
25800
|
-
import { basename, join as
|
|
25462
|
+
import { basename, join as join15 } from "path";
|
|
25801
25463
|
async function discoverWorkflows(dir, filter) {
|
|
25802
|
-
if (!
|
|
25464
|
+
if (!existsSync14(dir)) {
|
|
25803
25465
|
return [];
|
|
25804
25466
|
}
|
|
25805
25467
|
const entries = await readdir3(dir);
|
|
@@ -25822,7 +25484,7 @@ async function parseWorkflowTs(filePath, wrapsDir) {
|
|
|
25822
25484
|
const source = await readFile8(filePath, "utf-8");
|
|
25823
25485
|
const sourceHash = createHash2("sha256").update(source).digest("hex");
|
|
25824
25486
|
const slug = basename(filePath, ".ts");
|
|
25825
|
-
const shimDir =
|
|
25487
|
+
const shimDir = join15(wrapsDir, ".wraps", "_shims");
|
|
25826
25488
|
await mkdir8(shimDir, { recursive: true });
|
|
25827
25489
|
const clientShimContent = `
|
|
25828
25490
|
// Identity functions for workflow definitions
|
|
@@ -26051,7 +25713,7 @@ function durationToSeconds(duration) {
|
|
|
26051
25713
|
}
|
|
26052
25714
|
`;
|
|
26053
25715
|
await writeFile10(
|
|
26054
|
-
|
|
25716
|
+
join15(shimDir, "wraps-client-shim.mjs"),
|
|
26055
25717
|
clientShimContent,
|
|
26056
25718
|
"utf-8"
|
|
26057
25719
|
);
|
|
@@ -26063,13 +25725,13 @@ function durationToSeconds(duration) {
|
|
|
26063
25725
|
platform: "node",
|
|
26064
25726
|
target: "node20",
|
|
26065
25727
|
alias: {
|
|
26066
|
-
"@wraps.dev/client":
|
|
25728
|
+
"@wraps.dev/client": join15(shimDir, "wraps-client-shim.mjs")
|
|
26067
25729
|
}
|
|
26068
25730
|
});
|
|
26069
25731
|
const bundledCode = result.outputFiles[0].text;
|
|
26070
|
-
const tmpDir =
|
|
25732
|
+
const tmpDir = join15(wrapsDir, ".wraps", "_workflows");
|
|
26071
25733
|
await mkdir8(tmpDir, { recursive: true });
|
|
26072
|
-
const tmpPath =
|
|
25734
|
+
const tmpPath = join15(tmpDir, `${slug}.mjs`);
|
|
26073
25735
|
await writeFile10(tmpPath, bundledCode, "utf-8");
|
|
26074
25736
|
const mod = await import(`${tmpPath}?t=${Date.now()}`);
|
|
26075
25737
|
const definition = mod.default;
|
|
@@ -26422,20 +26084,20 @@ init_output();
|
|
|
26422
26084
|
async function workflowsPush(options) {
|
|
26423
26085
|
const startTime = Date.now();
|
|
26424
26086
|
const cwd = process.cwd();
|
|
26425
|
-
const wrapsDir =
|
|
26426
|
-
const configPath =
|
|
26427
|
-
if (!
|
|
26087
|
+
const wrapsDir = join16(cwd, "wraps");
|
|
26088
|
+
const configPath = join16(wrapsDir, "wraps.config.ts");
|
|
26089
|
+
if (!existsSync15(configPath)) {
|
|
26428
26090
|
throw errors.wrapsConfigNotFound();
|
|
26429
26091
|
}
|
|
26430
26092
|
if (!isJsonMode()) {
|
|
26431
|
-
clack31.intro(
|
|
26093
|
+
clack31.intro(pc32.bold("Push Workflows"));
|
|
26432
26094
|
}
|
|
26433
26095
|
const progress = new DeploymentProgress();
|
|
26434
26096
|
progress.start("Loading configuration");
|
|
26435
26097
|
const config2 = await loadWrapsConfig(wrapsDir);
|
|
26436
26098
|
progress.succeed("Configuration loaded");
|
|
26437
|
-
const workflowsDir =
|
|
26438
|
-
if (!
|
|
26099
|
+
const workflowsDir = join16(wrapsDir, config2.workflowsDir || "./workflows");
|
|
26100
|
+
if (!existsSync15(workflowsDir)) {
|
|
26439
26101
|
if (isJsonMode()) {
|
|
26440
26102
|
jsonSuccess("email.workflows.push", {
|
|
26441
26103
|
pushed: [],
|
|
@@ -26461,9 +26123,9 @@ async function workflowsPush(options) {
|
|
|
26461
26123
|
return;
|
|
26462
26124
|
}
|
|
26463
26125
|
const lockfile = await loadLockfile(wrapsDir);
|
|
26464
|
-
const templatesDir =
|
|
26126
|
+
const templatesDir = join16(wrapsDir, config2.templatesDir || "./templates");
|
|
26465
26127
|
let localTemplateSlugs;
|
|
26466
|
-
if (
|
|
26128
|
+
if (existsSync15(templatesDir)) {
|
|
26467
26129
|
const templateFiles = await discoverTemplates(templatesDir);
|
|
26468
26130
|
localTemplateSlugs = new Set(
|
|
26469
26131
|
templateFiles.map((f) => f.replace(/\.tsx?$/, ""))
|
|
@@ -26475,14 +26137,14 @@ async function workflowsPush(options) {
|
|
|
26475
26137
|
const validationErrors = [];
|
|
26476
26138
|
for (const file of workflowFiles) {
|
|
26477
26139
|
const slug = file.replace(/\.ts$/, "");
|
|
26478
|
-
const filePath =
|
|
26479
|
-
progress.start(`Processing ${
|
|
26140
|
+
const filePath = join16(workflowsDir, file);
|
|
26141
|
+
progress.start(`Processing ${pc32.cyan(slug)}`);
|
|
26480
26142
|
try {
|
|
26481
26143
|
const parsed = await parseWorkflowTs(filePath, wrapsDir);
|
|
26482
26144
|
const localHashMatches = lockfile.workflows?.[slug]?.localHash === parsed.sourceHash;
|
|
26483
26145
|
if (!options.force && localHashMatches) {
|
|
26484
26146
|
unchanged.push(slug);
|
|
26485
|
-
progress.succeed(`${
|
|
26147
|
+
progress.succeed(`${pc32.cyan(slug)} unchanged`);
|
|
26486
26148
|
continue;
|
|
26487
26149
|
}
|
|
26488
26150
|
const transformed = transformWorkflow(parsed.definition);
|
|
@@ -26499,15 +26161,15 @@ async function workflowsPush(options) {
|
|
|
26499
26161
|
message: e.message
|
|
26500
26162
|
}))
|
|
26501
26163
|
});
|
|
26502
|
-
progress.fail(`${
|
|
26164
|
+
progress.fail(`${pc32.cyan(slug)} has validation errors`);
|
|
26503
26165
|
continue;
|
|
26504
26166
|
}
|
|
26505
26167
|
toProcess.push({ slug, parsed, transformed });
|
|
26506
|
-
progress.succeed(`${
|
|
26168
|
+
progress.succeed(`${pc32.cyan(slug)} validated`);
|
|
26507
26169
|
} catch (err) {
|
|
26508
26170
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
26509
26171
|
parseErrors.push({ slug, error: errMsg });
|
|
26510
|
-
progress.fail(`Failed to parse ${
|
|
26172
|
+
progress.fail(`Failed to parse ${pc32.cyan(slug)}: ${errMsg}`);
|
|
26511
26173
|
}
|
|
26512
26174
|
}
|
|
26513
26175
|
if (validationErrors.length > 0 || parseErrors.length > 0) {
|
|
@@ -26526,7 +26188,7 @@ async function workflowsPush(options) {
|
|
|
26526
26188
|
} else {
|
|
26527
26189
|
console.log();
|
|
26528
26190
|
clack31.log.error(
|
|
26529
|
-
|
|
26191
|
+
pc32.red("Cannot push due to validation errors. Fix errors and retry.")
|
|
26530
26192
|
);
|
|
26531
26193
|
console.log();
|
|
26532
26194
|
}
|
|
@@ -26561,15 +26223,15 @@ async function workflowsPush(options) {
|
|
|
26561
26223
|
});
|
|
26562
26224
|
} else {
|
|
26563
26225
|
console.log();
|
|
26564
|
-
clack31.log.info(
|
|
26226
|
+
clack31.log.info(pc32.bold("Dry run \u2014 no changes made"));
|
|
26565
26227
|
console.log();
|
|
26566
26228
|
for (const w of toProcess) {
|
|
26567
26229
|
console.log(
|
|
26568
|
-
` ${
|
|
26230
|
+
` ${pc32.green("\u25CF")} ${pc32.cyan(w.slug)} \u2014 ${w.parsed.definition.name} (${w.transformed.steps.length} steps)`
|
|
26569
26231
|
);
|
|
26570
26232
|
}
|
|
26571
26233
|
for (const slug of unchanged) {
|
|
26572
|
-
console.log(` ${
|
|
26234
|
+
console.log(` ${pc32.dim("\u25CB")} ${pc32.dim(slug)} \u2014 unchanged`);
|
|
26573
26235
|
}
|
|
26574
26236
|
console.log();
|
|
26575
26237
|
}
|
|
@@ -26619,12 +26281,12 @@ async function workflowsPush(options) {
|
|
|
26619
26281
|
console.log();
|
|
26620
26282
|
if (enabled.length > 0) {
|
|
26621
26283
|
clack31.log.success(
|
|
26622
|
-
|
|
26284
|
+
pc32.green(`${enabled.length} workflow(s) pushed and enabled`)
|
|
26623
26285
|
);
|
|
26624
26286
|
}
|
|
26625
26287
|
if (drafts.length > 0) {
|
|
26626
26288
|
clack31.log.success(
|
|
26627
|
-
|
|
26289
|
+
pc32.green(`${drafts.length} workflow(s) pushed as draft`)
|
|
26628
26290
|
);
|
|
26629
26291
|
}
|
|
26630
26292
|
if (unchanged.length > 0) {
|
|
@@ -26635,7 +26297,7 @@ async function workflowsPush(options) {
|
|
|
26635
26297
|
`${conflicts.length} workflow(s) skipped due to dashboard edits. Use --force to overwrite.`
|
|
26636
26298
|
);
|
|
26637
26299
|
for (const c of conflicts) {
|
|
26638
|
-
console.log(` ${
|
|
26300
|
+
console.log(` ${pc32.yellow("!")} ${pc32.cyan(c.slug)}`);
|
|
26639
26301
|
}
|
|
26640
26302
|
}
|
|
26641
26303
|
console.log();
|
|
@@ -26704,13 +26366,13 @@ async function pushToAPI2(workflows, token, progress, options) {
|
|
|
26704
26366
|
progress.succeed(`Synced ${successCount} workflows to dashboard`);
|
|
26705
26367
|
for (const c of data.conflicts ?? []) {
|
|
26706
26368
|
progress.fail(
|
|
26707
|
-
`${
|
|
26369
|
+
`${pc32.cyan(c.slug)} was edited on the dashboard. Use ${pc32.bold("--force")} to overwrite.`
|
|
26708
26370
|
);
|
|
26709
26371
|
}
|
|
26710
26372
|
} else if (conflictCount > 0) {
|
|
26711
26373
|
for (const c of data.conflicts ?? []) {
|
|
26712
26374
|
progress.fail(
|
|
26713
|
-
`${
|
|
26375
|
+
`${pc32.cyan(c.slug)} was edited on the dashboard. Use ${pc32.bold("--force")} to overwrite.`
|
|
26714
26376
|
);
|
|
26715
26377
|
}
|
|
26716
26378
|
}
|
|
@@ -26738,7 +26400,7 @@ async function pushToAPI2(workflows, token, progress, options) {
|
|
|
26738
26400
|
}
|
|
26739
26401
|
} else if (workflows.length === 1) {
|
|
26740
26402
|
const w = workflows[0];
|
|
26741
|
-
progress.start(`Syncing ${
|
|
26403
|
+
progress.start(`Syncing ${pc32.cyan(w.slug)} to dashboard`);
|
|
26742
26404
|
try {
|
|
26743
26405
|
const resp = await fetch(`${apiBase}/v1/workflows/push`, {
|
|
26744
26406
|
method: "POST",
|
|
@@ -26766,7 +26428,7 @@ async function pushToAPI2(workflows, token, progress, options) {
|
|
|
26766
26428
|
if (Number(resp.status) === 409) {
|
|
26767
26429
|
results.push({ slug: w.slug, success: false, conflict: true });
|
|
26768
26430
|
progress.fail(
|
|
26769
|
-
`${
|
|
26431
|
+
`${pc32.cyan(w.slug)} was edited on the dashboard since last push. Use ${pc32.bold("--force")} to overwrite.`
|
|
26770
26432
|
);
|
|
26771
26433
|
} else if (resp.ok) {
|
|
26772
26434
|
const data = await resp.json();
|
|
@@ -26776,7 +26438,7 @@ async function pushToAPI2(workflows, token, progress, options) {
|
|
|
26776
26438
|
status: data.status,
|
|
26777
26439
|
success: true
|
|
26778
26440
|
});
|
|
26779
|
-
progress.succeed(`Synced ${
|
|
26441
|
+
progress.succeed(`Synced ${pc32.cyan(w.slug)} to dashboard`);
|
|
26780
26442
|
} else {
|
|
26781
26443
|
const body = await resp.text();
|
|
26782
26444
|
throw new Error(`API returned ${resp.status}: ${body}`);
|
|
@@ -26793,30 +26455,30 @@ async function pushToAPI2(workflows, token, progress, options) {
|
|
|
26793
26455
|
// src/commands/email/workflows/validate.ts
|
|
26794
26456
|
init_esm_shims();
|
|
26795
26457
|
init_events();
|
|
26796
|
-
import { existsSync as
|
|
26797
|
-
import { join as
|
|
26458
|
+
import { existsSync as existsSync16 } from "fs";
|
|
26459
|
+
import { join as join17 } from "path";
|
|
26798
26460
|
import * as clack32 from "@clack/prompts";
|
|
26799
|
-
import
|
|
26461
|
+
import pc33 from "picocolors";
|
|
26800
26462
|
init_errors();
|
|
26801
26463
|
init_json_output();
|
|
26802
26464
|
init_output();
|
|
26803
26465
|
async function workflowsValidate(options) {
|
|
26804
26466
|
const startTime = Date.now();
|
|
26805
26467
|
const cwd = process.cwd();
|
|
26806
|
-
const wrapsDir =
|
|
26807
|
-
const configPath =
|
|
26808
|
-
if (!
|
|
26468
|
+
const wrapsDir = join17(cwd, "wraps");
|
|
26469
|
+
const configPath = join17(wrapsDir, "wraps.config.ts");
|
|
26470
|
+
if (!existsSync16(configPath)) {
|
|
26809
26471
|
throw errors.wrapsConfigNotFound();
|
|
26810
26472
|
}
|
|
26811
26473
|
if (!isJsonMode()) {
|
|
26812
|
-
clack32.intro(
|
|
26474
|
+
clack32.intro(pc33.bold("Validate Workflows"));
|
|
26813
26475
|
}
|
|
26814
26476
|
const progress = new DeploymentProgress();
|
|
26815
26477
|
progress.start("Loading configuration");
|
|
26816
26478
|
const config2 = await loadWrapsConfig(wrapsDir);
|
|
26817
26479
|
progress.succeed("Configuration loaded");
|
|
26818
|
-
const workflowsDir =
|
|
26819
|
-
if (!
|
|
26480
|
+
const workflowsDir = join17(wrapsDir, config2.workflowsDir || "./workflows");
|
|
26481
|
+
if (!existsSync16(workflowsDir)) {
|
|
26820
26482
|
if (isJsonMode()) {
|
|
26821
26483
|
jsonSuccess("email.workflows.validate", { workflows: [], errors: [] });
|
|
26822
26484
|
} else {
|
|
@@ -26833,9 +26495,9 @@ async function workflowsValidate(options) {
|
|
|
26833
26495
|
}
|
|
26834
26496
|
return;
|
|
26835
26497
|
}
|
|
26836
|
-
const templatesDir =
|
|
26498
|
+
const templatesDir = join17(wrapsDir, config2.templatesDir || "./templates");
|
|
26837
26499
|
let localTemplateSlugs;
|
|
26838
|
-
if (
|
|
26500
|
+
if (existsSync16(templatesDir)) {
|
|
26839
26501
|
const templateFiles = await discoverTemplates(templatesDir);
|
|
26840
26502
|
localTemplateSlugs = new Set(
|
|
26841
26503
|
templateFiles.map((f) => f.replace(/\.tsx?$/, ""))
|
|
@@ -26845,8 +26507,8 @@ async function workflowsValidate(options) {
|
|
|
26845
26507
|
const parseErrors = [];
|
|
26846
26508
|
for (const file of workflowFiles) {
|
|
26847
26509
|
const slug = file.replace(/\.ts$/, "");
|
|
26848
|
-
const filePath =
|
|
26849
|
-
progress.start(`Validating ${
|
|
26510
|
+
const filePath = join17(workflowsDir, file);
|
|
26511
|
+
progress.start(`Validating ${pc33.cyan(slug)}`);
|
|
26850
26512
|
try {
|
|
26851
26513
|
const parsed = await parseWorkflowTs(filePath, wrapsDir);
|
|
26852
26514
|
const transformed = transformWorkflow(parsed.definition);
|
|
@@ -26871,20 +26533,20 @@ async function workflowsValidate(options) {
|
|
|
26871
26533
|
}))
|
|
26872
26534
|
});
|
|
26873
26535
|
if (errs.length === 0 && warnings.length === 0) {
|
|
26874
|
-
progress.succeed(`${
|
|
26536
|
+
progress.succeed(`${pc33.cyan(slug)} is valid`);
|
|
26875
26537
|
} else if (errs.length === 0) {
|
|
26876
26538
|
progress.succeed(
|
|
26877
|
-
`${
|
|
26539
|
+
`${pc33.cyan(slug)} is valid with ${warnings.length} warning(s)`
|
|
26878
26540
|
);
|
|
26879
26541
|
} else {
|
|
26880
26542
|
progress.fail(
|
|
26881
|
-
`${
|
|
26543
|
+
`${pc33.cyan(slug)} has ${errs.length} error(s), ${warnings.length} warning(s)`
|
|
26882
26544
|
);
|
|
26883
26545
|
}
|
|
26884
26546
|
} catch (err) {
|
|
26885
26547
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
26886
26548
|
parseErrors.push({ slug, error: errMsg });
|
|
26887
|
-
progress.fail(`Failed to parse ${
|
|
26549
|
+
progress.fail(`Failed to parse ${pc33.cyan(slug)}: ${errMsg}`);
|
|
26888
26550
|
}
|
|
26889
26551
|
}
|
|
26890
26552
|
if (isJsonMode()) {
|
|
@@ -26907,34 +26569,34 @@ async function workflowsValidate(options) {
|
|
|
26907
26569
|
const parseErrorCount = parseErrors.length;
|
|
26908
26570
|
if (parseErrorCount === 0 && invalidCount === 0) {
|
|
26909
26571
|
clack32.log.success(
|
|
26910
|
-
|
|
26572
|
+
pc33.green(`${validCount} workflow(s) validated successfully`)
|
|
26911
26573
|
);
|
|
26912
26574
|
} else {
|
|
26913
26575
|
if (validCount > 0) {
|
|
26914
|
-
clack32.log.success(
|
|
26576
|
+
clack32.log.success(pc33.green(`${validCount} workflow(s) valid`));
|
|
26915
26577
|
}
|
|
26916
26578
|
if (invalidCount > 0) {
|
|
26917
|
-
clack32.log.error(
|
|
26579
|
+
clack32.log.error(pc33.red(`${invalidCount} workflow(s) have errors`));
|
|
26918
26580
|
}
|
|
26919
26581
|
if (parseErrorCount > 0) {
|
|
26920
26582
|
clack32.log.error(
|
|
26921
|
-
|
|
26583
|
+
pc33.red(`${parseErrorCount} workflow(s) failed to parse`)
|
|
26922
26584
|
);
|
|
26923
26585
|
}
|
|
26924
26586
|
console.log();
|
|
26925
26587
|
for (const result of validationResults) {
|
|
26926
26588
|
if (!result.valid) {
|
|
26927
|
-
console.log(` ${
|
|
26589
|
+
console.log(` ${pc33.cyan(result.slug)}:`);
|
|
26928
26590
|
for (const err of result.errors) {
|
|
26929
26591
|
console.log(
|
|
26930
|
-
` ${
|
|
26592
|
+
` ${pc33.red("\u2715")} ${err.nodeId ? `[${err.nodeId}] ` : ""}${err.message}`
|
|
26931
26593
|
);
|
|
26932
26594
|
}
|
|
26933
26595
|
}
|
|
26934
26596
|
}
|
|
26935
26597
|
for (const parseErr of parseErrors) {
|
|
26936
|
-
console.log(` ${
|
|
26937
|
-
console.log(` ${
|
|
26598
|
+
console.log(` ${pc33.cyan(parseErr.slug)}:`);
|
|
26599
|
+
console.log(` ${pc33.red("\u2715")} Parse error: ${parseErr.error}`);
|
|
26938
26600
|
}
|
|
26939
26601
|
}
|
|
26940
26602
|
console.log();
|
|
@@ -26952,18 +26614,18 @@ async function workflowsValidate(options) {
|
|
|
26952
26614
|
init_esm_shims();
|
|
26953
26615
|
init_events();
|
|
26954
26616
|
import * as clack33 from "@clack/prompts";
|
|
26955
|
-
import
|
|
26617
|
+
import pc34 from "picocolors";
|
|
26956
26618
|
async function news() {
|
|
26957
26619
|
trackCommand("news", { success: true });
|
|
26958
|
-
clack33.intro(
|
|
26620
|
+
clack33.intro(pc34.bold("What's New in Wraps"));
|
|
26959
26621
|
console.log();
|
|
26960
26622
|
console.log(" See the latest updates, features, and improvements:");
|
|
26961
26623
|
console.log();
|
|
26962
26624
|
console.log(
|
|
26963
|
-
` ${
|
|
26625
|
+
` ${pc34.cyan("\u2192")} ${pc34.bold("Changelog:")} ${pc34.cyan("https://wraps.dev/changelog")}`
|
|
26964
26626
|
);
|
|
26965
26627
|
console.log();
|
|
26966
|
-
console.log(
|
|
26628
|
+
console.log(pc34.dim(" Subscribe to get notified about new releases."));
|
|
26967
26629
|
console.log();
|
|
26968
26630
|
}
|
|
26969
26631
|
|
|
@@ -26972,7 +26634,7 @@ init_esm_shims();
|
|
|
26972
26634
|
init_events();
|
|
26973
26635
|
init_json_output();
|
|
26974
26636
|
import * as clack34 from "@clack/prompts";
|
|
26975
|
-
import
|
|
26637
|
+
import pc35 from "picocolors";
|
|
26976
26638
|
function getBaseStatements() {
|
|
26977
26639
|
return [
|
|
26978
26640
|
{
|
|
@@ -27363,74 +27025,74 @@ function buildPolicy(service, preset) {
|
|
|
27363
27025
|
};
|
|
27364
27026
|
}
|
|
27365
27027
|
function displaySummary(service, preset) {
|
|
27366
|
-
clack34.intro(
|
|
27028
|
+
clack34.intro(pc35.bold("Wraps Required AWS Permissions"));
|
|
27367
27029
|
const serviceLabel = service ? service.toUpperCase() : "All Services";
|
|
27368
27030
|
const presetLabel = preset ? preset.charAt(0).toUpperCase() + preset.slice(1) : "All Features";
|
|
27369
27031
|
console.log(`
|
|
27370
|
-
${
|
|
27371
|
-
console.log(`${
|
|
27032
|
+
${pc35.dim("Service:")} ${pc35.cyan(serviceLabel)}`);
|
|
27033
|
+
console.log(`${pc35.dim("Preset:")} ${pc35.cyan(presetLabel)}
|
|
27372
27034
|
`);
|
|
27373
|
-
console.log(
|
|
27374
|
-
console.log(` ${
|
|
27375
|
-
console.log(` ${
|
|
27376
|
-
console.log(` ${
|
|
27035
|
+
console.log(pc35.bold("Required AWS Services:\n"));
|
|
27036
|
+
console.log(` ${pc35.green("+")} ${pc35.bold("IAM")} - Role management`);
|
|
27037
|
+
console.log(` ${pc35.green("+")} ${pc35.bold("STS")} - Credential validation`);
|
|
27038
|
+
console.log(` ${pc35.green("+")} ${pc35.bold("CloudWatch")} - Metrics access`);
|
|
27377
27039
|
console.log(
|
|
27378
|
-
` ${
|
|
27040
|
+
` ${pc35.green("+")} ${pc35.bold("S3")} - State management ${pc35.dim("(wraps-state-* buckets)")}`
|
|
27379
27041
|
);
|
|
27380
27042
|
if (!service || service === "email") {
|
|
27381
27043
|
console.log(
|
|
27382
|
-
` ${
|
|
27044
|
+
` ${pc35.green("+")} ${pc35.bold("SES")} - Email sending & configuration`
|
|
27383
27045
|
);
|
|
27384
27046
|
if (!preset || preset === "production" || preset === "enterprise") {
|
|
27385
27047
|
console.log(
|
|
27386
|
-
` ${
|
|
27048
|
+
` ${pc35.green("+")} ${pc35.bold("EventBridge")} - Event routing (Production+)`
|
|
27387
27049
|
);
|
|
27388
27050
|
console.log(
|
|
27389
|
-
` ${
|
|
27051
|
+
` ${pc35.green("+")} ${pc35.bold("SQS")} - Event queuing (Production+)`
|
|
27390
27052
|
);
|
|
27391
27053
|
console.log(
|
|
27392
|
-
` ${
|
|
27054
|
+
` ${pc35.green("+")} ${pc35.bold("Lambda")} - Event processing (Production+)`
|
|
27393
27055
|
);
|
|
27394
27056
|
console.log(
|
|
27395
|
-
` ${
|
|
27057
|
+
` ${pc35.green("+")} ${pc35.bold("DynamoDB")} - Email history (Production+)`
|
|
27396
27058
|
);
|
|
27397
27059
|
}
|
|
27398
27060
|
console.log(
|
|
27399
|
-
` ${
|
|
27061
|
+
` ${pc35.yellow("?")} ${pc35.bold("Route53")} - Auto DNS ${pc35.dim("(optional)")}`
|
|
27400
27062
|
);
|
|
27401
27063
|
console.log(
|
|
27402
|
-
` ${
|
|
27064
|
+
` ${pc35.yellow("?")} ${pc35.bold("IAM OIDC")} - Vercel integration ${pc35.dim("(if using Vercel)")}`
|
|
27403
27065
|
);
|
|
27404
27066
|
}
|
|
27405
27067
|
if (!service || service === "sms") {
|
|
27406
27068
|
console.log(
|
|
27407
|
-
` ${
|
|
27069
|
+
` ${pc35.green("+")} ${pc35.bold("SMS Voice")} - SMS sending & management`
|
|
27408
27070
|
);
|
|
27409
|
-
console.log(` ${
|
|
27410
|
-
console.log(` ${
|
|
27071
|
+
console.log(` ${pc35.green("+")} ${pc35.bold("DynamoDB")} - Message history`);
|
|
27072
|
+
console.log(` ${pc35.green("+")} ${pc35.bold("Lambda")} - Event processing`);
|
|
27411
27073
|
}
|
|
27412
27074
|
if (!service || service === "cdn") {
|
|
27413
|
-
console.log(` ${
|
|
27075
|
+
console.log(` ${pc35.green("+")} ${pc35.bold("S3")} - Asset storage`);
|
|
27414
27076
|
console.log(
|
|
27415
|
-
` ${
|
|
27077
|
+
` ${pc35.green("+")} ${pc35.bold("CloudFront")} - CDN distribution`
|
|
27416
27078
|
);
|
|
27417
|
-
console.log(` ${
|
|
27079
|
+
console.log(` ${pc35.green("+")} ${pc35.bold("ACM")} - SSL certificates`);
|
|
27418
27080
|
console.log(
|
|
27419
|
-
` ${
|
|
27081
|
+
` ${pc35.yellow("?")} ${pc35.bold("Route53")} - DNS management ${pc35.dim("(optional)")}`
|
|
27420
27082
|
);
|
|
27421
27083
|
}
|
|
27422
27084
|
console.log(`
|
|
27423
|
-
${
|
|
27424
|
-
console.log(` ${
|
|
27085
|
+
${pc35.dim("Get full IAM policy JSON:")}`);
|
|
27086
|
+
console.log(` ${pc35.cyan("wraps permissions --json")}`);
|
|
27425
27087
|
if (service) {
|
|
27426
27088
|
console.log(`
|
|
27427
|
-
${
|
|
27428
|
-
console.log(` ${
|
|
27089
|
+
${pc35.dim("Get permissions for all services:")}`);
|
|
27090
|
+
console.log(` ${pc35.cyan("wraps permissions")}`);
|
|
27429
27091
|
}
|
|
27430
27092
|
console.log(`
|
|
27431
|
-
${
|
|
27093
|
+
${pc35.dim("Documentation:")}`);
|
|
27432
27094
|
console.log(
|
|
27433
|
-
` ${
|
|
27095
|
+
` ${pc35.blue("https://wraps.dev/docs/guides/aws-setup/permissions")}
|
|
27434
27096
|
`
|
|
27435
27097
|
);
|
|
27436
27098
|
}
|
|
@@ -27448,17 +27110,17 @@ async function permissions(options) {
|
|
|
27448
27110
|
});
|
|
27449
27111
|
} else {
|
|
27450
27112
|
displaySummary(options.service, options.preset);
|
|
27451
|
-
console.log(
|
|
27113
|
+
console.log(pc35.bold("Quick Setup:\n"));
|
|
27452
27114
|
console.log("1. Copy the IAM policy:");
|
|
27453
27115
|
console.log(
|
|
27454
|
-
` ${
|
|
27116
|
+
` ${pc35.cyan("wraps permissions --json > wraps-policy.json")}
|
|
27455
27117
|
`
|
|
27456
27118
|
);
|
|
27457
27119
|
console.log("2. Create the policy in AWS Console:");
|
|
27458
27120
|
console.log(" IAM > Policies > Create Policy > JSON\n");
|
|
27459
27121
|
console.log("3. Attach to your IAM user/role\n");
|
|
27460
27122
|
clack34.outro(
|
|
27461
|
-
|
|
27123
|
+
pc35.green("Run with --json to get the full IAM policy document")
|
|
27462
27124
|
);
|
|
27463
27125
|
}
|
|
27464
27126
|
trackCommand("permissions", {
|
|
@@ -27475,9 +27137,9 @@ import {
|
|
|
27475
27137
|
IAMClient as IAMClient2,
|
|
27476
27138
|
PutRolePolicyCommand
|
|
27477
27139
|
} from "@aws-sdk/client-iam";
|
|
27478
|
-
import { confirm as confirm14, intro as
|
|
27140
|
+
import { confirm as confirm14, intro as intro32, isCancel as isCancel20, log as log32, outro as outro19, select as select14 } from "@clack/prompts";
|
|
27479
27141
|
import * as pulumi21 from "@pulumi/pulumi";
|
|
27480
|
-
import
|
|
27142
|
+
import pc36 from "picocolors";
|
|
27481
27143
|
init_events();
|
|
27482
27144
|
init_aws();
|
|
27483
27145
|
init_config();
|
|
@@ -27655,7 +27317,7 @@ async function validateAndLoadMetadata(options, progress) {
|
|
|
27655
27317
|
"Validating AWS credentials",
|
|
27656
27318
|
async () => validateAWSCredentials()
|
|
27657
27319
|
);
|
|
27658
|
-
progress.info(`Connected to AWS account: ${
|
|
27320
|
+
progress.info(`Connected to AWS account: ${pc36.cyan(identity.accountId)}`);
|
|
27659
27321
|
let region = options.region;
|
|
27660
27322
|
if (!region) {
|
|
27661
27323
|
region = await getAWSRegion();
|
|
@@ -27663,12 +27325,12 @@ async function validateAndLoadMetadata(options, progress) {
|
|
|
27663
27325
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
27664
27326
|
if (!metadata) {
|
|
27665
27327
|
progress.stop();
|
|
27666
|
-
|
|
27667
|
-
`No Wraps deployment found for account ${
|
|
27328
|
+
log32.error(
|
|
27329
|
+
`No Wraps deployment found for account ${pc36.cyan(identity.accountId)} in region ${pc36.cyan(region)}`
|
|
27668
27330
|
);
|
|
27669
27331
|
console.log(
|
|
27670
27332
|
`
|
|
27671
|
-
Run ${
|
|
27333
|
+
Run ${pc36.cyan("wraps email init")} to deploy infrastructure first.
|
|
27672
27334
|
`
|
|
27673
27335
|
);
|
|
27674
27336
|
process.exit(1);
|
|
@@ -27677,10 +27339,10 @@ Run ${pc37.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
27677
27339
|
const hasSms = !!metadata.services.sms?.config;
|
|
27678
27340
|
if (!(hasEmail || hasSms)) {
|
|
27679
27341
|
progress.stop();
|
|
27680
|
-
|
|
27342
|
+
log32.error("No services deployed in this region.");
|
|
27681
27343
|
console.log(
|
|
27682
27344
|
`
|
|
27683
|
-
Run ${
|
|
27345
|
+
Run ${pc36.cyan("wraps email init")} or ${pc36.cyan("wraps sms init")} first.
|
|
27684
27346
|
`
|
|
27685
27347
|
);
|
|
27686
27348
|
process.exit(1);
|
|
@@ -27805,7 +27467,7 @@ async function updatePlatformRole(metadata, progress, externalId) {
|
|
|
27805
27467
|
progress.succeed("Platform access role created");
|
|
27806
27468
|
} else {
|
|
27807
27469
|
progress.info(
|
|
27808
|
-
`IAM role ${
|
|
27470
|
+
`IAM role ${pc36.cyan(roleName)} will be created when you add your AWS account in the dashboard`
|
|
27809
27471
|
);
|
|
27810
27472
|
}
|
|
27811
27473
|
}
|
|
@@ -27859,7 +27521,7 @@ async function registerConnection(params) {
|
|
|
27859
27521
|
async function authenticatedConnect(token, options) {
|
|
27860
27522
|
const startTime = Date.now();
|
|
27861
27523
|
if (!isJsonMode()) {
|
|
27862
|
-
|
|
27524
|
+
intro32(pc36.bold("Connect to Wraps Platform"));
|
|
27863
27525
|
}
|
|
27864
27526
|
const progress = new DeploymentProgress();
|
|
27865
27527
|
try {
|
|
@@ -27871,20 +27533,20 @@ async function authenticatedConnect(token, options) {
|
|
|
27871
27533
|
const org = await resolveOrganization();
|
|
27872
27534
|
if (!org) {
|
|
27873
27535
|
progress.stop();
|
|
27874
|
-
|
|
27536
|
+
log32.error(
|
|
27875
27537
|
"No organizations found. Sign in at https://app.wraps.dev to create one."
|
|
27876
27538
|
);
|
|
27877
27539
|
process.exit(1);
|
|
27878
27540
|
}
|
|
27879
27541
|
if (!isJsonMode()) {
|
|
27880
|
-
progress.info(`Organization: ${
|
|
27542
|
+
progress.info(`Organization: ${pc36.cyan(org.name)}`);
|
|
27881
27543
|
}
|
|
27882
27544
|
if (hasEmail) {
|
|
27883
27545
|
const emailConfig = metadata.services.email?.config;
|
|
27884
27546
|
if (!emailConfig?.eventTracking?.enabled) {
|
|
27885
27547
|
if (!isJsonMode()) {
|
|
27886
27548
|
progress.stop();
|
|
27887
|
-
|
|
27549
|
+
log32.warn(
|
|
27888
27550
|
"Event tracking must be enabled to connect to the Wraps Platform."
|
|
27889
27551
|
);
|
|
27890
27552
|
}
|
|
@@ -27934,12 +27596,12 @@ async function authenticatedConnect(token, options) {
|
|
|
27934
27596
|
);
|
|
27935
27597
|
if (!(result.success && result.webhookSecret)) {
|
|
27936
27598
|
progress.stop();
|
|
27937
|
-
|
|
27599
|
+
log32.error(
|
|
27938
27600
|
`Failed to register connection: ${result.error || "Unknown error"}`
|
|
27939
27601
|
);
|
|
27940
27602
|
console.log(
|
|
27941
27603
|
`
|
|
27942
|
-
You can try the manual flow: ${
|
|
27604
|
+
You can try the manual flow: ${pc36.cyan("wraps auth logout")} then ${pc36.cyan("wraps platform connect")}
|
|
27943
27605
|
`
|
|
27944
27606
|
);
|
|
27945
27607
|
process.exit(1);
|
|
@@ -27967,10 +27629,10 @@ You can try the manual flow: ${pc37.cyan("wraps auth logout")} then ${pc37.cyan(
|
|
|
27967
27629
|
} catch (error) {
|
|
27968
27630
|
const errName = error && typeof error === "object" && "name" in error ? error.name : "Unknown";
|
|
27969
27631
|
const errMsg = error instanceof Error ? error.message : String(error);
|
|
27970
|
-
|
|
27632
|
+
log32.warn(
|
|
27971
27633
|
`Could not create/update IAM role (${errName}): ${errMsg}
|
|
27972
|
-
You may need ${
|
|
27973
|
-
Run ${
|
|
27634
|
+
You may need ${pc36.cyan("iam:GetRole")}, ${pc36.cyan("iam:CreateRole")}, and ${pc36.cyan("iam:PutRolePolicy")} permissions.
|
|
27635
|
+
Run ${pc36.cyan("wraps platform update-role")} to retry.`
|
|
27974
27636
|
);
|
|
27975
27637
|
}
|
|
27976
27638
|
await saveConnectionMetadata(metadata);
|
|
@@ -27984,14 +27646,14 @@ You can try the manual flow: ${pc37.cyan("wraps auth logout")} then ${pc37.cyan(
|
|
|
27984
27646
|
webhookConnected: true
|
|
27985
27647
|
});
|
|
27986
27648
|
} else {
|
|
27987
|
-
outro19(
|
|
27649
|
+
outro19(pc36.green("Platform connection complete!"));
|
|
27988
27650
|
console.log();
|
|
27989
27651
|
console.log(
|
|
27990
|
-
|
|
27652
|
+
pc36.dim(
|
|
27991
27653
|
"Events from your AWS infrastructure will stream to the dashboard."
|
|
27992
27654
|
)
|
|
27993
27655
|
);
|
|
27994
|
-
console.log(` Dashboard: ${
|
|
27656
|
+
console.log(` Dashboard: ${pc36.cyan("https://app.wraps.dev")}`);
|
|
27995
27657
|
console.log();
|
|
27996
27658
|
}
|
|
27997
27659
|
const duration = Date.now() - startTime;
|
|
@@ -28022,7 +27684,7 @@ async function connect3(options) {
|
|
|
28022
27684
|
return;
|
|
28023
27685
|
}
|
|
28024
27686
|
const startTime = Date.now();
|
|
28025
|
-
|
|
27687
|
+
intro32(pc36.bold("Connect to Wraps Platform"));
|
|
28026
27688
|
const progress = new DeploymentProgress();
|
|
28027
27689
|
try {
|
|
28028
27690
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -28036,7 +27698,7 @@ async function connect3(options) {
|
|
|
28036
27698
|
"Validating AWS credentials",
|
|
28037
27699
|
async () => validateAWSCredentials()
|
|
28038
27700
|
);
|
|
28039
|
-
progress.info(`Connected to AWS account: ${
|
|
27701
|
+
progress.info(`Connected to AWS account: ${pc36.cyan(identity.accountId)}`);
|
|
28040
27702
|
let region = options.region;
|
|
28041
27703
|
if (!region) {
|
|
28042
27704
|
region = await getAWSRegion();
|
|
@@ -28044,12 +27706,12 @@ async function connect3(options) {
|
|
|
28044
27706
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
28045
27707
|
if (!metadata) {
|
|
28046
27708
|
progress.stop();
|
|
28047
|
-
|
|
28048
|
-
`No Wraps deployment found for account ${
|
|
27709
|
+
log32.error(
|
|
27710
|
+
`No Wraps deployment found for account ${pc36.cyan(identity.accountId)} in region ${pc36.cyan(region)}`
|
|
28049
27711
|
);
|
|
28050
27712
|
console.log(
|
|
28051
27713
|
`
|
|
28052
|
-
Run ${
|
|
27714
|
+
Run ${pc36.cyan("wraps email init")} to deploy infrastructure first.
|
|
28053
27715
|
`
|
|
28054
27716
|
);
|
|
28055
27717
|
process.exit(1);
|
|
@@ -28058,10 +27720,10 @@ Run ${pc37.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
28058
27720
|
const hasSms = !!metadata.services.sms?.config;
|
|
28059
27721
|
if (!(hasEmail || hasSms)) {
|
|
28060
27722
|
progress.stop();
|
|
28061
|
-
|
|
27723
|
+
log32.error("No services deployed in this region.");
|
|
28062
27724
|
console.log(
|
|
28063
27725
|
`
|
|
28064
|
-
Run ${
|
|
27726
|
+
Run ${pc36.cyan("wraps email init")} or ${pc36.cyan("wraps sms init")} first.
|
|
28065
27727
|
`
|
|
28066
27728
|
);
|
|
28067
27729
|
process.exit(1);
|
|
@@ -28076,10 +27738,10 @@ Run ${pc37.cyan("wraps email init")} or ${pc37.cyan("wraps sms init")} first.
|
|
|
28076
27738
|
const existingSecret = metadata.services.email?.webhookSecret;
|
|
28077
27739
|
if (!emailConfig?.eventTracking?.enabled) {
|
|
28078
27740
|
progress.stop();
|
|
28079
|
-
|
|
27741
|
+
log32.warn(
|
|
28080
27742
|
"Event tracking must be enabled to connect to the Wraps Platform."
|
|
28081
27743
|
);
|
|
28082
|
-
|
|
27744
|
+
log32.info(
|
|
28083
27745
|
"Enabling event tracking will allow SES events to be streamed to the dashboard."
|
|
28084
27746
|
);
|
|
28085
27747
|
const enableEventTracking = await confirm14({
|
|
@@ -28111,8 +27773,8 @@ Run ${pc37.cyan("wraps email init")} or ${pc37.cyan("wraps sms init")} first.
|
|
|
28111
27773
|
}
|
|
28112
27774
|
if (existingSecret) {
|
|
28113
27775
|
progress.stop();
|
|
28114
|
-
|
|
28115
|
-
`Already connected to Wraps Platform (AWS Account: ${
|
|
27776
|
+
log32.info(
|
|
27777
|
+
`Already connected to Wraps Platform (AWS Account: ${pc36.cyan(metadata.accountId)})`
|
|
28116
27778
|
);
|
|
28117
27779
|
const action = await select14({
|
|
28118
27780
|
message: "What would you like to do?",
|
|
@@ -28239,36 +27901,36 @@ Run ${pc37.cyan("wraps email init")} or ${pc37.cyan("wraps sms init")} first.
|
|
|
28239
27901
|
progress.succeed("Platform access role updated");
|
|
28240
27902
|
} else {
|
|
28241
27903
|
progress.info(
|
|
28242
|
-
`IAM role ${
|
|
27904
|
+
`IAM role ${pc36.cyan(roleName)} will be created when you add your AWS account in the dashboard`
|
|
28243
27905
|
);
|
|
28244
27906
|
}
|
|
28245
27907
|
await saveConnectionMetadata(metadata);
|
|
28246
27908
|
progress.stop();
|
|
28247
|
-
outro19(
|
|
27909
|
+
outro19(pc36.green("Platform connection complete!"));
|
|
28248
27910
|
if (webhookSecret && needsDeployment) {
|
|
28249
27911
|
console.log(`
|
|
28250
|
-
${
|
|
28251
|
-
console.log(
|
|
28252
|
-
console.log(` ${
|
|
28253
|
-
console.log(
|
|
27912
|
+
${pc36.bold("Webhook Secret")} ${pc36.dim("(save this!)")}`);
|
|
27913
|
+
console.log(pc36.dim("\u2500".repeat(60)));
|
|
27914
|
+
console.log(` ${pc36.cyan(webhookSecret)}`);
|
|
27915
|
+
console.log(pc36.dim("\u2500".repeat(60)));
|
|
28254
27916
|
} else if (metadata.services.email?.webhookSecret && !needsDeployment) {
|
|
28255
27917
|
console.log(`
|
|
28256
|
-
${
|
|
28257
|
-
console.log(
|
|
28258
|
-
console.log(` ${
|
|
28259
|
-
console.log(
|
|
27918
|
+
${pc36.bold("Existing Webhook Secret:")}`);
|
|
27919
|
+
console.log(pc36.dim("\u2500".repeat(60)));
|
|
27920
|
+
console.log(` ${pc36.cyan(metadata.services.email.webhookSecret)}`);
|
|
27921
|
+
console.log(pc36.dim("\u2500".repeat(60)));
|
|
28260
27922
|
}
|
|
28261
27923
|
console.log(`
|
|
28262
|
-
${
|
|
28263
|
-
console.log(` 1. Go to ${
|
|
28264
|
-
console.log(` 2. Navigate to ${
|
|
28265
|
-
console.log(` 3. Add your AWS account: ${
|
|
27924
|
+
${pc36.bold("Next Steps:")}`);
|
|
27925
|
+
console.log(` 1. Go to ${pc36.cyan("https://app.wraps.dev")}`);
|
|
27926
|
+
console.log(` 2. Navigate to ${pc36.dim("Settings \u2192 AWS Accounts")}`);
|
|
27927
|
+
console.log(` 3. Add your AWS account: ${pc36.cyan(identity.accountId)}`);
|
|
28266
27928
|
if (webhookSecret) {
|
|
28267
27929
|
console.log(" 4. Paste the webhook secret shown above");
|
|
28268
27930
|
}
|
|
28269
27931
|
console.log();
|
|
28270
27932
|
console.log(
|
|
28271
|
-
|
|
27933
|
+
pc36.dim(
|
|
28272
27934
|
"Events from your AWS infrastructure will stream to the dashboard."
|
|
28273
27935
|
)
|
|
28274
27936
|
);
|
|
@@ -28296,51 +27958,51 @@ ${pc37.bold("Next Steps:")}`);
|
|
|
28296
27958
|
// src/commands/platform/index.ts
|
|
28297
27959
|
init_esm_shims();
|
|
28298
27960
|
import * as clack35 from "@clack/prompts";
|
|
28299
|
-
import
|
|
27961
|
+
import pc37 from "picocolors";
|
|
28300
27962
|
async function platform() {
|
|
28301
|
-
clack35.intro(
|
|
27963
|
+
clack35.intro(pc37.bold("Wraps Platform"));
|
|
28302
27964
|
console.log();
|
|
28303
27965
|
console.log(
|
|
28304
27966
|
" The Wraps Platform extends the free CLI with hosted features:"
|
|
28305
27967
|
);
|
|
28306
27968
|
console.log();
|
|
28307
|
-
console.log(` ${
|
|
28308
|
-
console.log(` ${
|
|
28309
|
-
console.log(` ${
|
|
28310
|
-
console.log(` ${
|
|
28311
|
-
console.log(` ${
|
|
28312
|
-
console.log(` ${
|
|
28313
|
-
console.log(` ${
|
|
27969
|
+
console.log(` ${pc37.bold("Features:")}`);
|
|
27970
|
+
console.log(` ${pc37.green("\u2713")} Visual email template editor`);
|
|
27971
|
+
console.log(` ${pc37.green("\u2713")} Broadcast campaigns & scheduling`);
|
|
27972
|
+
console.log(` ${pc37.green("\u2713")} Contact management & segments`);
|
|
27973
|
+
console.log(` ${pc37.green("\u2713")} Workflow automations`);
|
|
27974
|
+
console.log(` ${pc37.green("\u2713")} Analytics dashboard`);
|
|
27975
|
+
console.log(` ${pc37.green("\u2713")} Team collaboration`);
|
|
28314
27976
|
console.log();
|
|
28315
|
-
console.log(` ${
|
|
28316
|
-
console.log(` ${
|
|
28317
|
-
console.log(` ${
|
|
28318
|
-
console.log(` ${
|
|
28319
|
-
console.log(` ${
|
|
27977
|
+
console.log(` ${pc37.bold("Pricing:")}`);
|
|
27978
|
+
console.log(` ${pc37.cyan("Starter")} $10/mo 5,000 contacts`);
|
|
27979
|
+
console.log(` ${pc37.cyan("Growth")} $25/mo 25,000 contacts`);
|
|
27980
|
+
console.log(` ${pc37.cyan("Scale")} $50/mo 100,000 contacts`);
|
|
27981
|
+
console.log(` ${pc37.cyan("Enterprise")} Custom Unlimited contacts`);
|
|
28320
27982
|
console.log();
|
|
28321
27983
|
console.log(
|
|
28322
|
-
|
|
27984
|
+
pc37.dim(" + AWS costs at $0.10 per 1,000 emails (paid directly to AWS)")
|
|
28323
27985
|
);
|
|
28324
27986
|
console.log();
|
|
28325
27987
|
console.log(
|
|
28326
|
-
` ${
|
|
27988
|
+
` ${pc37.bold("Learn more:")} ${pc37.cyan("https://wraps.dev/platform")}`
|
|
28327
27989
|
);
|
|
28328
27990
|
console.log();
|
|
28329
|
-
console.log(
|
|
27991
|
+
console.log(pc37.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\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
28330
27992
|
console.log();
|
|
28331
|
-
console.log(` ${
|
|
27993
|
+
console.log(` ${pc37.bold("Platform Commands:")}`);
|
|
28332
27994
|
console.log();
|
|
28333
27995
|
console.log(
|
|
28334
|
-
` ${
|
|
27996
|
+
` ${pc37.cyan("wraps platform connect")} Connect infrastructure to Wraps Platform`
|
|
28335
27997
|
);
|
|
28336
27998
|
console.log(
|
|
28337
|
-
` ${
|
|
27999
|
+
` ${pc37.cyan("wraps platform update-role")} Update IAM permissions for dashboard`
|
|
28338
28000
|
);
|
|
28339
28001
|
console.log();
|
|
28340
28002
|
console.log(
|
|
28341
|
-
|
|
28003
|
+
pc37.dim(" The connect command sets up event streaming and IAM permissions")
|
|
28342
28004
|
);
|
|
28343
|
-
console.log(
|
|
28005
|
+
console.log(pc37.dim(" in one step. Run it after deploying infrastructure."));
|
|
28344
28006
|
console.log();
|
|
28345
28007
|
}
|
|
28346
28008
|
|
|
@@ -28356,12 +28018,12 @@ import {
|
|
|
28356
28018
|
GetRoleCommand as GetRoleCommand2,
|
|
28357
28019
|
IAMClient as IAMClient3
|
|
28358
28020
|
} from "@aws-sdk/client-iam";
|
|
28359
|
-
import { confirm as confirm15, intro as
|
|
28360
|
-
import
|
|
28021
|
+
import { confirm as confirm15, intro as intro34, isCancel as isCancel21, log as log33, outro as outro20 } from "@clack/prompts";
|
|
28022
|
+
import pc38 from "picocolors";
|
|
28361
28023
|
async function updateRole(options) {
|
|
28362
28024
|
const startTime = Date.now();
|
|
28363
28025
|
if (!isJsonMode()) {
|
|
28364
|
-
|
|
28026
|
+
intro34(pc38.bold("Update Platform Access Role"));
|
|
28365
28027
|
}
|
|
28366
28028
|
const progress = new DeploymentProgress();
|
|
28367
28029
|
const identity = await progress.execute(
|
|
@@ -28372,12 +28034,12 @@ async function updateRole(options) {
|
|
|
28372
28034
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
28373
28035
|
if (!metadata) {
|
|
28374
28036
|
progress.stop();
|
|
28375
|
-
|
|
28376
|
-
`No Wraps deployment found for account ${
|
|
28037
|
+
log33.error(
|
|
28038
|
+
`No Wraps deployment found for account ${pc38.cyan(identity.accountId)} in region ${pc38.cyan(region)}`
|
|
28377
28039
|
);
|
|
28378
28040
|
console.log(
|
|
28379
28041
|
`
|
|
28380
|
-
Run ${
|
|
28042
|
+
Run ${pc38.cyan("wraps email init")} to deploy infrastructure first.
|
|
28381
28043
|
`
|
|
28382
28044
|
);
|
|
28383
28045
|
process.exit(1);
|
|
@@ -28397,28 +28059,28 @@ Run ${pc39.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
28397
28059
|
const externalId = metadata.platform?.externalId;
|
|
28398
28060
|
if (!(roleExists2 || externalId)) {
|
|
28399
28061
|
progress.stop();
|
|
28400
|
-
|
|
28062
|
+
log33.warn(`IAM role ${pc38.cyan(roleName)} does not exist`);
|
|
28401
28063
|
console.log(
|
|
28402
28064
|
"\nThis role is created when you connect AWS accounts through the Wraps Platform."
|
|
28403
28065
|
);
|
|
28404
28066
|
console.log(
|
|
28405
|
-
`Run ${
|
|
28067
|
+
`Run ${pc38.cyan("wraps platform connect")} while logged in to create the role automatically.
|
|
28406
28068
|
`
|
|
28407
28069
|
);
|
|
28408
28070
|
process.exit(0);
|
|
28409
28071
|
}
|
|
28410
28072
|
if (roleExists2) {
|
|
28411
|
-
progress.info(`Found IAM role: ${
|
|
28073
|
+
progress.info(`Found IAM role: ${pc38.cyan(roleName)}`);
|
|
28412
28074
|
} else {
|
|
28413
28075
|
progress.info(
|
|
28414
|
-
`IAM role ${
|
|
28076
|
+
`IAM role ${pc38.cyan(roleName)} not found \u2014 will create it using stored externalId`
|
|
28415
28077
|
);
|
|
28416
28078
|
}
|
|
28417
28079
|
if (!options.force) {
|
|
28418
28080
|
progress.stop();
|
|
28419
28081
|
const actionLabel = roleExists2 ? "Update" : "Create";
|
|
28420
28082
|
const shouldContinue = await confirm15({
|
|
28421
|
-
message: `${actionLabel} IAM role ${
|
|
28083
|
+
message: `${actionLabel} IAM role ${pc38.cyan(roleName)} with latest permissions?`,
|
|
28422
28084
|
initialValue: true
|
|
28423
28085
|
});
|
|
28424
28086
|
if (isCancel21(shouldContinue) || !shouldContinue) {
|
|
@@ -28502,53 +28164,53 @@ Run ${pc39.cyan("wraps email init")} to deploy infrastructure first.
|
|
|
28502
28164
|
});
|
|
28503
28165
|
return;
|
|
28504
28166
|
}
|
|
28505
|
-
outro20(
|
|
28167
|
+
outro20(pc38.green(`\u2713 Platform access role ${actionVerb} successfully`));
|
|
28506
28168
|
console.log(`
|
|
28507
|
-
${
|
|
28169
|
+
${pc38.bold("Permissions:")}`);
|
|
28508
28170
|
console.log(`
|
|
28509
|
-
${
|
|
28171
|
+
${pc38.bold(pc38.cyan("Email:"))}`);
|
|
28510
28172
|
console.log(
|
|
28511
|
-
` ${
|
|
28173
|
+
` ${pc38.green("\u2713")} SES metrics and identity verification (always enabled)`
|
|
28512
28174
|
);
|
|
28513
|
-
console.log(` ${
|
|
28514
|
-
console.log(` ${
|
|
28175
|
+
console.log(` ${pc38.green("\u2713")} SES template management (always enabled)`);
|
|
28176
|
+
console.log(` ${pc38.green("\u2713")} Inbound bucket detection (always enabled)`);
|
|
28515
28177
|
if (sendingEnabled) {
|
|
28516
|
-
console.log(` ${
|
|
28178
|
+
console.log(` ${pc38.green("\u2713")} Email sending via SES`);
|
|
28517
28179
|
}
|
|
28518
28180
|
if (eventTracking?.dynamoDBHistory) {
|
|
28519
28181
|
console.log(
|
|
28520
|
-
` ${
|
|
28182
|
+
` ${pc38.green("\u2713")} DynamoDB read access (including DescribeTable)`
|
|
28521
28183
|
);
|
|
28522
28184
|
}
|
|
28523
28185
|
if (eventTracking?.enabled) {
|
|
28524
|
-
console.log(` ${
|
|
28186
|
+
console.log(` ${pc38.green("\u2713")} EventBridge and SQS access`);
|
|
28525
28187
|
}
|
|
28526
28188
|
if (emailArchiving?.enabled) {
|
|
28527
|
-
console.log(` ${
|
|
28189
|
+
console.log(` ${pc38.green("\u2713")} Mail Manager Archive access`);
|
|
28528
28190
|
}
|
|
28529
28191
|
const inbound = emailConfig?.inbound;
|
|
28530
28192
|
if (inbound?.enabled) {
|
|
28531
|
-
console.log(` ${
|
|
28193
|
+
console.log(` ${pc38.green("\u2713")} S3 access for inbound email`);
|
|
28532
28194
|
}
|
|
28533
28195
|
if (smsEnabled) {
|
|
28534
28196
|
console.log(`
|
|
28535
|
-
${
|
|
28197
|
+
${pc38.bold(pc38.cyan("SMS:"))}`);
|
|
28536
28198
|
console.log(
|
|
28537
|
-
` ${
|
|
28199
|
+
` ${pc38.green("\u2713")} SMS Voice V2 read access (phone numbers, config, registrations)`
|
|
28538
28200
|
);
|
|
28539
28201
|
if (smsSendingEnabled) {
|
|
28540
|
-
console.log(` ${
|
|
28202
|
+
console.log(` ${pc38.green("\u2713")} SMS sending via SMS Voice V2`);
|
|
28541
28203
|
}
|
|
28542
28204
|
if (smsEventTracking?.dynamoDBHistory) {
|
|
28543
|
-
console.log(` ${
|
|
28205
|
+
console.log(` ${pc38.green("\u2713")} DynamoDB read access for SMS history`);
|
|
28544
28206
|
}
|
|
28545
28207
|
if (smsEventTracking?.enabled) {
|
|
28546
|
-
console.log(` ${
|
|
28208
|
+
console.log(` ${pc38.green("\u2713")} SNS topic access for SMS events`);
|
|
28547
28209
|
}
|
|
28548
28210
|
}
|
|
28549
28211
|
console.log(
|
|
28550
28212
|
`
|
|
28551
|
-
${
|
|
28213
|
+
${pc38.dim(`The Wraps Platform will now have ${actionVerb} permissions for feature detection.`)}
|
|
28552
28214
|
`
|
|
28553
28215
|
);
|
|
28554
28216
|
}
|
|
@@ -28743,7 +28405,7 @@ import * as clack36 from "@clack/prompts";
|
|
|
28743
28405
|
import * as pulumi22 from "@pulumi/pulumi";
|
|
28744
28406
|
import getPort from "get-port";
|
|
28745
28407
|
import open2 from "open";
|
|
28746
|
-
import
|
|
28408
|
+
import pc39 from "picocolors";
|
|
28747
28409
|
|
|
28748
28410
|
// src/console/server.ts
|
|
28749
28411
|
init_esm_shims();
|
|
@@ -29933,13 +29595,13 @@ function createMetricsRouter(config2) {
|
|
|
29933
29595
|
const router = createRouter5();
|
|
29934
29596
|
router.get("/stream", async (req, res) => {
|
|
29935
29597
|
const connectionId = randomUUID().slice(0, 8);
|
|
29936
|
-
const
|
|
29598
|
+
const log47 = (msg, data) => {
|
|
29937
29599
|
console.log(JSON.stringify({ connectionId, msg, ...data }));
|
|
29938
29600
|
};
|
|
29939
29601
|
res.setHeader("Content-Type", "text/event-stream");
|
|
29940
29602
|
res.setHeader("Cache-Control", "no-cache");
|
|
29941
29603
|
res.setHeader("Connection", "keep-alive");
|
|
29942
|
-
|
|
29604
|
+
log47("SSE connected");
|
|
29943
29605
|
res.write('data: {"type":"connected"}\n\n');
|
|
29944
29606
|
const { startTime, endTime } = req.query;
|
|
29945
29607
|
const getTimeRange = () => ({
|
|
@@ -29949,7 +29611,7 @@ function createMetricsRouter(config2) {
|
|
|
29949
29611
|
const sendMetrics = async () => {
|
|
29950
29612
|
try {
|
|
29951
29613
|
const timeRange = getTimeRange();
|
|
29952
|
-
|
|
29614
|
+
log47("Fetching metrics", {
|
|
29953
29615
|
start: timeRange.start.toISOString(),
|
|
29954
29616
|
end: timeRange.end.toISOString()
|
|
29955
29617
|
});
|
|
@@ -29962,7 +29624,7 @@ function createMetricsRouter(config2) {
|
|
|
29962
29624
|
),
|
|
29963
29625
|
fetchSendQuota(config2.roleArn, config2.region)
|
|
29964
29626
|
]);
|
|
29965
|
-
|
|
29627
|
+
log47("Metrics fetched successfully");
|
|
29966
29628
|
const data = {
|
|
29967
29629
|
type: "metrics",
|
|
29968
29630
|
timestamp: Date.now(),
|
|
@@ -29992,7 +29654,7 @@ function createMetricsRouter(config2) {
|
|
|
29992
29654
|
const interval = setInterval(sendMetrics, 6e4);
|
|
29993
29655
|
req.on("close", () => {
|
|
29994
29656
|
clearInterval(interval);
|
|
29995
|
-
|
|
29657
|
+
log47("SSE disconnected");
|
|
29996
29658
|
});
|
|
29997
29659
|
});
|
|
29998
29660
|
router.get("/snapshot", async (_req, res) => {
|
|
@@ -31370,7 +31032,7 @@ init_fs();
|
|
|
31370
31032
|
init_metadata();
|
|
31371
31033
|
init_output();
|
|
31372
31034
|
async function dashboard(options) {
|
|
31373
|
-
clack36.intro(
|
|
31035
|
+
clack36.intro(pc39.bold("Wraps Dashboard"));
|
|
31374
31036
|
const progress = new DeploymentProgress();
|
|
31375
31037
|
const identity = await progress.execute(
|
|
31376
31038
|
"Validating AWS credentials",
|
|
@@ -31413,7 +31075,7 @@ async function dashboard(options) {
|
|
|
31413
31075
|
progress.stop();
|
|
31414
31076
|
clack36.log.error("No Wraps infrastructure found");
|
|
31415
31077
|
console.log(
|
|
31416
|
-
`\\nRun ${
|
|
31078
|
+
`\\nRun ${pc39.cyan("wraps email init")}, ${pc39.cyan("wraps sms init")}, or ${pc39.cyan("wraps storage init")} to deploy infrastructure first.\\n`
|
|
31417
31079
|
);
|
|
31418
31080
|
process.exit(1);
|
|
31419
31081
|
}
|
|
@@ -31457,7 +31119,7 @@ async function dashboard(options) {
|
|
|
31457
31119
|
progress.stop();
|
|
31458
31120
|
clack36.log.success("Starting dashboard server...");
|
|
31459
31121
|
console.log(
|
|
31460
|
-
`${
|
|
31122
|
+
`${pc39.dim("Using current AWS credentials (no role assumption)")}\\n`
|
|
31461
31123
|
);
|
|
31462
31124
|
const { url } = await startConsoleServer({
|
|
31463
31125
|
port,
|
|
@@ -31490,8 +31152,8 @@ async function dashboard(options) {
|
|
|
31490
31152
|
cdnCustomDomain,
|
|
31491
31153
|
cdnCertificateArn
|
|
31492
31154
|
});
|
|
31493
|
-
console.log(`\\n${
|
|
31494
|
-
console.log(`${
|
|
31155
|
+
console.log(`\\n${pc39.bold("Dashboard:")} ${pc39.cyan(url)}`);
|
|
31156
|
+
console.log(`${pc39.dim("Press Ctrl+C to stop")}\\n`);
|
|
31495
31157
|
getTelemetryClient().showFooterOnce();
|
|
31496
31158
|
if (!options.noOpen) {
|
|
31497
31159
|
await open2(url);
|
|
@@ -31513,7 +31175,7 @@ init_errors();
|
|
|
31513
31175
|
init_json_output();
|
|
31514
31176
|
init_metadata();
|
|
31515
31177
|
import * as clack37 from "@clack/prompts";
|
|
31516
|
-
import
|
|
31178
|
+
import pc40 from "picocolors";
|
|
31517
31179
|
async function destroy(options) {
|
|
31518
31180
|
trackCommand("destroy", { success: true });
|
|
31519
31181
|
if (isJsonMode() && !options.force) {
|
|
@@ -31524,7 +31186,7 @@ async function destroy(options) {
|
|
|
31524
31186
|
);
|
|
31525
31187
|
}
|
|
31526
31188
|
if (!isJsonMode()) {
|
|
31527
|
-
clack37.intro(
|
|
31189
|
+
clack37.intro(pc40.bold("Wraps Infrastructure Teardown"));
|
|
31528
31190
|
}
|
|
31529
31191
|
const spinner10 = clack37.spinner();
|
|
31530
31192
|
spinner10.start("Validating AWS credentials");
|
|
@@ -31546,14 +31208,14 @@ async function destroy(options) {
|
|
|
31546
31208
|
clack37.log.warn("No Wraps services found in this region");
|
|
31547
31209
|
console.log(
|
|
31548
31210
|
`
|
|
31549
|
-
Run ${
|
|
31211
|
+
Run ${pc40.cyan("wraps email init")} to deploy infrastructure.
|
|
31550
31212
|
`
|
|
31551
31213
|
);
|
|
31552
31214
|
process.exit(0);
|
|
31553
31215
|
}
|
|
31554
31216
|
if (deployedServices.length === 1) {
|
|
31555
31217
|
const service = deployedServices[0];
|
|
31556
|
-
clack37.log.info(`Found ${
|
|
31218
|
+
clack37.log.info(`Found ${pc40.cyan(service)} service deployed`);
|
|
31557
31219
|
if (service === "email") {
|
|
31558
31220
|
await emailDestroy(options);
|
|
31559
31221
|
return;
|
|
@@ -31591,7 +31253,7 @@ Run ${pc41.cyan("wraps email init")} to deploy infrastructure.
|
|
|
31591
31253
|
await emailDestroy(options);
|
|
31592
31254
|
}
|
|
31593
31255
|
if (serviceToDestroy === "all") {
|
|
31594
|
-
clack37.outro(
|
|
31256
|
+
clack37.outro(pc40.green("All Wraps infrastructure has been removed"));
|
|
31595
31257
|
}
|
|
31596
31258
|
}
|
|
31597
31259
|
|
|
@@ -31604,23 +31266,23 @@ init_json_output();
|
|
|
31604
31266
|
init_output();
|
|
31605
31267
|
import * as clack38 from "@clack/prompts";
|
|
31606
31268
|
import * as pulumi23 from "@pulumi/pulumi";
|
|
31607
|
-
import
|
|
31269
|
+
import pc41 from "picocolors";
|
|
31608
31270
|
async function status(_options) {
|
|
31609
31271
|
const startTime = Date.now();
|
|
31610
31272
|
const progress = new DeploymentProgress();
|
|
31611
31273
|
if (!isJsonMode()) {
|
|
31612
|
-
clack38.intro(
|
|
31274
|
+
clack38.intro(pc41.bold("Wraps Infrastructure Status"));
|
|
31613
31275
|
}
|
|
31614
31276
|
const identity = await progress.execute(
|
|
31615
31277
|
"Loading infrastructure status",
|
|
31616
31278
|
async () => validateAWSCredentials()
|
|
31617
31279
|
);
|
|
31618
31280
|
if (!isJsonMode()) {
|
|
31619
|
-
progress.info(`AWS Account: ${
|
|
31281
|
+
progress.info(`AWS Account: ${pc41.cyan(identity.accountId)}`);
|
|
31620
31282
|
}
|
|
31621
31283
|
const region = await getAWSRegion();
|
|
31622
31284
|
if (!isJsonMode()) {
|
|
31623
|
-
progress.info(`Region: ${
|
|
31285
|
+
progress.info(`Region: ${pc41.cyan(region)}`);
|
|
31624
31286
|
}
|
|
31625
31287
|
const services = [];
|
|
31626
31288
|
try {
|
|
@@ -31675,32 +31337,32 @@ async function status(_options) {
|
|
|
31675
31337
|
clack38.note(
|
|
31676
31338
|
services.map((s) => {
|
|
31677
31339
|
if (s.status === "deployed") {
|
|
31678
|
-
const details = s.details ?
|
|
31679
|
-
return ` ${
|
|
31340
|
+
const details = s.details ? pc41.dim(` (${s.details})`) : "";
|
|
31341
|
+
return ` ${pc41.green("\u2713")} ${s.name}${details}`;
|
|
31680
31342
|
}
|
|
31681
|
-
return ` ${
|
|
31343
|
+
return ` ${pc41.dim("\u25CB")} ${s.name} ${pc41.dim("(not deployed)")}`;
|
|
31682
31344
|
}).join("\n"),
|
|
31683
31345
|
"Services"
|
|
31684
31346
|
);
|
|
31685
31347
|
const hasDeployedServices = services.some((s) => s.status === "deployed");
|
|
31686
31348
|
if (hasDeployedServices) {
|
|
31687
31349
|
console.log(`
|
|
31688
|
-
${
|
|
31350
|
+
${pc41.bold("Details:")}`);
|
|
31689
31351
|
if (services.find((s) => s.name === "Email")?.status === "deployed") {
|
|
31690
|
-
console.log(` ${
|
|
31352
|
+
console.log(` ${pc41.dim("Email:")} ${pc41.cyan("wraps email status")}`);
|
|
31691
31353
|
}
|
|
31692
31354
|
if (services.find((s) => s.name === "SMS")?.status === "deployed") {
|
|
31693
|
-
console.log(` ${
|
|
31355
|
+
console.log(` ${pc41.dim("SMS:")} ${pc41.cyan("wraps sms status")}`);
|
|
31694
31356
|
}
|
|
31695
31357
|
} else {
|
|
31696
31358
|
console.log(`
|
|
31697
|
-
${
|
|
31698
|
-
console.log(` ${
|
|
31699
|
-
console.log(` ${
|
|
31359
|
+
${pc41.bold("Get started:")}`);
|
|
31360
|
+
console.log(` ${pc41.dim("Deploy email:")} ${pc41.cyan("wraps email init")}`);
|
|
31361
|
+
console.log(` ${pc41.dim("Deploy SMS:")} ${pc41.cyan("wraps sms init")}`);
|
|
31700
31362
|
}
|
|
31701
31363
|
console.log(`
|
|
31702
|
-
${
|
|
31703
|
-
console.log(`${
|
|
31364
|
+
${pc41.bold("Dashboard:")} ${pc41.blue("https://app.wraps.dev")}`);
|
|
31365
|
+
console.log(`${pc41.bold("Docs:")} ${pc41.blue("https://wraps.dev/docs")}
|
|
31704
31366
|
`);
|
|
31705
31367
|
trackCommand("status", {
|
|
31706
31368
|
success: true,
|
|
@@ -31713,7 +31375,7 @@ ${pc42.bold("Dashboard:")} ${pc42.blue("https://app.wraps.dev")}`);
|
|
|
31713
31375
|
init_esm_shims();
|
|
31714
31376
|
import * as clack39 from "@clack/prompts";
|
|
31715
31377
|
import * as pulumi25 from "@pulumi/pulumi";
|
|
31716
|
-
import
|
|
31378
|
+
import pc42 from "picocolors";
|
|
31717
31379
|
|
|
31718
31380
|
// src/infrastructure/sms-stack.ts
|
|
31719
31381
|
init_esm_shims();
|
|
@@ -32405,18 +32067,18 @@ async function createSMSProtectConfigurationWithSDK(configurationSetName, region
|
|
|
32405
32067
|
const existing = await client.send(
|
|
32406
32068
|
new DescribeProtectConfigurationsCommand({})
|
|
32407
32069
|
);
|
|
32408
|
-
for (const
|
|
32409
|
-
if (!(
|
|
32070
|
+
for (const pc54 of existing.ProtectConfigurations || []) {
|
|
32071
|
+
if (!(pc54.ProtectConfigurationArn && pc54.ProtectConfigurationId)) {
|
|
32410
32072
|
continue;
|
|
32411
32073
|
}
|
|
32412
32074
|
const tagsResponse = await client.send(
|
|
32413
32075
|
new ListTagsForResourceCommand({
|
|
32414
|
-
ResourceArn:
|
|
32076
|
+
ResourceArn: pc54.ProtectConfigurationArn
|
|
32415
32077
|
})
|
|
32416
32078
|
);
|
|
32417
32079
|
const nameTag = tagsResponse.Tags?.find((t) => t.Key === "Name");
|
|
32418
32080
|
if (nameTag?.Value === protectConfigName) {
|
|
32419
|
-
existingProtectConfigId =
|
|
32081
|
+
existingProtectConfigId = pc54.ProtectConfigurationId;
|
|
32420
32082
|
break;
|
|
32421
32083
|
}
|
|
32422
32084
|
}
|
|
@@ -32512,13 +32174,13 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
|
32512
32174
|
new DescribeProtectConfigurationsCommand({})
|
|
32513
32175
|
);
|
|
32514
32176
|
if (existing.ProtectConfigurations) {
|
|
32515
|
-
for (const
|
|
32516
|
-
if (!(
|
|
32177
|
+
for (const pc54 of existing.ProtectConfigurations) {
|
|
32178
|
+
if (!(pc54.ProtectConfigurationArn && pc54.ProtectConfigurationId)) {
|
|
32517
32179
|
continue;
|
|
32518
32180
|
}
|
|
32519
32181
|
const tagsResponse = await client.send(
|
|
32520
32182
|
new ListTagsForResourceCommand({
|
|
32521
|
-
ResourceArn:
|
|
32183
|
+
ResourceArn: pc54.ProtectConfigurationArn
|
|
32522
32184
|
})
|
|
32523
32185
|
);
|
|
32524
32186
|
const isWrapsManaged = tagsResponse.Tags?.some(
|
|
@@ -32527,7 +32189,7 @@ async function deleteSMSProtectConfigurationWithSDK(region) {
|
|
|
32527
32189
|
if (isWrapsManaged) {
|
|
32528
32190
|
await client.send(
|
|
32529
32191
|
new DeleteProtectConfigurationCommand({
|
|
32530
|
-
ProtectConfigurationId:
|
|
32192
|
+
ProtectConfigurationId: pc54.ProtectConfigurationId
|
|
32531
32193
|
})
|
|
32532
32194
|
);
|
|
32533
32195
|
}
|
|
@@ -32561,7 +32223,7 @@ async function smsDestroy(options) {
|
|
|
32561
32223
|
}
|
|
32562
32224
|
if (!isJsonMode()) {
|
|
32563
32225
|
clack39.intro(
|
|
32564
|
-
|
|
32226
|
+
pc42.bold(
|
|
32565
32227
|
options.preview ? "SMS Infrastructure Destruction Preview" : "SMS Infrastructure Teardown"
|
|
32566
32228
|
)
|
|
32567
32229
|
);
|
|
@@ -32611,7 +32273,7 @@ async function smsDestroy(options) {
|
|
|
32611
32273
|
}
|
|
32612
32274
|
if (!(options.force || options.preview)) {
|
|
32613
32275
|
const confirmed = await clack39.confirm({
|
|
32614
|
-
message:
|
|
32276
|
+
message: pc42.red(
|
|
32615
32277
|
"Are you sure you want to destroy all SMS infrastructure?"
|
|
32616
32278
|
),
|
|
32617
32279
|
initialValue: false
|
|
@@ -32650,7 +32312,7 @@ async function smsDestroy(options) {
|
|
|
32650
32312
|
commandName: "wraps sms destroy"
|
|
32651
32313
|
});
|
|
32652
32314
|
clack39.outro(
|
|
32653
|
-
|
|
32315
|
+
pc42.green("Preview complete. Run without --preview to destroy.")
|
|
32654
32316
|
);
|
|
32655
32317
|
trackServiceRemoved("sms", {
|
|
32656
32318
|
preview: true,
|
|
@@ -32747,20 +32409,20 @@ async function smsDestroy(options) {
|
|
|
32747
32409
|
}
|
|
32748
32410
|
if (destroyFailed) {
|
|
32749
32411
|
clack39.outro(
|
|
32750
|
-
|
|
32412
|
+
pc42.yellow("SMS infrastructure partially removed. Metadata cleaned up.")
|
|
32751
32413
|
);
|
|
32752
32414
|
} else {
|
|
32753
|
-
clack39.outro(
|
|
32415
|
+
clack39.outro(pc42.green("SMS infrastructure has been removed"));
|
|
32754
32416
|
console.log(`
|
|
32755
|
-
${
|
|
32756
|
-
console.log(` ${
|
|
32757
|
-
console.log(` ${
|
|
32758
|
-
console.log(` ${
|
|
32759
|
-
console.log(` ${
|
|
32417
|
+
${pc42.bold("Cleaned up:")}`);
|
|
32418
|
+
console.log(` ${pc42.green("\u2713")} Phone number released`);
|
|
32419
|
+
console.log(` ${pc42.green("\u2713")} Configuration set deleted`);
|
|
32420
|
+
console.log(` ${pc42.green("\u2713")} Event processing infrastructure removed`);
|
|
32421
|
+
console.log(` ${pc42.green("\u2713")} IAM role deleted`);
|
|
32760
32422
|
}
|
|
32761
32423
|
console.log(
|
|
32762
32424
|
`
|
|
32763
|
-
Run ${
|
|
32425
|
+
Run ${pc42.cyan("wraps sms init")} to deploy infrastructure again.
|
|
32764
32426
|
`
|
|
32765
32427
|
);
|
|
32766
32428
|
trackServiceRemoved("sms", {
|
|
@@ -32774,7 +32436,7 @@ Run ${pc43.cyan("wraps sms init")} to deploy infrastructure again.
|
|
|
32774
32436
|
init_esm_shims();
|
|
32775
32437
|
import * as clack40 from "@clack/prompts";
|
|
32776
32438
|
import * as pulumi26 from "@pulumi/pulumi";
|
|
32777
|
-
import
|
|
32439
|
+
import pc43 from "picocolors";
|
|
32778
32440
|
init_events();
|
|
32779
32441
|
init_aws();
|
|
32780
32442
|
init_errors();
|
|
@@ -33301,7 +32963,7 @@ async function promptEstimatedSMSVolume() {
|
|
|
33301
32963
|
async function init3(options) {
|
|
33302
32964
|
const startTime = Date.now();
|
|
33303
32965
|
if (!isJsonMode()) {
|
|
33304
|
-
clack40.intro(
|
|
32966
|
+
clack40.intro(pc43.bold("Wraps SMS Infrastructure Setup"));
|
|
33305
32967
|
}
|
|
33306
32968
|
const progress = new DeploymentProgress();
|
|
33307
32969
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -33315,7 +32977,7 @@ async function init3(options) {
|
|
|
33315
32977
|
"Validating AWS credentials",
|
|
33316
32978
|
async () => validateAWSCredentials()
|
|
33317
32979
|
);
|
|
33318
|
-
progress.info(`Connected to AWS account: ${
|
|
32980
|
+
progress.info(`Connected to AWS account: ${pc43.cyan(identity.accountId)}`);
|
|
33319
32981
|
const provider = options.provider || await promptProvider();
|
|
33320
32982
|
const region = options.region || await promptRegion(await getAWSRegion());
|
|
33321
32983
|
let vercelConfig;
|
|
@@ -33328,9 +32990,9 @@ async function init3(options) {
|
|
|
33328
32990
|
);
|
|
33329
32991
|
if (existingConnection?.services?.sms) {
|
|
33330
32992
|
clack40.log.warn(
|
|
33331
|
-
`SMS already configured for account ${
|
|
32993
|
+
`SMS already configured for account ${pc43.cyan(identity.accountId)} in region ${pc43.cyan(region)}`
|
|
33332
32994
|
);
|
|
33333
|
-
clack40.log.info(`Use ${
|
|
32995
|
+
clack40.log.info(`Use ${pc43.cyan("wraps sms status")} to view current setup`);
|
|
33334
32996
|
process.exit(0);
|
|
33335
32997
|
}
|
|
33336
32998
|
let preset = options.preset;
|
|
@@ -33372,7 +33034,7 @@ async function init3(options) {
|
|
|
33372
33034
|
}
|
|
33373
33035
|
progress.info(
|
|
33374
33036
|
`
|
|
33375
|
-
${
|
|
33037
|
+
${pc43.bold("Fraud Protection")} - Block SMS to countries where you don't do business`
|
|
33376
33038
|
);
|
|
33377
33039
|
const allowedCountries = await promptAllowedCountries();
|
|
33378
33040
|
let aitFiltering = false;
|
|
@@ -33394,13 +33056,13 @@ ${pc44.bold("Fraud Protection")} - Block SMS to countries where you don't do bus
|
|
|
33394
33056
|
};
|
|
33395
33057
|
const estimatedVolume = await promptEstimatedSMSVolume();
|
|
33396
33058
|
progress.info(`
|
|
33397
|
-
${
|
|
33059
|
+
${pc43.bold("Cost Estimate:")}`);
|
|
33398
33060
|
const costSummary = getSMSCostSummary(smsConfig, estimatedVolume);
|
|
33399
33061
|
clack40.log.info(costSummary);
|
|
33400
33062
|
const warnings = validateSMSConfig(smsConfig);
|
|
33401
33063
|
if (warnings.length > 0) {
|
|
33402
33064
|
progress.info(`
|
|
33403
|
-
${
|
|
33065
|
+
${pc43.yellow(pc43.bold("Important Notes:"))}`);
|
|
33404
33066
|
for (const warning of warnings) {
|
|
33405
33067
|
clack40.log.warn(warning);
|
|
33406
33068
|
}
|
|
@@ -33483,7 +33145,7 @@ ${pc44.yellow(pc44.bold("Important Notes:"))}`);
|
|
|
33483
33145
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
33484
33146
|
clack40.log.warn(`Phone pool creation failed: ${msg}`);
|
|
33485
33147
|
clack40.log.info(
|
|
33486
|
-
`Run ${
|
|
33148
|
+
`Run ${pc43.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
33487
33149
|
);
|
|
33488
33150
|
}
|
|
33489
33151
|
}
|
|
@@ -33501,7 +33163,7 @@ ${pc44.yellow(pc44.bold("Important Notes:"))}`);
|
|
|
33501
33163
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
33502
33164
|
clack40.log.warn(`Event destination creation failed: ${msg}`);
|
|
33503
33165
|
clack40.log.info(
|
|
33504
|
-
`Run ${
|
|
33166
|
+
`Run ${pc43.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
33505
33167
|
);
|
|
33506
33168
|
}
|
|
33507
33169
|
}
|
|
@@ -33522,7 +33184,7 @@ ${pc44.yellow(pc44.bold("Important Notes:"))}`);
|
|
|
33522
33184
|
const msg = sdkError instanceof Error ? sdkError.message : String(sdkError);
|
|
33523
33185
|
clack40.log.warn(`Protect configuration creation failed: ${msg}`);
|
|
33524
33186
|
clack40.log.info(
|
|
33525
|
-
`Run ${
|
|
33187
|
+
`Run ${pc43.cyan("wraps sms sync")} to retry SDK resource creation.`
|
|
33526
33188
|
);
|
|
33527
33189
|
}
|
|
33528
33190
|
}
|
|
@@ -33576,47 +33238,47 @@ ${pc44.yellow(pc44.bold("Important Notes:"))}`);
|
|
|
33576
33238
|
return;
|
|
33577
33239
|
}
|
|
33578
33240
|
console.log("\n");
|
|
33579
|
-
clack40.log.success(
|
|
33241
|
+
clack40.log.success(pc43.green(pc43.bold("SMS infrastructure deployed!")));
|
|
33580
33242
|
console.log("\n");
|
|
33581
33243
|
clack40.note(
|
|
33582
33244
|
[
|
|
33583
|
-
`${
|
|
33584
|
-
`${
|
|
33585
|
-
`${
|
|
33586
|
-
`${
|
|
33587
|
-
outputs.tableName ? `${
|
|
33245
|
+
`${pc43.bold("Phone Number:")} ${pc43.cyan(outputs.phoneNumber || "Provisioning...")}`,
|
|
33246
|
+
`${pc43.bold("Phone Type:")} ${pc43.cyan(smsConfig.phoneNumberType || "simulator")}`,
|
|
33247
|
+
`${pc43.bold("Config Set:")} ${pc43.cyan(outputs.configSetName || "wraps-sms-config")}`,
|
|
33248
|
+
`${pc43.bold("Region:")} ${pc43.cyan(outputs.region)}`,
|
|
33249
|
+
outputs.tableName ? `${pc43.bold("History Table:")} ${pc43.cyan(outputs.tableName)}` : "",
|
|
33588
33250
|
"",
|
|
33589
|
-
|
|
33590
|
-
|
|
33251
|
+
pc43.dim("IAM Role:"),
|
|
33252
|
+
pc43.dim(` ${outputs.roleArn}`)
|
|
33591
33253
|
].filter(Boolean).join("\n"),
|
|
33592
33254
|
"SMS Infrastructure"
|
|
33593
33255
|
);
|
|
33594
33256
|
const nextSteps = [];
|
|
33595
33257
|
if (smsConfig.phoneNumberType === "toll-free") {
|
|
33596
33258
|
nextSteps.push(
|
|
33597
|
-
`${
|
|
33259
|
+
`${pc43.cyan("wraps sms register")} - Submit toll-free registration (required before sending)`
|
|
33598
33260
|
);
|
|
33599
33261
|
}
|
|
33600
33262
|
nextSteps.push(
|
|
33601
|
-
`${
|
|
33263
|
+
`${pc43.cyan("wraps sms test --to +1234567890")} - Send a test message`
|
|
33602
33264
|
);
|
|
33603
|
-
nextSteps.push(`${
|
|
33265
|
+
nextSteps.push(`${pc43.cyan("wraps sms status")} - View SMS configuration`);
|
|
33604
33266
|
console.log("\n");
|
|
33605
|
-
clack40.log.info(
|
|
33267
|
+
clack40.log.info(pc43.bold("Next steps:"));
|
|
33606
33268
|
for (const step of nextSteps) {
|
|
33607
33269
|
console.log(` ${step}`);
|
|
33608
33270
|
}
|
|
33609
33271
|
console.log("\n");
|
|
33610
|
-
clack40.log.info(
|
|
33611
|
-
console.log(
|
|
33272
|
+
clack40.log.info(pc43.bold("SDK Usage:"));
|
|
33273
|
+
console.log(pc43.dim(" npm install @wraps.dev/sms"));
|
|
33612
33274
|
console.log("");
|
|
33613
|
-
console.log(
|
|
33614
|
-
console.log(
|
|
33615
|
-
console.log(
|
|
33616
|
-
console.log(
|
|
33617
|
-
console.log(
|
|
33618
|
-
console.log(
|
|
33619
|
-
clack40.outro(
|
|
33275
|
+
console.log(pc43.dim(" import { Wraps } from '@wraps.dev/sms';"));
|
|
33276
|
+
console.log(pc43.dim(" const wraps = new Wraps();"));
|
|
33277
|
+
console.log(pc43.dim(" await wraps.sms.send({"));
|
|
33278
|
+
console.log(pc43.dim(" to: '+14155551234',"));
|
|
33279
|
+
console.log(pc43.dim(" message: 'Your code is 123456',"));
|
|
33280
|
+
console.log(pc43.dim(" });"));
|
|
33281
|
+
clack40.outro(pc43.green("Setup complete!"));
|
|
33620
33282
|
const duration = Date.now() - startTime;
|
|
33621
33283
|
const enabledFeatures = [];
|
|
33622
33284
|
if (smsConfig.tracking?.enabled) {
|
|
@@ -33653,7 +33315,7 @@ init_json_output();
|
|
|
33653
33315
|
init_metadata();
|
|
33654
33316
|
init_output();
|
|
33655
33317
|
import * as clack41 from "@clack/prompts";
|
|
33656
|
-
import
|
|
33318
|
+
import pc44 from "picocolors";
|
|
33657
33319
|
async function getPhoneNumberDetails(region) {
|
|
33658
33320
|
const { PinpointSMSVoiceV2Client: PinpointSMSVoiceV2Client5, DescribePhoneNumbersCommand: DescribePhoneNumbersCommand2 } = await import("@aws-sdk/client-pinpoint-sms-voice-v2");
|
|
33659
33321
|
const client = new PinpointSMSVoiceV2Client5({ region });
|
|
@@ -33694,7 +33356,7 @@ async function getRegistrationStatus(region, registrationId) {
|
|
|
33694
33356
|
async function smsRegister(options) {
|
|
33695
33357
|
const startTime = Date.now();
|
|
33696
33358
|
if (!isJsonMode()) {
|
|
33697
|
-
clack41.intro(
|
|
33359
|
+
clack41.intro(pc44.bold("Wraps SMS - Toll-Free Registration"));
|
|
33698
33360
|
}
|
|
33699
33361
|
const progress = new DeploymentProgress();
|
|
33700
33362
|
const identity = await progress.execute(
|
|
@@ -33708,7 +33370,7 @@ async function smsRegister(options) {
|
|
|
33708
33370
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
33709
33371
|
if (!metadata?.services?.sms) {
|
|
33710
33372
|
clack41.log.error("No SMS infrastructure found.");
|
|
33711
|
-
clack41.log.info(`Run ${
|
|
33373
|
+
clack41.log.info(`Run ${pc44.cyan("wraps sms init")} first.`);
|
|
33712
33374
|
process.exit(1);
|
|
33713
33375
|
}
|
|
33714
33376
|
const phoneDetails = await progress.execute(
|
|
@@ -33742,14 +33404,14 @@ async function smsRegister(options) {
|
|
|
33742
33404
|
}
|
|
33743
33405
|
console.log("");
|
|
33744
33406
|
console.log(
|
|
33745
|
-
`${
|
|
33407
|
+
`${pc44.bold("Phone Number:")} ${pc44.cyan(phoneDetails.phoneNumber)}`
|
|
33746
33408
|
);
|
|
33747
|
-
console.log(`${
|
|
33409
|
+
console.log(`${pc44.bold("Type:")} ${pc44.cyan(phoneDetails.type)}`);
|
|
33748
33410
|
console.log(
|
|
33749
|
-
`${
|
|
33411
|
+
`${pc44.bold("Status:")} ${phoneDetails.status === "ACTIVE" ? pc44.green(phoneDetails.status) : pc44.yellow(phoneDetails.status)}`
|
|
33750
33412
|
);
|
|
33751
33413
|
if (registrationStatus) {
|
|
33752
|
-
console.log(`${
|
|
33414
|
+
console.log(`${pc44.bold("Registration:")} ${pc44.cyan(registrationStatus)}`);
|
|
33753
33415
|
}
|
|
33754
33416
|
console.log("");
|
|
33755
33417
|
if (phoneDetails.status === "ACTIVE") {
|
|
@@ -33767,21 +33429,21 @@ async function smsRegister(options) {
|
|
|
33767
33429
|
clack41.log.info(`Your ${phoneDetails.type} number should be ready to use.`);
|
|
33768
33430
|
process.exit(0);
|
|
33769
33431
|
}
|
|
33770
|
-
console.log(
|
|
33432
|
+
console.log(pc44.bold("Toll-Free Registration Required"));
|
|
33771
33433
|
console.log("");
|
|
33772
33434
|
console.log(
|
|
33773
|
-
|
|
33435
|
+
pc44.dim("To send SMS at scale, you must register your toll-free number.")
|
|
33774
33436
|
);
|
|
33775
|
-
console.log(
|
|
33437
|
+
console.log(pc44.dim("This process typically takes 1-15 business days."));
|
|
33776
33438
|
console.log("");
|
|
33777
|
-
console.log(
|
|
33778
|
-
console.log(` ${
|
|
33439
|
+
console.log(pc44.bold("You'll need to provide:"));
|
|
33440
|
+
console.log(` ${pc44.dim("\u2022")} Business name and address`);
|
|
33779
33441
|
console.log(
|
|
33780
|
-
` ${
|
|
33442
|
+
` ${pc44.dim("\u2022")} Use case description (what messages you're sending)`
|
|
33781
33443
|
);
|
|
33782
|
-
console.log(` ${
|
|
33783
|
-
console.log(` ${
|
|
33784
|
-
console.log(` ${
|
|
33444
|
+
console.log(` ${pc44.dim("\u2022")} Sample messages (2-3 examples)`);
|
|
33445
|
+
console.log(` ${pc44.dim("\u2022")} How users opt-in to receive messages`);
|
|
33446
|
+
console.log(` ${pc44.dim("\u2022")} Expected monthly message volume`);
|
|
33785
33447
|
console.log("");
|
|
33786
33448
|
const openConsole = await clack41.confirm({
|
|
33787
33449
|
message: "Open AWS Console to start registration?",
|
|
@@ -33806,33 +33468,33 @@ async function smsRegister(options) {
|
|
|
33806
33468
|
} catch {
|
|
33807
33469
|
clack41.log.info("Open this URL in your browser:");
|
|
33808
33470
|
console.log(`
|
|
33809
|
-
${
|
|
33471
|
+
${pc44.cyan(consoleUrl)}
|
|
33810
33472
|
`);
|
|
33811
33473
|
}
|
|
33812
33474
|
}
|
|
33813
33475
|
console.log("");
|
|
33814
|
-
console.log(
|
|
33476
|
+
console.log(pc44.bold("Next Steps:"));
|
|
33815
33477
|
console.log(
|
|
33816
|
-
` 1. Click ${
|
|
33478
|
+
` 1. Click ${pc44.cyan("Create registration")} in the AWS Console`
|
|
33817
33479
|
);
|
|
33818
|
-
console.log(` 2. Select ${
|
|
33480
|
+
console.log(` 2. Select ${pc44.cyan("Toll-free number registration")}`);
|
|
33819
33481
|
console.log(" 3. Fill out the business information form");
|
|
33820
33482
|
console.log(" 4. Submit and wait for approval (1-15 business days)");
|
|
33821
33483
|
console.log("");
|
|
33822
33484
|
console.log(
|
|
33823
|
-
|
|
33485
|
+
pc44.dim("Once approved, run `wraps sms sync` to complete setup.")
|
|
33824
33486
|
);
|
|
33825
33487
|
} else {
|
|
33826
33488
|
const consoleUrl = `https://${region}.console.aws.amazon.com/sms-voice/home?region=${region}#/registrations`;
|
|
33827
33489
|
console.log("");
|
|
33828
33490
|
console.log("When you're ready, go to:");
|
|
33829
|
-
console.log(` ${
|
|
33491
|
+
console.log(` ${pc44.cyan(consoleUrl)}`);
|
|
33830
33492
|
}
|
|
33831
33493
|
trackCommand("sms:register", {
|
|
33832
33494
|
success: true,
|
|
33833
33495
|
duration_ms: Date.now() - startTime
|
|
33834
33496
|
});
|
|
33835
|
-
clack41.outro(
|
|
33497
|
+
clack41.outro(pc44.dim("Good luck with your registration!"));
|
|
33836
33498
|
}
|
|
33837
33499
|
|
|
33838
33500
|
// src/commands/sms/status.ts
|
|
@@ -33845,43 +33507,43 @@ init_metadata();
|
|
|
33845
33507
|
init_output();
|
|
33846
33508
|
import * as clack42 from "@clack/prompts";
|
|
33847
33509
|
import * as pulumi27 from "@pulumi/pulumi";
|
|
33848
|
-
import
|
|
33510
|
+
import pc45 from "picocolors";
|
|
33849
33511
|
function displaySMSStatus(options) {
|
|
33850
33512
|
const lines = [];
|
|
33851
|
-
lines.push(
|
|
33513
|
+
lines.push(pc45.bold(pc45.green("SMS Infrastructure Active")));
|
|
33852
33514
|
lines.push("");
|
|
33853
|
-
lines.push(
|
|
33515
|
+
lines.push(pc45.bold("Phone Number"));
|
|
33854
33516
|
if (options.phoneNumber) {
|
|
33855
|
-
lines.push(` Number: ${
|
|
33517
|
+
lines.push(` Number: ${pc45.cyan(options.phoneNumber)}`);
|
|
33856
33518
|
} else {
|
|
33857
|
-
lines.push(` Number: ${
|
|
33519
|
+
lines.push(` Number: ${pc45.yellow("Provisioning...")}`);
|
|
33858
33520
|
}
|
|
33859
|
-
lines.push(` Type: ${
|
|
33521
|
+
lines.push(` Type: ${pc45.cyan(options.phoneNumberType || "simulator")}`);
|
|
33860
33522
|
lines.push("");
|
|
33861
|
-
lines.push(
|
|
33862
|
-
lines.push(` Region: ${
|
|
33523
|
+
lines.push(pc45.bold("Configuration"));
|
|
33524
|
+
lines.push(` Region: ${pc45.cyan(options.region)}`);
|
|
33863
33525
|
if (options.preset) {
|
|
33864
|
-
lines.push(` Preset: ${
|
|
33526
|
+
lines.push(` Preset: ${pc45.cyan(options.preset)}`);
|
|
33865
33527
|
}
|
|
33866
33528
|
if (options.configSetName) {
|
|
33867
|
-
lines.push(` Config Set: ${
|
|
33529
|
+
lines.push(` Config Set: ${pc45.cyan(options.configSetName)}`);
|
|
33868
33530
|
}
|
|
33869
33531
|
lines.push("");
|
|
33870
|
-
lines.push(
|
|
33532
|
+
lines.push(pc45.bold("Features"));
|
|
33871
33533
|
lines.push(
|
|
33872
|
-
` Event Tracking: ${options.eventTracking ?
|
|
33534
|
+
` Event Tracking: ${options.eventTracking ? pc45.green("Enabled") : pc45.dim("Disabled")}`
|
|
33873
33535
|
);
|
|
33874
33536
|
if (options.tableName) {
|
|
33875
|
-
lines.push(` Message History: ${
|
|
33876
|
-
lines.push(` Table: ${
|
|
33537
|
+
lines.push(` Message History: ${pc45.green("Enabled")}`);
|
|
33538
|
+
lines.push(` Table: ${pc45.dim(options.tableName)}`);
|
|
33877
33539
|
}
|
|
33878
33540
|
if (options.queueUrl) {
|
|
33879
|
-
lines.push(` Event Queue: ${
|
|
33541
|
+
lines.push(` Event Queue: ${pc45.green("Enabled")}`);
|
|
33880
33542
|
}
|
|
33881
33543
|
lines.push("");
|
|
33882
33544
|
if (options.roleArn) {
|
|
33883
|
-
lines.push(
|
|
33884
|
-
lines.push(` ${
|
|
33545
|
+
lines.push(pc45.bold("IAM Role"));
|
|
33546
|
+
lines.push(` ${pc45.dim(options.roleArn)}`);
|
|
33885
33547
|
}
|
|
33886
33548
|
clack42.note(lines.join("\n"), "SMS Status");
|
|
33887
33549
|
}
|
|
@@ -33889,7 +33551,7 @@ async function smsStatus(_options) {
|
|
|
33889
33551
|
const startTime = Date.now();
|
|
33890
33552
|
const progress = new DeploymentProgress();
|
|
33891
33553
|
if (!isJsonMode()) {
|
|
33892
|
-
clack42.intro(
|
|
33554
|
+
clack42.intro(pc45.bold("Wraps SMS Status"));
|
|
33893
33555
|
}
|
|
33894
33556
|
const identity = await progress.execute(
|
|
33895
33557
|
"Loading SMS infrastructure status",
|
|
@@ -33902,7 +33564,7 @@ async function smsStatus(_options) {
|
|
|
33902
33564
|
clack42.log.error("No SMS infrastructure found");
|
|
33903
33565
|
console.log(
|
|
33904
33566
|
`
|
|
33905
|
-
Run ${
|
|
33567
|
+
Run ${pc45.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
33906
33568
|
`
|
|
33907
33569
|
);
|
|
33908
33570
|
process.exit(1);
|
|
@@ -33938,25 +33600,25 @@ Run ${pc46.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
33938
33600
|
}
|
|
33939
33601
|
displaySMSStatus(smsStatusData);
|
|
33940
33602
|
console.log("");
|
|
33941
|
-
clack42.log.info(
|
|
33603
|
+
clack42.log.info(pc45.bold("Commands:"));
|
|
33942
33604
|
console.log(
|
|
33943
|
-
` ${
|
|
33605
|
+
` ${pc45.cyan("wraps sms test --to +1234567890")} - Send a test message`
|
|
33944
33606
|
);
|
|
33945
|
-
console.log(` ${
|
|
33607
|
+
console.log(` ${pc45.cyan("wraps sms destroy")} - Remove SMS infrastructure`);
|
|
33946
33608
|
trackCommand("sms:status", {
|
|
33947
33609
|
success: true,
|
|
33948
33610
|
phone_type: smsConfig?.phoneNumberType,
|
|
33949
33611
|
event_tracking: smsConfig?.eventTracking?.enabled,
|
|
33950
33612
|
duration_ms: Date.now() - startTime
|
|
33951
33613
|
});
|
|
33952
|
-
clack42.outro(
|
|
33614
|
+
clack42.outro(pc45.dim("SMS infrastructure is ready"));
|
|
33953
33615
|
}
|
|
33954
33616
|
|
|
33955
33617
|
// src/commands/sms/sync.ts
|
|
33956
33618
|
init_esm_shims();
|
|
33957
33619
|
import * as clack43 from "@clack/prompts";
|
|
33958
33620
|
import * as pulumi28 from "@pulumi/pulumi";
|
|
33959
|
-
import
|
|
33621
|
+
import pc46 from "picocolors";
|
|
33960
33622
|
init_events();
|
|
33961
33623
|
init_aws();
|
|
33962
33624
|
init_errors();
|
|
@@ -33967,7 +33629,7 @@ init_output();
|
|
|
33967
33629
|
async function smsSync(options) {
|
|
33968
33630
|
const startTime = Date.now();
|
|
33969
33631
|
if (!isJsonMode()) {
|
|
33970
|
-
clack43.intro(
|
|
33632
|
+
clack43.intro(pc46.bold("Wraps SMS Infrastructure Sync"));
|
|
33971
33633
|
}
|
|
33972
33634
|
const progress = new DeploymentProgress();
|
|
33973
33635
|
const identity = await progress.execute(
|
|
@@ -33982,7 +33644,7 @@ async function smsSync(options) {
|
|
|
33982
33644
|
clack43.log.error("No SMS infrastructure found to sync");
|
|
33983
33645
|
console.log(
|
|
33984
33646
|
`
|
|
33985
|
-
Run ${
|
|
33647
|
+
Run ${pc46.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
33986
33648
|
`
|
|
33987
33649
|
);
|
|
33988
33650
|
process.exit(1);
|
|
@@ -33991,10 +33653,10 @@ Run ${pc47.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
33991
33653
|
const storedStackName = smsService.pulumiStackName;
|
|
33992
33654
|
progress.info("Found existing SMS configuration");
|
|
33993
33655
|
progress.info(
|
|
33994
|
-
`Phone type: ${
|
|
33656
|
+
`Phone type: ${pc46.cyan(smsConfig.phoneNumberType || "simulator")}`
|
|
33995
33657
|
);
|
|
33996
33658
|
progress.info(
|
|
33997
|
-
`Event tracking: ${
|
|
33659
|
+
`Event tracking: ${pc46.cyan(smsConfig.eventTracking?.enabled ? "enabled" : "disabled")}`
|
|
33998
33660
|
);
|
|
33999
33661
|
if (!options.yes) {
|
|
34000
33662
|
const confirmed = await clack43.confirm({
|
|
@@ -34127,7 +33789,7 @@ Run ${pc47.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
34127
33789
|
return;
|
|
34128
33790
|
}
|
|
34129
33791
|
console.log("\n");
|
|
34130
|
-
clack43.log.success(
|
|
33792
|
+
clack43.log.success(pc46.green("SMS infrastructure synced successfully!"));
|
|
34131
33793
|
const changes = [];
|
|
34132
33794
|
if (outputs.lambdaFunctions?.length) {
|
|
34133
33795
|
changes.push("Lambda functions updated");
|
|
@@ -34135,13 +33797,13 @@ Run ${pc47.cyan("wraps sms init")} to deploy SMS infrastructure first.
|
|
|
34135
33797
|
changes.push("SDK resources verified");
|
|
34136
33798
|
console.log("");
|
|
34137
33799
|
for (const change of changes) {
|
|
34138
|
-
console.log(` ${
|
|
33800
|
+
console.log(` ${pc46.green("\u2713")} ${change}`);
|
|
34139
33801
|
}
|
|
34140
33802
|
trackCommand("sms:sync", {
|
|
34141
33803
|
success: true,
|
|
34142
33804
|
duration_ms: Date.now() - startTime
|
|
34143
33805
|
});
|
|
34144
|
-
clack43.outro(
|
|
33806
|
+
clack43.outro(pc46.green("Sync complete!"));
|
|
34145
33807
|
}
|
|
34146
33808
|
|
|
34147
33809
|
// src/commands/sms/test.ts
|
|
@@ -34157,7 +33819,7 @@ import {
|
|
|
34157
33819
|
SendTextMessageCommand
|
|
34158
33820
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
34159
33821
|
import * as clack44 from "@clack/prompts";
|
|
34160
|
-
import
|
|
33822
|
+
import pc47 from "picocolors";
|
|
34161
33823
|
|
|
34162
33824
|
// src/utils/sms/validation.ts
|
|
34163
33825
|
init_esm_shims();
|
|
@@ -34180,7 +33842,7 @@ async function smsTest(options) {
|
|
|
34180
33842
|
const startTime = Date.now();
|
|
34181
33843
|
const progress = new DeploymentProgress();
|
|
34182
33844
|
if (!isJsonMode()) {
|
|
34183
|
-
clack44.intro(
|
|
33845
|
+
clack44.intro(pc47.bold("Wraps SMS Test"));
|
|
34184
33846
|
}
|
|
34185
33847
|
const identity = await progress.execute(
|
|
34186
33848
|
"Validating AWS credentials",
|
|
@@ -34193,7 +33855,7 @@ async function smsTest(options) {
|
|
|
34193
33855
|
clack44.log.error("No SMS infrastructure found");
|
|
34194
33856
|
console.log(
|
|
34195
33857
|
`
|
|
34196
|
-
Run ${
|
|
33858
|
+
Run ${pc47.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
34197
33859
|
`
|
|
34198
33860
|
);
|
|
34199
33861
|
process.exit(1);
|
|
@@ -34322,16 +33984,16 @@ Run ${pc48.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
34322
33984
|
return;
|
|
34323
33985
|
}
|
|
34324
33986
|
console.log("\n");
|
|
34325
|
-
clack44.log.success(
|
|
33987
|
+
clack44.log.success(pc47.green("Test SMS sent successfully!"));
|
|
34326
33988
|
console.log("");
|
|
34327
33989
|
clack44.note(
|
|
34328
33990
|
[
|
|
34329
|
-
`${
|
|
34330
|
-
`${
|
|
34331
|
-
`${
|
|
34332
|
-
`${
|
|
33991
|
+
`${pc47.bold("Message ID:")} ${pc47.cyan(messageId || "unknown")}`,
|
|
33992
|
+
`${pc47.bold("To:")} ${pc47.cyan(toNumber)}`,
|
|
33993
|
+
`${pc47.bold("Message:")} ${message}`,
|
|
33994
|
+
`${pc47.bold("Type:")} ${pc47.cyan(smsConfig?.phoneNumberType || "simulator")}`,
|
|
34333
33995
|
"",
|
|
34334
|
-
|
|
33996
|
+
pc47.dim(
|
|
34335
33997
|
smsConfig?.phoneNumberType === "simulator" ? "Note: Simulator messages are not actually delivered" : "Check your phone for the message!"
|
|
34336
33998
|
)
|
|
34337
33999
|
].join("\n"),
|
|
@@ -34340,10 +34002,10 @@ Run ${pc48.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
34340
34002
|
if (smsConfig?.eventTracking?.enabled) {
|
|
34341
34003
|
console.log("");
|
|
34342
34004
|
clack44.log.info(
|
|
34343
|
-
|
|
34005
|
+
pc47.dim("Event tracking is enabled. Check DynamoDB for delivery status.")
|
|
34344
34006
|
);
|
|
34345
34007
|
}
|
|
34346
|
-
clack44.outro(
|
|
34008
|
+
clack44.outro(pc47.green("Test complete!"));
|
|
34347
34009
|
} catch (error) {
|
|
34348
34010
|
progress.stop();
|
|
34349
34011
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -34368,7 +34030,7 @@ Run ${pc48.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
34368
34030
|
clack44.log.error("Toll-free number registration is not complete");
|
|
34369
34031
|
console.log(
|
|
34370
34032
|
`
|
|
34371
|
-
Run ${
|
|
34033
|
+
Run ${pc47.cyan("wraps sms register")} to check registration status.
|
|
34372
34034
|
`
|
|
34373
34035
|
);
|
|
34374
34036
|
} else if (errorName === "AccessDeniedException") {
|
|
@@ -34377,7 +34039,7 @@ Run ${pc48.cyan("wraps sms register")} to check registration status.
|
|
|
34377
34039
|
);
|
|
34378
34040
|
console.log(
|
|
34379
34041
|
`
|
|
34380
|
-
Run ${
|
|
34042
|
+
Run ${pc47.cyan("wraps sms upgrade")} to update IAM policies.
|
|
34381
34043
|
`
|
|
34382
34044
|
);
|
|
34383
34045
|
} else {
|
|
@@ -34391,7 +34053,7 @@ Run ${pc48.cyan("wraps sms upgrade")} to update IAM policies.
|
|
|
34391
34053
|
init_esm_shims();
|
|
34392
34054
|
import * as clack45 from "@clack/prompts";
|
|
34393
34055
|
import * as pulumi29 from "@pulumi/pulumi";
|
|
34394
|
-
import
|
|
34056
|
+
import pc48 from "picocolors";
|
|
34395
34057
|
init_events();
|
|
34396
34058
|
init_aws();
|
|
34397
34059
|
init_errors();
|
|
@@ -34404,7 +34066,7 @@ async function smsUpgrade(options) {
|
|
|
34404
34066
|
const startTime = Date.now();
|
|
34405
34067
|
let upgradeAction = "";
|
|
34406
34068
|
if (!isJsonMode()) {
|
|
34407
|
-
clack45.intro(
|
|
34069
|
+
clack45.intro(pc48.bold("Wraps SMS Upgrade - Enhance Your SMS Infrastructure"));
|
|
34408
34070
|
}
|
|
34409
34071
|
const progress = new DeploymentProgress();
|
|
34410
34072
|
const wasAutoInstalled = await progress.execute(
|
|
@@ -34418,7 +34080,7 @@ async function smsUpgrade(options) {
|
|
|
34418
34080
|
"Validating AWS credentials",
|
|
34419
34081
|
async () => validateAWSCredentials()
|
|
34420
34082
|
);
|
|
34421
|
-
progress.info(`Connected to AWS account: ${
|
|
34083
|
+
progress.info(`Connected to AWS account: ${pc48.cyan(identity.accountId)}`);
|
|
34422
34084
|
let region = options.region;
|
|
34423
34085
|
if (!region) {
|
|
34424
34086
|
const defaultRegion = await getAWSRegion();
|
|
@@ -34427,34 +34089,34 @@ async function smsUpgrade(options) {
|
|
|
34427
34089
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
34428
34090
|
if (!metadata) {
|
|
34429
34091
|
clack45.log.error(
|
|
34430
|
-
`No Wraps connection found for account ${
|
|
34092
|
+
`No Wraps connection found for account ${pc48.cyan(identity.accountId)} in region ${pc48.cyan(region)}`
|
|
34431
34093
|
);
|
|
34432
34094
|
clack45.log.info(
|
|
34433
|
-
`Use ${
|
|
34095
|
+
`Use ${pc48.cyan("wraps sms init")} to create new infrastructure.`
|
|
34434
34096
|
);
|
|
34435
34097
|
process.exit(1);
|
|
34436
34098
|
}
|
|
34437
34099
|
if (!metadata.services.sms) {
|
|
34438
34100
|
clack45.log.error("No SMS infrastructure found");
|
|
34439
34101
|
clack45.log.info(
|
|
34440
|
-
`Use ${
|
|
34102
|
+
`Use ${pc48.cyan("wraps sms init")} to deploy SMS infrastructure.`
|
|
34441
34103
|
);
|
|
34442
34104
|
process.exit(1);
|
|
34443
34105
|
}
|
|
34444
34106
|
progress.info(`Found existing connection created: ${metadata.timestamp}`);
|
|
34445
34107
|
console.log(`
|
|
34446
|
-
${
|
|
34108
|
+
${pc48.bold("Current Configuration:")}
|
|
34447
34109
|
`);
|
|
34448
34110
|
if (metadata.services.sms.preset) {
|
|
34449
|
-
console.log(` Preset: ${
|
|
34111
|
+
console.log(` Preset: ${pc48.cyan(metadata.services.sms.preset)}`);
|
|
34450
34112
|
} else {
|
|
34451
|
-
console.log(` Preset: ${
|
|
34113
|
+
console.log(` Preset: ${pc48.cyan("custom")}`);
|
|
34452
34114
|
}
|
|
34453
34115
|
const config2 = metadata.services.sms.config;
|
|
34454
34116
|
if (!config2) {
|
|
34455
34117
|
clack45.log.error("No SMS configuration found in metadata");
|
|
34456
34118
|
clack45.log.info(
|
|
34457
|
-
`Use ${
|
|
34119
|
+
`Use ${pc48.cyan("wraps sms init")} to create new infrastructure.`
|
|
34458
34120
|
);
|
|
34459
34121
|
process.exit(1);
|
|
34460
34122
|
}
|
|
@@ -34466,45 +34128,45 @@ ${pc49.bold("Current Configuration:")}
|
|
|
34466
34128
|
"short-code": "Short code ($995+/mo, 100+ MPS)"
|
|
34467
34129
|
};
|
|
34468
34130
|
console.log(
|
|
34469
|
-
` Phone Type: ${
|
|
34131
|
+
` Phone Type: ${pc48.cyan(phoneTypeLabels2[config2.phoneNumberType] || config2.phoneNumberType)}`
|
|
34470
34132
|
);
|
|
34471
34133
|
}
|
|
34472
34134
|
if (config2.tracking?.enabled) {
|
|
34473
|
-
console.log(` ${
|
|
34135
|
+
console.log(` ${pc48.green("\u2713")} Delivery Tracking`);
|
|
34474
34136
|
if (config2.tracking.linkTracking) {
|
|
34475
|
-
console.log(` ${
|
|
34137
|
+
console.log(` ${pc48.dim("\u2514\u2500")} Link click tracking enabled`);
|
|
34476
34138
|
}
|
|
34477
34139
|
}
|
|
34478
34140
|
if (config2.eventTracking?.enabled) {
|
|
34479
|
-
console.log(` ${
|
|
34141
|
+
console.log(` ${pc48.green("\u2713")} Event Tracking (SNS)`);
|
|
34480
34142
|
if (config2.eventTracking.dynamoDBHistory) {
|
|
34481
34143
|
console.log(
|
|
34482
|
-
` ${
|
|
34144
|
+
` ${pc48.dim("\u2514\u2500")} Message History: ${pc48.cyan(config2.eventTracking.archiveRetention || "90days")}`
|
|
34483
34145
|
);
|
|
34484
34146
|
}
|
|
34485
34147
|
}
|
|
34486
34148
|
if (config2.messageArchiving?.enabled) {
|
|
34487
34149
|
console.log(
|
|
34488
|
-
` ${
|
|
34150
|
+
` ${pc48.green("\u2713")} Message Archiving (${config2.messageArchiving.retention})`
|
|
34489
34151
|
);
|
|
34490
34152
|
}
|
|
34491
34153
|
if (config2.optOutManagement) {
|
|
34492
|
-
console.log(` ${
|
|
34154
|
+
console.log(` ${pc48.green("\u2713")} Opt-out Management`);
|
|
34493
34155
|
}
|
|
34494
34156
|
if (config2.protectConfiguration?.enabled) {
|
|
34495
34157
|
const countries = config2.protectConfiguration.allowedCountries?.join(", ") || "US";
|
|
34496
|
-
console.log(` ${
|
|
34497
|
-
console.log(` ${
|
|
34158
|
+
console.log(` ${pc48.green("\u2713")} Fraud Protection`);
|
|
34159
|
+
console.log(` ${pc48.dim("\u2514\u2500")} Allowed countries: ${pc48.cyan(countries)}`);
|
|
34498
34160
|
if (config2.protectConfiguration.aitFiltering) {
|
|
34499
|
-
console.log(` ${
|
|
34161
|
+
console.log(` ${pc48.dim("\u2514\u2500")} AIT filtering: ${pc48.cyan("enabled")}`);
|
|
34500
34162
|
}
|
|
34501
34163
|
} else {
|
|
34502
|
-
console.log(` ${
|
|
34164
|
+
console.log(` ${pc48.dim("\u25CB")} Fraud Protection (not configured)`);
|
|
34503
34165
|
}
|
|
34504
34166
|
const currentCostData = calculateSMSCosts(config2, 1e4);
|
|
34505
34167
|
console.log(
|
|
34506
34168
|
`
|
|
34507
|
-
Estimated Cost: ${
|
|
34169
|
+
Estimated Cost: ${pc48.cyan(`~${formatCost3(currentCostData.total.monthly)}/mo`)}`
|
|
34508
34170
|
);
|
|
34509
34171
|
console.log("");
|
|
34510
34172
|
const phoneTypeLabels = {
|
|
@@ -34611,22 +34273,22 @@ ${pc49.bold("Current Configuration:")}
|
|
|
34611
34273
|
if (selectedType === "toll-free") {
|
|
34612
34274
|
console.log(
|
|
34613
34275
|
`
|
|
34614
|
-
${
|
|
34276
|
+
${pc48.yellow("\u26A0")} ${pc48.bold("Toll-free Registration Required")}
|
|
34615
34277
|
`
|
|
34616
34278
|
);
|
|
34617
34279
|
console.log(
|
|
34618
|
-
|
|
34280
|
+
pc48.dim("Toll-free numbers require carrier registration before")
|
|
34619
34281
|
);
|
|
34620
34282
|
console.log(
|
|
34621
|
-
|
|
34283
|
+
pc48.dim("they can send messages at scale. After deployment:\n")
|
|
34622
34284
|
);
|
|
34623
34285
|
console.log(
|
|
34624
|
-
` 1. Run ${
|
|
34286
|
+
` 1. Run ${pc48.cyan("wraps sms register")} to start registration`
|
|
34625
34287
|
);
|
|
34626
34288
|
console.log(" 2. Submit your business use case information");
|
|
34627
34289
|
console.log(" 3. Wait for carrier verification (1-5 business days)");
|
|
34628
34290
|
console.log(
|
|
34629
|
-
|
|
34291
|
+
pc48.dim("\nUntil verified, sending is limited to low volume.\n")
|
|
34630
34292
|
);
|
|
34631
34293
|
const confirmTollFree = await clack45.confirm({
|
|
34632
34294
|
message: "Continue with toll-free number request?",
|
|
@@ -34640,10 +34302,10 @@ ${pc49.yellow("\u26A0")} ${pc49.bold("Toll-free Registration Required")}
|
|
|
34640
34302
|
if (selectedType === "10dlc") {
|
|
34641
34303
|
console.log(
|
|
34642
34304
|
`
|
|
34643
|
-
${
|
|
34305
|
+
${pc48.yellow("\u26A0")} ${pc48.bold("10DLC Campaign Registration Required")}
|
|
34644
34306
|
`
|
|
34645
34307
|
);
|
|
34646
|
-
console.log(
|
|
34308
|
+
console.log(pc48.dim("10DLC requires brand and campaign registration:"));
|
|
34647
34309
|
console.log(" \u2022 Brand registration: one-time $4 fee");
|
|
34648
34310
|
console.log(" \u2022 Campaign registration: $15/mo per campaign");
|
|
34649
34311
|
console.log(" \u2022 Verification takes 1-7 business days");
|
|
@@ -34876,12 +34538,12 @@ ${pc49.yellow("\u26A0")} ${pc49.bold("10DLC Campaign Registration Required")}
|
|
|
34876
34538
|
const enableLinkTracking = !config2.tracking?.linkTracking;
|
|
34877
34539
|
if (enableLinkTracking) {
|
|
34878
34540
|
clack45.log.info(
|
|
34879
|
-
|
|
34541
|
+
pc48.dim(
|
|
34880
34542
|
"Link tracking will track clicks on URLs in your SMS messages."
|
|
34881
34543
|
)
|
|
34882
34544
|
);
|
|
34883
34545
|
clack45.log.info(
|
|
34884
|
-
|
|
34546
|
+
pc48.dim("URLs will be rewritten to go through a tracking endpoint.")
|
|
34885
34547
|
);
|
|
34886
34548
|
}
|
|
34887
34549
|
const confirmed = await clack45.confirm({
|
|
@@ -35094,18 +34756,18 @@ ${pc49.yellow("\u26A0")} ${pc49.bold("10DLC Campaign Registration Required")}
|
|
|
35094
34756
|
const newCostData = calculateSMSCosts(updatedConfig, 1e4);
|
|
35095
34757
|
const costDiff = newCostData.total.monthly - currentCostData.total.monthly;
|
|
35096
34758
|
console.log(`
|
|
35097
|
-
${
|
|
34759
|
+
${pc48.bold("Cost Impact:")}`);
|
|
35098
34760
|
console.log(
|
|
35099
|
-
` Current: ${
|
|
34761
|
+
` Current: ${pc48.cyan(`${formatCost3(currentCostData.total.monthly)}/mo`)}`
|
|
35100
34762
|
);
|
|
35101
34763
|
console.log(
|
|
35102
|
-
` New: ${
|
|
34764
|
+
` New: ${pc48.cyan(`${formatCost3(newCostData.total.monthly)}/mo`)}`
|
|
35103
34765
|
);
|
|
35104
34766
|
if (costDiff > 0) {
|
|
35105
|
-
console.log(` Change: ${
|
|
34767
|
+
console.log(` Change: ${pc48.yellow(`+${formatCost3(costDiff)}/mo`)}`);
|
|
35106
34768
|
} else if (costDiff < 0) {
|
|
35107
34769
|
console.log(
|
|
35108
|
-
` Change: ${
|
|
34770
|
+
` Change: ${pc48.green(`-${formatCost3(Math.abs(costDiff))}/mo`)}`
|
|
35109
34771
|
);
|
|
35110
34772
|
}
|
|
35111
34773
|
console.log("");
|
|
@@ -35257,43 +34919,43 @@ ${pc49.bold("Cost Impact:")}`);
|
|
|
35257
34919
|
}
|
|
35258
34920
|
progress.info("Connection metadata updated");
|
|
35259
34921
|
console.log("\n");
|
|
35260
|
-
clack45.log.success(
|
|
34922
|
+
clack45.log.success(pc48.green(pc48.bold("SMS infrastructure upgraded!")));
|
|
35261
34923
|
console.log("\n");
|
|
35262
34924
|
clack45.note(
|
|
35263
34925
|
[
|
|
35264
|
-
`${
|
|
35265
|
-
`${
|
|
35266
|
-
`${
|
|
35267
|
-
`${
|
|
35268
|
-
outputs.tableName ? `${
|
|
34926
|
+
`${pc48.bold("Phone Number:")} ${pc48.cyan(outputs.phoneNumber || "Provisioning...")}`,
|
|
34927
|
+
`${pc48.bold("Phone Type:")} ${pc48.cyan(updatedConfig.phoneNumberType || "simulator")}`,
|
|
34928
|
+
`${pc48.bold("Config Set:")} ${pc48.cyan(outputs.configSetName || "wraps-sms-config")}`,
|
|
34929
|
+
`${pc48.bold("Region:")} ${pc48.cyan(outputs.region)}`,
|
|
34930
|
+
outputs.tableName ? `${pc48.bold("History Table:")} ${pc48.cyan(outputs.tableName)}` : "",
|
|
35269
34931
|
"",
|
|
35270
|
-
|
|
35271
|
-
|
|
34932
|
+
pc48.dim("IAM Role:"),
|
|
34933
|
+
pc48.dim(` ${outputs.roleArn}`)
|
|
35272
34934
|
].filter(Boolean).join("\n"),
|
|
35273
34935
|
"SMS Infrastructure"
|
|
35274
34936
|
);
|
|
35275
34937
|
console.log(`
|
|
35276
|
-
${
|
|
34938
|
+
${pc48.green("\u2713")} ${pc48.bold("Upgrade complete!")}
|
|
35277
34939
|
`);
|
|
35278
34940
|
if (upgradeAction === "phone-number") {
|
|
35279
34941
|
console.log(
|
|
35280
|
-
`Upgraded to ${
|
|
34942
|
+
`Upgraded to ${pc48.cyan(updatedConfig.phoneNumberType)} number (${pc48.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
35281
34943
|
`
|
|
35282
34944
|
);
|
|
35283
34945
|
if (updatedConfig.phoneNumberType === "toll-free") {
|
|
35284
|
-
console.log(`${
|
|
34946
|
+
console.log(`${pc48.bold("Next Steps:")}`);
|
|
35285
34947
|
console.log(
|
|
35286
|
-
` 1. Run ${
|
|
34948
|
+
` 1. Run ${pc48.cyan("wraps sms register")} to start toll-free registration`
|
|
35287
34949
|
);
|
|
35288
34950
|
console.log(" 2. Submit your business information and use case");
|
|
35289
34951
|
console.log(" 3. Wait for carrier verification (1-5 business days)");
|
|
35290
34952
|
console.log("");
|
|
35291
34953
|
console.log(
|
|
35292
|
-
|
|
34954
|
+
pc48.dim("Until verified, your number can only send limited messages.")
|
|
35293
34955
|
);
|
|
35294
34956
|
console.log("");
|
|
35295
34957
|
} else if (updatedConfig.phoneNumberType === "10dlc") {
|
|
35296
|
-
console.log(`${
|
|
34958
|
+
console.log(`${pc48.bold("Next Steps:")}`);
|
|
35297
34959
|
console.log(" 1. Register your brand in the AWS Console");
|
|
35298
34960
|
console.log(" 2. Create a 10DLC campaign for your use case");
|
|
35299
34961
|
console.log(" 3. Wait for campaign approval (1-7 business days)");
|
|
@@ -35301,16 +34963,16 @@ ${pc49.green("\u2713")} ${pc49.bold("Upgrade complete!")}
|
|
|
35301
34963
|
}
|
|
35302
34964
|
} else if (upgradeAction === "preset" && newPreset) {
|
|
35303
34965
|
console.log(
|
|
35304
|
-
`Upgraded to ${
|
|
34966
|
+
`Upgraded to ${pc48.cyan(newPreset)} preset (${pc48.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
35305
34967
|
`
|
|
35306
34968
|
);
|
|
35307
34969
|
} else {
|
|
35308
34970
|
console.log(
|
|
35309
|
-
`Updated configuration (${
|
|
34971
|
+
`Updated configuration (${pc48.green(`${formatCost3(newCostData.total.monthly)}/mo`)})
|
|
35310
34972
|
`
|
|
35311
34973
|
);
|
|
35312
34974
|
}
|
|
35313
|
-
console.log(
|
|
34975
|
+
console.log(pc48.dim(getSMSCostSummary(updatedConfig, 1e4)));
|
|
35314
34976
|
const enabledFeatures = [];
|
|
35315
34977
|
if (updatedConfig.tracking?.enabled) {
|
|
35316
34978
|
enabledFeatures.push("tracking");
|
|
@@ -35334,7 +34996,7 @@ ${pc49.green("\u2713")} ${pc49.bold("Upgrade complete!")}
|
|
|
35334
34996
|
action: typeof upgradeAction === "string" ? upgradeAction : void 0,
|
|
35335
34997
|
duration_ms: Date.now() - startTime
|
|
35336
34998
|
});
|
|
35337
|
-
clack45.outro(
|
|
34999
|
+
clack45.outro(pc48.green("Upgrade complete!"));
|
|
35338
35000
|
}
|
|
35339
35001
|
|
|
35340
35002
|
// src/commands/sms/verify-number.ts
|
|
@@ -35354,12 +35016,12 @@ import {
|
|
|
35354
35016
|
VerifyDestinationNumberCommand
|
|
35355
35017
|
} from "@aws-sdk/client-pinpoint-sms-voice-v2";
|
|
35356
35018
|
import * as clack46 from "@clack/prompts";
|
|
35357
|
-
import
|
|
35019
|
+
import pc49 from "picocolors";
|
|
35358
35020
|
async function smsVerifyNumber(options) {
|
|
35359
35021
|
const startTime = Date.now();
|
|
35360
35022
|
const progress = new DeploymentProgress();
|
|
35361
35023
|
if (!isJsonMode()) {
|
|
35362
|
-
clack46.intro(
|
|
35024
|
+
clack46.intro(pc49.bold("Wraps SMS - Verify Destination Number"));
|
|
35363
35025
|
}
|
|
35364
35026
|
const identity = await progress.execute(
|
|
35365
35027
|
"Validating AWS credentials",
|
|
@@ -35372,7 +35034,7 @@ async function smsVerifyNumber(options) {
|
|
|
35372
35034
|
clack46.log.error("No SMS infrastructure found");
|
|
35373
35035
|
console.log(
|
|
35374
35036
|
`
|
|
35375
|
-
Run ${
|
|
35037
|
+
Run ${pc49.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
35376
35038
|
`
|
|
35377
35039
|
);
|
|
35378
35040
|
process.exit(1);
|
|
@@ -35389,16 +35051,16 @@ Run ${pc50.cyan("wraps sms init")} to deploy SMS infrastructure.
|
|
|
35389
35051
|
clack46.log.info("No verified destination numbers found");
|
|
35390
35052
|
console.log(
|
|
35391
35053
|
`
|
|
35392
|
-
Run ${
|
|
35054
|
+
Run ${pc49.cyan("wraps sms verify-number")} to verify a number.
|
|
35393
35055
|
`
|
|
35394
35056
|
);
|
|
35395
35057
|
} else {
|
|
35396
35058
|
console.log("\n");
|
|
35397
|
-
clack46.log.info(
|
|
35059
|
+
clack46.log.info(pc49.bold("Verified Destination Numbers:"));
|
|
35398
35060
|
console.log("");
|
|
35399
35061
|
for (const num of response.VerifiedDestinationNumbers) {
|
|
35400
|
-
const status2 = num.Status === "VERIFIED" ?
|
|
35401
|
-
console.log(` ${
|
|
35062
|
+
const status2 = num.Status === "VERIFIED" ? pc49.green("\u2713 Verified") : pc49.yellow("\u29D6 Pending");
|
|
35063
|
+
console.log(` ${pc49.cyan(num.DestinationPhoneNumber)} - ${status2}`);
|
|
35402
35064
|
}
|
|
35403
35065
|
console.log("");
|
|
35404
35066
|
}
|
|
@@ -35416,7 +35078,7 @@ Run ${pc50.cyan("wraps sms verify-number")} to verify a number.
|
|
|
35416
35078
|
});
|
|
35417
35079
|
return;
|
|
35418
35080
|
}
|
|
35419
|
-
clack46.outro(
|
|
35081
|
+
clack46.outro(pc49.green("Done!"));
|
|
35420
35082
|
return;
|
|
35421
35083
|
} catch (error) {
|
|
35422
35084
|
progress.stop();
|
|
@@ -35435,7 +35097,7 @@ Run ${pc50.cyan("wraps sms verify-number")} to verify a number.
|
|
|
35435
35097
|
clack46.log.error("Phone number is required for deletion");
|
|
35436
35098
|
console.log(
|
|
35437
35099
|
`
|
|
35438
|
-
Usage: ${
|
|
35100
|
+
Usage: ${pc49.cyan("wraps sms verify-number --delete --phone-number +14155551234")}
|
|
35439
35101
|
`
|
|
35440
35102
|
);
|
|
35441
35103
|
process.exit(1);
|
|
@@ -35460,7 +35122,7 @@ Usage: ${pc50.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
35460
35122
|
);
|
|
35461
35123
|
});
|
|
35462
35124
|
progress.stop();
|
|
35463
|
-
clack46.log.success(`Removed ${
|
|
35125
|
+
clack46.log.success(`Removed ${pc49.cyan(phoneNumber2)} from verified list`);
|
|
35464
35126
|
trackCommand("sms:verify-number:delete", {
|
|
35465
35127
|
success: true,
|
|
35466
35128
|
duration_ms: Date.now() - startTime
|
|
@@ -35472,7 +35134,7 @@ Usage: ${pc50.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
35472
35134
|
});
|
|
35473
35135
|
return;
|
|
35474
35136
|
}
|
|
35475
|
-
clack46.outro(
|
|
35137
|
+
clack46.outro(pc49.green("Done!"));
|
|
35476
35138
|
return;
|
|
35477
35139
|
} catch (error) {
|
|
35478
35140
|
progress.stop();
|
|
@@ -35544,11 +35206,11 @@ Usage: ${pc50.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
35544
35206
|
progress.stop();
|
|
35545
35207
|
console.log("\n");
|
|
35546
35208
|
clack46.log.success(
|
|
35547
|
-
|
|
35209
|
+
pc49.green(`Phone number ${pc49.cyan(phoneNumber)} verified!`)
|
|
35548
35210
|
);
|
|
35549
35211
|
console.log("");
|
|
35550
35212
|
console.log(
|
|
35551
|
-
`You can now send test messages to this number with ${
|
|
35213
|
+
`You can now send test messages to this number with ${pc49.cyan("wraps sms test")}`
|
|
35552
35214
|
);
|
|
35553
35215
|
trackCommand("sms:verify-number:confirm", {
|
|
35554
35216
|
success: true,
|
|
@@ -35561,7 +35223,7 @@ Usage: ${pc50.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
35561
35223
|
});
|
|
35562
35224
|
return;
|
|
35563
35225
|
}
|
|
35564
|
-
clack46.outro(
|
|
35226
|
+
clack46.outro(pc49.green("Verification complete!"));
|
|
35565
35227
|
return;
|
|
35566
35228
|
} catch (error) {
|
|
35567
35229
|
progress.stop();
|
|
@@ -35570,7 +35232,7 @@ Usage: ${pc50.cyan("wraps sms verify-number --delete --phone-number +14155551234
|
|
|
35570
35232
|
clack46.log.error("Invalid verification code. Please try again.");
|
|
35571
35233
|
console.log(
|
|
35572
35234
|
`
|
|
35573
|
-
Run ${
|
|
35235
|
+
Run ${pc49.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
|
|
35574
35236
|
`
|
|
35575
35237
|
);
|
|
35576
35238
|
} else {
|
|
@@ -35606,11 +35268,11 @@ Run ${pc50.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
35606
35268
|
);
|
|
35607
35269
|
});
|
|
35608
35270
|
progress.stop();
|
|
35609
|
-
clack46.log.success(`Verification code resent to ${
|
|
35271
|
+
clack46.log.success(`Verification code resent to ${pc49.cyan(phoneNumber)}`);
|
|
35610
35272
|
console.log("");
|
|
35611
35273
|
console.log(
|
|
35612
35274
|
`Once you receive the code, run:
|
|
35613
|
-
${
|
|
35275
|
+
${pc49.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
|
|
35614
35276
|
);
|
|
35615
35277
|
trackCommand("sms:verify-number:resend", {
|
|
35616
35278
|
success: true,
|
|
@@ -35623,7 +35285,7 @@ Run ${pc50.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
35623
35285
|
});
|
|
35624
35286
|
return;
|
|
35625
35287
|
}
|
|
35626
|
-
clack46.outro(
|
|
35288
|
+
clack46.outro(pc49.green("Code sent!"));
|
|
35627
35289
|
return;
|
|
35628
35290
|
} catch (error) {
|
|
35629
35291
|
progress.stop();
|
|
@@ -35652,9 +35314,9 @@ Run ${pc50.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
35652
35314
|
return;
|
|
35653
35315
|
}
|
|
35654
35316
|
clack46.log.info(
|
|
35655
|
-
`Number ${
|
|
35317
|
+
`Number ${pc49.cyan(phoneNumber)} is already verified and ready to use!`
|
|
35656
35318
|
);
|
|
35657
|
-
clack46.outro(
|
|
35319
|
+
clack46.outro(pc49.green("Done!"));
|
|
35658
35320
|
return;
|
|
35659
35321
|
}
|
|
35660
35322
|
if (existingNumber?.Status === "PENDING") {
|
|
@@ -35679,14 +35341,14 @@ Run ${pc50.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
35679
35341
|
return;
|
|
35680
35342
|
}
|
|
35681
35343
|
clack46.log.info(
|
|
35682
|
-
`Verification already in progress. New code sent to ${
|
|
35344
|
+
`Verification already in progress. New code sent to ${pc49.cyan(phoneNumber)}`
|
|
35683
35345
|
);
|
|
35684
35346
|
console.log("");
|
|
35685
35347
|
console.log(
|
|
35686
35348
|
`Once you receive the code, run:
|
|
35687
|
-
${
|
|
35349
|
+
${pc49.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`
|
|
35688
35350
|
);
|
|
35689
|
-
clack46.outro(
|
|
35351
|
+
clack46.outro(pc49.green("Code sent!"));
|
|
35690
35352
|
return;
|
|
35691
35353
|
}
|
|
35692
35354
|
const createResponse = await progress.execute(
|
|
@@ -35708,7 +35370,7 @@ Run ${pc50.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
35708
35370
|
progress.stop();
|
|
35709
35371
|
console.log("\n");
|
|
35710
35372
|
clack46.log.success(
|
|
35711
|
-
`Verification code sent to ${
|
|
35373
|
+
`Verification code sent to ${pc49.cyan(phoneNumber)} via SMS`
|
|
35712
35374
|
);
|
|
35713
35375
|
console.log("");
|
|
35714
35376
|
clack46.note(
|
|
@@ -35716,9 +35378,9 @@ Run ${pc50.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
35716
35378
|
"1. Check your phone for the verification code",
|
|
35717
35379
|
"",
|
|
35718
35380
|
"2. Complete verification with:",
|
|
35719
|
-
` ${
|
|
35381
|
+
` ${pc49.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --code YOUR_CODE`)}`,
|
|
35720
35382
|
"",
|
|
35721
|
-
|
|
35383
|
+
pc49.dim("The code expires in 24 hours")
|
|
35722
35384
|
].join("\n"),
|
|
35723
35385
|
"Next Steps"
|
|
35724
35386
|
);
|
|
@@ -35734,7 +35396,7 @@ Run ${pc50.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
35734
35396
|
});
|
|
35735
35397
|
return;
|
|
35736
35398
|
}
|
|
35737
|
-
clack46.outro(
|
|
35399
|
+
clack46.outro(pc49.green("Verification started!"));
|
|
35738
35400
|
} catch (error) {
|
|
35739
35401
|
progress.stop();
|
|
35740
35402
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -35742,7 +35404,7 @@ Run ${pc50.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
35742
35404
|
clack46.log.error("This number is already being verified");
|
|
35743
35405
|
console.log(
|
|
35744
35406
|
`
|
|
35745
|
-
Run ${
|
|
35407
|
+
Run ${pc49.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`)} to get a new code.
|
|
35746
35408
|
`
|
|
35747
35409
|
);
|
|
35748
35410
|
} else {
|
|
@@ -35759,18 +35421,18 @@ Run ${pc50.cyan(`wraps sms verify-number --phone-number ${phoneNumber} --resend`
|
|
|
35759
35421
|
init_esm_shims();
|
|
35760
35422
|
init_events();
|
|
35761
35423
|
import * as clack47 from "@clack/prompts";
|
|
35762
|
-
import
|
|
35424
|
+
import pc50 from "picocolors";
|
|
35763
35425
|
async function support() {
|
|
35764
35426
|
trackCommand("support", { success: true });
|
|
35765
|
-
clack47.intro(
|
|
35427
|
+
clack47.intro(pc50.bold("Get Help with Wraps"));
|
|
35766
35428
|
console.log();
|
|
35767
|
-
console.log(` ${
|
|
35429
|
+
console.log(` ${pc50.bold("Email:")} ${pc50.cyan("hey@wraps.sh")}`);
|
|
35768
35430
|
console.log(
|
|
35769
|
-
` ${
|
|
35431
|
+
` ${pc50.bold("GitHub:")} ${pc50.cyan("https://github.com/wraps-dev/wraps/issues")}`
|
|
35770
35432
|
);
|
|
35771
|
-
console.log(` ${
|
|
35433
|
+
console.log(` ${pc50.bold("Docs:")} ${pc50.cyan("https://wraps.dev/docs")}`);
|
|
35772
35434
|
console.log();
|
|
35773
|
-
console.log(
|
|
35435
|
+
console.log(pc50.dim(" Response time: Usually within 24 hours"));
|
|
35774
35436
|
console.log();
|
|
35775
35437
|
}
|
|
35776
35438
|
|
|
@@ -35778,7 +35440,7 @@ async function support() {
|
|
|
35778
35440
|
init_esm_shims();
|
|
35779
35441
|
init_client();
|
|
35780
35442
|
import * as clack48 from "@clack/prompts";
|
|
35781
|
-
import
|
|
35443
|
+
import pc51 from "picocolors";
|
|
35782
35444
|
async function telemetryEnable() {
|
|
35783
35445
|
const client = getTelemetryClient();
|
|
35784
35446
|
const override = client.enable();
|
|
@@ -35786,70 +35448,70 @@ async function telemetryEnable() {
|
|
|
35786
35448
|
clack48.log.warn(
|
|
35787
35449
|
"Telemetry enabled in config, but overridden by environment"
|
|
35788
35450
|
);
|
|
35789
|
-
console.log(` Reason: ${
|
|
35790
|
-
console.log(` Config: ${
|
|
35451
|
+
console.log(` Reason: ${pc51.yellow(override)}`);
|
|
35452
|
+
console.log(` Config: ${pc51.dim(client.getConfigPath())}`);
|
|
35791
35453
|
console.log();
|
|
35792
35454
|
} else {
|
|
35793
|
-
clack48.log.success(
|
|
35794
|
-
console.log(` Config: ${
|
|
35455
|
+
clack48.log.success(pc51.green("Telemetry enabled"));
|
|
35456
|
+
console.log(` Config: ${pc51.dim(client.getConfigPath())}`);
|
|
35795
35457
|
console.log(`
|
|
35796
|
-
${
|
|
35458
|
+
${pc51.dim("Thank you for helping improve Wraps!")}
|
|
35797
35459
|
`);
|
|
35798
35460
|
}
|
|
35799
35461
|
}
|
|
35800
35462
|
async function telemetryDisable() {
|
|
35801
35463
|
const client = getTelemetryClient();
|
|
35802
35464
|
client.disable();
|
|
35803
|
-
clack48.log.success(
|
|
35804
|
-
console.log(` Config: ${
|
|
35465
|
+
clack48.log.success(pc51.green("Telemetry disabled"));
|
|
35466
|
+
console.log(` Config: ${pc51.dim(client.getConfigPath())}`);
|
|
35805
35467
|
console.log(
|
|
35806
35468
|
`
|
|
35807
|
-
${
|
|
35469
|
+
${pc51.dim("You can re-enable with:")} wraps telemetry enable
|
|
35808
35470
|
`
|
|
35809
35471
|
);
|
|
35810
35472
|
}
|
|
35811
35473
|
async function telemetryStatus() {
|
|
35812
35474
|
const client = getTelemetryClient();
|
|
35813
|
-
clack48.intro(
|
|
35475
|
+
clack48.intro(pc51.bold("Telemetry Status"));
|
|
35814
35476
|
const override = client.getEnvOverride();
|
|
35815
|
-
const status2 = client.isEnabled() ?
|
|
35477
|
+
const status2 = client.isEnabled() ? pc51.green("Enabled") : pc51.red("Disabled");
|
|
35816
35478
|
console.log();
|
|
35817
|
-
console.log(` ${
|
|
35479
|
+
console.log(` ${pc51.bold("Status:")} ${status2}`);
|
|
35818
35480
|
if (!client.isEnabled() && override) {
|
|
35819
|
-
console.log(` ${
|
|
35481
|
+
console.log(` ${pc51.bold("Reason:")} ${pc51.yellow(override)}`);
|
|
35820
35482
|
}
|
|
35821
|
-
console.log(` ${
|
|
35483
|
+
console.log(` ${pc51.bold("Config file:")} ${pc51.dim(client.getConfigPath())}`);
|
|
35822
35484
|
if (client.isEnabled()) {
|
|
35823
35485
|
console.log();
|
|
35824
|
-
console.log(
|
|
35825
|
-
console.log(` ${
|
|
35486
|
+
console.log(pc51.bold(" How to opt-out:"));
|
|
35487
|
+
console.log(` ${pc51.cyan("wraps telemetry disable")}`);
|
|
35826
35488
|
console.log(
|
|
35827
|
-
` ${
|
|
35489
|
+
` ${pc51.dim("Or set:")} ${pc51.cyan("WRAPS_TELEMETRY_DISABLED=1")}`
|
|
35828
35490
|
);
|
|
35829
|
-
console.log(` ${
|
|
35491
|
+
console.log(` ${pc51.dim("Or set:")} ${pc51.cyan("DO_NOT_TRACK=1")}`);
|
|
35830
35492
|
} else {
|
|
35831
35493
|
console.log();
|
|
35832
|
-
console.log(
|
|
35833
|
-
console.log(` ${
|
|
35494
|
+
console.log(pc51.bold(" How to opt-in:"));
|
|
35495
|
+
console.log(` ${pc51.cyan("wraps telemetry enable")}`);
|
|
35834
35496
|
}
|
|
35835
35497
|
console.log();
|
|
35836
|
-
console.log(
|
|
35498
|
+
console.log(pc51.bold(" Debug mode:"));
|
|
35837
35499
|
console.log(
|
|
35838
|
-
` ${
|
|
35500
|
+
` ${pc51.dim("See what would be sent:")} ${pc51.cyan("WRAPS_TELEMETRY_DEBUG=1 wraps <command>")}`
|
|
35839
35501
|
);
|
|
35840
35502
|
console.log();
|
|
35841
35503
|
console.log(
|
|
35842
|
-
` ${
|
|
35504
|
+
` ${pc51.dim("Learn more:")} ${pc51.cyan("https://wraps.dev/docs/telemetry")}`
|
|
35843
35505
|
);
|
|
35844
35506
|
console.log();
|
|
35845
35507
|
}
|
|
35846
35508
|
|
|
35847
35509
|
// src/commands/workflow/init.ts
|
|
35848
35510
|
init_esm_shims();
|
|
35849
|
-
import { existsSync as
|
|
35850
|
-
import { join as
|
|
35511
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync2, writeFileSync } from "fs";
|
|
35512
|
+
import { join as join18 } from "path";
|
|
35851
35513
|
import * as clack49 from "@clack/prompts";
|
|
35852
|
-
import
|
|
35514
|
+
import pc52 from "picocolors";
|
|
35853
35515
|
var EXAMPLE_CASCADE_WORKFLOW = `import {
|
|
35854
35516
|
defineWorkflow,
|
|
35855
35517
|
sendEmail,
|
|
@@ -35944,15 +35606,15 @@ export default defineConfig({
|
|
|
35944
35606
|
});
|
|
35945
35607
|
`;
|
|
35946
35608
|
async function workflowInit(options = {}) {
|
|
35947
|
-
clack49.intro(
|
|
35948
|
-
const wrapsDir =
|
|
35949
|
-
const workflowsDir =
|
|
35950
|
-
const configPath =
|
|
35951
|
-
if (
|
|
35609
|
+
clack49.intro(pc52.bgCyan(pc52.black(" wraps workflow init ")));
|
|
35610
|
+
const wrapsDir = join18(process.cwd(), "wraps");
|
|
35611
|
+
const workflowsDir = join18(wrapsDir, "workflows");
|
|
35612
|
+
const configPath = join18(wrapsDir, "wraps.config.ts");
|
|
35613
|
+
if (existsSync17(workflowsDir)) {
|
|
35952
35614
|
clack49.log.info(
|
|
35953
|
-
`Workflows directory already exists at ${
|
|
35615
|
+
`Workflows directory already exists at ${pc52.cyan("wraps/workflows/")}`
|
|
35954
35616
|
);
|
|
35955
|
-
const files =
|
|
35617
|
+
const files = existsSync17(join18(workflowsDir, "cart-recovery.ts")) || existsSync17(join18(workflowsDir, "welcome-sequence.ts"));
|
|
35956
35618
|
if (files && !options.yes) {
|
|
35957
35619
|
const shouldContinue = await clack49.confirm({
|
|
35958
35620
|
message: "Example files may already exist. Overwrite them?",
|
|
@@ -35960,7 +35622,7 @@ async function workflowInit(options = {}) {
|
|
|
35960
35622
|
});
|
|
35961
35623
|
if (clack49.isCancel(shouldContinue) || !shouldContinue) {
|
|
35962
35624
|
clack49.log.info("Skipping file creation.");
|
|
35963
|
-
|
|
35625
|
+
showNextSteps2();
|
|
35964
35626
|
clack49.outro("Done!");
|
|
35965
35627
|
return;
|
|
35966
35628
|
}
|
|
@@ -35969,50 +35631,50 @@ async function workflowInit(options = {}) {
|
|
|
35969
35631
|
try {
|
|
35970
35632
|
const s = clack49.spinner();
|
|
35971
35633
|
s.start("Creating workflows directory...");
|
|
35972
|
-
|
|
35634
|
+
mkdirSync2(workflowsDir, { recursive: true });
|
|
35973
35635
|
s.stop("Created wraps/workflows/");
|
|
35974
35636
|
s.start("Scaffolding example workflows...");
|
|
35975
|
-
|
|
35976
|
-
|
|
35637
|
+
writeFileSync(
|
|
35638
|
+
join18(workflowsDir, "cart-recovery.ts"),
|
|
35977
35639
|
EXAMPLE_CASCADE_WORKFLOW,
|
|
35978
35640
|
"utf-8"
|
|
35979
35641
|
);
|
|
35980
|
-
|
|
35981
|
-
|
|
35642
|
+
writeFileSync(
|
|
35643
|
+
join18(workflowsDir, "welcome-sequence.ts"),
|
|
35982
35644
|
EXAMPLE_WELCOME_WORKFLOW,
|
|
35983
35645
|
"utf-8"
|
|
35984
35646
|
);
|
|
35985
35647
|
s.stop("Created 2 example workflows");
|
|
35986
|
-
if (!
|
|
35987
|
-
|
|
35988
|
-
clack49.log.info(`Created ${
|
|
35648
|
+
if (!existsSync17(configPath)) {
|
|
35649
|
+
writeFileSync(configPath, EXAMPLE_CONFIG, "utf-8");
|
|
35650
|
+
clack49.log.info(`Created ${pc52.cyan("wraps/wraps.config.ts")}`);
|
|
35989
35651
|
}
|
|
35990
35652
|
clack49.log.success(
|
|
35991
|
-
`${
|
|
35992
|
-
${
|
|
35993
|
-
${
|
|
35994
|
-
${
|
|
35653
|
+
`${pc52.bold("Workflows scaffolded!")} Created:
|
|
35654
|
+
${pc52.cyan("wraps/wraps.config.ts")} \u2014 Project config
|
|
35655
|
+
${pc52.cyan("wraps/workflows/cart-recovery.ts")} \u2014 Cross-channel cascade example
|
|
35656
|
+
${pc52.cyan("wraps/workflows/welcome-sequence.ts")} \u2014 Welcome series example`
|
|
35995
35657
|
);
|
|
35996
|
-
|
|
35997
|
-
clack49.outro(
|
|
35658
|
+
showNextSteps2();
|
|
35659
|
+
clack49.outro(pc52.green("Happy orchestrating!"));
|
|
35998
35660
|
} catch (error) {
|
|
35999
35661
|
clack49.log.error(
|
|
36000
35662
|
`Failed to scaffold workflows: ${error instanceof Error ? error.message : String(error)}`
|
|
36001
35663
|
);
|
|
36002
|
-
clack49.outro(
|
|
35664
|
+
clack49.outro(pc52.red("Scaffolding failed."));
|
|
36003
35665
|
process.exitCode = 1;
|
|
36004
35666
|
}
|
|
36005
35667
|
}
|
|
36006
|
-
function
|
|
35668
|
+
function showNextSteps2() {
|
|
36007
35669
|
clack49.log.info(
|
|
36008
|
-
`${
|
|
35670
|
+
`${pc52.bold("Next steps:")}
|
|
36009
35671
|
|
|
36010
|
-
1. Edit ${
|
|
36011
|
-
2. Edit your workflows in ${
|
|
36012
|
-
3. Validate: ${
|
|
36013
|
-
4. Push: ${
|
|
35672
|
+
1. Edit ${pc52.cyan("wraps/wraps.config.ts")} with your org slug and domain
|
|
35673
|
+
2. Edit your workflows in ${pc52.cyan("wraps/workflows/")}
|
|
35674
|
+
3. Validate: ${pc52.cyan("wraps email workflows validate")}
|
|
35675
|
+
4. Push: ${pc52.cyan("wraps email workflows push")}
|
|
36014
35676
|
|
|
36015
|
-
${
|
|
35677
|
+
${pc52.dim("Docs:")} ${pc52.underline("https://wraps.dev/docs/guides/orchestration")}`
|
|
36016
35678
|
);
|
|
36017
35679
|
}
|
|
36018
35680
|
|
|
@@ -36086,7 +35748,7 @@ if (nodeMajorVersion < 20) {
|
|
|
36086
35748
|
var __filename2 = fileURLToPath5(import.meta.url);
|
|
36087
35749
|
var __dirname3 = dirname3(__filename2);
|
|
36088
35750
|
var packageJson = JSON.parse(
|
|
36089
|
-
readFileSync3(
|
|
35751
|
+
readFileSync3(join19(__dirname3, "../package.json"), "utf-8")
|
|
36090
35752
|
);
|
|
36091
35753
|
var VERSION = packageJson.version;
|
|
36092
35754
|
setupTabCompletion();
|
|
@@ -36095,190 +35757,187 @@ function showVersion() {
|
|
|
36095
35757
|
process.exit(0);
|
|
36096
35758
|
}
|
|
36097
35759
|
function showHelp() {
|
|
36098
|
-
clack50.intro(
|
|
35760
|
+
clack50.intro(pc53.bold(`WRAPS CLI v${VERSION}`));
|
|
36099
35761
|
console.log("Deploy AWS infrastructure to your account\n");
|
|
36100
35762
|
console.log("Usage: wraps [service] <command> [options]\n");
|
|
36101
35763
|
console.log("Services:");
|
|
36102
|
-
console.log(` ${
|
|
35764
|
+
console.log(` ${pc53.cyan("email")} Email infrastructure (AWS SES)`);
|
|
36103
35765
|
console.log(
|
|
36104
|
-
` ${
|
|
35766
|
+
` ${pc53.cyan("sms")} SMS infrastructure (AWS End User Messaging)`
|
|
36105
35767
|
);
|
|
36106
35768
|
console.log(
|
|
36107
|
-
` ${
|
|
35769
|
+
` ${pc53.cyan("cdn")} CDN infrastructure (AWS S3 + CloudFront)
|
|
36108
35770
|
`
|
|
36109
35771
|
);
|
|
36110
35772
|
console.log("Email Commands:");
|
|
36111
35773
|
console.log(
|
|
36112
|
-
` ${
|
|
35774
|
+
` ${pc53.cyan("email init")} Deploy new email infrastructure`
|
|
36113
35775
|
);
|
|
36114
35776
|
console.log(
|
|
36115
|
-
` ${
|
|
35777
|
+
` ${pc53.cyan("email check")} Check email deliverability for a domain`
|
|
36116
35778
|
);
|
|
36117
35779
|
console.log(
|
|
36118
|
-
` ${
|
|
35780
|
+
` ${pc53.cyan("email connect")} Connect to existing AWS SES`
|
|
36119
35781
|
);
|
|
36120
35782
|
console.log(
|
|
36121
|
-
` ${
|
|
35783
|
+
` ${pc53.cyan("email status")} Show email infrastructure details`
|
|
36122
35784
|
);
|
|
36123
|
-
console.log(` ${
|
|
36124
|
-
console.log(` ${
|
|
35785
|
+
console.log(` ${pc53.cyan("email test")} Send a test email`);
|
|
35786
|
+
console.log(` ${pc53.cyan("email verify")} Verify domain DNS records`);
|
|
36125
35787
|
console.log(
|
|
36126
|
-
` ${
|
|
35788
|
+
` ${pc53.cyan("email sync")} Apply CLI updates to infrastructure`
|
|
36127
35789
|
);
|
|
36128
|
-
console.log(` ${
|
|
35790
|
+
console.log(` ${pc53.cyan("email upgrade")} Add features`);
|
|
36129
35791
|
console.log(
|
|
36130
|
-
` ${
|
|
35792
|
+
` ${pc53.cyan("email restore")} Restore original configuration`
|
|
36131
35793
|
);
|
|
36132
35794
|
console.log(
|
|
36133
|
-
` ${
|
|
35795
|
+
` ${pc53.cyan("email destroy")} Remove email infrastructure`
|
|
36134
35796
|
);
|
|
36135
|
-
console.log(` ${
|
|
36136
|
-
console.log(` ${
|
|
36137
|
-
console.log(` ${
|
|
35797
|
+
console.log(` ${pc53.cyan("email domains add")} Add a domain to SES`);
|
|
35798
|
+
console.log(` ${pc53.cyan("email domains list")} List all domains`);
|
|
35799
|
+
console.log(` ${pc53.cyan("email domains remove")} Remove a domain`);
|
|
36138
35800
|
console.log(
|
|
36139
|
-
` ${
|
|
35801
|
+
` ${pc53.cyan("email inbound init")} Enable inbound email receiving`
|
|
36140
35802
|
);
|
|
36141
|
-
console.log(` ${
|
|
35803
|
+
console.log(` ${pc53.cyan("email inbound status")} Show inbound email status`);
|
|
36142
35804
|
console.log(
|
|
36143
|
-
` ${
|
|
35805
|
+
` ${pc53.cyan("email inbound verify")} Verify inbound DNS records`
|
|
36144
35806
|
);
|
|
36145
35807
|
console.log(
|
|
36146
|
-
` ${
|
|
35808
|
+
` ${pc53.cyan("email inbound test")} Send test email and verify receipt`
|
|
36147
35809
|
);
|
|
36148
35810
|
console.log(
|
|
36149
|
-
` ${
|
|
35811
|
+
` ${pc53.cyan("email inbound destroy")} Remove inbound email infrastructure
|
|
36150
35812
|
`
|
|
36151
35813
|
);
|
|
36152
35814
|
console.log("Template Commands:");
|
|
36153
35815
|
console.log(
|
|
36154
|
-
` ${
|
|
35816
|
+
` ${pc53.cyan("email templates init")} Initialize templates-as-code`
|
|
36155
35817
|
);
|
|
36156
35818
|
console.log(
|
|
36157
|
-
` ${
|
|
35819
|
+
` ${pc53.cyan("email templates push")} Push templates to SES + dashboard`
|
|
36158
35820
|
);
|
|
36159
35821
|
console.log(
|
|
36160
|
-
` ${
|
|
35822
|
+
` ${pc53.cyan("email templates preview")} Preview templates in browser`
|
|
36161
35823
|
);
|
|
36162
35824
|
console.log(
|
|
36163
|
-
` ${
|
|
35825
|
+
` ${pc53.cyan("push")} ${pc53.dim("(alias for email templates push)")}
|
|
36164
35826
|
`
|
|
36165
35827
|
);
|
|
36166
35828
|
console.log("Workflow Commands:");
|
|
36167
35829
|
console.log(
|
|
36168
|
-
` ${
|
|
35830
|
+
` ${pc53.cyan("email workflows init")} Initialize workflows-as-code`
|
|
36169
35831
|
);
|
|
36170
35832
|
console.log(
|
|
36171
|
-
` ${
|
|
35833
|
+
` ${pc53.cyan("email workflows validate")} Validate workflow files`
|
|
36172
35834
|
);
|
|
36173
35835
|
console.log(
|
|
36174
|
-
` ${
|
|
36175
|
-
);
|
|
36176
|
-
console.log(
|
|
36177
|
-
` ${pc54.cyan("email workflows generate")} Generate workflow from template
|
|
35836
|
+
` ${pc53.cyan("email workflows push")} Push workflows to dashboard
|
|
36178
35837
|
`
|
|
36179
35838
|
);
|
|
36180
35839
|
console.log("SMS Commands:");
|
|
36181
|
-
console.log(` ${
|
|
35840
|
+
console.log(` ${pc53.cyan("sms init")} Deploy SMS infrastructure`);
|
|
36182
35841
|
console.log(
|
|
36183
|
-
` ${
|
|
35842
|
+
` ${pc53.cyan("sms status")} Show SMS infrastructure details`
|
|
36184
35843
|
);
|
|
36185
|
-
console.log(` ${
|
|
35844
|
+
console.log(` ${pc53.cyan("sms test")} Send a test SMS message`);
|
|
36186
35845
|
console.log(
|
|
36187
|
-
` ${
|
|
35846
|
+
` ${pc53.cyan("sms verify-number")} Verify a destination phone number`
|
|
36188
35847
|
);
|
|
36189
35848
|
console.log(
|
|
36190
|
-
` ${
|
|
35849
|
+
` ${pc53.cyan("sms sync")} Sync infrastructure (update Lambda, etc.)`
|
|
36191
35850
|
);
|
|
36192
|
-
console.log(` ${
|
|
36193
|
-
console.log(` ${
|
|
35851
|
+
console.log(` ${pc53.cyan("sms upgrade")} Upgrade SMS features`);
|
|
35852
|
+
console.log(` ${pc53.cyan("sms register")} Register toll-free number`);
|
|
36194
35853
|
console.log(
|
|
36195
|
-
` ${
|
|
35854
|
+
` ${pc53.cyan("sms destroy")} Remove SMS infrastructure
|
|
36196
35855
|
`
|
|
36197
35856
|
);
|
|
36198
35857
|
console.log("CDN Commands:");
|
|
36199
35858
|
console.log(
|
|
36200
|
-
` ${
|
|
35859
|
+
` ${pc53.cyan("cdn init")} Deploy CDN infrastructure (S3 + CloudFront)`
|
|
36201
35860
|
);
|
|
36202
35861
|
console.log(
|
|
36203
|
-
` ${
|
|
35862
|
+
` ${pc53.cyan("cdn status")} Show CDN infrastructure details`
|
|
36204
35863
|
);
|
|
36205
35864
|
console.log(
|
|
36206
|
-
` ${
|
|
35865
|
+
` ${pc53.cyan("cdn verify")} Check DNS and certificate status`
|
|
36207
35866
|
);
|
|
36208
35867
|
console.log(
|
|
36209
|
-
` ${
|
|
35868
|
+
` ${pc53.cyan("cdn upgrade")} Add custom domain after cert validation`
|
|
36210
35869
|
);
|
|
36211
35870
|
console.log(
|
|
36212
|
-
` ${
|
|
35871
|
+
` ${pc53.cyan("cdn sync")} Sync infrastructure with current config`
|
|
36213
35872
|
);
|
|
36214
35873
|
console.log(
|
|
36215
|
-
` ${
|
|
35874
|
+
` ${pc53.cyan("cdn destroy")} Remove CDN infrastructure
|
|
36216
35875
|
`
|
|
36217
35876
|
);
|
|
36218
35877
|
console.log("Local Development:");
|
|
36219
35878
|
console.log(
|
|
36220
|
-
` ${
|
|
35879
|
+
` ${pc53.cyan("console")} Start local web console
|
|
36221
35880
|
`
|
|
36222
35881
|
);
|
|
36223
35882
|
console.log("Platform:");
|
|
36224
35883
|
console.log(
|
|
36225
|
-
` ${
|
|
35884
|
+
` ${pc53.cyan("platform")} Show platform info and pricing`
|
|
36226
35885
|
);
|
|
36227
35886
|
console.log(
|
|
36228
|
-
` ${
|
|
35887
|
+
` ${pc53.cyan("platform connect")} Connect to Wraps Platform (events + IAM)`
|
|
36229
35888
|
);
|
|
36230
35889
|
console.log(
|
|
36231
|
-
` ${
|
|
35890
|
+
` ${pc53.cyan("platform update-role")} Update platform IAM permissions
|
|
36232
35891
|
`
|
|
36233
35892
|
);
|
|
36234
35893
|
console.log("Auth:");
|
|
36235
35894
|
console.log(
|
|
36236
|
-
` ${
|
|
35895
|
+
` ${pc53.cyan("auth login")} Sign in to wraps.dev (device flow)`
|
|
36237
35896
|
);
|
|
36238
|
-
console.log(` ${
|
|
35897
|
+
console.log(` ${pc53.cyan("auth status")} Show current auth state`);
|
|
36239
35898
|
console.log(
|
|
36240
|
-
` ${
|
|
35899
|
+
` ${pc53.cyan("auth logout")} Sign out and remove stored token
|
|
36241
35900
|
`
|
|
36242
35901
|
);
|
|
36243
35902
|
console.log("AWS Setup:");
|
|
36244
35903
|
console.log(
|
|
36245
|
-
` ${
|
|
35904
|
+
` ${pc53.cyan("aws setup")} Interactive AWS setup wizard`
|
|
36246
35905
|
);
|
|
36247
35906
|
console.log(
|
|
36248
|
-
` ${
|
|
35907
|
+
` ${pc53.cyan("aws doctor")} Diagnose AWS configuration issues
|
|
36249
35908
|
`
|
|
36250
35909
|
);
|
|
36251
35910
|
console.log("Global Commands:");
|
|
36252
|
-
console.log(` ${
|
|
36253
|
-
console.log(` ${
|
|
36254
|
-
console.log(` ${
|
|
36255
|
-
console.log(` ${
|
|
35911
|
+
console.log(` ${pc53.cyan("status")} Show overview of all services`);
|
|
35912
|
+
console.log(` ${pc53.cyan("destroy")} Remove deployed infrastructure`);
|
|
35913
|
+
console.log(` ${pc53.cyan("permissions")} Show required AWS IAM permissions`);
|
|
35914
|
+
console.log(` ${pc53.cyan("completion")} Generate shell completion script`);
|
|
36256
35915
|
console.log(
|
|
36257
|
-
` ${
|
|
35916
|
+
` ${pc53.cyan("telemetry")} Manage anonymous telemetry settings`
|
|
36258
35917
|
);
|
|
36259
|
-
console.log(` ${
|
|
35918
|
+
console.log(` ${pc53.cyan("news")} Show recent Wraps updates`);
|
|
36260
35919
|
console.log(
|
|
36261
|
-
` ${
|
|
35920
|
+
` ${pc53.cyan("support")} Get help and support contact info
|
|
36262
35921
|
`
|
|
36263
35922
|
);
|
|
36264
35923
|
console.log("Options:");
|
|
36265
35924
|
console.log(
|
|
36266
|
-
` ${
|
|
36267
|
-
);
|
|
36268
|
-
console.log(` ${
|
|
36269
|
-
console.log(` ${
|
|
36270
|
-
console.log(` ${
|
|
36271
|
-
console.log(` ${
|
|
36272
|
-
console.log(` ${
|
|
36273
|
-
console.log(` ${
|
|
36274
|
-
console.log(` ${
|
|
35925
|
+
` ${pc53.dim("-p, --provider")} Hosting provider (vercel, aws, railway, other)`
|
|
35926
|
+
);
|
|
35927
|
+
console.log(` ${pc53.dim("-r, --region")} AWS region`);
|
|
35928
|
+
console.log(` ${pc53.dim("-d, --domain")} Domain name`);
|
|
35929
|
+
console.log(` ${pc53.dim("--account")} AWS account ID or alias`);
|
|
35930
|
+
console.log(` ${pc53.dim("--preset")} Configuration preset`);
|
|
35931
|
+
console.log(` ${pc53.dim("--token")} API key or token for auth`);
|
|
35932
|
+
console.log(` ${pc53.dim("-y, --yes")} Skip confirmation prompts`);
|
|
35933
|
+
console.log(` ${pc53.dim("-f, --force")} Force destructive operations`);
|
|
36275
35934
|
console.log(
|
|
36276
|
-
` ${
|
|
35935
|
+
` ${pc53.dim("--preview")} Preview changes without deploying`
|
|
36277
35936
|
);
|
|
36278
|
-
console.log(` ${
|
|
35937
|
+
console.log(` ${pc53.dim("-v, --version")} Show version number
|
|
36279
35938
|
`);
|
|
36280
35939
|
console.log(
|
|
36281
|
-
`Run ${
|
|
35940
|
+
`Run ${pc53.cyan("wraps <service> <command> --help")} for more information.
|
|
36282
35941
|
`
|
|
36283
35942
|
);
|
|
36284
35943
|
}
|
|
@@ -36463,11 +36122,6 @@ args.options([
|
|
|
36463
36122
|
description: "Push workflow as draft without enabling it",
|
|
36464
36123
|
defaultValue: false
|
|
36465
36124
|
},
|
|
36466
|
-
{
|
|
36467
|
-
name: "name",
|
|
36468
|
-
description: "Output file slug for generated workflow",
|
|
36469
|
-
defaultValue: void 0
|
|
36470
|
-
},
|
|
36471
36125
|
{
|
|
36472
36126
|
name: "noExample",
|
|
36473
36127
|
description: "Skip creating example template",
|
|
@@ -36493,25 +36147,25 @@ if (!primaryCommand) {
|
|
|
36493
36147
|
const telemetry = getTelemetryClient();
|
|
36494
36148
|
if (telemetry.shouldShowNotification()) {
|
|
36495
36149
|
console.log();
|
|
36496
|
-
clack50.log.info(
|
|
36150
|
+
clack50.log.info(pc53.bold("Anonymous Telemetry"));
|
|
36497
36151
|
console.log(
|
|
36498
|
-
` Wraps collects ${
|
|
36152
|
+
` Wraps collects ${pc53.cyan("anonymous usage data")} to improve the CLI.`
|
|
36499
36153
|
);
|
|
36500
36154
|
console.log(
|
|
36501
|
-
` We ${
|
|
36155
|
+
` We ${pc53.bold("never")} collect: domains, AWS credentials, email content, or PII.`
|
|
36502
36156
|
);
|
|
36503
36157
|
console.log(
|
|
36504
|
-
` We ${
|
|
36158
|
+
` We ${pc53.bold("only")} collect: command names, success/failure, CLI version, OS.`
|
|
36505
36159
|
);
|
|
36506
36160
|
console.log();
|
|
36507
|
-
console.log(` Opt-out anytime: ${
|
|
36508
|
-
console.log(` Or set: ${
|
|
36509
|
-
console.log(` Learn more: ${
|
|
36161
|
+
console.log(` Opt-out anytime: ${pc53.cyan("wraps telemetry disable")}`);
|
|
36162
|
+
console.log(` Or set: ${pc53.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
|
|
36163
|
+
console.log(` Learn more: ${pc53.cyan("https://wraps.dev/docs")}`);
|
|
36510
36164
|
console.log();
|
|
36511
36165
|
telemetry.markNotificationShown();
|
|
36512
36166
|
}
|
|
36513
36167
|
trackCommand("interactive:menu", { success: true, duration_ms: 0 });
|
|
36514
|
-
clack50.intro(
|
|
36168
|
+
clack50.intro(pc53.bold(`WRAPS CLI v${VERSION}`));
|
|
36515
36169
|
console.log(" Deploy AWS infrastructure to your account.\n");
|
|
36516
36170
|
const action = await clack50.select({
|
|
36517
36171
|
message: "What would you like to do?",
|
|
@@ -36648,20 +36302,20 @@ async function run() {
|
|
|
36648
36302
|
const telemetry = getTelemetryClient();
|
|
36649
36303
|
if (telemetry.shouldShowNotification()) {
|
|
36650
36304
|
console.log();
|
|
36651
|
-
clack50.log.info(
|
|
36305
|
+
clack50.log.info(pc53.bold("Anonymous Telemetry"));
|
|
36652
36306
|
console.log(
|
|
36653
|
-
` Wraps collects ${
|
|
36307
|
+
` Wraps collects ${pc53.cyan("anonymous usage data")} to improve the CLI.`
|
|
36654
36308
|
);
|
|
36655
36309
|
console.log(
|
|
36656
|
-
` We ${
|
|
36310
|
+
` We ${pc53.bold("never")} collect: domains, AWS credentials, email content, or PII.`
|
|
36657
36311
|
);
|
|
36658
36312
|
console.log(
|
|
36659
|
-
` We ${
|
|
36313
|
+
` We ${pc53.bold("only")} collect: command names, success/failure, CLI version, OS.`
|
|
36660
36314
|
);
|
|
36661
36315
|
console.log();
|
|
36662
|
-
console.log(` Opt-out anytime: ${
|
|
36663
|
-
console.log(` Or set: ${
|
|
36664
|
-
console.log(` Learn more: ${
|
|
36316
|
+
console.log(` Opt-out anytime: ${pc53.cyan("wraps telemetry disable")}`);
|
|
36317
|
+
console.log(` Or set: ${pc53.cyan("WRAPS_TELEMETRY_DISABLED=1")}`);
|
|
36318
|
+
console.log(` Learn more: ${pc53.cyan("https://wraps.dev/docs")}`);
|
|
36665
36319
|
console.log();
|
|
36666
36320
|
telemetry.markNotificationShown();
|
|
36667
36321
|
}
|
|
@@ -36746,7 +36400,7 @@ async function run() {
|
|
|
36746
36400
|
clack50.log.error("--domain flag is required");
|
|
36747
36401
|
console.log(
|
|
36748
36402
|
`
|
|
36749
|
-
Usage: ${
|
|
36403
|
+
Usage: ${pc53.cyan("wraps email verify --domain yourapp.com")}
|
|
36750
36404
|
`
|
|
36751
36405
|
);
|
|
36752
36406
|
throw new Error("Missing required flag: --domain");
|
|
@@ -36802,7 +36456,7 @@ Usage: ${pc54.cyan("wraps email verify --domain yourapp.com")}
|
|
|
36802
36456
|
);
|
|
36803
36457
|
console.log(
|
|
36804
36458
|
`
|
|
36805
|
-
Available commands: ${
|
|
36459
|
+
Available commands: ${pc53.cyan("init")}, ${pc53.cyan("destroy")}, ${pc53.cyan("status")}, ${pc53.cyan("verify")}, ${pc53.cyan("test")}
|
|
36806
36460
|
`
|
|
36807
36461
|
);
|
|
36808
36462
|
throw new Error(
|
|
@@ -36830,7 +36484,7 @@ Available commands: ${pc54.cyan("init")}, ${pc54.cyan("destroy")}, ${pc54.cyan("
|
|
|
36830
36484
|
clack50.log.error("--domain flag is required");
|
|
36831
36485
|
console.log(
|
|
36832
36486
|
`
|
|
36833
|
-
Usage: ${
|
|
36487
|
+
Usage: ${pc53.cyan("wraps email domains verify --domain yourapp.com")}
|
|
36834
36488
|
`
|
|
36835
36489
|
);
|
|
36836
36490
|
throw new Error("Missing required flag: --domain");
|
|
@@ -36843,7 +36497,7 @@ Usage: ${pc54.cyan("wraps email domains verify --domain yourapp.com")}
|
|
|
36843
36497
|
clack50.log.error("--domain flag is required");
|
|
36844
36498
|
console.log(
|
|
36845
36499
|
`
|
|
36846
|
-
Usage: ${
|
|
36500
|
+
Usage: ${pc53.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
36847
36501
|
`
|
|
36848
36502
|
);
|
|
36849
36503
|
throw new Error("Missing required flag: --domain");
|
|
@@ -36856,7 +36510,7 @@ Usage: ${pc54.cyan("wraps email domains get-dkim --domain yourapp.com")}
|
|
|
36856
36510
|
clack50.log.error("--domain flag is required");
|
|
36857
36511
|
console.log(
|
|
36858
36512
|
`
|
|
36859
|
-
Usage: ${
|
|
36513
|
+
Usage: ${pc53.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
36860
36514
|
`
|
|
36861
36515
|
);
|
|
36862
36516
|
throw new Error("Missing required flag: --domain");
|
|
@@ -36873,7 +36527,7 @@ Usage: ${pc54.cyan("wraps email domains remove --domain yourapp.com --force")}
|
|
|
36873
36527
|
);
|
|
36874
36528
|
console.log(
|
|
36875
36529
|
`
|
|
36876
|
-
Available commands: ${
|
|
36530
|
+
Available commands: ${pc53.cyan("add")}, ${pc53.cyan("list")}, ${pc53.cyan("verify")}, ${pc53.cyan("get-dkim")}, ${pc53.cyan("remove")}
|
|
36877
36531
|
`
|
|
36878
36532
|
);
|
|
36879
36533
|
throw new Error(
|
|
@@ -36918,7 +36572,7 @@ Available commands: ${pc54.cyan("add")}, ${pc54.cyan("list")}, ${pc54.cyan("veri
|
|
|
36918
36572
|
);
|
|
36919
36573
|
console.log(
|
|
36920
36574
|
`
|
|
36921
|
-
Available commands: ${
|
|
36575
|
+
Available commands: ${pc53.cyan("init")}, ${pc53.cyan("push")}, ${pc53.cyan("preview")}
|
|
36922
36576
|
`
|
|
36923
36577
|
);
|
|
36924
36578
|
throw new Error(
|
|
@@ -36956,21 +36610,13 @@ Available commands: ${pc54.cyan("init")}, ${pc54.cyan("push")}, ${pc54.cyan("pre
|
|
|
36956
36610
|
token: flags.token
|
|
36957
36611
|
});
|
|
36958
36612
|
break;
|
|
36959
|
-
case "generate":
|
|
36960
|
-
await workflowsGenerate({
|
|
36961
|
-
template: flags.template,
|
|
36962
|
-
name: flags.name,
|
|
36963
|
-
force: flags.force,
|
|
36964
|
-
json: flags.json
|
|
36965
|
-
});
|
|
36966
|
-
break;
|
|
36967
36613
|
default:
|
|
36968
36614
|
clack50.log.error(
|
|
36969
36615
|
`Unknown workflows command: ${workflowsSubCommand || "(none)"}`
|
|
36970
36616
|
);
|
|
36971
36617
|
console.log(
|
|
36972
36618
|
`
|
|
36973
|
-
Available commands: ${
|
|
36619
|
+
Available commands: ${pc53.cyan("init")}, ${pc53.cyan("validate")}, ${pc53.cyan("push")}
|
|
36974
36620
|
`
|
|
36975
36621
|
);
|
|
36976
36622
|
throw new Error(
|
|
@@ -36991,7 +36637,7 @@ Available commands: ${pc54.cyan("init")}, ${pc54.cyan("validate")}, ${pc54.cyan(
|
|
|
36991
36637
|
clack50.log.error(`Unknown email command: ${subCommand}`);
|
|
36992
36638
|
console.log(
|
|
36993
36639
|
`
|
|
36994
|
-
Run ${
|
|
36640
|
+
Run ${pc53.cyan("wraps --help")} for available commands.
|
|
36995
36641
|
`
|
|
36996
36642
|
);
|
|
36997
36643
|
throw new Error(`Unknown email command: ${subCommand}`);
|
|
@@ -37069,7 +36715,7 @@ Run ${pc54.cyan("wraps --help")} for available commands.
|
|
|
37069
36715
|
clack50.log.error(`Unknown sms command: ${subCommand}`);
|
|
37070
36716
|
console.log(
|
|
37071
36717
|
`
|
|
37072
|
-
Run ${
|
|
36718
|
+
Run ${pc53.cyan("wraps --help")} for available commands.
|
|
37073
36719
|
`
|
|
37074
36720
|
);
|
|
37075
36721
|
throw new Error(`Unknown sms command: ${subCommand}`);
|
|
@@ -37133,7 +36779,7 @@ Run ${pc54.cyan("wraps --help")} for available commands.
|
|
|
37133
36779
|
clack50.log.error(`Unknown cdn command: ${subCommand}`);
|
|
37134
36780
|
console.log(
|
|
37135
36781
|
`
|
|
37136
|
-
Run ${
|
|
36782
|
+
Run ${pc53.cyan("wraps --help")} for available commands.
|
|
37137
36783
|
`
|
|
37138
36784
|
);
|
|
37139
36785
|
throw new Error(`Unknown cdn command: ${subCommand}`);
|
|
@@ -37159,9 +36805,9 @@ Run ${pc54.cyan("wraps --help")} for available commands.
|
|
|
37159
36805
|
`Unknown workflow command: ${subCommand || "(none)"}`
|
|
37160
36806
|
);
|
|
37161
36807
|
console.log(`
|
|
37162
|
-
Available commands: ${
|
|
36808
|
+
Available commands: ${pc53.cyan("init")}
|
|
37163
36809
|
`);
|
|
37164
|
-
console.log(`Run ${
|
|
36810
|
+
console.log(`Run ${pc53.cyan("wraps --help")} for more information.
|
|
37165
36811
|
`);
|
|
37166
36812
|
throw new Error(
|
|
37167
36813
|
`Unknown workflow command: ${subCommand || "(none)"}`
|
|
@@ -37206,11 +36852,11 @@ Available commands: ${pc54.cyan("init")}
|
|
|
37206
36852
|
clack50.log.error(`Unknown platform command: ${subCommand}`);
|
|
37207
36853
|
console.log(
|
|
37208
36854
|
`
|
|
37209
|
-
Available commands: ${
|
|
36855
|
+
Available commands: ${pc53.cyan("connect")}, ${pc53.cyan("update-role")}
|
|
37210
36856
|
`
|
|
37211
36857
|
);
|
|
37212
36858
|
console.log(
|
|
37213
|
-
`Run ${
|
|
36859
|
+
`Run ${pc53.cyan("wraps platform")} for more information.
|
|
37214
36860
|
`
|
|
37215
36861
|
);
|
|
37216
36862
|
throw new Error(`Unknown platform command: ${subCommand}`);
|
|
@@ -37238,7 +36884,7 @@ Available commands: ${pc54.cyan("connect")}, ${pc54.cyan("update-role")}
|
|
|
37238
36884
|
clack50.log.error(`Unknown auth command: ${subCommand || "(none)"}`);
|
|
37239
36885
|
console.log(
|
|
37240
36886
|
`
|
|
37241
|
-
Available commands: ${
|
|
36887
|
+
Available commands: ${pc53.cyan("login")}, ${pc53.cyan("status")}, ${pc53.cyan("logout")}
|
|
37242
36888
|
`
|
|
37243
36889
|
);
|
|
37244
36890
|
throw new Error(`Unknown auth command: ${subCommand || "(none)"}`);
|
|
@@ -37259,10 +36905,10 @@ Available commands: ${pc54.cyan("login")}, ${pc54.cyan("status")}, ${pc54.cyan("
|
|
|
37259
36905
|
clack50.log.error(`Unknown aws command: ${subCommand}`);
|
|
37260
36906
|
console.log(
|
|
37261
36907
|
`
|
|
37262
|
-
Available commands: ${
|
|
36908
|
+
Available commands: ${pc53.cyan("setup")}, ${pc53.cyan("doctor")}
|
|
37263
36909
|
`
|
|
37264
36910
|
);
|
|
37265
|
-
console.log(`Run ${
|
|
36911
|
+
console.log(`Run ${pc53.cyan("wraps --help")} for more information.
|
|
37266
36912
|
`);
|
|
37267
36913
|
throw new Error(`Unknown aws command: ${subCommand}`);
|
|
37268
36914
|
}
|
|
@@ -37338,7 +36984,7 @@ Available commands: ${pc54.cyan("setup")}, ${pc54.cyan("doctor")}
|
|
|
37338
36984
|
clack50.log.error(`Unknown telemetry command: ${subCommand}`);
|
|
37339
36985
|
console.log(
|
|
37340
36986
|
`
|
|
37341
|
-
Available commands: ${
|
|
36987
|
+
Available commands: ${pc53.cyan("enable")}, ${pc53.cyan("disable")}, ${pc53.cyan("status")}
|
|
37342
36988
|
`
|
|
37343
36989
|
);
|
|
37344
36990
|
throw new Error(`Unknown telemetry command: ${subCommand}`);
|
|
@@ -37365,7 +37011,7 @@ Please specify a command for ${primaryCommand} service.
|
|
|
37365
37011
|
clack50.log.error(`Unknown command: ${primaryCommand}`);
|
|
37366
37012
|
console.log(
|
|
37367
37013
|
`
|
|
37368
|
-
Run ${
|
|
37014
|
+
Run ${pc53.cyan("wraps --help")} for available commands.
|
|
37369
37015
|
`
|
|
37370
37016
|
);
|
|
37371
37017
|
throw new Error(`Unknown command: ${primaryCommand}`);
|