@revstackhq/cli 0.0.0-dev-20260227103607 → 0.0.0-dev-20260228060138

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.
Files changed (56) hide show
  1. package/.turbo/turbo-build.log +51 -42
  2. package/CHANGELOG.md +11 -0
  3. package/dist/cli.js +622 -49
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/init.d.ts +0 -7
  6. package/dist/commands/init.js +443 -24
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/login.d.ts +0 -6
  9. package/dist/commands/login.js.map +1 -1
  10. package/dist/commands/logout.d.ts +0 -5
  11. package/dist/commands/logout.js.map +1 -1
  12. package/dist/commands/pull.d.ts +0 -7
  13. package/dist/commands/pull.js +120 -11
  14. package/dist/commands/pull.js.map +1 -1
  15. package/dist/commands/push.js +59 -14
  16. package/dist/commands/push.js.map +1 -1
  17. package/dist/commands/templates/ai-agent-platform.d.ts +5 -0
  18. package/dist/commands/templates/ai-agent-platform.js +119 -0
  19. package/dist/commands/templates/ai-agent-platform.js.map +1 -0
  20. package/dist/commands/templates/b2b-saas.js +23 -10
  21. package/dist/commands/templates/b2b-saas.js.map +1 -1
  22. package/dist/commands/templates/developer-tools.d.ts +5 -0
  23. package/dist/commands/templates/developer-tools.js +131 -0
  24. package/dist/commands/templates/developer-tools.js.map +1 -0
  25. package/dist/commands/templates/ecommerce-platform.d.ts +5 -0
  26. package/dist/commands/templates/ecommerce-platform.js +144 -0
  27. package/dist/commands/templates/ecommerce-platform.js.map +1 -0
  28. package/dist/commands/templates/index.js +437 -23
  29. package/dist/commands/templates/index.js.map +1 -1
  30. package/dist/commands/templates/starter.d.ts +1 -0
  31. package/dist/commands/templates/starter.js +13 -8
  32. package/dist/commands/templates/starter.js.map +1 -1
  33. package/dist/commands/templates/usage-based.js +18 -4
  34. package/dist/commands/templates/usage-based.js.map +1 -1
  35. package/dist/utils/auth.d.ts +0 -5
  36. package/dist/utils/auth.js.map +1 -1
  37. package/dist/utils/config-loader.d.ts +0 -6
  38. package/dist/utils/config-loader.js +4 -0
  39. package/dist/utils/config-loader.js.map +1 -1
  40. package/package.json +2 -2
  41. package/src/commands/init.ts +6 -8
  42. package/src/commands/login.ts +0 -6
  43. package/src/commands/logout.ts +0 -5
  44. package/src/commands/pull.ts +148 -60
  45. package/src/commands/push.ts +67 -16
  46. package/src/commands/templates/ai-agent-platform.ts +114 -0
  47. package/src/commands/templates/b2b-saas.ts +23 -10
  48. package/src/commands/templates/developer-tools.ts +126 -0
  49. package/src/commands/templates/ecommerce-platform.ts +139 -0
  50. package/src/commands/templates/index.ts +6 -0
  51. package/src/commands/templates/starter.ts +14 -8
  52. package/src/commands/templates/usage-based.ts +18 -4
  53. package/src/utils/auth.ts +0 -6
  54. package/src/utils/config-loader.ts +6 -7
  55. package/tests/integration/pull.test.ts +6 -0
  56. package/tests/integration/push.test.ts +3 -0
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/commands/login.ts","../src/utils/auth.ts","../src/commands/logout.ts","../src/commands/init.ts","../src/commands/templates/starter.ts","../src/commands/templates/b2b-saas.ts","../src/commands/templates/usage-based.ts","../src/commands/templates/index.ts","../src/commands/push.ts","../src/utils/config-loader.ts","../src/commands/pull.ts"],"sourcesContent":["/**\n * @file cli.ts\n * @description Entry point for the Revstack CLI.\n * Registers all commands and parses process.argv.\n */\n\nimport { Command } from \"commander\";\nimport { createRequire } from \"node:module\";\n\nimport { loginCommand } from \"@/commands/login.js\";\nimport { logoutCommand } from \"@/commands/logout.js\";\nimport { initCommand } from \"@/commands/init.js\";\nimport { pushCommand } from \"@/commands/push.js\";\nimport { pullCommand } from \"@/commands/pull.js\";\n\nconst require = createRequire(import.meta.url);\nconst packageJson = require(\"../package.json\") as { version: string };\n\nconst program = new Command();\n\nprogram\n .name(\"revstack\")\n .description(\"The official CLI for Revstack — Billing as Code\")\n .version(packageJson.version);\n\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\nprogram.addCommand(initCommand);\nprogram.addCommand(pushCommand);\nprogram.addCommand(pullCommand);\n\nprogram.parse(process.argv);\n","/**\n * @file commands/login.ts\n * @description Interactive authentication flow. Prompts the user for their\n * Revstack Secret Key and stores it globally for subsequent CLI commands.\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport prompts from \"prompts\";\nimport { setApiKey } from \"@/utils/auth.js\";\n\nexport const loginCommand = new Command(\"login\")\n .description(\"Authenticate with your Revstack Secret Key\")\n .action(async () => {\n console.log(\n \"\\n\" + chalk.bold(\" Revstack \") + chalk.dim(\"— Authentication\\n\"),\n );\n\n const response = await prompts({\n type: \"password\",\n name: \"secretKey\",\n message: \"Enter your Revstack Secret Key\",\n validate: (value: string) =>\n value.startsWith(\"sk_\") ? true : \"Secret key must start with sk_\",\n });\n\n if (!response.secretKey) {\n console.log(chalk.dim(\"\\n Login cancelled.\\n\"));\n process.exit(0);\n }\n\n setApiKey(response.secretKey);\n\n console.log(\n \"\\n\" +\n chalk.green(\" ✔ Authenticated successfully!\\n\") +\n chalk.dim(\" Credentials saved to ~/.revstack/credentials.json\\n\"),\n );\n });\n","/**\n * @file utils/auth.ts\n * @description Manages global Revstack credentials stored at ~/.revstack/credentials.json.\n * Provides simple get/set helpers for the API key used by all authenticated commands.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nconst CREDENTIALS_DIR = path.join(os.homedir(), \".revstack\");\nconst CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, \"credentials.json\");\n\ninterface Credentials {\n apiKey: string;\n}\n\n/**\n * Persist an API key to the global credentials file.\n * Creates `~/.revstack/` if it doesn't exist.\n */\nexport function setApiKey(key: string): void {\n if (!fs.existsSync(CREDENTIALS_DIR)) {\n fs.mkdirSync(CREDENTIALS_DIR, { recursive: true });\n }\n\n const credentials: Credentials = { apiKey: key };\n fs.writeFileSync(\n CREDENTIALS_FILE,\n JSON.stringify(credentials, null, 2),\n \"utf-8\",\n );\n}\n\n/**\n * Read the stored API key, or return `null` if none is configured.\n */\nexport function getApiKey(): string | null {\n if (!fs.existsSync(CREDENTIALS_FILE)) {\n return null;\n }\n\n try {\n const raw = fs.readFileSync(CREDENTIALS_FILE, \"utf-8\");\n const credentials: Credentials = JSON.parse(raw);\n return credentials.apiKey ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Remove stored credentials. Used by `revstack logout`.\n */\nexport function clearApiKey(): void {\n if (fs.existsSync(CREDENTIALS_FILE)) {\n fs.unlinkSync(CREDENTIALS_FILE);\n }\n}\n","/**\n * @file commands/logout.ts\n * @description Clears stored Revstack credentials.\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { clearApiKey, getApiKey } from \"@/utils/auth.js\";\n\nexport const logoutCommand = new Command(\"logout\")\n .description(\"Clear stored Revstack credentials\")\n .action(() => {\n if (!getApiKey()) {\n console.log(chalk.dim(\"\\n Not currently logged in.\\n\"));\n return;\n }\n\n clearApiKey();\n\n console.log(\n \"\\n\" +\n chalk.green(\" ✔ Successfully logged out.\\n\") +\n chalk.dim(\n \" Credentials removed from ~/.revstack/credentials.json\\n\",\n ),\n );\n });\n","/**\n * @file commands/init.ts\n * @description Scaffolds a new `revstack.config.ts` in the current directory.\n * Generates a starter config with the immutable Default Guest Plan and\n * a sample Pro plan using type-safe helpers from @revstackhq/core.\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { spawnSync } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\nimport ora from \"ora\";\n\nimport { TEMPLATES } from \"./templates/index\";\n\nexport const initCommand = new Command(\"init\")\n .description(\"Scaffold a new revstack.config.ts in the current directory\")\n .option(\n \"-t, --template <name>\",\n \"Choose a starting template (starter, b2b-saas, usage-based)\",\n \"starter\",\n )\n .action(async (options) => {\n const templateName = options.template || \"starter\";\n const template = TEMPLATES[templateName];\n\n if (!template) {\n console.log(\n chalk.red(\n `\\n ✖ Unknown template \"${templateName}\". Available templates: ${Object.keys(TEMPLATES).join(\", \")}\\n`,\n ),\n );\n process.exit(1);\n }\n const cwd = process.cwd();\n const configPath = path.resolve(cwd, \"revstack.config.ts\");\n\n if (fs.existsSync(configPath)) {\n console.log(\n \"\\n\" +\n chalk.yellow(\" ⚠ revstack.config.ts already exists.\\n\") +\n chalk.dim(\" Delete it first if you want to start fresh.\\n\"),\n );\n process.exit(1);\n }\n\n // Step 1: Create revstack directory and config files\n const revstackDir = path.resolve(cwd, \"revstack\");\n if (!fs.existsSync(revstackDir)) {\n fs.mkdirSync(revstackDir, { recursive: true });\n }\n\n fs.writeFileSync(\n path.resolve(revstackDir, \"features.ts\"),\n template.features,\n \"utf-8\",\n );\n fs.writeFileSync(\n path.resolve(revstackDir, \"addons.ts\"),\n template.addons,\n \"utf-8\",\n );\n fs.writeFileSync(\n path.resolve(revstackDir, \"plans.ts\"),\n template.plans,\n \"utf-8\",\n );\n fs.writeFileSync(\n path.resolve(revstackDir, \"index.ts\"),\n template.index,\n \"utf-8\",\n );\n fs.writeFileSync(configPath, template.root, \"utf-8\");\n\n // Step 2: Detect package manager & verify package.json\n let packageManager = \"npm\";\n if (fs.existsSync(path.resolve(cwd, \"pnpm-lock.yaml\"))) {\n packageManager = \"pnpm\";\n } else if (fs.existsSync(path.resolve(cwd, \"yarn.lock\"))) {\n packageManager = \"yarn\";\n } else if (fs.existsSync(path.resolve(cwd, \"package-lock.json\"))) {\n packageManager = \"npm\";\n }\n\n const packageJsonPath = path.resolve(cwd, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) {\n // Create a default package.json if it doesn't exist\n try {\n spawnSync(\"npm\", [\"init\", \"-y\"], { cwd, stdio: \"ignore\", shell: true });\n } catch (err) {\n // Ignore initialization errors; the install command may still work or provide a better error.\n }\n }\n\n // Step 3: Install @revstackhq/core\n const spinner = ora(\"Installing @revstackhq/core...\").start();\n let installFailed = false;\n\n try {\n const cliDir = path.dirname(fileURLToPath(import.meta.url));\n const pkgJsonPath = path.resolve(cliDir, \"../../package.json\");\n let cliVersion = \"dev\";\n try {\n const pkgData = fs.readFileSync(pkgJsonPath, \"utf-8\");\n cliVersion = JSON.parse(pkgData).version;\n } catch (e) {\n // Fallback\n }\n\n const tag = cliVersion.includes(\"dev\") ? `@${cliVersion}` : \"@latest\";\n const pkgName = `@revstackhq/core${tag}`;\n\n const installArgs =\n packageManager === \"yarn\"\n ? [\"add\", pkgName]\n : packageManager === \"pnpm\"\n ? [\"add\", pkgName]\n : [\"install\", pkgName];\n\n let result = spawnSync(packageManager, installArgs, { cwd, shell: true });\n if (result.error || result.status !== 0) {\n if (packageManager === \"pnpm\") {\n result = spawnSync(\"pnpm\", [\"add\", \"-w\", pkgName], {\n cwd,\n shell: true,\n });\n } else if (packageManager === \"yarn\") {\n result = spawnSync(\"yarn\", [\"add\", \"-W\", pkgName], {\n cwd,\n shell: true,\n });\n }\n }\n\n if (result.error || result.status !== 0) {\n throw new Error(\n \"Install failed: \" +\n (result.stderr\n ? result.stderr.toString()\n : result.stdout\n ? result.stdout.toString()\n : \"Unknown error\"),\n );\n }\n spinner.succeed(\"Dependencies installed\");\n } catch (err: any) {\n installFailed = true;\n spinner.fail(\n \"Failed to install @revstackhq/core automatically (\" +\n packageManager +\n \"). Reason: \" +\n err.message,\n );\n }\n\n // Step 4: Final Success Message\n console.log(\n \"\\n\" +\n chalk.green(\" ✔ Created revstack config structure\\n\") +\n \"\\n\" +\n chalk.dim(\" Includes the \") +\n chalk.white(\"Default Guest Plan\") +\n chalk.dim(\" (required by Revstack).\\n\") +\n \"\\n\" +\n chalk.dim(\" Next steps:\\n\") +\n (installFailed\n ? chalk.dim(\" 0. \") +\n chalk.white(\n \"Run \" +\n chalk.bold(packageManager + \" install @revstackhq/core\") +\n \" manually\\n\",\n )\n : \"\") +\n chalk.dim(\" 1. \") +\n chalk.white(\"Edit the config to match your billing model\\n\") +\n chalk.dim(\" 2. \") +\n chalk.white(\"Run \") +\n chalk.bold(\"revstack login\") +\n chalk.white(\" to authenticate\\n\") +\n chalk.dim(\" 3. \") +\n chalk.white(\"Run \") +\n chalk.bold(\"revstack push\") +\n chalk.white(\" to deploy\\n\"),\n );\n });\n","export interface TemplateConfig {\r\n features: string;\r\n addons: string;\r\n plans: string;\r\n index: string;\r\n root: string;\r\n}\r\n\r\nexport const starter: TemplateConfig = {\r\n features: `import { defineFeature } from \"@revstackhq/core\";\r\n\r\nexport const features = {\r\n seats: defineFeature({ name: \"Seats\", type: \"static\", unit_type: \"count\" }),\r\n priority_support: defineFeature({ name: \"Priority Support\", type: \"boolean\", unit_type: \"custom\" }),\r\n};\r\n`,\r\n addons: `import { defineAddon } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const addons = {\r\n extra_seats: defineAddon<typeof features>({\r\n name: \"5 Extra Seats\",\r\n description: \"Add 5 more team members to your workspace.\",\r\n type: \"recurring\",\r\n prices: [\r\n { amount: 1500, currency: \"USD\", billing_interval: \"monthly\" }\r\n ],\r\n features: {\r\n seats: { value_limit: 5, type: \"increment\", is_hard_limit: false },\r\n }\r\n }),\r\n vip_support: defineAddon<typeof features>({\r\n name: \"Priority Support\",\r\n description: \"24/7 Slack channel support.\",\r\n type: \"recurring\",\r\n prices: [\r\n { amount: 9900, currency: \"USD\", billing_interval: \"monthly\" }\r\n ],\r\n features: {\r\n priority_support: { has_access: true },\r\n }\r\n })\r\n};\r\n`,\r\n plans: `import { definePlan } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const plans = {\r\n // DO NOT DELETE: Automatically created default plan for guests.\r\n default: definePlan<typeof features>({\r\n name: \"Default\",\r\n description: \"Automatically created default plan for guests.\",\r\n is_default: true,\r\n is_public: false,\r\n type: \"free\",\r\n features: {},\r\n }),\r\n pro: definePlan<typeof features>({\r\n name: \"Pro\",\r\n description: \"For professional teams.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n available_addons: [\"extra_seats\", \"vip_support\"],\r\n prices: [\r\n { amount: 2900, currency: \"USD\", billing_interval: \"monthly\", trial_period_days: 14 }\r\n ],\r\n features: {\r\n seats: { value_limit: 5, is_hard_limit: true },\r\n },\r\n }),\r\n};\r\n`,\r\n index: `import { defineConfig } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\nimport { addons } from \"./addons\";\r\nimport { plans } from \"./plans\";\r\n\r\nexport default defineConfig({\r\n features,\r\n addons,\r\n plans,\r\n});\r\n`,\r\n root: `import config from \"./revstack\";\r\n\r\nexport default config;\r\n`,\r\n};\r\n","import { TemplateConfig } from \"./starter\";\r\n\r\nexport const b2bSaas: TemplateConfig = {\r\n features: `import { defineFeature } from \"@revstackhq/core\";\r\n\r\nexport const features = {\r\n active_users: defineFeature({ name: \"Active Users\", type: \"static\", unit_type: \"count\" }),\r\n api_access: defineFeature({ name: \"API Access\", type: \"boolean\", unit_type: \"custom\" }),\r\n custom_domain: defineFeature({ name: \"Custom Domain\", type: \"boolean\", unit_type: \"custom\" }),\r\n};\r\n`,\r\n addons: `import { defineAddon } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const addons = {\r\n extra_users: defineAddon<typeof features>({\r\n name: \"10 Extra Users\",\r\n description: \"Add 10 more active users to your workspace.\",\r\n type: \"recurring\",\r\n prices: [\r\n { amount: 5000, currency: \"USD\", billing_interval: \"monthly\" }\r\n ],\r\n features: {\r\n active_users: { value_limit: 10, type: \"increment\", is_hard_limit: true },\r\n }\r\n }),\r\n dedicated_support: defineAddon<typeof features>({\r\n name: \"Dedicated Support\",\r\n description: \"Enterprise SLA with 1-hour response time.\",\r\n type: \"recurring\",\r\n prices: [\r\n { amount: 49900, currency: \"USD\", billing_interval: \"monthly\" }\r\n ],\r\n features: {}\r\n })\r\n};\r\n`,\r\n plans: `import { definePlan } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const plans = {\r\n default: definePlan<typeof features>({\r\n name: \"Default\",\r\n description: \"Automatically created default plan for guests.\",\r\n is_default: true,\r\n is_public: false,\r\n type: \"free\",\r\n features: {},\r\n }),\r\n startup: definePlan<typeof features>({\r\n name: \"Startup\",\r\n description: \"For small teams getting started.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n available_addons: [\"extra_users\"],\r\n prices: [\r\n { amount: 9900, currency: \"USD\", billing_interval: \"monthly\" }\r\n ],\r\n features: {\r\n active_users: { value_limit: 10, is_hard_limit: true },\r\n api_access: { value_bool: false },\r\n custom_domain: { value_bool: false },\r\n },\r\n }),\r\n enterprise: definePlan<typeof features>({\r\n name: \"Enterprise\",\r\n description: \"Advanced features for scale.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n available_addons: [\"extra_users\", \"dedicated_support\"],\r\n prices: [\r\n { amount: 49900, currency: \"USD\", billing_interval: \"monthly\" }\r\n ],\r\n features: {\r\n active_users: { value_limit: 100, is_hard_limit: false },\r\n api_access: { value_bool: true },\r\n custom_domain: { value_bool: true },\r\n },\r\n }),\r\n};\r\n`,\r\n index: `import { defineConfig } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\nimport { addons } from \"./addons\";\r\nimport { plans } from \"./plans\";\r\n\r\nexport default defineConfig({\r\n features,\r\n addons,\r\n plans,\r\n});\r\n`,\r\n root: `import config from \"./revstack\";\r\n\r\nexport default config;\r\n`,\r\n};\r\n","import { TemplateConfig } from \"./starter\";\r\n\r\nexport const usageBased: TemplateConfig = {\r\n features: `import { defineFeature } from \"@revstackhq/core\";\r\n\r\nexport const features = {\r\n api_requests: defineFeature({ name: \"API Requests\", type: \"metered\", unit_type: \"requests\" }),\r\n storage_gb: defineFeature({ name: \"Storage (GB)\", type: \"metered\", unit_type: \"custom\" }),\r\n};\r\n`,\r\n addons: `import { defineAddon } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const addons = {\r\n premium_support: defineAddon<typeof features>({\r\n name: \"Premium Support\",\r\n description: \"24/7 dedicated support.\",\r\n type: \"recurring\",\r\n prices: [\r\n { amount: 20000, currency: \"USD\", billing_interval: \"monthly\" }\r\n ],\r\n features: {}\r\n })\r\n};\r\n`,\r\n plans: `import { definePlan } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const plans = {\r\n default: definePlan<typeof features>({\r\n name: \"Default\",\r\n description: \"Automatically created default plan for guests.\",\r\n is_default: true,\r\n is_public: false,\r\n type: \"free\",\r\n features: {},\r\n }),\r\n pay_as_you_go: definePlan<typeof features>({\r\n name: \"Pay As You Go\",\r\n description: \"Flexible usage-based pricing.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n available_addons: [\"premium_support\"],\r\n prices: [\r\n {\r\n amount: 0,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n overage_configuration: {\r\n api_requests: { overage_amount: 15, overage_unit: 1000 }, // $0.15 per 1k extra requests\r\n storage_gb: { overage_amount: 50, overage_unit: 1 }, // $0.50 per extra GB\r\n }\r\n } // Base platform fee\r\n ],\r\n features: {\r\n api_requests: { value_limit: 10000, is_hard_limit: false, reset_period: \"monthly\" }, // 10k free requests per month\r\n storage_gb: { value_limit: 5, is_hard_limit: false, reset_period: \"never\" }, // 5GB free storage lifetime\r\n },\r\n }),\r\n};\r\n`,\r\n index: `import { defineConfig } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\nimport { addons } from \"./addons\";\r\nimport { plans } from \"./plans\";\r\n\r\nexport default defineConfig({\r\n features,\r\n addons,\r\n plans,\r\n});\r\n`,\r\n root: `import config from \"./revstack\";\r\n\r\nexport default config;\r\n`,\r\n};\r\n","import { starter } from \"./starter\";\r\nimport { b2bSaas } from \"./b2b-saas\";\r\nimport { usageBased } from \"./usage-based\";\r\nimport type { TemplateConfig } from \"./starter\";\r\n\r\nexport const TEMPLATES: Record<string, TemplateConfig> = {\r\n starter: starter,\r\n \"b2b-saas\": b2bSaas,\r\n \"usage-based\": usageBased,\r\n};\r\n\r\nexport type { TemplateConfig };\r\n","/**\n * @file commands/push.ts\n * @description The core deployment command. Loads the local config, sends it\n * to Revstack Cloud for diffing, presents the changes, and (upon confirmation)\n * pushes the config to production.\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport prompts from \"prompts\";\nimport ora from \"ora\";\nimport { getApiKey } from \"@/utils/auth\";\nimport { loadLocalConfig } from \"@/utils/config-loader\";\nimport { validateConfig, RevstackValidationError } from \"@revstackhq/core\";\n\n// ─── Types ───────────────────────────────────────────────────\n\ninterface DiffEntry {\n action: \"added\" | \"removed\" | \"updated\";\n entity: string;\n id: string;\n message: string;\n}\n\ninterface DiffResponse {\n diff: DiffEntry[];\n canPush: boolean;\n blockedReason?: string;\n}\n\n// ─── Helpers ─────────────────────────────────────────────────\n\nconst API_BASE = \"https://app.revstack.dev\";\n\nconst DIFF_ICONS: Record<DiffEntry[\"action\"], string> = {\n added: chalk.green(\" + \"),\n removed: chalk.red(\" − \"),\n updated: chalk.yellow(\" ~ \"),\n};\n\nconst DIFF_COLORS: Record<DiffEntry[\"action\"], (text: string) => string> = {\n added: chalk.green,\n removed: chalk.red,\n updated: chalk.yellow,\n};\n\nfunction printDiff(diff: DiffEntry[]): void {\n if (diff.length === 0) {\n console.log(\n chalk.dim(\"\\n No changes detected. Your config is up to date.\\n\"),\n );\n return;\n }\n\n console.log(chalk.bold(\"\\n Changes:\\n\"));\n\n for (const entry of diff) {\n const icon = DIFF_ICONS[entry.action];\n const color = DIFF_COLORS[entry.action];\n const label = chalk.dim(`[${entry.entity}]`);\n console.log(\n `${icon}${color(entry.id)} ${label} ${chalk.white(entry.message)}`,\n );\n }\n\n console.log();\n}\n\nfunction requireAuth(): string {\n const apiKey = getApiKey();\n\n if (!apiKey) {\n console.error(\n \"\\n\" +\n chalk.red(\" ✖ Not authenticated.\\n\") +\n chalk.dim(\" Run \") +\n chalk.bold(\"revstack login\") +\n chalk.dim(\" first.\\n\"),\n );\n process.exit(1);\n }\n\n return apiKey;\n}\n\n// ─── Command ─────────────────────────────────────────────────\n\nexport const pushCommand = new Command(\"push\")\n .description(\"Push your local billing config to Revstack Cloud\")\n .option(\"-e, --env <environment>\", \"Target environment\", \"test\")\n .action(async (options: { env: string }) => {\n const apiKey = requireAuth();\n const config = await loadLocalConfig(process.cwd());\n\n // ── Step 1: Validate config ────────────────────────────────\n\n const validationSpinner = ora({\n text: \"Validating billing configuration...\",\n prefixText: \" \",\n }).start();\n\n try {\n validateConfig(config as any); // cast to match RevstackConfig expected by validateConfig\n validationSpinner.succeed(\"Configuration validated\");\n } catch (error: any) {\n if (\n error instanceof RevstackValidationError ||\n error?.name === \"RevstackValidationError\"\n ) {\n validationSpinner.fail(\"Configuration invalid\");\n console.error(\n chalk.red(\n \"\\n ✖ The billing configuration contains business logic errors:\\n\",\n ),\n );\n for (const err of error.errors || []) {\n console.error(chalk.red(` • ${err}`));\n }\n console.log();\n process.exit(1);\n }\n\n validationSpinner.fail(\"Validation failed\");\n console.error(\n chalk.red(\n `\\n An unexpected error occurred during validation: ${error?.message || String(error)}\\n`,\n ),\n );\n process.exit(1);\n }\n\n // ── Step 2: Compute diff ──────────────────────────────────\n\n const spinner = ora({\n text: \"Calculating diff...\",\n prefixText: \" \",\n }).start();\n\n let diffResponse: DiffResponse;\n\n try {\n const res = await fetch(`${API_BASE}/api/v1/cli/diff`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ env: options.env, config }),\n });\n\n if (!res.ok) {\n spinner.fail(\"Failed to calculate diff\");\n console.error(\n chalk.red(`\\n API returned ${res.status}: ${res.statusText}\\n`),\n );\n process.exit(1);\n }\n\n diffResponse = (await res.json()) as DiffResponse;\n spinner.succeed(\"Diff calculated\");\n } catch (error: unknown) {\n spinner.fail(\"Failed to reach Revstack Cloud\");\n console.error(chalk.red(`\\n ${(error as Error).message}\\n`));\n process.exit(1);\n }\n\n // ── Step 2: Present diff ──────────────────────────────────\n\n printDiff(diffResponse.diff);\n\n if (diffResponse.diff.length === 0) {\n return;\n }\n\n // ── Step 3: Check if push is allowed ──────────────────────\n\n if (!diffResponse.canPush) {\n console.log(\n chalk.red(\" ✖ Push is blocked.\\n\") +\n chalk.dim(\n ` ${diffResponse.blockedReason ?? \"The server rejected this configuration.\"}\\n`,\n ),\n );\n process.exit(1);\n }\n\n // ── Step 4: Confirm ───────────────────────────────────────\n\n const envLabel =\n options.env === \"production\"\n ? chalk.red.bold(options.env)\n : chalk.cyan.bold(options.env);\n\n const { confirm } = await prompts({\n type: \"confirm\",\n name: \"confirm\",\n message: `Apply these changes to ${envLabel}?`,\n initial: false,\n });\n\n if (!confirm) {\n console.log(chalk.dim(\"\\n Push cancelled.\\n\"));\n return;\n }\n\n // ── Step 5: Push ──────────────────────────────────────────\n\n const pushSpinner = ora({\n text: `Pushing to ${options.env}...`,\n prefixText: \" \",\n }).start();\n\n try {\n const res = await fetch(`${API_BASE}/api/v1/cli/push`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ env: options.env, config }),\n });\n\n if (!res.ok) {\n pushSpinner.fail(\"Push failed\");\n console.error(\n chalk.red(`\\n API returned ${res.status}: ${res.statusText}\\n`),\n );\n process.exit(1);\n }\n\n pushSpinner.succeed(\"Pushed successfully\");\n console.log(\n \"\\n\" +\n chalk.green(\" ✔ Config deployed to \") +\n envLabel +\n \"\\n\" +\n chalk.dim(\" Changes are now live.\\n\"),\n );\n } catch (error: unknown) {\n pushSpinner.fail(\"Push failed\");\n console.error(chalk.red(`\\n ${(error as Error).message}\\n`));\n process.exit(1);\n }\n });\n","/**\n * @file utils/config-loader.ts\n * @description Loads and evaluates the user's `revstack.config.ts` at runtime\n * using jiti (just-in-time TypeScript compilation). Returns a sanitized,\n * JSON-safe representation of the config for network transmission.\n */\n\nimport { createJiti } from \"jiti\";\nimport path from \"node:path\";\nimport chalk from \"chalk\";\n\n/**\n * Load the `revstack.config.ts` from the given directory.\n *\n * @param cwd - The directory to search for `revstack.config.ts`.\n * @returns The parsed and sanitized configuration object.\n */\nexport async function loadLocalConfig(\n cwd: string,\n): Promise<Record<string, unknown>> {\n const configPath = path.resolve(cwd, \"revstack.config.ts\");\n\n try {\n const jiti = createJiti(cwd);\n const module = (await jiti.import(configPath)) as Record<string, unknown>;\n const config = (module.default ?? module) as Record<string, unknown>;\n\n // Sanitize: strip functions, class instances, and non-serializable data.\n // This ensures we only send plain JSON to the Revstack Cloud API.\n return JSON.parse(JSON.stringify(config));\n } catch (error: unknown) {\n const err = error as NodeJS.ErrnoException;\n\n if (\n err.code === \"ERR_MODULE_NOT_FOUND\" ||\n err.code === \"ENOENT\" ||\n err.code === \"MODULE_NOT_FOUND\"\n ) {\n console.error(\n chalk.red(\n \"\\n ✖ Could not find revstack.config.ts in the current directory.\\n\",\n ) +\n chalk.dim(\" Run \") +\n chalk.bold(\"revstack init\") +\n chalk.dim(\" to create one.\\n\"),\n );\n } else {\n console.error(\n chalk.red(\"\\n ✖ Failed to parse revstack.config.ts\\n\") +\n chalk.dim(\" \" + (err.message ?? String(error))) +\n \"\\n\",\n );\n }\n\n process.exit(1);\n }\n}\n","/**\n * @file commands/pull.ts\n * @description Fetches the current billing configuration from Revstack Cloud\n * and writes it back to the local `revstack.config.ts` file, overwriting\n * the existing config after user confirmation.\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport prompts from \"prompts\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { getApiKey } from \"@/utils/auth\";\n\n// ─── Types ───────────────────────────────────────────────────\n\ninterface RemoteFeature {\n name: string;\n type: string;\n unit_type: string;\n description?: string;\n}\n\ninterface RemotePrice {\n amount: number;\n currency: string;\n billing_interval: string;\n trial_period_days?: number;\n}\n\ninterface RemotePlanFeature {\n value_limit?: number;\n value_bool?: boolean;\n value_text?: string;\n is_hard_limit?: boolean;\n reset_period?: string;\n}\n\ninterface RemotePlan {\n name: string;\n description?: string;\n is_default: boolean;\n is_public: boolean;\n type: string;\n prices?: RemotePrice[];\n features: Record<string, RemotePlanFeature>;\n}\n\ninterface RemoteConfig {\n features: Record<string, RemoteFeature>;\n plans: Record<string, RemotePlan>;\n}\n\nfunction serializeObject(\n obj: Record<string, unknown>,\n depth: number = 0,\n): string {\n const entries = Object.entries(obj);\n if (entries.length === 0) return \"{}\";\n\n const pad = \" \".repeat(depth + 1);\n const closePad = \" \".repeat(depth);\n\n const lines = entries\n .map(([key, value]) => {\n if (value === undefined) return null;\n\n const formattedValue =\n typeof value === \"string\"\n ? `\"${value}\"`\n : typeof value === \"number\" || typeof value === \"boolean\"\n ? String(value)\n : Array.isArray(value)\n ? serializeArray(value, depth + 1)\n : typeof value === \"object\" && value !== null\n ? serializeObject(value as Record<string, unknown>, depth + 1)\n : String(value);\n\n return `${pad}${key}: ${formattedValue},`;\n })\n .filter(Boolean);\n\n return `{\\n${lines.join(\"\\n\")}\\n${closePad}}`;\n}\n\nfunction serializeArray(arr: unknown[], depth: number): string {\n if (arr.length === 0) return \"[]\";\n\n const pad = \" \".repeat(depth + 1);\n const closePad = \" \".repeat(depth);\n\n const items = arr.map((item) => {\n if (typeof item === \"object\" && item !== null) {\n return `${pad}${serializeObject(item as Record<string, unknown>, depth + 1)},`;\n }\n return `${pad}${JSON.stringify(item)},`;\n });\n\n return `[\\n${items.join(\"\\n\")}\\n${closePad}]`;\n}\n\nfunction generateFeaturesSource(config: RemoteConfig): string {\n const featureEntries = Object.entries(config.features).map(([slug, f]) => {\n const props: Record<string, unknown> = {\n name: f.name,\n type: f.type,\n unit_type: f.unit_type,\n };\n if (f.description) props.description = f.description;\n\n return ` ${slug}: defineFeature(${serializeObject(props, 2)}),`;\n });\n\n return `import { defineFeature } from \"@revstackhq/core\";\n\nexport const features = {\n${featureEntries.join(\"\\n\")}\n};\n`;\n}\n\nfunction generatePlansSource(config: RemoteConfig): string {\n const planEntries = Object.entries(config.plans).map(([slug, plan]) => {\n const props: Record<string, unknown> = {\n name: plan.name,\n };\n if (plan.description) props.description = plan.description;\n props.is_default = plan.is_default;\n props.is_public = plan.is_public;\n props.type = plan.type;\n\n if (plan.prices && plan.prices.length > 0) {\n props.prices = plan.prices;\n }\n\n props.features = plan.features;\n\n const comment = plan.is_default\n ? ` // DO NOT DELETE: Automatically created default plan for guests.\\n`\n : \"\";\n\n return `${comment} ${slug}: definePlan<typeof features>(${serializeObject(props, 3)}),`;\n });\n\n return `import { definePlan } from \"@revstackhq/core\";\nimport { features } from \"./features\";\n\nexport const plans = {\n${planEntries.join(\"\\n\")}\n};\n`;\n}\n\nfunction generateRootConfigSource(): string {\n return `import { defineConfig } from \"@revstackhq/core\";\nimport { features } from \"./revstack/features\";\nimport { plans } from \"./revstack/plans\";\n\nexport default defineConfig({\n features,\n plans,\n});\n`;\n}\n\n// ─── Helpers ─────────────────────────────────────────────────\n\nconst API_BASE = \"https://app.revstack.dev\";\n\n// ─── Command ─────────────────────────────────────────────────\n\nexport const pullCommand = new Command(\"pull\")\n .description(\n \"Pull the remote billing config and overwrite local revstack.config.ts and revstack/ files\",\n )\n .option(\"-e, --env <environment>\", \"Target environment\", \"test\")\n .action(async (options: { env: string }) => {\n const apiKey = getApiKey();\n\n if (!apiKey) {\n console.error(\n \"\\n\" +\n chalk.red(\" ✖ Not authenticated.\\n\") +\n chalk.dim(\" Run \") +\n chalk.bold(\"revstack login\") +\n chalk.dim(\" first.\\n\"),\n );\n process.exit(1);\n }\n\n // ── 1. Fetch remote config ─────────────────────────────\n const spinner = ora({\n text: \"Fetching remote configuration...\",\n prefixText: \" \",\n }).start();\n\n let remoteConfig: RemoteConfig;\n\n try {\n const res = await fetch(\n `${API_BASE}/api/v1/cli/pull?env=${encodeURIComponent(options.env)}`,\n {\n headers: { Authorization: `Bearer ${apiKey}` },\n },\n );\n\n if (!res.ok) {\n spinner.fail(\"Failed to fetch remote config\");\n console.error(\n chalk.red(`\\n API returned ${res.status}: ${res.statusText}\\n`),\n );\n process.exit(1);\n }\n\n remoteConfig = (await res.json()) as RemoteConfig;\n spinner.succeed(\"Remote config fetched\");\n } catch (error: unknown) {\n spinner.fail(\"Failed to reach Revstack Cloud\");\n console.error(chalk.red(`\\n ${(error as Error).message}\\n`));\n process.exit(1);\n }\n\n // ── 2. Show summary ────────────────────────────────────\n const featureCount = Object.keys(remoteConfig.features).length;\n const planCount = Object.keys(remoteConfig.plans).length;\n\n console.log(\n \"\\n\" +\n chalk.dim(\" Remote state: \") +\n chalk.white(`${featureCount} features, ${planCount} plans`) +\n chalk.dim(` (${options.env})\\n`),\n );\n\n // ── 3. Confirm overwrite ───────────────────────────────\n const cwd = process.cwd();\n const configPath = path.resolve(cwd, \"revstack.config.ts\");\n const revstackDir = path.resolve(cwd, \"revstack\");\n const featuresPath = path.resolve(revstackDir, \"features.ts\");\n const plansPath = path.resolve(revstackDir, \"plans.ts\");\n\n const rootExists = fs.existsSync(configPath);\n const dirExists = fs.existsSync(revstackDir);\n\n if (rootExists || dirExists) {\n const { confirm } = await prompts({\n type: \"confirm\",\n name: \"confirm\",\n message:\n \"This will overwrite your local configuration files (revstack.config.ts and revstack/ data). Are you sure?\",\n initial: false,\n });\n\n if (!confirm) {\n console.log(chalk.dim(\"\\n Pull cancelled.\\n\"));\n return;\n }\n }\n\n // ── 4. Generate and write ──────────────────────────────\n if (!fs.existsSync(revstackDir)) {\n fs.mkdirSync(revstackDir, { recursive: true });\n }\n\n const featuresSource = generateFeaturesSource(remoteConfig);\n const plansSource = generatePlansSource(remoteConfig);\n const rootSource = generateRootConfigSource();\n\n fs.writeFileSync(featuresPath, featuresSource, \"utf-8\");\n fs.writeFileSync(plansPath, plansSource, \"utf-8\");\n fs.writeFileSync(configPath, rootSource, \"utf-8\");\n\n console.log(\n \"\\n\" +\n chalk.green(\" ✔ Local files updated from remote.\\n\") +\n chalk.dim(\" Review the files and run \") +\n chalk.bold(\"revstack push\") +\n chalk.dim(\" to re-deploy.\\n\"),\n );\n });\n"],"mappings":";;;AAMA,SAAS,WAAAA,gBAAe;AACxB,SAAS,qBAAqB;;;ACD9B,SAAS,eAAe;AACxB,OAAO,WAAW;AAClB,OAAO,aAAa;;;ACFpB,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,OAAO,QAAQ;AAEf,IAAM,kBAAkB,KAAK,KAAK,GAAG,QAAQ,GAAG,WAAW;AAC3D,IAAM,mBAAmB,KAAK,KAAK,iBAAiB,kBAAkB;AAU/D,SAAS,UAAU,KAAmB;AAC3C,MAAI,CAAC,GAAG,WAAW,eAAe,GAAG;AACnC,OAAG,UAAU,iBAAiB,EAAE,WAAW,KAAK,CAAC;AAAA,EACnD;AAEA,QAAM,cAA2B,EAAE,QAAQ,IAAI;AAC/C,KAAG;AAAA,IACD;AAAA,IACA,KAAK,UAAU,aAAa,MAAM,CAAC;AAAA,IACnC;AAAA,EACF;AACF;AAKO,SAAS,YAA2B;AACzC,MAAI,CAAC,GAAG,WAAW,gBAAgB,GAAG;AACpC,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,MAAM,GAAG,aAAa,kBAAkB,OAAO;AACrD,UAAM,cAA2B,KAAK,MAAM,GAAG;AAC/C,WAAO,YAAY,UAAU;AAAA,EAC/B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,cAAoB;AAClC,MAAI,GAAG,WAAW,gBAAgB,GAAG;AACnC,OAAG,WAAW,gBAAgB;AAAA,EAChC;AACF;;;AD/CO,IAAM,eAAe,IAAI,QAAQ,OAAO,EAC5C,YAAY,4CAA4C,EACxD,OAAO,YAAY;AAClB,UAAQ;AAAA,IACN,OAAO,MAAM,KAAK,aAAa,IAAI,MAAM,IAAI,yBAAoB;AAAA,EACnE;AAEA,QAAM,WAAW,MAAM,QAAQ;AAAA,IAC7B,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU,CAAC,UACT,MAAM,WAAW,KAAK,IAAI,OAAO;AAAA,EACrC,CAAC;AAED,MAAI,CAAC,SAAS,WAAW;AACvB,YAAQ,IAAI,MAAM,IAAI,wBAAwB,CAAC;AAC/C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,YAAU,SAAS,SAAS;AAE5B,UAAQ;AAAA,IACN,OACE,MAAM,MAAM,wCAAmC,IAC/C,MAAM,IAAI,yDAAyD;AAAA,EACvE;AACF,CAAC;;;AEjCH,SAAS,WAAAC,gBAAe;AACxB,OAAOC,YAAW;AAGX,IAAM,gBAAgB,IAAIC,SAAQ,QAAQ,EAC9C,YAAY,mCAAmC,EAC/C,OAAO,MAAM;AACZ,MAAI,CAAC,UAAU,GAAG;AAChB,YAAQ,IAAIC,OAAM,IAAI,gCAAgC,CAAC;AACvD;AAAA,EACF;AAEA,cAAY;AAEZ,UAAQ;AAAA,IACN,OACEA,OAAM,MAAM,qCAAgC,IAC5CA,OAAM;AAAA,MACJ;AAAA,IACF;AAAA,EACJ;AACF,CAAC;;;ACnBH,SAAS,WAAAC,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB;AAC9B,OAAO,SAAS;;;ACLT,IAAM,UAA0B;AAAA,EACrC,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOV,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4BR,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA6BP,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWP,MAAM;AAAA;AAAA;AAAA;AAIR;;;ACtFO,IAAM,UAA0B;AAAA,EACrC,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQV,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA0BR,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA8CP,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWP,MAAM;AAAA;AAAA;AAAA;AAIR;;;AChGO,IAAM,aAA6B;AAAA,EACxC,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOV,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeR,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqCP,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWP,MAAM;AAAA;AAAA;AAAA;AAIR;;;ACxEO,IAAM,YAA4C;AAAA,EACvD;AAAA,EACA,YAAY;AAAA,EACZ,eAAe;AACjB;;;AJQO,IAAM,cAAc,IAAIC,SAAQ,MAAM,EAC1C,YAAY,4DAA4D,EACxE;AAAA,EACC;AAAA,EACA;AAAA,EACA;AACF,EACC,OAAO,OAAO,YAAY;AACzB,QAAM,eAAe,QAAQ,YAAY;AACzC,QAAM,WAAW,UAAU,YAAY;AAEvC,MAAI,CAAC,UAAU;AACb,YAAQ;AAAA,MACNC,OAAM;AAAA,QACJ;AAAA,6BAA2B,YAAY,2BAA2B,OAAO,KAAK,SAAS,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA,MACrG;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,aAAaC,MAAK,QAAQ,KAAK,oBAAoB;AAEzD,MAAIC,IAAG,WAAW,UAAU,GAAG;AAC7B,YAAQ;AAAA,MACN,OACEF,OAAM,OAAO,+CAA0C,IACvDA,OAAM,IAAI,mDAAmD;AAAA,IACjE;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,cAAcC,MAAK,QAAQ,KAAK,UAAU;AAChD,MAAI,CAACC,IAAG,WAAW,WAAW,GAAG;AAC/B,IAAAA,IAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,EAC/C;AAEA,EAAAA,IAAG;AAAA,IACDD,MAAK,QAAQ,aAAa,aAAa;AAAA,IACvC,SAAS;AAAA,IACT;AAAA,EACF;AACA,EAAAC,IAAG;AAAA,IACDD,MAAK,QAAQ,aAAa,WAAW;AAAA,IACrC,SAAS;AAAA,IACT;AAAA,EACF;AACA,EAAAC,IAAG;AAAA,IACDD,MAAK,QAAQ,aAAa,UAAU;AAAA,IACpC,SAAS;AAAA,IACT;AAAA,EACF;AACA,EAAAC,IAAG;AAAA,IACDD,MAAK,QAAQ,aAAa,UAAU;AAAA,IACpC,SAAS;AAAA,IACT;AAAA,EACF;AACA,EAAAC,IAAG,cAAc,YAAY,SAAS,MAAM,OAAO;AAGnD,MAAI,iBAAiB;AACrB,MAAIA,IAAG,WAAWD,MAAK,QAAQ,KAAK,gBAAgB,CAAC,GAAG;AACtD,qBAAiB;AAAA,EACnB,WAAWC,IAAG,WAAWD,MAAK,QAAQ,KAAK,WAAW,CAAC,GAAG;AACxD,qBAAiB;AAAA,EACnB,WAAWC,IAAG,WAAWD,MAAK,QAAQ,KAAK,mBAAmB,CAAC,GAAG;AAChE,qBAAiB;AAAA,EACnB;AAEA,QAAM,kBAAkBA,MAAK,QAAQ,KAAK,cAAc;AACxD,MAAI,CAACC,IAAG,WAAW,eAAe,GAAG;AAEnC,QAAI;AACF,gBAAU,OAAO,CAAC,QAAQ,IAAI,GAAG,EAAE,KAAK,OAAO,UAAU,OAAO,KAAK,CAAC;AAAA,IACxE,SAAS,KAAK;AAAA,IAEd;AAAA,EACF;AAGA,QAAM,UAAU,IAAI,gCAAgC,EAAE,MAAM;AAC5D,MAAI,gBAAgB;AAEpB,MAAI;AACF,UAAM,SAASD,MAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AAC1D,UAAM,cAAcA,MAAK,QAAQ,QAAQ,oBAAoB;AAC7D,QAAI,aAAa;AACjB,QAAI;AACF,YAAM,UAAUC,IAAG,aAAa,aAAa,OAAO;AACpD,mBAAa,KAAK,MAAM,OAAO,EAAE;AAAA,IACnC,SAAS,GAAG;AAAA,IAEZ;AAEA,UAAM,MAAM,WAAW,SAAS,KAAK,IAAI,IAAI,UAAU,KAAK;AAC5D,UAAM,UAAU,mBAAmB,GAAG;AAEtC,UAAM,cACJ,mBAAmB,SACf,CAAC,OAAO,OAAO,IACf,mBAAmB,SACjB,CAAC,OAAO,OAAO,IACf,CAAC,WAAW,OAAO;AAE3B,QAAI,SAAS,UAAU,gBAAgB,aAAa,EAAE,KAAK,OAAO,KAAK,CAAC;AACxE,QAAI,OAAO,SAAS,OAAO,WAAW,GAAG;AACvC,UAAI,mBAAmB,QAAQ;AAC7B,iBAAS,UAAU,QAAQ,CAAC,OAAO,MAAM,OAAO,GAAG;AAAA,UACjD;AAAA,UACA,OAAO;AAAA,QACT,CAAC;AAAA,MACH,WAAW,mBAAmB,QAAQ;AACpC,iBAAS,UAAU,QAAQ,CAAC,OAAO,MAAM,OAAO,GAAG;AAAA,UACjD;AAAA,UACA,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA,IACF;AAEA,QAAI,OAAO,SAAS,OAAO,WAAW,GAAG;AACvC,YAAM,IAAI;AAAA,QACR,sBACG,OAAO,SACJ,OAAO,OAAO,SAAS,IACvB,OAAO,SACL,OAAO,OAAO,SAAS,IACvB;AAAA,MACV;AAAA,IACF;AACA,YAAQ,QAAQ,wBAAwB;AAAA,EAC1C,SAAS,KAAU;AACjB,oBAAgB;AAChB,YAAQ;AAAA,MACN,uDACE,iBACA,gBACA,IAAI;AAAA,IACR;AAAA,EACF;AAGA,UAAQ;AAAA,IACN,OACEF,OAAM,MAAM,8CAAyC,IACrD,OACAA,OAAM,IAAI,mBAAmB,IAC7BA,OAAM,MAAM,oBAAoB,IAChCA,OAAM,IAAI,4BAA4B,IACtC,OACAA,OAAM,IAAI,mBAAmB,KAC5B,gBACGA,OAAM,IAAI,SAAS,IACnBA,OAAM;AAAA,MACJ,SACEA,OAAM,KAAK,iBAAiB,2BAA2B,IACvD;AAAA,IACJ,IACA,MACJA,OAAM,IAAI,SAAS,IACnBA,OAAM,MAAM,+CAA+C,IAC3DA,OAAM,IAAI,SAAS,IACnBA,OAAM,MAAM,MAAM,IAClBA,OAAM,KAAK,gBAAgB,IAC3BA,OAAM,MAAM,oBAAoB,IAChCA,OAAM,IAAI,SAAS,IACnBA,OAAM,MAAM,MAAM,IAClBA,OAAM,KAAK,eAAe,IAC1BA,OAAM,MAAM,cAAc;AAAA,EAC9B;AACF,CAAC;;;AKnLH,SAAS,WAAAG,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,cAAa;AACpB,OAAOC,UAAS;;;ACHhB,SAAS,kBAAkB;AAC3B,OAAOC,WAAU;AACjB,OAAOC,YAAW;AAQlB,eAAsB,gBACpB,KACkC;AAClC,QAAM,aAAaD,MAAK,QAAQ,KAAK,oBAAoB;AAEzD,MAAI;AACF,UAAM,OAAO,WAAW,GAAG;AAC3B,UAAM,SAAU,MAAM,KAAK,OAAO,UAAU;AAC5C,UAAM,SAAU,OAAO,WAAW;AAIlC,WAAO,KAAK,MAAM,KAAK,UAAU,MAAM,CAAC;AAAA,EAC1C,SAAS,OAAgB;AACvB,UAAM,MAAM;AAEZ,QACE,IAAI,SAAS,0BACb,IAAI,SAAS,YACb,IAAI,SAAS,oBACb;AACA,cAAQ;AAAA,QACNC,OAAM;AAAA,UACJ;AAAA,QACF,IACEA,OAAM,IAAI,UAAU,IACpBA,OAAM,KAAK,eAAe,IAC1BA,OAAM,IAAI,mBAAmB;AAAA,MACjC;AAAA,IACF,OAAO;AACL,cAAQ;AAAA,QACNA,OAAM,IAAI,iDAA4C,IACpDA,OAAM,IAAI,UAAU,IAAI,WAAW,OAAO,KAAK,EAAE,IACjD;AAAA,MACJ;AAAA,IACF;AAEA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AD3CA,SAAS,gBAAgB,+BAA+B;AAmBxD,IAAM,WAAW;AAEjB,IAAM,aAAkD;AAAA,EACtD,OAAOC,OAAM,MAAM,MAAM;AAAA,EACzB,SAASA,OAAM,IAAI,WAAM;AAAA,EACzB,SAASA,OAAM,OAAO,MAAM;AAC9B;AAEA,IAAM,cAAqE;AAAA,EACzE,OAAOA,OAAM;AAAA,EACb,SAASA,OAAM;AAAA,EACf,SAASA,OAAM;AACjB;AAEA,SAAS,UAAU,MAAyB;AAC1C,MAAI,KAAK,WAAW,GAAG;AACrB,YAAQ;AAAA,MACNA,OAAM,IAAI,uDAAuD;AAAA,IACnE;AACA;AAAA,EACF;AAEA,UAAQ,IAAIA,OAAM,KAAK,gBAAgB,CAAC;AAExC,aAAW,SAAS,MAAM;AACxB,UAAM,OAAO,WAAW,MAAM,MAAM;AACpC,UAAM,QAAQ,YAAY,MAAM,MAAM;AACtC,UAAM,QAAQA,OAAM,IAAI,IAAI,MAAM,MAAM,GAAG;AAC3C,YAAQ;AAAA,MACN,GAAG,IAAI,GAAG,MAAM,MAAM,EAAE,CAAC,IAAI,KAAK,IAAIA,OAAM,MAAM,MAAM,OAAO,CAAC;AAAA,IAClE;AAAA,EACF;AAEA,UAAQ,IAAI;AACd;AAEA,SAAS,cAAsB;AAC7B,QAAM,SAAS,UAAU;AAEzB,MAAI,CAAC,QAAQ;AACX,YAAQ;AAAA,MACN,OACEA,OAAM,IAAI,+BAA0B,IACpCA,OAAM,IAAI,UAAU,IACpBA,OAAM,KAAK,gBAAgB,IAC3BA,OAAM,IAAI,WAAW;AAAA,IACzB;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,SAAO;AACT;AAIO,IAAM,cAAc,IAAIC,SAAQ,MAAM,EAC1C,YAAY,kDAAkD,EAC9D,OAAO,2BAA2B,sBAAsB,MAAM,EAC9D,OAAO,OAAO,YAA6B;AAC1C,QAAM,SAAS,YAAY;AAC3B,QAAM,SAAS,MAAM,gBAAgB,QAAQ,IAAI,CAAC;AAIlD,QAAM,oBAAoBC,KAAI;AAAA,IAC5B,MAAM;AAAA,IACN,YAAY;AAAA,EACd,CAAC,EAAE,MAAM;AAET,MAAI;AACF,mBAAe,MAAa;AAC5B,sBAAkB,QAAQ,yBAAyB;AAAA,EACrD,SAAS,OAAY;AACnB,QACE,iBAAiB,2BACjB,OAAO,SAAS,2BAChB;AACA,wBAAkB,KAAK,uBAAuB;AAC9C,cAAQ;AAAA,QACNF,OAAM;AAAA,UACJ;AAAA,QACF;AAAA,MACF;AACA,iBAAW,OAAO,MAAM,UAAU,CAAC,GAAG;AACpC,gBAAQ,MAAMA,OAAM,IAAI,cAAS,GAAG,EAAE,CAAC;AAAA,MACzC;AACA,cAAQ,IAAI;AACZ,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,sBAAkB,KAAK,mBAAmB;AAC1C,YAAQ;AAAA,MACNA,OAAM;AAAA,QACJ;AAAA,oDAAuD,OAAO,WAAW,OAAO,KAAK,CAAC;AAAA;AAAA,MACxF;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAIA,QAAM,UAAUE,KAAI;AAAA,IAClB,MAAM;AAAA,IACN,YAAY;AAAA,EACd,CAAC,EAAE,MAAM;AAET,MAAI;AAEJ,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,QAAQ,oBAAoB;AAAA,MACrD,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,MAAM;AAAA,MACjC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,KAAK,QAAQ,KAAK,OAAO,CAAC;AAAA,IACnD,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,cAAQ,KAAK,0BAA0B;AACvC,cAAQ;AAAA,QACNF,OAAM,IAAI;AAAA,iBAAoB,IAAI,MAAM,KAAK,IAAI,UAAU;AAAA,CAAI;AAAA,MACjE;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,mBAAgB,MAAM,IAAI,KAAK;AAC/B,YAAQ,QAAQ,iBAAiB;AAAA,EACnC,SAAS,OAAgB;AACvB,YAAQ,KAAK,gCAAgC;AAC7C,YAAQ,MAAMA,OAAM,IAAI;AAAA,IAAQ,MAAgB,OAAO;AAAA,CAAI,CAAC;AAC5D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAIA,YAAU,aAAa,IAAI;AAE3B,MAAI,aAAa,KAAK,WAAW,GAAG;AAClC;AAAA,EACF;AAIA,MAAI,CAAC,aAAa,SAAS;AACzB,YAAQ;AAAA,MACNA,OAAM,IAAI,6BAAwB,IAChCA,OAAM;AAAA,QACJ,OAAO,aAAa,iBAAiB,yCAAyC;AAAA;AAAA,MAChF;AAAA,IACJ;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAIA,QAAM,WACJ,QAAQ,QAAQ,eACZA,OAAM,IAAI,KAAK,QAAQ,GAAG,IAC1BA,OAAM,KAAK,KAAK,QAAQ,GAAG;AAEjC,QAAM,EAAE,QAAQ,IAAI,MAAMG,SAAQ;AAAA,IAChC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS,0BAA0B,QAAQ;AAAA,IAC3C,SAAS;AAAA,EACX,CAAC;AAED,MAAI,CAAC,SAAS;AACZ,YAAQ,IAAIH,OAAM,IAAI,uBAAuB,CAAC;AAC9C;AAAA,EACF;AAIA,QAAM,cAAcE,KAAI;AAAA,IACtB,MAAM,cAAc,QAAQ,GAAG;AAAA,IAC/B,YAAY;AAAA,EACd,CAAC,EAAE,MAAM;AAET,MAAI;AACF,UAAM,MAAM,MAAM,MAAM,GAAG,QAAQ,oBAAoB;AAAA,MACrD,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,MAAM;AAAA,MACjC;AAAA,MACA,MAAM,KAAK,UAAU,EAAE,KAAK,QAAQ,KAAK,OAAO,CAAC;AAAA,IACnD,CAAC;AAED,QAAI,CAAC,IAAI,IAAI;AACX,kBAAY,KAAK,aAAa;AAC9B,cAAQ;AAAA,QACNF,OAAM,IAAI;AAAA,iBAAoB,IAAI,MAAM,KAAK,IAAI,UAAU;AAAA,CAAI;AAAA,MACjE;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,gBAAY,QAAQ,qBAAqB;AACzC,YAAQ;AAAA,MACN,OACEA,OAAM,MAAM,8BAAyB,IACrC,WACA,OACAA,OAAM,IAAI,6BAA6B;AAAA,IAC3C;AAAA,EACF,SAAS,OAAgB;AACvB,gBAAY,KAAK,aAAa;AAC9B,YAAQ,MAAMA,OAAM,IAAI;AAAA,IAAQ,MAAgB,OAAO;AAAA,CAAI,CAAC;AAC5D,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;;;AE5OH,SAAS,WAAAI,gBAAe;AACxB,OAAOC,YAAW;AAClB,OAAOC,UAAS;AAChB,OAAOC,cAAa;AACpB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AA0CjB,SAAS,gBACP,KACA,QAAgB,GACR;AACR,QAAM,UAAU,OAAO,QAAQ,GAAG;AAClC,MAAI,QAAQ,WAAW,EAAG,QAAO;AAEjC,QAAM,MAAM,KAAK,OAAO,QAAQ,CAAC;AACjC,QAAM,WAAW,KAAK,OAAO,KAAK;AAElC,QAAM,QAAQ,QACX,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AACrB,QAAI,UAAU,OAAW,QAAO;AAEhC,UAAM,iBACJ,OAAO,UAAU,WACb,IAAI,KAAK,MACT,OAAO,UAAU,YAAY,OAAO,UAAU,YAC5C,OAAO,KAAK,IACZ,MAAM,QAAQ,KAAK,IACjB,eAAe,OAAO,QAAQ,CAAC,IAC/B,OAAO,UAAU,YAAY,UAAU,OACrC,gBAAgB,OAAkC,QAAQ,CAAC,IAC3D,OAAO,KAAK;AAExB,WAAO,GAAG,GAAG,GAAG,GAAG,KAAK,cAAc;AAAA,EACxC,CAAC,EACA,OAAO,OAAO;AAEjB,SAAO;AAAA,EAAM,MAAM,KAAK,IAAI,CAAC;AAAA,EAAK,QAAQ;AAC5C;AAEA,SAAS,eAAe,KAAgB,OAAuB;AAC7D,MAAI,IAAI,WAAW,EAAG,QAAO;AAE7B,QAAM,MAAM,KAAK,OAAO,QAAQ,CAAC;AACjC,QAAM,WAAW,KAAK,OAAO,KAAK;AAElC,QAAM,QAAQ,IAAI,IAAI,CAAC,SAAS;AAC9B,QAAI,OAAO,SAAS,YAAY,SAAS,MAAM;AAC7C,aAAO,GAAG,GAAG,GAAG,gBAAgB,MAAiC,QAAQ,CAAC,CAAC;AAAA,IAC7E;AACA,WAAO,GAAG,GAAG,GAAG,KAAK,UAAU,IAAI,CAAC;AAAA,EACtC,CAAC;AAED,SAAO;AAAA,EAAM,MAAM,KAAK,IAAI,CAAC;AAAA,EAAK,QAAQ;AAC5C;AAEA,SAAS,uBAAuB,QAA8B;AAC5D,QAAM,iBAAiB,OAAO,QAAQ,OAAO,QAAQ,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM;AACxE,UAAM,QAAiC;AAAA,MACrC,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,MACR,WAAW,EAAE;AAAA,IACf;AACA,QAAI,EAAE,YAAa,OAAM,cAAc,EAAE;AAEzC,WAAO,KAAK,IAAI,mBAAmB,gBAAgB,OAAO,CAAC,CAAC;AAAA,EAC9D,CAAC;AAED,SAAO;AAAA;AAAA;AAAA,EAGP,eAAe,KAAK,IAAI,CAAC;AAAA;AAAA;AAG3B;AAEA,SAAS,oBAAoB,QAA8B;AACzD,QAAM,cAAc,OAAO,QAAQ,OAAO,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,IAAI,MAAM;AACrE,UAAM,QAAiC;AAAA,MACrC,MAAM,KAAK;AAAA,IACb;AACA,QAAI,KAAK,YAAa,OAAM,cAAc,KAAK;AAC/C,UAAM,aAAa,KAAK;AACxB,UAAM,YAAY,KAAK;AACvB,UAAM,OAAO,KAAK;AAElB,QAAI,KAAK,UAAU,KAAK,OAAO,SAAS,GAAG;AACzC,YAAM,SAAS,KAAK;AAAA,IACtB;AAEA,UAAM,WAAW,KAAK;AAEtB,UAAM,UAAU,KAAK,aACjB;AAAA,IACA;AAEJ,WAAO,GAAG,OAAO,OAAO,IAAI,iCAAiC,gBAAgB,OAAO,CAAC,CAAC;AAAA,EACxF,CAAC;AAED,SAAO;AAAA;AAAA;AAAA;AAAA,EAIP,YAAY,KAAK,IAAI,CAAC;AAAA;AAAA;AAGxB;AAEA,SAAS,2BAAmC;AAC1C,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAST;AAIA,IAAMC,YAAW;AAIV,IAAM,cAAc,IAAIC,SAAQ,MAAM,EAC1C;AAAA,EACC;AACF,EACC,OAAO,2BAA2B,sBAAsB,MAAM,EAC9D,OAAO,OAAO,YAA6B;AAC1C,QAAM,SAAS,UAAU;AAEzB,MAAI,CAAC,QAAQ;AACX,YAAQ;AAAA,MACN,OACEC,OAAM,IAAI,+BAA0B,IACpCA,OAAM,IAAI,UAAU,IACpBA,OAAM,KAAK,gBAAgB,IAC3BA,OAAM,IAAI,WAAW;AAAA,IACzB;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,UAAUC,KAAI;AAAA,IAClB,MAAM;AAAA,IACN,YAAY;AAAA,EACd,CAAC,EAAE,MAAM;AAET,MAAI;AAEJ,MAAI;AACF,UAAM,MAAM,MAAM;AAAA,MAChB,GAAGH,SAAQ,wBAAwB,mBAAmB,QAAQ,GAAG,CAAC;AAAA,MAClE;AAAA,QACE,SAAS,EAAE,eAAe,UAAU,MAAM,GAAG;AAAA,MAC/C;AAAA,IACF;AAEA,QAAI,CAAC,IAAI,IAAI;AACX,cAAQ,KAAK,+BAA+B;AAC5C,cAAQ;AAAA,QACNE,OAAM,IAAI;AAAA,iBAAoB,IAAI,MAAM,KAAK,IAAI,UAAU;AAAA,CAAI;AAAA,MACjE;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,mBAAgB,MAAM,IAAI,KAAK;AAC/B,YAAQ,QAAQ,uBAAuB;AAAA,EACzC,SAAS,OAAgB;AACvB,YAAQ,KAAK,gCAAgC;AAC7C,YAAQ,MAAMA,OAAM,IAAI;AAAA,IAAQ,MAAgB,OAAO;AAAA,CAAI,CAAC;AAC5D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAGA,QAAM,eAAe,OAAO,KAAK,aAAa,QAAQ,EAAE;AACxD,QAAM,YAAY,OAAO,KAAK,aAAa,KAAK,EAAE;AAElD,UAAQ;AAAA,IACN,OACEA,OAAM,IAAI,kBAAkB,IAC5BA,OAAM,MAAM,GAAG,YAAY,cAAc,SAAS,QAAQ,IAC1DA,OAAM,IAAI,KAAK,QAAQ,GAAG;AAAA,CAAK;AAAA,EACnC;AAGA,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,aAAaE,MAAK,QAAQ,KAAK,oBAAoB;AACzD,QAAM,cAAcA,MAAK,QAAQ,KAAK,UAAU;AAChD,QAAM,eAAeA,MAAK,QAAQ,aAAa,aAAa;AAC5D,QAAM,YAAYA,MAAK,QAAQ,aAAa,UAAU;AAEtD,QAAM,aAAaC,IAAG,WAAW,UAAU;AAC3C,QAAM,YAAYA,IAAG,WAAW,WAAW;AAE3C,MAAI,cAAc,WAAW;AAC3B,UAAM,EAAE,QAAQ,IAAI,MAAMC,SAAQ;AAAA,MAChC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SACE;AAAA,MACF,SAAS;AAAA,IACX,CAAC;AAED,QAAI,CAAC,SAAS;AACZ,cAAQ,IAAIJ,OAAM,IAAI,uBAAuB,CAAC;AAC9C;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAACG,IAAG,WAAW,WAAW,GAAG;AAC/B,IAAAA,IAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,EAC/C;AAEA,QAAM,iBAAiB,uBAAuB,YAAY;AAC1D,QAAM,cAAc,oBAAoB,YAAY;AACpD,QAAM,aAAa,yBAAyB;AAE5C,EAAAA,IAAG,cAAc,cAAc,gBAAgB,OAAO;AACtD,EAAAA,IAAG,cAAc,WAAW,aAAa,OAAO;AAChD,EAAAA,IAAG,cAAc,YAAY,YAAY,OAAO;AAEhD,UAAQ;AAAA,IACN,OACEH,OAAM,MAAM,6CAAwC,IACpDA,OAAM,IAAI,+BAA+B,IACzCA,OAAM,KAAK,eAAe,IAC1BA,OAAM,IAAI,kBAAkB;AAAA,EAChC;AACF,CAAC;;;AXxQH,IAAMK,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,cAAcA,SAAQ,iBAAiB;AAE7C,IAAM,UAAU,IAAIC,SAAQ;AAE5B,QACG,KAAK,UAAU,EACf,YAAY,sDAAiD,EAC7D,QAAQ,YAAY,OAAO;AAE9B,QAAQ,WAAW,YAAY;AAC/B,QAAQ,WAAW,aAAa;AAChC,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,WAAW;AAE9B,QAAQ,MAAM,QAAQ,IAAI;","names":["Command","Command","chalk","Command","chalk","Command","chalk","fs","path","Command","chalk","path","fs","Command","chalk","prompts","ora","path","chalk","chalk","Command","ora","prompts","Command","chalk","ora","prompts","fs","path","API_BASE","Command","chalk","ora","path","fs","prompts","require","Command"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/commands/login.ts","../src/utils/auth.ts","../src/commands/logout.ts","../src/commands/init.ts","../src/commands/templates/starter.ts","../src/commands/templates/b2b-saas.ts","../src/commands/templates/usage-based.ts","../src/commands/templates/ecommerce-platform.ts","../src/commands/templates/developer-tools.ts","../src/commands/templates/ai-agent-platform.ts","../src/commands/templates/index.ts","../src/commands/push.ts","../src/utils/config-loader.ts","../src/commands/pull.ts"],"sourcesContent":["/**\n * @file cli.ts\n * @description Entry point for the Revstack CLI.\n * Registers all commands and parses process.argv.\n */\n\nimport { Command } from \"commander\";\nimport { createRequire } from \"node:module\";\n\nimport { loginCommand } from \"@/commands/login.js\";\nimport { logoutCommand } from \"@/commands/logout.js\";\nimport { initCommand } from \"@/commands/init.js\";\nimport { pushCommand } from \"@/commands/push.js\";\nimport { pullCommand } from \"@/commands/pull.js\";\n\nconst require = createRequire(import.meta.url);\nconst packageJson = require(\"../package.json\") as { version: string };\n\nconst program = new Command();\n\nprogram\n .name(\"revstack\")\n .description(\"The official CLI for Revstack — Billing as Code\")\n .version(packageJson.version);\n\nprogram.addCommand(loginCommand);\nprogram.addCommand(logoutCommand);\nprogram.addCommand(initCommand);\nprogram.addCommand(pushCommand);\nprogram.addCommand(pullCommand);\n\nprogram.parse(process.argv);\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport prompts from \"prompts\";\nimport { setApiKey } from \"@/utils/auth.js\";\n\nexport const loginCommand = new Command(\"login\")\n .description(\"Authenticate with your Revstack Secret Key\")\n .action(async () => {\n console.log(\n \"\\n\" + chalk.bold(\" Revstack \") + chalk.dim(\"— Authentication\\n\"),\n );\n\n const response = await prompts({\n type: \"password\",\n name: \"secretKey\",\n message: \"Enter your Revstack Secret Key\",\n validate: (value: string) =>\n value.startsWith(\"sk_\") ? true : \"Secret key must start with sk_\",\n });\n\n if (!response.secretKey) {\n console.log(chalk.dim(\"\\n Login cancelled.\\n\"));\n process.exit(0);\n }\n\n setApiKey(response.secretKey);\n\n console.log(\n \"\\n\" +\n chalk.green(\" ✔ Authenticated successfully!\\n\") +\n chalk.dim(\" Credentials saved to ~/.revstack/credentials.json\\n\"),\n );\n });\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport os from \"node:os\";\n\nconst CREDENTIALS_DIR = path.join(os.homedir(), \".revstack\");\nconst CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, \"credentials.json\");\n\ninterface Credentials {\n apiKey: string;\n}\n\n/**\n * Persist an API key to the global credentials file.\n * Creates `~/.revstack/` if it doesn't exist.\n */\nexport function setApiKey(key: string): void {\n if (!fs.existsSync(CREDENTIALS_DIR)) {\n fs.mkdirSync(CREDENTIALS_DIR, { recursive: true });\n }\n\n const credentials: Credentials = { apiKey: key };\n fs.writeFileSync(\n CREDENTIALS_FILE,\n JSON.stringify(credentials, null, 2),\n \"utf-8\",\n );\n}\n\n/**\n * Read the stored API key, or return `null` if none is configured.\n */\nexport function getApiKey(): string | null {\n if (!fs.existsSync(CREDENTIALS_FILE)) {\n return null;\n }\n\n try {\n const raw = fs.readFileSync(CREDENTIALS_FILE, \"utf-8\");\n const credentials: Credentials = JSON.parse(raw);\n return credentials.apiKey ?? null;\n } catch {\n return null;\n }\n}\n\n/**\n * Remove stored credentials. Used by `revstack logout`.\n */\nexport function clearApiKey(): void {\n if (fs.existsSync(CREDENTIALS_FILE)) {\n fs.unlinkSync(CREDENTIALS_FILE);\n }\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { clearApiKey, getApiKey } from \"@/utils/auth.js\";\n\nexport const logoutCommand = new Command(\"logout\")\n .description(\"Clear stored Revstack credentials\")\n .action(() => {\n if (!getApiKey()) {\n console.log(chalk.dim(\"\\n Not currently logged in.\\n\"));\n return;\n }\n\n clearApiKey();\n\n console.log(\n \"\\n\" +\n chalk.green(\" ✔ Successfully logged out.\\n\") +\n chalk.dim(\n \" Credentials removed from ~/.revstack/credentials.json\\n\",\n ),\n );\n });\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { spawnSync } from \"node:child_process\";\nimport { fileURLToPath } from \"node:url\";\nimport ora from \"ora\";\n\nimport { TEMPLATES } from \"./templates/index\";\n\nexport const initCommand = new Command(\"init\")\n .description(\"Scaffold a new revstack.config.ts in the current directory\")\n .option(\n \"-t, --template <name>\",\n `Choose a starting template (${Object.keys(TEMPLATES).join(\", \")})`,\n \"starter\",\n )\n .action(async (options) => {\n const templateName = options.template || \"starter\";\n const template = TEMPLATES[templateName];\n\n if (!template) {\n console.log(\n chalk.red(\n `\\n ✖ Unknown template \"${templateName}\". Available templates: ${Object.keys(TEMPLATES).join(\", \")}\\n`,\n ),\n );\n process.exit(1);\n }\n const cwd = process.cwd();\n const configPath = path.resolve(cwd, \"revstack.config.ts\");\n\n if (fs.existsSync(configPath)) {\n console.log(\n \"\\n\" +\n chalk.yellow(\" ⚠ revstack.config.ts already exists.\\n\") +\n chalk.dim(\" Delete it first if you want to start fresh.\\n\"),\n );\n process.exit(1);\n }\n\n // Step 1: Create revstack directory and config files\n const revstackDir = path.resolve(cwd, \"revstack\");\n if (!fs.existsSync(revstackDir)) {\n fs.mkdirSync(revstackDir, { recursive: true });\n }\n\n fs.writeFileSync(\n path.resolve(revstackDir, \"features.ts\"),\n template.features,\n \"utf-8\",\n );\n fs.writeFileSync(\n path.resolve(revstackDir, \"addons.ts\"),\n template.addons,\n \"utf-8\",\n );\n fs.writeFileSync(\n path.resolve(revstackDir, \"coupons.ts\"),\n template.coupons,\n \"utf-8\",\n );\n fs.writeFileSync(\n path.resolve(revstackDir, \"plans.ts\"),\n template.plans,\n \"utf-8\",\n );\n fs.writeFileSync(\n path.resolve(revstackDir, \"index.ts\"),\n template.index,\n \"utf-8\",\n );\n fs.writeFileSync(configPath, template.root, \"utf-8\");\n\n // Step 2: Detect package manager & verify package.json\n let packageManager = \"npm\";\n if (fs.existsSync(path.resolve(cwd, \"pnpm-lock.yaml\"))) {\n packageManager = \"pnpm\";\n } else if (fs.existsSync(path.resolve(cwd, \"yarn.lock\"))) {\n packageManager = \"yarn\";\n } else if (fs.existsSync(path.resolve(cwd, \"package-lock.json\"))) {\n packageManager = \"npm\";\n }\n\n const packageJsonPath = path.resolve(cwd, \"package.json\");\n if (!fs.existsSync(packageJsonPath)) {\n // Create a default package.json if it doesn't exist\n try {\n spawnSync(\"npm\", [\"init\", \"-y\"], { cwd, stdio: \"ignore\", shell: true });\n } catch (err) {\n // Ignore initialization errors; the install command may still work or provide a better error.\n }\n }\n\n // Step 3: Install @revstackhq/core\n const spinner = ora(\"Installing @revstackhq/core...\").start();\n let installFailed = false;\n\n try {\n const cliDir = path.dirname(fileURLToPath(import.meta.url));\n const pkgJsonPath = path.resolve(cliDir, \"../../package.json\");\n let cliVersion = \"dev\";\n try {\n const pkgData = fs.readFileSync(pkgJsonPath, \"utf-8\");\n cliVersion = JSON.parse(pkgData).version;\n } catch (e) {\n // Fallback\n }\n\n const tag = cliVersion.includes(\"dev\") ? `@${cliVersion}` : \"@latest\";\n const pkgName = `@revstackhq/core${tag}`;\n\n const installArgs =\n packageManager === \"yarn\"\n ? [\"add\", pkgName]\n : packageManager === \"pnpm\"\n ? [\"add\", pkgName]\n : [\"install\", pkgName];\n\n let result = spawnSync(packageManager, installArgs, { cwd, shell: true });\n if (result.error || result.status !== 0) {\n if (packageManager === \"pnpm\") {\n result = spawnSync(\"pnpm\", [\"add\", \"-w\", pkgName], {\n cwd,\n shell: true,\n });\n } else if (packageManager === \"yarn\") {\n result = spawnSync(\"yarn\", [\"add\", \"-W\", pkgName], {\n cwd,\n shell: true,\n });\n }\n }\n\n if (result.error || result.status !== 0) {\n throw new Error(\n \"Install failed: \" +\n (result.stderr\n ? result.stderr.toString()\n : result.stdout\n ? result.stdout.toString()\n : \"Unknown error\"),\n );\n }\n spinner.succeed(\"Dependencies installed\");\n } catch (err: any) {\n installFailed = true;\n spinner.fail(\n \"Failed to install @revstackhq/core automatically (\" +\n packageManager +\n \"). Reason: \" +\n err.message,\n );\n }\n\n // Step 4: Final Success Message\n console.log(\n \"\\n\" +\n chalk.green(\" ✔ Created revstack config structure\\n\") +\n \"\\n\" +\n chalk.dim(\" Includes the \") +\n chalk.white(\"Default Guest Plan\") +\n chalk.dim(\" (required by Revstack).\\n\") +\n \"\\n\" +\n chalk.dim(\" Next steps:\\n\") +\n (installFailed\n ? chalk.dim(\" 0. \") +\n chalk.white(\n \"Run \" +\n chalk.bold(packageManager + \" install @revstackhq/core\") +\n \" manually\\n\",\n )\n : \"\") +\n chalk.dim(\" 1. \") +\n chalk.white(\"Edit the config to match your billing model\\n\") +\n chalk.dim(\" 2. \") +\n chalk.white(\"Run \") +\n chalk.bold(\"revstack login\") +\n chalk.white(\" to authenticate\\n\") +\n chalk.dim(\" 3. \") +\n chalk.white(\"Run \") +\n chalk.bold(\"revstack push\") +\n chalk.white(\" to deploy\\n\"),\n );\n });\n","export interface TemplateConfig {\r\n features: string;\r\n addons: string;\r\n plans: string;\r\n coupons: string;\r\n index: string;\r\n root: string;\r\n}\r\n\r\nexport const starter: TemplateConfig = {\r\n features: `import { defineFeature } from \"@revstackhq/core\";\r\n\r\nexport const features = {\r\n seats: defineFeature({ name: \"Seats\", type: \"static\", unit_type: \"count\" }),\r\n priority_support: defineFeature({ name: \"Priority Support\", type: \"boolean\", unit_type: \"custom\" }),\r\n};\r\n`,\r\n addons: `import { defineAddon } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const addons = {\r\n extra_seats: defineAddon<typeof features>({\r\n name: \"5 Extra Seats\",\r\n description: \"Add 5 more team members to your workspace.\",\r\n type: \"recurring\",\r\n amount: 1500,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n features: {\r\n seats: { value_limit: 5, type: \"increment\", is_hard_limit: false },\r\n }\r\n }),\r\n vip_support: defineAddon<typeof features>({\r\n name: \"Priority Support\",\r\n description: \"24/7 Slack channel support.\",\r\n type: \"recurring\",\r\n amount: 9900,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n features: {\r\n priority_support: { has_access: true },\r\n }\r\n })\r\n};\r\n`,\r\n plans: `import { definePlan } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const plans = {\r\n // DO NOT DELETE: Automatically created default plan for guests.\r\n default: definePlan<typeof features>({\r\n name: \"Default\",\r\n description: \"Automatically created default plan for guests.\",\r\n is_default: true,\r\n is_public: false,\r\n type: \"free\",\r\n features: {},\r\n }),\r\n pro: definePlan<typeof features>({\r\n name: \"Pro\",\r\n description: \"For professional teams.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n prices: [\r\n { amount: 2900, currency: \"USD\", billing_interval: \"monthly\", trial_period_days: 14, available_addons: [\"extra_seats\", \"vip_support\"] }\r\n ],\r\n features: {\r\n seats: { value_limit: 5, is_hard_limit: true },\r\n },\r\n }),\r\n};\r\n`,\r\n coupons: `import type { DiscountDef } from \"@revstackhq/core\";\r\n\r\nexport const coupons: DiscountDef[] = [];\r\n`,\r\n index: `import { defineConfig } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\nimport { addons } from \"./addons\";\r\nimport { plans } from \"./plans\";\r\nimport { coupons } from \"./coupons\";\r\n\r\nexport default defineConfig({\r\n features,\r\n addons,\r\n plans,\r\n coupons,\r\n});\r\n`,\r\n root: `import config from \"./revstack\";\r\n\r\nexport default config;\r\n`,\r\n};\r\n","import { TemplateConfig } from \"./starter\";\r\n\r\nexport const b2bSaas: TemplateConfig = {\r\n features: `import { defineFeature } from \"@revstackhq/core\";\r\n\r\nexport const features = {\r\n active_users: defineFeature({ name: \"Active Users\", type: \"static\", unit_type: \"count\" }),\r\n api_access: defineFeature({ name: \"API Access\", type: \"boolean\", unit_type: \"custom\" }),\r\n custom_domain: defineFeature({ name: \"Custom Domain\", type: \"boolean\", unit_type: \"custom\" }),\r\n};\r\n`,\r\n addons: `import { defineAddon } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const addons = {\r\n extra_users: defineAddon<typeof features>({\r\n name: \"10 Extra Users\",\r\n description: \"Add 10 more active users to your workspace.\",\r\n type: \"recurring\",\r\n amount: 5000,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n features: {\r\n active_users: { value_limit: 10, type: \"increment\", is_hard_limit: true },\r\n }\r\n }),\r\n dedicated_support: defineAddon<typeof features>({\r\n name: \"Dedicated Support\",\r\n description: \"Enterprise SLA with 1-hour response time.\",\r\n type: \"recurring\",\r\n amount: 49900,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n features: {}\r\n })\r\n};\r\n`,\r\n coupons: `import type { DiscountDef } from \"@revstackhq/core\";\r\n\r\nexport const coupons: DiscountDef[] = [\r\n {\r\n code: \"ENTERPRISE_B2B\",\r\n name: \"Annual Contract Rebate\",\r\n type: \"amount\",\r\n value: 50000,\r\n duration: \"once\",\r\n applies_to_plans: [\"enterprise\"]\r\n }\r\n];\r\n`,\r\n plans: `import { definePlan } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const plans = {\r\n default: definePlan<typeof features>({\r\n name: \"Default\",\r\n description: \"Automatically created default plan for guests.\",\r\n is_default: true,\r\n is_public: false,\r\n type: \"free\",\r\n features: {},\r\n }),\r\n startup: definePlan<typeof features>({\r\n name: \"Startup\",\r\n description: \"For small teams getting started.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n prices: [\r\n { amount: 9900, currency: \"USD\", billing_interval: \"monthly\", available_addons: [\"extra_users\"] }\r\n ],\r\n features: {\r\n active_users: { value_limit: 10, is_hard_limit: true },\r\n api_access: { value_bool: false },\r\n custom_domain: { value_bool: false },\r\n },\r\n }),\r\n enterprise: definePlan<typeof features>({\r\n name: \"Enterprise\",\r\n description: \"Advanced features for scale.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n prices: [\r\n { amount: 49900, currency: \"USD\", billing_interval: \"monthly\", available_addons: [\"extra_users\", \"dedicated_support\"] }\r\n ],\r\n features: {\r\n active_users: { value_limit: 100, is_hard_limit: false },\r\n api_access: { value_bool: true },\r\n custom_domain: { value_bool: true },\r\n },\r\n }),\r\n};\r\n`,\r\n index: `import { defineConfig } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\nimport { addons } from \"./addons\";\r\nimport { plans } from \"./plans\";\r\nimport { coupons } from \"./coupons\";\r\n\r\nexport default defineConfig({\r\n features,\r\n addons,\r\n plans,\r\n coupons,\r\n});\r\n`,\r\n root: `import config from \"./revstack\";\r\n\r\nexport default config;\r\n`,\r\n};\r\n","import { TemplateConfig } from \"./starter\";\r\n\r\nexport const usageBased: TemplateConfig = {\r\n features: `import { defineFeature } from \"@revstackhq/core\";\r\n\r\nexport const features = {\r\n api_requests: defineFeature({ name: \"API Requests\", type: \"metered\", unit_type: \"requests\" }),\r\n storage_gb: defineFeature({ name: \"Storage (GB)\", type: \"metered\", unit_type: \"custom\" }),\r\n};\r\n`,\r\n addons: `import { defineAddon } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const addons = {\r\n premium_support: defineAddon<typeof features>({\r\n name: \"Premium Support\",\r\n description: \"24/7 dedicated support.\",\r\n type: \"recurring\",\r\n amount: 20000,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n features: {}\r\n })\r\n};\r\n`,\r\n coupons: `import type { DiscountDef } from \"@revstackhq/core\";\r\n\r\nexport const coupons: DiscountDef[] = [\r\n {\r\n code: \"STARTUP_ACCELERATOR\",\r\n name: \"Startup Program Credits\",\r\n type: \"amount\",\r\n value: 500000, // $5,000 credit\r\n duration: \"forever\",\r\n }\r\n];\r\n`,\r\n plans: `import { definePlan } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const plans = {\r\n default: definePlan<typeof features>({\r\n name: \"Default\",\r\n description: \"Automatically created default plan for guests.\",\r\n is_default: true,\r\n is_public: false,\r\n type: \"free\",\r\n features: {},\r\n }),\r\n pay_as_you_go: definePlan<typeof features>({\r\n name: \"Pay As You Go\",\r\n description: \"Flexible usage-based pricing.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n prices: [\r\n {\r\n amount: 0,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n available_addons: [\"premium_support\"],\r\n overage_configuration: {\r\n api_requests: { overage_amount: 15, overage_unit: 1000 }, // $0.15 per 1k extra requests\r\n storage_gb: { overage_amount: 50, overage_unit: 1 }, // $0.50 per extra GB\r\n }\r\n } // Base platform fee\r\n ],\r\n features: {\r\n api_requests: { value_limit: 10000, is_hard_limit: false, reset_period: \"monthly\" }, // 10k free requests per month\r\n storage_gb: { value_limit: 5, is_hard_limit: false, reset_period: \"never\" }, // 5GB free storage lifetime\r\n },\r\n }),\r\n};\r\n`,\r\n index: `import { defineConfig } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\nimport { addons } from \"./addons\";\r\nimport { plans } from \"./plans\";\r\nimport { coupons } from \"./coupons\";\r\n\r\nexport default defineConfig({\r\n features,\r\n addons,\r\n plans,\r\n coupons,\r\n});\r\n`,\r\n root: `import config from \"./revstack\";\r\n\r\nexport default config;\r\n`,\r\n};\r\n","import { TemplateConfig } from \"./starter\";\r\n\r\nexport const ecommercePlatform: TemplateConfig = {\r\n features: `import { defineFeature } from \"@revstackhq/core\";\r\n\r\nexport const features = {\r\n orders: defineFeature({ name: \"Monthly Orders\", type: \"metered\", unit_type: \"count\" }),\r\n storefronts: defineFeature({ name: \"Storefronts\", type: \"static\", unit_type: \"count\" }),\r\n advanced_analytics: defineFeature({ name: \"Advanced Analytics\", type: \"boolean\", unit_type: \"custom\" }),\r\n};\r\n`,\r\n addons: `import { defineAddon } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const addons = {\r\n extra_storefront: defineAddon<typeof features>({\r\n name: \"Additional Storefront\",\r\n description: \"Launch a new brand under the same account.\",\r\n type: \"recurring\",\r\n amount: 5000,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n features: {\r\n storefronts: { value_limit: 1, type: \"increment\", is_hard_limit: true },\r\n }\r\n }),\r\n custom_domain_ssl: defineAddon<typeof features>({\r\n name: \"Custom Domain & SSL\",\r\n description: \"Secure your storefront with a custom domain.\",\r\n type: \"recurring\",\r\n amount: 1500,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n features: {}\r\n })\r\n};\r\n`,\r\n plans: `import { definePlan } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const plans = {\r\n default: definePlan<typeof features>({\r\n name: \"Default Sandbox\",\r\n description: \"Test your store safely before going live.\",\r\n is_default: true,\r\n is_public: false,\r\n type: \"free\",\r\n features: {},\r\n }),\r\n basic: definePlan<typeof features>({\r\n name: \"Basic Commerce\",\r\n description: \"Everything you need to sell online.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n prices: [\r\n {\r\n amount: 2900,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n available_addons: [\"custom_domain_ssl\"],\r\n overage_configuration: {\r\n orders: { overage_amount: 50, overage_unit: 100 } // $0.50 per 100 extra orders\r\n }\r\n }\r\n ],\r\n features: {\r\n orders: { value_limit: 500, is_hard_limit: false, reset_period: \"monthly\" },\r\n storefronts: { value_limit: 1, is_hard_limit: true },\r\n advanced_analytics: { value_bool: false },\r\n },\r\n }),\r\n pro: definePlan<typeof features>({\r\n name: \"Pro Seller\",\r\n description: \"For scaling businesses.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n prices: [\r\n {\r\n amount: 19900,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n available_addons: [\"extra_storefront\", \"custom_domain_ssl\"],\r\n overage_configuration: {\r\n orders: { overage_amount: 30, overage_unit: 100 } // $0.30 per 100 extra orders\r\n }\r\n }\r\n ],\r\n features: {\r\n orders: { value_limit: 5000, is_hard_limit: false, reset_period: \"monthly\" },\r\n storefronts: { value_limit: 2, is_hard_limit: true },\r\n advanced_analytics: { value_bool: true },\r\n },\r\n }),\r\n};\r\n`,\r\n coupons: `import type { DiscountDef } from \"@revstackhq/core\";\r\n\r\nexport const coupons: DiscountDef[] = [\r\n {\r\n code: \"BFCM_PROMO\",\r\n name: \"Black Friday Cyber Monday 20%\",\r\n type: \"percent\",\r\n value: 20,\r\n duration: \"repeating\",\r\n duration_in_months: 6,\r\n expires_at: \"2024-11-29T00:00:00Z\", // Ephemeral timestamp\r\n max_redemptions: 5000\r\n },\r\n {\r\n code: \"FIRST_MONTH_FREE\",\r\n name: \"New Store Launch\",\r\n type: \"percent\",\r\n value: 100,\r\n duration: \"repeating\",\r\n duration_in_months: 1,\r\n applies_to_plans: [\"basic\"]\r\n }\r\n];\r\n`,\r\n index: `import { defineConfig } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\nimport { addons } from \"./addons\";\r\nimport { plans } from \"./plans\";\r\nimport { coupons } from \"./coupons\";\r\n\r\nexport default defineConfig({\r\n features,\r\n addons,\r\n plans,\r\n coupons,\r\n});\r\n`,\r\n root: `import config from \"./revstack\";\r\n\r\nexport default config;\r\n`,\r\n};\r\n","import { TemplateConfig } from \"./starter\";\r\n\r\nexport const developerTools: TemplateConfig = {\r\n features: `import { defineFeature } from \"@revstackhq/core\";\r\n\r\nexport const features = {\r\n bandwidth_gb: defineFeature({ name: \"Bandwidth (GB)\", type: \"metered\", unit_type: \"custom\" }),\r\n compute_hours: defineFeature({ name: \"Compute (GB-Hours)\", type: \"metered\", unit_type: \"custom\" }),\r\n serverless_invokes: defineFeature({ name: \"Serverless Invocations\", type: \"metered\", unit_type: \"count\" }),\r\n sso_auth: defineFeature({ name: \"Enterprise SSO\", type: \"boolean\", unit_type: \"custom\" })\r\n};\r\n`,\r\n addons: `import { defineAddon } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const addons = {\r\n dedicated_ipv4: defineAddon<typeof features>({\r\n name: \"Dedicated IPv4 Address\",\r\n description: \"Assign a static IP to your deployments.\",\r\n type: \"recurring\",\r\n amount: 500,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n features: {}\r\n }),\r\n premium_sla: defineAddon<typeof features>({\r\n name: \"Premium Escalation SLA\",\r\n description: \"Direct engineering support with 30-min response time.\",\r\n type: \"recurring\",\r\n amount: 150000,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n features: {}\r\n })\r\n};\r\n`,\r\n plans: `import { definePlan } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const plans = {\r\n default: definePlan<typeof features>({\r\n name: \"Hobby\",\r\n description: \"For personal or non-commercial projects.\",\r\n is_default: true,\r\n is_public: true,\r\n type: \"free\",\r\n features: {\r\n bandwidth_gb: { value_limit: 100, is_hard_limit: true, reset_period: \"monthly\" },\r\n compute_hours: { value_limit: 100, is_hard_limit: true, reset_period: \"monthly\" },\r\n serverless_invokes: { value_limit: 100000, is_hard_limit: true, reset_period: \"monthly\" },\r\n sso_auth: { value_bool: false }\r\n },\r\n }),\r\n pro: definePlan<typeof features>({\r\n name: \"Pro\",\r\n description: \"For production apps and growing teams.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n prices: [\r\n {\r\n amount: 2000,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n available_addons: [\"dedicated_ipv4\"],\r\n overage_configuration: {\r\n bandwidth_gb: { overage_amount: 40, overage_unit: 100 }, // $0.40 per 100GB extra\r\n compute_hours: { overage_amount: 2, overage_unit: 1 }, // $0.02 per extra GB hr\r\n serverless_invokes: { overage_amount: 50, overage_unit: 1000000 } // $0.50 per 1M invokes\r\n }\r\n }\r\n ],\r\n features: {\r\n bandwidth_gb: { value_limit: 1000, is_hard_limit: false, reset_period: \"monthly\" },\r\n compute_hours: { value_limit: 1000, is_hard_limit: false, reset_period: \"monthly\" },\r\n serverless_invokes: { value_limit: 5000000, is_hard_limit: false, reset_period: \"monthly\" },\r\n sso_auth: { value_bool: false }\r\n },\r\n }),\r\n enterprise: definePlan<typeof features>({\r\n name: \"Enterprise\",\r\n description: \"Custom infrastructure and legal compliance.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"custom\",\r\n prices: [],\r\n features: {\r\n bandwidth_gb: { value_limit: 50000, is_hard_limit: false, reset_period: \"monthly\" },\r\n compute_hours: { value_limit: 10000, is_hard_limit: false, reset_period: \"monthly\" },\r\n serverless_invokes: { value_limit: 100000000, is_hard_limit: false, reset_period: \"monthly\" },\r\n sso_auth: { value_bool: true }\r\n },\r\n }),\r\n};\r\n`,\r\n coupons: `import type { DiscountDef } from \"@revstackhq/core\";\r\n\r\nexport const coupons: DiscountDef[] = [\r\n {\r\n code: \"YCOMBINATOR\",\r\n name: \"YC Startup Accelerator Credit\",\r\n type: \"amount\",\r\n value: 1000000, // $10,000 credit\r\n duration: \"forever\",\r\n applies_to_plans: [\"pro\", \"enterprise\"]\r\n }\r\n];\r\n`,\r\n index: `import { defineConfig } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\nimport { addons } from \"./addons\";\r\nimport { plans } from \"./plans\";\r\nimport { coupons } from \"./coupons\";\r\n\r\nexport default defineConfig({\r\n features,\r\n addons,\r\n plans,\r\n coupons,\r\n});\r\n`,\r\n root: `import config from \"./revstack\";\r\n\r\nexport default config;\r\n`,\r\n};\r\n","import { TemplateConfig } from \"./starter\";\r\n\r\nexport const aiAgentPlatform: TemplateConfig = {\r\n features: `import { defineFeature } from \"@revstackhq/core\";\r\n\r\nexport const features = {\r\n llm_tokens: defineFeature({ name: \"LLM Tokens (Input+Output)\", type: \"metered\", unit_type: \"count\" }),\r\n active_agents: defineFeature({ name: \"Concurrent Agents\", type: \"static\", unit_type: \"count\" }),\r\n vector_storage_gb: defineFeature({ name: \"Vector Database (GB)\", type: \"metered\", unit_type: \"custom\" }),\r\n custom_fine_tuning: defineFeature({ name: \"Model Fine-Tuning\", type: \"boolean\", unit_type: \"custom\" })\r\n};\r\n`,\r\n addons: `import { defineAddon } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const addons = {\r\n extra_vector_storage: defineAddon<typeof features>({\r\n name: \"10GB Vector Storage Block\",\r\n description: \"Retain long-term memory for your AI agents.\",\r\n type: \"recurring\",\r\n amount: 1000,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n features: {\r\n vector_storage_gb: { value_limit: 10, type: \"increment\", is_hard_limit: false }\r\n }\r\n }),\r\n fine_tuning_job: defineAddon<typeof features>({\r\n name: \"Fine-Tuning Job Runner\",\r\n description: \"Pay once to run a distributed model fine-tuning job on your dataset.\",\r\n type: \"one_time\",\r\n amount: 25000,\r\n currency: \"USD\",\r\n features: {\r\n custom_fine_tuning: { has_access: true }\r\n }\r\n })\r\n};\r\n`,\r\n plans: `import { definePlan } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\n\r\nexport const plans = {\r\n default: definePlan<typeof features>({\r\n name: \"Free Preview\",\r\n description: \"Trial sandbox using shared models.\",\r\n is_default: true,\r\n is_public: true,\r\n type: \"free\",\r\n features: {\r\n llm_tokens: { value_limit: 100000, is_hard_limit: true, reset_period: \"monthly\" },\r\n active_agents: { value_limit: 1, is_hard_limit: true },\r\n vector_storage_gb: { value_limit: 0, is_hard_limit: true, reset_period: \"never\" },\r\n custom_fine_tuning: { value_bool: false }\r\n },\r\n }),\r\n builder: definePlan<typeof features>({\r\n name: \"AI Builder\",\r\n description: \"High concurrency and dedicated model endpoints.\",\r\n is_default: false,\r\n is_public: true,\r\n type: \"paid\",\r\n prices: [\r\n {\r\n amount: 4900,\r\n currency: \"USD\",\r\n billing_interval: \"monthly\",\r\n available_addons: [\"extra_vector_storage\", \"fine_tuning_job\"],\r\n overage_configuration: {\r\n llm_tokens: { overage_amount: 15, overage_unit: 1000000 } // $0.15 per 1M tokens\r\n }\r\n }\r\n ],\r\n features: {\r\n llm_tokens: { value_limit: 10000000, is_hard_limit: false, reset_period: \"monthly\" }, // 10M free tokens included\r\n active_agents: { value_limit: 10, is_hard_limit: true },\r\n vector_storage_gb: { value_limit: 5, is_hard_limit: true, reset_period: \"never\" }, // Hard limit until they buy the addon\r\n custom_fine_tuning: { value_bool: false } // Only unlocked via the one-off addon\r\n },\r\n }),\r\n};\r\n`,\r\n coupons: `import type { DiscountDef } from \"@revstackhq/core\";\r\n\r\nexport const coupons: DiscountDef[] = [\r\n {\r\n code: \"BETA_TESTER\",\r\n name: \"Early Beta Access Discount\",\r\n type: \"percent\",\r\n value: 50,\r\n duration: \"repeating\",\r\n duration_in_months: 12,\r\n max_redemptions: 100\r\n }\r\n];\r\n`,\r\n index: `import { defineConfig } from \"@revstackhq/core\";\r\nimport { features } from \"./features\";\r\nimport { addons } from \"./addons\";\r\nimport { plans } from \"./plans\";\r\nimport { coupons } from \"./coupons\";\r\n\r\nexport default defineConfig({\r\n features,\r\n addons,\r\n plans,\r\n coupons,\r\n});\r\n`,\r\n root: `import config from \"./revstack\";\r\n\r\nexport default config;\r\n`,\r\n};\r\n","import { starter } from \"./starter\";\r\nimport { b2bSaas } from \"./b2b-saas\";\r\nimport { usageBased } from \"./usage-based\";\r\nimport { ecommercePlatform } from \"./ecommerce-platform\";\r\nimport { developerTools } from \"./developer-tools\";\r\nimport { aiAgentPlatform } from \"./ai-agent-platform\";\r\nimport type { TemplateConfig } from \"./starter\";\r\n\r\nexport const TEMPLATES: Record<string, TemplateConfig> = {\r\n starter: starter,\r\n \"b2b-saas\": b2bSaas,\r\n \"usage-based\": usageBased,\r\n \"ecommerce-platform\": ecommercePlatform,\r\n \"developer-tools\": developerTools,\r\n \"ai-agent-platform\": aiAgentPlatform,\r\n};\r\n\r\nexport type { TemplateConfig };\r\n","/**\n * @file commands/push.ts\n * @description The core deployment command. Loads the local config, sends it\n * to Revstack Cloud for diffing, presents the changes, and (upon confirmation)\n * pushes the config to production.\n */\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport prompts from \"prompts\";\nimport ora from \"ora\";\nimport { getApiKey } from \"@/utils/auth\";\nimport { loadLocalConfig } from \"@/utils/config-loader\";\nimport {\n validateConfig,\n RevstackValidationError,\n RevstackConfigSchema,\n} from \"@revstackhq/core\";\n\n// ─── Types ───────────────────────────────────────────────────\n\ninterface DiffEntry {\n action: \"added\" | \"removed\" | \"updated\";\n entity: string;\n id: string;\n message: string;\n}\n\ninterface DiffResponse {\n diff: DiffEntry[];\n canPush: boolean;\n blockedReason?: string;\n}\n\n// ─── Helpers ─────────────────────────────────────────────────\n\nconst API_BASE = \"https://app.revstack.dev\";\n\nconst DIFF_ICONS: Record<DiffEntry[\"action\"], string> = {\n added: chalk.green(\" + \"),\n removed: chalk.red(\" − \"),\n updated: chalk.yellow(\" ~ \"),\n};\n\nconst DIFF_COLORS: Record<DiffEntry[\"action\"], (text: string) => string> = {\n added: chalk.green,\n removed: chalk.red,\n updated: chalk.yellow,\n};\n\nfunction printDiff(diff: DiffEntry[], env: string): void {\n if (diff.length === 0) {\n console.log(\n chalk.dim(\"\\n No changes detected. Your config is up to date.\\n\"),\n );\n return;\n }\n\n if (env === \"production\") {\n console.log(\n chalk.bgRed.white.bold(\"\\n ⚠️ YOU ARE PUSHING TO PRODUCTION ⚠️ \\n\"),\n );\n } else {\n console.log(chalk.bold(\"\\n Changes:\\n\"));\n }\n\n const groups: Record<string, DiffEntry[]> = {};\n for (const entry of diff) {\n if (!groups[entry.entity]) groups[entry.entity] = [];\n groups[entry.entity].push(entry);\n }\n\n let added = 0;\n let updated = 0;\n let removed = 0;\n\n for (const [entityName, entries] of Object.entries(groups)) {\n console.log(chalk.dim(` ${entityName}s`));\n for (const entry of entries) {\n if (entry.action === \"added\") added++;\n if (entry.action === \"updated\") updated++;\n if (entry.action === \"removed\") removed++;\n\n const icon = DIFF_ICONS[entry.action];\n const color = DIFF_COLORS[entry.action];\n console.log(`${icon}${color(entry.id)} ${chalk.white(entry.message)}`);\n }\n console.log();\n }\n\n console.log(\n chalk.bold(\n ` Summary: ${added} added, ${updated} updated, ${removed} removed\\n`,\n ),\n );\n}\n\nfunction requireAuth(): string {\n const apiKey = getApiKey();\n\n if (!apiKey) {\n console.error(\n \"\\n\" +\n chalk.red(\" ✖ Not authenticated.\\n\") +\n chalk.dim(\" Run \") +\n chalk.bold(\"revstack login\") +\n chalk.dim(\" first.\\n\"),\n );\n process.exit(1);\n }\n\n return apiKey;\n}\n\n// ─── Command ─────────────────────────────────────────────────\n\nexport const pushCommand = new Command(\"push\")\n .description(\"Push your local billing config to Revstack Cloud\")\n .option(\"-e, --env <environment>\", \"Target environment\", \"test\")\n .action(async (options: { env: string }) => {\n const apiKey = requireAuth();\n const config = await loadLocalConfig(process.cwd());\n\n // ── Step 1: Validate config ────────────────────────────────\n\n const validationSpinner = ora({\n text: \"Validating billing configuration...\",\n prefixText: \" \",\n }).start();\n\n try {\n // Tier 1: Structural Validation\n const parsedConfig = RevstackConfigSchema.parse(config);\n\n // Tier 2: Business Logic Validation\n validateConfig(parsedConfig as any);\n\n validationSpinner.succeed(\"Configuration validated\");\n } catch (error: any) {\n validationSpinner.fail(\"Configuration invalid\");\n\n if (error?.name === \"ZodError\") {\n console.error(\n chalk.red(\n \"\\n ✖ The billing configuration contains schema/formatting errors:\\n\",\n ),\n );\n for (const err of error.errors || []) {\n const path = err.path.join(\".\");\n console.error(chalk.red(` • [${path}] ${err.message}`));\n }\n console.log();\n process.exit(1);\n }\n\n if (\n error instanceof RevstackValidationError ||\n error?.name === \"RevstackValidationError\"\n ) {\n console.error(\n chalk.red(\n \"\\n ✖ The billing configuration contains business logic errors:\\n\",\n ),\n );\n for (const err of error.errors || []) {\n console.error(chalk.red(` • ${err}`));\n }\n console.log();\n process.exit(1);\n }\n\n validationSpinner.fail(\"Validation failed\");\n console.error(\n chalk.red(\n `\\n An unexpected error occurred during validation: ${error?.message || String(error)}\\n`,\n ),\n );\n process.exit(1);\n }\n\n // ── Step 2: Compute diff ──────────────────────────────────\n\n const spinner = ora({\n text: \"Calculating diff...\",\n prefixText: \" \",\n }).start();\n\n let diffResponse: DiffResponse;\n\n try {\n const res = await fetch(`${API_BASE}/api/v1/cli/diff`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ env: options.env, config }),\n });\n\n if (!res.ok) {\n spinner.fail(\"Failed to calculate diff\");\n console.error(\n chalk.red(`\\n API returned ${res.status}: ${res.statusText}\\n`),\n );\n process.exit(1);\n }\n\n diffResponse = (await res.json()) as DiffResponse;\n spinner.succeed(\"Diff calculated\");\n } catch (error: unknown) {\n spinner.fail(\"Failed to reach Revstack Cloud\");\n console.error(chalk.red(`\\n ${(error as Error).message}\\n`));\n process.exit(1);\n }\n\n // ── Step 2: Present diff ──────────────────────────────────\n\n printDiff(diffResponse.diff, options.env);\n\n if (diffResponse.diff.length === 0) {\n return;\n }\n\n // ── Step 3: Check if push is allowed ──────────────────────\n\n if (!diffResponse.canPush) {\n console.log(\n \"\\n\" +\n chalk.bgRed.white.bold(\" BLOCKED: PUSH IMPOSSIBLE \") +\n \"\\n\\n\" +\n chalk.red(\n ` ✖ ${diffResponse.blockedReason ?? \"The server rejected this configuration due to destructive changes.\"}\\n`,\n ),\n );\n process.exit(1);\n }\n\n // ── Step 4: Confirm ───────────────────────────────────────\n\n const envLabel =\n options.env === \"production\"\n ? chalk.red.bold(options.env)\n : chalk.cyan.bold(options.env);\n\n const { confirm } = await prompts({\n type: \"confirm\",\n name: \"confirm\",\n message: `Apply these changes to ${envLabel}?`,\n initial: false,\n });\n\n if (!confirm) {\n console.log(chalk.dim(\"\\n Push cancelled.\\n\"));\n return;\n }\n\n // ── Step 5: Push ──────────────────────────────────────────\n\n const pushSpinner = ora({\n text: `Pushing to ${options.env}...`,\n prefixText: \" \",\n }).start();\n\n try {\n const res = await fetch(`${API_BASE}/api/v1/cli/push`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({ env: options.env, config }),\n });\n\n if (!res.ok) {\n pushSpinner.fail(\"Push failed\");\n console.error(\n chalk.red(`\\n API returned ${res.status}: ${res.statusText}\\n`),\n );\n process.exit(1);\n }\n\n pushSpinner.succeed(\"Pushed successfully\");\n console.log(\n \"\\n\" +\n chalk.green(\" ✔ Config deployed to \") +\n envLabel +\n \"\\n\" +\n chalk.dim(\" Changes are now live.\\n\"),\n );\n } catch (error: unknown) {\n pushSpinner.fail(\"Push failed\");\n console.error(chalk.red(`\\n ${(error as Error).message}\\n`));\n process.exit(1);\n }\n });\n","import { createJiti } from \"jiti\";\nimport path from \"node:path\";\nimport chalk from \"chalk\";\n\n/**\n * Load the `revstack.config.ts` from the given directory.\n *\n * @param cwd - The directory to search for `revstack.config.ts`.\n * @returns The parsed and sanitized configuration object.\n */\nexport async function loadLocalConfig(\n cwd: string,\n): Promise<Record<string, unknown>> {\n const configPath = path.resolve(cwd, \"revstack.config.ts\");\n\n try {\n const jiti = createJiti(cwd);\n const module = (await jiti.import(configPath)) as Record<string, unknown>;\n const config = (module.default ?? module) as Record<string, unknown>;\n\n // Sanitize: strip functions, class instances, and non-serializable data.\n // This ensures we only send plain JSON to the Revstack Cloud API.\n return JSON.parse(JSON.stringify(config));\n } catch (error: unknown) {\n const err = error as NodeJS.ErrnoException;\n\n if (\n err.code === \"ERR_MODULE_NOT_FOUND\" ||\n err.code === \"ENOENT\" ||\n err.code === \"MODULE_NOT_FOUND\"\n ) {\n console.error(\n chalk.red(\n \"\\n ✖ Could not find revstack.config.ts in the current directory.\\n\",\n ) +\n chalk.dim(\" Run \") +\n chalk.bold(\"revstack init\") +\n chalk.dim(\" to create one.\\n\"),\n );\n } else if (err.name === \"SyntaxError\" || error instanceof SyntaxError) {\n console.error(\n chalk.red(\"\\n ✖ Syntax Error in revstack.config.ts\\n\") +\n chalk.dim(\" \" + (err.message ?? String(error))) +\n \"\\n\",\n );\n } else {\n console.error(\n chalk.red(\"\\n ✖ Failed to parse revstack.config.ts\\n\") +\n chalk.dim(\" \" + (err.message ?? String(error))) +\n \"\\n\",\n );\n }\n\n process.exit(1);\n }\n}\n","import { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport ora from \"ora\";\nimport prompts from \"prompts\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { execa } from \"execa\";\nimport { getApiKey } from \"@/utils/auth\";\nimport { type RevstackConfig, RevstackConfigSchema } from \"@revstackhq/core\";\n\nfunction serializeObject(\n obj: Record<string, unknown>,\n depth: number = 0,\n): string {\n const entries = Object.entries(obj);\n if (entries.length === 0) return \"{}\";\n\n const pad = \" \".repeat(depth + 1);\n const closePad = \" \".repeat(depth);\n\n const lines = entries\n .map(([key, value]) => {\n if (value === undefined) return null;\n\n const formattedValue =\n typeof value === \"string\"\n ? `\"${value}\"`\n : typeof value === \"number\" || typeof value === \"boolean\"\n ? String(value)\n : Array.isArray(value)\n ? serializeArray(value, depth + 1)\n : typeof value === \"object\" && value !== null\n ? serializeObject(value as Record<string, unknown>, depth + 1)\n : String(value);\n\n return `${pad}${key}: ${formattedValue},`;\n })\n .filter(Boolean);\n\n return `{\\n${lines.join(\"\\n\")}\\n${closePad}}`;\n}\n\nfunction serializeArray(arr: unknown[], depth: number): string {\n if (arr.length === 0) return \"[]\";\n\n const pad = \" \".repeat(depth + 1);\n const closePad = \" \".repeat(depth);\n\n const items = arr.map((item) => {\n if (typeof item === \"object\" && item !== null) {\n return `${pad}${serializeObject(item as Record<string, unknown>, depth + 1)},`;\n }\n return `${pad}${JSON.stringify(item)},`;\n });\n\n return `[\\n${items.join(\"\\n\")}\\n${closePad}]`;\n}\n\nfunction generateFeaturesSource(config: RevstackConfig): string {\n const featureEntries = Object.entries(config.features).map(([slug, f]) => {\n const props: Record<string, unknown> = {\n name: f.name,\n type: f.type,\n unit_type: f.unit_type,\n };\n if (f.description) props.description = f.description;\n\n return ` ${slug}: defineFeature(${serializeObject(props, 2)}),`;\n });\n\n return `import { defineFeature } from \"@revstackhq/core\";\n\nexport const features = {\n${featureEntries.join(\"\\n\")}\n};\n`;\n}\n\nfunction generatePlansSource(config: RevstackConfig): string {\n const planEntries = Object.entries(config.plans).map(([slug, plan]) => {\n const props: Record<string, unknown> = {\n name: plan.name,\n };\n if (plan.description) props.description = plan.description;\n props.is_default = plan.is_default;\n props.is_public = plan.is_public;\n props.type = plan.type;\n\n if (plan.prices && plan.prices.length > 0) {\n props.prices = plan.prices;\n }\n\n props.features = plan.features;\n\n const comment = plan.is_default\n ? ` // DO NOT DELETE: Automatically created default plan for guests.\\n`\n : \"\";\n\n return `${comment} ${slug}: definePlan<typeof features>(${serializeObject(props, 3)}),`;\n });\n\n return `import { definePlan } from \"@revstackhq/core\";\nimport { features } from \"./features\";\n\nexport const plans = {\n${planEntries.join(\"\\n\")}\n};\n`;\n}\n\nfunction generateAddonsSource(config: RevstackConfig): string {\n if (!config.addons) return \"\";\n\n const addonEntries = Object.entries(config.addons).map(([slug, addon]) => {\n const props: Record<string, unknown> = {\n name: addon.name,\n type: addon.type,\n amount: addon.amount,\n currency: addon.currency,\n };\n if (addon.description) props.description = addon.description;\n if (addon.billing_interval) props.billing_interval = addon.billing_interval;\n props.features = addon.features;\n\n return ` ${slug}: defineAddon<typeof features>(${serializeObject(props, 2)}),`;\n });\n\n return `import { defineAddon } from \"@revstackhq/core\";\nimport { features } from \"./features\";\n\nexport const addons = {\n${addonEntries.join(\"\\n\")}\n};\n`;\n}\n\nfunction generateCouponsSource(config: RevstackConfig): string {\n if (!config.coupons || config.coupons.length === 0) return \"\";\n\n // Make sure we format date strings and numbers properly but let serializeArray sort deep nesting\n const couponsArray = config.coupons.map((coupon) => {\n const props: Record<string, unknown> = {\n code: coupon.code,\n type: coupon.type,\n value: coupon.value,\n duration: coupon.duration,\n };\n if (coupon.name) props.name = coupon.name;\n if (coupon.duration_in_months)\n props.duration_in_months = coupon.duration_in_months;\n if (coupon.applies_to_plans)\n props.applies_to_plans = coupon.applies_to_plans;\n if (coupon.max_redemptions) props.max_redemptions = coupon.max_redemptions;\n if (coupon.expires_at) props.expires_at = coupon.expires_at;\n\n return props;\n });\n\n return `import type { DiscountDef } from \"@revstackhq/core\";\n\nexport const coupons: DiscountDef[] = ${serializeArray(couponsArray, 0)};\n`;\n}\n\nfunction generateRootConfigSource(config: RevstackConfig): string {\n const hasAddons = !!config.addons && Object.keys(config.addons).length > 0;\n const hasCoupons = !!config.coupons && config.coupons.length > 0;\n\n const imports = [\n `import { defineConfig } from \"@revstackhq/core\";`,\n `import { features } from \"./revstack/features\";`,\n `import { plans } from \"./revstack/plans\";`,\n ];\n if (hasAddons) {\n imports.push(`import { addons } from \"./revstack/addons\";`);\n }\n if (hasCoupons) {\n imports.push(`import { coupons } from \"./revstack/coupons\";`);\n }\n\n const configProps: Record<string, unknown> = {\n features: \"__RAW_features\",\n plans: \"__RAW_plans\",\n };\n\n if (hasAddons) {\n configProps.addons = \"__RAW_addons\";\n }\n\n if (hasCoupons) {\n configProps.coupons = \"__RAW_coupons\";\n }\n\n // Serialize the config object, but then remove the quotes around our RAW variables\n let configStr = serializeObject(configProps, 0);\n configStr = configStr.replace(/\"__RAW_features\"/g, \"features\");\n configStr = configStr.replace(/\"__RAW_plans\"/g, \"plans\");\n configStr = configStr.replace(/\"__RAW_addons\"/g, \"addons\");\n configStr = configStr.replace(/\"__RAW_coupons\"/g, \"coupons\");\n\n return `${imports.join(\"\\n\")}\n\nexport default defineConfig(${configStr});\n`;\n}\n\n// ─── Helpers ─────────────────────────────────────────────────\n\nconst API_BASE = \"https://app.revstack.dev\";\n\n// ─── Command ─────────────────────────────────────────────────\n\nexport const pullCommand = new Command(\"pull\")\n .description(\n \"Pull the remote billing config and overwrite local revstack.config.ts and revstack/ files\",\n )\n .option(\"-e, --env <environment>\", \"Target environment\", \"test\")\n .action(async (options: { env: string }) => {\n const apiKey = getApiKey();\n\n if (!apiKey) {\n console.error(\n \"\\n\" +\n chalk.red(\" ✖ Not authenticated.\\n\") +\n chalk.dim(\" Run \") +\n chalk.bold(\"revstack login\") +\n chalk.dim(\" first.\\n\"),\n );\n process.exit(1);\n }\n\n // ── 1. Fetch remote config ─────────────────────────────\n const spinner = ora({\n text: \"Fetching remote configuration...\",\n prefixText: \" \",\n }).start();\n\n let remoteConfig: RevstackConfig;\n\n try {\n const res = await fetch(\n `${API_BASE}/api/v1/cli/pull?env=${encodeURIComponent(options.env)}`,\n {\n headers: { Authorization: `Bearer ${apiKey}` },\n },\n );\n\n if (!res.ok) {\n spinner.fail(\"Failed to fetch remote config\");\n console.error(\n chalk.red(`\\n API returned ${res.status}: ${res.statusText}\\n`),\n );\n process.exit(1);\n }\n\n const rawData = await res.json();\n\n try {\n remoteConfig = RevstackConfigSchema.parse(rawData);\n } catch (validationError: any) {\n spinner.fail(\"Remote config failed schema validation\");\n console.error(chalk.red(`\\n ${validationError.message}\\n`));\n process.exit(1);\n }\n\n spinner.succeed(\"Remote config fetched\");\n } catch (error: unknown) {\n spinner.fail(\"Failed to reach Revstack Cloud\");\n console.error(chalk.red(`\\n ${(error as Error).message}\\n`));\n process.exit(1);\n }\n\n // ── 2. Show summary ────────────────────────────────────\n const featureCount = Object.keys(remoteConfig.features).length;\n const planCount = Object.keys(remoteConfig.plans).length;\n const addonCount = remoteConfig.addons\n ? Object.keys(remoteConfig.addons).length\n : 0;\n const couponCount = remoteConfig.coupons ? remoteConfig.coupons.length : 0;\n\n console.log(\n \"\\n\" +\n chalk.dim(\" Remote state: \") +\n chalk.white(\n `${featureCount} features, ${planCount} plans, ${addonCount} addons, ${couponCount} coupons`,\n ) +\n chalk.dim(` (${options.env})\\n`),\n );\n\n // ── 3. Confirm overwrite ───────────────────────────────\n const cwd = process.cwd();\n const configPath = path.resolve(cwd, \"revstack.config.ts\");\n const revstackDir = path.resolve(cwd, \"revstack\");\n const featuresPath = path.resolve(revstackDir, \"features.ts\");\n const plansPath = path.resolve(revstackDir, \"plans.ts\");\n\n const rootExists = fs.existsSync(configPath);\n const dirExists = fs.existsSync(revstackDir);\n\n if (rootExists || dirExists) {\n const { confirm } = await prompts({\n type: \"confirm\",\n name: \"confirm\",\n message:\n \"This will overwrite your local configuration files (revstack.config.ts and revstack/ data). Are you sure?\",\n initial: false,\n });\n\n if (!confirm) {\n console.log(chalk.dim(\"\\n Pull cancelled.\\n\"));\n return;\n }\n }\n\n // ── 4. Generate and write ──────────────────────────────\n if (!fs.existsSync(revstackDir)) {\n fs.mkdirSync(revstackDir, { recursive: true });\n }\n\n const featuresSource = generateFeaturesSource(remoteConfig);\n const plansSource = generatePlansSource(remoteConfig);\n const rootSource = generateRootConfigSource(remoteConfig);\n\n fs.writeFileSync(featuresPath, featuresSource, \"utf-8\");\n fs.writeFileSync(plansPath, plansSource, \"utf-8\");\n fs.writeFileSync(configPath, rootSource, \"utf-8\");\n\n if (remoteConfig.addons && Object.keys(remoteConfig.addons).length > 0) {\n const addonsSource = generateAddonsSource(remoteConfig);\n const addonsPath = path.resolve(revstackDir, \"addons.ts\");\n fs.writeFileSync(addonsPath, addonsSource, \"utf-8\");\n }\n\n if (remoteConfig.coupons && remoteConfig.coupons.length > 0) {\n const couponsSource = generateCouponsSource(remoteConfig);\n const couponsPath = path.resolve(revstackDir, \"coupons.ts\");\n fs.writeFileSync(couponsPath, couponsSource, \"utf-8\");\n }\n\n // ── 5. Format Files ────────────────────────────────────\n const formatSpinner = ora(\"Formatting generated files...\").start();\n try {\n // Run prettier on the generated files. We use npx to ensure it runs\n // using the locally hoisted version of prettier.\n await execa(\n \"npx\",\n [\"prettier\", \"--write\", \"revstack.config.ts\", \"revstack/**/*.ts\"],\n {\n cwd,\n stdio: \"ignore\",\n },\n );\n formatSpinner.succeed(\"Files formatted successfully\");\n } catch (err) {\n // It's not the end of the world if prettier fails, just notify\n formatSpinner.info(\n \"Files written properly, but automatic formatting (prettier) skipped or failed.\",\n );\n }\n\n console.log(\n \"\\n\" +\n chalk.green(\" ✔ Local files updated from remote.\\n\") +\n chalk.dim(\" Review the files and run \") +\n chalk.bold(\"revstack push\") +\n chalk.dim(\" to re-deploy.\\n\"),\n );\n });\n"],"mappings":"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","names":["Command","Command","chalk","Command","chalk","Command","chalk","fs","path","Command","chalk","path","fs","Command","chalk","prompts","ora","path","chalk","chalk","Command","ora","path","prompts","Command","chalk","ora","prompts","fs","path","RevstackConfigSchema","API_BASE","Command","chalk","ora","path","fs","prompts","require","Command"]}
@@ -1,12 +1,5 @@
1
1
  import { Command } from 'commander';
2
2
 
3
- /**
4
- * @file commands/init.ts
5
- * @description Scaffolds a new `revstack.config.ts` in the current directory.
6
- * Generates a starter config with the immutable Default Guest Plan and
7
- * a sample Pro plan using type-safe helpers from @revstackhq/core.
8
- */
9
-
10
3
  declare const initCommand: Command;
11
4
 
12
5
  export { initCommand };