@wraps.dev/cli 3.7.0 → 3.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js
CHANGED
|
@@ -27936,6 +27936,30 @@ function displayStatus(status2) {
|
|
|
27936
27936
|
`${pc10.bold("Integration:")} ${pc10.cyan(status2.integrationLevel)}`,
|
|
27937
27937
|
`${pc10.bold("Region:")} ${pc10.cyan(status2.region)}`
|
|
27938
27938
|
];
|
|
27939
|
+
if (status2.sending) {
|
|
27940
|
+
const { sandbox, sandboxUncertain } = status2.sending;
|
|
27941
|
+
if (sandboxUncertain) {
|
|
27942
|
+
infoLines.push(
|
|
27943
|
+
`${pc10.bold("Sending:")} ${pc10.yellow("could not determine (SES unreachable)")}`
|
|
27944
|
+
);
|
|
27945
|
+
} else if (sandbox) {
|
|
27946
|
+
infoLines.push(
|
|
27947
|
+
`${pc10.bold("Sending:")} ${pc10.yellow("SANDBOX")} ${pc10.dim("\u2014 you can only send to verified addresses")}`
|
|
27948
|
+
);
|
|
27949
|
+
} else {
|
|
27950
|
+
infoLines.push(`${pc10.bold("Sending:")} ${pc10.green("production")}`);
|
|
27951
|
+
}
|
|
27952
|
+
if (status2.sending.sentLast24Hours !== void 0 || status2.sending.max24HourSend !== void 0 || status2.sending.maxSendRate !== void 0) {
|
|
27953
|
+
infoLines.push(
|
|
27954
|
+
`${pc10.bold("Quota:")} ${pc10.cyan(`${status2.sending.sentLast24Hours ?? 0}/${status2.sending.max24HourSend ?? 0}`)} sent (24h) ${pc10.dim(`\xB7 max rate ${status2.sending.maxSendRate ?? 0}/s`)}`
|
|
27955
|
+
);
|
|
27956
|
+
}
|
|
27957
|
+
}
|
|
27958
|
+
if (status2.cloudFormationStacks && status2.cloudFormationStacks.length > 0) {
|
|
27959
|
+
infoLines.push(
|
|
27960
|
+
`${pc10.bold("CloudFormation stacks:")} ${pc10.cyan(status2.cloudFormationStacks.join(", "))}`
|
|
27961
|
+
);
|
|
27962
|
+
}
|
|
27939
27963
|
if (status2.domains.length > 0) {
|
|
27940
27964
|
const PURPOSE_DISPLAY = {
|
|
27941
27965
|
transactional: "Transactional",
|
|
@@ -37368,6 +37392,11 @@ function buildConsolePolicyDocument(emailConfig, smsConfig) {
|
|
|
37368
37392
|
// SES v2 API for listing/getting email identities (domains)
|
|
37369
37393
|
"ses:ListEmailIdentities",
|
|
37370
37394
|
"ses:GetEmailIdentity",
|
|
37395
|
+
// Write, deliberately. verifyOwnEmailIdentity in
|
|
37396
|
+
// apps/web/src/actions/ses-onboarding.ts creates the operator's own
|
|
37397
|
+
// address as an SES identity so a sandboxed account can complete a
|
|
37398
|
+
// real first send. This is the ONLY identity write the role grants.
|
|
37399
|
+
"ses:CreateEmailIdentity",
|
|
37371
37400
|
// SES v2 API for configuration set scanning (needed by dashboard).
|
|
37372
37401
|
// List is what makes Get reachable — Get takes a name only List can find.
|
|
37373
37402
|
"ses:ListConfigurationSets",
|
|
@@ -37418,6 +37447,18 @@ function buildConsolePolicyDocument(emailConfig, smsConfig) {
|
|
|
37418
37447
|
Resource: "*"
|
|
37419
37448
|
});
|
|
37420
37449
|
}
|
|
37450
|
+
const suppressionList = emailConfig?.suppressionList;
|
|
37451
|
+
if (suppressionList?.enabled !== false) {
|
|
37452
|
+
statements.push({
|
|
37453
|
+
Effect: "Allow",
|
|
37454
|
+
Action: [
|
|
37455
|
+
"ses:ListSuppressedDestinations",
|
|
37456
|
+
"ses:GetSuppressedDestination",
|
|
37457
|
+
"ses:DeleteSuppressedDestination"
|
|
37458
|
+
],
|
|
37459
|
+
Resource: "*"
|
|
37460
|
+
});
|
|
37461
|
+
}
|
|
37421
37462
|
statements.push({
|
|
37422
37463
|
Effect: "Allow",
|
|
37423
37464
|
Action: [
|
|
@@ -51799,6 +51840,7 @@ async function emailStatus(options) {
|
|
|
51799
51840
|
}
|
|
51800
51841
|
}
|
|
51801
51842
|
let stackOutputs = {};
|
|
51843
|
+
let cloudFormationStacks;
|
|
51802
51844
|
try {
|
|
51803
51845
|
await ensurePulumiWorkDir({ accountId: identity.accountId, region });
|
|
51804
51846
|
const stack = await pulumi24.automation.LocalWorkspace.selectStack({
|
|
@@ -51807,17 +51849,32 @@ async function emailStatus(options) {
|
|
|
51807
51849
|
});
|
|
51808
51850
|
stackOutputs = await stack.outputs();
|
|
51809
51851
|
} catch (_error) {
|
|
51810
|
-
|
|
51811
|
-
|
|
51812
|
-
|
|
51813
|
-
|
|
51852
|
+
const cfCheck = await findWrapsCloudFormationStacks(region);
|
|
51853
|
+
if (cfCheck.checked && cfCheck.stacks.length > 0) {
|
|
51854
|
+
cloudFormationStacks = cfCheck.stacks;
|
|
51855
|
+
} else {
|
|
51856
|
+
progress.stop();
|
|
51857
|
+
clack35.log.error("No email infrastructure found");
|
|
51858
|
+
if (!cfCheck.checked) {
|
|
51859
|
+
console.log(
|
|
51860
|
+
pc37.dim(
|
|
51861
|
+
"\nCould not check for CloudFormation stacks (missing cloudformation:DescribeStacks).\n"
|
|
51862
|
+
)
|
|
51863
|
+
);
|
|
51864
|
+
}
|
|
51865
|
+
console.log(
|
|
51866
|
+
`
|
|
51814
51867
|
Run ${pc37.cyan("wraps email init")} to deploy email infrastructure.
|
|
51815
51868
|
`
|
|
51816
|
-
|
|
51817
|
-
|
|
51818
|
-
|
|
51869
|
+
);
|
|
51870
|
+
process.exit(1);
|
|
51871
|
+
return;
|
|
51872
|
+
}
|
|
51819
51873
|
}
|
|
51820
|
-
const domains = await
|
|
51874
|
+
const [domains, sesAccountStatus] = await Promise.all([
|
|
51875
|
+
listSESDomains(region),
|
|
51876
|
+
getSESAccountStatus(region)
|
|
51877
|
+
]);
|
|
51821
51878
|
const { SESv2Client: SESv2Client12, GetEmailIdentityCommand: GetEmailIdentityCommand7 } = await import("@aws-sdk/client-sesv2");
|
|
51822
51879
|
const sesv2Client = new SESv2Client12({ region });
|
|
51823
51880
|
const metadata = await loadConnectionMetadata(identity.accountId, region);
|
|
@@ -51880,7 +51937,16 @@ Run ${pc37.cyan("wraps email init")} to deploy email infrastructure.
|
|
|
51880
51937
|
customTrackingDomain: stackOutputs.customTrackingDomain?.value,
|
|
51881
51938
|
httpsEnabled: stackOutputs.httpsTrackingEnabled?.value,
|
|
51882
51939
|
cloudFrontDomain: stackOutputs.cloudFrontDomain?.value
|
|
51883
|
-
} : void 0
|
|
51940
|
+
} : void 0,
|
|
51941
|
+
sending: {
|
|
51942
|
+
sandbox: sesAccountStatus.isSandbox,
|
|
51943
|
+
sandboxUncertain: sesAccountStatus.sandboxUncertain ?? false,
|
|
51944
|
+
max24HourSend: sesAccountStatus.sendQuota?.max24HourSend,
|
|
51945
|
+
maxSendRate: sesAccountStatus.sendQuota?.maxSendRate,
|
|
51946
|
+
sentLast24Hours: sesAccountStatus.sendQuota?.sentLast24Hours,
|
|
51947
|
+
enforcementStatus: sesAccountStatus.enforcementStatus
|
|
51948
|
+
},
|
|
51949
|
+
cloudFormationStacks
|
|
51884
51950
|
};
|
|
51885
51951
|
if (isJsonMode()) {
|
|
51886
51952
|
jsonSuccess("email.status", statusData);
|
|
@@ -52734,6 +52800,32 @@ import { join as join14 } from "path";
|
|
|
52734
52800
|
|
|
52735
52801
|
// ../template-render/src/mustache-case.ts
|
|
52736
52802
|
init_esm_shims();
|
|
52803
|
+
var HANDLEBARS_BLOCK_HELPERS = /* @__PURE__ */ new Set(["if", "unless", "each", "with"]);
|
|
52804
|
+
function normalizePlainTextMustaches(text14, canonicalVars) {
|
|
52805
|
+
const canonicalByLower = /* @__PURE__ */ new Map();
|
|
52806
|
+
for (const name of canonicalVars) {
|
|
52807
|
+
canonicalByLower.set(name.toLowerCase(), name);
|
|
52808
|
+
}
|
|
52809
|
+
function restoreIdentifier(name) {
|
|
52810
|
+
return canonicalByLower.get(name.toLowerCase()) ?? name;
|
|
52811
|
+
}
|
|
52812
|
+
return text14.replace(
|
|
52813
|
+
/\{\{([#/]?)([A-Z][A-Z0-9_]*(?:\.[A-Z0-9_]+)*)((?:\s+[A-Z0-9_.]+)*)\s*\}\}/g,
|
|
52814
|
+
(match, sigil, name, args) => {
|
|
52815
|
+
const lower = name.toLowerCase();
|
|
52816
|
+
const isHelper = lower === "else" || HANDLEBARS_BLOCK_HELPERS.has(lower);
|
|
52817
|
+
const restoredArgs = args.split(/\s+/).filter(Boolean).map(restoreIdentifier).join(" ");
|
|
52818
|
+
if (isHelper) {
|
|
52819
|
+
const suffix = restoredArgs ? ` ${restoredArgs}` : "";
|
|
52820
|
+
return `{{${sigil}${lower}${suffix}}}`;
|
|
52821
|
+
}
|
|
52822
|
+
if (!args && canonicalByLower.has(lower)) {
|
|
52823
|
+
return `{{${sigil}${canonicalByLower.get(lower)}}}`;
|
|
52824
|
+
}
|
|
52825
|
+
return match;
|
|
52826
|
+
}
|
|
52827
|
+
);
|
|
52828
|
+
}
|
|
52737
52829
|
function toSesVariableName(name) {
|
|
52738
52830
|
if (!name.includes(".")) {
|
|
52739
52831
|
return name;
|
|
@@ -53207,37 +53299,6 @@ import pc40 from "picocolors";
|
|
|
53207
53299
|
|
|
53208
53300
|
// src/utils/email/template-render.ts
|
|
53209
53301
|
init_esm_shims();
|
|
53210
|
-
|
|
53211
|
-
// src/utils/email/template-mustache-case.ts
|
|
53212
|
-
init_esm_shims();
|
|
53213
|
-
var HANDLEBARS_BLOCK_HELPERS = /* @__PURE__ */ new Set(["if", "unless", "each", "with"]);
|
|
53214
|
-
function normalizePlainTextMustaches(text14, canonicalVars) {
|
|
53215
|
-
const canonicalByLower = /* @__PURE__ */ new Map();
|
|
53216
|
-
for (const name of canonicalVars) {
|
|
53217
|
-
canonicalByLower.set(name.toLowerCase(), name);
|
|
53218
|
-
}
|
|
53219
|
-
function restoreIdentifier(name) {
|
|
53220
|
-
return canonicalByLower.get(name.toLowerCase()) ?? name;
|
|
53221
|
-
}
|
|
53222
|
-
return text14.replace(
|
|
53223
|
-
/\{\{([#/]?)([A-Z][A-Z0-9_]*(?:\.[A-Z0-9_]+)*)((?:\s+[A-Z0-9_.]+)*)\s*\}\}/g,
|
|
53224
|
-
(match, sigil, name, args) => {
|
|
53225
|
-
const lower = name.toLowerCase();
|
|
53226
|
-
const isHelper = lower === "else" || HANDLEBARS_BLOCK_HELPERS.has(lower);
|
|
53227
|
-
const restoredArgs = args.split(/\s+/).filter(Boolean).map(restoreIdentifier).join(" ");
|
|
53228
|
-
if (isHelper) {
|
|
53229
|
-
const suffix = restoredArgs ? ` ${restoredArgs}` : "";
|
|
53230
|
-
return `{{${sigil}${lower}${suffix}}}`;
|
|
53231
|
-
}
|
|
53232
|
-
if (!args && canonicalByLower.has(lower)) {
|
|
53233
|
-
return `{{${sigil}${canonicalByLower.get(lower)}}}`;
|
|
53234
|
-
}
|
|
53235
|
-
return match;
|
|
53236
|
-
}
|
|
53237
|
-
);
|
|
53238
|
-
}
|
|
53239
|
-
|
|
53240
|
-
// src/utils/email/template-render.ts
|
|
53241
53302
|
async function renderTemplateWithProxy(Component) {
|
|
53242
53303
|
const accessedProps = /* @__PURE__ */ new Set();
|
|
53243
53304
|
const props = new Proxy({}, {
|