@carrierllc/mcp 0.13.41 → 0.13.47
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/{chunk-6OAZJBLA.js → chunk-4XUAUQ3U.js} +67 -7
- package/dist/chunk-4XUAUQ3U.js.map +1 -0
- package/dist/cli.js +55 -9
- package/dist/cli.js.map +1 -1
- package/dist/index.js +66 -15
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/storefront/CLERK.md +23 -0
- package/templates/storefront/src/app/activate/[orderId]/ActivateClient.tsx +29 -22
- package/templates/storefront/src/app/activate/[orderId]/page.tsx +2 -2
- package/templates/storefront/src/app/api/checkout/claim/route.ts +7 -6
- package/templates/storefront/src/app/api/checkout/guest/route.ts +72 -17
- package/templates/storefront/src/app/api/orders/[orderId]/route.ts +2 -2
- package/templates/storefront/src/app/checkout/[templateId]/CheckoutClient.tsx +51 -25
- package/templates/storefront/src/app/checkout/success/CheckoutSuccessClient.tsx +165 -131
- package/templates/storefront/src/app/checkout/success/FocusHeading.tsx +20 -0
- package/templates/storefront/src/app/checkout/success/page.tsx +136 -15
- package/templates/storefront/src/app/dashboard/EsimControls.tsx +20 -24
- package/templates/storefront/src/app/dashboard/page.tsx +43 -23
- package/templates/storefront/src/app/globals.css +44 -5
- package/templates/storefront/src/app/help/page.tsx +2 -2
- package/templates/storefront/src/app/layout.tsx +5 -3
- package/templates/storefront/src/app/page.tsx +27 -7
- package/templates/storefront/src/app/shop/ShopClient.tsx +106 -72
- package/templates/storefront/src/app/shop/page.tsx +7 -2
- package/templates/storefront/src/app/sign-in/[[...sign-in]]/StorefrontSignInClient.tsx +297 -0
- package/templates/storefront/src/app/sign-in/[[...sign-in]]/page.tsx +13 -14
- package/templates/storefront/src/app/sign-up/[[...sign-up]]/StorefrontSignUpClient.tsx +31 -28
- package/templates/storefront/src/app/sign-up/[[...sign-up]]/page.tsx +5 -2
- package/templates/storefront/src/brand.config.ts +16 -0
- package/templates/storefront/src/components/Providers.tsx +20 -1
- package/templates/storefront/src/components/faq/FaqSection.tsx +2 -2
- package/templates/storefront/src/components/footer/StorefrontFooter.tsx +7 -7
- package/templates/storefront/src/components/landing/FinalCTA.tsx +4 -9
- package/templates/storefront/src/components/landing/HeroSection.tsx +4 -7
- package/templates/storefront/src/components/landing/HowItWorks.tsx +1 -1
- package/templates/storefront/src/components/landing/PlanCard.tsx +23 -13
- package/templates/storefront/src/components/landing/TierPlanBoard.tsx +237 -0
- package/templates/storefront/src/components/nav/StorefrontNav.tsx +8 -11
- package/templates/storefront/src/components/shop/CountrySearch.tsx +94 -0
- package/templates/storefront/src/components/theme/BrandStyles.tsx +2 -2
- package/templates/storefront/src/components/theme/ThemeToggle.tsx +1 -1
- package/templates/storefront/src/components/theme/brand-accent-css.ts +21 -0
- package/templates/storefront/src/components/theme/brand-style.ts +88 -0
- package/templates/storefront/src/components/theme/clerk-appearance.ts +18 -2
- package/templates/storefront/src/lib/buyer-auth-copy.ts +83 -0
- package/templates/storefront/src/lib/buyer-error.ts +32 -0
- package/templates/storefront/src/lib/buyer-session.ts +41 -0
- package/templates/storefront/src/lib/catalog-countries.ts +179 -0
- package/templates/storefront/src/lib/checkout-client-error.ts +28 -0
- package/templates/storefront/src/lib/checkout-copy.ts +89 -0
- package/templates/storefront/src/lib/checkout-order-claim.ts +8 -7
- package/templates/storefront/src/lib/checkout-return.ts +18 -0
- package/templates/storefront/src/lib/clerk-instance.ts +89 -0
- package/templates/storefront/src/lib/order-reference.ts +15 -0
- package/templates/storefront/src/lib/request-origin.ts +28 -0
- package/templates/storefront/src/lib/sanitize-auth-redirect.ts +20 -4
- package/templates/storefront/src/lib/tap-target.ts +17 -0
- package/templates/storefront/src/lib/verify-checkout-session.ts +118 -19
- package/templates/storefront/src/middleware.ts +11 -0
- package/templates/storefront/src/vendor/carrier/catalog-guard.ts +9 -5
- package/templates/storefront/src/vendor/carrier/client.ts +22 -4
- package/templates/storefront/src/vendor/carrier/country-offers.ts +106 -0
- package/templates/storefront/src/vendor/carrier/stripe-price.ts +134 -0
- package/templates/storefront/src/vendor/carrier/tiers.ts +161 -0
- package/templates/storefront/src/vendor/carrier/types.ts +22 -0
- package/templates/storefront/src/vendor/geo/index.ts +15 -4
- package/dist/chunk-6OAZJBLA.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
verifyStorefront,
|
|
45
45
|
walletScreen,
|
|
46
46
|
which
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-4XUAUQ3U.js";
|
|
48
48
|
import {
|
|
49
49
|
copyTree,
|
|
50
50
|
exists,
|
|
@@ -194,7 +194,17 @@ function installAuthGuidance() {
|
|
|
194
194
|
import { join as join3 } from "path";
|
|
195
195
|
function preserveClerkFromEnv(existing, fresh) {
|
|
196
196
|
let out = fresh;
|
|
197
|
-
for (const key of [
|
|
197
|
+
for (const key of [
|
|
198
|
+
"NEXT_PUBLIC_CLERK_INSTANCE",
|
|
199
|
+
"NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY",
|
|
200
|
+
"CLERK_SECRET_KEY",
|
|
201
|
+
"NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY_PRODUCTION",
|
|
202
|
+
"CLERK_SECRET_KEY_PRODUCTION",
|
|
203
|
+
"NEXT_PUBLIC_PASSWORD_RESET_ENABLED",
|
|
204
|
+
"NEXT_PUBLIC_CLERK_SIGN_IN_URL",
|
|
205
|
+
"NEXT_PUBLIC_CLERK_SIGN_UP_URL",
|
|
206
|
+
"NEXT_PUBLIC_COUNTRY_CATALOG"
|
|
207
|
+
]) {
|
|
198
208
|
const line = existing.split("\n").find((l) => l.startsWith(`${key}=`));
|
|
199
209
|
if (!line) continue;
|
|
200
210
|
const value = line.slice(key.length + 1);
|
|
@@ -2121,6 +2131,8 @@ function regionLabel(code) {
|
|
|
2121
2131
|
}
|
|
2122
2132
|
|
|
2123
2133
|
// ../../packages/sdk/src/storefront-write.ts
|
|
2134
|
+
var STRIPE_PRICE_ID_RE = /^price_[A-Za-z0-9_]+$/;
|
|
2135
|
+
var STRIPE_PRICE_ID_MAX_LENGTH = 255;
|
|
2124
2136
|
var THEME_FIELDS = [
|
|
2125
2137
|
["accent", "accent"],
|
|
2126
2138
|
["accentDark", "accentDark"],
|
|
@@ -2157,7 +2169,9 @@ function completePlanInput(input, plans) {
|
|
|
2157
2169
|
input.regions,
|
|
2158
2170
|
input.description,
|
|
2159
2171
|
input.active,
|
|
2160
|
-
input.sortOrder
|
|
2172
|
+
input.sortOrder,
|
|
2173
|
+
input.stripePriceId,
|
|
2174
|
+
input.stripePriceMode
|
|
2161
2175
|
].some((value) => value !== void 0);
|
|
2162
2176
|
if (!touched) return input;
|
|
2163
2177
|
const slug2 = input.slug?.trim();
|
|
@@ -2184,6 +2198,8 @@ function storefrontPlanBody(input) {
|
|
|
2184
2198
|
if (input.accountId !== void 0 && (!Number.isSafeInteger(input.accountId) || input.accountId <= 0)) {
|
|
2185
2199
|
return { error: "OCS account id must be a positive integer." };
|
|
2186
2200
|
}
|
|
2201
|
+
const stripe = stripePriceFields(input.stripePriceId, input.stripePriceMode);
|
|
2202
|
+
if (stripe && "error" in stripe) return stripe;
|
|
2187
2203
|
const productId = input.productId?.trim() ?? "";
|
|
2188
2204
|
if (productId !== "") {
|
|
2189
2205
|
const body2 = { product_id: productId };
|
|
@@ -2191,7 +2207,7 @@ function storefrontPlanBody(input) {
|
|
|
2191
2207
|
if (input.priceCents !== void 0) body2.price_cents = input.priceCents;
|
|
2192
2208
|
if (input.active !== void 0) body2.active = input.active;
|
|
2193
2209
|
if (input.sortOrder !== void 0) body2.sort_order = input.sortOrder;
|
|
2194
|
-
return body2;
|
|
2210
|
+
return stripe ? { ...body2, ...stripe } : body2;
|
|
2195
2211
|
}
|
|
2196
2212
|
const touched = [
|
|
2197
2213
|
input.slug,
|
|
@@ -2206,7 +2222,9 @@ function storefrontPlanBody(input) {
|
|
|
2206
2222
|
input.regions,
|
|
2207
2223
|
input.description,
|
|
2208
2224
|
input.active,
|
|
2209
|
-
input.sortOrder
|
|
2225
|
+
input.sortOrder,
|
|
2226
|
+
input.stripePriceId,
|
|
2227
|
+
input.stripePriceMode
|
|
2210
2228
|
].some((value) => value !== void 0);
|
|
2211
2229
|
if (!touched) return null;
|
|
2212
2230
|
if (!input.slug || !input.name || input.priceCents === void 0 || !input.currency || input.templateId === void 0) {
|
|
@@ -2230,7 +2248,27 @@ function storefrontPlanBody(input) {
|
|
|
2230
2248
|
if (input.description !== void 0) body.description = input.description;
|
|
2231
2249
|
if (input.active !== void 0) body.active = input.active;
|
|
2232
2250
|
if (input.sortOrder !== void 0) body.sort_order = input.sortOrder;
|
|
2233
|
-
return body;
|
|
2251
|
+
return stripe ? { ...body, ...stripe } : body;
|
|
2252
|
+
}
|
|
2253
|
+
function stripePriceFields(id, mode) {
|
|
2254
|
+
if (id === void 0 && mode === void 0) return void 0;
|
|
2255
|
+
if (typeof id === "string") {
|
|
2256
|
+
const trimmed = id.trim();
|
|
2257
|
+
if (trimmed.length < 1 || trimmed.length > STRIPE_PRICE_ID_MAX_LENGTH || !STRIPE_PRICE_ID_RE.test(trimmed)) {
|
|
2258
|
+
return { error: "stripe_price_id must look like price_\u2026 and be 1-255 characters." };
|
|
2259
|
+
}
|
|
2260
|
+
id = trimmed;
|
|
2261
|
+
}
|
|
2262
|
+
if (id === null || mode === null) {
|
|
2263
|
+
if (id !== void 0 && id !== null || mode !== void 0 && mode !== null) {
|
|
2264
|
+
return { error: "Sending null clears both stripe_price_id and stripe_price_mode." };
|
|
2265
|
+
}
|
|
2266
|
+
return { stripe_price_id: null, stripe_price_mode: null };
|
|
2267
|
+
}
|
|
2268
|
+
if (id === void 0 || mode === void 0) {
|
|
2269
|
+
return { error: "stripe_price_id and stripe_price_mode must be set together." };
|
|
2270
|
+
}
|
|
2271
|
+
return { stripe_price_id: id, stripe_price_mode: mode };
|
|
2234
2272
|
}
|
|
2235
2273
|
function isStorefrontPlanError(value) {
|
|
2236
2274
|
return value !== null && "error" in value;
|
|
@@ -2327,6 +2365,10 @@ function hostedPublishInputFromFlags(flags) {
|
|
|
2327
2365
|
if (!logo.ok) return { ok: false, text: logo.text };
|
|
2328
2366
|
const sortOrder = parseWholeNumber(flags.planSortOrder, "Plan sort order");
|
|
2329
2367
|
if (!sortOrder.ok) return { ok: false, text: sortOrder.message };
|
|
2368
|
+
const stripeMode = flags.stripePriceMode;
|
|
2369
|
+
if (stripeMode !== void 0 && stripeMode !== "test" && stripeMode !== "live") {
|
|
2370
|
+
return { ok: false, text: "stripe_price_mode must be test or live." };
|
|
2371
|
+
}
|
|
2330
2372
|
return {
|
|
2331
2373
|
ok: true,
|
|
2332
2374
|
input: {
|
|
@@ -2355,7 +2397,9 @@ function hostedPublishInputFromFlags(flags) {
|
|
|
2355
2397
|
regions: countries.value,
|
|
2356
2398
|
description: flags.planText,
|
|
2357
2399
|
planActive: flags.inactive ? false : void 0,
|
|
2358
|
-
planSortOrder: sortOrder.value
|
|
2400
|
+
planSortOrder: sortOrder.value,
|
|
2401
|
+
stripePriceId: flags.stripePriceId,
|
|
2402
|
+
stripePriceMode: stripeMode
|
|
2359
2403
|
}
|
|
2360
2404
|
};
|
|
2361
2405
|
}
|
|
@@ -2416,7 +2460,9 @@ function planInput(input) {
|
|
|
2416
2460
|
regions: input.regions,
|
|
2417
2461
|
description: input.description,
|
|
2418
2462
|
active: input.planActive,
|
|
2419
|
-
sortOrder: input.planSortOrder
|
|
2463
|
+
sortOrder: input.planSortOrder,
|
|
2464
|
+
stripePriceId: input.stripePriceId,
|
|
2465
|
+
stripePriceMode: input.stripePriceMode
|
|
2420
2466
|
};
|
|
2421
2467
|
}
|
|
2422
2468
|
function findStore(body, slug2) {
|
|
@@ -7235,7 +7281,7 @@ site.command("deploy [dir]").description("Build + deploy a storefront to whichev
|
|
|
7235
7281
|
p3.outro("");
|
|
7236
7282
|
}
|
|
7237
7283
|
);
|
|
7238
|
-
site.command("publish").description("Publish a Carrier-hosted storefront. Does not deploy a self-hosted copy.").requiredOption("--slug <slug>", "Shop address, such as acme or Acme Mobile").requiredOption("--name <name>", "Brand name").option("--status <status>", "draft or published", "published").option("--accent <hex>", "Accent color, such as #112233").option("--accent-dark <hex>", "Darker accent").option("--bg <hex>", "Page background").option("--text <hex>", "Body text color").option("--logo <url-or-file>", "https logo address, or a PNG, JPEG, WebP, or GIF under 70 KB").option("--hero <text>", "Shop headline").option("--tagline <text>", "Line under the headline").option("--support-email <email>", "Support address").option("--legal-name <name>", "Legal name in the footer").option("--product <id>", "Connectivity plan id. Copies its template, price, and allowance.").option("--plan <slug>", "Plan slug, such as eu-1gb").option("--plan-name <name>", "Plan name on the shop").option("--price <amount>", "Retail price, such as 9.00").option("--price-cents <cents>", "Retail price in minor units").option("--currency <code>", "Three-letter currency code").option("--template-id <id>", "OCS package template id").option("--ocs-account-id <id>", "Owned OCS account override; omit for automatic resolution").option("--data-gb <gb>", "Data allowance, such as 1 or 1 GB, or the text Unlimited").option("--unlimited", "The only way to sell an unlimited plan. A 0 or missing --data-gb without this is refused.").option("--validity-days <days>", "Validity, such as 7 or 7 days").option("--countries <names>", "Country names or codes, such as France, DE").option("--plan-text <text>", "Buyer-facing sentence. Omit to leave the saved text unchanged.").option("--inactive", "Keep the plan off the shop").option("--plan-sort-order <n>", "Plan display order on the shop (ascending, default 0)").action(async (o) => {
|
|
7284
|
+
site.command("publish").description("Publish a Carrier-hosted storefront. Does not deploy a self-hosted copy.").requiredOption("--slug <slug>", "Shop address, such as acme or Acme Mobile").requiredOption("--name <name>", "Brand name").option("--status <status>", "draft or published", "published").option("--accent <hex>", "Accent color, such as #112233").option("--accent-dark <hex>", "Darker accent").option("--bg <hex>", "Page background").option("--text <hex>", "Body text color").option("--logo <url-or-file>", "https logo address, or a PNG, JPEG, WebP, or GIF under 70 KB").option("--hero <text>", "Shop headline").option("--tagline <text>", "Line under the headline").option("--support-email <email>", "Support address").option("--legal-name <name>", "Legal name in the footer").option("--product <id>", "Connectivity plan id. Copies its template, price, and allowance.").option("--plan <slug>", "Plan slug, such as eu-1gb").option("--plan-name <name>", "Plan name on the shop").option("--price <amount>", "Retail price, such as 9.00").option("--price-cents <cents>", "Retail price in minor units").option("--currency <code>", "Three-letter currency code").option("--template-id <id>", "OCS package template id").option("--ocs-account-id <id>", "Owned OCS account override; omit for automatic resolution").option("--data-gb <gb>", "Data allowance, such as 1 or 1 GB, or the text Unlimited").option("--unlimited", "The only way to sell an unlimited plan. A 0 or missing --data-gb without this is refused.").option("--validity-days <days>", "Validity, such as 7 or 7 days").option("--countries <names>", "Country names or codes, such as France, DE").option("--plan-text <text>", "Buyer-facing sentence. Omit to leave the saved text unchanged.").option("--inactive", "Keep the plan off the shop").option("--plan-sort-order <n>", "Plan display order on the shop (ascending, default 0)").option("--stripe-price-id <id>", "Existing Stripe Price id (price_\u2026, 1-255 characters), stored, not yet charged. Set with --stripe-price-mode.").option("--stripe-price-mode <mode>", "test or live. Set with --stripe-price-id.").action(async (o) => {
|
|
7239
7285
|
header();
|
|
7240
7286
|
const built = hostedPublishInputFromFlags(o);
|
|
7241
7287
|
if (!built.ok) {
|