// Price changes of existing (live) products: the owner's call, never confirmed by --yes. Used by play products, // play subscriptions, apple subscriptions and prices import (apple iap never changes the prices of an existing product). // Imported only by those commands, so --allow-price-changes is a flag of theirs alone (tools/gen-flags.ts). import { confirm, type Ctx, declined } from './ctx'; /** The flag that lets a write command change the price of an existing product. `flow run` never adds it and refuses it in steps. */ export const ALLOW_PRICE_CHANGES = 'allow-price-changes'; /** A held price change of one existing product: per region / territory, current -> wanted. */ export interface HeldPrice { id: string; changes: { region: string; from: string; to: string }[] } /** * Price changes of existing (live) products are the owner's call. `--yes` (also the one `flow run --apply --yes` adds * to write steps) confirms creates, first prices and other updates, never these. They go with --allow-price-changes, * or when the owner answers the question in a terminal (no --yes), or as a desktop owner action. Nothing to change, * true. When false the command applies everything else and ends with holdPriceChanges(). */ export async function allowPriceChanges(ctx: Ctx, count: number, question: string): Promise { if (!count || ctx.args.has('allow-price-changes')) return true; const yes = ctx.args.has('yes'); if (process.env.STOREBOUND_SERVE === '1' || (process.stdin.isTTY && !yes)) return confirm(withoutYes(ctx), question); return false; } /** The end of a run that left price changes alone: one line per product, then declined (exit DECLINED_EXIT), so a flow stops there. */ export function holdPriceChanges(held: HeldPrice[]): void { if (!held.length) return; for (const h of held) console.error(`price change on ${h.id} (${priceDiff(h.changes)}) needs the owner: re-run with --${ALLOW_PRICE_CHANGES}`); declined(`${held.length} price change(s) of existing products need the owner (re-run with --${ALLOW_PRICE_CHANGES}); everything else was applied`); } /** "US USD 2.99 -> USD 3.99, DE ..." (at most 4 regions, then "+N more"). Pure. */ export function priceDiff(changes: HeldPrice['changes']): string { const shown = changes.slice(0, 4).map(c => `${c.region} ${c.from} -> ${c.to}`).join(', '); return changes.length > 4 ? `${shown}, +${changes.length - 4} more` : shown; } /** The same context with --yes hidden: for questions --yes must not answer. */ export function withoutYes(ctx: Ctx): Ctx { return { ...ctx, args: { ...ctx.args, has: (n: string) => n !== 'yes' && ctx.args.has(n) } }; }