@bigcommerce/catalyst 1.4.1 → 1.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/lib/errors.ts","../src/cli/lib/logger.ts","../src/cli/lib/telemetry.ts","../package.json","../src/cli/lib/user-config.ts","../src/cli/program.ts","../src/cli/commands/auth.ts","../src/cli/lib/auth-errors.ts","../src/cli/lib/login.ts","../src/cli/lib/auth.ts","../src/cli/lib/http-errors.ts","../src/cli/lib/clipboard.ts","../src/cli/lib/project.ts","../src/cli/lib/project-config.ts","../src/cli/lib/shared-options.ts","../src/cli/commands/build.ts","../src/cli/lib/build-env.ts","../src/cli/lib/commerce-hosting.ts","../src/cli/lib/sort-package-json.ts","../src/cli/lib/detect-package-manager.ts","../src/cli/lib/get-module-cli-path.ts","../src/cli/lib/install-dependencies.ts","../src/cli/lib/project-state.ts","../src/cli/lib/required-build-env.ts","../src/cli/lib/wrangler-config.ts","../src/cli/commands/channels.ts","../src/cli/lib/channel-checkout-url-flow.ts","../src/cli/lib/channel-site-flow.ts","../src/cli/lib/channels.ts","../src/cli/lib/checkout-url.ts","../src/cli/lib/create-channel-flow.ts","../src/cli/lib/localization.ts","../src/cli/lib/env-config.ts","../src/cli/lib/resolve-credentials.ts","../src/cli/lib/write-env.ts","../src/cli/commands/create.ts","../src/cli/lib/extract-catalyst.ts","../src/cli/lib/init-git-repo.ts","../src/cli/lib/rewrite-core-package.ts","../src/cli/lib/setup-core-project.ts","../src/cli/commands/debug.ts","../src/cli/lib/collect-diagnostics.ts","../src/cli/commands/deploy.ts","../src/cli/lib/deployment-errors.ts","../src/cli/commands/domains.ts","../src/cli/lib/domains.ts","../src/cli/lib/observability.ts","../src/cli/commands/env.ts","../src/cli/commands/logs.ts","../src/cli/commands/projects.ts","../src/cli/commands/start.ts","../src/cli/commands/telemetry.ts","../src/cli/commands/upgrade.ts","../src/cli/commands/version.ts","../src/cli/hooks/telemetry.ts","../src/cli/index.ts"],"sourcesContent":["// Base class for errors that are the user's to fix and whose message already\n// says everything they need (bad input, a naming/ownership conflict, invalid\n// credentials, a feature that isn't enabled). The top-level handler in\n// `index.ts` prints these plainly and exits non-zero WITHOUT the \"share your\n// Correlation ID with BigCommerce support\" bug-report framing that unexpected\n// and server-side errors get — a clear 4xx response is not a bug to report.\nexport class UserActionableError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UserActionableError';\n }\n}\n","import { createConsola } from 'consola';\n\nexport const consola = createConsola({\n level: process.env.CONSOLA_LEVEL ? parseInt(process.env.CONSOLA_LEVEL, 10) : 3,\n // Drop the per-line timestamp. It adds noise for a short-lived CLI and, on\n // long lines, consola can't right-align it so it falls back to an inline\n // `[time]` prefix that breaks copy-pasteable command suggestions.\n formatOptions: { date: false },\n});\n","import { Analytics } from '@segment/analytics-node';\nimport Conf from 'conf';\nimport { randomBytes, randomUUID } from 'node:crypto';\n\nimport PACKAGE_INFO from '../../../package.json';\n\nimport { getUserConfig, UserConfigSchema } from './user-config';\n\nconst TELEMETRY_KEY_ENABLED = 'telemetry.enabled';\nconst TELEMETRY_KEY_ID = `telemetry.anonymousId`;\n\n// CLI telemetry is best-effort: command completion must never be delayed by a\n// slow or unreachable analytics endpoint. `closeAndFlush()` uses the flush\n// interval to derive its timeout, so keep both bounds intentionally short.\nconst TELEMETRY_FLUSH_INTERVAL_MS = 200;\nconst TELEMETRY_HTTP_REQUEST_TIMEOUT_MS = 200;\n\nexport class Telemetry {\n readonly correlationId: string;\n readonly analytics: Analytics;\n readonly startTime: number;\n commandName = 'unknown';\n\n private userConfig: Conf<UserConfigSchema>;\n private CATALYST_TELEMETRY_DISABLED: string | undefined;\n\n private readonly projectName = 'catalyst-cli';\n private readonly projectVersion = PACKAGE_INFO.version;\n\n constructor() {\n this.CATALYST_TELEMETRY_DISABLED = process.env.CATALYST_TELEMETRY_DISABLED;\n\n this.userConfig = getUserConfig();\n\n this.correlationId = randomUUID();\n this.startTime = Date.now();\n this.analytics = new Analytics({\n writeKey: process.env.CLI_SEGMENT_WRITE_KEY ?? 'not-a-valid-segment-write-key',\n flushInterval: TELEMETRY_FLUSH_INTERVAL_MS,\n httpRequestTimeout: TELEMETRY_HTTP_REQUEST_TIMEOUT_MS,\n maxRetries: 0,\n });\n }\n\n durationMs(): number {\n return Date.now() - this.startTime;\n }\n\n async track(eventName: string, payload: Record<string, unknown>) {\n if (!this.isEnabled()) {\n return Promise.resolve(undefined);\n }\n\n this.analytics.track({\n event: eventName,\n anonymousId: this.getAnonymousId(),\n properties: {\n ...payload,\n correlationId: this.correlationId,\n nodeVersion: process.version,\n platform: process.platform,\n arch: process.arch,\n cliVersion: PACKAGE_INFO.version,\n },\n context: {\n app: {\n name: this.projectName,\n version: this.projectVersion,\n },\n },\n });\n }\n\n async identify(storeHash?: string) {\n if (!this.isEnabled()) {\n return Promise.resolve(undefined);\n }\n\n if (!storeHash) {\n return Promise.resolve(undefined);\n }\n\n this.analytics.identify({\n userId: storeHash,\n anonymousId: this.getAnonymousId(),\n context: {\n app: {\n name: this.projectName,\n version: this.projectVersion,\n },\n },\n });\n }\n\n setEnabled = (_enabled: boolean) => {\n const enabled = Boolean(_enabled);\n\n this.userConfig.set('telemetry.enabled', enabled);\n };\n\n isEnabled() {\n return (\n !this.CATALYST_TELEMETRY_DISABLED &&\n this.userConfig.get<typeof TELEMETRY_KEY_ENABLED, boolean>(TELEMETRY_KEY_ENABLED, true)\n );\n }\n\n private getAnonymousId(): string {\n const val = this.userConfig.get<typeof TELEMETRY_KEY_ID, string>(TELEMETRY_KEY_ID);\n\n if (val) {\n return val;\n }\n\n const generated = randomBytes(32).toString('hex');\n\n this.userConfig.set(TELEMETRY_KEY_ID, generated);\n\n return generated;\n }\n}\n\nlet telemetryInstance: Telemetry | undefined;\n\n// Singleton so the pre-hook, post-hook, error handler, and command bodies all\n// share one correlationId. resetTelemetry() is for test isolation.\nexport function getTelemetry(): Telemetry {\n telemetryInstance ??= new Telemetry();\n\n return telemetryInstance;\n}\n\nexport function resetTelemetry(): void {\n telemetryInstance = undefined;\n}\n","{\n \"name\": \"@bigcommerce/catalyst\",\n \"version\": \"1.4.1\",\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/bigcommerce/catalyst\",\n \"directory\": \"packages/catalyst\"\n },\n \"bin\": {\n \"catalyst\": \"dist/cli.js\"\n },\n \"files\": [\n \"dist\",\n \"templates\"\n ],\n \"scripts\": {\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint . --max-warnings 0\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"build\": \"tsup\"\n },\n \"engines\": {\n \"node\": \"^22.0.0 || ^24.0.0\"\n },\n \"dependencies\": {\n \"@commander-js/extra-typings\": \"^14.0.0\",\n \"@inquirer/prompts\": \"^7.5.3\",\n \"@segment/analytics-node\": \"^2.2.1\",\n \"adm-zip\": \"^0.5.16\",\n \"commander\": \"^14.0.0\",\n \"conf\": \"^13.1.0\",\n \"consola\": \"^3.4.2\",\n \"cross-spawn\": \"^7.0.6\",\n \"dotenv\": \"^16.5.0\",\n \"execa\": \"^9.6.0\",\n \"fs-extra\": \"^11.3.0\",\n \"lodash.kebabcase\": \"^4.1.1\",\n \"nypm\": \"^0.5.4\",\n \"open\": \"^10.1.0\",\n \"semver\": \"^7.7.4\",\n \"std-env\": \"^3.9.0\",\n \"tar\": \"^7.5.7\",\n \"tldts\": \"^7.4.12\",\n \"yocto-spinner\": \"^1.0.0\",\n \"zod\": \"^4.0.5\"\n },\n \"devDependencies\": {\n \"@bigcommerce/eslint-config\": \"^2.11.0\",\n \"@bigcommerce/eslint-config-catalyst\": \"workspace:^\",\n \"@types/adm-zip\": \"^0.5.7\",\n \"@types/cross-spawn\": \"^6.0.6\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/lodash.kebabcase\": \"^4.1.9\",\n \"@types/node\": \"^22.15.30\",\n \"@types/semver\": \"^7.7.0\",\n \"@vitest/coverage-v8\": \"^3.2.4\",\n \"@vitest/ui\": \"^3.2.4\",\n \"eslint\": \"^8.57.1\",\n \"msw\": \"^2.9.0\",\n \"prettier\": \"^3.6.2\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.8.3\",\n \"vitest\": \"^3.2.4\"\n },\n \"peerDependencies\": {\n \"@opennextjs/cloudflare\": \"^1.17.3\"\n },\n \"peerDependenciesMeta\": {\n \"@opennextjs/cloudflare\": {\n \"optional\": true\n }\n }\n}\n","import Conf from 'conf';\n\nexport interface UserConfigSchema {\n telemetry: {\n enabled: boolean;\n anonymousId: string;\n };\n}\n\nlet userConfigInstance: Conf<UserConfigSchema> | undefined;\n\n// User-scoped config (per-machine, not per-project). Lives in the OS config dir\n// — keeping telemetry out of the user's working directory so commands like\n// `catalyst create` don't drop a stray `.bigcommerce/` next to where they're run.\nexport function getUserConfig(): Conf<UserConfigSchema> {\n userConfigInstance ??= new Conf<UserConfigSchema>({\n projectName: 'catalyst-cli',\n projectSuffix: '',\n configName: 'config',\n schema: {\n telemetry: {\n type: 'object',\n properties: {\n enabled: { type: 'boolean' },\n anonymousId: { type: 'string' },\n },\n },\n },\n });\n\n return userConfigInstance;\n}\n\nexport function resetUserConfig(): void {\n userConfigInstance = undefined;\n}\n","import { Command } from 'commander';\nimport { colorize } from 'consola/utils';\n\nimport PACKAGE_INFO from '../../package.json';\n\nimport { auth } from './commands/auth';\nimport { build } from './commands/build';\nimport { channels } from './commands/channels';\nimport { create } from './commands/create';\nimport { debug } from './commands/debug';\nimport { deploy } from './commands/deploy';\nimport { domains } from './commands/domains';\nimport { env } from './commands/env';\nimport { logs } from './commands/logs';\nimport { projects } from './commands/projects';\nimport { start } from './commands/start';\nimport { telemetry } from './commands/telemetry';\nimport { upgrade } from './commands/upgrade';\nimport { version } from './commands/version';\nimport { telemetryPostHook, telemetryPreHook } from './hooks/telemetry';\nimport { consola } from './lib/logger';\n\n// Env files are only loaded by `build` and `deploy` (which auto-load\n// .env.local and .env, or an explicit `--env-path`). No other command reads env\n// files, so running the CLI can't be surprised by a stray `.env.local` on disk.\n\n// CATALYST_STORE_HASH falls back to BIGCOMMERCE_STORE_HASH so freshly-scaffolded\n// projects work without duplicating the same value under two names. Aliasing\n// here means every command's `.env('CATALYST_STORE_HASH')` binding picks it up\n// without per-command changes.\nif (!process.env.CATALYST_STORE_HASH && process.env.BIGCOMMERCE_STORE_HASH) {\n process.env.CATALYST_STORE_HASH = process.env.BIGCOMMERCE_STORE_HASH;\n}\n\nexport const program = new Command();\n\nconsola.log(colorize('cyanBright', `◢ ${PACKAGE_INFO.name} v${PACKAGE_INFO.version}\\n`));\n\nprogram\n .name(PACKAGE_INFO.name)\n .version(PACKAGE_INFO.version)\n .summary('CLI tool for Catalyst development')\n .description(\n 'CLI tool for Catalyst development.\\n\\nConfiguration priority: flags > process.env > .bigcommerce/project.json. `build` and `deploy` additionally load env files (--env-path, or an auto-loaded .env.local/.env) for the build.\\n\\nCATALYST_STORE_HASH falls back to BIGCOMMERCE_STORE_HASH if unset.\\n\\nRun `catalyst <command> --help` for details on a specific command.',\n )\n .configureHelp({ showGlobalOptions: true })\n .addCommand(version)\n .addCommand(create)\n .addCommand(start)\n .addCommand(build)\n .addCommand(deploy)\n .addCommand(domains)\n .addCommand(logs)\n .addCommand(projects)\n .addCommand(env)\n .addCommand(channels)\n .addCommand(auth)\n .addCommand(upgrade)\n .addCommand(telemetry)\n .addCommand(debug)\n .hook('preAction', telemetryPreHook)\n .hook('postAction', telemetryPostHook);\n","import { Command, Option } from 'commander';\nimport { z } from 'zod';\n\nimport { assertAuthorized, UnauthorizedError } from '../lib/auth-errors';\nimport { consola } from '../lib/logger';\nimport { LoginAbortedError, login as runInteractiveLogin } from '../lib/login';\nimport { fetchProjects } from '../lib/project';\nimport { getProjectConfig } from '../lib/project-config';\nimport {\n accessTokenOption,\n apiHostOption,\n loginUrlOption,\n resolveApiHost,\n storeHashOption,\n} from '../lib/shared-options';\n\nconst StoreProfileSchema = z.object({\n data: z.object({\n store_name: z.string(),\n }),\n});\n\nasync function fetchStoreProfile(storeHash: string, accessToken: string, apiHost: string) {\n const response = await fetch(`https://${apiHost}/stores/${storeHash}/v3/settings/store/profile`, {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n Accept: 'application/json',\n },\n });\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw new Error(`${response.status} ${response.statusText}`);\n }\n\n const res: unknown = await response.json();\n const result = StoreProfileSchema.safeParse(res);\n\n if (!result.success) {\n throw new Error('Unexpected response from store profile API');\n }\n\n return result.data.data;\n}\n\n// `login` verifies rather than just checking for stored credentials: every other\n// command answers a rejected token with \"Run `catalyst auth login`\", so refusing\n// because credentials are merely *present* loops the user back with no way out\n// but `auth logout`. `unverifiable` keeps that distinct from a real rejection —\n// we can't prove the token is bad, so we don't discard it.\ntype CredentialStatus =\n | { valid: true; storeName: string }\n | { valid: false; reason: 'unauthorized' }\n | { valid: false; reason: 'unverifiable'; message: string };\n\nasync function checkCredentials(\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<CredentialStatus> {\n try {\n const { store_name: storeName } = await fetchStoreProfile(storeHash, accessToken, apiHost);\n\n return { valid: true, storeName };\n } catch (error) {\n if (error instanceof UnauthorizedError) return { valid: false, reason: 'unauthorized' };\n\n return {\n valid: false,\n reason: 'unverifiable',\n message: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nconst whoami = new Command('whoami')\n .configureHelp({ showGlobalOptions: true })\n .description('Verify stored credentials and display store/project info.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst auth whoami\n\n Logged in to My Store (abc123), connected to project my-project (43eba682-0c48-11f1-9bd5-827a48b0ce1e)`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .action(async (options) => {\n try {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n const storeHash = options.storeHash ?? config.get('storeHash');\n const accessToken = options.accessToken ?? config.get('accessToken');\n\n if (!storeHash || !accessToken) {\n consola.info('Not logged in: no credentials found.');\n consola.info(\n 'Run `catalyst auth login`, or provide --store-hash and --access-token flags (or set CATALYST_STORE_HASH and CATALYST_ACCESS_TOKEN environment variables).',\n );\n process.exit(1);\n\n return;\n }\n\n const store = await fetchStoreProfile(storeHash, accessToken, apiHost);\n\n const projectUuid = config.get('projectUuid');\n\n if (projectUuid) {\n const projects = await fetchProjects(storeHash, accessToken, apiHost);\n const linkedProject = projects.find((p) => p.uuid === projectUuid);\n\n if (linkedProject) {\n consola.info(\n `Logged in to ${store.store_name} (${storeHash}), connected to project ${linkedProject.name} (${projectUuid})`,\n );\n } else {\n consola.info(\n `Logged in to ${store.store_name} (${storeHash}), project ${projectUuid} not found`,\n );\n }\n } else {\n consola.info(`Logged in to ${store.store_name} (${storeHash})`);\n }\n\n process.exit(0);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n if (error instanceof UnauthorizedError) {\n consola.error(\n 'Not logged in: your access token is invalid or has expired. Run `catalyst auth login`.',\n );\n } else if (message.includes('401') || message.includes('403')) {\n consola.error(`Not logged in: invalid credentials (${message})`);\n } else {\n consola.error(`Failed to verify credentials: ${message}`);\n }\n\n process.exit(1);\n }\n });\n\nconst login = new Command('login')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Authenticate via browser using the OAuth device code flow. Falls back to an interactive store hash + access token prompt if the browser flow is unavailable. Passing --store-hash and --access-token verifies and stores those credentials instead. If already logged in with credentials that still work, displays them and suggests `catalyst auth logout`; if the stored token has expired or been revoked, re-authenticates in place.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Login interactively (browser, with manual fallback)\n $ catalyst auth login\n\n # Login with existing credentials (skips interactive flow)\n $ catalyst auth login --store-hash <STORE_HASH> --access-token <ACCESS_TOKEN>\n\n # Re-authenticate without checking the stored credentials first\n $ catalyst auth login --force`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(loginUrlOption())\n .addOption(\n new Option(\n '--force',\n 'Skip the check on any credentials already stored and re-authenticate regardless.',\n ),\n )\n .action(async (options, command) => {\n try {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n const storeHash = options.storeHash ?? config.get('storeHash');\n const accessToken = options.accessToken ?? config.get('accessToken');\n // Both flags typed on the command line. These options also read\n // CATALYST_STORE_HASH/CATALYST_ACCESS_TOKEN, but an exported env var is\n // ambient config and must not turn a plain `auth login` into a silent\n // credential write — only an explicit pair of flags does.\n const suppliedOnCli =\n command.getOptionValueSource('storeHash') === 'cli' &&\n command.getOptionValueSource('accessToken') === 'cli';\n\n // Non-interactive login: the user named the credentials to use, so verify\n // and persist them rather than reporting on them.\n if (suppliedOnCli && storeHash && accessToken) {\n if (!options.force) {\n const status = await checkCredentials(storeHash, accessToken, apiHost);\n\n // Opening a browser instead would hide what's wrong with what they passed.\n if (!status.valid && status.reason === 'unauthorized') {\n consola.error(`The credentials provided for store ${storeHash} were rejected.`);\n consola.info(\n 'Check the store hash and access token, or run `catalyst auth login` without them to authenticate in the browser.',\n );\n process.exit(1);\n\n return;\n }\n\n if (!status.valid) {\n consola.warn(`Couldn't verify the credentials provided: ${status.message}`);\n }\n }\n\n config.set('storeHash', storeHash);\n config.set('accessToken', accessToken);\n\n consola.success(`Logged in to store ${storeHash}.`);\n process.exit(0);\n\n return;\n }\n\n if (storeHash && accessToken && !options.force) {\n const status = await checkCredentials(storeHash, accessToken, apiHost);\n\n if (status.valid) {\n consola.info(`Already logged in to ${status.storeName} (${storeHash}).`);\n consola.info(\n 'Run `catalyst auth logout` first to re-authenticate, or `catalyst auth login --force` to skip this check.',\n );\n process.exit(0);\n\n return;\n }\n\n // The device-code flow needs the same network that just failed, so\n // trading working credentials for another error is a downgrade.\n if (status.reason === 'unverifiable') {\n consola.warn(\n `Found credentials for store ${storeHash} but couldn't verify them: ${status.message}`,\n );\n consola.info(\n 'Keeping them. Re-run once the API is reachable, or `catalyst auth login --force` to re-authenticate regardless.',\n );\n process.exit(0);\n\n return;\n }\n\n consola.warn(\n `Stored credentials for store ${storeHash} are no longer valid — re-authenticating.`,\n );\n }\n\n const credentials = await runInteractiveLogin(options.loginUrl, apiHost);\n\n config.set('storeHash', credentials.storeHash);\n config.set('accessToken', credentials.accessToken);\n\n consola.success(`Logged in to store ${credentials.storeHash}.`);\n process.exit(0);\n } catch (error) {\n if (error instanceof LoginAbortedError) {\n consola.info(\n 'Login aborted. Re-run `catalyst auth login` when you have your credentials ready.',\n );\n process.exit(0);\n\n return;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n\n consola.error(`Login failed: ${message}`);\n process.exit(1);\n }\n });\n\nconst logout = new Command('logout')\n .configureHelp({ showGlobalOptions: true })\n .description('Remove stored credentials for the current project.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst auth logout`,\n )\n .action(() => {\n try {\n const config = getProjectConfig();\n\n const storeHash = config.get('storeHash');\n const accessToken = config.get('accessToken');\n\n if (!storeHash && !accessToken) {\n consola.info('Not logged in: no credentials found.');\n process.exit(0);\n\n return;\n }\n\n config.delete('storeHash');\n config.delete('accessToken');\n\n consola.success(`Logged out from store ${storeHash ?? 'unknown'}.`);\n process.exit(0);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n consola.error(`Logout failed: ${message}`);\n process.exit(1);\n }\n });\n\nexport const auth = new Command('auth')\n .configureHelp({ showGlobalOptions: true })\n .description('Manage authentication for the BigCommerce CLI.')\n .addCommand(whoami)\n .addCommand(login)\n .addCommand(logout);\n","import { UserActionableError } from './errors';\n\n// Thrown when an authenticated API call comes back 401 Unauthorized — i.e. the\n// access token was sent but rejected. This covers an expired/revoked token as\n// well as a token that was never valid (e.g. a typo'd `--access-token` flag or\n// a stale `CATALYST_ACCESS_TOKEN` env var). It does NOT cover the \"no\n// credentials at all\" case — that's caught earlier by `resolveCredentials`\n// (and `auth whoami`'s own guard) before any request is made.\n//\n// The CLI can't refresh the token silently (the device-code flow returns no\n// refresh token), so the only recovery is to re-authenticate. Callers should\n// let this propagate to the top-level handler in `index.ts`, which prints the\n// message without the generic \"share your Correlation ID with support\"\n// bug-report framing.\nexport class UnauthorizedError extends UserActionableError {\n constructor() {\n super(\n 'Your access token is invalid or has expired.\\n' +\n 'Run `catalyst auth login` to re-authenticate.',\n );\n this.name = 'UnauthorizedError';\n }\n}\n\n// Call immediately after an authenticated `fetch`, before any other status\n// checks. Only 401 means \"invalid/expired token\" — 403 is overloaded elsewhere\n// to mean \"API not enabled\" (scope/feature flag), so it is intentionally not\n// treated as an auth failure here.\nexport function assertAuthorized(response: Response): void {\n if (response.status === 401) {\n throw new UnauthorizedError();\n }\n}\n","import { confirm, input, password } from '@inquirer/prompts';\nimport { colorize } from 'consola/utils';\nimport open from 'open';\nimport yoctoSpinner from 'yocto-spinner';\nimport { z } from 'zod';\n\nimport { DEVICE_OAUTH_SCOPES, requestDeviceCode, waitForDeviceToken } from './auth';\nimport { copyToClipboard } from './clipboard';\nimport { UserActionableError } from './errors';\nimport { consola } from './logger';\n\nexport interface LoginResult {\n storeHash: string;\n accessToken: string;\n}\n\n// Thrown when the user declines the manual-login fallback after the browser\n// (device-code) flow has failed. Callers should treat this as a clean exit,\n// not an error — the user explicitly chose to abort.\nexport class LoginAbortedError extends Error {\n constructor() {\n super('Login aborted by user.');\n this.name = 'LoginAbortedError';\n }\n}\n\nconst StoreProfileSchema = z.object({\n data: z.object({\n store_name: z.string(),\n }),\n});\n\nasync function fetchStoreProfile(storeHash: string, accessToken: string, apiHost: string) {\n const response = await fetch(`https://${apiHost}/stores/${storeHash}/v3/settings/store/profile`, {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n Accept: 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`${response.status} ${response.statusText}`);\n }\n\n const res: unknown = await response.json();\n const result = StoreProfileSchema.safeParse(res);\n\n if (!result.success) {\n throw new Error('Unexpected response from store profile API');\n }\n\n return result.data.data;\n}\n\nasync function deviceCodeLogin(loginUrl: string): Promise<LoginResult> {\n const deviceCode = await requestDeviceCode(loginUrl);\n\n consola.info(\n `${colorize('yellow', 'Your one-time code:')} ${colorize('bold', deviceCode.user_code)}`,\n );\n\n // Wait for the user to acknowledge before hijacking their browser. This keeps\n // the UX consistent across `create`, `auth login`, and the channel commands.\n // In non-interactive contexts (CI, piped stdin) there's nobody to press\n // Enter, so skip straight to opening the verification URL.\n if (process.stdin.isTTY) {\n await input({ message: 'Press Enter to open your browser and sign in' });\n\n // Best-effort: drop the code on the clipboard so the user can paste it\n // straight into the verification page. We already printed it above as a\n // fallback, and a clipboard failure must never interrupt the flow.\n const copied = await copyToClipboard(deviceCode.user_code);\n\n if (copied) {\n consola.info('Copied the code to your clipboard — paste it into the sign-in page.');\n }\n }\n\n try {\n await open(deviceCode.verification_uri);\n consola.info(`Opened ${deviceCode.verification_uri} in your browser.`);\n } catch {\n consola.info(`Open ${deviceCode.verification_uri} in your browser and enter the code above.`);\n }\n\n const spinner = yoctoSpinner().start('Waiting for authentication...');\n\n const credentials = await waitForDeviceToken(\n loginUrl,\n deviceCode.device_code,\n deviceCode.interval,\n );\n\n spinner.success('Authentication complete.');\n\n return {\n storeHash: credentials.store_hash,\n accessToken: credentials.access_token,\n };\n}\n\nasync function manualLogin(apiHost: string): Promise<LoginResult> {\n consola.info(\n 'Create a store-level API account from your BigCommerce Control Panel:\\n' +\n ' Settings → API → Store-level API accounts → Create API account\\n' +\n `Grant these OAuth scopes: ${DEVICE_OAUTH_SCOPES}`,\n );\n\n const storeHashInput = await input({ message: 'Store hash:' });\n const storeHash = storeHashInput.trim();\n\n if (!storeHash) {\n throw new UserActionableError('Store hash is required.');\n }\n\n const accessTokenInput = await password({ message: 'Access token:', mask: true });\n const accessToken = accessTokenInput.trim();\n\n if (!accessToken) {\n throw new UserActionableError('Access token is required.');\n }\n\n const spinner = yoctoSpinner().start('Validating credentials...');\n\n try {\n const profile = await fetchStoreProfile(storeHash, accessToken, apiHost);\n\n spinner.success(`Validated credentials for ${profile.store_name} (${storeHash}).`);\n } catch (error) {\n spinner.error('Failed to validate credentials.');\n\n const message = error instanceof Error ? error.message : String(error);\n\n throw new UserActionableError(\n `Could not validate credentials (${message}). Double-check your store hash and access token, then try again.`,\n );\n }\n\n return { storeHash, accessToken };\n}\n\n// Interactive login orchestrator. Used by `catalyst create`, `catalyst auth\n// login`, and `catalyst projects create` to gather credentials when none are\n// supplied via flags/env/config.\n//\n// Happy path: opens the browser device-code flow. When that fails (e.g. the\n// device-code endpoint returns 404 because the OAuth client isn't yet\n// provisioned for the user's environment), we ask the user if they'd like to\n// fall back to pasting a store-level API account's credentials instead, then\n// validate them via the store profile API before returning.\nexport async function login(loginUrl: string, apiHost: string): Promise<LoginResult> {\n try {\n return await deviceCodeLogin(loginUrl);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n consola.warn(`Browser login didn't work (${message}).`);\n\n const shouldFallback = await confirm({\n message: 'Try logging in manually with a store hash and access token instead?',\n default: true,\n });\n\n if (!shouldFallback) {\n throw new LoginAbortedError();\n }\n\n return manualLogin(apiHost);\n }\n}\n","import { z } from 'zod';\n\nimport { httpError } from './http-errors';\n\nexport const DEVICE_OAUTH_CLIENT_ID = 'b8063bu6hhml4e0lqh22yut63atsbyv';\nexport const DEVICE_OAUTH_SCOPES = [\n 'store_v2_information',\n 'store_v2_products',\n 'store_v2_content',\n 'store_sites',\n 'store_storefront_api',\n 'store_infrastructure_deployments_manage',\n 'store_infrastructure_logs_read_only',\n 'store_infrastructure_projects_manage',\n 'store_channel_settings',\n].join(' ');\n\nexport const DEFAULT_LOGIN_URL = 'https://login.bigcommerce.com';\n\nexport const DeviceCodeResponseSchema = z.object({\n device_code: z.string(),\n user_code: z.string(),\n verification_uri: z.string(),\n expires_in: z.number(),\n interval: z.number(),\n});\n\nexport const DeviceCodeSuccessSchema = z.object({\n access_token: z.string(),\n store_hash: z.string(),\n context: z.string(),\n api_uri: z.string(),\n});\n\nexport async function requestDeviceCode(loginUrl: string) {\n const response = await fetch(`${loginUrl}/device/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n client_id: DEVICE_OAUTH_CLIENT_ID,\n scopes: DEVICE_OAUTH_SCOPES,\n }),\n });\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to request device code');\n }\n\n const res: unknown = await response.json();\n\n return DeviceCodeResponseSchema.parse(res);\n}\n\nexport async function pollDeviceToken(loginUrl: string, deviceCode: string) {\n const response = await fetch(`${loginUrl}/device/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n device_code: deviceCode,\n client_id: DEVICE_OAUTH_CLIENT_ID,\n }),\n });\n\n if (response.status !== 200) {\n return null;\n }\n\n const res: unknown = await response.json();\n\n return DeviceCodeSuccessSchema.parse(res);\n}\n\nexport async function waitForDeviceToken(\n loginUrl: string,\n deviceCode: string,\n interval: number,\n): Promise<z.infer<typeof DeviceCodeSuccessSchema>> {\n const credentials = await pollDeviceToken(loginUrl, deviceCode);\n\n if (credentials) {\n return credentials;\n }\n\n await new Promise((resolve) => {\n setTimeout(resolve, interval * 1000);\n });\n\n return waitForDeviceToken(loginUrl, deviceCode, interval);\n}\n","import { z } from 'zod';\n\nimport { UserActionableError } from './errors';\n\n// BigCommerce APIs surface errors as an RFC-7807-ish envelope:\n// `{ title, detail, errors: { <field>: <message> } }`. We prefer the server's\n// own prose over anything we could invent, so callers show the API's reason\n// verbatim when it's available.\nconst apiErrorBodySchema = z.object({\n title: z.string().optional(),\n detail: z.string().optional(),\n errors: z.record(z.string(), z.string()).optional(),\n});\n\n// Curated copy for when the response has no usable body. Keyed by status class,\n// not exact code, so any 4xx/5xx we don't specifically handle still reads well.\nconst FALLBACK_CLIENT_ERROR =\n 'The request was rejected. Check your input — your access token may be missing a required scope, or the resource may not exist.';\nconst FALLBACK_SERVER_ERROR =\n 'Something went wrong on our end. Please try again. If the issue persists, contact support.';\n\n// Pulls a human-readable message out of a parsed API error body, preferring the\n// most specific prose the server gave us: its `detail`, then `title`, enriched\n// with any field-level `errors`. Returns undefined when the body doesn't match\n// the envelope (empty, HTML, plain text, or already-consumed).\nexport function extractApiErrorMessage(body: unknown): string | undefined {\n const parsed = apiErrorBodySchema.safeParse(body);\n\n if (!parsed.success) return undefined;\n\n const { title, detail, errors } = parsed.data;\n const fieldErrors =\n errors && Object.keys(errors).length > 0\n ? Object.entries(errors)\n .map(([field, message]) => `${field}: ${message}`)\n .join('; ')\n : undefined;\n\n const headline = detail ?? title;\n\n if (headline && fieldErrors) return `${headline} (${fieldErrors})`;\n\n return headline ?? fieldErrors;\n}\n\n// Turns a non-OK `Response` into a readable error to throw. Reads the body once\n// (safely — a malformed or empty body never throws) and prefers the API's own\n// message; otherwise it falls back to curated copy for the status class.\n//\n// The 4xx/5xx split decides the *type*, which the top-level handler in\n// `index.ts` keys off: a 4xx is a clear, user-actionable response, so it throws\n// `UserActionableError` and the handler drops the \"share your Correlation ID\n// with support\" bug-report framing; a 5xx is a server-side failure worth\n// escalating, so it stays a plain `Error` and keeps that framing.\n//\n// Returns the error rather than throwing so call sites read\n// `throw await httpError(response, 'Failed to fetch projects')` and TypeScript\n// still sees the throw for control-flow narrowing.\nexport async function httpError(response: Response, action: string): Promise<Error> {\n const body: unknown = await response.json().catch(() => null);\n const isServerError = response.status >= 500;\n const detail =\n extractApiErrorMessage(body) ?? (isServerError ? FALLBACK_SERVER_ERROR : FALLBACK_CLIENT_ERROR);\n const message = `${action}: ${detail}`;\n\n return isServerError ? new Error(message) : new UserActionableError(message);\n}\n","import { execa } from 'execa';\n\ninterface ClipboardCommand {\n command: string;\n args: string[];\n}\n\n// Resolve the platform-native clipboard utility. Returns null when we don't\n// know how to reach the clipboard on this platform, so callers can fall back to\n// simply printing the value.\nfunction clipboardCommand(): ClipboardCommand | null {\n switch (process.platform) {\n case 'darwin':\n return { command: 'pbcopy', args: [] };\n\n case 'win32':\n return { command: 'clip', args: [] };\n\n case 'linux':\n // Wayland sessions expose wl-copy; X11 sessions typically ship xclip.\n return process.env.WAYLAND_DISPLAY\n ? { command: 'wl-copy', args: [] }\n : { command: 'xclip', args: ['-selection', 'clipboard'] };\n\n default:\n return null;\n }\n}\n\n// Best-effort copy of `text` to the system clipboard. Never throws — returns\n// `true` on success and `false` when the clipboard is unreachable (unknown\n// platform, missing utility, spawn failure). Callers must always print the\n// value as a fallback so the flow works even when the copy fails.\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const clipboard = clipboardCommand();\n\n if (!clipboard) {\n return false;\n }\n\n try {\n await execa(clipboard.command, clipboard.args, { input: text });\n\n return true;\n } catch {\n return false;\n }\n}\n","import { z } from 'zod';\n\nimport { assertAuthorized } from './auth-errors';\nimport { UserActionableError } from './errors';\nimport { httpError } from './http-errors';\nimport { getTelemetry } from './telemetry';\n\nexport class InfrastructureProjectValidationError extends UserActionableError {\n constructor(message: string) {\n super(message);\n this.name = 'InfrastructureProjectValidationError';\n }\n}\n\nconst fetchProjectsSchema = z.object({\n data: z.array(\n z.object({\n uuid: z.string(),\n name: z.string(),\n deployment_hostnames: z.array(z.string()),\n }),\n ),\n});\n\nexport interface ProjectListItem {\n uuid: string;\n name: string;\n deployment_hostnames: string[];\n}\n\nfunction projectsUrl(storeHash: string, apiHost: string) {\n return `https://${apiHost}/stores/${storeHash}/v3/infrastructure/projects`;\n}\n\nfunction authHeaders(accessToken: string) {\n return {\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n };\n}\n\nexport async function hasProjectsAccess(\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<boolean> {\n const response = await fetch(projectsUrl(storeHash, apiHost), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n assertAuthorized(response);\n\n if (response.status === 200) return true;\n if (response.status === 403) return false;\n\n throw await httpError(response, 'Failed to check project access');\n}\n\nexport async function fetchProjects(\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<ProjectListItem[]> {\n const response = await fetch(projectsUrl(storeHash, apiHost), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n assertAuthorized(response);\n\n if (response.status === 403) {\n throw new UserActionableError(\n 'Infrastructure Projects API not enabled. If you are part of the beta, contact support@bigcommerce.com to enable it.',\n );\n }\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch projects');\n }\n\n const res: unknown = await response.json();\n\n const { data } = fetchProjectsSchema.parse(res);\n\n return data;\n}\n\nconst createProjectSchema = z.object({\n data: z.object({\n uuid: z.string(),\n name: z.string(),\n date_created: z.coerce.date(),\n date_modified: z.coerce.date(),\n }),\n});\n\nexport interface CreateProjectResult {\n uuid: string;\n name: string;\n date_created: Date;\n date_modified: Date;\n}\n\nconst validationErrorBodySchema = z.object({\n title: z.string().optional(),\n detail: z.string().optional(),\n errors: z.record(z.string(), z.string()).optional(),\n});\n\nfunction extractValidationMessage(body: unknown): string | null {\n const parsed = validationErrorBodySchema.safeParse(body);\n\n if (!parsed.success) return null;\n\n const { title, detail, errors } = parsed.data;\n\n if (errors && Object.keys(errors).length > 0) {\n return Object.values(errors).join('; ');\n }\n\n return detail ?? title ?? null;\n}\n\nexport async function createProject(\n name: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<CreateProjectResult> {\n const response = await fetch(projectsUrl(storeHash, apiHost), {\n method: 'POST',\n headers: {\n ...authHeaders(accessToken),\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ name }),\n });\n\n assertAuthorized(response);\n\n if (response.status === 400 || response.status === 422) {\n const body: unknown = await response.json().catch(() => null);\n const fallback =\n response.status === 422\n ? \"The project name you entered doesn't meet the requirements. It must be 3–32 characters long and use only letters, numbers, hyphens (-), underscores (_), and periods (.)\"\n : response.statusText;\n const message = extractValidationMessage(body) ?? fallback;\n\n throw new InfrastructureProjectValidationError(message);\n }\n\n // The API returns 403 (or 404 when the flag is off) if the store isn't in the\n // Infrastructure Projects beta; both mean \"not enabled for this store\".\n if (response.status === 403 || response.status === 404) {\n throw new UserActionableError(\n 'Infrastructure Projects API not enabled. If you are part of the beta, contact support@bigcommerce.com to enable it.',\n );\n }\n\n // TODO: TRAC-592 - remove this check once the API returns proper 400/422 with validation messages for duplicate names instead of 502\n if (response.status === 502) {\n throw new Error('Failed to create project, is the name already in use?');\n }\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to create project');\n }\n\n const res: unknown = await response.json();\n\n const { data } = createProjectSchema.parse(res);\n\n return data;\n}\n\nexport async function deleteProject(\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<void> {\n const response = await fetch(`${projectsUrl(storeHash, apiHost)}/${projectUuid}`, {\n method: 'DELETE',\n headers: authHeaders(accessToken),\n });\n\n assertAuthorized(response);\n\n if (response.status === 403) {\n throw new UserActionableError(\n 'Infrastructure Projects API not enabled. If you are part of the beta, contact support@bigcommerce.com to enable it.',\n );\n }\n\n if (response.status === 404) {\n throw new UserActionableError(`Project ${projectUuid} not found.`);\n }\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to delete project');\n }\n}\n","import Conf from 'conf';\nimport { join } from 'path';\n\nexport interface ProjectConfigSchema {\n projectUuid: string;\n // Reserved for future use\n framework: 'catalyst';\n storeHash?: string;\n accessToken?: string;\n apiHost?: string;\n // Persistent deployment environment variables (KEY -> VALUE). Every entry is\n // sent to the deployment as a `secret` by `catalyst deploy`. Managed via the\n // `catalyst env` commands. Lives here (gitignored .bigcommerce/project.json)\n // so users don't have to re-pass `--secret` on every deploy.\n env?: Record<string, string>;\n}\n\n// `cwd` defaults to the process working directory — the project the user is\n// currently in. `catalyst create` passes the freshly-scaffolded project dir\n// explicitly, since that project isn't the cwd at the time it's seeded.\nexport function getProjectConfig(cwd: string = process.cwd()) {\n return new Conf<ProjectConfigSchema>({\n cwd: join(cwd, '.bigcommerce'),\n projectSuffix: '',\n configName: 'project',\n schema: {\n projectUuid: { type: 'string', format: 'uuid' },\n framework: {\n type: 'string',\n enum: ['catalyst'],\n default: 'catalyst',\n },\n storeHash: { type: 'string' },\n accessToken: { type: 'string' },\n apiHost: { type: 'string' },\n env: {\n type: 'object',\n additionalProperties: { type: 'string' },\n default: {},\n },\n },\n });\n}\n","import { Option } from 'commander';\nimport type Conf from 'conf';\n\nimport { DEFAULT_LOGIN_URL } from './auth';\nimport { getProjectConfig, ProjectConfigSchema } from './project-config';\n\nexport const DEFAULT_API_HOST = 'api.bigcommerce.com';\n\nexport const storeHashOption = () =>\n new Option(\n '--store-hash <hash>',\n 'BigCommerce store hash. Can be found in the URL of your store Control Panel. Read from .bigcommerce/project.json or .env when not provided.',\n ).env('CATALYST_STORE_HASH');\n\nexport const accessTokenOption = () =>\n new Option(\n '--access-token <token>',\n 'BigCommerce access token. Can be found after creating a store-level API account. Read from .bigcommerce/project.json or .env when not provided.',\n ).env('CATALYST_ACCESS_TOKEN');\n\nexport const apiHostOption = () =>\n new Option(\n '--api-host <host>',\n 'BigCommerce API host. Read from .bigcommerce/project.json or CATALYST_API_HOST when not provided. Defaults to api.bigcommerce.com.',\n )\n .env('CATALYST_API_HOST')\n .hideHelp();\n\nexport const loginUrlOption = () =>\n new Option('--login-url <url>', 'BigCommerce login URL.')\n .env('BIGCOMMERCE_LOGIN_URL')\n .default(DEFAULT_LOGIN_URL)\n .hideHelp();\n\nexport const projectUuidOption = () =>\n new Option(\n '--project-uuid <uuid>',\n 'BigCommerce infrastructure project UUID. Read from .bigcommerce/project.json or .env when not provided.',\n ).env('CATALYST_PROJECT_UUID');\n\nexport const envPathOption = () =>\n new Option(\n '--env-path <path>',\n 'Path to an environment file to load for the build (relative to the current working directory). When omitted, .env.local and .env are auto-loaded from the current directory. Other commands never load env files.',\n );\n\nexport const resolveProjectUuid = (options: { projectUuid?: string }) => {\n const config = getProjectConfig();\n const projectUuid = options.projectUuid ?? config.get('projectUuid');\n\n if (!projectUuid) {\n throw new Error(\n 'Project UUID is required. Please run either `catalyst projects link` or `catalyst projects create` or this command again with --project-uuid <uuid>.',\n );\n }\n\n return projectUuid;\n};\n\nexport const resolveApiHost = (\n options: { apiHost?: string },\n config: Conf<ProjectConfigSchema>,\n): string => options.apiHost ?? config.get('apiHost') ?? DEFAULT_API_HOST;\n","import { Command, InvalidArgumentError, Option } from 'commander';\nimport { execa } from 'execa';\nimport { copyFile, cp, rm, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { valid as validSemver } from 'semver';\n\nimport { loadBuildEnv } from '../lib/build-env';\nimport { reconcileOpenNextVersion } from '../lib/commerce-hosting';\nimport { detectProjectPackageManager } from '../lib/detect-package-manager';\nimport { getModuleCliPath } from '../lib/get-module-cli-path';\nimport { installDependencies } from '../lib/install-dependencies';\nimport { consola } from '../lib/logger';\nimport { getProjectConfig } from '../lib/project-config';\nimport { getProjectState } from '../lib/project-state';\nimport { assertRequiredBuildEnv } from '../lib/required-build-env';\nimport { envPathOption } from '../lib/shared-options';\nimport { getWranglerConfig } from '../lib/wrangler-config';\n\nexport const WRANGLER_VERSION = '4.128.0';\n\n// npm dist-tags (e.g. latest, beta) aren't valid semver, so they're allowed\n// through a narrow character allowlist. This also guards the value before\n// it's interpolated into the `wrangler@<version>` spec passed to `pnpm dlx`,\n// rejecting anything that could smuggle extra args or shell metacharacters in.\nconst DIST_TAG_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;\n\nexport const parseWranglerVersion = (value: string): string => {\n if (!validSemver(value) && !DIST_TAG_PATTERN.test(value)) {\n throw new InvalidArgumentError(\n `\"${value}\" is not a valid Wrangler version or dist-tag (e.g. 4.90.0 or latest).`,\n );\n }\n\n return value;\n};\n\nexport async function buildCatalystProject(\n projectUuid: string,\n wranglerVersion: string = WRANGLER_VERSION,\n): Promise<void> {\n // Fail fast with an actionable message if the vars the build reads aren't\n // loaded — otherwise the missing values surface as a raw stack trace deep in\n // the OpenNext/Next.js prerender.\n assertRequiredBuildEnv();\n\n const coreDir = process.cwd();\n\n // The build invokes the project's own adapter, so offer to move a stale pin\n // before compiling against it. Reinstall when it moves.\n const projectPackageManager = await detectProjectPackageManager(coreDir);\n\n if (await reconcileOpenNextVersion(coreDir, projectPackageManager, { canUpgrade: true })) {\n await installDependencies(coreDir, projectPackageManager);\n }\n\n const openNextOutDir = join(coreDir, '.open-next');\n const bigcommerceDistDir = join(coreDir, '.bigcommerce', 'dist');\n\n consola.start('Generating GraphQL types...');\n\n await execa('node', [join(coreDir, 'scripts', 'generate.cjs')], {\n stdio: 'inherit',\n cwd: coreDir,\n });\n\n consola.success('GraphQL types generated');\n\n const wranglerConfig = getWranglerConfig(projectUuid);\n\n // Wrangler's --outdir writes alongside existing files instead of replacing\n // the directory. Stale artifacts (e.g. wasm modules named by an older\n // Wrangler version) end up in the bundle and break the Cloudflare upload.\n await rm(bigcommerceDistDir, { recursive: true, force: true });\n\n consola.start('Copying templates...');\n\n await copyFile(\n join(getModuleCliPath(), 'templates', 'open-next.config.ts'),\n join(coreDir, '.bigcommerce', 'open-next.config.ts'),\n );\n await writeFile(\n join(coreDir, '.bigcommerce', 'wrangler.jsonc'),\n JSON.stringify(wranglerConfig, null, 2),\n );\n\n consola.success('Templates copied');\n\n consola.start('Building project...');\n\n await execa(\n 'pnpm',\n [\n 'exec',\n 'opennextjs-cloudflare',\n 'build',\n '--skipWranglerConfigCheck',\n '--openNextConfigPath',\n join(coreDir, '.bigcommerce', 'open-next.config.ts'),\n ],\n {\n stdout: ['pipe', 'inherit'],\n cwd: coreDir,\n },\n );\n\n // Workers Assets serves `/_next/static/*` directly, bypassing the Next.js\n // server that would normally set the immutable Cache-Control on it. Its\n // default is `max-age=0, must-revalidate`, so browsers revalidate every\n // hashed asset on every repeat view. `_headers` overrides that, and has to\n // live inside the assets directory — written after the OpenNext build because\n // that build regenerates the directory, and before the Wrangler dry-run so\n // Wrangler validates it.\n await copyFile(\n join(getModuleCliPath(), 'templates', 'public_headers'),\n join(openNextOutDir, 'assets', '_headers'),\n );\n\n await execa(\n 'pnpm',\n [\n 'dlx',\n `wrangler@${wranglerVersion}`,\n 'deploy',\n '--config',\n join(coreDir, '.bigcommerce', 'wrangler.jsonc'),\n '--keep-vars',\n '--outdir',\n bigcommerceDistDir,\n '--dry-run',\n ],\n {\n stdout: ['pipe', 'inherit'],\n cwd: coreDir,\n },\n );\n\n consola.success('Project built');\n\n await cp(join(openNextOutDir, 'assets'), join(bigcommerceDistDir, 'assets'), {\n recursive: true,\n force: true,\n });\n}\n\nexport const build = new Command('build')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Build your Catalyst project using the OpenNext/Cloudflare build pipeline. Also runs a Wrangler dry-run to generate deployment artifacts.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n $ catalyst build\n\n # Include project UUID\n $ catalyst build --project-uuid <UUID>\n\n # Build with a specific Wrangler version\n $ catalyst build --wrangler-version 4.24.3`,\n )\n .addOption(\n new Option(\n '--project-uuid <uuid>',\n 'Project UUID to be included in the deployment configuration.',\n ).env('CATALYST_PROJECT_UUID'),\n )\n .addOption(\n new Option(\n '--wrangler-version <version>',\n `Wrangler version or dist-tag to build with. Defaults to ${WRANGLER_VERSION}.`,\n ).argParser(parseWranglerVersion),\n )\n .addOption(envPathOption())\n .action(async (options) => {\n // The build reads storefront env vars (BIGCOMMERCE_*). Load them from the\n // env file(s) before building so both the build and any pre-build checks\n // see them.\n loadBuildEnv({ envPath: options.envPath });\n\n // Project must be transformed (middleware swapped in, OpenNext dep installed)\n // before the OpenNext build pipeline can run. If it isn't, fall through to\n // `next build` so this command works for self-hosted Catalyst projects too.\n const state = getProjectState();\n\n if (!state.isTransformed) {\n consola.info('Project is not set up for Commerce Hosting — running `next build`.');\n consola.info('To deploy to Commerce Hosting, run `catalyst deploy`.');\n\n // `next build` reads the same storefront env vars; fail fast with an\n // actionable message here too, since this path doesn't go through\n // buildCatalystProject where the check normally runs.\n assertRequiredBuildEnv();\n\n await execa('pnpm', ['exec', 'next', 'build'], {\n stdio: 'inherit',\n cwd: process.cwd(),\n });\n\n return;\n }\n\n const config = getProjectConfig();\n const projectUuid = options.projectUuid ?? config.get('projectUuid');\n\n if (!projectUuid) {\n throw new Error(\n 'Project UUID is required. Please run `catalyst projects create` or `catalyst projects link` or this command again with --project-uuid <uuid>.',\n );\n }\n\n await buildCatalystProject(projectUuid, options.wranglerVersion);\n });\n","import { colorize } from 'consola/utils';\nimport { config } from 'dotenv';\nimport { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { UserActionableError } from './errors';\nimport { consola } from './logger';\n\n// Conventional env files auto-loaded (in precedence order) for the build when\n// `--env-path` isn't given. `.env.local` wins over `.env`, and neither\n// overrides values already present in the real environment — matching Next.js\n// precedence (process.env > .env.local > .env).\nconst AUTO_ENV_FILES = ['.env.local', '.env'] as const;\n\ninterface LoadBuildEnvOptions {\n // Explicit env file passed via `--env-path`. When set, only this file is\n // loaded (and it overrides existing values); when unset, the conventional\n // files above are auto-loaded instead.\n envPath?: string;\n // Directory the paths are resolved against. Defaults to the current working\n // directory; injectable for tests.\n cwd?: string;\n}\n\n// Loads storefront environment variables into `process.env` for the\n// build/deploy pipeline so the spawned build (and the checks that run before\n// it) can see them. This is intentionally scoped to `build` and `deploy`: no\n// other command loads env files, so running the CLI can't be surprised by a\n// stray `.env.local` on disk.\nexport function loadBuildEnv({ envPath, cwd = process.cwd() }: LoadBuildEnvOptions): void {\n if (envPath !== undefined) {\n const envFilePath = resolve(cwd, envPath);\n const result = config({ path: envFilePath, override: true });\n\n if (result.error) {\n const errCode =\n 'code' in result.error && typeof result.error.code === 'string'\n ? result.error.code\n : undefined;\n const message =\n errCode === 'ENOENT'\n ? `Env file not found: ${envFilePath}`\n : `Failed to load --env-path ${envPath}: ${result.error.message}`;\n\n throw new UserActionableError(message);\n }\n\n consola.log(colorize('cyanBright', `Loaded environment variables from ${envFilePath}\\n`));\n\n return;\n }\n\n // Auto-load the conventional files. `.env.local` is loaded first so it takes\n // precedence over `.env`; `override: false` means the real environment always\n // wins over both. Missing files are expected and ignored.\n const loaded = AUTO_ENV_FILES.filter((file) => {\n const envFilePath = resolve(cwd, file);\n\n if (!existsSync(envFilePath)) {\n return false;\n }\n\n return !config({ path: envFilePath, override: false }).error;\n });\n\n if (loaded.length > 0) {\n consola.log(colorize('cyanBright', `Loaded environment variables from ${loaded.join(', ')}\\n`));\n }\n}\n","import { confirm, input, select, Separator } from '@inquirer/prompts';\nimport { colorize } from 'consola/utils';\nimport { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { minVersion, satisfies, lt as semverLt, validRange } from 'semver';\nimport { z } from 'zod';\n\nimport type { PackageManager } from './detect-package-manager';\nimport { consola } from './logger';\nimport {\n createProject,\n fetchProjects,\n InfrastructureProjectValidationError,\n type ProjectListItem,\n} from './project';\nimport { sortPackageJsonFields } from './sort-package-json';\n\n// Exported so `cloudflare-context-symbol.spec.ts` can assert the version its\n// symbol-key assumption was verified against. Keep it exact: a range would\n// admit versions that key was never checked against, and that failure is silent\n// (null context, so every native-hosted store degrades to an in-process cache).\n//\n// This is what new projects are pinned to, not a floor existing ones are held\n// at -- see `reconcileOpenNextVersion`.\nexport const OPENNEXT_CLOUDFLARE_VERSION = '1.20.6';\n\n// The `next` peer range OPENNEXT_CLOUDFLARE_VERSION declares. Update both\n// together, from the new adapter's `peerDependencies.next`.\nexport const OPENNEXT_REQUIRED_NEXT_RANGE = '>=15.5.24 <16 || >=16.3.3';\n\nconst corePackageJsonSchema = z.looseObject({\n dependencies: z.record(z.string(), z.string()).optional(),\n});\n\n// Loose on purpose: the point is to carry unknown keys through untouched, so\n// this only asserts the file holds an object at all.\nconst projectJsonSchema = z.looseObject({});\n\n// Existing contents of `.bigcommerce/project.json`, or an empty object if it is\n// absent, unreadable, or not a JSON object. A corrupt file shouldn't fail setup\n// -- the keys this helper writes are enough to rebuild a working project.\nconst readProjectJson = (path: string): Record<string, unknown> => {\n if (!existsSync(path)) return {};\n\n try {\n const parsed = projectJsonSchema.safeParse(JSON.parse(readFileSync(path, 'utf-8')));\n\n return parsed.success ? parsed.data : {};\n } catch {\n return {};\n }\n};\n\nconst writeJson = (path: string, value: unknown) => {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(value, null, 2)}\\n`);\n};\n\nconst convertProxyToMiddleware = (projectDir: string) => {\n const proxyPath = join(projectDir, 'proxy.ts');\n const middlewarePath = join(projectDir, 'middleware.ts');\n\n if (!existsSync(proxyPath)) return;\n\n const contents = readFileSync(proxyPath, 'utf-8')\n .replace('export const proxy', 'export const middleware')\n .replace('export const config = {', \"export const config = {\\n runtime: 'experimental-edge',\");\n\n writeFileSync(middlewarePath, contents);\n unlinkSync(proxyPath);\n};\n\n// The default `instrumentation.ts` registers `@vercel/otel`, whose node\n// build OpenNext bundles into the worker chunk; workerd then throws on cold\n// start with \"Failed to prepare server\". A Vercel-deploying user may have\n// customized the hook though, so we prompt before removing it (and only drop\n// `@vercel/otel` if the user agrees — their customization probably imports it).\n// In non-TTY contexts (CI deploys, scripts), skip the cleanup with a warning so\n// no customization is silently wiped. Exported because callers run this on\n// already-transformed projects too, where `setupCommerceHosting` would\n// short-circuit.\nexport const cleanupCloudflareIncompatibilities = async (projectDir: string) => {\n const instrumentationPath = join(projectDir, 'instrumentation.ts');\n\n if (!existsSync(instrumentationPath)) return;\n\n if (!process.stdin.isTTY) {\n consola.warn(\n 'instrumentation.ts is present and may be incompatible with the Cloudflare Workers ' +\n 'bundle (the default @vercel/otel scaffolding throws at cold start under workerd). ' +\n 'Skipping automatic cleanup in non-interactive mode — re-run interactively to remove it, ' +\n 'or delete/gate it manually.',\n );\n\n return;\n }\n\n const shouldRemove = await confirm({\n message:\n 'Catalyst found instrumentation.ts, which is incompatible with the Cloudflare Workers ' +\n 'bundle when it uses @vercel/otel (causes \"Failed to prepare server\" at cold start).\\n' +\n 'Remove it and drop @vercel/otel from package.json? (required for native hosting)',\n default: true,\n });\n\n if (!shouldRemove) {\n consola.info(\n 'Leaving instrumentation.ts in place. The Cloudflare worker will continue to log ' +\n '\"Failed to prepare server\" at cold start until this is resolved manually.',\n );\n\n return;\n }\n\n unlinkSync(instrumentationPath);\n consola.info('Removed instrumentation.ts (incompatible with Cloudflare Workers).');\n\n const corePackageJsonPath = join(projectDir, 'package.json');\n\n if (existsSync(corePackageJsonPath)) {\n const pkg = corePackageJsonSchema.parse(JSON.parse(readFileSync(corePackageJsonPath, 'utf-8')));\n\n if (pkg.dependencies && '@vercel/otel' in pkg.dependencies) {\n const { '@vercel/otel': _removedVercelOtel, ...preservedDeps } = pkg.dependencies;\n\n pkg.dependencies = preservedDeps;\n writeJson(corePackageJsonPath, sortPackageJsonFields(pkg));\n consola.info('Dropped @vercel/otel from package.json.');\n }\n }\n};\n\n// The adapter pin lives in the project's own package.json, and `deploy` skips\n// `setupCommerceHosting` once transformed, so a CLI bump never reaches an\n// existing project by itself. `catalyst upgrade` can't move it either: the pin\n// is injected, so it is absent from the upstream tree and no merge ever sees it\n// (same reason `findStaleCli` checks the CLI's own pin out-of-band).\nexport const reconcileOpenNextVersion = async (\n projectDir: string,\n packageManager: PackageManager,\n { canUpgrade }: { canUpgrade: boolean },\n): Promise<boolean> => {\n const corePackageJsonPath = join(projectDir, 'package.json');\n\n if (!existsSync(corePackageJsonPath)) return false;\n\n const pkg = corePackageJsonSchema.parse(JSON.parse(readFileSync(corePackageJsonPath, 'utf-8')));\n const range = pkg.dependencies?.['@opennextjs/cloudflare'];\n\n // Not a Commerce Hosting project; adding the dep is setup's job.\n if (range === undefined) return false;\n\n // Tarball, git URL, or `link:` -- minVersion() throws on these.\n if (!validRange(range)) return false;\n\n // Already admits the target; their next install picks it up.\n if (satisfies(OPENNEXT_CLOUDFLARE_VERSION, range)) return false;\n\n const current = minVersion(range)?.version;\n\n // Only nudge a project that is behind; downgrading one ahead would be wrong.\n if (current === undefined || !semverLt(current, OPENNEXT_CLOUDFLARE_VERSION)) return false;\n\n const manualStep = `\\`${packageManager} add @opennextjs/cloudflare@${OPENNEXT_CLOUDFLARE_VERSION}\\``;\n const behind = `This project pins @opennextjs/cloudflare ${current}, but this CLI targets ${OPENNEXT_CLOUDFLARE_VERSION}.`;\n\n // Bumping past what the project's Next supports would leave an unsupported\n // dependency set, so don't offer an upgrade that can't work.\n const nextRange = pkg.dependencies?.next;\n const nextVersion =\n nextRange !== undefined && validRange(nextRange) ? minVersion(nextRange) : null;\n\n if (nextVersion !== null && !satisfies(nextVersion.version, OPENNEXT_REQUIRED_NEXT_RANGE)) {\n consola.warn(\n `${behind} That release needs Next.js ${OPENNEXT_REQUIRED_NEXT_RANGE}, but this project ` +\n `is on ${nextVersion.version}. Run \\`catalyst upgrade\\` to move core and Next first, ` +\n 'then re-run the deploy to pick up the adapter.',\n );\n\n return false;\n }\n\n // `--prebuilt` uploads an existing bundle, never rebuilt against a new adapter.\n if (!canUpgrade) {\n consola.warn(\n `${behind} The deploy will use the existing build output. Re-run without \\`--prebuilt\\`, ` +\n `or update it with ${manualStep}, to pick up adapter fixes released since then.`,\n );\n\n return false;\n }\n\n // Never rewrite deps unattended: pnpm treats the lockfile as frozen in CI, so\n // the install that has to follow would fail the deploy.\n if (!process.stdin.isTTY) {\n consola.warn(\n `${behind} Skipping the upgrade prompt in a non-interactive environment. Update it with ` +\n `${manualStep} and commit the lockfile to pick up adapter fixes released since then.`,\n );\n\n return false;\n }\n\n const shouldUpgrade = await confirm({\n message:\n `${behind} Adapter fixes released since then are not applied. ` +\n `Update it to ${OPENNEXT_CLOUDFLARE_VERSION} and reinstall now?`,\n default: true,\n });\n\n if (!shouldUpgrade) {\n consola.info(`Keeping @opennextjs/cloudflare ${current}. Update it later with ${manualStep}.`);\n\n return false;\n }\n\n pkg.dependencies = {\n ...pkg.dependencies,\n '@opennextjs/cloudflare': OPENNEXT_CLOUDFLARE_VERSION,\n };\n\n writeJson(corePackageJsonPath, sortPackageJsonFields(pkg));\n consola.info(`Updated @opennextjs/cloudflare to ${OPENNEXT_CLOUDFLARE_VERSION}.`);\n\n return true;\n};\n\nexport const setupCommerceHosting = async ({\n projectDir,\n projectUuid,\n storeHash,\n accessToken,\n}: {\n projectDir: string;\n projectUuid: string;\n storeHash?: string;\n accessToken?: string;\n}) => {\n await cleanupCloudflareIncompatibilities(projectDir);\n\n const corePackageJsonPath = join(projectDir, 'package.json');\n const pkg = corePackageJsonSchema.parse(JSON.parse(readFileSync(corePackageJsonPath, 'utf-8')));\n\n pkg.dependencies = {\n ...pkg.dependencies,\n '@opennextjs/cloudflare': OPENNEXT_CLOUDFLARE_VERSION,\n };\n\n writeJson(corePackageJsonPath, sortPackageJsonFields(pkg));\n\n const projectJsonPath = join(projectDir, '.bigcommerce', 'project.json');\n\n // Merge rather than rebuild. `catalyst env` stores deployment variables under\n // `env` in this same file and `apiHost` is persisted here too, so\n // constructing a fresh object silently dropped both. Losing `env` is the\n // costly one: those entries are sent as secrets on every `catalyst deploy`,\n // so a wipe means the next deploy ships a worker without its storefront\n // credentials, with nothing in the output mentioning env vars. `deploy` and\n // `projects link` both reach this on projects that already hold real values.\n const projectJson: Record<string, unknown> = {\n ...readProjectJson(projectJsonPath),\n projectUuid,\n framework: 'catalyst',\n };\n\n // Absent means \"not supplied on this run\", not \"clear it\" -- linking without\n // credentials must not drop credentials the project already had.\n if (storeHash) projectJson.storeHash = storeHash;\n if (accessToken) projectJson.accessToken = accessToken;\n\n writeJson(projectJsonPath, projectJson);\n\n convertProxyToMiddleware(projectDir);\n};\n\ninterface CommerceHostingApiContext {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n}\n\n// Thrown by `selectOrCreateInfrastructureProject` when the user declines the\n// \"Would you like to create one?\" prompt that surfaces when no projects exist.\n// Callers translate this into a context-appropriate error (e.g. \"Cannot deploy\n// without being linked to a project\").\nexport class NoLinkedProjectError extends Error {\n constructor() {\n super('No infrastructure project linked: user declined to create one.');\n this.name = 'NoLinkedProjectError';\n }\n}\n\nasync function promptForNewProjectName(api: CommerceHostingApiContext): Promise<ProjectListItem> {\n const newProjectName = await input({ message: 'Enter a name for the new project:' });\n\n const data = await createProject(newProjectName, api.storeHash, api.accessToken, api.apiHost);\n\n consola.success(`Project \"${data.name}\" created successfully.`);\n\n // Newly created — provisioning is async, hostnames not registered yet.\n return { uuid: data.uuid, name: data.name, deployment_hostnames: [] };\n}\n\n// Generic \"select an existing project, or create a new one\" prompt — used by\n// `catalyst projects link` and by `catalyst deploy` when its linked project is\n// missing. Distinct from `promptForCommerceHostingProject` which has\n// default-name + auto-create semantics tailored to `catalyst create`.\n//\n// Pass `linkedProjectUuid` to decorate the matching project's label with\n// `[linked]` so the user can see which one is the current selection.\nexport async function selectOrCreateInfrastructureProject(\n api: CommerceHostingApiContext,\n linkedProjectUuid?: string,\n): Promise<ProjectListItem> {\n consola.start('Fetching projects...');\n\n const existingProjects = await fetchProjects(api.storeHash, api.accessToken, api.apiHost);\n\n consola.success('Projects fetched.');\n\n // No existing projects on the store — skip the select prompt and offer\n // creation directly. Declining means we have nothing to link to.\n if (existingProjects.length === 0) {\n const shouldCreate = await confirm({\n message:\n 'There are not any hosting projects that you can link to yet. Would you like to create one?',\n default: true,\n });\n\n if (!shouldCreate) {\n throw new NoLinkedProjectError();\n }\n\n return promptForNewProjectName(api);\n }\n\n const choices = [\n ...existingProjects.map((p) => ({\n name: p.uuid === linkedProjectUuid ? `${p.name} ${colorize('green', '[linked]')}` : p.name,\n value: p.uuid,\n description: p.uuid,\n })),\n {\n name: 'Create a new project',\n value: 'create',\n description: 'Create a new hosting project for this Catalyst storefront.',\n },\n ];\n\n const selected = await select({\n message: 'Select a project or create a new project (Press <enter> to select).',\n choices,\n });\n\n if (selected === 'create') {\n return promptForNewProjectName(api);\n }\n\n const matched = existingProjects.find((p) => p.uuid === selected);\n\n if (!matched) {\n throw new Error(`Selected project ${String(selected)} not found in fetched list.`);\n }\n\n return matched;\n}\n\nexport async function promptForCommerceHostingProject(\n api: CommerceHostingApiContext,\n defaultName: string,\n autoUseDefaultName?: boolean,\n useExistingOnCollision?: boolean,\n): Promise<ProjectListItem> {\n const existingProjects = await fetchProjects(api.storeHash, api.accessToken, api.apiHost);\n const takenNames = existingProjects.map((project) => project.name);\n\n if (autoUseDefaultName) {\n return autoCreateCommerceHostingProject(\n api,\n defaultName,\n existingProjects,\n useExistingOnCollision,\n );\n }\n\n const conflict = existingProjects.find(\n (project) => project.name.toLowerCase() === defaultName.toLowerCase(),\n );\n\n if (!conflict) {\n return autoCreateCommerceHostingProject(\n api,\n defaultName,\n existingProjects,\n useExistingOnCollision,\n );\n }\n\n type Action = 'use-named' | 'select-from-list' | 'create';\n\n const hasOtherProjects = existingProjects.length > 1;\n\n const choices: Array<{ name: string; value: Action }> = [\n { name: `Use \"${conflict.name}\"`, value: 'use-named' },\n ];\n\n if (hasOtherProjects) {\n choices.push({ name: 'Select from my projects', value: 'select-from-list' });\n }\n\n choices.push({ name: 'Create a new project', value: 'create' });\n\n const action = await select<Action>({\n message: hasOtherProjects\n ? `It looks like you already have an existing Commerce Hosting project named \"${conflict.name}\". Would you like to use it, select from your projects, or create a new one?`\n : `It looks like you already have an existing Commerce Hosting project named \"${conflict.name}\". Would you like to use it, or create a new one?`,\n choices,\n });\n\n if (action === 'use-named') {\n consola.success(`Using existing Commerce Hosting project \"${conflict.name}\"`);\n\n return conflict;\n }\n\n if (action === 'create') {\n return promptAndCreateCommerceHostingProject(api, takenNames, defaultName);\n }\n\n const selected = await select<ProjectListItem | 'create-new'>({\n message: 'Which Commerce Hosting project would you like to use?',\n choices: [\n ...existingProjects.map((project) => ({\n name: project.name,\n value: project,\n description: project.uuid,\n })),\n new Separator(),\n { name: 'Create a new project', value: 'create-new' as const },\n ],\n });\n\n if (selected === 'create-new') {\n return promptAndCreateCommerceHostingProject(api, takenNames, defaultName);\n }\n\n consola.success(`Using existing Commerce Hosting project \"${selected.name}\"`);\n\n return selected;\n}\n\nexport async function promptAndCreateCommerceHostingProject(\n api: CommerceHostingApiContext,\n takenNames: readonly string[],\n defaultName?: string,\n): Promise<ProjectListItem> {\n const projectName = await input({\n message: 'What would you like to name your Commerce Hosting project?',\n default: defaultName,\n validate: (value) => {\n const trimmed = value.trim();\n\n if (!trimmed) return 'Project name is required';\n\n const conflict = takenNames.find((taken) => taken.toLowerCase() === trimmed.toLowerCase());\n\n if (conflict) {\n return `A Commerce Hosting project named \"${conflict}\" already exists`;\n }\n\n return true;\n },\n theme: {\n style: {\n help: () =>\n colorize(\n 'dim',\n '(The project that hosts your storefront on Commerce — often matches your folder name.)',\n ),\n },\n },\n });\n\n try {\n const created = await createProject(\n projectName.trim(),\n api.storeHash,\n api.accessToken,\n api.apiHost,\n );\n\n consola.success(`Commerce Hosting project \"${created.name}\" created successfully`);\n\n return { uuid: created.uuid, name: created.name, deployment_hostnames: [] };\n } catch (error) {\n if (error instanceof InfrastructureProjectValidationError) {\n consola.error(error.message);\n\n return promptAndCreateCommerceHostingProject(api, takenNames, defaultName);\n }\n\n throw error;\n }\n}\n\nasync function resolveCollisionChoice(\n existingName: string,\n useExistingOnCollision: boolean | undefined,\n): Promise<boolean> {\n if (useExistingOnCollision === true) return true;\n\n if (!process.stdin.isTTY) return false;\n\n return select<boolean>({\n message: `A Commerce Hosting project named \"${existingName}\" already exists. Use the existing project?`,\n choices: [\n { name: 'Yes', value: true },\n { name: 'No', value: false },\n ],\n });\n}\n\nasync function autoCreateCommerceHostingProject(\n api: CommerceHostingApiContext,\n name: string,\n existingProjects: readonly ProjectListItem[],\n useExistingOnCollision?: boolean,\n): Promise<ProjectListItem> {\n const existing = existingProjects.find(\n (project) => project.name.toLowerCase() === name.toLowerCase(),\n );\n\n if (existing) {\n const shouldUseExisting = await resolveCollisionChoice(existing.name, useExistingOnCollision);\n\n if (shouldUseExisting) {\n consola.success(`Using existing Commerce Hosting project \"${existing.name}\"`);\n\n return existing;\n }\n\n consola.error(\n 'Not reusing the existing project. Re-run with a different --project-name, or pass --use-existing to reuse it.',\n );\n process.exit(1);\n }\n\n try {\n const created = await createProject(name, api.storeHash, api.accessToken, api.apiHost);\n\n consola.success(`Commerce Hosting project \"${created.name}\" created successfully`);\n\n return { uuid: created.uuid, name: created.name, deployment_hostnames: [] };\n } catch (error) {\n if (error instanceof InfrastructureProjectValidationError) {\n consola.error(\n `Failed to create Commerce Hosting project \"${name}\": ${error.message}\\nRe-run with a different --project-name.`,\n );\n process.exit(1);\n }\n\n throw error;\n }\n}\n\n// Orchestrates prompt + file mutations. Callable from `catalyst create --hosting commerce`\n// (eager) and `catalyst deploy` (lazy). Idempotent — safe to re-run.\nexport async function runCommerceHostingSetup({\n api,\n projectDir,\n defaultProjectName,\n autoUseProjectName,\n useExistingOnCollision,\n}: {\n api: CommerceHostingApiContext;\n projectDir: string;\n defaultProjectName: string;\n autoUseProjectName?: boolean;\n useExistingOnCollision?: boolean;\n}): Promise<ProjectListItem> {\n const project = await promptForCommerceHostingProject(\n api,\n defaultProjectName,\n autoUseProjectName,\n useExistingOnCollision,\n );\n\n await setupCommerceHosting({\n projectDir,\n projectUuid: project.uuid,\n storeHash: api.storeHash,\n accessToken: api.accessToken,\n });\n\n return project;\n}\n","// Canonical order for top-level fields in core/package.json. Anything not in\n// this list is appended afterwards in its original position relative to other\n// unknown keys, so we don't drop or reshuffle uncommon fields like `keywords`.\nconst FIELD_ORDER = [\n 'name',\n 'description',\n 'version',\n 'private',\n 'engines',\n 'scripts',\n 'dependencies',\n 'devDependencies',\n] as const;\n\nexport function sortPackageJsonFields<T extends Record<string, unknown>>(pkg: T): T {\n const ordered: Record<string, unknown> = {};\n\n FIELD_ORDER.forEach((field) => {\n if (field in pkg) {\n ordered[field] = pkg[field];\n }\n });\n\n Object.keys(pkg).forEach((key) => {\n if (!(key in ordered)) {\n ordered[key] = pkg[key];\n }\n });\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return ordered as T;\n}\n","import { access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { detectPackageManager as detectFromDir } from 'nypm';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\n// Lockfile -> package manager, in nypm's own check order.\nconst PROJECT_LOCKFILES = [\n ['pnpm-lock.yaml', 'pnpm'],\n ['yarn.lock', 'yarn'],\n ['bun.lock', 'bun'],\n ['bun.lockb', 'bun'],\n ['package-lock.json', 'npm'],\n] as const satisfies ReadonlyArray<readonly [string, PackageManager]>;\n\n// Detect a project's package manager from its lockfile alone, returning null\n// when the directory has none so the caller can decide its own last resort.\n// Unlike detectProjectPackageManager() this never throws — nypm parses\n// package.json to read `packageManager`, which blows up on a manifest left full\n// of merge conflict markers — and it can express \"I don't know\", which nypm\n// can't, since it falls back to npm internally.\nexport const detectLockfileManager = async (dir: string): Promise<PackageManager | null> => {\n const found = await Promise.all(\n PROJECT_LOCKFILES.map(async ([file, manager]) =>\n access(join(dir, file))\n .then(() => manager)\n .catch(() => null),\n ),\n );\n\n return found.find((manager) => manager !== null) ?? null;\n};\n\n// Detect the package manager that INVOKED the CLI (via npx / pnpm dlx / yarn dlx\n// / bunx) by parsing the leading token of npm_config_user_agent, which every\n// manager sets when it spawns a child process. This is deliberately not\n// nypm.detectPackageManager(cwd): that keys off a lockfile in the project, which\n// a freshly extracted project does not have yet.\nexport const detectPackageManager = (): PackageManager => {\n const userAgent = process.env.npm_config_user_agent ?? '';\n const name = userAgent.split(' ')[0]?.split('/')[0];\n\n if (name === 'pnpm' || name === 'yarn' || name === 'bun') {\n return name;\n }\n\n // Some bunx versions omit npm_config_user_agent; fall back to the bun runtime marker.\n if (process.versions.bun) {\n return 'bun';\n }\n\n return 'npm';\n};\n\n// Detect the package manager an EXISTING project uses, from its lockfile or the\n// package.json `packageManager` field. Used by flows that run inside an\n// already-scaffolded project (e.g. `project link`), where a lockfile exists —\n// unlike detectPackageManager(), which infers the INVOKING manager for a freshly\n// extracted project that has no lockfile yet. Falls back to npm, since most\n// users will have it installed, when detection is inconclusive or returns a\n// manager we don't support.\nexport const detectProjectPackageManager = async (projectDir: string): Promise<PackageManager> => {\n const detected = await detectFromDir(projectDir);\n const name = detected?.name;\n\n if (name === 'pnpm' || name === 'yarn' || name === 'bun' || name === 'npm') {\n return name;\n }\n\n return 'npm';\n};\n","/* eslint-disable no-underscore-dangle */\n\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport function getModuleCliPath() {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n return join(__dirname, '..');\n}\n","import { installDependencies as installDeps } from 'nypm';\nimport yoctoSpinner from 'yocto-spinner';\n\nimport type { PackageManager } from './detect-package-manager';\n\n// Restore an env var to a captured previous value, unsetting it when it wasn't\n// set before (a plain assignment can't represent \"absent\").\nconst restoreEnv = (key: string, previous: string | undefined) => {\n if (previous === undefined) {\n Reflect.deleteProperty(process.env, key);\n } else {\n process.env[key] = previous;\n }\n};\n\n// nypm runs the install through tinyexec, which in silent mode drains the\n// child's stdout to completion BEFORE it starts reading stderr. pnpm sends its\n// progress to stdout but floods stderr with Node warnings — on Node 26 the\n// `File descriptor N opened in unmanaged mode` spam alone is thousands of\n// lines. That stderr fills its ~64KB pipe buffer while tinyexec is still busy\n// on stdout, pnpm blocks writing, and the whole install deadlocks (the original\n// \"hangs forever\" bug). These env vars keep the child quiet on stderr so the\n// buffer never fills:\n// - NODE_NO_WARNINGS: drop pnpm/corepack's internal Node warnings (the flood).\n// - COREPACK_ENABLE_DOWNLOAD_PROMPT: never block on corepack's download\n// confirmation (defensive; corepack already defaults this off for the\n// `corepack pnpm` entrypoint, but pin it so no path can stall on stdin).\nconst withQuietInstallEnv = async <T>(run: () => Promise<T>): Promise<T> => {\n const prevNodeNoWarnings = process.env.NODE_NO_WARNINGS;\n const prevDownloadPrompt = process.env.COREPACK_ENABLE_DOWNLOAD_PROMPT;\n\n process.env.NODE_NO_WARNINGS ??= '1';\n process.env.COREPACK_ENABLE_DOWNLOAD_PROMPT ??= '0';\n\n try {\n return await run();\n } finally {\n restoreEnv('NODE_NO_WARNINGS', prevNodeNoWarnings);\n restoreEnv('COREPACK_ENABLE_DOWNLOAD_PROMPT', prevDownloadPrompt);\n }\n};\n\nexport const installDependencies = async (\n projectDir: string,\n packageManager: PackageManager = 'pnpm',\n) => {\n const spinner = yoctoSpinner().start(\n `Installing dependencies with ${packageManager}. This could take a minute...`,\n );\n\n try {\n await withQuietInstallEnv(() => installDeps({ cwd: projectDir, silent: true, packageManager }));\n spinner.success('Dependencies installed successfully.');\n } catch (error) {\n const message = error instanceof Error ? error.message : 'unknown error';\n\n spinner.error(`Failed to install dependencies: ${message}`);\n throw error;\n }\n};\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { z } from 'zod';\n\nconst projectJsonSchema = z.looseObject({\n projectUuid: z.string().optional(),\n});\n\nconst packageJsonSchema = z.looseObject({\n dependencies: z.record(z.string(), z.string()).optional(),\n});\n\nexport interface ProjectState {\n projectUuid: string | undefined;\n hasMiddleware: boolean;\n hasProxy: boolean;\n hasOpenNextDep: boolean;\n\n // Derived signals — `isLinked` reflects intent (UUID registered via\n // `catalyst projects create` or commerce-hosting setup); `isTransformed`\n // reflects on-disk readiness (middleware.ts swapped in, OpenNext dep\n // installed). A deploy needs both, but `catalyst build` only cares about\n // `isTransformed` so it can dispatch to OpenNext vs `next build`.\n isLinked: boolean;\n isTransformed: boolean;\n isFullySetUp: boolean;\n}\n\nconst safeReadJson = (path: string): unknown => {\n try {\n return JSON.parse(readFileSync(path, 'utf-8'));\n } catch {\n return null;\n }\n};\n\n// Read-only inspection of a Catalyst project at `cwd` (typically `core/`).\n// Avoids `getProjectConfig()` deliberately — that would instantiate `Conf`\n// and create `.bigcommerce/` as a side effect.\nexport function getProjectState(cwd: string = process.cwd()): ProjectState {\n const projectJson = projectJsonSchema.safeParse(\n safeReadJson(join(cwd, '.bigcommerce', 'project.json')),\n );\n const projectUuid = projectJson.success ? projectJson.data.projectUuid : undefined;\n\n const hasMiddleware = existsSync(join(cwd, 'middleware.ts'));\n const hasProxy = existsSync(join(cwd, 'proxy.ts'));\n\n const pkgJson = packageJsonSchema.safeParse(safeReadJson(join(cwd, 'package.json')));\n const hasOpenNextDep = pkgJson.success\n ? Boolean(pkgJson.data.dependencies?.['@opennextjs/cloudflare'])\n : false;\n\n const isLinked = Boolean(projectUuid);\n const isTransformed = hasMiddleware && !hasProxy && hasOpenNextDep;\n const isFullySetUp = isLinked && isTransformed;\n\n return {\n projectUuid,\n hasMiddleware,\n hasProxy,\n hasOpenNextDep,\n isLinked,\n isTransformed,\n isFullySetUp,\n };\n}\n","import { UserActionableError } from './errors';\n\n// Env vars the core storefront build genuinely asserts on. Without these the\n// OpenNext/Next.js build fails deep inside prerendering with a raw stack trace:\n// BIGCOMMERCE_CHANNEL_ID is passed straight to createClient() with no fallback,\n// so the client constructor throws \"Client configuration must include a\n// channelId\" immediately; empty storefront token/store hash make Storefront API\n// calls fail; a missing AUTH_SECRET throws \"AUTH_SECRET is not set\" during\n// static generation. These are the values the app reads at build time — see\n// core/client/index.ts and core/auth/anonymous-session.ts.\nexport const REQUIRED_BUILD_ENV_VARS = [\n 'BIGCOMMERCE_STORE_HASH',\n 'BIGCOMMERCE_STOREFRONT_TOKEN',\n 'BIGCOMMERCE_CHANNEL_ID',\n 'AUTH_SECRET',\n] as const;\n\n// A var counts as missing when it's unset or only whitespace — the core reads\n// most of these with a `?? ''` fallback, so an empty value fails just as\n// cryptically as an absent one.\nexport const findMissingBuildEnv = (env: NodeJS.ProcessEnv = process.env): string[] => {\n return REQUIRED_BUILD_ENV_VARS.filter((name) => {\n const value = env[name];\n\n return value === undefined || value.trim() === '';\n });\n};\n\n// Fail fast with a clear, actionable message before we shell out to the build.\n// Naming the missing vars (and pointing at `--env-path`/`.env.local`) turns an\n// \"ugly build error\" into something the user can act on immediately.\nexport const assertRequiredBuildEnv = (env: NodeJS.ProcessEnv = process.env): void => {\n const missing = findMissingBuildEnv(env);\n\n if (missing.length === 0) {\n return;\n }\n\n const missingList = missing.map((name) => ` - ${name}`).join('\\n');\n\n throw new UserActionableError(\n `Missing required environment variable${missing.length === 1 ? '' : 's'} for the build:\\n` +\n `${missingList}\\n\\n` +\n 'These are read by the build itself, so they must be set before it runs. ' +\n 'The build automatically loads `.env.local` and `.env` from the current ' +\n `directory (${process.cwd()}) — add the variables above to one of those ` +\n 'files (`.env.local` takes precedence).\\n' +\n 'To load an env file from a different location, pass `--env-path <path>` ' +\n '(for example `--env-path ../.env.local` when running from a subdirectory).',\n );\n};\n","// The compatibility date, compatibility flags, Durable Object classes,\n// migration tag, and KV namespace binding below are mirrored in Ignition,\n// which builds its own Worker metadata at deploy time\n// (pkg/cloudflare/upload/metadata.go and\n// pkg/cloudflare/upload/migrations/migrations.go). Keep both sides in sync\n// when changing any of them.\n//\n// Note that only the CATALYST_ROUTES_KV *binding name* is shared with\n// Ignition — the namespace id here is a local-only placeholder (see below),\n// while Ignition binds the real per-project namespace it provisioned.\nexport function getCompatibilityDate(now = new Date()): string {\n const date = new Date(now);\n\n // One month behind the current date: recent enough to track Cloudflare\n // runtime behavior (per Cloudflare guidance), buffered enough to avoid\n // brand-new compatibility-date-gated changes. Ignition applies the same\n // offset at deploy time, so the bundle is never built against newer\n // semantics than it runs under.\n date.setUTCMonth(date.getUTCMonth() - 1);\n\n return date.toISOString().slice(0, 10);\n}\n\n// Namespace id for the routing cache KV binding in the *generated* config,\n// which only ever drives local `wrangler dev`/`opennextjs-cloudflare preview`\n// (where Miniflare keys its simulated store under `.wrangler/state/v3/kv`)\n// and the `wrangler deploy --dry-run` bundling step, which never resolves\n// bindings against the Cloudflare API. Ignition overwrites this with the real\n// per-project namespace id when it uploads the Worker.\n//\n// The value is deliberately not a 32-char lowercase hex string — the only\n// shape a real provisioned Cloudflare namespace id can take — so it cannot\n// collide with a production store's cache even if this config were somehow\n// used against the live API. Such a request fails closed with an invalid-id\n// error instead of reading or writing someone's real routing cache.\nconst LOCAL_ROUTES_KV_NAMESPACE_ID = 'catalyst-routes-kv-local';\n\nexport function getWranglerConfig(projectUuid: string) {\n return {\n $schema: 'node_modules/wrangler/config-schema.json',\n main: '../.open-next/worker.js',\n name: `project-${projectUuid}`,\n compatibility_date: getCompatibilityDate(),\n compatibility_flags: ['nodejs_compat', 'global_fetch_strictly_public'],\n observability: {\n enabled: true,\n head_sampling_rate: 0.05,\n logs: {\n enabled: true,\n head_sampling_rate: 1,\n invocation_logs: false,\n },\n },\n assets: {\n directory: '../.open-next/assets',\n binding: 'ASSETS',\n },\n services: [\n {\n binding: 'WORKER_SELF_REFERENCE',\n service: `project-${projectUuid}`,\n },\n ],\n r2_buckets: [\n {\n binding: 'NEXT_INC_CACHE_R2_BUCKET',\n bucket_name: `project-${projectUuid}`,\n },\n ],\n kv_namespaces: [\n {\n binding: 'CATALYST_ROUTES_KV',\n id: LOCAL_ROUTES_KV_NAMESPACE_ID,\n },\n ],\n durable_objects: {\n bindings: [\n {\n name: 'NEXT_CACHE_DO_QUEUE',\n class_name: 'DOQueueHandler',\n },\n {\n name: 'NEXT_TAG_CACHE_DO_SHARDED',\n class_name: 'DOShardedTagCache',\n },\n {\n name: 'NEXT_CACHE_DO_PURGE',\n class_name: 'BucketCachePurge',\n },\n ],\n },\n migrations: [\n {\n tag: 'v1',\n new_sqlite_classes: ['DOQueueHandler', 'DOShardedTagCache', 'BucketCachePurge'],\n },\n ],\n };\n}\n","import { confirm, select } from '@inquirer/prompts';\nimport { Command, InvalidArgumentError, Option } from 'commander';\nimport type Conf from 'conf';\nimport { colorize } from 'consola/utils';\n\nimport { runChannelCheckoutUrlFlow } from '../lib/channel-checkout-url-flow';\nimport { resolveChannel, runChannelSiteUrlFlow } from '../lib/channel-site-flow';\nimport {\n channelPlatformLabel,\n type ChannelSiteDetails,\n checkChannelEligibility,\n deleteChannelCheckoutUrl,\n fetchAvailableChannels,\n findChannelSiteUrl,\n getChannelInit,\n getChannelSite,\n sortChannelsByPlatform,\n updateChannelCheckoutUrl,\n} from '../lib/channels';\nimport { normalizeCheckoutUrl, warnOnCrossDomainCheckout } from '../lib/checkout-url';\nimport { NoLinkedProjectError } from '../lib/commerce-hosting';\nimport { runCreateChannelFlow } from '../lib/create-channel-flow';\nimport { parseEnvAssignment } from '../lib/env-config';\nimport { consola } from '../lib/logger';\nimport { LoginAbortedError, login as runInteractiveLogin } from '../lib/login';\nimport { getProjectConfig, type ProjectConfigSchema } from '../lib/project-config';\nimport { resolveCredentials } from '../lib/resolve-credentials';\nimport {\n accessTokenOption,\n apiHostOption,\n loginUrlOption,\n projectUuidOption,\n resolveApiHost,\n storeHashOption,\n} from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\nimport { writeEnv } from '../lib/write-env';\n\nconst parseChannelId = (value: string): number => {\n const parsed = Number.parseInt(value, 10);\n\n if (Number.isNaN(parsed)) {\n throw new InvalidArgumentError(`\"${value}\" is not a valid channel ID (expected a number).`);\n }\n\n return parsed;\n};\n\n// Adapts the shared normalizer to commander, which formats InvalidArgumentError\n// as an option-level usage error.\nconst parseCheckoutUrl = (value: string): string => {\n try {\n return normalizeCheckoutUrl(value);\n } catch (error) {\n throw new InvalidArgumentError(error instanceof Error ? error.message : String(error));\n }\n};\n\nconst CHECKOUT_URL_NOTES = `\nCheckout is hosted by BigCommerce, so a checkout URL must be a domain you have\npointed at BigCommerce with a certificate provisioned there — not one added with\n\\`catalyst domains add\\`, which only routes traffic to this project.\n\nBigCommerce also requires the checkout URL to share a main domain with the\nchannel's storefront URL, so that sessions carry between the two. This means a\ncustom checkout URL is only possible on a custom storefront domain; channels on\nan auto-generated deployment hostname use the shared checkout domain.`;\n\n// Resolve credentials from flags/env → persisted project config → interactive\n// login (persisting on success). Returns null when the user aborts login.\n// `channel link` is an onboarding command — a fresh clone has neither\n// .env.local nor .bigcommerce/project.json — so it logs the user in like\n// `catalyst projects create`, rather than erroring like the operational commands.\nasync function resolveCredentialsWithLogin(\n options: { storeHash?: string; accessToken?: string; loginUrl: string },\n config: Conf<ProjectConfigSchema>,\n apiHost: string,\n): Promise<{ storeHash: string; accessToken: string } | null> {\n const storeHash = options.storeHash ?? config.get('storeHash');\n const accessToken = options.accessToken ?? config.get('accessToken');\n\n if (storeHash && accessToken) {\n return { storeHash, accessToken };\n }\n\n try {\n const credentials = await runInteractiveLogin(options.loginUrl, apiHost);\n\n config.set('storeHash', credentials.storeHash);\n config.set('accessToken', credentials.accessToken);\n\n return credentials;\n } catch (error) {\n if (error instanceof LoginAbortedError) {\n return null;\n }\n\n throw error;\n }\n}\n\nconst update = new Command('update')\n .configureHelp({ showGlobalOptions: true })\n .description(\"Update a BigCommerce channel's storefront and checkout URLs.\")\n .addHelpText(\n 'after',\n `${CHECKOUT_URL_NOTES}\n\nWith no flags, this updates the storefront URL and prompts for the hostname.\nPass a checkout flag on its own to change only the checkout URL, leaving the\nstorefront URL alone.\n\nExamples:\n # Pick a channel and hostname interactively\n $ catalyst channels update\n\n # Point the storefront at a deployment hostname\n $ catalyst channels update --channel-id 123 --hostname my-storefront.example.com\n\n # Set both at once\n $ catalyst channels update --channel-id 123 --hostname my-storefront.example.com --checkout-url checkout.example.com\n\n # Change only the checkout URL\n $ catalyst channels update --channel-id 123 --checkout-url checkout.example.com\n\n # Fall back to the shared checkout domain\n $ catalyst channels update --channel-id 123 --remove-checkout-url`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .addOption(\n new Option(\n '--channel-id <id>',\n 'Skip the channel prompt and target this channel directly.',\n ).argParser((value: string) => Number(value)),\n )\n .addOption(\n new Option(\n '--hostname <hostname>',\n \"Skip the hostname prompt and use this hostname directly. Must be one of the project's deployment_hostnames.\",\n ),\n )\n .addOption(\n new Option(\n '--checkout-url <url>',\n \"Set the channel's checkout URL. Must share a main domain with the storefront URL.\",\n ).argParser(parseCheckoutUrl),\n )\n .addOption(\n new Option(\n '--remove-checkout-url',\n \"Remove the channel's custom checkout URL so checkout falls back to the shared checkout domain.\",\n ).conflicts('checkoutUrl'),\n )\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n // A checkout flag on its own means \"change only the checkout URL\": going\n // through the site-URL flow would prompt for a hostname the caller never\n // asked to change.\n const touchesCheckout = options.checkoutUrl !== undefined || options.removeCheckoutUrl === true;\n const updatesSiteUrl = options.hostname !== undefined || !touchesCheckout;\n let channelId = options.channelId;\n\n if (updatesSiteUrl) {\n try {\n ({ channelId } = await runChannelSiteUrlFlow({\n storeHash,\n accessToken,\n apiHost,\n projectUuid: options.projectUuid ?? config.get('projectUuid'),\n channelId: options.channelId,\n hostname: options.hostname,\n }));\n } catch (error) {\n if (error instanceof NoLinkedProjectError) {\n consola.info(\n \"When you're ready to create a project, run `catalyst projects create` or re-run `catalyst channels update`.\",\n );\n process.exit(0);\n\n // Unreachable in production; prevents continuation when process.exit is mocked in tests.\n return;\n }\n\n throw error;\n }\n }\n\n if (touchesCheckout) {\n const channel =\n channelId === undefined\n ? await resolveChannel({ storeHash, accessToken, apiHost })\n : { id: channelId, name: undefined };\n const label = channel.name ? `\"${channel.name}\" (${channel.id})` : String(channel.id);\n\n if (options.checkoutUrl !== undefined) {\n const updated = await updateChannelCheckoutUrl(\n channel.id,\n options.checkoutUrl,\n storeHash,\n accessToken,\n apiHost,\n );\n\n consola.success(`Updated channel ${label} checkout URL to ${options.checkoutUrl}.`);\n reportChannelSite(updated);\n await warnOnCrossDomainCheckout(updated, { storeHash, accessToken, apiHost });\n } else {\n await deleteChannelCheckoutUrl(channel.id, storeHash, accessToken, apiHost);\n\n consola.success(\n `Removed the custom checkout URL from channel ${label}. Checkout now uses the shared checkout domain.`,\n );\n\n // The fallback domain belongs to the default channel, so it can't be\n // known before the delete. Re-read the site to show where it landed, and\n // warn if that's a different domain than the storefront.\n const reverted = await getChannelSite(channel.id, storeHash, accessToken, apiHost);\n\n reportChannelSite(reverted);\n await warnOnCrossDomainCheckout(reverted, { storeHash, accessToken, apiHost });\n }\n }\n\n process.exit(0);\n });\n\nconst link = new Command('link')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Link this Catalyst project to a BigCommerce channel and write its credentials to .env.local.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Pick a channel interactively (logs you in if needed)\n $ catalyst channels link\n\n # Non-interactive\n $ catalyst channels link --store-hash <hash> --access-token <token> --channel-id 123\n\n # Append extra environment variables to .env.local\n $ catalyst channels link --channel-id 123 --env MY_FLAG=1`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(loginUrlOption())\n .addOption(\n new Option('--channel-id <id>', 'Link this channel directly, skipping the picker.').argParser(\n parseChannelId,\n ),\n )\n .option(\n '--env <vars...>',\n 'Arbitrary environment variables to set in .env.local. Format: KEY=VALUE (repeatable).',\n )\n .addOption(\n new Option('--cli-api-origin <origin>', 'Catalyst CLI API origin')\n .default('https://cxm-prd.bigcommerceapp.com')\n .hideHelp(),\n )\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n const credentials = await resolveCredentialsWithLogin(options, config, apiHost);\n\n if (!credentials) {\n consola.info(\n 'Login aborted. Re-run `catalyst channels link` when you have your credentials ready.',\n );\n process.exit(0);\n\n return;\n }\n\n const { storeHash, accessToken } = credentials;\n\n await getTelemetry().identify(storeHash);\n\n let channelId = options.channelId;\n let channelName: string | undefined;\n\n if (channelId === undefined) {\n const availableChannels = await fetchAvailableChannels(storeHash, accessToken, apiHost);\n\n if (availableChannels.length === 0) {\n consola.info(\n 'No storefront channels found on this store. Create one with `catalyst create` and try again.',\n );\n process.exit(0);\n\n return;\n }\n\n channelId = await select({\n message: 'Which channel would you like to link?',\n choices: sortChannelsByPlatform(availableChannels).map((c) => ({\n name: c.name,\n value: c.id,\n description: channelPlatformLabel(c.platform),\n })),\n });\n\n channelName = availableChannels.find((c) => c.id === channelId)?.name;\n }\n\n const initData = await getChannelInit(channelId, storeHash, accessToken, options.cliApiOrigin);\n\n const envVars: Record<string, string> = { ...initData.envVars };\n\n // Inline `--env KEY=VALUE` overrides win over the channel-provided values.\n if (options.env) {\n options.env.forEach((entry) => {\n const { key, value } = parseEnvAssignment(entry);\n\n envVars[key] = value;\n });\n }\n\n // Writes .env.local in the current working directory — `channel link`\n // runs from inside `core/`, the same place `dev`/`build`/`deploy` run.\n writeEnv(process.cwd(), envVars);\n\n const label = channelName ? `\"${channelName}\" (${channelId})` : `${channelId}`;\n\n consola.success(\n `Linked to channel ${label} and wrote ${colorize('cyanBright', '.env.local')}.`,\n );\n consola.log(`Next steps:\\n\\n ${colorize('yellow', 'pnpm run dev')}`);\n\n process.exit(0);\n });\n\nconst create = new Command('create')\n .configureHelp({ showGlobalOptions: true })\n .description('Create a new Catalyst storefront channel on your BigCommerce store.')\n .addHelpText(\n 'after',\n `\nExamples:\n # Create a channel interactively (logs you in if needed)\n $ catalyst channels create\n\n # Non-interactive, and link it to this project afterwards\n $ catalyst channels create --name \"My Store\" --locale en --no-sample-data --link\n\n # Add additional storefront languages (max 4)\n $ catalyst channels create --name \"My Store\" --additional-locales es fr`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(loginUrlOption())\n .option('--name <name>', 'Name for the new channel. Skips the name prompt.')\n .option(\n '--locale <locale>',\n 'Default storefront locale (e.g. \"en\"). Skips the default-language prompt.',\n )\n .option(\n '--additional-locales <locales...>',\n 'Additional storefront locales, max 4 (e.g. --additional-locales es fr). Skips the additional-languages prompt.',\n )\n .addOption(new Option('--sample-data', 'Install sample data on the new channel.'))\n .addOption(new Option('--no-sample-data', 'Create the channel without sample data.'))\n .option(\n '--link',\n 'Link the new channel to this project — write its credentials to .env.local without prompting.',\n )\n .addOption(\n new Option('--cli-api-origin <origin>', 'Catalyst CLI API origin')\n .default('https://cxm-prd.bigcommerceapp.com')\n .hideHelp(),\n )\n .action(async (options) => {\n if (options.additionalLocales && options.additionalLocales.length > 4) {\n consola.error('You can only set up to 4 additional locales.');\n process.exit(1);\n\n return;\n }\n\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n const credentials = await resolveCredentialsWithLogin(options, config, apiHost);\n\n if (!credentials) {\n consola.info(\n 'Login aborted. Re-run `catalyst channels create` when you have your credentials ready.',\n );\n process.exit(0);\n\n return;\n }\n\n const { storeHash, accessToken } = credentials;\n\n await getTelemetry().identify(storeHash);\n\n const eligibility = await checkChannelEligibility(storeHash, accessToken, options.cliApiOrigin);\n\n if (!eligibility.eligible) {\n consola.warn(eligibility.message);\n process.exit(0);\n\n return;\n }\n\n const channelData = await runCreateChannelFlow({\n storeHash,\n accessToken,\n apiHost,\n cliApiOrigin: options.cliApiOrigin,\n name: options.name,\n locale: options.locale,\n additionalLocales: options.additionalLocales,\n sampleData: options.sampleData,\n });\n\n consola.success(`Created channel ${channelData.channelId}.`);\n consola.warn(\n 'A preview storefront has been deployed in your BigCommerce control panel. This preview may look different from your local environment as it may be running different code. Additionally, it may take a few minutes for the channel storefront to be accessible.',\n );\n\n // `--link` opts in non-interactively; otherwise ask before touching .env.local.\n const shouldLink = options.link\n ? true\n : await select({\n message: 'Would you like to link this channel to your project?',\n choices: [\n { name: 'Yes', value: true },\n { name: 'No', value: false },\n ],\n });\n\n if (shouldLink) {\n // Same write path as `channel link`: write the channel's credentials to\n // .env.local in the current working directory (where `dev`/`build`/`deploy` run).\n writeEnv(process.cwd(), channelData.envVars);\n\n consola.success(\n `Linked to channel ${channelData.channelId} and wrote ${colorize('cyanBright', '.env.local')}.`,\n );\n consola.log(`Next steps:\\n\\n ${colorize('yellow', 'pnpm run dev')}`);\n }\n\n process.exit(0);\n });\n\nconst CHECKOUT_LABEL_WIDTH = 'Storefront'.length;\n\nconst row = (label: string, value: string) => ` ${label.padEnd(CHECKOUT_LABEL_WIDTH)} ${value}`;\n\n// `primary` is the merchant-facing storefront, `canonical` BigCommerce's own\n// permanent address, `checkout` where hosted checkout lives — easy to conflate\n// when debugging a redirect.\nfunction reportChannelSite(site: ChannelSiteDetails): void {\n const canonical = findChannelSiteUrl(site, 'canonical');\n const checkout = findChannelSiteUrl(site, 'checkout');\n\n consola.log(row('Storefront', findChannelSiteUrl(site, 'primary') ?? site.url));\n\n if (canonical) {\n consola.log(row('Canonical', canonical));\n }\n\n consola.log(row('Checkout', checkout ?? '(none)'));\n\n if (!site.isCheckoutUrlCustomized) {\n consola.info(\n 'This channel has no checkout URL of its own, so checkout uses the default ' +\n \"channel's primary URL.\",\n );\n }\n}\n\ninterface ChannelTargetOptions {\n storeHash?: string;\n accessToken?: string;\n apiHost?: string;\n channelId?: number;\n}\n\n// Resolves credentials and the target channel — the preamble every\n// channel-scoped command below shares.\nasync function resolveChannelTarget(options: ChannelTargetOptions) {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n const channel = await resolveChannel({\n storeHash,\n accessToken,\n apiHost,\n channelId: options.channelId,\n // Read-only: these commands report on a channel, so the picker must not\n // say \"to update\" — the shared default is written for `channels update`.\n message: 'Select a channel.',\n });\n\n return {\n config,\n apiHost,\n storeHash,\n accessToken,\n channel,\n label: channel.name ? `\"${channel.name}\" (${channel.id})` : String(channel.id),\n };\n}\n\nconst info = new Command('info')\n .configureHelp({ showGlobalOptions: true })\n .description(\"Show a channel's site URLs — storefront, canonical and checkout.\")\n .addHelpText(\n 'after',\n `${CHECKOUT_URL_NOTES}\n\nExamples:\n # Pick a channel interactively; the same as bare \\`catalyst channels\\`\n $ catalyst channels info\n\n # Target a channel directly\n $ catalyst channels info --channel-id 123`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(\n new Option(\n '--channel-id <id>',\n 'Skip the channel prompt and target this channel directly.',\n ).argParser(parseChannelId),\n )\n .action(async (options: ChannelTargetOptions) => {\n const { apiHost, storeHash, accessToken, channel, label } = await resolveChannelTarget(options);\n\n consola.start('Fetching channel site...');\n\n const site = await getChannelSite(channel.id, storeHash, accessToken, apiHost);\n\n consola.success(`Channel ${label}:`);\n reportChannelSite(site);\n\n const report = await warnOnCrossDomainCheckout(site, { storeHash, accessToken, apiHost });\n\n // The channel and site are already in hand, so offer to fix it rather than\n // making the user re-run `channels update --checkout-url`.\n //\n // Not offered on a managed zone, where BigCommerce would reject every value\n // (the diagnostic explains why), nor without a TTY, so the command stays\n // scriptable — matching the guards in `commerce-hosting`.\n if (report.crossDomain && report.storefrontOnManagedZone !== true) {\n const suggested = report.suggestion ?? '<domain>';\n\n if (!process.stdin.isTTY) {\n consola.info(\n `Set one with \\`catalyst channels update --channel-id ${channel.id} --checkout-url ${suggested}\\`.`,\n );\n process.exit(0);\n\n return;\n }\n\n const shouldSet = await confirm({\n message: 'Set a checkout URL for this channel now?',\n default: true,\n });\n\n if (shouldSet) {\n await runChannelCheckoutUrlFlow({\n storeHash,\n accessToken,\n apiHost,\n // Already chosen above; don't ask again.\n channelId: channel.id,\n channelName: channel.name,\n storefrontUrl: findChannelSiteUrl(site, 'primary') ?? site.url,\n });\n\n process.exit(0);\n\n return;\n }\n\n consola.info(\n `When you're ready, run \\`catalyst channels update --channel-id ${channel.id} --checkout-url <domain>\\`.`,\n );\n }\n\n process.exit(0);\n });\n\n// Resource commands are plural; the singular form stays as an alias so existing\n// scripts and muscle memory keep working.\nexport const channels = new Command('channels')\n .alias('channel')\n .configureHelp({ showGlobalOptions: true })\n .description('Manage BigCommerce channels.')\n // `info` is the default so bare `catalyst channels` reports the current\n // state, matching how `logs` defaults to `tail`.\n .addCommand(info, { isDefault: true })\n .addCommand(create)\n .addCommand(link)\n .addCommand(update);\n","import { input } from '@inquirer/prompts';\n\nimport { resolveChannel } from './channel-site-flow';\nimport { findChannelSiteUrl, getChannelSite, updateChannelCheckoutUrl } from './channels';\nimport { normalizeCheckoutUrl, suggestCheckoutUrl } from './checkout-url';\nimport { consola } from './logger';\n\nexport interface ChannelCheckoutUrlFlowOptions {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n // Non-interactive overrides. When supplied, the corresponding prompt is\n // skipped.\n channelId?: number;\n url?: string;\n // Set by a caller that already resolved the channel and fetched the site, so\n // the flow neither re-prompts nor re-reads.\n channelName?: string;\n storefrontUrl?: string;\n}\n\n// Prompts for a checkout URL and writes it.\n//\n// Unlike a site URL this can't be derived from the deployment: BigCommerce —\n// not this project's worker — serves checkout, so the domain must already point\n// there with a certificate. Defaults to the `checkout.` subdomain of the\n// storefront, which the same-main-domain rule makes the near-certain answer.\nexport async function runChannelCheckoutUrlFlow(\n options: ChannelCheckoutUrlFlowOptions,\n): Promise<void> {\n const channel =\n options.channelId !== undefined\n ? { id: options.channelId, name: options.channelName }\n : await resolveChannel(options);\n const label = channel.name ? `\"${channel.name}\" (${channel.id})` : String(channel.id);\n\n let storefrontUrl = options.storefrontUrl;\n\n // The storefront URL only feeds the prompt default, so skip the read when the\n // caller already has it.\n if (!storefrontUrl) {\n const site = await getChannelSite(\n channel.id,\n options.storeHash,\n options.accessToken,\n options.apiHost,\n );\n\n storefrontUrl = findChannelSiteUrl(site, 'primary') ?? site.url;\n\n const currentCheckoutUrl = findChannelSiteUrl(site, 'checkout');\n\n consola.info(`Channel ${label} storefront is ${storefrontUrl}.`);\n\n if (currentCheckoutUrl) {\n consola.info(\n `Checkout is currently ${currentCheckoutUrl}${\n site.isCheckoutUrlCustomized ? '' : ', inherited from the default channel'\n }.`,\n );\n }\n }\n\n const answer =\n options.url ??\n (await input({\n message: 'Checkout URL for this channel (must share a main domain with the storefront)',\n default: suggestCheckoutUrl(storefrontUrl),\n }));\n\n const checkoutUrl = normalizeCheckoutUrl(answer);\n\n await updateChannelCheckoutUrl(\n channel.id,\n checkoutUrl,\n options.storeHash,\n options.accessToken,\n options.apiHost,\n );\n\n consola.success(`Updated channel ${label} checkout URL to ${checkoutUrl}.`);\n}\n","import { select } from '@inquirer/prompts';\n\nimport {\n type Channel,\n fetchAvailableChannels,\n getChannelSite,\n updateChannelSiteUrl,\n} from './channels';\nimport { warnOnCrossDomainCheckout } from './checkout-url';\nimport { selectOrCreateInfrastructureProject } from './commerce-hosting';\nimport { consola } from './logger';\nimport { fetchProjects, type ProjectListItem } from './project';\n\nexport interface ChannelSiteFlowOptions {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n // Linked project UUID (from --project-uuid or .bigcommerce/project.json). When\n // present and resolvable, skips the project picker; otherwise falls back to\n // `selectOrCreateInfrastructureProject`, which may throw NoLinkedProjectError\n // (caller decides how to surface it).\n projectUuid?: string;\n // Non-interactive overrides. When supplied, the corresponding prompt is\n // skipped.\n channelId?: number;\n hostname?: string;\n // When set, this hostname is pre-selected in the hostname prompt. Used by\n // `catalyst deploy --update-site-url` to default to the freshly-deployed\n // hostname.\n preferHostname?: string;\n}\n\nasync function resolveProject(options: ChannelSiteFlowOptions): Promise<ProjectListItem> {\n const api = {\n storeHash: options.storeHash,\n accessToken: options.accessToken,\n apiHost: options.apiHost,\n };\n\n if (options.projectUuid) {\n const projects = await fetchProjects(api.storeHash, api.accessToken, api.apiHost);\n const matched = projects.find((p) => p.uuid === options.projectUuid);\n\n if (matched) return matched;\n\n consola.warn(\n `Project ${options.projectUuid} not found on this store. Pick another to continue.`,\n );\n }\n\n return selectOrCreateInfrastructureProject(api, options.projectUuid);\n}\n\n// Exported so `channels info` and `channels update` resolve channels the same\n// way rather than re-deriving the Catalyst-platform filter and its error copy.\nexport async function resolveChannel(options: {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n channelId?: number;\n // Overrides the picker copy for callers that aren't about to write anything —\n // `channels info` only reads, so \"to update\" would misdescribe it.\n message?: string;\n}): Promise<{ id: number; name?: string }> {\n if (options.channelId !== undefined) {\n return { id: options.channelId };\n }\n\n consola.start('Fetching channels...');\n\n const channels = await fetchAvailableChannels(\n options.storeHash,\n options.accessToken,\n options.apiHost,\n );\n\n consola.success('Channels fetched.');\n\n // Only Catalyst-platform channels can meaningfully be pointed at a Catalyst\n // deployment hostname; other storefront platforms (Stencil, etc.) are\n // filtered out so the picker stays focused.\n const catalystChannels = channels.filter((c: Channel) => c.platform === 'catalyst');\n\n if (catalystChannels.length === 0) {\n throw new Error(\n 'No Catalyst channels found on this store. Create one with `catalyst create` and try again.',\n );\n }\n\n const id = await select({\n message: options.message ?? 'Select the channel to update.',\n choices: catalystChannels.map((c: Channel) => ({\n name: c.name,\n value: c.id,\n description: `id: ${c.id}`,\n })),\n });\n\n const matched = catalystChannels.find((c) => c.id === id);\n\n return { id, name: matched?.name };\n}\n\nasync function resolveHostname(\n project: ProjectListItem,\n options: ChannelSiteFlowOptions,\n): Promise<string> {\n if (options.hostname) {\n return options.hostname;\n }\n\n if (project.deployment_hostnames.length === 0) {\n throw new Error(\n `Project \"${project.name}\" has no deployment hostnames yet. Run \\`catalyst deploy\\` first to create one.`,\n );\n }\n\n // When the caller knows which hostname they want surfaced first (e.g. the\n // freshly-deployed one from `catalyst deploy --update-site-url`), order it to\n // the top of the list so it's the default selection.\n const ordered = options.preferHostname\n ? [\n ...project.deployment_hostnames.filter((h) => h === options.preferHostname),\n ...project.deployment_hostnames.filter((h) => h !== options.preferHostname),\n ]\n : project.deployment_hostnames;\n\n const selected = await select({\n message: 'Select the hostname to point the channel at.',\n choices: ordered.map((h) => ({ name: h, value: h })),\n });\n\n return selected;\n}\n\nexport interface ChannelSiteFlowResult {\n channelId: number;\n}\n\nexport async function runChannelSiteUrlFlow(\n options: ChannelSiteFlowOptions,\n): Promise<ChannelSiteFlowResult> {\n const project = await resolveProject(options);\n const channel = await resolveChannel(options);\n const hostname = await resolveHostname(project, options);\n const siteUrl = hostname.startsWith('https://') ? hostname : `https://${hostname}`;\n\n await updateChannelSiteUrl(\n channel.id,\n siteUrl,\n options.storeHash,\n options.accessToken,\n options.apiHost,\n );\n\n const channelLabel = channel.name ? `\"${channel.name}\" (${channel.id})` : String(channel.id);\n\n consola.success(`Updated channel ${channelLabel} site URL to ${siteUrl}.`);\n\n // Moving the site URL is when checkout is most likely left behind. The PUT\n // response above carries no `urls`, hence the re-fetch. Soft-failed: the write\n // already succeeded, so a failed diagnostic mustn't look like a failed write.\n try {\n const site = await getChannelSite(\n channel.id,\n options.storeHash,\n options.accessToken,\n options.apiHost,\n );\n\n const report = await warnOnCrossDomainCheckout(site, {\n storeHash: options.storeHash,\n accessToken: options.accessToken,\n apiHost: options.apiHost,\n });\n\n // Can run mid-deploy, so it prints a command rather than prompting. Skipped\n // on a managed zone, where no checkout URL can be set at all.\n if (report.crossDomain && report.storefrontOnManagedZone !== true) {\n consola.info('Set a checkout URL for this channel with:');\n consola.log(\n ` catalyst channels update --channel-id ${channel.id}` +\n ` --checkout-url ${report.suggestion ?? '<domain>'}`,\n );\n }\n } catch {\n // Diagnostics are advisory; the write above succeeded.\n }\n\n // Returned so a caller running several channel flows back to back — `channels\n // update --hostname --checkout-url`, or `deploy --update-site-url\n // --update-checkout-url` — reuses this channel instead of resolving it twice.\n return { channelId: channel.id };\n}\n","import { z } from 'zod';\n\nimport { assertAuthorized } from './auth-errors';\nimport { UserActionableError } from './errors';\nimport { httpError } from './http-errors';\nimport { getTelemetry } from './telemetry';\n\n// `origin` is the CLI-API gateway (configured via `--cli-api-origin`, default\n// `https://cxm-prd.bigcommerceapp.com`). Distinct from `apiHost` used for the\n// BC store API (api.bigcommerce.com).\nconst cliApiUrl = (origin: string, storeHash: string, path: string) =>\n `${origin}/stores/${storeHash}/cli-api/v3${path}`;\n\nconst channelsUrl = (storeHash: string, apiHost: string, query: Record<string, string> = {}) => {\n const params = new URLSearchParams(query).toString();\n\n return `https://${apiHost}/stores/${storeHash}/v3/channels${params ? `?${params}` : ''}`;\n};\n\nconst authHeaders = (accessToken: string) => ({\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n Accept: 'application/json',\n});\n\n// envVars values are coerced to strings: the BC API returns mixed primitives\n// (e.g. BIGCOMMERCE_CHANNEL_ID is a number) but they all end up in .env.local as text.\nconst envVarsSchema = z.record(z.string(), z.coerce.string());\n\nconst channelSchema = z.object({\n id: z.number(),\n name: z.string(),\n platform: z.string(),\n});\n\nexport type Channel = z.infer<typeof channelSchema>;\n\nconst channelsResponseSchema = z.object({\n data: z.array(channelSchema),\n});\n\n// Channels are surfaced Catalyst-first, then Next, then Stencil\n// (`bigcommerce`), then anything else — the order the `create` and\n// `channel link` pickers both present. Returns a sorted copy.\nconst CHANNEL_PLATFORM_ORDER = ['catalyst', 'next', 'bigcommerce'];\n\nexport function sortChannelsByPlatform(channels: Channel[]): Channel[] {\n return [...channels].sort((a, b) => {\n const aIndex = CHANNEL_PLATFORM_ORDER.indexOf(a.platform);\n const bIndex = CHANNEL_PLATFORM_ORDER.indexOf(b.platform);\n\n if (aIndex === -1 && bIndex === -1) return 0;\n if (aIndex === -1) return 1;\n if (bIndex === -1) return -1;\n\n return aIndex - bIndex;\n });\n}\n\n// Human-friendly platform name for channel pickers. `bigcommerce` is the\n// Stencil storefront platform; everything else is title-cased.\nexport function channelPlatformLabel(platform: string): string {\n return platform === 'bigcommerce'\n ? 'Stencil'\n : platform.charAt(0).toUpperCase() + platform.slice(1);\n}\n\nconst initResponseSchema = z.object({\n data: z.object({\n storefront_api_token: z.string(),\n envVars: envVarsSchema,\n }),\n});\n\nconst createChannelResponseSchema = z.object({\n data: z.object({\n id: z.number(),\n storefront_api_token: z.string(),\n envVars: envVarsSchema,\n }),\n});\n\nconst eligibilityResponseSchema = z.object({\n data: z.object({\n eligible: z.boolean(),\n message: z.string(),\n }),\n});\n\n// `type` is a plain string, not an enum: the API documents\n// `primary | canonical | checkout`, but an unrecognised role shouldn't crash a\n// diagnostic read.\nconst siteUrlSchema = z.object({\n url: z.string(),\n type: z.string(),\n});\n\n// `ssl_status` is documented `dedicated | shared` but comes back null on shared\n// SSL. The rest are optional because the narrower `PUT .../site` response omits\n// them.\nconst channelSiteSchema = z.object({\n data: z.object({\n id: z.number(),\n url: z.string(),\n channel_id: z.number(),\n ssl_status: z.string().nullable().optional(),\n is_checkout_url_customized: z.boolean().optional(),\n urls: z.array(siteUrlSchema).optional(),\n }),\n});\n\n// Tokens minted before `store_channel_settings`/`store_sites` joined\n// `DEVICE_OAUTH_SCOPES` 401/403 here, and re-login is the only recovery — so say\n// that rather than surfacing a bare status.\nfunction assertChannelSettingsAuthorized(response: Response, action: string): void {\n if (response.status === 401 || response.status === 403) {\n throw new UserActionableError(\n `${action} (${response.status}). Re-run \\`catalyst auth login\\` to refresh your access token with the store_channel_settings and store_sites scopes.`,\n );\n }\n}\n\nexport interface ChannelInit {\n storefrontToken: string;\n envVars: Record<string, string>;\n}\n\nexport async function getChannelInit(\n channelId: number | string,\n storeHash: string,\n accessToken: string,\n origin: string,\n): Promise<ChannelInit> {\n const response = await fetch(cliApiUrl(origin, storeHash, `/channels/${channelId}/init`), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to initialize channel');\n }\n\n const { data } = initResponseSchema.parse(await response.json());\n\n return { storefrontToken: data.storefront_api_token, envVars: data.envVars };\n}\n\nexport interface ChannelEligibility {\n eligible: boolean;\n message: string;\n}\n\nexport async function checkChannelEligibility(\n storeHash: string,\n accessToken: string,\n origin: string,\n): Promise<ChannelEligibility> {\n const response = await fetch(cliApiUrl(origin, storeHash, '/channels/catalyst/eligibility'), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to check Catalyst eligibility');\n }\n\n return eligibilityResponseSchema.parse(await response.json()).data;\n}\n\nexport interface CreatedChannel {\n channelId: number;\n storefrontToken: string;\n envVars: Record<string, string>;\n}\n\nexport async function createChannel(\n name: string,\n storefrontLocale: string,\n additionalLocales: string[],\n installSampleData: boolean,\n storeHash: string,\n accessToken: string,\n origin: string,\n): Promise<CreatedChannel> {\n const response = await fetch(cliApiUrl(origin, storeHash, '/channels/catalyst'), {\n method: 'POST',\n headers: { ...authHeaders(accessToken), 'Content-Type': 'application/json' },\n body: JSON.stringify({\n name,\n initialData: { type: installSampleData ? 'sample' : 'none' },\n deployStorefront: true,\n devOrigin: 'http://localhost:3000',\n storefrontLanguage: storefrontLocale,\n additionalLocales,\n }),\n });\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to create channel');\n }\n\n const { data } = createChannelResponseSchema.parse(await response.json());\n\n return {\n channelId: data.id,\n storefrontToken: data.storefront_api_token,\n envVars: data.envVars,\n };\n}\n\nexport async function fetchAvailableChannels(\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<Channel[]> {\n const response = await fetch(\n channelsUrl(storeHash, apiHost, { available: 'true', type: 'storefront' }),\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n Accept: 'application/json',\n },\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch channels');\n }\n\n return channelsResponseSchema.parse(await response.json()).data;\n}\n\nexport interface ChannelSite {\n id: number;\n url: string;\n channelId: number;\n}\n\nexport async function updateChannelSiteUrl(\n channelId: number,\n siteUrl: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<ChannelSite> {\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/channels/${channelId}/site`,\n {\n method: 'PUT',\n headers: {\n 'X-Auth-Token': accessToken,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'X-Correlation-Id': getTelemetry().correlationId,\n },\n body: JSON.stringify({ url: siteUrl }),\n },\n );\n\n assertChannelSettingsAuthorized(response, 'Failed to update channel site');\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to update channel site');\n }\n\n const res: unknown = await response.json();\n const { data } = channelSiteSchema.parse(res);\n\n return { id: data.id, url: data.url, channelId: data.channel_id };\n}\n\nexport interface ChannelSiteUrl {\n url: string;\n type: string;\n}\n\nexport interface ChannelSiteDetails extends ChannelSite {\n sslStatus: string | null;\n // When false, BigCommerce falls back to the *default* channel's primary URL —\n // not this channel's — which can silently put checkout on an unrelated domain.\n isCheckoutUrlCustomized: boolean;\n urls: ChannelSiteUrl[];\n}\n\nconst toChannelSiteDetails = (\n data: z.infer<typeof channelSiteSchema>['data'],\n): ChannelSiteDetails => ({\n id: data.id,\n url: data.url,\n channelId: data.channel_id,\n sslStatus: data.ssl_status ?? null,\n isCheckoutUrlCustomized: data.is_checkout_url_customized ?? false,\n urls: data.urls ?? [],\n});\n\nexport function findChannelSiteUrl(site: ChannelSiteDetails, type: string): string | undefined {\n return site.urls.find((entry) => entry.type === type)?.url;\n}\n\nexport async function getChannelSite(\n channelId: number,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<ChannelSiteDetails> {\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/channels/${channelId}/site`,\n { method: 'GET', headers: authHeaders(accessToken) },\n );\n\n assertChannelSettingsAuthorized(response, 'Failed to fetch channel site');\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch channel site');\n }\n\n const res: unknown = await response.json();\n\n return toChannelSiteDetails(channelSiteSchema.parse(res).data);\n}\n\n// Channel-scoped and hyphenated. The headless guide's `/sites/{site_id}/checkout_url`\n// is wrong; the OpenAPI spec and API reference both use this form.\nconst checkoutUrlPath = (storeHash: string, apiHost: string, channelId: number) =>\n `https://${apiHost}/stores/${storeHash}/v3/channels/${channelId}/site/checkout-url`;\n\n// BigCommerce requires the checkout URL to share a main domain with the\n// storefront and 422s otherwise. Not pre-validated here: the registrable domain\n// needs the public suffix list, and a wrong local check would block a valid\n// setup. `httpError` surfaces the API's own explanation instead.\nexport async function updateChannelCheckoutUrl(\n channelId: number,\n checkoutUrl: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<ChannelSiteDetails> {\n const response = await fetch(checkoutUrlPath(storeHash, apiHost, channelId), {\n method: 'PUT',\n headers: { ...authHeaders(accessToken), 'Content-Type': 'application/json' },\n body: JSON.stringify({ url: checkoutUrl }),\n });\n\n assertChannelSettingsAuthorized(response, 'Failed to update channel checkout URL');\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to update channel checkout URL');\n }\n\n const res: unknown = await response.json();\n\n return toChannelSiteDetails(channelSiteSchema.parse(res).data);\n}\n\n// Drops the channel back to the shared checkout domain. No useful response body.\nexport async function deleteChannelCheckoutUrl(\n channelId: number,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<void> {\n const response = await fetch(checkoutUrlPath(storeHash, apiHost, channelId), {\n method: 'DELETE',\n headers: authHeaders(accessToken),\n });\n\n assertChannelSettingsAuthorized(response, 'Failed to remove channel checkout URL');\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to remove channel checkout URL');\n }\n}\n","import { getDomain } from 'tldts';\n\nimport { type ChannelSiteDetails, findChannelSiteUrl } from './channels';\nimport { UserActionableError } from './errors';\nimport { consola } from './logger';\nimport { fetchProjects } from './project';\n\nexport interface CheckoutDomainContext {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n}\n\nconst normalizeHostname = (hostname: string) => hostname.toLowerCase().replace(/\\.$/, '');\n\nconst parentDomain = (hostname: string) => hostname.split('.').slice(1).join('.');\n\nconst isSubdomainOf = (hostname: string, parent: string) => hostname.endsWith(`.${parent}`);\n\nfunction hostnameOf(url: string): string | undefined {\n try {\n return new URL(url).hostname;\n } catch {\n return undefined;\n }\n}\n\n// Whether two hostnames share a registrable domain — the relationship\n// BigCommerce requires between a channel's storefront and its checkout URL.\n//\n// Uses the public suffix list rather than comparing labels. BigCommerce does a\n// real registrable-domain comparison, which a hand-rolled rule can't match:\n// `store-x.example.store` and `store-x.c.example.store` share a registrable\n// domain and the API accepts that pairing, while `example.co.uk` and\n// `other.co.uk` do not. Every label-counting approximation gets one of those\n// two wrong, and being wrong here means telling a merchant to replace a working\n// checkout URL.\n//\n// `getDomain` returns null for a hostname with no registrable domain (an IP, or\n// a bare public suffix), which counts as not sharing.\nexport function sharesMainDomain(a: string, b: string): boolean {\n const first = getDomain(normalizeHostname(a));\n\n return first !== null && first === getDomain(normalizeHostname(b));\n}\n\n// The checkout subdomain a merchant most likely wants:\n// `https://www.example.com` → `https://checkout.example.com`.\n//\n// Strips only a leading `www.`. Reducing to the last two labels would suggest\n// `https://checkout.co.uk` for a storefront on `www.example.co.uk`; prefixing\n// the host as-is can never produce a bare public suffix and always satisfies\n// the same-main-domain rule. Pre-fills an editable prompt, so a bad URL just\n// means no suggestion.\nexport function suggestCheckoutUrl(storefrontUrl: string): string | undefined {\n const host = hostnameOf(storefrontUrl);\n\n if (!host) return undefined;\n\n const base = normalizeHostname(host).replace(/^www\\./, '');\n\n return `https://checkout.${base}`;\n}\n\n// Validates only the unambiguous parts: parses as a URL, uses https. A bare\n// hostname gets `https://` prefixed; path and query are dropped since the API\n// wants an origin.\nexport function normalizeCheckoutUrl(value: string): string {\n const withScheme = /^[a-z][a-z\\d+.-]*:\\/\\//i.test(value) ? value : `https://${value}`;\n let parsed: URL;\n\n try {\n parsed = new URL(withScheme);\n } catch {\n throw new UserActionableError(\n `\"${value}\" is not a valid URL. Pass a hostname or an https URL, e.g. https://checkout.example.com.`,\n );\n }\n\n if (parsed.protocol !== 'https:') {\n throw new UserActionableError(\n `The checkout URL must use https, but \"${value}\" uses ${parsed.protocol.replace(':', '')}.`,\n );\n }\n\n return parsed.origin;\n}\n\n// Whether a hostname sits on a BigCommerce-managed hosting zone — the\n// auto-generated `<project>.<zone>` address a deployment gets before a custom\n// domain is attached. That's what governs checkout: a checkout subdomain there\n// would be two levels deep and can't be issued a certificate, so no custom\n// checkout URL is possible at all.\n//\n// The zone is derived from the store's own `deployment_hostnames` rather than\n// hardcoded, so it survives a zone change.\n//\n// Deliberately not \"is this registered as a custom domain on the linked\n// project?\" — an auto-generated hostname can appear in a project's domain list,\n// and a real vanity domain often belongs to another project, so that test is\n// wrong in both directions.\n//\n// Best-effort: failure resolves to `undefined` so the caller degrades to\n// generic advice rather than losing the warning.\nasync function isManagedHostingHostname(\n hostname: string,\n context: CheckoutDomainContext,\n): Promise<boolean | undefined> {\n try {\n const projects = await fetchProjects(context.storeHash, context.accessToken, context.apiHost);\n const zones = projects\n .flatMap((project) => project.deployment_hostnames)\n .map((deploymentHostname) => parentDomain(normalizeHostname(deploymentHostname)))\n .filter((zone) => zone.includes('.'));\n\n if (zones.length === 0) return undefined;\n\n const host = normalizeHostname(hostname);\n\n return zones.some((zone) => host === zone || isSubdomainOf(host, zone));\n } catch {\n return undefined;\n }\n}\n\nexport interface CheckoutDomainReport {\n // True only when both hostnames were readable and don't share a registrable\n // domain. A missing or unreadable checkout URL is not \"cross domain\".\n crossDomain: boolean;\n // On a managed zone, no custom checkout URL can be issued a certificate.\n // Undefined means unknown — callers must not treat that as false.\n storefrontOnManagedZone?: boolean;\n suggestion?: string;\n}\n\n// Warns when a channel's checkout domain doesn't share a main domain with its\n// storefront, which breaks session and cart continuity under third-party-cookie\n// restrictions. Nothing else surfaces it: the redirect is resolved server-side,\n// so a storefront moved to a new domain keeps redirecting to the old checkout.\n//\n// Returns its verdict so each caller can pick a fitting follow-up —\n// `channels checkout-url` offers to set the URL, `runChannelSiteUrlFlow` can be\n// mid-deploy and prints a command instead.\n//\n// Never throws: a diagnostic must not fail the command that called it.\nexport async function warnOnCrossDomainCheckout(\n site: ChannelSiteDetails,\n context: CheckoutDomainContext,\n): Promise<CheckoutDomainReport> {\n const storefrontUrl = findChannelSiteUrl(site, 'primary') ?? site.url;\n const storefrontHost = hostnameOf(storefrontUrl);\n const checkoutUrl = findChannelSiteUrl(site, 'checkout');\n\n if (!storefrontHost) return { crossDomain: false };\n\n const suggestion = suggestCheckoutUrl(storefrontUrl);\n const checkoutHost = checkoutUrl ? hostnameOf(checkoutUrl) : undefined;\n\n // Nothing to compare, and the command reports the absence itself.\n if (!checkoutHost || sharesMainDomain(storefrontHost, checkoutHost)) {\n return { crossDomain: false, suggestion };\n }\n\n // Both cases warn: the consequence is identical, and cross-domain checkout\n // costs real carts. Only the cause differs, which changes the wording and the\n // remedy. Kept to one sentence each — this fires on every channel that has\n // never had a checkout URL set, so a paragraph would train people to skip it.\n if (site.isCheckoutUrlCustomized) {\n consola.warn(\n `This channel's checkout URL (${checkoutHost}) is on a different domain than its ` +\n `storefront (${storefrontHost}) — most likely a storefront URL change left it behind.`,\n );\n } else {\n consola.warn(\n `Checkout is on the default channel's domain (${checkoutHost}), not this channel's ` +\n `storefront (${storefrontHost}).`,\n );\n }\n\n consola.info(\n 'Shopper sessions and carts may not carry into checkout in browsers that restrict ' +\n 'cross-domain cookies.',\n );\n\n const storefrontOnManagedZone = await isManagedHostingHostname(storefrontHost, context);\n const report = { crossDomain: true, storefrontOnManagedZone, suggestion };\n\n if (storefrontOnManagedZone === false) {\n consola.info(\n `To put checkout on this channel's own domain, point ` +\n `${suggestion?.replace('https://', '') ?? 'your checkout subdomain'} at BigCommerce and ` +\n 'provision a certificate for it there.',\n );\n\n return report;\n }\n\n if (storefrontOnManagedZone === true) {\n consola.info(\n `${storefrontHost} is an auto-generated deployment hostname, and a checkout subdomain of ` +\n 'one cannot be issued a certificate — so no checkout URL can be set for this channel ' +\n 'until its storefront is on a custom domain. Add one with `catalyst domains add`.',\n );\n\n return report;\n }\n\n consola.info(\n 'BigCommerce requires the checkout URL to share a main domain with the storefront. Set one ' +\n 'with `catalyst channels update --checkout-url <domain>` once it points at BigCommerce.',\n );\n\n return report;\n}\n","import { checkbox, input, select } from '@inquirer/prompts';\nimport { colorize } from 'consola/utils';\n\nimport { createChannel, type CreatedChannel } from './channels';\nimport { UserActionableError } from './errors';\nimport { getAvailableLocales } from './localization';\nimport { consola } from './logger';\n\n// Human-readable summary of the allowed characters, reused in the prompt\n// validation and the flag-path error so both surface the same guidance.\nconst ALLOWED_CHANNEL_NAME_CHARS = 'letters, numbers, spaces, hyphens (-), and underscores (_)';\n\n// The Catalyst channels API rejects names containing other punctuation (e.g. an\n// apostrophe in \"Bob's Store\") with an opaque server error. Validate up front so\n// the user gets an immediate, actionable message instead. Letters/numbers are\n// matched with Unicode classes so non-ASCII names (accents, other scripts) pass.\nconst CHANNEL_NAME_PATTERN = /^[\\p{L}\\p{N} _-]+$/u;\n\n// Returns an error message when `name` is not a valid channel name, or\n// `undefined` when it is. Shared by the interactive prompt and the `--name` flag.\nexport function getChannelNameError(name: string): string | undefined {\n if (name.trim().length === 0) {\n return 'Channel name cannot be empty.';\n }\n\n if (!CHANNEL_NAME_PATTERN.test(name)) {\n return `\"${name}\" is not a valid channel name. Channel names may contain only ${ALLOWED_CHANNEL_NAME_CHARS}.`;\n }\n\n return undefined;\n}\n\nexport interface CreateChannelFlowOptions {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n cliApiOrigin: string;\n // Non-interactive overrides. When a value is supplied the corresponding\n // prompt is skipped, so a fully-flagged invocation runs headless.\n name?: string;\n locale?: string;\n additionalLocales?: string[];\n sampleData?: boolean;\n}\n\n// Shared channel-creation flow used by both `catalyst create` (while scaffolding)\n// and `catalyst channels create` (on an existing project). Prompts for anything\n// not provided as a flag, then POSTs to create the Catalyst channel.\nexport async function runCreateChannelFlow(\n options: CreateChannelFlowOptions,\n): Promise<CreatedChannel> {\n const { storeHash, accessToken, apiHost, cliApiOrigin } = options;\n\n // A `--name` flag skips the prompt (and its validation), so check it here to\n // fail fast with the same clear message rather than an opaque API rejection.\n if (options.name !== undefined) {\n const nameError = getChannelNameError(options.name);\n\n if (nameError) {\n throw new UserActionableError(nameError);\n }\n }\n\n const name =\n options.name ??\n (await input({\n message: 'What would you like to name your new channel?',\n validate: (value) => getChannelNameError(value) ?? true,\n }));\n\n // The locale list backs both the default-locale and additional-locales\n // prompts. Fetch it lazily and once — a fully-flagged run skips the call.\n let availableLocales: Awaited<ReturnType<typeof getAvailableLocales>> | undefined;\n const loadLocales = async () => {\n availableLocales ??= await getAvailableLocales(storeHash, accessToken, apiHost);\n\n return availableLocales;\n };\n\n const storefrontLocale =\n options.locale ??\n (await select({\n message: 'Which default language would you like to set for your channel?',\n default: 'en',\n choices: await loadLocales(),\n theme: {\n style: {\n help: () => colorize('dim', '(Select locale from the list or start typing the name)'),\n },\n },\n }));\n\n let additionalLocales = options.additionalLocales;\n\n if (additionalLocales === undefined) {\n const shouldAddAdditionalLocales = await select({\n message: 'Would you like to add additional languages?',\n choices: [\n { name: 'Yes', value: true },\n { name: 'No', value: false },\n ],\n });\n\n additionalLocales = [];\n\n if (shouldAddAdditionalLocales) {\n const localeChoices = (await loadLocales())\n .filter(({ value }) => value !== storefrontLocale)\n .map(({ name: localeName, value }) => ({ name: localeName, value, description: value }));\n\n additionalLocales = await checkbox({\n message: 'Which additional languages would you like to add to your channel?',\n choices: localeChoices,\n validate: (items) =>\n items.length <= 4 || 'You can only select up to 4 additional languages.',\n });\n }\n }\n\n const shouldInstallSampleData =\n options.sampleData ??\n (await select({\n message: 'Would you like to install sample data?',\n choices: [\n { name: 'Yes', value: true },\n { name: 'No', value: false },\n ],\n }));\n\n // The API call blocks for several seconds (it provisions the channel and,\n // when requested, populates sample data), so surface a spinner here — without\n // it the CLI looks frozen after the last prompt.\n consola.start('Creating channel...');\n\n const channel = await createChannel(\n name,\n storefrontLocale,\n additionalLocales,\n shouldInstallSampleData,\n storeHash,\n accessToken,\n cliApiOrigin,\n );\n\n consola.success('Channel created.');\n\n return channel;\n}\n","import { z } from 'zod';\n\nimport { assertAuthorized } from './auth-errors';\nimport { httpError } from './http-errors';\nimport { getTelemetry } from './telemetry';\n\nconst allowedLocales = [\n 'en',\n 'da',\n 'es-AR',\n 'es-CL',\n 'es-CO',\n 'es-MX',\n 'es-PE',\n 'es-419',\n 'es',\n 'it',\n 'nl',\n 'pl',\n 'pt',\n 'de',\n 'fr',\n 'ja',\n 'no',\n 'pt-BR',\n 'sv',\n];\n\nconst AvailableLocalesSuccessSchema = z.object({\n data: z.array(\n z.object({\n id: z.string(),\n name: z.string(),\n fallback: z.string().nullable(),\n is_supported: z.boolean(),\n }),\n ),\n});\n\nexport const getAvailableLocales = async (\n storeHash: string,\n accessToken: string,\n apiHost: string,\n) => {\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/settings/store/available-locales`,\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n Accept: 'application/json',\n },\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch available locales');\n }\n\n return AvailableLocalesSuccessSchema.parse(await response.json())\n .data.filter(({ id }) => allowedLocales.includes(id))\n .map(({ name, id }) => ({ name: `${name} (${id})`, value: id }));\n};\n","import type Conf from 'conf';\n\nimport { ProjectConfigSchema } from './project-config';\n\n// A single deployment environment variable as the infrastructure API expects\n// it. We only persist/send `secret` vars today (see ProjectConfigSchema.env).\nexport interface DeploymentSecret {\n type: 'secret';\n key: string;\n value: string;\n}\n\n// Matches POSIX-ish env var names: leading letter/underscore, then\n// letters/digits/underscores. Keeps the stored config (and the deployment\n// payload) free of keys that wouldn't be valid env vars at runtime.\nconst ENV_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n// Parse a single `KEY=VALUE` assignment. Splits on the *first* `=` only, so\n// values containing `=` (e.g. base64 or tokens) survive intact. Validates the\n// key shape and rejects empty values.\nexport const parseEnvAssignment = (input: string): { key: string; value: string } => {\n const separatorIndex = input.indexOf('=');\n\n if (separatorIndex === -1) {\n throw new Error(`Invalid env var format: ${input}. Expected format: KEY=VALUE`);\n }\n\n const key = input.slice(0, separatorIndex).trim();\n const value = input.slice(separatorIndex + 1).trim();\n\n if (!key || !value) {\n throw new Error(`Invalid env var format: ${input}. Expected format: KEY=VALUE`);\n }\n\n if (!ENV_KEY_PATTERN.test(key)) {\n throw new Error(\n `Invalid env var name: ${key}. Names must start with a letter or underscore and contain only letters, numbers, and underscores.`,\n );\n }\n\n return { key, value };\n};\n\n// Read the persisted env var map (KEY -> VALUE), defaulting to empty.\nexport const getStoredEnv = (config: Conf<ProjectConfigSchema>): Record<string, string> => {\n return config.get('env') ?? {};\n};\n\n// Convert a persisted env var map into the deployment `secret` payload shape.\nexport const toDeploymentSecrets = (envVars: Record<string, string>): DeploymentSecret[] => {\n return Object.entries(envVars).map(([key, value]) => ({ type: 'secret', key, value }));\n};\n\n// Merge persisted secrets with inline `--secret` flag secrets, keyed by name.\n// Inline flags win on conflict so users can override a stored value per-run.\nexport const mergeDeploymentSecrets = (\n persisted: DeploymentSecret[],\n flagSecrets: DeploymentSecret[],\n): DeploymentSecret[] => {\n const byKey = new Map<string, DeploymentSecret>();\n\n persisted.forEach((secret) => byKey.set(secret.key, secret));\n flagSecrets.forEach((secret) => byKey.set(secret.key, secret));\n\n return Array.from(byKey.values());\n};\n","import Conf from 'conf';\n\nimport { consola } from './logger';\nimport { ProjectConfigSchema } from './project-config';\n\nexport function resolveCredentials(\n options: { storeHash?: string; accessToken?: string },\n config: Conf<ProjectConfigSchema>,\n): { storeHash: string; accessToken: string } {\n const storeHash = options.storeHash ?? config.get('storeHash');\n const accessToken = options.accessToken ?? config.get('accessToken');\n\n if (!storeHash || !accessToken) {\n consola.error('Missing credentials.');\n consola.info(\n 'Run `catalyst auth login`, or provide --store-hash and --access-token flags (or set CATALYST_STORE_HASH and CATALYST_ACCESS_TOKEN environment variables).',\n );\n process.exit(1);\n\n // Unreachable in production; prevents continuation when process.exit is mocked in tests.\n throw new Error('Missing credentials');\n }\n\n return { storeHash, accessToken };\n}\n","import { outputFileSync } from 'fs-extra/esm';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n// Matches an \"active\" env assignment — `KEY=VALUE` that isn't commented out.\n// The value is captured greedily (and may be empty) so blank documented keys\n// like `KEY=` still parse and `KEY=a=b` keeps the full value.\nconst ACTIVE_KEY_LINE = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/;\n\nconst keyFromLine = (line: string): string | null => {\n const match = ACTIVE_KEY_LINE.exec(line);\n\n return match ? match[1] : null;\n};\n\n// Parse a .env-style body into an ordered KEY -> VALUE map, skipping comments\n// and blank lines. Last assignment wins, matching dotenv semantics.\nconst parseEnvValues = (contents: string): Map<string, string> => {\n const values = new Map<string, string>();\n\n contents.split('\\n').forEach((line) => {\n const match = ACTIVE_KEY_LINE.exec(line);\n\n if (match) {\n values.set(match[1], match[2]);\n }\n });\n\n return values;\n};\n\n// Writes .env.local at the project root — Next.js (and all the catalyst CLI\n// commands) read env vars from there, since the extracted project is the package\n// they run inside.\n//\n// `.env.example` (shipped with the scaffolded project) is the source of truth\n// for shape: the generated `.env.local` mirrors its ordering and per-key comment\n// blocks so the file stays self-documenting. Values supplied by the CLI are\n// substituted in place; documented keys we weren't given keep the example's own\n// line (blank or default) so the user still sees what's expected. Any existing\n// `.env.local` is reconciled rather than clobbered — the user's current values\n// are preserved unless the CLI is explicitly supplying a new one.\nexport const writeEnv = (projectDir: string, envVars: Record<string, string>) => {\n const examplePath = join(projectDir, '.env.example');\n const localPath = join(projectDir, '.env.local');\n\n const existingLocal = existsSync(localPath)\n ? parseEnvValues(readFileSync(localPath, 'utf-8'))\n : new Map<string, string>();\n\n // CLI-supplied vars win over what's already on disk so a re-run (e.g.\n // `channel link`) updates credentials in place; anything the CLI didn't touch\n // falls back to the user's existing value. An empty CLI value is treated as\n // \"not supplied\" — the channel init API returns blank placeholders for keys it\n // doesn't own (e.g. MAKESWIFT_SITE_API_KEY), and those must not clobber a real\n // value the user already has on disk.\n const resolve = (key: string): string | undefined => {\n if (key in envVars && envVars[key] !== '') {\n return envVars[key];\n }\n\n return existingLocal.get(key);\n };\n\n // Without a template we can't follow the documented ordering/comments, so fall\n // back to a flat merge that still preserves the user's existing values.\n if (!existsSync(examplePath)) {\n const keys = [...new Set([...existingLocal.keys(), ...Object.keys(envVars)])];\n\n outputFileSync(localPath, `${keys.map((key) => `${key}=${resolve(key) ?? ''}`).join('\\n')}\\n`);\n\n return;\n }\n\n // Drop a single trailing newline before splitting so we don't reproduce a\n // spurious blank line; the final `join` re-adds exactly one.\n const exampleLines = readFileSync(examplePath, 'utf-8').replace(/\\n$/, '').split('\\n');\n const exampleKeys = new Set<string>();\n\n const lines = exampleLines.map((line) => {\n const key = keyFromLine(line);\n\n // Comments and blank lines are copied verbatim, preserving each key's\n // leading comment block.\n if (key === null) {\n return line;\n }\n\n exampleKeys.add(key);\n\n const value = resolve(key);\n\n // Documented keys without a value keep the example's own line so defaults\n // (e.g. `BIGCOMMERCE_CHANNEL_ID=1`) and blank placeholders survive.\n return value === undefined ? line : `${key}=${value}`;\n });\n\n // Keys the CLI supplied — or the user already had — that the template doesn't\n // document get appended in a clearly separated section, preserving the order\n // they were first seen (existing keys first, then newly supplied ones).\n const extraKeys: string[] = [];\n\n [...existingLocal.keys()].forEach((key) => {\n if (!exampleKeys.has(key)) {\n extraKeys.push(key);\n }\n });\n\n Object.keys(envVars).forEach((key) => {\n if (!exampleKeys.has(key) && !extraKeys.includes(key)) {\n extraKeys.push(key);\n }\n });\n\n if (extraKeys.length > 0) {\n lines.push('', '# Additional variables set by the Catalyst CLI (not in .env.example).');\n\n extraKeys.forEach((key) => {\n lines.push(`${key}=${resolve(key) ?? ''}`);\n });\n }\n\n outputFileSync(localPath, `${lines.join('\\n')}\\n`);\n};\n","import { Command, InvalidArgumentError, Option } from '@commander-js/extra-typings';\nimport { input, select } from '@inquirer/prompts';\nimport { execSync } from 'child_process';\nimport { colorize } from 'consola/utils';\nimport { pathExistsSync } from 'fs-extra/esm';\nimport kebabCase from 'lodash.kebabcase';\nimport { join } from 'path';\n\nimport { DEFAULT_LOGIN_URL } from '../lib/auth';\nimport {\n channelPlatformLabel,\n checkChannelEligibility,\n fetchAvailableChannels,\n getChannelInit,\n sortChannelsByPlatform,\n} from '../lib/channels';\nimport { promptForCommerceHostingProject, setupCommerceHosting } from '../lib/commerce-hosting';\nimport { runCreateChannelFlow } from '../lib/create-channel-flow';\nimport { detectPackageManager } from '../lib/detect-package-manager';\nimport { extractCatalyst } from '../lib/extract-catalyst';\nimport { initGitRepo } from '../lib/init-git-repo';\nimport { installDependencies } from '../lib/install-dependencies';\nimport { consola } from '../lib/logger';\nimport { login, LoginAbortedError } from '../lib/login';\nimport { hasProjectsAccess, type ProjectListItem } from '../lib/project';\nimport { getProjectConfig } from '../lib/project-config';\nimport { rewriteCorePackage } from '../lib/rewrite-core-package';\nimport { setupCoreProject } from '../lib/setup-core-project';\nimport { accessTokenOption, storeHashOption } from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\nimport { writeEnv } from '../lib/write-env';\n\nfunction getPlatformCheckCommand(command: string): string {\n const isWindows = process.platform === 'win32';\n\n return isWindows ? `where.exe ${command}` : `which ${command}`;\n}\n\nfunction parseChannelId(value: string): number {\n const parsed = parseInt(value, 10);\n\n if (Number.isNaN(parsed)) {\n throw new InvalidArgumentError(`\"${value}\" is not a valid channel ID (expected a number).`);\n }\n\n return parsed;\n}\n\n// Variadic argParser: called once per `--env KEY=VALUE`, accumulating into a\n// merged record. Splits on the first `=` so values containing `=` are preserved.\nfunction parseEnvFlag(\n value: string,\n previous: Record<string, string> = {},\n): Record<string, string> {\n const eqIdx = value.indexOf('=');\n\n if (eqIdx <= 0) {\n throw new InvalidArgumentError(`Expected KEY=VALUE, got \"${value}\".`);\n }\n\n const key = value.substring(0, eqIdx);\n const val = value.substring(eqIdx + 1);\n\n if (!val) {\n throw new InvalidArgumentError(`Expected KEY=VALUE with non-empty value, got \"${value}\".`);\n }\n\n return { ...previous, [key]: val };\n}\n\nasync function handleChannelSelection(storeHash: string, accessToken: string, apiHost: string) {\n const channels = await fetchAvailableChannels(storeHash, accessToken, apiHost);\n\n const existingChannel = await select({\n message: 'Which channel would you like to use?',\n choices: sortChannelsByPlatform(channels).map((ch) => ({\n name: ch.name,\n value: ch,\n description: `Channel Platform: ${channelPlatformLabel(ch.platform)}`,\n })),\n });\n\n return existingChannel.id;\n}\n\nasync function setupProject(options: {\n projectName?: string;\n projectDir: string;\n}): Promise<{ projectName: string; projectDir: string }> {\n let { projectName, projectDir } = options;\n\n if (!pathExistsSync(projectDir)) {\n consola.error(`--project-dir ${projectDir} is not a valid path`);\n process.exit(1);\n }\n\n if (projectName) {\n projectName = kebabCase(projectName);\n projectDir = join(options.projectDir, projectName);\n\n if (pathExistsSync(projectDir)) {\n consola.error(`${projectDir} already exists`);\n process.exit(1);\n }\n }\n\n if (!projectName) {\n const validateProjectName = (i: string) => {\n const formatted = kebabCase(i);\n\n if (!formatted) return 'Project name is required';\n\n const targetDir = join(options.projectDir, formatted);\n\n if (pathExistsSync(targetDir)) return `Destination '${targetDir}' already exists`;\n\n projectName = formatted;\n projectDir = targetDir;\n\n return true;\n };\n\n await input({\n message: 'What do you want to name your project directory?',\n default: 'my-catalyst-app',\n validate: validateProjectName,\n });\n }\n\n if (!projectName) throw new Error('Something went wrong, projectName is not defined');\n if (!projectDir) throw new Error('Something went wrong, projectDir is not defined');\n\n return { projectName, projectDir };\n}\n\nfunction checkRequiredTools() {\n try {\n execSync(getPlatformCheckCommand('git'), { stdio: 'ignore' });\n } catch {\n consola.error('git is required to create a Catalyst project');\n process.exit(1);\n }\n}\n\nexport const create = new Command('create')\n .configureHelp({ showGlobalOptions: true })\n .description('Scaffold and connect a Catalyst storefront to your BigCommerce store.')\n .addHelpText(\n 'after',\n `\nExamples:\n # Interactive scaffold (default — self-hosted, no hosting prompt)\n $ catalyst create\n\n # Non-interactive: skip the project-name prompt\n $ catalyst create --project-name my-store\n\n # Eagerly set up Commerce Hosting at create time\n $ catalyst create --project-name my-store --hosting commerce`,\n )\n .option('--project-name <name>', 'Name of your Catalyst project')\n .option('--project-dir <dir>', 'Directory in which to create your project', process.cwd())\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .option('--channel-id <id>', 'BigCommerce channel ID', parseChannelId)\n .option('--storefront-token <token>', 'BigCommerce storefront token')\n .option(\n '--gh-ref <ref>',\n 'Extract a specific ref (tag, branch, or commit) from the source repository',\n '@bigcommerce/catalyst-core@latest',\n )\n .option('--repository <repository>', 'GitHub repository to extract from', 'bigcommerce/catalyst')\n .option(\n '--env <vars...>',\n 'Arbitrary environment variables to set in .env.local. Format: KEY=VALUE (repeatable).',\n parseEnvFlag,\n )\n .addOption(\n new Option(\n '--hosting <mode>',\n 'Hosting mode: \"self-hosted\" (default) or \"commerce\" to set up Commerce Hosting at create time. When omitted, scaffolding is hosting-agnostic; run `catalyst deploy` later to opt in.',\n ).choices(['self-hosted', 'commerce'] as const),\n )\n .option(\n '--use-existing',\n 'Only used with --hosting commerce and --project-name. When the named project already exists on the store, reuse it instead of prompting. Has no effect without --hosting commerce.',\n )\n .addOption(\n new Option('--bigcommerce-hostname <hostname>', 'BigCommerce hostname')\n .default('bigcommerce.com')\n .hideHelp(),\n )\n .addOption(\n new Option('--login-url <url>', 'BigCommerce login URL.')\n .env('BIGCOMMERCE_LOGIN_URL')\n .default(DEFAULT_LOGIN_URL)\n .hideHelp(),\n )\n .addOption(\n new Option('--cli-api-origin <origin>', 'Catalyst CLI API origin')\n .default('https://cxm-prd.bigcommerceapp.com')\n .hideHelp(),\n )\n // eslint-disable-next-line complexity\n .action(async (options) => {\n const { ghRef, repository } = options;\n\n if (options.useExisting && options.hosting !== 'commerce') {\n consola.warn('--use-existing has no effect without --hosting commerce. Ignoring.');\n }\n\n checkRequiredTools();\n\n const { projectName, projectDir } = await setupProject({\n projectName: options.projectName,\n projectDir: options.projectDir,\n });\n\n let storeHash = options.storeHash;\n let accessToken = options.accessToken;\n let channelId = options.channelId;\n let storefrontToken = options.storefrontToken;\n\n let envVars: Record<string, string> = {};\n\n // Always require store creds. `--channel-id` + `--storefront-token` aren't\n // enough on their own — the storefront also needs BIGCOMMERCE_STORE_HASH at\n // runtime, and downstream catalyst commands (deploy, project, ...) need an\n // access token. Device login covers the missing pieces; the user picks the\n // store during the OAuth flow regardless of any partial flags they passed.\n if (!storeHash || !accessToken) {\n const apiHost = `api.${options.bigcommerceHostname}`;\n\n try {\n const credentials = await login(options.loginUrl, apiHost);\n\n storeHash = credentials.storeHash;\n accessToken = credentials.accessToken;\n } catch (error) {\n if (error instanceof LoginAbortedError) {\n consola.info(\n 'Login aborted. Re-run `catalyst create` when you have your credentials ready.',\n );\n process.exit(0);\n\n return;\n }\n\n throw error;\n }\n }\n\n const useCommerceHosting = options.hosting === 'commerce';\n\n await getTelemetry().identify(storeHash);\n\n // Seed env vars from local state when all three were flag-provided. Channel\n // resolution below overwrites this wholesale via `envVars = { ...initData.envVars }`,\n // which is fine — that path means the user wanted us to fetch fresh values.\n if (storeHash && channelId && storefrontToken) {\n envVars.BIGCOMMERCE_STORE_HASH = storeHash;\n envVars.BIGCOMMERCE_CHANNEL_ID = channelId.toString();\n envVars.BIGCOMMERCE_STOREFRONT_TOKEN = storefrontToken;\n }\n\n // Resolve channel only when we have creds and are missing channel info.\n if (storeHash && accessToken && (!channelId || !storefrontToken)) {\n const apiHost = `api.${options.bigcommerceHostname}`;\n const cliApiOrigin = options.cliApiOrigin;\n\n if (channelId && !storefrontToken) {\n const initData = await getChannelInit(channelId, storeHash, accessToken, cliApiOrigin);\n\n envVars = { ...initData.envVars };\n storefrontToken = initData.storefrontToken;\n } else if (!channelId) {\n const eligibility = await checkChannelEligibility(storeHash, accessToken, cliApiOrigin);\n\n if (!eligibility.eligible) {\n consola.warn(eligibility.message);\n }\n\n let shouldCreateChannel;\n\n if (eligibility.eligible) {\n shouldCreateChannel = await select({\n message: 'Would you like to create a new channel?',\n choices: [\n { name: 'Yes', value: true },\n { name: 'No', value: false },\n ],\n });\n }\n\n if (shouldCreateChannel) {\n const channelData = await runCreateChannelFlow({\n storeHash,\n accessToken,\n apiHost,\n cliApiOrigin,\n });\n\n channelId = channelData.channelId;\n storefrontToken = channelData.storefrontToken;\n envVars = { ...channelData.envVars };\n\n consola.success('Channel created successfully.');\n consola.warn(\n 'A preview storefront has been deployed in your BigCommerce control panel. This preview may look different from your local environment as it may be running different code. Additionally, it may take a few minutes for the channel storefront to be accessible.',\n );\n }\n\n if (!shouldCreateChannel) {\n channelId = await handleChannelSelection(storeHash, accessToken, apiHost);\n\n const initData = await getChannelInit(channelId, storeHash, accessToken, cliApiOrigin);\n\n envVars = { ...initData.envVars };\n storefrontToken = initData.storefrontToken;\n }\n }\n }\n\n if (options.env) {\n Object.assign(envVars, options.env);\n }\n\n if (options.storeHash) envVars.BIGCOMMERCE_STORE_HASH = options.storeHash;\n if (options.channelId) envVars.BIGCOMMERCE_CHANNEL_ID = options.channelId.toString();\n if (options.storefrontToken) envVars.BIGCOMMERCE_STOREFRONT_TOKEN = options.storefrontToken;\n\n if (useCommerceHosting && accessToken) {\n envVars.BIGCOMMERCE_ACCESS_TOKEN = accessToken;\n }\n\n // Resolve the Commerce Hosting project before extraction so credential checks\n // and prompts happen up-front. We defer the file mutations\n // (`setupCommerceHosting`) until after extraction.\n let commerceHostingProject: ProjectListItem | undefined;\n\n if (useCommerceHosting && storeHash && accessToken) {\n const apiHost = `api.${options.bigcommerceHostname}`;\n const hasAccess = await hasProjectsAccess(storeHash, accessToken, apiHost);\n\n if (!hasAccess) {\n consola.error(\n 'This store does not have access to the Infrastructure Projects API. Contact support@bigcommerce.com to enable it.',\n );\n process.exit(1);\n }\n\n commerceHostingProject = await promptForCommerceHostingProject(\n { storeHash, accessToken, apiHost },\n projectName,\n !!options.projectName,\n options.useExisting,\n );\n }\n\n consola.info(`Creating '${projectName}' at '${projectDir}'`);\n\n const packageManager = detectPackageManager();\n\n // Anything that mutates `projectDir` runs inside this block. If a step\n // fails, the directory is likely partially populated — surface that to the\n // user so they can clean up before retrying. We don't auto-delete because\n // they may want to inspect the partial state first.\n try {\n await extractCatalyst({ repository, ref: ghRef, projectDir });\n // Turn the extracted core/ into an installable standalone project\n // (resolve workspace deps, drop `private`, record the catalyst version/ref).\n await rewriteCorePackage(projectDir, ghRef);\n setupCoreProject(projectDir);\n\n if (useCommerceHosting && commerceHostingProject && storeHash && accessToken) {\n await setupCommerceHosting({\n projectDir,\n projectUuid: commerceHostingProject.uuid,\n storeHash,\n accessToken,\n });\n }\n\n // Persist the credentials we just authenticated with into the new\n // project's `.bigcommerce/project.json` (gitignored). Every command\n // resolves credentials from this file, so without it `catalyst deploy`\n // and `catalyst projects create` would fail or re-prompt for login\n // immediately after `create` already logged the user in.\n //\n // Ordered after `setupCommerceHosting`, which writes the same file to\n // record `projectUuid`. Both merge into existing contents now, so the\n // order no longer matters for correctness — kept so the credentials\n // written here are the ones that land last.\n if (storeHash && accessToken) {\n const projectConfig = getProjectConfig(projectDir);\n\n projectConfig.set('storeHash', storeHash);\n projectConfig.set('accessToken', accessToken);\n }\n\n // Write env before install — matters for postinstall scripts that may\n // resolve env-driven config.\n writeEnv(projectDir, envVars);\n\n await installDependencies(projectDir, packageManager);\n initGitRepo(projectDir);\n } catch (error) {\n if (pathExistsSync(projectDir)) {\n consola.warn(\n `Setup failed before completion. '${projectDir}' may be in a partial state — review and delete it before re-running 'catalyst create'.`,\n );\n }\n\n throw error;\n }\n\n consola.success(`Created '${projectName}' at '${projectDir}'`);\n\n const steps = [`cd ${projectName} && ${packageManager} run dev`];\n\n if (useCommerceHosting) {\n steps.push(\n `Run 'cd ${projectName} && ${packageManager} run deploy' when ready to deploy to Commerce Hosting.`,\n );\n }\n\n consola.log(\n `Next steps:\\n\\n${steps.map((step) => ` ${colorize('yellow', step)}`).join('\\n')}`,\n );\n });\n","import { mkdirSync } from 'fs';\nimport { Readable } from 'stream';\nimport { pipeline } from 'stream/promises';\nimport type { ReadableStream as NodeReadableStream } from 'stream/web';\nimport { x } from 'tar';\n\nimport { consola } from './logger';\n\nconst SUBDIR = 'core';\nconst MAX_ATTEMPTS = 3;\n\nconst codeloadUrl = (repository: string, ref: string) =>\n `https://codeload.github.com/${repository}/tar.gz/${encodeURIComponent(ref)}`;\n\nconst wait = (ms: number) =>\n new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n\n// Download the repo tarball from GitHub's codeload endpoint and stream-extract\n// ONLY the `core/` subdirectory into `projectDir`, so merchants receive a clean\n// standalone project instead of the whole monorepo. Mirrors create-next-app:\n// fetch -> stream.pipeline -> tar.x({ strip, filter }).\n//\n// The archive's top-level directory is dynamic (e.g.\n// `catalyst--bigcommerce-catalyst-core-1.6.2` for a tag, `catalyst-canary` for a\n// branch), so we never hardcode it — `filter` keeps entries whose first path\n// segment after the top dir is `core/`, and `strip: 2` drops `<top>/core` so the\n// contents land at the project root.\nconst downloadAndExtract = async (repository: string, ref: string, projectDir: string) => {\n const url = codeloadUrl(repository, ref);\n const response = await fetch(url);\n\n if (!response.ok || !response.body) {\n throw new Error(`Failed to download ${url} (HTTP ${response.status})`);\n }\n\n await pipeline(\n // Node's global fetch types `body` as the DOM ReadableStream; it is the same\n // object Readable.fromWeb expects at runtime.\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n Readable.fromWeb(response.body as NodeReadableStream<Uint8Array>),\n x({\n cwd: projectDir,\n strip: 2,\n filter: (path) => path.split('/')[1] === SUBDIR,\n }),\n );\n};\n\n// Retries the download up to MAX_ATTEMPTS with linear backoff, following\n// create-next-app's pattern. Recursive rather than looped to keep each await off\n// the hot loop path (and satisfy lint).\nconst attemptDownload = async (\n repository: string,\n ref: string,\n projectDir: string,\n attempt = 1,\n): Promise<void> => {\n try {\n await downloadAndExtract(repository, ref, projectDir);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'unknown error';\n\n if (attempt >= MAX_ATTEMPTS) {\n throw new Error(`Failed to download Catalyst after ${MAX_ATTEMPTS} attempts: ${message}`);\n }\n\n consola.warn(`Download attempt ${attempt} failed (${message}). Retrying...`);\n await wait(attempt * 1000);\n\n return attemptDownload(repository, ref, projectDir, attempt + 1);\n }\n};\n\nexport const extractCatalyst = async ({\n repository,\n ref,\n projectDir,\n}: {\n repository: string;\n ref: string;\n projectDir: string;\n}) => {\n consola.info(`Downloading ${repository}#${ref}...`);\n\n mkdirSync(projectDir, { recursive: true });\n\n await attemptDownload(repository, ref, projectDir);\n};\n","import { execSync } from 'child_process';\nimport { rmSync } from 'fs';\nimport { join } from 'path';\n\nimport { consola } from './logger';\n\nconst run = (command: string, cwd: string) => execSync(command, { cwd, stdio: 'ignore' });\n\n// Initialize a fresh git repository for the merchant with a single initial\n// commit. We no longer clone, so there is no history or upstream remote to carry\n// over — merchants add their own. Best-effort: a missing git or a pre-existing\n// repo shouldn't fail project creation, so we warn and roll back a partial init.\nexport const initGitRepo = (projectDir: string) => {\n try {\n run('git init', projectDir);\n run('git add -A', projectDir);\n run('git commit -m \"Initial commit from Catalyst\"', projectDir);\n consola.success('Initialized a git repository.');\n } catch {\n rmSync(join(projectDir, '.git'), { recursive: true, force: true });\n consola.warn('Could not initialize a git repository. Skipping.');\n }\n};\n","import { readFileSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\n\nimport { consola } from './logger';\nimport { sortPackageJsonFields } from './sort-package-json';\n\n// Native-module build allowlist, lifted from the monorepo's root\n// pnpm-workspace.yaml `onlyBuiltDependencies`. A standalone install needs this so\n// pnpm (`pnpm.onlyBuiltDependencies`) and bun (`trustedDependencies`) run the\n// native postinstall builds without prompting. npm/yarn-classic run them anyway.\nconst NATIVE_BUILD_ALLOWLIST = [\n '@parcel/watcher',\n '@swc/core',\n '@vercel/speed-insights',\n 'esbuild',\n 'msw',\n 'protobufjs',\n 'puppeteer',\n 'sharp',\n 'workerd',\n];\n\nconst DEP_FIELDS = [\n 'dependencies',\n 'devDependencies',\n 'optionalDependencies',\n 'peerDependencies',\n] as const;\n\nconst corePackageJsonSchema = z.looseObject({\n version: z.string().optional(),\n private: z.boolean().optional(),\n scripts: z.record(z.string(), z.string()).optional(),\n dependencies: z.record(z.string(), z.string()).optional(),\n devDependencies: z.record(z.string(), z.string()).optional(),\n optionalDependencies: z.record(z.string(), z.string()).optional(),\n peerDependencies: z.record(z.string(), z.string()).optional(),\n pnpm: z.looseObject({}).optional(),\n catalyst: z.looseObject({}).optional(),\n});\n\nconst registryVersionSchema = z.object({ version: z.string() });\n\n// Resolve the published npm version for a workspace dependency. The extracted\n// tag tree still carries `workspace:^` (core is private, so changesets' publish-\n// time rewrite never touches the committed tree) — so we resolve the real\n// version at extraction time from the npm registry.\n//\n// NOTE: `latest` answers for today, not for `ref`. These packages version\n// independently of core (the changesets config has no `linked`/`fixed` group),\n// so scaffolding from an older `--gh-ref` can splice in a newer version than\n// that tag shipped. Harmless while they stay in step, wrong at the first major\n// bump. `catalyst upgrade` reads the versions out of the tag's own\n// `packages/*/package.json`; this path can't yet, because `extractCatalyst`\n// filters the tarball down to `core/`. Tracked as a follow-up.\nconst resolvePublishedVersion = async (pkgName: string): Promise<string> => {\n const response = await fetch(`https://registry.npmjs.org/${pkgName}/latest`);\n\n if (!response.ok) {\n throw new Error(\n `Could not resolve a published version for \"${pkgName}\" (HTTP ${response.status}). ` +\n 'The extracted project still references it via the workspace protocol and cannot be installed.',\n );\n }\n\n const { version } = registryVersionSchema.parse(await response.json());\n\n return `^${version}`;\n};\n\n// Transforms an extracted `core/package.json` into an installable, standalone\n// manifest: resolves `workspace:` deps to published versions, drops `private`,\n// bakes the native-build allowlist for pnpm/bun, strips monorepo-only (turbo)\n// scripts, and records the Catalyst version/ref the project was created from.\n// Also writes `.npmrc` so npm tolerates react-headroom's stale react peer range.\nexport const rewriteCorePackage = async (projectDir: string, ref: string) => {\n const packageJsonPath = join(projectDir, 'package.json');\n const pkg = corePackageJsonSchema.parse(JSON.parse(readFileSync(packageJsonPath, 'utf-8')));\n\n // Collect every workspace-protocol dependency across all dep fields, keeping a\n // reference to its owning record so we can rewrite it in place after resolving.\n const workspaceDeps = DEP_FIELDS.flatMap((field) => {\n const deps = pkg[field];\n\n if (!deps) return [];\n\n return Object.entries(deps)\n .filter(([, range]) => range.startsWith('workspace:'))\n .map(([name]) => ({ deps, name }));\n });\n\n await Promise.all(\n workspaceDeps.map(async ({ deps, name }) => {\n const resolved = await resolvePublishedVersion(name);\n\n deps[name] = resolved;\n consola.info(`Resolved ${name} to ${resolved}`);\n }),\n );\n\n // Merchants need an installable project; `private` blocks publish/install ergonomics.\n delete pkg.private;\n\n // Drop any monorepo-only scripts that shell out to turbo.\n if (pkg.scripts) {\n pkg.scripts = Object.fromEntries(\n Object.entries(pkg.scripts).filter(([, command]) => !command.includes('turbo')),\n );\n }\n\n pkg.pnpm = { ...pkg.pnpm, onlyBuiltDependencies: NATIVE_BUILD_ALLOWLIST };\n pkg.trustedDependencies = NATIVE_BUILD_ALLOWLIST;\n\n // Track what this project was scaffolded from (consumed by `catalyst upgrade`\n // and the backend user-agent). `ref` is the exact ref extracted.\n pkg.catalyst = { ...pkg.catalyst, version: pkg.version, ref };\n\n writeFileSync(packageJsonPath, `${JSON.stringify(sortPackageJsonFields(pkg), null, 2)}\\n`);\n\n // react-headroom (unmaintained) declares a react <=18 peer; core ships react 19.\n // pnpm/yarn/bun tolerate it, but npm errors ERESOLVE without this.\n writeFileSync(join(projectDir, '.npmrc'), 'legacy-peer-deps=true\\n');\n};\n","import { mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { z } from 'zod';\n\nimport PACKAGE_INFO from '../../../package.json';\n\nimport { sortPackageJsonFields } from './sort-package-json';\n\nconst corePackageJsonSchema = z.looseObject({\n scripts: z.record(z.string(), z.string()).optional(),\n devDependencies: z.record(z.string(), z.string()).optional(),\n});\n\nconst writeJson = (path: string, value: unknown) => {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(value, null, 2)}\\n`);\n};\n\n// Wires Catalyst CLI scripts and the `@bigcommerce/catalyst` dev dependency into\n// a freshly extracted project. Always runs at create time, regardless of hosting\n// choice — `catalyst build` / `catalyst start` / `catalyst deploy` dispatch on\n// project state, so these scripts work for self-hosted projects too without\n// rewrite. The CLI is a build-time tool (it only backs those npm scripts), never\n// imported at runtime, so it belongs in devDependencies, not dependencies.\nexport const setupCoreProject = (projectDir: string) => {\n const corePackageJsonPath = join(projectDir, 'package.json');\n const pkg = corePackageJsonSchema.parse(JSON.parse(readFileSync(corePackageJsonPath, 'utf-8')));\n\n pkg.scripts = {\n ...pkg.scripts,\n build: 'npm run generate && catalyst build',\n start: 'catalyst start',\n deploy: 'npm run generate && catalyst deploy',\n };\n\n pkg.devDependencies = {\n ...pkg.devDependencies,\n '@bigcommerce/catalyst': PACKAGE_INFO.version,\n };\n\n writeJson(corePackageJsonPath, sortPackageJsonFields(pkg));\n};\n","import { Command, Option } from 'commander';\n\nimport {\n collectDiagnostics,\n type ConfigSource,\n type Diagnostics,\n type ResolvedValue,\n} from '../lib/collect-diagnostics';\nimport { consola } from '../lib/logger';\n\nconst yesNo = (value: boolean): string => (value ? 'yes' : 'no');\n\nconst presence = (value: boolean): string => (value ? 'present' : 'absent');\n\nconst formatResolved = (value: ResolvedValue): string =>\n value.present ? `present (source: ${value.source})` : 'not set';\n\nconst formatSource = (source: ConfigSource): string =>\n source === 'unset' ? 'not set' : `set (${source})`;\n\nconst formatStorefront = (name: string | null, version: string | null): string => {\n if (!version) {\n return '(unknown)';\n }\n\n return name ? `${name}@${version}` : version;\n};\n\nconst formatList = (values: string[]): string => (values.length > 0 ? values.join(', ') : '(none)');\n\nconst envVarLines = (vars: Record<string, ConfigSource>): string[] =>\n Object.entries(vars).map(([name, source]) => ` ${name}: ${formatSource(source)}`);\n\n// Build a human-readable, copy-pasteable report. Kept to plain text (no colors)\n// so it survives a paste into a GitHub issue or support ticket unchanged.\nconst formatReport = (d: Diagnostics): string => {\n const lines = [\n 'Catalyst CLI Diagnostics',\n '',\n 'CLI',\n ` Package: ${d.cli.name}`,\n ` Version: ${d.cli.version}`,\n '',\n 'Runtime',\n ` Node: ${d.runtime.node}`,\n ` Platform: ${d.runtime.platform} (${d.runtime.arch})`,\n ` OS release: ${d.runtime.osRelease}`,\n ` Package manager: ${d.runtime.packageManager}`,\n '',\n 'Project',\n ` Directory: ${d.project.cwd}`,\n ` Storefront: ${formatStorefront(d.project.storefrontName, d.project.storefrontVersion)}`,\n ` Project UUID: ${d.project.projectUuid ?? '(not linked)'}`,\n ` Linked: ${yesNo(d.project.isLinked)}`,\n ` Transformed: ${yesNo(d.project.isTransformed)}`,\n ` Fully set up: ${yesNo(d.project.isFullySetUp)}`,\n ` middleware.ts: ${presence(d.project.hasMiddleware)}`,\n ` proxy.ts: ${presence(d.project.hasProxy)}`,\n ` OpenNext dep: ${d.project.hasOpenNextDep ? 'installed' : 'not installed'}`,\n '',\n 'Config (resolved without secrets)',\n ` Store hash: ${formatResolved(d.config.storeHash)}`,\n ` Access token: ${formatResolved(d.config.accessToken)}`,\n ` Project UUID: ${formatResolved(d.config.projectUuid)}`,\n ` API host: ${d.config.apiHost.present ? formatResolved(d.config.apiHost) : 'default (api.bigcommerce.com)'}`,\n ` project.json keys: ${formatList(d.config.projectJsonKeys)}`,\n ` Stored env keys: ${formatList(d.config.storedEnvKeys)}`,\n '',\n 'CLI environment variables (used to run the CLI)',\n ...envVarLines(d.config.cliEnvVars),\n '',\n 'Build environment variables (used to build the Next.js app)',\n ...envVarLines(d.config.buildEnvVars),\n '',\n 'Telemetry',\n ` Enabled: ${yesNo(d.telemetry.enabled)}`,\n ` Correlation ID: ${d.telemetry.correlationId}`,\n '',\n 'Files',\n ...Object.entries(d.files).map(([name, exists]) => ` ${name}: ${presence(exists)}`),\n ];\n\n return lines.join('\\n');\n};\n\nexport const debug = new Command('debug')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Print a diagnostic report (CLI, runtime, project, and config state) to include when filing a bug report. Never prints secret values — credentials and env vars are reported by presence only.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Print a human-readable report\n $ catalyst debug\n\n # Print machine-readable JSON (useful for copy/paste or piping)\n $ catalyst debug --json`,\n )\n .addOption(new Option('--json', 'Output the report as JSON.'))\n .action((options: { json?: boolean }) => {\n const diagnostics = collectDiagnostics();\n\n if (options.json) {\n consola.log(JSON.stringify(diagnostics, null, 2));\n\n return;\n }\n\n consola.log(formatReport(diagnostics));\n });\n","import { parse } from 'dotenv';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { release } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { z } from 'zod';\n\nimport PACKAGE_INFO from '../../../package.json';\n\nimport { detectPackageManager, type PackageManager } from './detect-package-manager';\nimport { getProjectState } from './project-state';\nimport { getTelemetry } from './telemetry';\n\n// Env vars the CLI itself reads to run commands (credential/flag bindings in\n// shared-options.ts plus the telemetry opt-out). We report only WHERE each is\n// set (or that it is unset) — never its value — so the report can never leak a\n// token, secret, or store identifier.\nexport const CLI_ENV_VARS = [\n 'CATALYST_STORE_HASH',\n 'CATALYST_ACCESS_TOKEN',\n 'CATALYST_PROJECT_UUID',\n 'CATALYST_API_HOST',\n 'BIGCOMMERCE_LOGIN_URL',\n 'CATALYST_TELEMETRY_DISABLED',\n] as const;\n\n// Env vars the storefront (Next.js app) build reads, not the CLI. Mirrors\n// REQUIRED_BUILD_ENV_VARS in required-build-env.ts — the values `build`/`deploy`\n// assert on before shelling out to the OpenNext/Next.js build.\nexport const BUILD_ENV_VARS = [\n 'BIGCOMMERCE_STORE_HASH',\n 'BIGCOMMERCE_STOREFRONT_TOKEN',\n 'BIGCOMMERCE_CHANNEL_ID',\n 'AUTH_SECRET',\n] as const;\n\n// Env files `build`/`deploy` auto-load, in precedence order (see build-env.ts).\n// `debug` doesn't load them into process.env — it only inspects their KEYS so\n// the report reflects what a build would resolve, without side effects.\nconst ENV_FILES = ['.env.local', '.env'] as const;\n\n// Lockfile -> package manager, checked in this order. This detects the\n// project's package manager (what `build`/`deploy` shell out to) rather than\n// whatever invoked the CLI, which is what a bug report actually needs.\nconst PROJECT_LOCKFILES: ReadonlyArray<readonly [string, PackageManager]> = [\n ['pnpm-lock.yaml', 'pnpm'],\n ['yarn.lock', 'yarn'],\n ['bun.lock', 'bun'],\n ['bun.lockb', 'bun'],\n ['package-lock.json', 'npm'],\n];\n\n// Where a value resolved from, following the CLI's priority chain\n// (process.env > .env.local > .env > .bigcommerce/project.json). Flags are\n// excluded because `debug` takes none of the credential flags itself.\nexport type EnvSource = 'process.env' | (typeof ENV_FILES)[number];\nexport type ConfigSource = EnvSource | 'project.json' | 'unset';\n\nexport interface ResolvedValue {\n present: boolean;\n source: ConfigSource;\n}\n\nexport interface Diagnostics {\n cli: {\n name: string;\n version: string;\n };\n runtime: {\n node: string;\n platform: string;\n arch: string;\n osRelease: string;\n packageManager: PackageManager;\n };\n project: {\n cwd: string;\n // The storefront package name + version from the project's package.json,\n // resolved the same way `upgrade` does. `name` identifies the Catalyst\n // family (catalyst-core, catalyst-makeswift, …). null when absent.\n storefrontName: string | null;\n storefrontVersion: string | null;\n projectUuid: string | null;\n isLinked: boolean;\n isTransformed: boolean;\n isFullySetUp: boolean;\n hasMiddleware: boolean;\n hasProxy: boolean;\n hasOpenNextDep: boolean;\n };\n config: {\n storeHash: ResolvedValue;\n accessToken: ResolvedValue;\n projectUuid: ResolvedValue;\n // The API host override. 'unset' means the CLI falls back to its default\n // (api.bigcommerce.com). Resolved like the credentials above.\n apiHost: ResolvedValue;\n // Top-level keys present in .bigcommerce/project.json (names only — values\n // are never included so masked secrets like accessToken can't leak).\n projectJsonKeys: string[];\n // Names of persisted deployment env vars (project.json `env` map keys only).\n storedEnvKeys: string[];\n // Env var name -> where it resolved from ('unset' if nowhere), split by\n // consumer: `cliEnvVars` are read by the CLI, `buildEnvVars` by the Next.js\n // app build. The value is never included, only the source.\n cliEnvVars: Record<string, ConfigSource>;\n buildEnvVars: Record<string, ConfigSource>;\n };\n telemetry: {\n enabled: boolean;\n correlationId: string;\n };\n // Relative path -> whether the file/directory exists on disk. Presence only;\n // contents are never read into the report.\n files: Record<string, boolean>;\n}\n\nexport interface CollectDiagnosticsOptions {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n}\n\n// A value counts as present only when it is a non-empty, non-whitespace string —\n// mirroring how the build treats \"\" the same as unset (see required-build-env.ts).\nconst hasValue = (value: string | undefined): boolean => value !== undefined && value.trim() !== '';\n\ninterface EnvLayer {\n source: EnvSource;\n values: Record<string, string | undefined>;\n}\n\n// Build the ordered env layers the CLI resolves against: the real environment\n// first, then the auto-loaded env files. File values are parsed into memory\n// only to detect presence — they are never surfaced in the report.\nconst buildEnvLayers = (cwd: string, env: NodeJS.ProcessEnv): EnvLayer[] => {\n const layers: EnvLayer[] = [{ source: 'process.env', values: env }];\n\n ENV_FILES.forEach((file) => {\n const path = join(cwd, file);\n\n if (!existsSync(path)) {\n return;\n }\n\n try {\n layers.push({ source: file, values: parse(readFileSync(path, 'utf-8')) });\n } catch {\n // A malformed/unreadable env file shouldn't break the report.\n }\n });\n\n return layers;\n};\n\n// The first layer (process.env > .env.local > .env) that carries a non-empty\n// value for any of the given keys. Returns only the source — never a value.\nconst resolveEnvSource = (layers: EnvLayer[], ...keys: string[]): EnvSource | undefined =>\n layers.find((layer) => keys.some((key) => hasValue(layer.values[key])))?.source;\n\n// Map each named var to the layer it resolves from (or 'unset'), values omitted.\nconst resolveEnvVars = (\n layers: EnvLayer[],\n names: readonly string[],\n): Record<string, ConfigSource> =>\n Object.fromEntries(names.map((name) => [name, resolveEnvSource(layers, name) ?? 'unset']));\n\n// Resolve which source (if any) supplies a credential, without exposing the\n// value itself. Env layers win over project.json, matching build/deploy.\nconst resolveValue = (\n envSource: EnvSource | undefined,\n configValue: string | undefined,\n): ResolvedValue => {\n if (envSource) {\n return { present: true, source: envSource };\n }\n\n if (hasValue(configValue)) {\n return { present: true, source: 'project.json' };\n }\n\n return { present: false, source: 'unset' };\n};\n\nconst asString = (value: unknown): string | undefined =>\n typeof value === 'string' ? value : undefined;\n\nconst lockfileManager = (dir: string): PackageManager | undefined =>\n PROJECT_LOCKFILES.find(([file]) => existsSync(join(dir, file)))?.[1];\n\n// Detect the project's package manager from the nearest lockfile, walking up\n// from cwd so it still works when the CLI is run from a subdirectory (e.g.\n// `core/` in a monorepo, where the lockfile lives at the repo root). Falls back\n// to the manager that invoked the CLI when no lockfile is found anywhere.\nconst detectProjectPackageManager = (cwd: string): PackageManager => {\n let dir = cwd;\n\n for (;;) {\n const match = lockfileManager(dir);\n\n if (match) {\n return match;\n }\n\n const parent = dirname(dir);\n\n if (parent === dir) {\n // Reached the filesystem root without finding a lockfile.\n return detectPackageManager();\n }\n\n dir = parent;\n }\n};\n\n// An open object schema: known credential fields plus any other keys the file\n// may carry, all kept as `unknown` so we can enumerate key names without\n// coercing (or trusting the type of) their values.\nconst projectJsonSchema = z.looseObject({});\n\nconst safeReadJson = (path: string): unknown => {\n try {\n return JSON.parse(readFileSync(path, 'utf-8'));\n } catch {\n return null;\n }\n};\n\n// Read .bigcommerce/project.json as a raw object without going through\n// getProjectConfig() — that instantiates Conf and would create .bigcommerce/ as\n// a side effect (see project-state.ts). Returns null when absent, malformed, or\n// not a JSON object.\nconst readProjectJson = (cwd: string): Record<string, unknown> | null => {\n const result = projectJsonSchema.safeParse(\n safeReadJson(join(cwd, '.bigcommerce', 'project.json')),\n );\n\n return result.success ? result.data : null;\n};\n\n// Mirrors upgrade.ts: `catalyst.version` is the source of truth for the\n// storefront version, falling back to the plain `version`. `name` identifies\n// which Catalyst family the project is on (e.g. @bigcommerce/catalyst-core).\nconst storefrontPackageSchema = z.looseObject({\n name: z.string().optional(),\n version: z.string().optional(),\n catalyst: z.looseObject({ version: z.string().optional() }).optional(),\n});\n\nconst readStorefrontInfo = (cwd: string): { name: string | null; version: string | null } => {\n const result = storefrontPackageSchema.safeParse(safeReadJson(join(cwd, 'package.json')));\n\n if (!result.success) {\n return { name: null, version: null };\n }\n\n return {\n name: result.data.name ?? null,\n version: result.data.catalyst?.version ?? result.data.version ?? null,\n };\n};\n\nconst readStoredEnvKeys = (projectJson: Record<string, unknown> | null): string[] => {\n const env = projectJson?.env;\n\n if (typeof env === 'object' && env !== null && !Array.isArray(env)) {\n return Object.keys(env).sort();\n }\n\n return [];\n};\n\n// Gather a diagnostic snapshot of the CLI, runtime, project, and config state.\n// By construction this never includes secret values — credentials are reported\n// as presence + source only, and file/env checks report existence only.\nexport function collectDiagnostics({\n cwd = process.cwd(),\n env = process.env,\n}: CollectDiagnosticsOptions = {}): Diagnostics {\n const state = getProjectState(cwd);\n const telemetry = getTelemetry();\n const projectJson = readProjectJson(cwd);\n const storefront = readStorefrontInfo(cwd);\n\n // The CLI reads its own config only from the real environment (Commander\n // `.env()` bindings) and .bigcommerce/project.json — never from .env files\n // (see the note in program.ts). Only the storefront BUILD vars are loaded\n // from .env.local/.env, and only by `build`/`deploy`, so only those are\n // resolved across the file layers.\n const cliEnv: EnvLayer[] = [{ source: 'process.env', values: env }];\n const buildEnv = buildEnvLayers(cwd, env);\n\n return {\n cli: {\n name: PACKAGE_INFO.name,\n version: PACKAGE_INFO.version,\n },\n runtime: {\n node: process.version,\n platform: process.platform,\n arch: process.arch,\n osRelease: release(),\n packageManager: detectProjectPackageManager(cwd),\n },\n project: {\n cwd,\n storefrontName: storefront.name,\n storefrontVersion: storefront.version,\n projectUuid: state.projectUuid ?? null,\n isLinked: state.isLinked,\n isTransformed: state.isTransformed,\n isFullySetUp: state.isFullySetUp,\n hasMiddleware: state.hasMiddleware,\n hasProxy: state.hasProxy,\n hasOpenNextDep: state.hasOpenNextDep,\n },\n config: {\n storeHash: resolveValue(\n resolveEnvSource(cliEnv, 'CATALYST_STORE_HASH', 'BIGCOMMERCE_STORE_HASH'),\n asString(projectJson?.storeHash),\n ),\n accessToken: resolveValue(\n resolveEnvSource(cliEnv, 'CATALYST_ACCESS_TOKEN'),\n asString(projectJson?.accessToken),\n ),\n projectUuid: resolveValue(\n resolveEnvSource(cliEnv, 'CATALYST_PROJECT_UUID'),\n asString(projectJson?.projectUuid),\n ),\n apiHost: resolveValue(\n resolveEnvSource(cliEnv, 'CATALYST_API_HOST'),\n asString(projectJson?.apiHost),\n ),\n projectJsonKeys: projectJson ? Object.keys(projectJson).sort() : [],\n storedEnvKeys: readStoredEnvKeys(projectJson),\n cliEnvVars: resolveEnvVars(cliEnv, CLI_ENV_VARS),\n buildEnvVars: resolveEnvVars(buildEnv, BUILD_ENV_VARS),\n },\n telemetry: {\n enabled: telemetry.isEnabled(),\n correlationId: telemetry.correlationId,\n },\n files: {\n '.env.local': existsSync(join(cwd, '.env.local')),\n '.env': existsSync(join(cwd, '.env')),\n '.bigcommerce/project.json': existsSync(join(cwd, '.bigcommerce', 'project.json')),\n '.bigcommerce/wrangler.jsonc': existsSync(join(cwd, '.bigcommerce', 'wrangler.jsonc')),\n '.open-next/': existsSync(join(cwd, '.open-next')),\n 'package.json': existsSync(join(cwd, 'package.json')),\n },\n };\n}\n","import { confirm } from '@inquirer/prompts';\nimport AdmZip from 'adm-zip';\nimport { Command, Option } from 'commander';\nimport { colorize } from 'consola/utils';\nimport { access, readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport yoctoSpinner from 'yocto-spinner';\nimport { z } from 'zod';\n\nimport { assertAuthorized } from '../lib/auth-errors';\nimport { loadBuildEnv } from '../lib/build-env';\nimport { runChannelCheckoutUrlFlow } from '../lib/channel-checkout-url-flow';\nimport { runChannelSiteUrlFlow } from '../lib/channel-site-flow';\nimport {\n cleanupCloudflareIncompatibilities,\n NoLinkedProjectError,\n reconcileOpenNextVersion,\n selectOrCreateInfrastructureProject,\n setupCommerceHosting,\n} from '../lib/commerce-hosting';\nimport { getDeploymentErrorMessage } from '../lib/deployment-errors';\nimport { detectProjectPackageManager } from '../lib/detect-package-manager';\nimport {\n getStoredEnv,\n mergeDeploymentSecrets,\n parseEnvAssignment,\n toDeploymentSecrets,\n} from '../lib/env-config';\nimport { httpError } from '../lib/http-errors';\nimport { installDependencies } from '../lib/install-dependencies';\nimport { consola } from '../lib/logger';\nimport { getProjectConfig } from '../lib/project-config';\nimport { getProjectState } from '../lib/project-state';\nimport { resolveCredentials } from '../lib/resolve-credentials';\nimport {\n accessTokenOption,\n apiHostOption,\n envPathOption,\n projectUuidOption,\n resolveApiHost,\n storeHashOption,\n} from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\n\nimport { buildCatalystProject, parseWranglerVersion, WRANGLER_VERSION } from './build';\n\nconst stepsEnum = z.enum([\n 'initializing',\n 'downloading',\n 'unzipping',\n 'processing',\n 'deploying',\n 'finalizing',\n 'complete',\n]);\n\nconst STEPS: Record<z.infer<typeof stepsEnum>, string> = {\n initializing: 'Initializing...',\n downloading: 'Downloading...',\n unzipping: 'Unzipping...',\n processing: 'Processing...',\n deploying: 'Deploying...',\n finalizing: 'Finalizing...',\n complete: 'Complete',\n};\n\nconst UploadSignatureSchema = z.object({\n data: z.object({\n upload_url: z.url(),\n upload_uuid: z.string(),\n }),\n});\n\nconst CreateDeploymentSchema = z.object({\n data: z.object({\n deployment_uuid: z.uuid(),\n }),\n});\n\nconst ProjectSchema = z.object({\n data: z.array(\n z.object({\n uuid: z.uuid(),\n name: z.string(),\n }),\n ),\n});\n\nconst DeploymentStatusSchema = z.object({\n deployment_uuid: z.uuid(),\n deployment_status: z.enum(['queued', 'in_progress', 'failed', 'completed']),\n event: z\n .object({\n step: stepsEnum,\n progress: z.number(),\n })\n .nullable(),\n deployment_hostnames: z.array(z.string()).optional(),\n error: z\n .object({\n code: z.number(),\n })\n .optional(),\n});\n\nexport const generateBundleZip = async () => {\n consola.info('Generating bundle...');\n\n const bigcommerceDir = join(process.cwd(), '.bigcommerce');\n const distDir = join(process.cwd(), '.bigcommerce', 'dist');\n\n // Check if .bigcommerce/dist exists\n try {\n await access(distDir);\n } catch {\n throw new Error(`Dist directory not found: ${distDir}`);\n }\n\n // Check if .bigcommerce/dist is not empty\n const buildDirContents = await readdir(distDir);\n\n if (buildDirContents.length === 0) {\n throw new Error(`Dist directory is empty: ${distDir}`);\n }\n\n const outputZip = join(bigcommerceDir, 'bundle.zip');\n\n // Use AdmZip to create the zip\n const zip = new AdmZip();\n\n zip.addLocalFolder(distDir, 'output');\n zip.writeZip(outputZip);\n\n consola.success(`Bundle created at: ${outputZip}`);\n};\n\nexport const generateUploadSignature = async (\n storeHash: string,\n accessToken: string,\n apiHost: string,\n) => {\n consola.info('Generating upload signature...');\n\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/deployments/uploads`,\n {\n method: 'POST',\n headers: {\n 'X-Auth-Token': accessToken,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'X-Correlation-Id': getTelemetry().correlationId,\n },\n body: JSON.stringify({}),\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to generate upload signature');\n }\n\n const res: unknown = await response.json();\n const { data } = UploadSignatureSchema.parse(res);\n\n consola.success('Upload signature generated.');\n\n return data;\n};\n\nexport const uploadBundleZip = async (uploadUrl: string) => {\n consola.info('Uploading bundle...');\n\n const zipPath = join(process.cwd(), '.bigcommerce', 'bundle.zip');\n\n // Read the zip file as a buffer\n const fileBuffer = await readFile(zipPath);\n\n const response = await fetch(uploadUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/zip',\n },\n body: fileBuffer,\n });\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to upload bundle');\n }\n\n consola.success('Bundle uploaded successfully.');\n\n return true;\n};\n\nexport const parseEnvironmentVariables = (secretOption?: string[]) => {\n return secretOption?.map((envVar) => {\n const { key, value } = parseEnvAssignment(envVar);\n\n return {\n type: 'secret' as const,\n key,\n value,\n };\n });\n};\n\nexport const createDeployment = async (\n projectUuid: string,\n uploadUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n environmentVariables?: Array<{ type: 'secret' | 'plain_text'; key: string; value: string }>,\n) => {\n consola.info('Creating deployment...');\n\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/deployments`,\n {\n method: 'POST',\n headers: {\n 'X-Auth-Token': accessToken,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'X-Correlation-Id': getTelemetry().correlationId,\n },\n body: JSON.stringify({\n project_uuid: projectUuid,\n upload_uuid: uploadUuid,\n environment_variables: environmentVariables,\n }),\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to create deployment');\n }\n\n const res: unknown = await response.json();\n const { data } = CreateDeploymentSchema.parse(res);\n\n consola.success('Deployment started...');\n\n return data;\n};\n\nexport const getDeploymentStatus = async (\n deploymentUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<string | undefined> => {\n consola.info('Fetching deployment status...');\n\n const spinner = yoctoSpinner().start('Fetching...');\n\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/deployments/${deploymentUuid}/events`,\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n Accept: 'text/event-stream',\n Connection: 'keep-alive',\n 'X-Correlation-Id': getTelemetry().correlationId,\n },\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to open deployment event stream');\n }\n\n const reader = response.body?.getReader();\n\n if (!reader) {\n throw new Error('Failed to read event stream.');\n }\n\n const decoder = new TextDecoder();\n let done = false;\n let deploymentHostname: string | undefined;\n\n while (!done) {\n // eslint-disable-next-line no-await-in-loop\n const { value, done: streamDone } = await reader.read();\n let json: unknown;\n\n if (value) {\n const chunk = decoder.decode(value, { stream: true }).trim();\n const split = chunk\n .split('\\n\\n')\n .map((s) => s.replace('data:', '').trim())\n .filter(Boolean);\n\n // eslint-disable-next-line no-loop-func\n split.forEach((event) => {\n try {\n json = JSON.parse(event);\n } catch (error) {\n consola.warn(`Failed to parse event, dropping from stream. Event: ${event}`, error);\n\n return;\n }\n\n const data = DeploymentStatusSchema.parse(json);\n\n if (data.error) {\n throw new Error(\n `Deployment failed (error code ${data.error.code}): ${getDeploymentErrorMessage(data.error.code)}`,\n );\n }\n\n if (data.event && STEPS[data.event.step] !== spinner.text) {\n spinner.text = STEPS[data.event.step];\n }\n\n if (data.deployment_hostnames && data.deployment_hostnames.length > 0) {\n deploymentHostname = data.deployment_hostnames[0];\n }\n });\n }\n\n done = streamDone;\n }\n\n spinner.success('Deployment completed successfully.');\n\n if (deploymentHostname) {\n consola.success(\n `View your deployment at: ${colorize('blue', `https://${deploymentHostname}`)}`,\n );\n }\n\n return deploymentHostname;\n};\n\nexport const fetchProject = async (\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n) => {\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/projects`,\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'X-Correlation-Id': getTelemetry().correlationId,\n },\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch projects');\n }\n\n const res: unknown = await response.json();\n const { data } = ProjectSchema.parse(res);\n\n return data.find((project) => project.uuid === projectUuid);\n};\n\nexport const deploy = new Command('deploy')\n .configureHelp({ showGlobalOptions: true })\n .description('Deploy your application to Cloudflare.')\n .addHelpText(\n 'after',\n `\nEnvironment variables saved with \\`catalyst env add\\` are sent automatically on every deploy.\nUse \\`--secret\\` to set or override a variable for a single run.\n\nExample:\n $ catalyst deploy --secret BIGCOMMERCE_STORE_HASH=<YOUR_STORE_HASH> --secret BIGCOMMERCE_STOREFRONT_TOKEN=<YOUR_STOREFRONT_TOKEN>`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option(\n '--update-site-url',\n \"After a successful deploy, prompt to update a channel's site URL to the new hostname.\",\n )\n .option(\n '--update-checkout-url',\n \"After a successful deploy, prompt to update a channel's checkout URL.\",\n )\n .addOption(\n new Option(\n '--secret <value>',\n 'Secret to set for this deployment (repeatable). Overrides a stored value for the same key. Format: --secret KEY=VALUE',\n ).argParser((value: string, previous: string[] = []) => {\n return previous.concat([value]);\n }),\n )\n .option('--dry-run', 'Run the command to generate the bundle without uploading or deploying.')\n .option(\n '--prebuilt',\n 'Skip the build step. Requires .bigcommerce/dist/ to already contain build output.',\n )\n .addOption(\n new Option(\n '--wrangler-version <version>',\n `Wrangler version or dist-tag to build with. Ignored with --prebuilt. Defaults to ${WRANGLER_VERSION}.`,\n ).argParser(parseWranglerVersion),\n )\n .addOption(envPathOption())\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n const telemetry = getTelemetry();\n\n await telemetry.identify(storeHash);\n\n // Resolve a *valid* projectUuid before doing any expensive build/upload\n // work. If the linked UUID no longer exists on the server (e.g. project\n // deleted out from under us), prompt the user to pick a new one rather\n // than failing mid-deploy.\n const linkedProjectUuid = options.projectUuid ?? config.get('projectUuid');\n let projectUuid: string;\n\n const promptForProject = async (): Promise<{ uuid: string; name: string }> => {\n try {\n return await selectOrCreateInfrastructureProject({\n storeHash,\n accessToken,\n apiHost,\n });\n } catch (error) {\n if (error instanceof NoLinkedProjectError) {\n consola.info(\n \"When you're ready to create a project, run `catalyst projects create` or re-run `catalyst deploy`.\",\n );\n process.exit(0);\n }\n\n throw error;\n }\n };\n\n if (linkedProjectUuid) {\n const existing = await fetchProject(linkedProjectUuid, storeHash, accessToken, apiHost);\n\n if (existing) {\n projectUuid = linkedProjectUuid;\n } else {\n consola.warn(\n `The linked project (${linkedProjectUuid}) no longer exists on this store. It may have been deleted.`,\n );\n\n const selected = await promptForProject();\n\n projectUuid = selected.uuid;\n config.set('projectUuid', projectUuid);\n consola.success(`Linked project \"${selected.name}\".`);\n }\n } else {\n consola.info('No project is currently linked.');\n\n const selected = await promptForProject();\n\n projectUuid = selected.uuid;\n config.set('projectUuid', projectUuid);\n consola.success(`Linked project \"${selected.name}\".`);\n }\n\n // The OpenNext build pipeline requires the project to be transformed\n // (proxy.ts → middleware.ts, @opennextjs/cloudflare installed). Run setup\n // here so first-run `catalyst deploy` works on a fresh self-hosted scaffold\n // without forcing the user to re-run after a separate setup step.\n if (!getProjectState().isTransformed) {\n const shouldSetup = await confirm({\n message:\n 'Your project is not yet set up for Commerce Hosting deployments. Would you like to run the Commerce Hosting setup now?',\n default: true,\n });\n\n if (!shouldSetup) {\n consola.info(\"When you're ready to deploy, re-run `catalyst deploy` to complete setup.\");\n process.exit(0);\n }\n\n const projectDir = process.cwd();\n\n await setupCommerceHosting({ projectDir, projectUuid, storeHash, accessToken });\n consola.success('Commerce Hosting setup complete.');\n\n // Match the manager the project was scaffolded with (from its lockfile),\n // rather than forcing pnpm on npm/yarn/bun projects.\n const packageManager = await detectProjectPackageManager(projectDir);\n\n await installDependencies(projectDir, packageManager);\n } else {\n // Existing Commerce Hosting users may carry artifacts incompatible with\n // the Cloudflare worker bundle from earlier Catalyst versions\n // (`core/instrumentation.ts`, `@vercel/otel`). Sweep them on every deploy\n // so the fix lands without forcing a re-link.\n await cleanupCloudflareIncompatibilities(process.cwd());\n\n // The build path offers to move a stale adapter pin. `--prebuilt` skips\n // the build, so surface it here instead -- without changing dependencies\n // the existing bundle was never compiled against.\n if (options.prebuilt) {\n const projectDir = process.cwd();\n\n await reconcileOpenNextVersion(projectDir, await detectProjectPackageManager(projectDir), {\n canUpgrade: false,\n });\n }\n }\n\n if (options.prebuilt) {\n const distDir = join(process.cwd(), '.bigcommerce', 'dist');\n\n try {\n await access(distDir);\n } catch {\n throw new Error(\n 'No build output found at .bigcommerce/dist/. Run `catalyst build` first or remove `--prebuilt` to build automatically.',\n );\n }\n\n const contents = await readdir(distDir);\n\n if (contents.length === 0) {\n throw new Error(\n 'No build output found at .bigcommerce/dist/. Run `catalyst build` first or remove `--prebuilt` to build automatically.',\n );\n }\n\n consola.info('Using existing build output (--prebuilt).');\n } else {\n // The build reads storefront env vars (BIGCOMMERCE_*). Load them from the\n // env file(s) before building so both the build and any pre-build checks\n // see them. Skipped for --prebuilt above, which doesn't run the build.\n loadBuildEnv({ envPath: options.envPath });\n\n await buildCatalystProject(projectUuid, options.wranglerVersion);\n }\n\n await generateBundleZip();\n\n if (options.dryRun) {\n consola.info('Dry run enabled — skipping upload and deployment steps.');\n consola.info('Next steps (skipped):');\n consola.info('- Generate upload signature');\n consola.info('- Upload bundle.zip');\n consola.info('- Create deployment');\n\n process.exit(0);\n }\n\n const uploadSignature = await generateUploadSignature(storeHash, accessToken, apiHost);\n\n await uploadBundleZip(uploadSignature.upload_url);\n\n // Merge persisted env vars (`catalyst env add`) with any inline `--secret`\n // flags. Inline flags win on conflict, letting users override a stored\n // value for a single run. Send `undefined` when there's nothing to set so\n // we preserve the prior payload shape.\n const flagSecrets = parseEnvironmentVariables(options.secret) ?? [];\n const persistedSecrets = toDeploymentSecrets(getStoredEnv(config));\n const mergedSecrets = mergeDeploymentSecrets(persistedSecrets, flagSecrets);\n const environmentVariables = mergedSecrets.length > 0 ? mergedSecrets : undefined;\n\n const { deployment_uuid: deploymentUuid } = await createDeployment(\n projectUuid,\n uploadSignature.upload_uuid,\n storeHash,\n accessToken,\n apiHost,\n environmentVariables,\n );\n\n const deploymentHostname = await getDeploymentStatus(\n deploymentUuid,\n storeHash,\n accessToken,\n apiHost,\n );\n\n // Soft-failed: the bundle is already live, so a non-zero exit here would\n // misrepresent what happened.\n const warnChannelFlowFailed = (what: string, error: unknown) => {\n consola.warn(\n `Failed to update channel ${what}: ${error instanceof Error ? error.message : String(error)}`,\n );\n consola.info(\n 'Update it manually in the control panel, or re-run `catalyst auth login` if the token is missing the store_channel_settings scope.',\n );\n };\n\n // Carried over so both flags don't ask which channel twice.\n let resolvedChannelId: number | undefined;\n\n if (options.updateSiteUrl) {\n try {\n ({ channelId: resolvedChannelId } = await runChannelSiteUrlFlow({\n storeHash,\n accessToken,\n apiHost,\n projectUuid,\n preferHostname: deploymentHostname,\n }));\n } catch (error) {\n warnChannelFlowFailed('site URL', error);\n }\n }\n\n if (options.updateCheckoutUrl) {\n try {\n await runChannelCheckoutUrlFlow({\n storeHash,\n accessToken,\n apiHost,\n channelId: resolvedChannelId,\n });\n } catch (error) {\n warnChannelFlowFailed('checkout URL', error);\n }\n }\n });\n","const ERROR_MESSAGES: Record<number, string> = {\n 10: 'Something went wrong on our end. Please try again. If the issue persists, contact support.',\n 20: \"We couldn't retrieve your bundle. This is usually a temporary issue — please try deploying again. If the problem continues, contact support.\",\n 30: 'Your bundle could not be extracted. This may mean your build output is too large (max 64 MB compressed / 512 MB uncompressed) or the archive is corrupted. Try reducing your build size or rebuilding your project and deploying again.',\n 40: `There's a problem with your build output. This could be caused by:\n- A worker.js file larger than 40 MB\n- An individual asset file larger than 25 MB\n- More than 1,000 total files in the bundle`,\n 50: 'Deployment failed. This is usually a temporary issue — please try again. If the problem persists, contact support.',\n 60: \"Your code was deployed, but we couldn't determine your deployment URL. Please try deploying again. If the issue persists, contact support.\",\n};\n\nexport function getDeploymentErrorMessage(code: number): string {\n return (\n ERROR_MESSAGES[code] ??\n `Deployment failed with an unexpected error (code: ${code}). Please try again. If the issue persists, contact support.`\n );\n}\n","import { confirm, select } from '@inquirer/prompts';\nimport { Command, Option } from 'commander';\nimport { colorize } from 'consola/utils';\n\nimport {\n claimDomain,\n CreatedDomain,\n createDomain,\n deleteDomain,\n Domain,\n DomainBoundToProjectError,\n DomainOwnershipVerificationError,\n DomainStatus,\n DomainStatusFilter,\n findDomain,\n getDomain,\n listDomains,\n OwnershipVerification,\n PointingRecords,\n transferDomain,\n} from '../lib/domains';\nimport { UserActionableError } from '../lib/errors';\nimport { consola } from '../lib/logger';\nimport { fetchProjects } from '../lib/project';\nimport { getProjectConfig } from '../lib/project-config';\nimport { resolveCredentials } from '../lib/resolve-credentials';\nimport {\n accessTokenOption,\n apiHostOption,\n projectUuidOption,\n resolveApiHost,\n resolveProjectUuid,\n storeHashOption,\n} from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\n\nconst WAIT_INTERVAL_MS = 5000;\nconst WAIT_TIMEOUT_MS = 5 * 60 * 1000;\nconst DOMAIN_STATUS_FILTERS: DomainStatusFilter[] = ['pending', 'verified', 'failed'];\nconst RECORD_TYPE_WIDTH = 'CNAME'.length;\n\nconst STATUS_COLORS: Record<DomainStatus, Parameters<typeof colorize>[0]> = {\n pending: 'yellow',\n verified: 'green',\n failed: 'red',\n unknown: 'gray',\n};\n\nconst STATUS_LABELS: Record<DomainStatus, string> = {\n pending: 'pending',\n verified: 'active',\n failed: 'failed',\n unknown: 'unknown',\n};\n\ninterface DomainCommandContext {\n projectUuid: string;\n storeHash: string;\n accessToken: string;\n apiHost: string;\n}\n\ninterface DomainCommandOptions {\n storeHash?: string;\n accessToken?: string;\n apiHost?: string;\n projectUuid?: string;\n}\n\ninterface WaitForDomainVerificationOptions extends DomainCommandContext {\n domain: string;\n intervalMs?: number;\n timeoutMs?: number;\n}\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nfunction resolveDomainCommandContext(options: DomainCommandOptions): DomainCommandContext {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n const projectUuid = resolveProjectUuid(options);\n\n return {\n projectUuid,\n storeHash,\n accessToken,\n apiHost,\n };\n}\n\n// Resolves the destination project for a transfer. Uses `--to-project-uuid`\n// when given; otherwise fetches the store's projects and prompts the user to\n// pick one, excluding the source project (a domain can't be transferred to the\n// project it already belongs to).\nasync function resolveDestinationProject(\n domain: string,\n context: DomainCommandContext,\n toProjectUuid?: string,\n): Promise<string> {\n if (toProjectUuid) {\n if (toProjectUuid === context.projectUuid) {\n throw new UserActionableError('The destination project must differ from the source project.');\n }\n\n return toProjectUuid;\n }\n\n consola.start('Fetching projects...');\n\n const projects = await fetchProjects(context.storeHash, context.accessToken, context.apiHost);\n\n consola.success('Projects fetched.');\n\n const destinations = projects.filter((project) => project.uuid !== context.projectUuid);\n\n if (destinations.length === 0) {\n throw new UserActionableError(\n 'No other projects to transfer to. Create another project with `catalyst projects create` first.',\n );\n }\n\n return select({\n message: `Select the project to transfer ${domain} to (Press <enter> to select).`,\n choices: destinations.map((project) => ({\n name: project.name,\n value: project.uuid,\n description: project.uuid,\n })),\n });\n}\n\nexport function formatDomainStatus(status: DomainStatus): string {\n return colorize(STATUS_COLORS[status], STATUS_LABELS[status]);\n}\n\nexport function formatDomain(domain: Domain): string {\n return `${domain.domain} ${formatDomainStatus(domain.verification_status)}`;\n}\n\n// Renders the records to publish as an indented block:\n//\n// A 198.51.100.10\n// CNAME shop.hosting.bigcommerce.com\n//\n// Returns null when there's nothing publishable: the API withholds the records\n// until the domain is bound, and nulls individual values it doesn't have.\nexport function formatPointingRecords(records?: PointingRecords | null): string | null {\n const rows: string[] = [];\n\n if (records?.a_record_value) {\n rows.push(`${'A'.padEnd(RECORD_TYPE_WIDTH)} ${records.a_record_value}`);\n }\n\n if (records?.cname_record_value) {\n rows.push(`${'CNAME'.padEnd(RECORD_TYPE_WIDTH)} ${records.cname_record_value}`);\n }\n\n if (rows.length === 0) {\n return null;\n }\n\n return rows.map((row) => ` ${row}`).join('\\n');\n}\n\nexport function formatOwnershipVerification(record: OwnershipVerification): string {\n const lines = [\n 'Add this DNS record to verify ownership:',\n ` Type: ${record.type}`,\n ` Name: ${record.name}`,\n ];\n\n if (record.value) {\n lines.push(` Value: ${record.value}`);\n }\n\n return lines.join('\\n');\n}\n\nexport async function waitForDomainVerification({\n domain,\n projectUuid,\n storeHash,\n accessToken,\n apiHost,\n intervalMs = WAIT_INTERVAL_MS,\n timeoutMs = WAIT_TIMEOUT_MS,\n}: WaitForDomainVerificationOptions): Promise<Domain> {\n const startedAt = Date.now();\n let current = await getDomain(domain, projectUuid, storeHash, accessToken, apiHost);\n\n while (current.verification_status === 'pending' && Date.now() - startedAt < timeoutMs) {\n // eslint-disable-next-line no-await-in-loop\n await sleep(intervalMs);\n // eslint-disable-next-line no-await-in-loop\n current = await getDomain(domain, projectUuid, storeHash, accessToken, apiHost);\n }\n\n return current;\n}\n\nconst add = new Command('add')\n .configureHelp({ showGlobalOptions: true })\n .description('Add a custom domain to the current Native Hosting project.')\n .argument('<domain>', 'Custom domain to add.')\n .addHelpText(\n 'after',\n `\nThe DNS records that point the domain at this project are printed once the domain\nis added. They are returned only by this command, so save them: publish the CNAME\nfor a subdomain, or the A record for an apex domain.\n\nExamples:\n $ catalyst domains add www.example.com\n\n # Wait until the domain leaves pending verification\n $ catalyst domains add www.example.com --wait`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--wait', 'Poll until domain verification completes or times out.')\n .action(async (domain, options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n consola.start(`Adding domain ${domain}...`);\n\n let created: CreatedDomain;\n\n try {\n created = await createDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n } catch (error) {\n if (error instanceof DomainOwnershipVerificationError) {\n consola.warn(`${domain} is already in use on another store.`);\n consola.log(formatOwnershipVerification(error.ownershipVerification));\n consola.info('Once the record is live, claim it with:');\n consola.log(` catalyst domains claim ${domain}`);\n process.exit(1);\n\n return;\n }\n\n if (error instanceof DomainBoundToProjectError) {\n consola.warn(`${domain} is already bound to another project in this store.`);\n consola.info('To move it to this project, run:');\n consola.log(\n ` catalyst domains transfer ${domain} --project-uuid ${error.projectUuid} --to-project-uuid ${context.projectUuid}`,\n );\n process.exit(1);\n\n return;\n }\n\n throw error;\n }\n\n consola.success(`Domain ${created.domain} added.`);\n\n // Only the create response carries the records, so they're read from\n // `created` rather than from `result` — polling re-fetches the domain\n // resource, which doesn't include them.\n const records = formatPointingRecords(created.pointing_records);\n let result: Domain = created;\n\n if (options.wait && result.verification_status === 'pending') {\n consola.start(`Waiting for ${result.domain} to verify...`);\n result = await waitForDomainVerification({ domain: result.domain, ...context });\n }\n\n consola.log(formatDomain(result));\n\n if (records) {\n consola.info(`Point ${created.domain} at this project with one of these DNS records:`);\n consola.log(records);\n consola.info(\n 'Use the CNAME for a subdomain, or the A record for an apex domain. Save them now — only `domains add` returns them.',\n );\n }\n\n if (result.verification_status === 'pending') {\n consola.info(\n `Run \\`catalyst domains status ${result.domain}\\` to check verification progress.`,\n );\n }\n\n process.exit(0);\n });\n\nconst list = new Command('list')\n .configureHelp({ showGlobalOptions: true })\n .description('List custom domains for the current Native Hosting project.')\n .addHelpText(\n 'after',\n `\nExamples:\n $ catalyst domains list\n\n # Show pending domains only\n $ catalyst domains list --status pending`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--domain <domain>', 'Only show a specific domain.')\n .addOption(\n new Option('--status <status>', 'Filter by verification status.').choices(\n DOMAIN_STATUS_FILTERS,\n ),\n )\n .action(async (options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n consola.start('Fetching domains...');\n\n const result = await listDomains(\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n {\n domains: options.domain ? [options.domain] : undefined,\n verificationStatus: options.status,\n },\n );\n\n consola.success('Domains fetched.');\n\n if (result.length === 0) {\n consola.info('No custom domains found.');\n process.exit(0);\n\n return;\n }\n\n result.forEach((item) => consola.log(formatDomain(item)));\n process.exit(0);\n });\n\nconst showStatus = new Command('status')\n .configureHelp({ showGlobalOptions: true })\n .description('Show the status of a custom domain on the current Native Hosting project.')\n .argument('<domain>', 'Custom domain to check.')\n .addHelpText(\n 'after',\n `\nExamples:\n $ catalyst domains status www.example.com\n\n # Wait until the domain leaves pending verification\n $ catalyst domains status www.example.com --wait`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--wait', 'Poll until domain verification completes or times out.')\n .action(async (domain, options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n consola.start(`Fetching status for ${domain}...`);\n\n let result = await getDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n consola.success('Domain status fetched.');\n\n if (options.wait && result.verification_status === 'pending') {\n consola.start(`Waiting for ${result.domain} to verify...`);\n result = await waitForDomainVerification({ domain: result.domain, ...context });\n }\n\n consola.log(formatDomain(result));\n process.exit(0);\n });\n\nconst claim = new Command('claim')\n .configureHelp({ showGlobalOptions: true })\n .description('Claim a custom domain that is currently in use on another store.')\n .argument('<domain>', 'Custom domain to claim.')\n .addHelpText(\n 'after',\n `\nClaiming requires publishing the ownership-verification TXT record returned when\nyou try to add a domain that is already in use on another store. Publish the\nrecord with your DNS provider, then run this command to complete the claim.\n\nExamples:\n $ catalyst domains claim www.example.com\n\n # Wait until the claimed domain leaves pending verification\n $ catalyst domains claim www.example.com --wait`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--wait', 'Poll until domain verification completes or times out.')\n .action(async (domain, options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n consola.start(`Claiming domain ${domain}...`);\n\n try {\n await claimDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n } catch (error) {\n if (error instanceof DomainOwnershipVerificationError) {\n consola.warn(`Ownership of ${domain} could not be verified yet.`);\n consola.log(formatOwnershipVerification(error.ownershipVerification));\n consola.info('Once the record is live, run the claim again:');\n consola.log(` catalyst domains claim ${domain}`);\n process.exit(1);\n\n return;\n }\n\n throw error;\n }\n\n consola.success(`Domain ${domain} claimed.`);\n\n let result = await getDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n if (options.wait && result.verification_status === 'pending') {\n consola.start(`Waiting for ${result.domain} to verify...`);\n result = await waitForDomainVerification({ domain: result.domain, ...context });\n }\n\n consola.log(formatDomain(result));\n process.exit(0);\n });\n\nconst transfer = new Command('transfer')\n .configureHelp({ showGlobalOptions: true })\n .description('Transfer a custom domain to another project in the same store.')\n .argument('<domain>', 'Custom domain to transfer.')\n .addHelpText(\n 'after',\n `\nThe domain is transferred from the current project to the destination project.\nOmit --to-project-uuid to pick the destination from a list of your projects.\n\nExamples:\n # Pick the destination project interactively\n $ catalyst domains transfer www.example.com\n\n # Transfer to a specific project\n $ catalyst domains transfer www.example.com --to-project-uuid <uuid>`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--to-project-uuid <uuid>', 'Destination project UUID. Prompts to choose one if omitted.')\n .option('--wait', 'Poll until domain verification completes or times out.')\n .action(async (domain, options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n // Confirm the domain is on the source project before doing anything else.\n // `transfer` moves a domain *from* the current project, so a domain that\n // lives elsewhere can't be transferred from here — catch it now instead of\n // letting the API reject the transfer with an opaque ownership error after\n // the user has already picked a destination.\n consola.start(`Checking ${domain} on the current project...`);\n\n const owned = await findDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n if (!owned) {\n // The domain isn't on the linked project. Scan the store's other projects\n // so we can point the user at the exact owner — `domains list` only shows\n // the *current* project's domains, so it can't help them find where the\n // domain actually lives.\n consola.start(`Locating the project that owns ${domain}...`);\n\n const projects = await fetchProjects(context.storeHash, context.accessToken, context.apiHost);\n const candidates = projects.filter((project) => project.uuid !== context.projectUuid);\n const matches = await Promise.all(\n candidates.map(async (project) => ({\n project,\n found: await findDomain(\n domain,\n project.uuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n ),\n })),\n );\n const owner = matches.find((match) => match.found)?.project;\n\n if (!owner) {\n throw new UserActionableError(\n `${domain} isn't on any project in this store. If it's in use on another store, ` +\n `claim it with \\`catalyst domains claim ${domain}\\`; otherwise double-check the domain name.`,\n );\n }\n\n const toSuffix = options.toProjectUuid ? ` --to-project-uuid ${options.toProjectUuid}` : '';\n\n consola.warn(\n `${domain} is on project \"${owner.name}\" (${owner.uuid}), not the current project.`,\n );\n consola.info('Re-run the transfer from that project:');\n consola.log(` catalyst domains transfer ${domain} --project-uuid ${owner.uuid}${toSuffix}`);\n process.exit(1);\n\n return;\n }\n\n consola.success(`${domain} found on the current project.`);\n\n const newProjectUuid = await resolveDestinationProject(domain, context, options.toProjectUuid);\n\n consola.start(`Transferring domain ${domain}...`);\n\n await transferDomain(\n domain,\n context.projectUuid,\n newProjectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n consola.success(`Domain ${domain} transferred.`);\n\n let result = await getDomain(\n domain,\n newProjectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n if (options.wait && result.verification_status === 'pending') {\n consola.start(`Waiting for ${result.domain} to verify...`);\n result = await waitForDomainVerification({\n domain: result.domain,\n projectUuid: newProjectUuid,\n storeHash: context.storeHash,\n accessToken: context.accessToken,\n apiHost: context.apiHost,\n });\n }\n\n consola.log(formatDomain(result));\n process.exit(0);\n });\n\nconst remove = new Command('remove')\n .configureHelp({ showGlobalOptions: true })\n .description('Remove a custom domain from the current Native Hosting project.')\n .argument('<domain>', 'Custom domain to remove.')\n .addHelpText(\n 'after',\n `\nExamples:\n $ catalyst domains remove www.example.com\n\n # Skip confirmation for an active domain\n $ catalyst domains remove www.example.com --force`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--force', 'Skip the confirmation prompt before removing an active domain.')\n .action(async (domain, options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n consola.start(`Fetching status for ${domain}...`);\n\n const current = await getDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n if (current.verification_status === 'verified' && !options.force) {\n const confirmed = await confirm({\n message: `Remove active domain ${current.domain}? Traffic may stop routing to this project.`,\n default: false,\n });\n\n if (!confirmed) {\n consola.info('Aborted. No domain was removed.');\n process.exit(0);\n\n return;\n }\n }\n\n consola.start(`Removing domain ${current.domain}...`);\n\n await deleteDomain(\n current.domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n consola.success(`Domain ${current.domain} removed.`);\n process.exit(0);\n });\n\nexport const domains = new Command('domains')\n .alias('domain')\n .configureHelp({ showGlobalOptions: true })\n .description('Manage custom domains for the current Native Hosting project.')\n .addCommand(add)\n .addCommand(list)\n .addCommand(showStatus)\n .addCommand(claim)\n .addCommand(transfer)\n .addCommand(remove);\n","/* eslint-disable max-classes-per-file -- the two domain-collision error types are co-located with the response parsing that throws them */\nimport { z } from 'zod';\n\nimport { assertAuthorized } from './auth-errors';\nimport { UserActionableError } from './errors';\nimport { formatV3Error } from './observability';\nimport { getTelemetry } from './telemetry';\n\nexport const domainStatusSchema = z.enum(['pending', 'verified', 'failed', 'unknown']);\n\nexport type DomainStatus = z.infer<typeof domainStatusSchema>;\n\n// The DNS records the merchant publishes to point a domain at their project.\n// The API sends `pointing_records: null` until the domain is bound and the\n// records are known, and nulls individual values it doesn't have, so every\n// field is treated as optional.\nconst pointingRecordsSchema = z.object({\n a_record_value: z.string().nullish(),\n cname_record_value: z.string().nullish(),\n});\n\nexport type PointingRecords = z.infer<typeof pointingRecordsSchema>;\n\nconst domainSchema = z.object({\n domain: z.string(),\n project_uuid: z.string(),\n verification_status: domainStatusSchema,\n});\n\n// Only the create endpoint returns the records — they're layered onto the domain\n// resource in that one response, so the domain shape itself stays without them.\n// A caller that doesn't keep them can't fetch them again.\nconst createdDomainSchema = domainSchema.extend({\n pointing_records: pointingRecordsSchema.nullish(),\n});\n\nconst ownershipVerificationSchema = z.object({\n type: z.string(),\n name: z.string(),\n value: z.string().optional(),\n});\n\nexport type OwnershipVerification = z.infer<typeof ownershipVerificationSchema>;\n\nconst ownershipVerificationMetaSchema = z.object({\n meta: z.object({\n ownership_verification: ownershipVerificationSchema,\n }),\n});\n\n// Raised when the Domains API rejects an add/claim because ownership of a\n// domain bound to another store has not been verified. Carries the TXT record\n// the caller must publish so the command can render actionable next steps\n// instead of an opaque error.\nexport class DomainOwnershipVerificationError extends UserActionableError {\n readonly ownershipVerification: OwnershipVerification;\n\n constructor(message: string, ownershipVerification: OwnershipVerification) {\n super(message);\n this.name = 'DomainOwnershipVerificationError';\n this.ownershipVerification = ownershipVerification;\n }\n}\n\nfunction parseOwnershipVerification(body: unknown): OwnershipVerification | undefined {\n const parsed = ownershipVerificationMetaSchema.safeParse(body);\n\n return parsed.success ? parsed.data.meta.ownership_verification : undefined;\n}\n\nconst boundProjectMetaSchema = z.object({\n meta: z.object({\n project_uuid: z.string(),\n }),\n});\n\n// Raised when the Domains API rejects an add/claim because the domain is\n// already bound to a different project in the *same* store. Carries the UUID of\n// that project so the caller can point the user at `domains transfer`.\nexport class DomainBoundToProjectError extends UserActionableError {\n readonly projectUuid: string;\n\n constructor(message: string, projectUuid: string) {\n super(message);\n this.name = 'DomainBoundToProjectError';\n this.projectUuid = projectUuid;\n }\n}\n\nfunction parseBoundProjectUuid(body: unknown): string | undefined {\n const parsed = boundProjectMetaSchema.safeParse(body);\n\n return parsed.success ? parsed.data.meta.project_uuid : undefined;\n}\n\nconst domainResponseSchema = z.object({\n data: domainSchema,\n});\n\nconst createdDomainResponseSchema = z.object({\n data: createdDomainSchema,\n});\n\nconst domainListResponseSchema = z.object({\n data: z.array(domainSchema),\n});\n\nexport type Domain = z.infer<typeof domainSchema>;\nexport type CreatedDomain = z.infer<typeof createdDomainSchema>;\nexport type DomainStatusFilter = Exclude<DomainStatus, 'unknown'>;\n\ninterface ListDomainsFilters {\n domains?: string[];\n verificationStatus?: DomainStatusFilter;\n}\n\nconst DOMAINS_API_NOT_ENABLED =\n 'Infrastructure Domains API not enabled. If you are part of the beta, contact support@bigcommerce.com to enable it.';\n\nfunction domainsUrl(storeHash: string, projectUuid: string, apiHost: string) {\n return `https://${apiHost}/stores/${storeHash}/v3/infrastructure/projects/${projectUuid}/domains`;\n}\n\nfunction domainUrl(storeHash: string, projectUuid: string, domain: string, apiHost: string) {\n return `${domainsUrl(storeHash, projectUuid, apiHost)}/${encodeURIComponent(domain)}`;\n}\n\nfunction domainClaimUrl(storeHash: string, projectUuid: string, domain: string, apiHost: string) {\n return `${domainUrl(storeHash, projectUuid, domain, apiHost)}/claim`;\n}\n\nfunction domainTransferUrl(\n storeHash: string,\n projectUuid: string,\n domain: string,\n apiHost: string,\n) {\n return `${domainUrl(storeHash, projectUuid, domain, apiHost)}/transfer`;\n}\n\nfunction authHeaders(accessToken: string) {\n return {\n Accept: 'application/json',\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n };\n}\n\nfunction formatResponseStatus(response: Response, message?: string): string {\n return [response.status, response.statusText || message].filter(Boolean).join(' ');\n}\n\nfunction buildErrorMessage(response: Response, body: unknown, action: string): string {\n const message = formatV3Error(body);\n\n if (response.status >= 500) {\n const status = formatResponseStatus(response, message);\n\n return `${action}: ${status}. This is a server-side response from the Domains API.`;\n }\n\n return message ?? `${action}: ${response.statusText}`;\n}\n\n// Throws for any non-OK Domains API response. Surfaces typed errors for the two\n// claimable/movable conflicts so callers can guide the user: a\n// `meta.ownership_verification` TXT record (domain on another store → claim) or\n// a `meta.project_uuid` (domain on another project in this store → transfer).\n// Otherwise throws a plain formatted error.\nasync function assertDomainResponse(response: Response, action: string): Promise<void> {\n assertAuthorized(response);\n\n if (response.status === 403) {\n throw new UserActionableError(DOMAINS_API_NOT_ENABLED);\n }\n\n if (response.ok) {\n return;\n }\n\n const body: unknown = await response.json().catch(() => null);\n const message = buildErrorMessage(response, body, action);\n const ownershipVerification = parseOwnershipVerification(body);\n\n if (ownershipVerification) {\n throw new DomainOwnershipVerificationError(message, ownershipVerification);\n }\n\n const boundProjectUuid = parseBoundProjectUuid(body);\n\n if (boundProjectUuid) {\n throw new DomainBoundToProjectError(message, boundProjectUuid);\n }\n\n // 5xx responses are server-side failures worth escalating, so keep the\n // Correlation ID + support framing. A 4xx (validation, not-found, conflict)\n // is a clear, user-actionable response — surface just the message.\n if (response.status >= 500) {\n throw new Error(message);\n }\n\n throw new UserActionableError(message);\n}\n\nexport async function createDomain(\n domain: string,\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<CreatedDomain> {\n const response = await fetch(domainsUrl(storeHash, projectUuid, apiHost), {\n method: 'POST',\n headers: {\n ...authHeaders(accessToken),\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ domain }),\n });\n\n await assertDomainResponse(response, 'Failed to add domain');\n\n const result: unknown = await response.json();\n\n return createdDomainResponseSchema.parse(result).data;\n}\n\nexport async function getDomain(\n domain: string,\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<Domain> {\n const response = await fetch(domainUrl(storeHash, projectUuid, domain, apiHost), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n await assertDomainResponse(response, 'Failed to fetch domain');\n\n const result: unknown = await response.json();\n\n return domainResponseSchema.parse(result).data;\n}\n\n// Like `getDomain`, but returns null when the domain isn't present on the\n// given project (404) instead of throwing. Used by `transfer` to confirm the\n// source project actually owns the domain before attempting the move, so the\n// user gets clear guidance instead of the API's opaque ownership rejection.\nexport async function findDomain(\n domain: string,\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<Domain | null> {\n const response = await fetch(domainUrl(storeHash, projectUuid, domain, apiHost), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n if (response.status === 404) {\n return null;\n }\n\n await assertDomainResponse(response, 'Failed to fetch domain');\n\n const result: unknown = await response.json();\n\n return domainResponseSchema.parse(result).data;\n}\n\nexport async function listDomains(\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n filters: ListDomainsFilters = {},\n): Promise<Domain[]> {\n const search = new URLSearchParams();\n\n if (filters.domains && filters.domains.length > 0) {\n search.set('domain:in', filters.domains.join(','));\n }\n\n if (filters.verificationStatus) {\n search.set('verification_status', filters.verificationStatus);\n }\n\n const query = search.toString();\n const url = `${domainsUrl(storeHash, projectUuid, apiHost)}${query ? `?${query}` : ''}`;\n const response = await fetch(url, {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n await assertDomainResponse(response, 'Failed to fetch domains');\n\n const result: unknown = await response.json();\n\n return domainListResponseSchema.parse(result).data;\n}\n\nexport async function deleteDomain(\n domain: string,\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<void> {\n const response = await fetch(domainUrl(storeHash, projectUuid, domain, apiHost), {\n method: 'DELETE',\n headers: authHeaders(accessToken),\n });\n\n await assertDomainResponse(response, `Failed to remove domain: ${response.statusText}`);\n}\n\nexport async function claimDomain(\n domain: string,\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<void> {\n const response = await fetch(domainClaimUrl(storeHash, projectUuid, domain, apiHost), {\n method: 'POST',\n headers: authHeaders(accessToken),\n });\n\n await assertDomainResponse(response, 'Failed to claim domain');\n}\n\n// Moves a domain from its current project (`projectUuid`, the source) to\n// `newProjectUuid` (the destination) within the same store. The API rejects a\n// transfer where the destination equals the source.\nexport async function transferDomain(\n domain: string,\n projectUuid: string,\n newProjectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<void> {\n const response = await fetch(domainTransferUrl(storeHash, projectUuid, domain, apiHost), {\n method: 'POST',\n headers: {\n ...authHeaders(accessToken),\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ new_project_uuid: newProjectUuid }),\n });\n\n await assertDomainResponse(response, 'Failed to transfer domain');\n}\n","import { colorize } from 'consola/utils';\nimport { z } from 'zod';\n\nimport { assertAuthorized } from './auth-errors';\nimport { UserActionableError } from './errors';\nimport { httpError } from './http-errors';\nimport { getTelemetry } from './telemetry';\n\nexport const LOG_LEVELS = ['debug', 'info', 'warn', 'error'] as const;\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\nconst SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;\n\nconst logEntrySchema = z.object({\n timestamp: z.string().nullable().optional(),\n entry_type: z.string().optional(),\n level: z.string().optional(),\n messages: z.array(z.unknown()).optional(),\n is_exception: z.boolean().optional(),\n exception_name: z.string().optional(),\n request: z\n .object({\n method: z.string().optional(),\n url: z.string().optional(),\n status_code: z.number().optional(),\n })\n .nullable()\n .optional(),\n});\n\nconst queryLogsSchema = z.object({\n data: z.array(logEntrySchema),\n meta: z\n .object({\n cursor_pagination: z\n .object({\n // The REST proxy exposes page availability via links, while the\n // gRPC response uses has_next_page/has_prev_page. Accept both while\n // the API contract is transitioning.\n has_next_page: z.boolean().optional(),\n has_prev_page: z.boolean().optional(),\n start_cursor: z.string().nullable().optional(),\n end_cursor: z.string().nullable().optional(),\n links: z\n .object({\n next: z.string().optional(),\n previous: z.string().optional(),\n })\n .optional(),\n })\n .optional(),\n })\n .optional(),\n});\n\nexport type LogEntry = z.infer<typeof logEntrySchema>;\nexport type QueryLogsResult = z.infer<typeof queryLogsSchema>;\n\nexport interface QueryLogsParams {\n start: string;\n end: string;\n entryType?: 'log' | 'request';\n method?: string;\n statusCode?: number;\n urlLike?: string;\n levelMin?: LogLevel;\n limit?: number;\n after?: string;\n before?: string;\n}\n\nconst v3ErrorSchema = z.object({\n title: z.string().optional(),\n errors: z.record(z.string(), z.string()).optional(),\n});\n\nexport function formatV3Error(body: unknown): string | undefined {\n const parsed = v3ErrorSchema.safeParse(body);\n\n if (!parsed.success) return undefined;\n\n const { title, errors } = parsed.data;\n const fieldErrors =\n errors && Object.keys(errors).length > 0\n ? Object.entries(errors)\n .map(([field, message]) => `${field}: ${message}`)\n .join('; ')\n : undefined;\n\n if (title && fieldErrors) return `${title} (${fieldErrors})`;\n\n return title ?? fieldErrors;\n}\n\n// Accepts either an ISO-8601 timestamp or a Unix epoch (seconds) and returns\n// milliseconds since epoch, or null when the value can't be parsed.\nfunction parseTimeInput(value: string): number | null {\n const trimmed = value.trim();\n\n if (/^\\d+$/.test(trimmed)) {\n return Number(trimmed) * 1000;\n }\n\n const ms = Date.parse(trimmed);\n\n return Number.isNaN(ms) ? null : ms;\n}\n\nconst DURATION_UNIT_MS: Record<string, number> = {\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n};\n\nfunction parseDuration(value: string): number | null {\n const match = /^(\\d+)([smhd])$/.exec(value.trim());\n\n if (!match) return null;\n\n return Number(match[1]) * DURATION_UNIT_MS[match[2]];\n}\n\nexport function resolveTimeWindow(\n opts: { start?: string; end?: string; since?: string },\n nowMs = Date.now(),\n): {\n start: string;\n end: string;\n} {\n const { since } = opts;\n let { start, end } = opts;\n let startMs: number | null;\n let endMs: number | null;\n\n if (end) {\n endMs = parseTimeInput(end);\n\n if (endMs === null) {\n throw new UserActionableError(\n `Invalid --end value \"${end}\". Provide an ISO-8601 timestamp or a Unix epoch (seconds).`,\n );\n }\n } else {\n endMs = nowMs;\n end = new Date(endMs).toISOString();\n }\n\n if (since) {\n const durationMs = parseDuration(since);\n\n if (durationMs === null) {\n throw new UserActionableError(\n `Invalid --since value \"${since}\". Provide a duration like 30m, 6h, or 2d (units: s, m, h, d).`,\n );\n }\n\n startMs = endMs - durationMs;\n start = new Date(startMs).toISOString();\n } else if (start) {\n startMs = parseTimeInput(start);\n\n if (startMs === null) {\n throw new UserActionableError(\n `Invalid --start value \"${start}\". Provide an ISO-8601 timestamp or a Unix epoch (seconds).`,\n );\n }\n } else {\n throw new UserActionableError(\n 'Provide a time window with --since <duration> or --start <time>.',\n );\n }\n\n if (startMs > endMs) {\n throw new UserActionableError('Invalid time window: --start must be before or equal to --end.');\n }\n\n if (endMs - startMs > SEVEN_DAYS_MS) {\n throw new UserActionableError('Invalid time window: the range must not exceed 7 days.');\n }\n\n return { start, end };\n}\n\nconst LEVEL_COLORS: Record<string, Parameters<typeof colorize>[0]> = {\n debug: 'gray',\n info: 'green',\n warn: 'yellow',\n error: 'red',\n};\n\nexport type LogLineFormat = 'default' | 'short' | 'request';\n\nconst UNKNOWN_TIME = 'unknown';\n\nfunction isRedundantExceptionName(name: string, message: string): boolean {\n const parts = name\n .split('<*>')\n .map((part) => part.trim())\n .filter((part) => part.length > 0);\n\n return parts.length > 0 && parts.every((part) => message.includes(part));\n}\n\nconst stringifyMessage = (message: unknown) =>\n typeof message === 'string' ? message : JSON.stringify(message);\n\nconst joinMessages = (messages: LogEntry['messages']) =>\n (messages ?? []).map(stringifyMessage).join(' ').replace(/\\s+/g, ' ').trim();\n\n// Identifies Cloudflare's auto-generated per-request invocation row (as\n// opposed to real application output like console.* or exceptions).\nexport function isRequestLogEntry(entry: LogEntry): boolean {\n if (entry.entry_type != null) return entry.entry_type === 'request';\n\n // Older API deployments don't send entry_type. Fall back to a heuristic:\n // the auto-generated row's message is exactly \"<method> <url>\", duplicating\n // the entry's request details.\n const method = entry.request?.method;\n const url = entry.request?.url;\n\n if (!method || !url) return false;\n\n return joinMessages(entry.messages) === `${method} ${url}`;\n}\n\nexport function formatLogEntry(entry: LogEntry, format: LogLineFormat = 'default'): string {\n const message = joinMessages(entry.messages);\n\n if (format === 'short') return message;\n\n const level = entry.level ?? 'unknown';\n const coloredLevel = colorize(LEVEL_COLORS[level.toLowerCase()] ?? 'white', level.toUpperCase());\n\n const exceptionStr =\n entry.is_exception &&\n entry.exception_name &&\n !isRedundantExceptionName(entry.exception_name, message)\n ? ` ${colorize('red', `[${entry.exception_name}]`)}`\n : '';\n\n let requestStr = '';\n\n if (format === 'request' && entry.request) {\n const parts: string[] = [];\n\n if (entry.request.method) parts.push(entry.request.method);\n if (entry.request.url) parts.push(entry.request.url);\n\n // status_code 0 is the backend's \"unknown\" sentinel — omit it.\n const status = entry.request.status_code ? ` (${entry.request.status_code})` : '';\n\n if (parts.length > 0) requestStr = ` ${parts.join(' ')}${status}`;\n }\n\n // A request row carries no application output — its message only duplicates\n // the request details — so print it as a bare request line, without a level\n // bracket or message.\n if (format === 'request' && isRequestLogEntry(entry)) {\n return `[${entry.timestamp ?? UNKNOWN_TIME}]${requestStr}`;\n }\n\n // `requestStr` is empty outside the `request` format, so the level stays\n // adjacent to the timestamp there and only slides after the request details\n // when they are present.\n return `[${entry.timestamp ?? UNKNOWN_TIME}]${requestStr} [${coloredLevel}]${exceptionStr} ${message}`;\n}\n\nexport async function queryLogs(\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n params: QueryLogsParams,\n): Promise<QueryLogsResult> {\n const search = new URLSearchParams();\n\n search.set('start', params.start);\n search.set('end', params.end);\n\n if (params.entryType) search.set('entry_type', params.entryType);\n if (params.method) search.set('method', params.method);\n if (params.statusCode != null) search.set('status_code', String(params.statusCode));\n if (params.urlLike) search.set('url:like', params.urlLike); // colon param\n if (params.levelMin) search.set('level:min', params.levelMin); // colon param\n if (params.limit != null) search.set('limit', String(params.limit));\n if (params.after) search.set('after', params.after);\n if (params.before) search.set('before', params.before);\n\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/logs/${projectUuid}?${search.toString()}`,\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n Accept: 'application/json',\n },\n },\n );\n\n assertAuthorized(response);\n\n if (response.status === 403) {\n throw new UserActionableError(\n 'Infrastructure Logs API not enabled. If you are part of the beta, contact support@bigcommerce.com to enable it.',\n );\n }\n\n if (response.status === 404) {\n // The gateway also 404s when the token belongs to a different store than\n // the one in the URL, so a bad credential pairing looks identical to a\n // missing project.\n throw new UserActionableError(\n 'Project not found. Check the project UUID, and that --store-hash and --access-token belong to the store that owns the project.',\n );\n }\n\n // 400 (bad UUID) and 422 (invalid window/filter) both carry the field-keyed\n // v3 error envelope — surface its message rather than the bare status.\n if (response.status === 400 || response.status === 422) {\n const body: unknown = await response.json().catch(() => null);\n\n throw new UserActionableError(formatV3Error(body) ?? 'Invalid log query.');\n }\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch logs');\n }\n\n const res: unknown = await response.json();\n\n return queryLogsSchema.parse(res);\n}\n","import { Command } from 'commander';\n\nimport { getStoredEnv, parseEnvAssignment } from '../lib/env-config';\nimport { consola } from '../lib/logger';\nimport { getProjectConfig } from '../lib/project-config';\n\n// Values are secrets, so we never print them back. A fixed-width mask avoids\n// leaking the length of the stored value.\nconst MASK = '••••••';\n\nconst add = new Command('add')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Add or update one or more deployment environment variables. Stored in .bigcommerce/project.json and sent as secrets on every `catalyst deploy`.',\n )\n .argument('<vars...>', 'One or more environment variables in KEY=VALUE format.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst env add BIGCOMMERCE_STORE_HASH=abc123 BIGCOMMERCE_STOREFRONT_TOKEN=ey...`,\n )\n .action((vars: string[]) => {\n const config = getProjectConfig();\n const stored = { ...getStoredEnv(config) };\n\n // Parse everything before writing so a single invalid entry doesn't leave a\n // partial update behind.\n const parsed = vars.map((entry) => parseEnvAssignment(entry));\n\n parsed.forEach(({ key, value }) => {\n stored[key] = value;\n });\n\n config.set('env', stored);\n\n const keys = parsed.map(({ key }) => key);\n\n consola.success(\n `Saved ${keys.length} environment variable${keys.length === 1 ? '' : 's'} to .bigcommerce/project.json:`,\n );\n keys.forEach((key) => consola.log(` ${key}=${MASK}`));\n\n process.exit(0);\n });\n\nconst remove = new Command('remove')\n .configureHelp({ showGlobalOptions: true })\n .description('Remove one or more stored deployment environment variables.')\n .argument('<keys...>', 'One or more environment variable names to remove.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst env remove BIGCOMMERCE_STORE_HASH BIGCOMMERCE_STOREFRONT_TOKEN`,\n )\n .action((keys: string[]) => {\n const config = getProjectConfig();\n const stored = getStoredEnv(config);\n const toRemove = new Set<string>();\n\n keys.forEach((key) => {\n if (key in stored) {\n toRemove.add(key);\n } else {\n consola.warn(`No stored environment variable named \"${key}\". Skipping.`);\n }\n });\n\n const next = Object.fromEntries(Object.entries(stored).filter(([key]) => !toRemove.has(key)));\n\n config.set('env', next);\n\n const removed = Array.from(toRemove);\n\n if (removed.length > 0) {\n consola.success(\n `Removed ${removed.length} environment variable${removed.length === 1 ? '' : 's'}: ${removed.join(', ')}.`,\n );\n }\n\n process.exit(0);\n });\n\nconst list = new Command('list')\n .configureHelp({ showGlobalOptions: true })\n .description('List stored deployment environment variables (values are masked).')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst env list`,\n )\n .action(() => {\n const config = getProjectConfig();\n const stored = getStoredEnv(config);\n const keys = Object.keys(stored).sort();\n\n if (keys.length === 0) {\n consola.info('No environment variables stored. Add one with `catalyst env add KEY=VALUE`.');\n process.exit(0);\n\n return;\n }\n\n keys.forEach((key) => consola.log(`${key}=${MASK}`));\n\n process.exit(0);\n });\n\nexport const env = new Command('env')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Manage persistent deployment environment variables. These are sent as secrets on every `catalyst deploy`, so you no longer need to pass `--secret` each time.',\n )\n .addCommand(add)\n .addCommand(remove)\n .addCommand(list);\n","import { Command, InvalidArgumentError, Option } from 'commander';\nimport { colorize } from 'consola/utils';\nimport { z } from 'zod';\n\nimport { UnauthorizedError } from '../lib/auth-errors';\nimport { httpError } from '../lib/http-errors';\nimport { consola } from '../lib/logger';\nimport {\n formatLogEntry,\n isRequestLogEntry,\n LOG_LEVELS,\n queryLogs,\n QueryLogsResult,\n resolveTimeWindow,\n} from '../lib/observability';\nimport { getProjectConfig } from '../lib/project-config';\nimport { resolveCredentials } from '../lib/resolve-credentials';\nimport {\n accessTokenOption,\n apiHostOption,\n projectUuidOption,\n resolveApiHost,\n resolveProjectUuid,\n storeHashOption,\n} from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\n\ntype LogFormat = 'json' | 'pretty' | 'default' | 'short' | 'request';\n\nconst DEFAULT_CONNECTION_TTL_MS = 1 * 60 * 1000; // 1 minute\nconst MAX_RETRIES = 5;\n\nconst isFatalStatusCode = (status: number) => status >= 400 && status < 500;\n\nconst LEVEL_COLORS: Record<string, Parameters<typeof colorize>[0]> = {\n INFO: 'green',\n WARN: 'yellow',\n ERROR: 'red',\n DEBUG: 'gray',\n};\n\nconst LogEventSchema = z\n .object({\n uuid: z.string(),\n project_uuid: z.string(),\n request: z.object({\n method: z.string(),\n url: z.string(),\n status_code: z.number(),\n }),\n logs: z.array(\n z.object({\n timestamp: z.string(),\n level: z.string(),\n messages: z.array(z.unknown()),\n }),\n ),\n exceptions: z.array(z.unknown()),\n timestamp: z.string(),\n })\n .loose();\n\nclass StreamError extends Error {\n fatal: boolean;\n\n constructor(message: string, fatal: boolean) {\n super(message);\n this.fatal = fatal;\n }\n}\n\nconst formatMessages = (messages: unknown[]) =>\n messages.map((m) => (typeof m === 'string' ? m : JSON.stringify(m))).join(' ');\n\ntype LogEvent = z.infer<typeof LogEventSchema>;\n\n// Builds a `request` format line. The log entry is optional: a request that\n// logged nothing still has a timestamp, method, URL and status worth printing.\nconst formatRequestLine = (event: LogEvent, entry?: LogEvent['logs'][number]) => {\n const { request } = event;\n const msg = entry ? formatMessages(entry.messages) : '';\n const msgPart = msg ? ` ${msg}` : '';\n // The level labels the message, so an entry with nothing to say prints as a\n // bare request line — same as an event that carried no entries at all.\n const level = msg ? entry?.level.toUpperCase() : undefined;\n const levelPart = level ? ` [${colorize(LEVEL_COLORS[level] ?? 'white', level)}]` : '';\n\n return (\n `[${entry?.timestamp ?? event.timestamp}] ` +\n `${request.method} ${request.url} (${request.status_code})${levelPart}${msgPart}`\n );\n};\n\nconst formatLogEvent = (event: LogEvent, format: 'default' | 'short' | 'request') => {\n const { logs: logEntries, exceptions } = event;\n\n // `request` output is about the request, not the messages it emitted, so an\n // event with no log entries still prints one line. Otherwise requests that\n // logged nothing silently disappear from the stream.\n if (format === 'request' && logEntries.length === 0) {\n consola.log(formatRequestLine(event));\n }\n\n logEntries.forEach((entry) => {\n const msg = formatMessages(entry.messages);\n const level = entry.level.toUpperCase();\n const coloredLevel = colorize(LEVEL_COLORS[level] ?? 'white', level);\n\n switch (format) {\n case 'short':\n consola.log(msg);\n break;\n\n case 'request':\n consola.log(formatRequestLine(event, entry));\n break;\n\n default:\n consola.log(`[${entry.timestamp}] [${coloredLevel}] ${msg}`);\n break;\n }\n });\n\n exceptions.forEach((exception) => {\n consola.error(`[${event.timestamp}] EXCEPTION`, exception);\n });\n};\n\nexport const parseSSEEvent = (raw: string): string | null => {\n const joined = raw\n .split('\\n')\n .flatMap((line) => (line.startsWith('data:') ? [line.slice(5).trim()] : []))\n .join('\\n');\n\n return joined.length > 0 ? joined : null;\n};\n\nconst processLogEvent = (event: string, format: LogFormat) => {\n if (format === 'json') {\n process.stdout.write(`${event}\\n`);\n\n return;\n }\n\n try {\n const parsed: unknown = JSON.parse(event);\n const logEvent = LogEventSchema.parse(parsed);\n\n if (format === 'pretty') {\n consola.log(JSON.stringify(logEvent, null, 2));\n } else {\n formatLogEvent(logEvent, format);\n }\n } catch {\n consola.warn(`Failed to parse log event: ${event}`);\n }\n};\n\ntype TimeoutRaceResult<T> = { kind: 'value'; value: T } | { kind: 'timeout' };\n\n// Races a promise against a timer so a hung `reader.read()` doesn't block the\n// read pump. Without this, the connection TTL check never runs when the API\n// proxy half-closes the socket — bytes stop arriving but no FIN/error\n// surfaces, so the read promise stays pending forever.\nconst raceWithTimeout = async <T>(\n promise: Promise<T>,\n timeoutMs: number,\n): Promise<TimeoutRaceResult<T>> => {\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n\n const timeoutPromise = new Promise<TimeoutRaceResult<T>>((resolve) => {\n timeoutHandle = setTimeout(() => resolve({ kind: 'timeout' }), timeoutMs);\n });\n\n try {\n return await Promise.race([\n promise.then((value): TimeoutRaceResult<T> => ({ kind: 'value', value })),\n timeoutPromise,\n ]);\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n};\n\nconst openLogStream = async (\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n) => {\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/logs/${projectUuid}/tail`,\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n Accept: 'text/event-stream',\n Connection: 'keep-alive',\n },\n },\n );\n\n // An invalid/expired token won't recover by reconnecting — surface the\n // re-auth guidance and stop the loop (fatal) rather than burning retries.\n if (response.status === 401) {\n throw new StreamError(new UnauthorizedError().message, true);\n }\n\n if (!response.ok) {\n const error = await httpError(response, 'Failed to open log stream');\n\n throw new StreamError(error.message, isFatalStatusCode(response.status));\n }\n\n const reader = response.body?.getReader();\n\n if (!reader) {\n throw new StreamError('Failed to read log stream.', true);\n }\n\n return reader;\n};\n\n// Reasons the read pump stops on its own (vs. throwing). The outer reconnect\n// loop maps each to a user-facing message — or silence — and opens a fresh\n// stream.\ntype Rotation = 'ttl' | 'idle-timeout' | 'stream-done';\n\nconst pumpUntilRotation = async (\n reader: ReadableStreamDefaultReader<Uint8Array>,\n format: LogFormat,\n connectionTtlMs: number,\n): Promise<Rotation> => {\n const decoder = new TextDecoder();\n const connectTime = Date.now();\n let buffer = '';\n let receivedData = false;\n\n // eslint-disable-next-line no-constant-condition, @typescript-eslint/no-unnecessary-condition\n while (true) {\n const remainingTtlMs = connectionTtlMs - (Date.now() - connectTime);\n\n if (remainingTtlMs <= 0) {\n void reader.cancel();\n\n return 'ttl';\n }\n\n // eslint-disable-next-line no-await-in-loop\n const readResult = await raceWithTimeout(reader.read(), remainingTtlMs);\n\n if (readResult.kind === 'timeout') {\n void reader.cancel();\n\n // No data for the whole window: proxy likely half-closed the socket.\n // If data flowed earlier, treat it as a normal TTL boundary instead.\n return receivedData ? 'ttl' : 'idle-timeout';\n }\n\n const { value, done: streamDone } = readResult.value;\n\n if (value) {\n receivedData = true;\n buffer += decoder.decode(value, { stream: true });\n\n const parts = buffer.split('\\n\\n');\n\n // Last element is either empty (complete event) or a partial chunk to carry over\n buffer = parts.pop() ?? '';\n\n parts\n .map((raw) => parseSSEEvent(raw))\n .filter((event): event is string => event !== null)\n .forEach((event) => processLogEvent(event, format));\n }\n\n if (streamDone) {\n void reader.cancel();\n\n return 'stream-done';\n }\n }\n};\n\nexport const tailLogs = async (\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n format: LogFormat,\n connectionTtlMs = DEFAULT_CONNECTION_TTL_MS,\n) => {\n consola.info('Tailing logs...');\n\n let retries = 0;\n\n // eslint-disable-next-line no-constant-condition, @typescript-eslint/no-unnecessary-condition\n while (true) {\n try {\n // eslint-disable-next-line no-await-in-loop\n const reader = await openLogStream(projectUuid, storeHash, accessToken, apiHost);\n\n retries = 0;\n\n // eslint-disable-next-line no-await-in-loop\n const rotation = await pumpUntilRotation(reader, format, connectionTtlMs);\n\n if (rotation === 'idle-timeout') {\n consola.warn('Log stream idle, reconnecting...');\n }\n // 'ttl' and 'stream-done' are healthy rotations — reconnect silently.\n } catch (error) {\n if (error instanceof StreamError && error.fatal) {\n throw error;\n }\n\n const isServerDisconnect = error instanceof TypeError && error.message === 'terminated';\n\n if (isServerDisconnect) {\n consola.warn('Log stream closed by server, reconnecting...');\n } else {\n retries += 1;\n\n if (retries >= MAX_RETRIES) {\n throw new Error(`Failed to connect to log stream after ${MAX_RETRIES} retries.`);\n }\n\n consola.warn(\n `Log stream disconnected, reconnecting (attempt ${retries}/${MAX_RETRIES})...`,\n error,\n );\n }\n }\n }\n};\n\nconst tail = new Command('tail')\n .configureHelp({ showGlobalOptions: true })\n .description('Tail live logs from your deployed application.')\n .addHelpText(\n 'after',\n `\nFormats:\n default One line per log message: timestamp, level, and message.\n short Message text only.\n request One line per log message: timestamp, request method, URL, status\n code, level, and message. Requests that logged no messages are\n printed too, without the level and message.\n pretty Indented JSON of the whole event.\n json Raw JSON, one event per line (useful for piping to other tools).\n\nThe \\`default\\` and \\`short\\` formats only print requests that produced a log\nmessage. Use \\`--format request\\` (or \\`json\\`/\\`pretty\\`) to see every request,\nincluding ones with no message body.\n\nExamples:\n $ catalyst logs tail\n\n # Tail logs with request format\n $ catalyst logs tail --format request\n\n # Tail logs as raw JSON (useful for piping to other tools)\n $ catalyst logs tail --format json`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .addOption(\n new Option('--format <format>', 'Output format for log events.')\n .choices(['json', 'pretty', 'default', 'short', 'request'])\n .default('default'),\n )\n .action(async (options) => {\n try {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n const projectUuid = resolveProjectUuid(options);\n\n await tailLogs(projectUuid, storeHash, accessToken, apiHost, options.format);\n } catch (error) {\n consola.error(error);\n process.exit(1);\n }\n });\n\n// Validates a numeric flag client-side so typos fail instantly with a clear\n// message instead of sending NaN (or an out-of-range value) to the API.\nconst parseIntInRange = (flag: string, min: number, max: number) => (value: string) => {\n const parsed = Number(value);\n\n if (!Number.isInteger(parsed) || parsed < min || parsed > max) {\n throw new InvalidArgumentError(`${flag} must be an integer between ${min} and ${max}.`);\n }\n\n return parsed;\n};\n\n// A bare `catalyst` is only on PATH for global installs. When the CLI runs\n// through a package manager (`pnpm catalyst`, `npx catalyst`, ...) the printed\n// hint must include that wrapper or copy-pasting it fails with\n// \"command not found\".\nfunction invocationPrefix(): string {\n const packageManager = process.env.npm_config_user_agent?.split('/')[0];\n\n switch (packageManager) {\n case 'pnpm':\n case 'yarn':\n return `${packageManager} catalyst`;\n\n case 'bun':\n return 'bunx catalyst';\n\n case 'npm':\n return 'npx catalyst';\n\n default:\n return 'catalyst';\n }\n}\n\ninterface QueryHintOptions {\n method?: string;\n statusCode?: number;\n urlLike?: string;\n levelMin?: string;\n limit?: number;\n format: string;\n}\n\nfunction printPaginationHints(\n pagination: NonNullable<QueryLogsResult['meta']>['cursor_pagination'],\n start: string,\n end: string,\n options: QueryHintOptions,\n): void {\n // The REST API signals availability with `links` URLs. Retain the gRPC\n // booleans as a compatibility fallback for direct API consumers.\n const hasNextPage = Boolean(pagination?.links?.next) || pagination?.has_next_page === true;\n const hasPrevPage = Boolean(pagination?.links?.previous) || pagination?.has_prev_page === true;\n const endCursor = pagination?.end_cursor;\n const startCursor = pagination?.start_cursor;\n\n if (!(hasNextPage && endCursor) && !(hasPrevPage && startCursor)) return;\n\n const quoteArg = (value: string) => (/\\s/.test(value) ? `'${value}'` : value);\n // Cursors are only valid with the same window and filters, so pin the\n // resolved absolute timestamps (a --since window drifts with \"now\").\n const baseFlags = [\n `--start ${quoteArg(start)}`,\n `--end ${quoteArg(end)}`,\n ...(options.method ? [`--method ${quoteArg(options.method)}`] : []),\n ...(options.statusCode != null ? [`--status-code ${options.statusCode}`] : []),\n ...(options.urlLike ? [`--url-like ${quoteArg(options.urlLike)}`] : []),\n ...(options.levelMin ? [`--level-min ${options.levelMin}`] : []),\n ...(options.limit != null ? [`--limit ${options.limit}`] : []),\n // The entry_type filter derives from --format (default/short request only\n // application logs), so echoing --format is enough to reproduce it.\n ...(options.format !== 'default' ? [`--format ${options.format}`] : []),\n ];\n const command = `${invocationPrefix()} logs query ${baseFlags.join(' ')}`;\n\n if (hasNextPage && endCursor) {\n consola.info(`More results available. Next page:\\n ${command} --after ${quoteArg(endCursor)}`);\n }\n\n if (hasPrevPage && startCursor) {\n consola.info(\n `Newer results available. Previous page:\\n ${command} --before ${quoteArg(startCursor)}`,\n );\n }\n}\n\nconst query = new Command('query')\n .configureHelp({ showGlobalOptions: true })\n .description('Query historical logs from your deployed application.')\n .addHelpText(\n 'after',\n `\nSpecify a time window with \\`--since\\` (relative to now) or \\`--start\\`/\\`--end\\`\n(ISO-8601 timestamps or Unix epoch seconds, UTC). The window may not exceed\n7 days. Entries print oldest-first; timestamps are UTC. Page toward older\nentries by passing a previous page's end cursor to \\`--after\\` (the CLI prints\na ready-to-run command when more entries are available), or toward newer\nentries with \\`--before\\`. Cursors are only valid with the same window and\nfilters they came from. With \\`--format json\\`, the pagination cursors are\nemitted as a final \\`{\"meta\": ...}\\` line after the entries.\n\nThe \\`default\\` and \\`short\\` formats show only application log output,\nexcluding Cloudflare's auto-generated per-request rows. Use\n\\`--format request\\` (or \\`json\\`/\\`pretty\\`) to include them.\n\nExamples:\n # Last hour of logs\n $ catalyst logs query --since 1h\n\n # Newest 20 errors in the window (follow the printed --after hint for more)\n $ catalyst logs query --since 24h --level-min error --limit 20\n\n # Everything from today (UTC)\n $ catalyst logs query --start 2026-06-11T00:00:00Z\n\n # Errors only for a specific path\n $ catalyst logs query --since 24h --level-min error --url-like /cart\n\n # Errors with request details (method, URL, status)\n $ catalyst logs query --since 1h --level-min error --format request\n\n # Raw JSON (NDJSON) for piping to other tools\n $ catalyst logs query --since 2d --format json`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .addOption(\n new Option(\n '--since <duration>',\n 'Relative window ending at --end (default: now), e.g. 30m, 6h, 2d (units: s, m, h, d).',\n ).conflicts('start'),\n )\n .option('--start <time>', 'Window start: ISO-8601 timestamp or Unix epoch (seconds).')\n .option(\n '--end <time>',\n 'Window end: ISO-8601 timestamp or Unix epoch (seconds). Defaults to now. The window must not exceed 7 days.',\n )\n .option('--method <method>', 'Filter by request HTTP method (case-insensitive).')\n .addOption(\n new Option('--status-code <code>', 'Filter by response status code (100-599).').argParser(\n parseIntInRange('--status-code', 100, 599),\n ),\n )\n .option('--url-like <substring>', 'Filter by URL substring (case-sensitive).')\n .addOption(\n new Option('--level-min <level>', 'Minimum log level.').choices(Array.from(LOG_LEVELS)),\n )\n .addOption(\n new Option(\n '--limit <count>',\n 'Maximum entries per page (1-500). Defaults to the API default (100).',\n ).argParser(parseIntInRange('--limit', 1, 500)),\n )\n .addOption(\n new Option(\n '--after <cursor>',\n \"Return the page after (older than) this cursor, from a previous page's end_cursor.\",\n ).conflicts('before'),\n )\n .addOption(\n new Option(\n '--before <cursor>',\n \"Return the page before (newer than) this cursor, from a previous page's start_cursor.\",\n ),\n )\n .addOption(\n new Option('--format <format>', 'Output format for log entries.')\n .choices(['json', 'pretty', 'default', 'short', 'request'])\n .default('default'),\n )\n .action(async (options) => {\n try {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n const projectUuid = resolveProjectUuid(options);\n const { start, end } = resolveTimeWindow(options);\n\n // default/short show only application output, so ask the API to filter\n // out Cloudflare's per-request rows (they don't consume the page limit).\n const hideRequestRows = options.format === 'default' || options.format === 'short';\n\n const result = await queryLogs(projectUuid, storeHash, accessToken, apiHost, {\n start,\n end,\n entryType: hideRequestRows ? 'log' : undefined,\n method: options.method,\n statusCode: options.statusCode,\n urlLike: options.urlLike,\n levelMin: options.levelMin,\n limit: options.limit,\n after: options.after,\n before: options.before,\n });\n\n const entries = result.data;\n const ordered = [...entries].reverse();\n\n if (options.format === 'json') {\n ordered.forEach((entry) => process.stdout.write(`${JSON.stringify(entry)}\\n`));\n\n // Entries carry no cursors, so scripted pagination needs the meta\n // echoed back; a trailing line keeps the stream line-delimited.\n const cursorPagination = result.meta?.cursor_pagination;\n\n if (cursorPagination) {\n process.stdout.write(\n `${JSON.stringify({ meta: { cursor_pagination: cursorPagination } })}\\n`,\n );\n }\n\n return;\n }\n\n if (options.format === 'pretty') {\n ordered.forEach((entry) => consola.log(JSON.stringify(entry, null, 2)));\n\n return;\n }\n\n if (entries.length === 0) {\n consola.info('No log entries found for the given window and filters.');\n\n return;\n }\n\n // `json`/`pretty` returned above, leaving the human line formats — capture\n // the narrowed value so it survives into the forEach closure.\n const lineFormat = options.format;\n\n // Older API deployments ignore the entry_type param, so also drop\n // request rows client-side — a no-op against new APIs.\n const visible = hideRequestRows\n ? ordered.filter((entry) => !isRequestLogEntry(entry))\n : ordered;\n const hiddenCount = ordered.length - visible.length;\n\n visible.forEach((entry) => consola.log(formatLogEntry(entry, lineFormat)));\n\n const shownPart = `${visible.length} ${visible.length === 1 ? 'entry' : 'entries'} shown`;\n\n consola.info(\n hiddenCount > 0\n ? `${shownPart}, ${hiddenCount} request ${hiddenCount === 1 ? 'row' : 'rows'} hidden (oldest first, times in UTC). Use --format request to see request rows.`\n : `${shownPart} (oldest first, times in UTC).`,\n );\n\n printPaginationHints(result.meta?.cursor_pagination, start, end, options);\n } catch (error) {\n consola.error(error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nexport const logs = new Command('logs')\n .alias('log')\n .configureHelp({ showGlobalOptions: true })\n .description('View logs from your deployed application.')\n .addCommand(tail, { isDefault: true })\n .addCommand(query);\n","import { confirm, input, select } from '@inquirer/prompts';\nimport { Command } from 'commander';\nimport { colorize } from 'consola/utils';\n\nimport {\n cleanupCloudflareIncompatibilities,\n NoLinkedProjectError,\n selectOrCreateInfrastructureProject,\n setupCommerceHosting,\n} from '../lib/commerce-hosting';\nimport { detectProjectPackageManager } from '../lib/detect-package-manager';\nimport { installDependencies } from '../lib/install-dependencies';\nimport { consola } from '../lib/logger';\nimport { LoginAbortedError, login as runInteractiveLogin } from '../lib/login';\nimport { createProject, deleteProject, fetchProjects } from '../lib/project';\nimport { getProjectConfig } from '../lib/project-config';\nimport { getProjectState } from '../lib/project-state';\nimport { resolveCredentials } from '../lib/resolve-credentials';\nimport {\n accessTokenOption,\n apiHostOption,\n loginUrlOption,\n projectUuidOption,\n resolveApiHost,\n storeHashOption,\n} from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\n\n// `catalyst projects link` runs from the project root, which is what\n// `setupCommerceHosting` and `installDependencies` expect.\nasync function offerCommerceHostingSetup(\n projectUuid: string,\n credentials?: { storeHash: string; accessToken: string },\n) {\n const projectDir = process.cwd();\n\n // Already-transformed projects skip the setup prompt below — but they may\n // still carry artifacts incompatible with the Cloudflare worker bundle\n // (e.g. `core/instrumentation.ts`, `@vercel/otel`). Run cleanup so existing\n // Commerce Hosting users pick up these fixes on re-link without prompting.\n if (getProjectState().isTransformed) {\n await cleanupCloudflareIncompatibilities(projectDir);\n\n return;\n }\n\n const shouldSetup = await confirm({\n message:\n 'Your project has been linked, but is not fully set up for Commerce Hosting deployments yet. Would you like to run the setup now?',\n default: true,\n });\n\n if (!shouldSetup) return;\n\n await setupCommerceHosting({\n projectDir,\n projectUuid,\n storeHash: credentials?.storeHash,\n accessToken: credentials?.accessToken,\n });\n\n consola.success('Commerce Hosting setup complete.');\n\n // Match the manager the project was scaffolded with (from its lockfile),\n // rather than forcing pnpm on npm/yarn/bun projects.\n const packageManager = await detectProjectPackageManager(projectDir);\n\n await installDependencies(projectDir, packageManager);\n}\n\nconst list = new Command('list')\n .configureHelp({ showGlobalOptions: true })\n .description('List BigCommerce infrastructure projects for your store.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst projects list`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n consola.start('Fetching projects...');\n\n const storeProjects = await fetchProjects(storeHash, accessToken, apiHost);\n\n consola.success('Projects fetched.');\n\n if (storeProjects.length === 0) {\n consola.info('No projects found.');\n process.exit(0);\n\n return;\n }\n\n const linkedProjectUuid = config.get('projectUuid');\n\n const projectList = storeProjects.map((p) => {\n const marker = p.uuid === linkedProjectUuid ? ` ${colorize('green', '[linked]')}` : '';\n const hostnames =\n p.deployment_hostnames.length === 0\n ? [' (not deployed)']\n : p.deployment_hostnames.map(\n (hostname) => ` ${colorize('blue', `https://${hostname}`)}`,\n );\n\n return [`${p.name} (${p.uuid})${marker}`, ...hostnames].join('\\n');\n });\n\n // Single log call so projects are blank-line separated without each blank\n // picking up a reporter timestamp.\n consola.log(projectList.join('\\n\\n'));\n\n process.exit(0);\n });\n\nconst create = new Command('create')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Create a new BigCommerce infrastructure project and link it to your local Catalyst project. Walks you through logging in if you are not authenticated yet.',\n )\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst projects create`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(loginUrlOption())\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n let storeHash = options.storeHash ?? config.get('storeHash');\n let accessToken = options.accessToken ?? config.get('accessToken');\n\n if (!storeHash || !accessToken) {\n consola.info(\n \"You're not logged in yet. Let's get you authenticated before creating a project.\",\n );\n\n try {\n const credentials = await runInteractiveLogin(options.loginUrl, apiHost);\n\n storeHash = credentials.storeHash;\n accessToken = credentials.accessToken;\n\n config.set('storeHash', storeHash);\n config.set('accessToken', accessToken);\n\n consola.success(`Logged in to store ${storeHash}.`);\n } catch (error) {\n if (error instanceof LoginAbortedError) {\n consola.info(\n 'Login aborted. Re-run `catalyst projects create` when you have your credentials ready.',\n );\n process.exit(0);\n\n return;\n }\n\n throw error;\n }\n }\n\n await getTelemetry().identify(storeHash);\n\n const newProjectName = await input({ message: 'Enter a name for the new project:' });\n\n const data = await createProject(newProjectName, storeHash, accessToken, apiHost);\n\n consola.success(`Project \"${data.name}\" created successfully.`);\n\n consola.start('Writing project UUID to .bigcommerce/project.json...');\n config.set('projectUuid', data.uuid);\n config.set('storeHash', storeHash);\n config.set('accessToken', accessToken);\n consola.success('Project UUID written to .bigcommerce/project.json.');\n\n process.exit(0);\n });\n\nexport const link = new Command('link')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Link your local Catalyst project to a BigCommerce infrastructure project. You can provide a project UUID directly, or fetch and select from available projects using your store credentials.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Link interactively (prompts to select or create)\n $ catalyst projects link\n\n # Link using a project UUID directly\n $ catalyst projects link --project-uuid <UUID>`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n const writeProjectConfig = (\n uuid: string,\n credentials?: { storeHash: string; accessToken: string },\n ) => {\n consola.start('Writing project UUID to .bigcommerce/project.json...');\n config.set('projectUuid', uuid);\n\n if (credentials) {\n config.set('storeHash', credentials.storeHash);\n config.set('accessToken', credentials.accessToken);\n }\n\n consola.success('Project UUID written to .bigcommerce/project.json.');\n };\n\n if (options.projectUuid) {\n writeProjectConfig(options.projectUuid);\n await offerCommerceHostingSetup(options.projectUuid);\n\n process.exit(0);\n\n return;\n }\n\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n let selected;\n\n try {\n selected = await selectOrCreateInfrastructureProject(\n { storeHash, accessToken, apiHost },\n config.get('projectUuid'),\n );\n } catch (error) {\n if (error instanceof NoLinkedProjectError) {\n consola.info(\n \"When you're ready to create a project, run `catalyst projects create` or re-run `catalyst projects link`.\",\n );\n process.exit(0);\n\n // Unreachable in production; prevents continuation when process.exit is mocked in tests.\n throw error;\n }\n\n throw error;\n }\n\n writeProjectConfig(selected.uuid, { storeHash, accessToken });\n await offerCommerceHostingSetup(selected.uuid, { storeHash, accessToken });\n\n process.exit(0);\n });\n\nconst del = new Command('delete')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Permanently delete a BigCommerce infrastructure project. This action is irreversible.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Select a project to delete interactively\n $ catalyst projects delete\n\n # Delete a specific project (still prompts for confirmation)\n $ catalyst projects delete --project-uuid <UUID>\n\n # Skip the confirmation prompt\n $ catalyst projects delete --project-uuid <UUID> --force`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--force', 'Skip the confirmation prompt before deleting.')\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n let targetUuid: string | undefined = options.projectUuid;\n let targetName: string | undefined;\n\n if (!targetUuid) {\n consola.start('Fetching projects...');\n\n const storeProjects = await fetchProjects(storeHash, accessToken, apiHost);\n\n consola.success('Projects fetched.');\n\n if (storeProjects.length === 0) {\n consola.info('No projects found.');\n process.exit(0);\n\n return;\n }\n\n const linkedProjectUuid = config.get('projectUuid');\n\n const selected = await select({\n message: 'Select a project to delete (Press <enter> to select).',\n choices: [\n ...storeProjects.map((p) => ({\n name:\n p.uuid === linkedProjectUuid ? `${p.name} ${colorize('green', '[linked]')}` : p.name,\n value: p.uuid,\n description: p.uuid,\n })),\n { name: 'Cancel', value: 'cancel', description: 'Exit without deleting any project.' },\n ],\n });\n\n if (selected === 'cancel') {\n consola.info('Aborted. No project was deleted.');\n process.exit(0);\n\n return;\n }\n\n const matched = storeProjects.find((p) => p.uuid === selected);\n\n if (!matched) {\n throw new Error(`Selected project ${String(selected)} not found in fetched list.`);\n }\n\n targetUuid = matched.uuid;\n targetName = matched.name;\n }\n\n if (!options.force) {\n const label = targetName ? `\"${targetName}\" (${targetUuid})` : targetUuid;\n\n const confirmed = await confirm({\n message: `Are you sure you want to delete project ${label}? This action is irreversible and will permanently destroy the project and all of its data.`,\n default: false,\n });\n\n if (!confirmed) {\n consola.info('Aborted. No project was deleted.');\n process.exit(0);\n\n return;\n }\n }\n\n consola.start(`Deleting project ${targetUuid}...`);\n\n await deleteProject(targetUuid, storeHash, accessToken, apiHost);\n\n consola.success(`Project ${targetUuid} deleted.`);\n\n if (config.get('projectUuid') === targetUuid) {\n config.delete('projectUuid');\n consola.info('Removed project UUID from .bigcommerce/project.json.');\n }\n\n process.exit(0);\n });\n\n// Resource commands are plural; the singular form stays as an alias so existing\n// scripts and muscle memory keep working.\nexport const projects = new Command('projects')\n .alias('project')\n .configureHelp({ showGlobalOptions: true })\n .description('Manage your BigCommerce infrastructure projects.')\n .addCommand(create)\n .addCommand(list)\n .addCommand(link)\n .addCommand(del);\n","import { Command } from 'commander';\nimport { execa } from 'execa';\nimport { existsSync, lstatSync, symlinkSync } from 'node:fs';\nimport { join, relative } from 'node:path';\n\nimport { consola } from '../lib/logger';\nimport { getProjectState } from '../lib/project-state';\n\nexport const start = new Command('start')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Start a local preview of your Catalyst storefront using the OpenNext Cloudflare adapter.',\n )\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst start`,\n )\n .action(async () => {\n // Project must be transformed before the OpenNext preview can run. If it\n // isn't, fall through to `next start` so this command works for self-hosted\n // Catalyst projects too.\n const state = getProjectState();\n\n if (!state.isTransformed) {\n consola.info('Project is not set up for Commerce Hosting — running `next start`.');\n\n await execa('pnpm', ['exec', 'next', 'start'], {\n stdio: 'inherit',\n cwd: process.cwd(),\n });\n\n return;\n }\n\n const envLocal = join(process.cwd(), '.env.local');\n const devVars = join(process.cwd(), '.bigcommerce', '.dev.vars');\n\n if (existsSync(envLocal)) {\n if (!existsSync(devVars)) {\n const target = relative(join(process.cwd(), '.bigcommerce'), envLocal);\n\n symlinkSync(target, devVars);\n consola.success('Symlinked .bigcommerce/.dev.vars → .env.local');\n } else if (!lstatSync(devVars).isSymbolicLink()) {\n consola.warn(\n '.bigcommerce/.dev.vars already exists and is not a symlink. ' +\n 'Wrangler will use it instead of .env.local.',\n );\n }\n } else {\n consola.warn(\n 'No .env.local file found. The preview server may fail without environment variables.\\n' +\n 'Create a .env.local file in your project root with the required variables.',\n );\n }\n\n await execa(\n 'pnpm',\n [\n 'exec',\n 'opennextjs-cloudflare',\n 'preview',\n '--config',\n join('.bigcommerce', 'wrangler.jsonc'),\n ],\n {\n stdio: 'inherit',\n cwd: process.cwd(),\n },\n );\n });\n","import { Argument, Command, Option } from 'commander';\nimport { colorize } from 'consola/utils';\n\nimport { consola } from '../lib/logger';\nimport { getTelemetry } from '../lib/telemetry';\n\nconst telemetryService = getTelemetry();\nlet isEnabled = telemetryService.isEnabled();\n\nexport const telemetry = new Command('telemetry')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'View or change CLI telemetry collection status. Enabling telemetry helps BigCommerce support diagnose and troubleshoot errors you encounter when using the CLI.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Show telemetry status\n $ catalyst telemetry\n\n # Enable telemetry collection\n $ catalyst telemetry enable\n\n # Disable telemetry collection\n $ catalyst telemetry --disable`,\n )\n .addArgument(new Argument('[arg]').choices(['disable', 'enable', 'status']))\n .addOption(new Option('--enable', `Enables CLI telemetry collection.`).conflicts('disable'))\n .option('--disable', `Disables CLI telemetry collection.`)\n .action((arg, options) => {\n if (options.enable || arg === 'enable') {\n telemetryService.setEnabled(true);\n isEnabled = true;\n\n consola.success('Success!\\n');\n } else if (options.disable || arg === 'disable') {\n telemetryService.setEnabled(false);\n\n if (isEnabled) {\n consola.success('Your preference has been saved.');\n } else {\n consola.info(`Catalyst CLI telemetry collection is already disabled.`);\n }\n\n isEnabled = false;\n } else {\n consola.info('Catalyst CLI Telemetry\\n');\n }\n\n consola.info(\n `Status: ${colorize('bold', isEnabled ? colorize('green', 'Enabled') : colorize('red', 'Disabled'))}`,\n );\n\n if (!isEnabled) {\n consola.info(\n `You have opted-out of Catalyst CLI telemetry. No data will be collected from your machine.`,\n );\n }\n });\n","import { Command, Option } from '@commander-js/extra-typings';\nimport { confirm } from '@inquirer/prompts';\nimport { execa } from 'execa';\nimport {\n access,\n copyFile,\n cp,\n mkdir,\n mkdtemp,\n readdir,\n readFile,\n rename,\n rm,\n writeFile,\n} from 'node:fs/promises';\nimport { homedir, tmpdir } from 'node:os';\nimport { dirname, join, relative } from 'node:path';\nimport { minVersion, satisfies, lt as semverLt, validRange, valid as validSemver } from 'semver';\nimport yoctoSpinner from 'yocto-spinner';\nimport { z } from 'zod';\n\nimport { cleanupCloudflareIncompatibilities } from '../lib/commerce-hosting';\nimport { detectLockfileManager, PackageManager } from '../lib/detect-package-manager';\nimport { consola } from '../lib/logger';\nimport { getProjectState } from '../lib/project-state';\nimport { getTelemetry } from '../lib/telemetry';\n\nconst CorePackageJson = z.object({\n name: z.string().optional(),\n version: z.string(),\n catalyst: z.object({ version: z.string(), ref: z.string() }).optional(),\n});\n\nconst DEP_FIELDS = [\n 'dependencies',\n 'devDependencies',\n 'optionalDependencies',\n 'peerDependencies',\n] as const;\n\nconst DepsPackageJson = z.looseObject({\n dependencies: z.record(z.string(), z.string()).optional(),\n devDependencies: z.record(z.string(), z.string()).optional(),\n optionalDependencies: z.record(z.string(), z.string()).optional(),\n peerDependencies: z.record(z.string(), z.string()).optional(),\n});\n\nconst WorkspacePackageJson = z.object({ name: z.string(), version: z.string() });\n\n// The CLI itself. `catalyst create` pins it exactly in devDependencies and it\n// doesn't exist in the upstream tree, so no merge will ever move it.\nconst CATALYST_CLI_PACKAGE = '@bigcommerce/catalyst';\n\n// Catalyst versions are git tags on the upstream monorepo (e.g.\n// \"@bigcommerce/catalyst-core@1.7.0\"), NOT npm packages. GitHub serves a\n// tarball for any tag via the repos/<owner>/<repo>/tarball/<ref> endpoint.\nconst DEFAULT_REPOSITORY = 'bigcommerce/catalyst';\n\n// Moving tags that don't pin a concrete version. When the target is one of\n// these we resolve the real version from the downloaded core/package.json so\n// catalyst.ref records a stable pin rather than the alias.\nconst MOVING_TAGS = new Set(['latest', 'canary', 'alpha']);\n\n// Known Catalyst package families, used to reconstruct a base ref from a\n// project's package.json `name` when `catalyst.ref` is missing.\nconst KNOWN_FAMILIES = new Set([\n '@bigcommerce/catalyst-core',\n '@bigcommerce/catalyst-makeswift',\n '@bigcommerce/catalyst-b2b-makeswift',\n '@bigcommerce/catalyst-b2b',\n]);\n\nconst CACHE_DIR = join(homedir(), '.cache', 'catalyst-cli', 'cores');\n\n// ── small fs helpers ──────────────────────────────────────────────────────────\nconst pathExists = (p: string) =>\n access(p)\n .then(() => true)\n .catch(() => false);\n\nasync function listFiles(dir: string, prefix = ''): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);\n\n const nested = await Promise.all(\n entries.map((entry) => {\n const rel = prefix ? `${prefix}/${entry.name}` : entry.name;\n\n return entry.isDirectory() ? listFiles(join(dir, entry.name), rel) : Promise.resolve([rel]);\n }),\n );\n\n return nested.flat();\n}\n\nasync function filesEqual(a: string, b: string): Promise<boolean> {\n const [ba, bb] = await Promise.all([\n readFile(a).catch(() => null),\n readFile(b).catch(() => null),\n ]);\n\n return ba !== null && bb !== null && ba.equals(bb);\n}\n\n// Returns the fraction of files in baseDir that exist and are identical in\n// destDir. Used to validate an inferred base: a correct base scores ~0.7-0.8+\n// (the files the merchant hasn't touched); a wrong base scores much lower.\nexport async function computeBaseSimilarity(baseDir: string, destDir: string): Promise<number> {\n const baseFiles = await listFiles(baseDir);\n\n if (baseFiles.length === 0) return 0;\n\n const matches = await Promise.all(\n baseFiles.map((rel) => filesEqual(join(baseDir, rel), join(destDir, rel))),\n );\n\n return matches.filter(Boolean).length / baseFiles.length;\n}\n\nasync function isBinary(p: string): Promise<boolean> {\n const buf = await readFile(p).catch(() => null);\n\n if (!buf) return false;\n\n // Same heuristic git uses: a NUL byte near the start means binary.\n return buf.subarray(0, 8000).includes(0);\n}\n\nasync function copyInto(src: string, dest: string): Promise<void> {\n await mkdir(dirname(dest), { recursive: true });\n await copyFile(src, dest);\n}\n\n// ── ref parsing ─────────────────────────────────────────────────────────────\n// Splits \"@bigcommerce/catalyst-core@1.7.0\" → { packageName, version }.\n// The last \"@\" separates the version (scoped names start with \"@\").\nexport function parseRef(ref: string): { packageName: string; version: string } {\n const lastAt = ref.lastIndexOf('@');\n\n if (lastAt <= 0) throw new Error(`Cannot parse ref \"${ref}\" — expected <package>@<version>.`);\n\n return { packageName: ref.slice(0, lastAt), version: ref.slice(lastAt + 1) };\n}\n\nasync function readResolvedVersion(coreDir: string): Promise<string> {\n const raw = await readFile(join(coreDir, 'package.json'), 'utf-8');\n const pkg = CorePackageJson.parse(JSON.parse(raw));\n\n // catalyst.version is the source of truth; older tags lack it and fall back to version.\n return pkg.catalyst?.version ?? pkg.version;\n}\n\n// ── Catalyst dependency reconciliation ────────────────────────────────────────\n// Every tag's committed core/package.json still carries `workspace:` specifiers\n// for the Catalyst packages: core is `private`, so it is never published and\n// pnpm's publish-time rewrite never runs on the tagged tree. Base and theirs\n// therefore agree on those lines, the merge correctly leaves ours alone, and the\n// merchant's Catalyst dependency versions never move. `catalyst create` resolves\n// them at scaffold time instead, which is why flat projects hold a real range\n// and monorepo-structure projects still hold `workspace:^`.\n\n// Package name → the version that tag published. Indexing can miss: a package\n// that didn't exist yet at an older ref simply isn't in that tag's manifest.\nexport type WorkspaceVersions = Record<string, string | undefined>;\n\n// A Catalyst dependency the merchant still references through the workspace\n// protocol, alongside the published version it would migrate to.\nexport interface WorkspaceDepFinding {\n name: string;\n ours: string;\n version: string;\n}\n\nconst readDepSpecifiers = (raw: string): Record<string, string | undefined> => {\n let parsed: z.infer<typeof DepsPackageJson>;\n\n try {\n parsed = DepsPackageJson.parse(JSON.parse(raw));\n } catch {\n return {}; // conflict markers or hand-broken JSON — nothing to reconcile\n }\n\n return Object.fromEntries(DEP_FIELDS.flatMap((field) => Object.entries(parsed[field] ?? {})));\n};\n\n// Scoped package names carry \"@\" and \"/\", and some carry \".\"; escape before\n// embedding in a pattern.\nconst escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n// Swap a dependency's `workspace:` specifier for `^<version>` in raw\n// package.json text. Deliberately textual rather than a JSON round-trip: parsing\n// and re-stringifying would reformat the whole file, desyncing the downloaded\n// trees from the merchant's copy and turning a one-line dependency bump into a\n// whole-file conflict. It also keeps working on a file that still has conflict\n// markers in other sections.\nexport const rewriteWorkspaceSpecifier = (raw: string, name: string, version: string): string =>\n raw.replace(\n new RegExp(`(\"${escapeRegExp(name)}\"\\\\s*:\\\\s*)\"workspace:[^\"]*\"`, 'g'),\n (_match, key: string) => `${key}\"^${version}\"`,\n );\n\n// Rewrites the downloaded base/theirs package.json so each side names the\n// version its own tag actually shipped. The normal 3-way merge then carries the\n// bump for free — or conflicts, if the merchant pinned deliberately.\n//\n// A dependency the merchant still holds as `workspace:` is skipped on both\n// sides: normalizing there would manufacture a conflict on something that works\n// fine as-is. Those come back as findings for the migration prompt instead.\nexport async function normalizeWorkspaceDeps(\n ourPkgRaw: string,\n baseDir: string,\n theirsDir: string,\n baseVersions: WorkspaceVersions,\n targetVersions: WorkspaceVersions,\n): Promise<{ workspace: WorkspaceDepFinding[]; bumped: string[] }> {\n const basePath = join(baseDir, 'package.json');\n const theirsPath = join(theirsDir, 'package.json');\n const [originalBase, originalTheirs] = await Promise.all([\n readFile(basePath, 'utf-8').catch(() => null),\n readFile(theirsPath, 'utf-8').catch(() => null),\n ]);\n\n if (originalBase === null || originalTheirs === null) return { workspace: [], bumped: [] };\n\n const ourSpecifiers = readDepSpecifiers(ourPkgRaw);\n const names = new Set(\n [\n ...Object.entries(readDepSpecifiers(originalBase)),\n ...Object.entries(readDepSpecifiers(originalTheirs)),\n ]\n .filter(([, range]) => range?.startsWith('workspace:'))\n .map(([name]) => name),\n );\n\n const decisions = [...names].map((name) => ({\n name,\n ours: ourSpecifiers[name],\n baseVersion: baseVersions[name],\n targetVersion: targetVersions[name],\n }));\n\n const workspace = decisions.flatMap(({ name, ours, targetVersion }) =>\n ours?.startsWith('workspace:') && targetVersion !== undefined\n ? [{ name, ours, version: targetVersion }]\n : [],\n );\n\n // Everything else gets both sides pinned to the version its own tag shipped.\n // A version is missing when the package didn't exist at that ref yet; leave\n // that side untouched so the merge sees no change rather than a bogus one.\n const normalizable = decisions.filter(({ ours }) => !ours?.startsWith('workspace:'));\n\n const baseRaw = normalizable.reduce(\n (acc, { name, baseVersion }) =>\n baseVersion === undefined ? acc : rewriteWorkspaceSpecifier(acc, name, baseVersion),\n originalBase,\n );\n const theirsRaw = normalizable.reduce(\n (acc, { name, targetVersion }) =>\n targetVersion === undefined ? acc : rewriteWorkspaceSpecifier(acc, name, targetVersion),\n originalTheirs,\n );\n const bumped = normalizable\n .filter(\n ({ baseVersion, targetVersion }) =>\n baseVersion !== undefined && targetVersion !== undefined && baseVersion !== targetVersion,\n )\n .map(({ name }) => name);\n\n await Promise.all([\n baseRaw === originalBase ? null : writeFile(basePath, baseRaw),\n theirsRaw === originalTheirs ? null : writeFile(theirsPath, theirsRaw),\n ]);\n\n return { workspace, bumped };\n}\n\n// Applies the findings to the merchant's own package.json text.\nexport const migrateWorkspaceDeps = (raw: string, findings: WorkspaceDepFinding[]): string =>\n findings.reduce((acc, { name, version }) => rewriteWorkspaceSpecifier(acc, name, version), raw);\n\n// The CLI that performs upgrades can't upgrade itself through the merge, so\n// check npm directly. Best-effort: a registry hiccup must never fail an upgrade.\nexport async function findStaleCli(\n pkgRaw: string,\n): Promise<{ current: string; latest: string } | null> {\n const range = readDepSpecifiers(pkgRaw)[CATALYST_CLI_PACKAGE];\n\n // A merchant may point the dep at a tarball, git URL, or `link:` path, none of\n // which minVersion() can parse (it throws rather than returning null).\n if (range === undefined || !validRange(range)) return null;\n\n const body: unknown = await fetch(`https://registry.npmjs.org/${CATALYST_CLI_PACKAGE}/latest`, {\n // A hanging registry would otherwise stall the CLI indefinitely.\n signal: AbortSignal.timeout(5000),\n })\n .then((res) => (res.ok ? res.json() : null))\n .catch(() => null);\n const latest = z.object({ version: z.string() }).safeParse(body).data?.version;\n\n // The registry promises a string, not a semver one, and an unparseable version\n // would throw straight out of satisfies(). A range that already admits the\n // published version needs no advisory either — the next install picks it up,\n // which leaves this for the exact pin `catalyst create` writes.\n if (latest === undefined || !validSemver(latest) || satisfies(latest, range)) return null;\n\n const current = minVersion(range)?.version;\n\n return current !== undefined && semverLt(current, latest) ? { current, latest } : null;\n}\n\n// ── CLI-managed npm scripts ───────────────────────────────────────────────────\n// `catalyst create` points `build`/`start`/`deploy` at the CLI (see\n// setup-core-project.ts) so they dispatch on project state. The upstream tree\n// keeps its own `next`-based commands, so in every created project those lines\n// are a permanent ours-vs-base delta — and a delta that conflicts the moment\n// core edits a neighbouring line. Core 1.11.0 inserted `\"test\": \"vitest run\"`\n// directly below `\"start\"` and did exactly that; resolving the hunk toward\n// theirs (the obvious choice, since you do want the new `test` script) silently\n// reverted `catalyst start` to `next start`.\n//\n// So pin both downloaded sides to the commands the project already has for those\n// keys. The merge then sees no change there at all, ours survives untouched, and\n// additions around it still apply cleanly. Only keys where ours already differs\n// from base get pinned: where ours matches base there is no delta to conflict\n// with, and leaving that alone lets a genuine upstream edit through.\nconst CLI_MANAGED_SCRIPTS = ['build', 'start', 'deploy'] as const;\n\nconst ScriptsPackageJson = z.looseObject({\n scripts: z.record(z.string(), z.string()).optional(),\n});\n\n// A CLI-managed script the two tags disagree about. Pinning hides that from the\n// merge, so it gets reported rather than lost silently. `null` on either side\n// means that tag didn't carry the script at all.\nexport interface ManagedScriptFinding {\n name: string;\n base: string | null;\n theirs: string | null;\n}\n\nconst readScripts = (raw: string): Record<string, string | undefined> => {\n try {\n return ScriptsPackageJson.parse(JSON.parse(raw)).scripts ?? {};\n } catch {\n return {}; // conflict markers or hand-broken JSON — nothing to reconcile\n }\n};\n\n// Locates the `\"scripts\"` object in raw package.json text. The alternation steps\n// over complete JSON strings, so a brace inside a command can't end the match\n// early.\nconst SCRIPTS_BLOCK = /\"scripts\"\\s*:\\s*\\{(?:[^{}\"]|\"(?:[^\"\\\\]|\\\\.)*\")*\\}/;\n\n// Sets a script's command in raw package.json text, appending the entry when the\n// side doesn't have it yet (no upstream tag carries `deploy`). Deliberately\n// textual rather than a JSON round-trip, for the same reason as\n// rewriteWorkspaceSpecifier: re-stringifying would reformat the whole file and\n// desync the downloaded trees from the merchant's copy, turning a one-line script\n// change into a whole-file conflict.\nexport const rewriteScriptCommand = (raw: string, name: string, command: string): string => {\n const block = SCRIPTS_BLOCK.exec(raw);\n\n if (!block) return raw;\n\n const splice = (replacement: string) =>\n raw.slice(0, block.index) + replacement + raw.slice(block.index + block[0].length);\n\n // Function replacer so `$&` / `$1` inside a command can't interpolate.\n const updated = block[0].replace(\n new RegExp(`(\"${escapeRegExp(name)}\"\\\\s*:\\\\s*)\"(?:[^\"\\\\\\\\]|\\\\\\\\.)*\"`),\n (_match, key: string) => `${key}${JSON.stringify(command)}`,\n );\n\n if (updated !== block[0]) return splice(updated);\n\n // Absent — append, reusing the block's own indentation so the inserted line is\n // byte-identical to the one `catalyst create` writes into the project.\n const closeIdx = block[0].length - 1;\n const head = block[0].slice(0, closeIdx).replace(/\\s+$/, '');\n const closeIndent = /\\n([ \\t]*)$/.exec(block[0].slice(0, closeIdx))?.[1] ?? '';\n const entryIndent = /\\n([ \\t]*)\"/.exec(block[0])?.[1] ?? `${closeIndent} `;\n const separator = head.endsWith('{') ? '' : ',';\n\n return splice(\n `${head}${separator}\\n${entryIndent}${JSON.stringify(name)}: ${JSON.stringify(command)}\\n${closeIndent}}`,\n );\n};\n\n// Rewrites the downloaded base/theirs package.json so both sides carry the\n// project's own commands for the CLI-managed scripts.\nexport async function normalizeManagedScripts(\n ourPkgRaw: string,\n baseDir: string,\n theirsDir: string,\n): Promise<{ pinned: string[]; upstreamChanged: ManagedScriptFinding[] }> {\n const basePath = join(baseDir, 'package.json');\n const theirsPath = join(theirsDir, 'package.json');\n const [originalBase, originalTheirs] = await Promise.all([\n readFile(basePath, 'utf-8').catch(() => null),\n readFile(theirsPath, 'utf-8').catch(() => null),\n ]);\n\n if (originalBase === null || originalTheirs === null) return { pinned: [], upstreamChanged: [] };\n\n const ourScripts = readScripts(ourPkgRaw);\n const baseScripts = readScripts(originalBase);\n const theirsScripts = readScripts(originalTheirs);\n\n const decisions = CLI_MANAGED_SCRIPTS.flatMap((name) => {\n const ours = ourScripts[name];\n\n return ours !== undefined && ours !== baseScripts[name] ? [{ name, ours }] : [];\n });\n\n // Report whenever the two tags disagree about the script, which covers core\n // changing the command, introducing it, and dropping it. Pinning makes the\n // merge blind to all three: an introduced command gets overwritten with the\n // project's own, and a dropped one gets written back.\n const upstreamChanged = decisions.flatMap<ManagedScriptFinding>(({ name }) => {\n const base = baseScripts[name] ?? null;\n const theirs = theirsScripts[name] ?? null;\n\n return base !== theirs ? [{ name, base, theirs }] : [];\n });\n\n const baseRaw = decisions.reduce(\n (acc, { name, ours }) => rewriteScriptCommand(acc, name, ours),\n originalBase,\n );\n const theirsRaw = decisions.reduce(\n (acc, { name, ours }) => rewriteScriptCommand(acc, name, ours),\n originalTheirs,\n );\n\n await Promise.all([\n baseRaw === originalBase ? null : writeFile(basePath, baseRaw),\n theirsRaw === originalTheirs ? null : writeFile(theirsPath, theirsRaw),\n ]);\n\n return { pinned: decisions.map(({ name }) => name), upstreamChanged };\n}\n\n// ── per-file 3-way merge engine ───────────────────────────────────────────────\ntype MergeOutcome = 'applied' | 'added' | 'deleted' | 'conflicted';\n\n// Runs git merge-file (standalone, no object store) writing the merged result\n// (with <<<ours/===/theirs>>> markers on conflict) to `oursPath`.\nasync function mergeFile(oursPath: string, basePath: string, theirsPath: string): Promise<boolean> {\n const merged = await execa(\n 'git',\n [\n 'merge-file',\n '-p',\n '-L',\n 'ours',\n '-L',\n 'base',\n '-L',\n 'theirs',\n oursPath,\n basePath,\n theirsPath,\n ],\n { reject: false, stripFinalNewline: false },\n );\n\n // git merge-file exits 0 (clean) or N>0 (N conflict hunks) — both are normal.\n // A fatal error (e.g. unreadable file) produces stderr output; guard against\n // overwriting the user's file with empty/partial stdout in that case.\n if (merged.stderr) throw new Error(`git merge-file failed: ${merged.stderr}`);\n\n await writeFile(oursPath, merged.stdout);\n\n return (merged.exitCode ?? 0) > 0; // >0 = conflict hunks\n}\n\nasync function mergeModified(\n rel: string,\n baseDir: string,\n theirsDir: string,\n catalystRoot: string,\n): Promise<MergeOutcome | null> {\n const basePath = join(baseDir, rel);\n const theirsPath = join(theirsDir, rel);\n const oursPath = join(catalystRoot, rel);\n\n // Upstream didn't actually change this file — nothing to do.\n if (await filesEqual(basePath, theirsPath)) return null;\n\n // Merchant deleted a file upstream modifies → restore theirs, flag for review.\n if (!(await pathExists(oursPath))) {\n await copyInto(theirsPath, oursPath);\n\n return 'conflicted';\n }\n\n if ((await isBinary(basePath)) || (await isBinary(theirsPath)) || (await isBinary(oursPath))) {\n if (await filesEqual(oursPath, basePath)) {\n await copyInto(theirsPath, oursPath);\n\n return 'applied';\n }\n\n return 'conflicted'; // binary both-changed — can't 3-way; leave ours\n }\n\n return (await mergeFile(oursPath, basePath, theirsPath)) ? 'conflicted' : 'applied';\n}\n\nasync function mergeAdded(\n rel: string,\n theirsDir: string,\n catalystRoot: string,\n emptyFile: string,\n): Promise<MergeOutcome> {\n const theirsPath = join(theirsDir, rel);\n const oursPath = join(catalystRoot, rel);\n\n if (!(await pathExists(oursPath))) {\n await copyInto(theirsPath, oursPath);\n\n return 'added';\n }\n\n if (await filesEqual(oursPath, theirsPath)) return 'applied'; // merchant already has it\n\n if ((await isBinary(oursPath)) || (await isBinary(theirsPath))) return 'conflicted';\n\n // Both added a different version — merge against an empty ancestor.\n const hadConflict = await mergeFile(oursPath, emptyFile, theirsPath);\n\n return hadConflict ? 'conflicted' : 'applied';\n}\n\nasync function mergeDeleted(\n rel: string,\n baseDir: string,\n catalystRoot: string,\n): Promise<MergeOutcome | null> {\n const basePath = join(baseDir, rel);\n const oursPath = join(catalystRoot, rel);\n\n if (!(await pathExists(oursPath))) return null; // already gone\n\n // Merchant kept upstream's version → safe to delete. Otherwise it's a\n // delete/modify conflict: keep ours and flag.\n if (await filesEqual(oursPath, basePath)) {\n await rm(oursPath, { force: true });\n\n return 'deleted';\n }\n\n return 'conflicted';\n}\n\nexport interface MergeResult {\n applied: string[];\n added: string[];\n deleted: string[];\n conflicted: string[];\n}\n\n// Per-file engine: walk the changed-file set and merge each file with\n// `git merge-file`. Needs no git object store, so it works on shallow / no-history\n// merchant repos. Trade-off: no rename detection (a rename = delete + add).\nexport async function mergeCorePerFile(\n baseDir: string,\n theirsDir: string,\n catalystRoot: string,\n emptyFile: string,\n): Promise<MergeResult> {\n const baseFiles = new Set(await listFiles(baseDir));\n const theirsFiles = new Set(await listFiles(theirsDir));\n const result: MergeResult = { applied: [], added: [], deleted: [], conflicted: [] };\n\n const decide = async (rel: string): Promise<void> => {\n const inBase = baseFiles.has(rel);\n const inTheirs = theirsFiles.has(rel);\n\n let outcome: MergeOutcome | null;\n\n if (inBase && inTheirs) {\n outcome = await mergeModified(rel, baseDir, theirsDir, catalystRoot);\n } else if (inTheirs) {\n outcome = await mergeAdded(rel, theirsDir, catalystRoot, emptyFile);\n } else {\n outcome = await mergeDeleted(rel, baseDir, catalystRoot);\n }\n\n if (outcome) result[outcome].push(rel);\n };\n\n await Promise.all([...new Set([...baseFiles, ...theirsFiles])].map(decide));\n\n return result;\n}\n\n// ── merge strategy selection ───────────────────────────────────────────────────\nexport type MergeStrategy = 'auto' | 'tree' | 'per-file';\n\n// `git merge-tree --write-tree` (the whole-tree engine) landed in git 2.38.\nexport async function gitSupportsMergeTree(): Promise<boolean> {\n try {\n const { stdout } = await execa('git', ['--version']);\n const match = /(\\d+)\\.(\\d+)/.exec(stdout);\n\n if (!match) return false;\n\n const [major, minor] = [Number(match[1]), Number(match[2])];\n\n return major > 2 || (major === 2 && minor >= 38);\n } catch {\n return false;\n }\n}\n\n// 'auto' resolves to the whole-tree engine when git supports it, else per-file.\nexport async function resolveStrategy(strategy: MergeStrategy): Promise<'tree' | 'per-file'> {\n if (strategy !== 'auto') return strategy;\n\n if (await gitSupportsMergeTree()) return 'tree';\n\n consola.warn('git < 2.38 — using the per-file merge engine (no `git merge-tree`).');\n\n return 'per-file';\n}\n\n// ── whole-tree 3-way merge engine (git merge-tree, 2.38+) ──────────────────────\n// Builds base/ours/theirs as commits in a throwaway object store, runs a real\n// recursive merge (rename detection, modify/delete, mode changes, binary — all\n// native to git), then materialises the merged tree into the catalyst root.\n// Conflicts come back as in-blob <<<ours/===/theirs>>> markers; like per-file it\n// never aborts. Branch names `ours`/`theirs` make the markers match the per-file\n// engine's labels.\nexport async function mergeCoreTree(\n baseDir: string,\n theirsDir: string,\n catalystRoot: string,\n): Promise<MergeResult> {\n const scratch = await mkdtemp(join(tmpdir(), 'catalyst-merge-'));\n\n try {\n await execa('git', ['init', '-q', scratch]);\n // Disable line-ending conversion so checkout-index writes LF on all platforms.\n await execa('git', ['config', 'core.autocrlf', 'false'], {\n env: { ...process.env, GIT_DIR: join(scratch, '.git') },\n });\n\n const env = {\n ...process.env,\n GIT_DIR: join(scratch, '.git'),\n GIT_AUTHOR_NAME: 'catalyst',\n GIT_AUTHOR_EMAIL: 'catalyst@bigcommerce.com',\n GIT_COMMITTER_NAME: 'catalyst',\n GIT_COMMITTER_EMAIL: 'catalyst@bigcommerce.com',\n };\n\n // Snapshot a directory as a tree object (own index per side; .gitignore is\n // honoured, so build artifacts like node_modules never enter the tree).\n const writeTree = async (workTree: string, tag: string): Promise<string> => {\n const sideEnv = {\n ...env,\n GIT_WORK_TREE: workTree,\n GIT_INDEX_FILE: join(scratch, `index.${tag}`),\n };\n\n await execa('git', ['add', '-A'], { env: sideEnv });\n\n return (await execa('git', ['write-tree'], { env: sideEnv })).stdout.trim();\n };\n\n const commitTree = (tree: string, parent?: string) =>\n execa('git', ['commit-tree', tree, '-m', 'x', ...(parent ? ['-p', parent] : [])], {\n env,\n }).then((r) => r.stdout.trim());\n\n // Run sequentially to avoid concurrent writes to the shared object store\n // on Windows, where simultaneous git processes cause EPERM on object files.\n const baseTree = await writeTree(baseDir, 'base');\n const oursTree = await writeTree(catalystRoot, 'ours');\n const theirsTree = await writeTree(theirsDir, 'theirs');\n\n const baseCommit = await commitTree(baseTree);\n const [oursCommit, theirsCommit] = await Promise.all([\n commitTree(oursTree, baseCommit),\n commitTree(theirsTree, baseCommit),\n ]);\n\n await Promise.all([\n execa('git', ['branch', 'ours', oursCommit], { env }),\n execa('git', ['branch', 'theirs', theirsCommit], { env }),\n ]);\n\n // -z --name-only output: <merged-tree-oid> NUL, then conflicted paths each\n // NUL-terminated, then an empty field marks the end of the conflicted set\n // (everything after is informational messages we don't need).\n const merge = await execa(\n 'git',\n [\n 'merge-tree',\n '--write-tree',\n '-z',\n '--name-only',\n `--merge-base=${baseCommit}`,\n 'ours',\n 'theirs',\n ],\n { env, reject: false },\n );\n\n if ((merge.exitCode ?? 0) > 1)\n throw new Error(merge.stderr || merge.stdout.slice(0, 500) || 'git merge-tree failed');\n\n // -z --name-only emits <merged-tree-oid>, then conflicted paths, then an\n // empty field; everything after that is informational and ignored.\n const fields = merge.stdout.split('\\0');\n const mergedTree = fields[0];\n const afterOid = fields.slice(1);\n const emptyAt = afterOid.indexOf('');\n const conflicted = afterOid.slice(0, emptyAt === -1 ? afterOid.length : emptyAt);\n const conflictedSet = new Set(conflicted);\n\n // Materialise the merged tree into the catalyst root (conflict markers are\n // already baked into the conflicted blobs).\n const outEnv = {\n ...env,\n GIT_WORK_TREE: catalystRoot,\n GIT_INDEX_FILE: join(scratch, 'index.out'),\n };\n\n await execa('git', ['read-tree', mergedTree], { env: outEnv });\n await execa('git', ['checkout-index', '-a', '-f'], { env: outEnv });\n\n // Classify ours → merged. -z --name-status emits [status, path, status, …].\n const diff = await execa(\n 'git',\n ['diff', '-z', '--no-renames', '--name-status', oursTree, mergedTree],\n { env },\n );\n\n const tokens = diff.stdout.split('\\0');\n const changes: Array<{ status: string; path: string }> = [];\n\n for (let i = 0; i + 1 < tokens.length; i += 2) {\n const status = tokens[i];\n const path = tokens[i + 1];\n\n if (status && path && !conflictedSet.has(path)) {\n changes.push({ status, path });\n }\n }\n\n // checkout-index only writes; it won't remove paths the merge dropped.\n const deleted = changes.filter((change) => change.status === 'D').map((change) => change.path);\n\n await Promise.all(deleted.map((path) => rm(join(catalystRoot, path), { force: true })));\n\n return {\n applied: changes\n .filter((change) => change.status !== 'A' && change.status !== 'D')\n .map((change) => change.path),\n added: changes.filter((change) => change.status === 'A').map((change) => change.path),\n deleted,\n conflicted,\n };\n } finally {\n await rm(scratch, { recursive: true, force: true, maxRetries: 10, retryDelay: 500 });\n }\n}\n\n// ── index staging ──────────────────────────────────────────────────────────────\n// After the merge, stage everything that merged cleanly (so the merchant only\n// reviews what needs attention) and register conflicted files as real unmerged\n// index entries: stage 1 = base, 2 = ours (the committed pre-upgrade blob),\n// 3 = theirs. `git status` then reports them as conflicts (UU / AA / DU), which\n// lights up editors' merge UIs. No MERGE_HEAD — the target tag isn't an ancestor,\n// so resolving is a normal `git add` + commit, not a merge commit.\nexport async function applyIndexState(\n gitRoot: string,\n relDir: string,\n baseDir: string,\n theirsDir: string,\n result: MergeResult,\n stampedPkg: boolean,\n): Promise<void> {\n const toRepoPath = (rel: string) => (relDir === '.' ? rel : `${relDir}/${rel}`);\n const pkgRel = 'package.json';\n\n // If the stamp resolved package.json (stripped its conflict markers and wrote\n // clean JSON), treat it as a clean file rather than a conflict — it should be\n // staged normally so it shows up in `git diff --cached`, not registered as UU.\n const stillConflicted = result.conflicted.filter((rel) => !(stampedPkg && rel === pkgRel));\n const conflictedRepoPaths = new Set(stillConflicted.map(toRepoPath));\n\n // 1. Pre-stage the clean changes (+ the resolved package.json when stamped).\n const clean = [...result.applied, ...result.added, ...result.deleted].map(toRepoPath);\n\n if (stampedPkg) clean.push(toRepoPath(pkgRel));\n\n const toStage = [...new Set(clean)].filter((path) => !conflictedRepoPaths.has(path));\n\n if (toStage.length) {\n await execa('git', ['add', '-A', '--', ...toStage], { cwd: gitRoot });\n }\n\n if (stillConflicted.length === 0) return;\n\n // 2. Conflicts → unmerged index entries. ours = the committed blob (the\n // clean-tree precondition guarantees the worktree matched HEAD before the\n // merge); base/theirs blobs get written into the repo's object store.\n const OID = /^[0-9a-f]{40,64}$/;\n // Detect SHA-256 repos (git 2.29+). SHA-1 uses a 40-zero null OID; SHA-256 uses 64.\n const gitFormat = (\n await execa('git', ['rev-parse', '--show-object-format'], { cwd: gitRoot, reject: false })\n ).stdout.trim();\n const NULL_OID = gitFormat === 'sha256' ? '0'.repeat(64) : '0'.repeat(40);\n\n // Write a file's content as a blob; null if the file is absent or the OID\n // comes back malformed (guards against shell wrappers polluting stdout).\n const hashBlob = async (file: string): Promise<string | null> => {\n if (!(await pathExists(file))) return null;\n\n const oid = (\n await execa('git', ['hash-object', '-w', '--', file], { cwd: gitRoot })\n ).stdout.trim();\n\n return OID.test(oid) ? oid : null;\n };\n\n // ours mode + blob via `ls-tree`. Unlike `rev-parse HEAD:<path>`, ls-tree\n // never echoes a missing path back as if it were an object name.\n const headEntry = async (repoPath: string): Promise<{ mode: string; oid: string } | null> => {\n const { stdout } = await execa('git', ['ls-tree', 'HEAD', '--', repoPath], {\n cwd: gitRoot,\n reject: false,\n });\n const match = /^(\\d{6}) blob ([0-9a-f]+)\\t/.exec(stdout);\n\n return match ? { mode: match[1], oid: match[2] } : null;\n };\n\n const records = await Promise.all(\n stillConflicted.map(async (rel) => {\n const repoPath = toRepoPath(rel);\n const [base, ours, theirs] = await Promise.all([\n hashBlob(join(baseDir, rel)),\n headEntry(repoPath),\n hashBlob(join(theirsDir, rel)),\n ]);\n\n return [\n `0 ${NULL_OID}\\t${repoPath}`,\n ...(base ? [`100644 ${base} 1\\t${repoPath}`] : []),\n ...(ours ? [`${ours.mode} ${ours.oid} 2\\t${repoPath}`] : []),\n ...(theirs ? [`100644 ${theirs} 3\\t${repoPath}`] : []),\n ].join('\\n');\n }),\n );\n\n await execa('git', ['update-index', '--index-info'], {\n cwd: gitRoot,\n input: `${records.join('\\n')}\\n`,\n });\n}\n\n// ── project (destination) layout resolution ───────────────────────────────────\n// The command is merchant-facing and must support two repo shapes:\n// * flat (future) — core/ contents at the repo root (package.json at root)\n// * nested (deprecated monorepo clone) — core/package.json under <root>/core\n// We locate the package.json carrying the `catalyst` field; if none has it yet\n// we fall back to the most likely Catalyst package.json so the auto-detect path\n// can still run.\ninterface Project {\n gitRoot: string;\n catalystRoot: string;\n relDir: string; // \".\" (flat) or \"core\" (nested), relative to gitRoot\n pkgPath: string;\n rawContent: string;\n pkg: z.infer<typeof CorePackageJson>;\n}\n\nexport async function resolveProject(cwd: string): Promise<Project | null> {\n let gitRoot: string;\n\n try {\n gitRoot = (await execa('git', ['rev-parse', '--show-toplevel'], { cwd })).stdout.trim();\n } catch {\n return null;\n }\n\n // Probe order favours the nested core/ first (a monorepo clone also has a\n // root package.json we don't want), then flat, then the cwd variants.\n const candidateDirs = [...new Set([join(gitRoot, 'core'), gitRoot, join(cwd, 'core'), cwd])];\n\n const parsed = (\n await Promise.all(\n candidateDirs.map(async (dir) => {\n const pkgPath = join(dir, 'package.json');\n const raw = await readFile(pkgPath, 'utf-8').catch(() => null);\n\n if (!raw) return null;\n\n let pkgJson: unknown;\n\n try {\n pkgJson = JSON.parse(raw);\n } catch {\n return null;\n }\n\n const result = CorePackageJson.safeParse(pkgJson);\n\n return result.success ? { dir, pkgPath, raw, pkg: result.data } : null;\n }),\n )\n ).filter((entry) => entry !== null);\n\n if (parsed.length === 0) return null;\n\n // Prefer the package.json that already declares `catalyst`; otherwise fall\n // back to one that looks like a Catalyst project (known family name).\n const chosen =\n parsed.find((p) => p.pkg.catalyst?.ref) ??\n parsed.find((p) => p.pkg.name !== undefined && KNOWN_FAMILIES.has(p.pkg.name)) ??\n parsed[0];\n\n return {\n gitRoot,\n catalystRoot: chosen.dir,\n relDir: relative(gitRoot, chosen.dir) || '.',\n pkgPath: chosen.pkgPath,\n rawContent: chosen.raw,\n pkg: chosen.pkg,\n };\n}\n\n// ── tarball download (source side stays the monorepo) ─────────────────────────\n// Harvests the versions the monorepo's publishable packages carried at this ref.\n// This is the only place they're knowable: the tag's core/package.json names them\n// as `workspace:`, and they version independently of core (no changesets\n// `linked`/`fixed` group), so an npm `latest` lookup would answer for today\n// rather than for the ref being downloaded.\nconst readWorkspaceVersions = async (repoDir: string): Promise<WorkspaceVersions> => {\n const packagesDir = join(repoDir, 'packages');\n const entries = await readdir(packagesDir, { withFileTypes: true }).catch(() => []);\n\n const manifests = await Promise.all(\n entries\n .filter((entry) => entry.isDirectory())\n .map(async (entry) => {\n const raw = await readFile(join(packagesDir, entry.name, 'package.json'), 'utf-8').catch(\n () => null,\n );\n\n if (raw === null) return null;\n\n try {\n return WorkspacePackageJson.parse(JSON.parse(raw));\n } catch {\n return null;\n }\n }),\n );\n\n return Object.fromEntries(\n manifests.filter((pkg) => pkg !== null).map(({ name, version }) => [name, version]),\n );\n};\n\nconst readCachedVersions = async (path: string): Promise<WorkspaceVersions | null> => {\n const raw = await readFile(path, 'utf-8').catch(() => null);\n\n if (raw === null) return null;\n\n try {\n return z.record(z.string(), z.string()).parse(JSON.parse(raw));\n } catch {\n return null;\n }\n};\n\nexport async function downloadCore(\n repository: string,\n ref: string,\n destDir: string,\n token?: string,\n): Promise<WorkspaceVersions> {\n // Never cache moving tags (latest/canary/alpha) — they'd go stale silently.\n const cacheable = !MOVING_TAGS.has(parseRef(ref).version);\n // Use a separator before the ref so that repository strings differing only\n // by characters that sanitize to '_' (e.g. '/' vs '_') produce distinct keys.\n const cacheKey = `${repository.replace(/[^a-zA-Z0-9._-]/g, '_')}__${ref.replace(/[^a-zA-Z0-9._-]/g, '_')}`;\n const cachePath = join(CACHE_DIR, cacheKey);\n const versionsPath = `${cachePath}.versions.json`;\n\n // Guard against a partially-written cache entry: two concurrent downloadCore\n // calls for the same ref can race — the first creates cachePath mid-copy, and\n // the second sees it as present but gets an incomplete directory. Validate with\n // a package.json sentinel (every extracted core/ tree must have one) plus the\n // versions sidecar, which also makes entries written before the sidecar existed\n // fall through to a fresh download rather than answering with no versions.\n const cachedVersions =\n cacheable && (await pathExists(join(cachePath, 'package.json')))\n ? await readCachedVersions(versionsPath)\n : null;\n\n if (cachedVersions) {\n await cp(cachePath, destDir, { recursive: true });\n\n return cachedVersions;\n }\n\n // encodeURIComponent turns \"@bigcommerce/catalyst-core@1.7.0\" into\n // \"%40bigcommerce%2Fcatalyst-core%401.7.0\", which the API accepts.\n const url = `https://api.github.com/repos/${repository}/tarball/${encodeURIComponent(ref)}`;\n const headers: Record<string, string> = {\n 'User-Agent': 'catalyst-cli',\n Accept: 'application/vnd.github+json',\n };\n\n if (token) headers.Authorization = `Bearer ${token}`;\n\n const res = await fetch(url, { headers });\n\n if (!res.ok) {\n let hint = '';\n\n if (res.status === 404) hint = ` — tag \"${ref}\" not found in ${repository}`;\n if (res.status === 403) hint = ' — GitHub rate limit hit; set GITHUB_TOKEN to raise it';\n\n throw new Error(`GitHub returned ${res.status} for ${ref}${hint}`);\n }\n\n const tarballPath = `${destDir}.tgz`;\n const rawDir = `${destDir}.raw`;\n\n await writeFile(tarballPath, Buffer.from(await res.arrayBuffer()));\n await mkdir(rawDir, { recursive: true });\n // --strip-components=1 drops the \"bigcommerce-catalyst-<sha>/\" top dir.\n await execa('tar', ['-xzf', tarballPath, '-C', rawDir, '--strip-components=1']);\n\n // Source is expected to be the monorepo (core/ inside); fall back to the\n // extracted root for a hypothetical flat-source tag (insurance, not a target).\n const coreDir = join(rawDir, 'core');\n const sourceDir = (await pathExists(coreDir)) ? coreDir : rawDir;\n\n // Read the sibling packages before rawDir is torn down — destDir keeps core/ only.\n const workspaceVersions = await readWorkspaceVersions(rawDir);\n\n await rename(sourceDir, destDir);\n await rm(tarballPath, { force: true });\n await rm(rawDir, { recursive: true, force: true });\n\n if (cacheable) {\n await mkdir(CACHE_DIR, { recursive: true });\n await cp(destDir, cachePath, { recursive: true })\n .then(() => writeFile(versionsPath, JSON.stringify(workspaceVersions)))\n .catch(() => {\n /* best-effort cache; ignore failures */\n });\n }\n\n return workspaceVersions;\n}\n\n// ── base-ref resolution / auto-detect ─────────────────────────────────────────\n// Returns the base ref to diff from, auto-detecting when catalyst.ref is absent.\nexport async function resolveBaseRef(\n project: Project,\n fromOption: string | undefined,\n assumeYes: boolean,\n): Promise<string | null> {\n if (project.pkg.catalyst?.ref) return project.pkg.catalyst.ref;\n if (fromOption) return fromOption;\n\n // Older projects mirror the Catalyst version in `version`; the package `name`\n // tells us the family. Propose the inferred ref and let the merchant confirm.\n const family =\n project.pkg.name && KNOWN_FAMILIES.has(project.pkg.name)\n ? project.pkg.name\n : '@bigcommerce/catalyst-core';\n const guess = `${family}@${project.pkg.version}`;\n\n consola.warn(`No \\`catalyst.ref\\` found in package.json. Inferred base: ${guess}`);\n\n if (assumeYes) return guess;\n\n const ok = await confirm({ message: `Upgrade from ${guess}?`, default: true }).catch(() => false);\n\n if (!ok) {\n consola.info('Re-run with `--from <ref>` to set the base version explicitly.');\n\n return null;\n }\n\n return guess;\n}\n\n// ── summary output ────────────────────────────────────────────────────────────\nfunction printWorkspaceFindings(findings: WorkspaceDepFinding[]): void {\n if (findings.length === 0) return;\n\n const pad = Math.max(...findings.map((finding) => finding.name.length));\n const rows = findings\n .map((finding) => ` ${finding.name.padEnd(pad)} ${finding.ours} → ^${finding.version}`)\n .join('\\n');\n\n consola.warn(\n `Catalyst dependencies still using the workspace protocol (${findings.length}):\\n${rows}\\n\\nThey resolve to your local packages/ copies, which \\`catalyst upgrade\\` does not update — so they never receive upgrades.`,\n );\n}\n\n// Pinning the CLI-managed scripts keeps the merge off those lines, so an upstream\n// edit to one of them would otherwise vanish without a trace. Report it instead.\nfunction printManagedScriptFindings(findings: ManagedScriptFinding[]): void {\n if (findings.length === 0) return;\n\n const pad = Math.max(...findings.map((finding) => finding.name.length));\n const show = (command: string | null) => command ?? '(absent)';\n const rows = findings\n .map(\n (finding) => ` ${finding.name.padEnd(pad)} ${show(finding.base)} → ${show(finding.theirs)}`,\n )\n .join('\\n');\n\n consola.warn(\n `Core's own version of ${findings.length} npm script${findings.length === 1 ? '' : 's'} the CLI manages for you changed:\\n${rows}\\n\\nYour project keeps its \\`catalyst\\`-backed command, which is almost always what you want — \\`catalyst build\\`/\\`start\\`/\\`deploy\\` wrap the equivalent \\`next\\` command. Apply the change by hand only if you have opted out of the CLI scripts.`,\n );\n}\n\ninterface Summary {\n result: MergeResult;\n relDir: string;\n stampedPkg: boolean;\n migratedDeps: number;\n packageManager: PackageManager;\n staleCli: { current: string; latest: string } | null;\n}\n\nfunction printSummary({\n result,\n relDir,\n stampedPkg,\n migratedDeps,\n packageManager,\n staleCli,\n}: Summary): void {\n // package.json is excluded from the conflict list when the stamp resolved it.\n const unresolved = result.conflicted.filter((f) => !(stampedPkg && f === 'package.json'));\n\n const parts = [\n `${result.applied.length} updated`,\n `${result.added.length} added`,\n `${result.deleted.length} removed`,\n ];\n\n if (unresolved.length) parts.push(`${unresolved.length} with conflicts`);\n\n consola.log(`\\n${parts.join(', ')}`);\n\n // Any package.json change can move dependencies, and the upgrade never installs,\n // so the lockfile is left behind either way.\n const pkgConflicted = unresolved.includes('package.json');\n const depsChanged =\n migratedDeps > 0 ||\n [...result.applied, ...result.added, ...result.conflicted].includes('package.json');\n\n // Stay quiet while package.json itself is unresolved: an install against a\n // manifest full of conflict markers just fails. It joins the resolution steps\n // below instead, so it runs in the right order.\n if (depsChanged && !pkgConflicted) {\n consola.info(\n `Dependencies changed — run \\`${packageManager} install\\` to update your lockfile.`,\n );\n }\n\n if (unresolved.length) {\n const files = unresolved.map((f) => ` ${f}`).join('\\n');\n const install = depsChanged && pkgConflicted ? ` && ${packageManager} install` : '';\n\n consola.warn(\n `\\nStaged the clean changes. ${unresolved.length} file(s) need conflict resolution (the <<<ours/===/theirs>>> markers):\\n${files}\\n\\nResolve them, then: git add ${relDir} && git commit${install}`,\n );\n } else {\n consola.success('Staged all changes — review with `git diff --cached`, then commit.');\n }\n\n if (staleCli) {\n consola.info(\n `Your Catalyst CLI is behind (${staleCli.current} → ${staleCli.latest}). Update it with \\`${packageManager} add -D ${CATALYST_CLI_PACKAGE}@${staleCli.latest}\\`.`,\n );\n }\n}\n\nexport async function reconcileNativeHosting(\n catalystRoot: string,\n result: MergeResult,\n): Promise<void> {\n const state = getProjectState(catalystRoot);\n\n if (!state.isLinked && !state.isTransformed) return;\n\n const instrumentationRel = 'instrumentation.ts';\n const instrumentationPath = join(catalystRoot, instrumentationRel);\n const hadInstrumentation = await pathExists(instrumentationPath);\n\n try {\n await cleanupCloudflareIncompatibilities(catalystRoot);\n } catch (err) {\n consola.warn(\n `Couldn't fully reconcile native-hosting files (${err instanceof Error ? err.message : String(err)}). Remove @vercel/otel from package.json by hand if the merge brought it back.`,\n );\n }\n\n if (hadInstrumentation && !(await pathExists(instrumentationPath))) {\n result.conflicted = result.conflicted.filter((rel) => rel !== instrumentationRel);\n result.applied = result.applied.filter((rel) => rel !== instrumentationRel);\n result.added = result.added.filter((rel) => rel !== instrumentationRel);\n }\n}\n\nexport const upgrade = new Command('upgrade')\n .configureHelp({ showGlobalOptions: true })\n .aliases([\n 'up',\n // These are hidden aliases\n 'upgrayedd',\n 'ugrad',\n ])\n .description('Upgrade your Catalyst project to a newer version by applying a 3-way merge.')\n .argument('[version]', 'Target version to upgrade to (default: latest)')\n .addOption(\n new Option(\n '--ref <ref>',\n 'Full git tag to upgrade to, e.g. an integration family like @bigcommerce/catalyst-makeswift@1.7.0. Overrides [version].',\n ),\n )\n .addOption(new Option('--from <ref>', 'Base ref to upgrade from (when catalyst.ref is missing)'))\n .option('--dry-run', 'Generate and display the diff without applying it')\n .option('--yes', 'Skip confirmation prompts (e.g. inferred base ref)')\n .addOption(\n new Option(\n '--strategy <strategy>',\n 'Merge engine: tree (git merge-tree, full fidelity), per-file (git merge-file, no-history fallback), or auto (tree when git >= 2.38, else per-file)',\n )\n .choices(['auto', 'tree', 'per-file'] as const)\n .default('auto' as const)\n .hideHelp(),\n )\n .addOption(\n new Option('--repository <owner/repo>', 'GitHub repository to pull versions from').default(\n DEFAULT_REPOSITORY,\n ),\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Upgrade to the latest Catalyst version\n $ catalyst upgrade\n\n # Upgrade to a specific version\n $ catalyst upgrade 1.8.0\n\n # Preview what would change without applying\n $ catalyst upgrade --dry-run\n\n # Upgrade to an integration family (makeswift, b2b-makeswift, ...)\n $ catalyst upgrade --ref @bigcommerce/catalyst-makeswift@1.7.0\n\nConflicts are written as standard <<<ours/===/theirs>>> markers — the upgrade\nnever aborts. Versions are git tags on the repository (not npm). Set GITHUB_TOKEN\nto raise the GitHub API rate limit.`,\n )\n // eslint-disable-next-line complexity\n .action(async (version, options) => {\n // ── 1. Resolve the merchant project (flat or nested layout) ───────────\n const project = await resolveProject(process.cwd());\n\n if (!project) {\n consola.error(\n 'Run `catalyst upgrade` from inside a Catalyst git repository (flat core/ repo or a project containing core/).',\n );\n process.exit(1);\n }\n\n const { gitRoot, catalystRoot, relDir, pkgPath } = project;\n\n // ── 2. Resolve base + target refs ─────────────────────────────────────\n const baseRef = await resolveBaseRef(project, options.from, options.yes ?? false);\n\n if (!baseRef) process.exit(1);\n\n let basePackage: string;\n let upstreamRef: string;\n let upstreamTagVersion: string;\n\n try {\n ({ packageName: basePackage } = parseRef(baseRef));\n upstreamRef = options.ref ?? `${basePackage}@${version ?? 'latest'}`;\n ({ version: upstreamTagVersion } = parseRef(upstreamRef));\n } catch {\n consola.error(\n `Invalid ref format — expected <package>@<version> (e.g. @bigcommerce/catalyst-core@1.7.0). Got: \"${baseRef}\"`,\n );\n process.exit(1);\n }\n\n if (upstreamRef === baseRef) {\n consola.success('Already up to date.');\n\n return;\n }\n\n // ── 3. Require a clean working tree at the catalyst root (preview exempt) ─\n // The merge writes in place, so pre-existing uncommitted edits would be\n // indistinguishable from the upgrade. Committing/stashing first gives the\n // merchant a clean point to diff and roll back from.\n if (!options.dryRun) {\n const statusArgs = relDir === '.' ? [] : ['--', relDir];\n const status = await execa('git', ['status', '--porcelain', ...statusArgs], {\n cwd: gitRoot,\n reject: false,\n });\n\n if (status.stdout.trim()) {\n const where = relDir === '.' ? 'The repo' : `${relDir}/`;\n\n consola.error(\n `${where} has uncommitted changes. Commit or stash them before upgrading, so the upgrade is isolated and reversible:\\n git add ${relDir} && git commit -m \"snapshot before upgrade\"\\n # or: git stash`,\n );\n process.exit(1);\n }\n }\n\n // ── 3b. Backfill catalyst.ref when it was inferred ────────────────────\n // If catalyst.ref was absent and the user confirmed an inferred base (not\n // an explicit --from), write the field and stage it so it travels with the\n // upgrade commit. Runs after the clean-tree check so we only add to an\n // already-clean index. --from is excluded: the user already knows the base\n // and shouldn't get an extra staged change they didn't ask for.\n if (!project.pkg.catalyst?.ref && !options.from && !options.dryRun) {\n const { version: baseVersion } = parseRef(baseRef);\n const rawPkg = await readFile(pkgPath, 'utf-8');\n const parsedPkg = z.record(z.string(), z.unknown()).parse(JSON.parse(rawPkg));\n\n parsedPkg.catalyst = { version: baseVersion, ref: baseRef };\n await writeFile(pkgPath, `${JSON.stringify(parsedPkg, null, 2)}\\n`);\n await execa('git', ['add', '--', pkgPath], { cwd: gitRoot });\n consola.success(`Added catalyst.ref → ${baseRef}`);\n }\n\n const token = process.env.GITHUB_TOKEN;\n const tmpDir = await mkdtemp(join(tmpdir(), 'catalyst-upgrade-'));\n\n try {\n const baseDir = join(tmpDir, 'base');\n const theirsDir = join(tmpDir, 'theirs');\n const emptyFile = join(tmpDir, '.empty');\n\n await writeFile(emptyFile, '');\n\n // Start the registry check now so its round-trip overlaps the tarball\n // downloads rather than adding dead air after the merge. Reading the\n // pre-merge manifest is also more robust: the CLI dependency isn't in\n // either upstream tree, so nothing below can move it, and this way the\n // advisory survives a merge that leaves conflict markers in package.json.\n const staleCliCheck = findStaleCli(project.rawContent).catch(() => null);\n\n const downloadSpinner = yoctoSpinner().start(`Downloading ${baseRef} and ${upstreamRef}...`);\n\n let baseVersions: WorkspaceVersions;\n let targetVersions: WorkspaceVersions;\n\n try {\n [baseVersions, targetVersions] = await Promise.all([\n downloadCore(options.repository, baseRef, baseDir, token),\n downloadCore(options.repository, upstreamRef, theirsDir, token),\n ]);\n downloadSpinner.success('Downloaded both versions.');\n } catch (err) {\n downloadSpinner.error('Download failed');\n throw err;\n }\n\n // When the base was auto-inferred (no catalyst.ref, no --from), validate\n // the guess by checking how many base files are unmodified in the project.\n // A correct base scores ~70-80%+; a wrong guess (e.g. merchant manually\n // bumped their version field without actually upgrading) scores much lower.\n if (!project.pkg.catalyst?.ref && !options.from) {\n const similarity = await computeBaseSimilarity(baseDir, catalystRoot);\n const pct = Math.round(similarity * 100);\n\n if (similarity < 0.5) {\n consola.warn(\n `Low confidence in inferred base ${baseRef} (${pct}% of base files match your project). If the merge result looks off, re-run with \\`--from <correct-version>\\` to set the base explicitly.`,\n );\n }\n }\n\n // For moving tags (latest/canary/alpha) we don't know the real version\n // until the tarball lands, so read it from the downloaded package.json.\n // For concrete tags the version is already in the tag itself.\n const resolvedVersion = MOVING_TAGS.has(upstreamTagVersion)\n ? await readResolvedVersion(theirsDir)\n : upstreamTagVersion;\n const newRef = MOVING_TAGS.has(upstreamTagVersion)\n ? `${basePackage}@${resolvedVersion}`\n : upstreamRef;\n\n // ── 3c. Teach the merge about Catalyst dependency versions ──────────\n // Runs before the dry run so the preview shows the dependency change too.\n // rawContent predates the 3b backfill, which only touches the `catalyst`\n // field — dependency specifiers are identical either way.\n const { workspace: workspaceDeps, bumped } = await normalizeWorkspaceDeps(\n project.rawContent,\n baseDir,\n theirsDir,\n baseVersions,\n targetVersions,\n );\n\n // ── 3d. Keep the merge off the CLI-managed npm scripts ──────────────\n // Also before the dry run, so the preview matches what will be applied.\n const { upstreamChanged: managedScripts } = await normalizeManagedScripts(\n project.rawContent,\n baseDir,\n theirsDir,\n );\n\n // ── 4. Dry run: show the unified diff and stop ──────────────────────\n if (options.dryRun) {\n const diffSpinner = yoctoSpinner().start('Generating diff...');\n const diff = await execa(\n 'git',\n ['diff', '--no-index', '--binary', '--diff-algorithm=histogram', 'base', 'theirs'],\n { cwd: tmpDir, reject: false, stripFinalNewline: false },\n );\n\n if ((diff.exitCode ?? 0) > 1) {\n diffSpinner.error('Failed to generate diff');\n throw new Error(diff.stderr);\n }\n\n if (!diff.stdout.trim()) {\n diffSpinner.success('No differences between versions — already up to date.');\n\n return;\n }\n\n const fileCount = (diff.stdout.match(/^diff --git /gm) ?? []).length;\n\n diffSpinner.success(`Diff ready — ${fileCount} file(s) affected.`);\n consola.log('\\nDiff preview (--dry-run, not applied):\\n');\n consola.log(diff.stdout);\n\n printWorkspaceFindings(workspaceDeps);\n printManagedScriptFindings(managedScripts);\n\n return;\n }\n\n // ── 5. Apply via 3-way merge (whole-tree by default, per-file fallback) ─\n const strategy = await resolveStrategy(options.strategy);\n const mergeSpinner = yoctoSpinner().start(`Merging changes (${strategy})...`);\n const result =\n strategy === 'tree'\n ? await mergeCoreTree(baseDir, theirsDir, catalystRoot)\n : await mergeCorePerFile(baseDir, theirsDir, catalystRoot, emptyFile);\n const total =\n result.applied.length +\n result.added.length +\n result.deleted.length +\n result.conflicted.length;\n\n if (total === 0) {\n mergeSpinner.success('No differences between versions — already up to date.');\n\n return;\n }\n\n if (result.conflicted.length) {\n mergeSpinner.warning('Merged with conflicts — resolve the markers, then commit.');\n } else {\n mergeSpinner.success('Merged cleanly.');\n }\n\n // ── 6. Stamp catalyst.ref (skip if package.json itself conflicted) ──\n const patchedRaw = await readFile(pkgPath, 'utf-8');\n\n // Non-null once the stamp has written clean JSON, and then it is exactly\n // what sits on disk. Stays null when package.json came out of the merge\n // carrying conflict markers.\n let stampedText: string | null = null;\n\n try {\n const patchedPkg = z.record(z.string(), z.unknown()).parse(JSON.parse(patchedRaw));\n\n patchedPkg.catalyst = { version: resolvedVersion, ref: newRef };\n stampedText = `${JSON.stringify(patchedPkg, null, 2)}\\n`;\n await writeFile(pkgPath, stampedText);\n consola.success(`catalyst.ref updated → ${newRef}`);\n } catch {\n // package.json has conflict markers (scripts, deps, etc.). The catalyst\n // field was added cleanly by ours and should sit outside the conflict\n // blocks — so replace just that field in-place, leaving all other conflict\n // markers intact for the merchant to resolve normally.\n const catalystReplacement = JSON.stringify(\n { version: resolvedVersion, ref: newRef },\n null,\n 2,\n )\n .split('\\n')\n .map((line, i) => (i === 0 ? line : ` ${line}`))\n .join('\\n');\n\n // Use a function replacer to prevent $-interpolation in the replacement string\n // (e.g. $& or $1 in a ref/version value would silently corrupt the output).\n const updated = patchedRaw.replace(\n /\"catalyst\":\\s*\\{[^}]*\\}/,\n () => `\"catalyst\": ${catalystReplacement}`,\n );\n\n if (updated !== patchedRaw) {\n await writeFile(pkgPath, updated);\n // stampedText stays null — the file still has conflict markers in other\n // sections, so it must stay as a UU unmerged entry so the editor shows\n // the merge UI. Only the catalyst field was resolved in place.\n consola.success(`catalyst.ref updated → ${newRef}`);\n consola.info(\n 'package.json still has conflicts in other sections — resolve them, then: git add package.json',\n );\n } else {\n consola.warn(\n `package.json has conflicts — after resolving, add:\\n \"catalyst\": { \"version\": \"${resolvedVersion}\", \"ref\": \"${newRef}\" }`,\n );\n }\n }\n\n printManagedScriptFindings(managedScripts);\n\n // ── 6b. Offer to migrate workspace-protocol Catalyst dependencies ────\n printWorkspaceFindings(workspaceDeps);\n\n let migratedDeps = 0;\n\n if (workspaceDeps.length) {\n // Rewriting a package.json that still holds conflict markers could land\n // inside a hunk the merchant hasn't reviewed, so the swap is only ever\n // applied to a file the stamp already parsed cleanly. Past that, --yes\n // means yes (as it does for the inferred base ref), and a non-interactive\n // run falls through to printing the versions.\n const accepted =\n stampedText !== null &&\n (options.yes === true ||\n (Boolean(process.stdin.isTTY) &&\n (await confirm({\n message: 'Replace them with the published versions?',\n default: true,\n }).catch(() => false))));\n\n if (accepted && stampedText !== null) {\n await writeFile(pkgPath, migrateWorkspaceDeps(stampedText, workspaceDeps));\n migratedDeps = workspaceDeps.length;\n consola.success(\n `Migrated ${migratedDeps} dependenc${migratedDeps === 1 ? 'y' : 'ies'} to published versions.`,\n );\n } else {\n consola.info(\n \"Keeping the workspace references. Switching abandons any local packages/ copy you've customized; otherwise apply the versions above in package.json and reinstall.\",\n );\n }\n }\n\n await reconcileNativeHosting(catalystRoot, result);\n\n // ── 7. Stage the clean changes; mark conflicts as real unmerged entries ─\n // Staging is a convenience; the merge already landed on disk, so never let\n // a git quirk here fail the whole upgrade.\n try {\n await applyIndexState(gitRoot, relDir, baseDir, theirsDir, result, stampedText !== null);\n } catch (err) {\n consola.warn(\n `Couldn't auto-stage the changes (${err instanceof Error ? err.message : String(err)}). Your files are merged on disk — run \\`git add ${relDir}\\` yourself.`,\n );\n }\n\n const gitVersion = await execa('git', ['--version'])\n .then((r) => r.stdout.trim())\n .catch(() => 'unknown');\n\n // The lockfile lives at the repo root for both layouts and is committed by\n // every real project, so it answers this on its own. Catalyst scaffolds with\n // pnpm, which makes it the least-surprising answer when there isn't one.\n const packageManager = (await detectLockfileManager(gitRoot)) ?? 'pnpm';\n const staleCli = await staleCliCheck;\n\n await getTelemetry().track('upgrade', {\n strategy,\n gitVersion,\n dryRun: Boolean(options.dryRun),\n applied: result.applied.length,\n added: result.added.length,\n deleted: result.deleted.length,\n conflicts: result.conflicted.length,\n hasConflicts: result.conflicted.length > 0,\n workspaceDepsFound: workspaceDeps.length,\n workspaceDepsMigrated: migratedDeps,\n catalystDepsBumped: bumped.length,\n cliOutdated: staleCli !== null,\n });\n\n printSummary({\n result,\n relDir,\n stampedPkg: stampedText !== null,\n migratedDeps,\n packageManager,\n staleCli,\n });\n } finally {\n await rm(tmpDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 500 });\n }\n });\n","import { Command } from 'commander';\n\nimport PACKAGE_INFO from '../../../package.json';\nimport { consola } from '../lib/logger';\n\nexport const version = new Command('version')\n .configureHelp({ showGlobalOptions: true })\n .description('Display detailed version information.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst version`,\n )\n .action(() => {\n consola.log('Version Information:');\n consola.log(`CLI Version: ${PACKAGE_INFO.version}`);\n consola.log(`Node Version: ${process.version}`);\n consola.log(`Platform: ${process.platform} (${process.arch})`);\n });\n","import { Command, type CommandUnknownOpts } from '@commander-js/extra-typings';\n\nimport { getTelemetry } from '../lib/telemetry';\n\nconst allowlistArguments = ['--keep-temp-dir', '--api-host', '--project-uuid'];\n\nfunction parseArguments(args: string[]) {\n return args.reduce<Record<string, string>>((result, arg, index, array) => {\n if (arg.includes('=')) {\n const [key, value] = arg.split('=');\n\n if (allowlistArguments.includes(key)) {\n return {\n ...result,\n [key]: value,\n };\n }\n }\n\n if (allowlistArguments.includes(arg)) {\n const nextValue =\n array[index + 1] && !array[index + 1].startsWith('--') ? array[index + 1] : null;\n\n if (nextValue && !nextValue.includes('--')) {\n return {\n ...result,\n [arg]: nextValue,\n };\n }\n }\n\n return result;\n }, {});\n}\n\nfunction getCommandPath(cmd: CommandUnknownOpts): string {\n const parts: string[] = [];\n let current: CommandUnknownOpts | null = cmd;\n\n while (current.parent) {\n parts.unshift(current.name());\n current = current.parent;\n }\n\n return parts.join(' ');\n}\n\nexport const telemetryPreHook = async (thisCommand: Command, actionCommand: CommandUnknownOpts) => {\n const telemetry = getTelemetry();\n const commandName = getCommandPath(actionCommand);\n\n telemetry.commandName = commandName;\n\n // Return the await to get a proper stack trace.\n // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n return await telemetry.track(commandName, {\n ...parseArguments(thisCommand.args),\n });\n};\n\nexport const telemetryPostHook = async () => {\n const telemetry = getTelemetry();\n\n await telemetry.track('command_completed', { durationMs: telemetry.durationMs() });\n await telemetry.analytics.closeAndFlush();\n};\n","#!/usr/bin/env node\nimport { UserActionableError } from './lib/errors';\nimport { consola } from './lib/logger';\nimport { getTelemetry } from './lib/telemetry';\nimport { program } from './program';\n\nconst handleFatalError = async (error: unknown) => {\n const telemetry = getTelemetry();\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorStack = error instanceof Error ? error.stack : undefined;\n\n try {\n await telemetry.track('error', {\n commandName: telemetry.commandName,\n errorMessage,\n errorStack,\n durationMs: telemetry.durationMs(),\n });\n await telemetry.analytics.closeAndFlush();\n } catch {\n // Don't mask the original error\n }\n\n // A user-actionable error (invalid/expired token, a clear 4xx validation or\n // conflict response, a feature that isn't enabled) already tells the user what\n // to do — print it without the \"share your Correlation ID with support\" noise\n // that only helps for genuine bugs and server-side failures.\n if (error instanceof UserActionableError) {\n consola.error(errorMessage);\n process.exit(1);\n }\n\n consola.error(errorMessage);\n\n if (telemetry.isEnabled()) {\n consola.info(\n `Correlation ID: ${telemetry.correlationId}\\nShare this Correlation ID with BigCommerce support.`,\n );\n } else {\n consola.info(\n 'Enable telemetry (`catalyst telemetry enable`) for improved troubleshooting with BigCommerce support.',\n );\n }\n\n process.exit(1);\n};\n\nprocess.on('uncaughtException', (error) => {\n void handleFatalError(error);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n void handleFatalError(reason);\n});\n\nvoid (async () => {\n try {\n await program.parseAsync(process.argv);\n } catch (error) {\n await handleFatalError(error);\n }\n})();\n"],"mappings":"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","names":["Command","colorize","Option","z","z","z","z","resolve","z","z","z","Conf","config","StoreProfileSchema","z","fetchStoreProfile","config","projects","login","Option","Command","Option","execa","join","colorize","colorize","confirm","input","colorize","existsSync","join","z","z","existsSync","join","confirm","input","colorize","join","dirname","join","yoctoSpinner","run","existsSync","readFileSync","join","z","projectJsonSchema","env","join","execa","Command","Option","config","confirm","select","Command","InvalidArgumentError","Option","colorize","input","select","z","query","authHeaders","z","channels","projects","projects","channels","select","input","input","select","colorize","z","z","input","select","colorize","input","config","config","existsSync","readFileSync","join","resolve","InvalidArgumentError","config","Command","Option","select","colorize","confirm","Command","InvalidArgumentError","Option","input","select","execSync","colorize","join","mkdirSync","resolve","mkdirSync","join","join","readFileSync","writeFileSync","join","z","corePackageJsonSchema","z","version","join","readFileSync","writeFileSync","mkdirSync","readFileSync","writeFileSync","dirname","join","z","corePackageJsonSchema","z","writeJson","mkdirSync","dirname","writeFileSync","join","readFileSync","parseChannelId","InvalidArgumentError","channels","select","join","input","execSync","create","Command","Option","colorize","Command","Option","existsSync","readFileSync","dirname","join","z","PROJECT_LOCKFILES","env","join","existsSync","readFileSync","detectProjectPackageManager","dirname","projectJsonSchema","z","safeReadJson","readProjectJson","telemetry","version","Command","Option","confirm","Command","Option","colorize","access","join","yoctoSpinner","z","z","join","access","yoctoSpinner","colorize","Command","Option","config","telemetry","confirm","confirm","select","Command","Option","colorize","z","colorize","z","z","start","colorize","z","authHeaders","getDomain","query","resolve","config","projects","select","colorize","row","getDomain","Command","Option","confirm","Command","add","Command","config","remove","list","Command","InvalidArgumentError","Option","colorize","z","LEVEL_COLORS","z","colorize","resolve","Command","Option","config","InvalidArgumentError","start","confirm","input","select","Command","colorize","confirm","list","Command","config","colorize","create","input","link","select","Command","execa","existsSync","join","Command","execa","join","existsSync","Command","Option","colorize","Command","Option","colorize","Command","Option","confirm","execa","access","copyFile","cp","readdir","readFile","rm","writeFile","dirname","join","relative","minVersion","satisfies","semverLt","validRange","validSemver","yoctoSpinner","z","z","DEP_FIELDS","join","access","readdir","readFile","dirname","copyFile","version","writeFile","validRange","validSemver","satisfies","minVersion","semverLt","execa","rm","env","resolveProject","relative","cp","confirm","Command","Option","yoctoSpinner","Command","Command","telemetry","Command","colorize","create","telemetry"]}
1
+ {"version":3,"sources":["../src/cli/lib/errors.ts","../src/cli/lib/logger.ts","../src/cli/lib/telemetry.ts","../package.json","../src/cli/lib/user-config.ts","../src/cli/program.ts","../src/cli/commands/auth.ts","../src/cli/lib/auth-errors.ts","../src/cli/lib/login.ts","../src/cli/lib/auth.ts","../src/cli/lib/http-errors.ts","../src/cli/lib/clipboard.ts","../src/cli/lib/project.ts","../src/cli/lib/project-config.ts","../src/cli/lib/shared-options.ts","../src/cli/commands/build.ts","../src/cli/lib/build-env.ts","../src/cli/lib/commerce-hosting.ts","../src/cli/lib/sort-package-json.ts","../src/cli/lib/detect-package-manager.ts","../src/cli/lib/get-module-cli-path.ts","../src/cli/lib/install-dependencies.ts","../src/cli/lib/project-state.ts","../src/cli/lib/required-build-env.ts","../src/cli/lib/wrangler-config.ts","../src/cli/commands/channels.ts","../src/cli/lib/can-prompt.ts","../src/cli/lib/channel-checkout-url-flow.ts","../src/cli/lib/channel-site-flow.ts","../src/cli/lib/channels.ts","../src/cli/lib/checkout-url.ts","../src/cli/lib/create-channel-flow.ts","../src/cli/lib/localization.ts","../src/cli/lib/env-config.ts","../src/cli/lib/resolve-credentials.ts","../src/cli/lib/write-env.ts","../src/cli/commands/create.ts","../src/cli/lib/extract-catalyst.ts","../src/cli/lib/init-git-repo.ts","../src/cli/lib/rewrite-core-package.ts","../src/cli/lib/setup-core-project.ts","../src/cli/commands/debug.ts","../src/cli/lib/collect-diagnostics.ts","../src/cli/commands/deploy.ts","../src/cli/lib/deploy-channel-urls.ts","../src/cli/lib/deployment-errors.ts","../src/cli/commands/domains.ts","../src/cli/lib/domains.ts","../src/cli/lib/observability.ts","../src/cli/commands/env.ts","../src/cli/commands/logs.ts","../src/cli/commands/projects.ts","../src/cli/commands/start.ts","../src/cli/commands/telemetry.ts","../src/cli/commands/upgrade.ts","../src/cli/commands/version.ts","../src/cli/hooks/telemetry.ts","../src/cli/index.ts"],"sourcesContent":["// Base class for errors that are the user's to fix and whose message already\n// says everything they need (bad input, a naming/ownership conflict, invalid\n// credentials, a feature that isn't enabled). The top-level handler in\n// `index.ts` prints these plainly and exits non-zero WITHOUT the \"share your\n// Correlation ID with BigCommerce support\" bug-report framing that unexpected\n// and server-side errors get — a clear 4xx response is not a bug to report.\nexport class UserActionableError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'UserActionableError';\n }\n}\n","import { createConsola } from 'consola';\n\nexport const consola = createConsola({\n level: process.env.CONSOLA_LEVEL ? parseInt(process.env.CONSOLA_LEVEL, 10) : 3,\n // Drop the per-line timestamp. It adds noise for a short-lived CLI and, on\n // long lines, consola can't right-align it so it falls back to an inline\n // `[time]` prefix that breaks copy-pasteable command suggestions.\n formatOptions: { date: false },\n});\n","import { Analytics } from '@segment/analytics-node';\nimport Conf from 'conf';\nimport { randomBytes, randomUUID } from 'node:crypto';\n\nimport PACKAGE_INFO from '../../../package.json';\n\nimport { getUserConfig, UserConfigSchema } from './user-config';\n\nconst TELEMETRY_KEY_ENABLED = 'telemetry.enabled';\nconst TELEMETRY_KEY_ID = `telemetry.anonymousId`;\n\n// CLI telemetry is best-effort: command completion must never be delayed by a\n// slow or unreachable analytics endpoint. `closeAndFlush()` uses the flush\n// interval to derive its timeout, so keep both bounds intentionally short.\nconst TELEMETRY_FLUSH_INTERVAL_MS = 200;\nconst TELEMETRY_HTTP_REQUEST_TIMEOUT_MS = 200;\n\nexport class Telemetry {\n readonly correlationId: string;\n readonly analytics: Analytics;\n readonly startTime: number;\n commandName = 'unknown';\n\n private userConfig: Conf<UserConfigSchema>;\n private CATALYST_TELEMETRY_DISABLED: string | undefined;\n\n private readonly projectName = 'catalyst-cli';\n private readonly projectVersion = PACKAGE_INFO.version;\n\n constructor() {\n this.CATALYST_TELEMETRY_DISABLED = process.env.CATALYST_TELEMETRY_DISABLED;\n\n this.userConfig = getUserConfig();\n\n this.correlationId = randomUUID();\n this.startTime = Date.now();\n this.analytics = new Analytics({\n writeKey: process.env.CLI_SEGMENT_WRITE_KEY ?? 'not-a-valid-segment-write-key',\n flushInterval: TELEMETRY_FLUSH_INTERVAL_MS,\n httpRequestTimeout: TELEMETRY_HTTP_REQUEST_TIMEOUT_MS,\n maxRetries: 0,\n });\n }\n\n durationMs(): number {\n return Date.now() - this.startTime;\n }\n\n async track(eventName: string, payload: Record<string, unknown>) {\n if (!this.isEnabled()) {\n return Promise.resolve(undefined);\n }\n\n this.analytics.track({\n event: eventName,\n anonymousId: this.getAnonymousId(),\n properties: {\n ...payload,\n correlationId: this.correlationId,\n nodeVersion: process.version,\n platform: process.platform,\n arch: process.arch,\n cliVersion: PACKAGE_INFO.version,\n },\n context: {\n app: {\n name: this.projectName,\n version: this.projectVersion,\n },\n },\n });\n }\n\n async identify(storeHash?: string) {\n if (!this.isEnabled()) {\n return Promise.resolve(undefined);\n }\n\n if (!storeHash) {\n return Promise.resolve(undefined);\n }\n\n this.analytics.identify({\n userId: storeHash,\n anonymousId: this.getAnonymousId(),\n context: {\n app: {\n name: this.projectName,\n version: this.projectVersion,\n },\n },\n });\n }\n\n setEnabled = (_enabled: boolean) => {\n const enabled = Boolean(_enabled);\n\n this.userConfig.set('telemetry.enabled', enabled);\n };\n\n isEnabled() {\n return (\n !this.CATALYST_TELEMETRY_DISABLED &&\n this.userConfig.get<typeof TELEMETRY_KEY_ENABLED, boolean>(TELEMETRY_KEY_ENABLED, true)\n );\n }\n\n private getAnonymousId(): string {\n const val = this.userConfig.get<typeof TELEMETRY_KEY_ID, string>(TELEMETRY_KEY_ID);\n\n if (val) {\n return val;\n }\n\n const generated = randomBytes(32).toString('hex');\n\n this.userConfig.set(TELEMETRY_KEY_ID, generated);\n\n return generated;\n }\n}\n\nlet telemetryInstance: Telemetry | undefined;\n\n// Singleton so the pre-hook, post-hook, error handler, and command bodies all\n// share one correlationId. resetTelemetry() is for test isolation.\nexport function getTelemetry(): Telemetry {\n telemetryInstance ??= new Telemetry();\n\n return telemetryInstance;\n}\n\nexport function resetTelemetry(): void {\n telemetryInstance = undefined;\n}\n","{\n \"name\": \"@bigcommerce/catalyst\",\n \"version\": \"1.4.2\",\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/bigcommerce/catalyst\",\n \"directory\": \"packages/catalyst\"\n },\n \"bin\": {\n \"catalyst\": \"dist/cli.js\"\n },\n \"files\": [\n \"dist\",\n \"templates\"\n ],\n \"scripts\": {\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint . --max-warnings 0\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:coverage\": \"vitest run --coverage\",\n \"build\": \"tsup\"\n },\n \"engines\": {\n \"node\": \"^22.0.0 || ^24.0.0\"\n },\n \"dependencies\": {\n \"@commander-js/extra-typings\": \"^14.0.0\",\n \"@inquirer/prompts\": \"^7.5.3\",\n \"@segment/analytics-node\": \"^2.2.1\",\n \"adm-zip\": \"^0.5.16\",\n \"commander\": \"^14.0.0\",\n \"conf\": \"^13.1.0\",\n \"consola\": \"^3.4.2\",\n \"cross-spawn\": \"^7.0.6\",\n \"dotenv\": \"^16.5.0\",\n \"execa\": \"^9.6.0\",\n \"fs-extra\": \"^11.3.0\",\n \"lodash.kebabcase\": \"^4.1.1\",\n \"nypm\": \"^0.5.4\",\n \"open\": \"^10.1.0\",\n \"semver\": \"^7.7.4\",\n \"std-env\": \"^3.9.0\",\n \"tar\": \"^7.5.7\",\n \"tldts\": \"^7.4.12\",\n \"yocto-spinner\": \"^1.0.0\",\n \"zod\": \"^4.0.5\"\n },\n \"devDependencies\": {\n \"@bigcommerce/eslint-config\": \"^2.11.0\",\n \"@bigcommerce/eslint-config-catalyst\": \"workspace:^\",\n \"@types/adm-zip\": \"^0.5.7\",\n \"@types/cross-spawn\": \"^6.0.6\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/lodash.kebabcase\": \"^4.1.9\",\n \"@types/node\": \"^22.15.30\",\n \"@types/semver\": \"^7.7.0\",\n \"@vitest/coverage-v8\": \"^3.2.4\",\n \"@vitest/ui\": \"^3.2.4\",\n \"eslint\": \"^8.57.1\",\n \"msw\": \"^2.9.0\",\n \"prettier\": \"^3.6.2\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.8.3\",\n \"vitest\": \"^3.2.4\"\n },\n \"peerDependencies\": {\n \"@opennextjs/cloudflare\": \"^1.17.3\"\n },\n \"peerDependenciesMeta\": {\n \"@opennextjs/cloudflare\": {\n \"optional\": true\n }\n }\n}\n","import Conf from 'conf';\n\nexport interface UserConfigSchema {\n telemetry: {\n enabled: boolean;\n anonymousId: string;\n };\n}\n\nlet userConfigInstance: Conf<UserConfigSchema> | undefined;\n\n// User-scoped config (per-machine, not per-project). Lives in the OS config dir\n// — keeping telemetry out of the user's working directory so commands like\n// `catalyst create` don't drop a stray `.bigcommerce/` next to where they're run.\nexport function getUserConfig(): Conf<UserConfigSchema> {\n userConfigInstance ??= new Conf<UserConfigSchema>({\n projectName: 'catalyst-cli',\n projectSuffix: '',\n configName: 'config',\n schema: {\n telemetry: {\n type: 'object',\n properties: {\n enabled: { type: 'boolean' },\n anonymousId: { type: 'string' },\n },\n },\n },\n });\n\n return userConfigInstance;\n}\n\nexport function resetUserConfig(): void {\n userConfigInstance = undefined;\n}\n","import { Command } from 'commander';\nimport { colorize } from 'consola/utils';\n\nimport PACKAGE_INFO from '../../package.json';\n\nimport { auth } from './commands/auth';\nimport { build } from './commands/build';\nimport { channels } from './commands/channels';\nimport { create } from './commands/create';\nimport { debug } from './commands/debug';\nimport { deploy } from './commands/deploy';\nimport { domains } from './commands/domains';\nimport { env } from './commands/env';\nimport { logs } from './commands/logs';\nimport { projects } from './commands/projects';\nimport { start } from './commands/start';\nimport { telemetry } from './commands/telemetry';\nimport { upgrade } from './commands/upgrade';\nimport { version } from './commands/version';\nimport { telemetryPostHook, telemetryPreHook } from './hooks/telemetry';\nimport { consola } from './lib/logger';\n\n// Env files are only loaded by `build` and `deploy` (which auto-load\n// .env.local and .env, or an explicit `--env-path`). No other command reads env\n// files, so running the CLI can't be surprised by a stray `.env.local` on disk.\n\n// CATALYST_STORE_HASH falls back to BIGCOMMERCE_STORE_HASH so freshly-scaffolded\n// projects work without duplicating the same value under two names. Aliasing\n// here means every command's `.env('CATALYST_STORE_HASH')` binding picks it up\n// without per-command changes.\nif (!process.env.CATALYST_STORE_HASH && process.env.BIGCOMMERCE_STORE_HASH) {\n process.env.CATALYST_STORE_HASH = process.env.BIGCOMMERCE_STORE_HASH;\n}\n\nexport const program = new Command();\n\nconsola.log(colorize('cyanBright', `◢ ${PACKAGE_INFO.name} v${PACKAGE_INFO.version}\\n`));\n\nprogram\n .name(PACKAGE_INFO.name)\n .version(PACKAGE_INFO.version)\n .summary('CLI tool for Catalyst development')\n .description(\n 'CLI tool for Catalyst development.\\n\\nConfiguration priority: flags > process.env > .bigcommerce/project.json. `build` and `deploy` additionally load env files (--env-path, or an auto-loaded .env.local/.env) for the build.\\n\\nCATALYST_STORE_HASH falls back to BIGCOMMERCE_STORE_HASH if unset.\\n\\nRun `catalyst <command> --help` for details on a specific command.',\n )\n .configureHelp({ showGlobalOptions: true })\n .addCommand(version)\n .addCommand(create)\n .addCommand(start)\n .addCommand(build)\n .addCommand(deploy)\n .addCommand(domains)\n .addCommand(logs)\n .addCommand(projects)\n .addCommand(env)\n .addCommand(channels)\n .addCommand(auth)\n .addCommand(upgrade)\n .addCommand(telemetry)\n .addCommand(debug)\n .hook('preAction', telemetryPreHook)\n .hook('postAction', telemetryPostHook);\n","import { Command, Option } from 'commander';\nimport { z } from 'zod';\n\nimport { assertAuthorized, UnauthorizedError } from '../lib/auth-errors';\nimport { consola } from '../lib/logger';\nimport { LoginAbortedError, login as runInteractiveLogin } from '../lib/login';\nimport { fetchProjects } from '../lib/project';\nimport { getProjectConfig } from '../lib/project-config';\nimport {\n accessTokenOption,\n apiHostOption,\n loginUrlOption,\n resolveApiHost,\n storeHashOption,\n} from '../lib/shared-options';\n\nconst StoreProfileSchema = z.object({\n data: z.object({\n store_name: z.string(),\n }),\n});\n\nasync function fetchStoreProfile(storeHash: string, accessToken: string, apiHost: string) {\n const response = await fetch(`https://${apiHost}/stores/${storeHash}/v3/settings/store/profile`, {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n Accept: 'application/json',\n },\n });\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw new Error(`${response.status} ${response.statusText}`);\n }\n\n const res: unknown = await response.json();\n const result = StoreProfileSchema.safeParse(res);\n\n if (!result.success) {\n throw new Error('Unexpected response from store profile API');\n }\n\n return result.data.data;\n}\n\n// `login` verifies rather than just checking for stored credentials: every other\n// command answers a rejected token with \"Run `catalyst auth login`\", so refusing\n// because credentials are merely *present* loops the user back with no way out\n// but `auth logout`. `unverifiable` keeps that distinct from a real rejection —\n// we can't prove the token is bad, so we don't discard it.\ntype CredentialStatus =\n | { valid: true; storeName: string }\n | { valid: false; reason: 'unauthorized' }\n | { valid: false; reason: 'unverifiable'; message: string };\n\nasync function checkCredentials(\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<CredentialStatus> {\n try {\n const { store_name: storeName } = await fetchStoreProfile(storeHash, accessToken, apiHost);\n\n return { valid: true, storeName };\n } catch (error) {\n if (error instanceof UnauthorizedError) return { valid: false, reason: 'unauthorized' };\n\n return {\n valid: false,\n reason: 'unverifiable',\n message: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\nconst whoami = new Command('whoami')\n .configureHelp({ showGlobalOptions: true })\n .description('Verify stored credentials and display store/project info.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst auth whoami\n\n Logged in to My Store (abc123), connected to project my-project (43eba682-0c48-11f1-9bd5-827a48b0ce1e)`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .action(async (options) => {\n try {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n const storeHash = options.storeHash ?? config.get('storeHash');\n const accessToken = options.accessToken ?? config.get('accessToken');\n\n if (!storeHash || !accessToken) {\n consola.info('Not logged in: no credentials found.');\n consola.info(\n 'Run `catalyst auth login`, or provide --store-hash and --access-token flags (or set CATALYST_STORE_HASH and CATALYST_ACCESS_TOKEN environment variables).',\n );\n process.exit(1);\n\n return;\n }\n\n const store = await fetchStoreProfile(storeHash, accessToken, apiHost);\n\n const projectUuid = config.get('projectUuid');\n\n if (projectUuid) {\n const projects = await fetchProjects(storeHash, accessToken, apiHost);\n const linkedProject = projects.find((p) => p.uuid === projectUuid);\n\n if (linkedProject) {\n consola.info(\n `Logged in to ${store.store_name} (${storeHash}), connected to project ${linkedProject.name} (${projectUuid})`,\n );\n } else {\n consola.info(\n `Logged in to ${store.store_name} (${storeHash}), project ${projectUuid} not found`,\n );\n }\n } else {\n consola.info(`Logged in to ${store.store_name} (${storeHash})`);\n }\n\n process.exit(0);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n if (error instanceof UnauthorizedError) {\n consola.error(\n 'Not logged in: your access token is invalid or has expired. Run `catalyst auth login`.',\n );\n } else if (message.includes('401') || message.includes('403')) {\n consola.error(`Not logged in: invalid credentials (${message})`);\n } else {\n consola.error(`Failed to verify credentials: ${message}`);\n }\n\n process.exit(1);\n }\n });\n\nconst login = new Command('login')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Authenticate via browser using the OAuth device code flow. Falls back to an interactive store hash + access token prompt if the browser flow is unavailable. Passing --store-hash and --access-token verifies and stores those credentials instead. If already logged in with credentials that still work, displays them and suggests `catalyst auth logout`; if the stored token has expired or been revoked, re-authenticates in place.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Login interactively (browser, with manual fallback)\n $ catalyst auth login\n\n # Login with existing credentials (skips interactive flow)\n $ catalyst auth login --store-hash <STORE_HASH> --access-token <ACCESS_TOKEN>\n\n # Re-authenticate without checking the stored credentials first\n $ catalyst auth login --force`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(loginUrlOption())\n .addOption(\n new Option(\n '--force',\n 'Skip the check on any credentials already stored and re-authenticate regardless.',\n ),\n )\n .action(async (options, command) => {\n try {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n const storeHash = options.storeHash ?? config.get('storeHash');\n const accessToken = options.accessToken ?? config.get('accessToken');\n // Both flags typed on the command line. These options also read\n // CATALYST_STORE_HASH/CATALYST_ACCESS_TOKEN, but an exported env var is\n // ambient config and must not turn a plain `auth login` into a silent\n // credential write — only an explicit pair of flags does.\n const suppliedOnCli =\n command.getOptionValueSource('storeHash') === 'cli' &&\n command.getOptionValueSource('accessToken') === 'cli';\n\n // Non-interactive login: the user named the credentials to use, so verify\n // and persist them rather than reporting on them.\n if (suppliedOnCli && storeHash && accessToken) {\n if (!options.force) {\n const status = await checkCredentials(storeHash, accessToken, apiHost);\n\n // Opening a browser instead would hide what's wrong with what they passed.\n if (!status.valid && status.reason === 'unauthorized') {\n consola.error(`The credentials provided for store ${storeHash} were rejected.`);\n consola.info(\n 'Check the store hash and access token, or run `catalyst auth login` without them to authenticate in the browser.',\n );\n process.exit(1);\n\n return;\n }\n\n if (!status.valid) {\n consola.warn(`Couldn't verify the credentials provided: ${status.message}`);\n }\n }\n\n config.set('storeHash', storeHash);\n config.set('accessToken', accessToken);\n\n consola.success(`Logged in to store ${storeHash}.`);\n process.exit(0);\n\n return;\n }\n\n if (storeHash && accessToken && !options.force) {\n const status = await checkCredentials(storeHash, accessToken, apiHost);\n\n if (status.valid) {\n consola.info(`Already logged in to ${status.storeName} (${storeHash}).`);\n consola.info(\n 'Run `catalyst auth logout` first to re-authenticate, or `catalyst auth login --force` to skip this check.',\n );\n process.exit(0);\n\n return;\n }\n\n // The device-code flow needs the same network that just failed, so\n // trading working credentials for another error is a downgrade.\n if (status.reason === 'unverifiable') {\n consola.warn(\n `Found credentials for store ${storeHash} but couldn't verify them: ${status.message}`,\n );\n consola.info(\n 'Keeping them. Re-run once the API is reachable, or `catalyst auth login --force` to re-authenticate regardless.',\n );\n process.exit(0);\n\n return;\n }\n\n consola.warn(\n `Stored credentials for store ${storeHash} are no longer valid — re-authenticating.`,\n );\n }\n\n const credentials = await runInteractiveLogin(options.loginUrl, apiHost);\n\n config.set('storeHash', credentials.storeHash);\n config.set('accessToken', credentials.accessToken);\n\n consola.success(`Logged in to store ${credentials.storeHash}.`);\n process.exit(0);\n } catch (error) {\n if (error instanceof LoginAbortedError) {\n consola.info(\n 'Login aborted. Re-run `catalyst auth login` when you have your credentials ready.',\n );\n process.exit(0);\n\n return;\n }\n\n const message = error instanceof Error ? error.message : String(error);\n\n consola.error(`Login failed: ${message}`);\n process.exit(1);\n }\n });\n\nconst logout = new Command('logout')\n .configureHelp({ showGlobalOptions: true })\n .description('Remove stored credentials for the current project.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst auth logout`,\n )\n .action(() => {\n try {\n const config = getProjectConfig();\n\n const storeHash = config.get('storeHash');\n const accessToken = config.get('accessToken');\n\n if (!storeHash && !accessToken) {\n consola.info('Not logged in: no credentials found.');\n process.exit(0);\n\n return;\n }\n\n config.delete('storeHash');\n config.delete('accessToken');\n\n consola.success(`Logged out from store ${storeHash ?? 'unknown'}.`);\n process.exit(0);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n consola.error(`Logout failed: ${message}`);\n process.exit(1);\n }\n });\n\nexport const auth = new Command('auth')\n .configureHelp({ showGlobalOptions: true })\n .description('Manage authentication for the BigCommerce CLI.')\n .addCommand(whoami)\n .addCommand(login)\n .addCommand(logout);\n","import { UserActionableError } from './errors';\n\n// Thrown when an authenticated API call comes back 401 Unauthorized — i.e. the\n// access token was sent but rejected. This covers an expired/revoked token as\n// well as a token that was never valid (e.g. a typo'd `--access-token` flag or\n// a stale `CATALYST_ACCESS_TOKEN` env var). It does NOT cover the \"no\n// credentials at all\" case — that's caught earlier by `resolveCredentials`\n// (and `auth whoami`'s own guard) before any request is made.\n//\n// The CLI can't refresh the token silently (the device-code flow returns no\n// refresh token), so the only recovery is to re-authenticate. Callers should\n// let this propagate to the top-level handler in `index.ts`, which prints the\n// message without the generic \"share your Correlation ID with support\"\n// bug-report framing.\nexport class UnauthorizedError extends UserActionableError {\n constructor() {\n super(\n 'Your access token is invalid or has expired.\\n' +\n 'Run `catalyst auth login` to re-authenticate.',\n );\n this.name = 'UnauthorizedError';\n }\n}\n\n// Call immediately after an authenticated `fetch`, before any other status\n// checks. Only 401 means \"invalid/expired token\" — 403 is overloaded elsewhere\n// to mean \"API not enabled\" (scope/feature flag), so it is intentionally not\n// treated as an auth failure here.\nexport function assertAuthorized(response: Response): void {\n if (response.status === 401) {\n throw new UnauthorizedError();\n }\n}\n","import { confirm, input, password } from '@inquirer/prompts';\nimport { colorize } from 'consola/utils';\nimport open from 'open';\nimport yoctoSpinner from 'yocto-spinner';\nimport { z } from 'zod';\n\nimport { DEVICE_OAUTH_SCOPES, requestDeviceCode, waitForDeviceToken } from './auth';\nimport { copyToClipboard } from './clipboard';\nimport { UserActionableError } from './errors';\nimport { consola } from './logger';\n\nexport interface LoginResult {\n storeHash: string;\n accessToken: string;\n}\n\n// Thrown when the user declines the manual-login fallback after the browser\n// (device-code) flow has failed. Callers should treat this as a clean exit,\n// not an error — the user explicitly chose to abort.\nexport class LoginAbortedError extends Error {\n constructor() {\n super('Login aborted by user.');\n this.name = 'LoginAbortedError';\n }\n}\n\nconst StoreProfileSchema = z.object({\n data: z.object({\n store_name: z.string(),\n }),\n});\n\nasync function fetchStoreProfile(storeHash: string, accessToken: string, apiHost: string) {\n const response = await fetch(`https://${apiHost}/stores/${storeHash}/v3/settings/store/profile`, {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n Accept: 'application/json',\n },\n });\n\n if (!response.ok) {\n throw new Error(`${response.status} ${response.statusText}`);\n }\n\n const res: unknown = await response.json();\n const result = StoreProfileSchema.safeParse(res);\n\n if (!result.success) {\n throw new Error('Unexpected response from store profile API');\n }\n\n return result.data.data;\n}\n\nasync function deviceCodeLogin(loginUrl: string): Promise<LoginResult> {\n const deviceCode = await requestDeviceCode(loginUrl);\n\n consola.info(\n `${colorize('yellow', 'Your one-time code:')} ${colorize('bold', deviceCode.user_code)}`,\n );\n\n // Wait for the user to acknowledge before hijacking their browser. This keeps\n // the UX consistent across `create`, `auth login`, and the channel commands.\n // In non-interactive contexts (CI, piped stdin) there's nobody to press\n // Enter, so skip straight to opening the verification URL.\n if (process.stdin.isTTY) {\n await input({ message: 'Press Enter to open your browser and sign in' });\n\n // Best-effort: drop the code on the clipboard so the user can paste it\n // straight into the verification page. We already printed it above as a\n // fallback, and a clipboard failure must never interrupt the flow.\n const copied = await copyToClipboard(deviceCode.user_code);\n\n if (copied) {\n consola.info('Copied the code to your clipboard — paste it into the sign-in page.');\n }\n }\n\n try {\n await open(deviceCode.verification_uri);\n consola.info(`Opened ${deviceCode.verification_uri} in your browser.`);\n } catch {\n consola.info(`Open ${deviceCode.verification_uri} in your browser and enter the code above.`);\n }\n\n const spinner = yoctoSpinner().start('Waiting for authentication...');\n\n const credentials = await waitForDeviceToken(\n loginUrl,\n deviceCode.device_code,\n deviceCode.interval,\n );\n\n spinner.success('Authentication complete.');\n\n return {\n storeHash: credentials.store_hash,\n accessToken: credentials.access_token,\n };\n}\n\nasync function manualLogin(apiHost: string): Promise<LoginResult> {\n consola.info(\n 'Create a store-level API account from your BigCommerce Control Panel:\\n' +\n ' Settings → API → Store-level API accounts → Create API account\\n' +\n `Grant these OAuth scopes: ${DEVICE_OAUTH_SCOPES}`,\n );\n\n const storeHashInput = await input({ message: 'Store hash:' });\n const storeHash = storeHashInput.trim();\n\n if (!storeHash) {\n throw new UserActionableError('Store hash is required.');\n }\n\n const accessTokenInput = await password({ message: 'Access token:', mask: true });\n const accessToken = accessTokenInput.trim();\n\n if (!accessToken) {\n throw new UserActionableError('Access token is required.');\n }\n\n const spinner = yoctoSpinner().start('Validating credentials...');\n\n try {\n const profile = await fetchStoreProfile(storeHash, accessToken, apiHost);\n\n spinner.success(`Validated credentials for ${profile.store_name} (${storeHash}).`);\n } catch (error) {\n spinner.error('Failed to validate credentials.');\n\n const message = error instanceof Error ? error.message : String(error);\n\n throw new UserActionableError(\n `Could not validate credentials (${message}). Double-check your store hash and access token, then try again.`,\n );\n }\n\n return { storeHash, accessToken };\n}\n\n// Interactive login orchestrator. Used by `catalyst create`, `catalyst auth\n// login`, and `catalyst projects create` to gather credentials when none are\n// supplied via flags/env/config.\n//\n// Happy path: opens the browser device-code flow. When that fails (e.g. the\n// device-code endpoint returns 404 because the OAuth client isn't yet\n// provisioned for the user's environment), we ask the user if they'd like to\n// fall back to pasting a store-level API account's credentials instead, then\n// validate them via the store profile API before returning.\nexport async function login(loginUrl: string, apiHost: string): Promise<LoginResult> {\n try {\n return await deviceCodeLogin(loginUrl);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n\n consola.warn(`Browser login didn't work (${message}).`);\n\n const shouldFallback = await confirm({\n message: 'Try logging in manually with a store hash and access token instead?',\n default: true,\n });\n\n if (!shouldFallback) {\n throw new LoginAbortedError();\n }\n\n return manualLogin(apiHost);\n }\n}\n","import { z } from 'zod';\n\nimport { httpError } from './http-errors';\n\nexport const DEVICE_OAUTH_CLIENT_ID = 'b8063bu6hhml4e0lqh22yut63atsbyv';\nexport const DEVICE_OAUTH_SCOPES = [\n 'store_v2_information',\n 'store_v2_products',\n 'store_v2_content',\n 'store_sites',\n 'store_storefront_api',\n 'store_infrastructure_deployments_manage',\n 'store_infrastructure_logs_read_only',\n 'store_infrastructure_projects_manage',\n 'store_channel_settings',\n].join(' ');\n\nexport const DEFAULT_LOGIN_URL = 'https://login.bigcommerce.com';\n\nexport const DeviceCodeResponseSchema = z.object({\n device_code: z.string(),\n user_code: z.string(),\n verification_uri: z.string(),\n expires_in: z.number(),\n interval: z.number(),\n});\n\nexport const DeviceCodeSuccessSchema = z.object({\n access_token: z.string(),\n store_hash: z.string(),\n context: z.string(),\n api_uri: z.string(),\n});\n\nexport async function requestDeviceCode(loginUrl: string) {\n const response = await fetch(`${loginUrl}/device/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n client_id: DEVICE_OAUTH_CLIENT_ID,\n scopes: DEVICE_OAUTH_SCOPES,\n }),\n });\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to request device code');\n }\n\n const res: unknown = await response.json();\n\n return DeviceCodeResponseSchema.parse(res);\n}\n\nexport async function pollDeviceToken(loginUrl: string, deviceCode: string) {\n const response = await fetch(`${loginUrl}/device/token`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n device_code: deviceCode,\n client_id: DEVICE_OAUTH_CLIENT_ID,\n }),\n });\n\n if (response.status !== 200) {\n return null;\n }\n\n const res: unknown = await response.json();\n\n return DeviceCodeSuccessSchema.parse(res);\n}\n\nexport async function waitForDeviceToken(\n loginUrl: string,\n deviceCode: string,\n interval: number,\n): Promise<z.infer<typeof DeviceCodeSuccessSchema>> {\n const credentials = await pollDeviceToken(loginUrl, deviceCode);\n\n if (credentials) {\n return credentials;\n }\n\n await new Promise((resolve) => {\n setTimeout(resolve, interval * 1000);\n });\n\n return waitForDeviceToken(loginUrl, deviceCode, interval);\n}\n","import { z } from 'zod';\n\nimport { UserActionableError } from './errors';\n\n// BigCommerce APIs surface errors as an RFC-7807-ish envelope:\n// `{ title, detail, errors: { <field>: <message> } }`. We prefer the server's\n// own prose over anything we could invent, so callers show the API's reason\n// verbatim when it's available.\nconst apiErrorBodySchema = z.object({\n title: z.string().optional(),\n detail: z.string().optional(),\n errors: z.record(z.string(), z.string()).optional(),\n});\n\n// Curated copy for when the response has no usable body. Keyed by status class,\n// not exact code, so any 4xx/5xx we don't specifically handle still reads well.\nconst FALLBACK_CLIENT_ERROR =\n 'The request was rejected. Check your input — your access token may be missing a required scope, or the resource may not exist.';\nconst FALLBACK_SERVER_ERROR =\n 'Something went wrong on our end. Please try again. If the issue persists, contact support.';\n\n// Pulls a human-readable message out of a parsed API error body, preferring the\n// most specific prose the server gave us: its `detail`, then `title`, enriched\n// with any field-level `errors`. Returns undefined when the body doesn't match\n// the envelope (empty, HTML, plain text, or already-consumed).\nexport function extractApiErrorMessage(body: unknown): string | undefined {\n const parsed = apiErrorBodySchema.safeParse(body);\n\n if (!parsed.success) return undefined;\n\n const { title, detail, errors } = parsed.data;\n const fieldErrors =\n errors && Object.keys(errors).length > 0\n ? Object.entries(errors)\n .map(([field, message]) => `${field}: ${message}`)\n .join('; ')\n : undefined;\n\n const headline = detail ?? title;\n\n if (headline && fieldErrors) return `${headline} (${fieldErrors})`;\n\n return headline ?? fieldErrors;\n}\n\n// Turns a non-OK `Response` into a readable error to throw. Reads the body once\n// (safely — a malformed or empty body never throws) and prefers the API's own\n// message; otherwise it falls back to curated copy for the status class.\n//\n// The 4xx/5xx split decides the *type*, which the top-level handler in\n// `index.ts` keys off: a 4xx is a clear, user-actionable response, so it throws\n// `UserActionableError` and the handler drops the \"share your Correlation ID\n// with support\" bug-report framing; a 5xx is a server-side failure worth\n// escalating, so it stays a plain `Error` and keeps that framing.\n//\n// Returns the error rather than throwing so call sites read\n// `throw await httpError(response, 'Failed to fetch projects')` and TypeScript\n// still sees the throw for control-flow narrowing.\nexport async function httpError(response: Response, action: string): Promise<Error> {\n const body: unknown = await response.json().catch(() => null);\n const isServerError = response.status >= 500;\n const detail =\n extractApiErrorMessage(body) ?? (isServerError ? FALLBACK_SERVER_ERROR : FALLBACK_CLIENT_ERROR);\n const message = `${action}: ${detail}`;\n\n return isServerError ? new Error(message) : new UserActionableError(message);\n}\n","import { execa } from 'execa';\n\ninterface ClipboardCommand {\n command: string;\n args: string[];\n}\n\n// Resolve the platform-native clipboard utility. Returns null when we don't\n// know how to reach the clipboard on this platform, so callers can fall back to\n// simply printing the value.\nfunction clipboardCommand(): ClipboardCommand | null {\n switch (process.platform) {\n case 'darwin':\n return { command: 'pbcopy', args: [] };\n\n case 'win32':\n return { command: 'clip', args: [] };\n\n case 'linux':\n // Wayland sessions expose wl-copy; X11 sessions typically ship xclip.\n return process.env.WAYLAND_DISPLAY\n ? { command: 'wl-copy', args: [] }\n : { command: 'xclip', args: ['-selection', 'clipboard'] };\n\n default:\n return null;\n }\n}\n\n// Best-effort copy of `text` to the system clipboard. Never throws — returns\n// `true` on success and `false` when the clipboard is unreachable (unknown\n// platform, missing utility, spawn failure). Callers must always print the\n// value as a fallback so the flow works even when the copy fails.\nexport async function copyToClipboard(text: string): Promise<boolean> {\n const clipboard = clipboardCommand();\n\n if (!clipboard) {\n return false;\n }\n\n try {\n await execa(clipboard.command, clipboard.args, { input: text });\n\n return true;\n } catch {\n return false;\n }\n}\n","import { z } from 'zod';\n\nimport { assertAuthorized } from './auth-errors';\nimport { UserActionableError } from './errors';\nimport { httpError } from './http-errors';\nimport { getTelemetry } from './telemetry';\n\nexport class InfrastructureProjectValidationError extends UserActionableError {\n constructor(message: string) {\n super(message);\n this.name = 'InfrastructureProjectValidationError';\n }\n}\n\nconst fetchProjectsSchema = z.object({\n data: z.array(\n z.object({\n uuid: z.string(),\n name: z.string(),\n deployment_hostnames: z.array(z.string()),\n }),\n ),\n});\n\nexport interface ProjectListItem {\n uuid: string;\n name: string;\n deployment_hostnames: string[];\n}\n\nfunction projectsUrl(storeHash: string, apiHost: string) {\n return `https://${apiHost}/stores/${storeHash}/v3/infrastructure/projects`;\n}\n\nfunction authHeaders(accessToken: string) {\n return {\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n };\n}\n\nexport async function hasProjectsAccess(\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<boolean> {\n const response = await fetch(projectsUrl(storeHash, apiHost), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n assertAuthorized(response);\n\n if (response.status === 200) return true;\n if (response.status === 403) return false;\n\n throw await httpError(response, 'Failed to check project access');\n}\n\nexport async function fetchProjects(\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<ProjectListItem[]> {\n const response = await fetch(projectsUrl(storeHash, apiHost), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n assertAuthorized(response);\n\n if (response.status === 403) {\n throw new UserActionableError(\n 'Infrastructure Projects API not enabled. If you are part of the beta, contact support@bigcommerce.com to enable it.',\n );\n }\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch projects');\n }\n\n const res: unknown = await response.json();\n\n const { data } = fetchProjectsSchema.parse(res);\n\n return data;\n}\n\nconst createProjectSchema = z.object({\n data: z.object({\n uuid: z.string(),\n name: z.string(),\n date_created: z.coerce.date(),\n date_modified: z.coerce.date(),\n }),\n});\n\nexport interface CreateProjectResult {\n uuid: string;\n name: string;\n date_created: Date;\n date_modified: Date;\n}\n\nconst validationErrorBodySchema = z.object({\n title: z.string().optional(),\n detail: z.string().optional(),\n errors: z.record(z.string(), z.string()).optional(),\n});\n\nfunction extractValidationMessage(body: unknown): string | null {\n const parsed = validationErrorBodySchema.safeParse(body);\n\n if (!parsed.success) return null;\n\n const { title, detail, errors } = parsed.data;\n\n if (errors && Object.keys(errors).length > 0) {\n return Object.values(errors).join('; ');\n }\n\n return detail ?? title ?? null;\n}\n\nexport async function createProject(\n name: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<CreateProjectResult> {\n const response = await fetch(projectsUrl(storeHash, apiHost), {\n method: 'POST',\n headers: {\n ...authHeaders(accessToken),\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ name }),\n });\n\n assertAuthorized(response);\n\n if (response.status === 400 || response.status === 422) {\n const body: unknown = await response.json().catch(() => null);\n const fallback =\n response.status === 422\n ? \"The project name you entered doesn't meet the requirements. It must be 3–32 characters long and use only letters, numbers, hyphens (-), underscores (_), and periods (.)\"\n : response.statusText;\n const message = extractValidationMessage(body) ?? fallback;\n\n throw new InfrastructureProjectValidationError(message);\n }\n\n // The API returns 403 (or 404 when the flag is off) if the store isn't in the\n // Infrastructure Projects beta; both mean \"not enabled for this store\".\n if (response.status === 403 || response.status === 404) {\n throw new UserActionableError(\n 'Infrastructure Projects API not enabled. If you are part of the beta, contact support@bigcommerce.com to enable it.',\n );\n }\n\n // TODO: TRAC-592 - remove this check once the API returns proper 400/422 with validation messages for duplicate names instead of 502\n if (response.status === 502) {\n throw new Error('Failed to create project, is the name already in use?');\n }\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to create project');\n }\n\n const res: unknown = await response.json();\n\n const { data } = createProjectSchema.parse(res);\n\n return data;\n}\n\nexport async function deleteProject(\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<void> {\n const response = await fetch(`${projectsUrl(storeHash, apiHost)}/${projectUuid}`, {\n method: 'DELETE',\n headers: authHeaders(accessToken),\n });\n\n assertAuthorized(response);\n\n if (response.status === 403) {\n throw new UserActionableError(\n 'Infrastructure Projects API not enabled. If you are part of the beta, contact support@bigcommerce.com to enable it.',\n );\n }\n\n if (response.status === 404) {\n throw new UserActionableError(`Project ${projectUuid} not found.`);\n }\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to delete project');\n }\n}\n","import Conf from 'conf';\nimport { join } from 'path';\n\nexport interface ProjectConfigSchema {\n projectUuid: string;\n // Reserved for future use\n framework: 'catalyst';\n storeHash?: string;\n accessToken?: string;\n apiHost?: string;\n // Persistent deployment environment variables (KEY -> VALUE). Every entry is\n // sent to the deployment as a `secret` by `catalyst deploy`. Managed via the\n // `catalyst env` commands. Lives here (gitignored .bigcommerce/project.json)\n // so users don't have to re-pass `--secret` on every deploy.\n env?: Record<string, string>;\n // Channels that declined the post-deploy site URL offer.\n declinedSiteUrlChannels?: number[];\n // Channels that declined the post-deploy checkout URL offer.\n declinedCheckoutUrlChannels?: number[];\n}\n\n// `cwd` defaults to the process working directory — the project the user is\n// currently in. `catalyst create` passes the freshly-scaffolded project dir\n// explicitly, since that project isn't the cwd at the time it's seeded.\nexport function getProjectConfig(cwd: string = process.cwd()) {\n return new Conf<ProjectConfigSchema>({\n cwd: join(cwd, '.bigcommerce'),\n projectSuffix: '',\n configName: 'project',\n schema: {\n projectUuid: { type: 'string', format: 'uuid' },\n framework: {\n type: 'string',\n enum: ['catalyst'],\n default: 'catalyst',\n },\n storeHash: { type: 'string' },\n accessToken: { type: 'string' },\n apiHost: { type: 'string' },\n env: {\n type: 'object',\n additionalProperties: { type: 'string' },\n default: {},\n },\n declinedSiteUrlChannels: {\n type: 'array',\n items: { type: 'number' },\n },\n declinedCheckoutUrlChannels: {\n type: 'array',\n items: { type: 'number' },\n },\n },\n });\n}\n","import { Option } from 'commander';\nimport type Conf from 'conf';\n\nimport { DEFAULT_LOGIN_URL } from './auth';\nimport { getProjectConfig, ProjectConfigSchema } from './project-config';\n\nexport const DEFAULT_API_HOST = 'api.bigcommerce.com';\n\nexport const storeHashOption = () =>\n new Option(\n '--store-hash <hash>',\n 'BigCommerce store hash. Can be found in the URL of your store Control Panel. Read from .bigcommerce/project.json or .env when not provided.',\n ).env('CATALYST_STORE_HASH');\n\nexport const accessTokenOption = () =>\n new Option(\n '--access-token <token>',\n 'BigCommerce access token. Can be found after creating a store-level API account. Read from .bigcommerce/project.json or .env when not provided.',\n ).env('CATALYST_ACCESS_TOKEN');\n\nexport const apiHostOption = () =>\n new Option(\n '--api-host <host>',\n 'BigCommerce API host. Read from .bigcommerce/project.json or CATALYST_API_HOST when not provided. Defaults to api.bigcommerce.com.',\n )\n .env('CATALYST_API_HOST')\n .hideHelp();\n\nexport const loginUrlOption = () =>\n new Option('--login-url <url>', 'BigCommerce login URL.')\n .env('BIGCOMMERCE_LOGIN_URL')\n .default(DEFAULT_LOGIN_URL)\n .hideHelp();\n\nexport const projectUuidOption = () =>\n new Option(\n '--project-uuid <uuid>',\n 'BigCommerce infrastructure project UUID. Read from .bigcommerce/project.json or .env when not provided.',\n ).env('CATALYST_PROJECT_UUID');\n\nexport const envPathOption = () =>\n new Option(\n '--env-path <path>',\n 'Path to an environment file to load for the build (relative to the current working directory). When omitted, .env.local and .env are auto-loaded from the current directory. Other commands never load env files.',\n );\n\nexport const resolveProjectUuid = (options: { projectUuid?: string }) => {\n const config = getProjectConfig();\n const projectUuid = options.projectUuid ?? config.get('projectUuid');\n\n if (!projectUuid) {\n throw new Error(\n 'Project UUID is required. Please run either `catalyst projects link` or `catalyst projects create` or this command again with --project-uuid <uuid>.',\n );\n }\n\n return projectUuid;\n};\n\nexport const resolveApiHost = (\n options: { apiHost?: string },\n config: Conf<ProjectConfigSchema>,\n): string => options.apiHost ?? config.get('apiHost') ?? DEFAULT_API_HOST;\n","import { Command, InvalidArgumentError, Option } from 'commander';\nimport { execa } from 'execa';\nimport { copyFile, cp, rm, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { valid as validSemver } from 'semver';\n\nimport { loadBuildEnv } from '../lib/build-env';\nimport { reconcileOpenNextVersion } from '../lib/commerce-hosting';\nimport { detectProjectPackageManager } from '../lib/detect-package-manager';\nimport { getModuleCliPath } from '../lib/get-module-cli-path';\nimport { installDependencies } from '../lib/install-dependencies';\nimport { consola } from '../lib/logger';\nimport { getProjectConfig } from '../lib/project-config';\nimport { getProjectState } from '../lib/project-state';\nimport { assertRequiredBuildEnv } from '../lib/required-build-env';\nimport { envPathOption } from '../lib/shared-options';\nimport { getWranglerConfig } from '../lib/wrangler-config';\n\nexport const WRANGLER_VERSION = '4.128.0';\n\n// npm dist-tags (e.g. latest, beta) aren't valid semver, so they're allowed\n// through a narrow character allowlist. This also guards the value before\n// it's interpolated into the `wrangler@<version>` spec passed to `pnpm dlx`,\n// rejecting anything that could smuggle extra args or shell metacharacters in.\nconst DIST_TAG_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;\n\nexport const parseWranglerVersion = (value: string): string => {\n if (!validSemver(value) && !DIST_TAG_PATTERN.test(value)) {\n throw new InvalidArgumentError(\n `\"${value}\" is not a valid Wrangler version or dist-tag (e.g. 4.90.0 or latest).`,\n );\n }\n\n return value;\n};\n\nexport async function buildCatalystProject(\n projectUuid: string,\n wranglerVersion: string = WRANGLER_VERSION,\n): Promise<void> {\n // Fail fast with an actionable message if the vars the build reads aren't\n // loaded — otherwise the missing values surface as a raw stack trace deep in\n // the OpenNext/Next.js prerender.\n assertRequiredBuildEnv();\n\n const coreDir = process.cwd();\n\n // The build invokes the project's own adapter, so offer to move a stale pin\n // before compiling against it. Reinstall when it moves.\n const projectPackageManager = await detectProjectPackageManager(coreDir);\n\n if (await reconcileOpenNextVersion(coreDir, projectPackageManager, { canUpgrade: true })) {\n await installDependencies(coreDir, projectPackageManager);\n }\n\n const openNextOutDir = join(coreDir, '.open-next');\n const bigcommerceDistDir = join(coreDir, '.bigcommerce', 'dist');\n\n consola.start('Generating GraphQL types...');\n\n await execa('node', [join(coreDir, 'scripts', 'generate.cjs')], {\n stdio: 'inherit',\n cwd: coreDir,\n });\n\n consola.success('GraphQL types generated');\n\n const wranglerConfig = getWranglerConfig(projectUuid);\n\n // Wrangler's --outdir writes alongside existing files instead of replacing\n // the directory. Stale artifacts (e.g. wasm modules named by an older\n // Wrangler version) end up in the bundle and break the Cloudflare upload.\n await rm(bigcommerceDistDir, { recursive: true, force: true });\n\n consola.start('Copying templates...');\n\n await copyFile(\n join(getModuleCliPath(), 'templates', 'open-next.config.ts'),\n join(coreDir, '.bigcommerce', 'open-next.config.ts'),\n );\n await writeFile(\n join(coreDir, '.bigcommerce', 'wrangler.jsonc'),\n JSON.stringify(wranglerConfig, null, 2),\n );\n\n consola.success('Templates copied');\n\n consola.start('Building project...');\n\n await execa(\n 'pnpm',\n [\n 'exec',\n 'opennextjs-cloudflare',\n 'build',\n '--skipWranglerConfigCheck',\n '--openNextConfigPath',\n join(coreDir, '.bigcommerce', 'open-next.config.ts'),\n ],\n {\n stdout: ['pipe', 'inherit'],\n cwd: coreDir,\n },\n );\n\n // Workers Assets serves `/_next/static/*` directly, bypassing the Next.js\n // server that would normally set the immutable Cache-Control on it. Its\n // default is `max-age=0, must-revalidate`, so browsers revalidate every\n // hashed asset on every repeat view. `_headers` overrides that, and has to\n // live inside the assets directory — written after the OpenNext build because\n // that build regenerates the directory, and before the Wrangler dry-run so\n // Wrangler validates it.\n await copyFile(\n join(getModuleCliPath(), 'templates', 'public_headers'),\n join(openNextOutDir, 'assets', '_headers'),\n );\n\n // pnpm 12 fails `dlx` on unapproved build scripts; Wrangler needs these two.\n await execa(\n 'pnpm',\n [\n 'dlx',\n '--allow-build=esbuild',\n '--allow-build=workerd',\n `wrangler@${wranglerVersion}`,\n 'deploy',\n '--config',\n join(coreDir, '.bigcommerce', 'wrangler.jsonc'),\n '--keep-vars',\n '--outdir',\n bigcommerceDistDir,\n '--dry-run',\n ],\n {\n stdout: ['pipe', 'inherit'],\n cwd: coreDir,\n },\n );\n\n consola.success('Project built');\n\n await cp(join(openNextOutDir, 'assets'), join(bigcommerceDistDir, 'assets'), {\n recursive: true,\n force: true,\n });\n}\n\nexport const build = new Command('build')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Build your Catalyst project using the OpenNext/Cloudflare build pipeline. Also runs a Wrangler dry-run to generate deployment artifacts.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n $ catalyst build\n\n # Include project UUID\n $ catalyst build --project-uuid <UUID>\n\n # Build with a specific Wrangler version\n $ catalyst build --wrangler-version 4.24.3`,\n )\n .addOption(\n new Option(\n '--project-uuid <uuid>',\n 'Project UUID to be included in the deployment configuration.',\n ).env('CATALYST_PROJECT_UUID'),\n )\n .addOption(\n new Option(\n '--wrangler-version <version>',\n `Wrangler version or dist-tag to build with. Defaults to ${WRANGLER_VERSION}.`,\n ).argParser(parseWranglerVersion),\n )\n .addOption(envPathOption())\n .action(async (options) => {\n // The build reads storefront env vars (BIGCOMMERCE_*). Load them from the\n // env file(s) before building so both the build and any pre-build checks\n // see them.\n loadBuildEnv({ envPath: options.envPath });\n\n // Project must be transformed (middleware swapped in, OpenNext dep installed)\n // before the OpenNext build pipeline can run. If it isn't, fall through to\n // `next build` so this command works for self-hosted Catalyst projects too.\n const state = getProjectState();\n\n if (!state.isTransformed) {\n consola.info('Project is not set up for Commerce Hosting — running `next build`.');\n consola.info('To deploy to Commerce Hosting, run `catalyst deploy`.');\n\n // `next build` reads the same storefront env vars; fail fast with an\n // actionable message here too, since this path doesn't go through\n // buildCatalystProject where the check normally runs.\n assertRequiredBuildEnv();\n\n await execa('pnpm', ['exec', 'next', 'build'], {\n stdio: 'inherit',\n cwd: process.cwd(),\n });\n\n return;\n }\n\n const config = getProjectConfig();\n const projectUuid = options.projectUuid ?? config.get('projectUuid');\n\n if (!projectUuid) {\n throw new Error(\n 'Project UUID is required. Please run `catalyst projects create` or `catalyst projects link` or this command again with --project-uuid <uuid>.',\n );\n }\n\n await buildCatalystProject(projectUuid, options.wranglerVersion);\n });\n","import { colorize } from 'consola/utils';\nimport { config } from 'dotenv';\nimport { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\n\nimport { UserActionableError } from './errors';\nimport { consola } from './logger';\n\n// Conventional env files auto-loaded (in precedence order) for the build when\n// `--env-path` isn't given. `.env.local` wins over `.env`, and neither\n// overrides values already present in the real environment — matching Next.js\n// precedence (process.env > .env.local > .env).\nconst AUTO_ENV_FILES = ['.env.local', '.env'] as const;\n\ninterface LoadBuildEnvOptions {\n // Explicit env file passed via `--env-path`. When set, only this file is\n // loaded (and it overrides existing values); when unset, the conventional\n // files above are auto-loaded instead.\n envPath?: string;\n // Directory the paths are resolved against. Defaults to the current working\n // directory; injectable for tests.\n cwd?: string;\n}\n\n// Loads storefront environment variables into `process.env` for the\n// build/deploy pipeline so the spawned build (and the checks that run before\n// it) can see them. This is intentionally scoped to `build` and `deploy`: no\n// other command loads env files, so running the CLI can't be surprised by a\n// stray `.env.local` on disk.\nexport function loadBuildEnv({ envPath, cwd = process.cwd() }: LoadBuildEnvOptions): void {\n if (envPath !== undefined) {\n const envFilePath = resolve(cwd, envPath);\n const result = config({ path: envFilePath, override: true });\n\n if (result.error) {\n const errCode =\n 'code' in result.error && typeof result.error.code === 'string'\n ? result.error.code\n : undefined;\n const message =\n errCode === 'ENOENT'\n ? `Env file not found: ${envFilePath}`\n : `Failed to load --env-path ${envPath}: ${result.error.message}`;\n\n throw new UserActionableError(message);\n }\n\n consola.log(colorize('cyanBright', `Loaded environment variables from ${envFilePath}\\n`));\n\n return;\n }\n\n // Auto-load the conventional files. `.env.local` is loaded first so it takes\n // precedence over `.env`; `override: false` means the real environment always\n // wins over both. Missing files are expected and ignored.\n const loaded = AUTO_ENV_FILES.filter((file) => {\n const envFilePath = resolve(cwd, file);\n\n if (!existsSync(envFilePath)) {\n return false;\n }\n\n return !config({ path: envFilePath, override: false }).error;\n });\n\n if (loaded.length > 0) {\n consola.log(colorize('cyanBright', `Loaded environment variables from ${loaded.join(', ')}\\n`));\n }\n}\n","import { confirm, input, select, Separator } from '@inquirer/prompts';\nimport { colorize } from 'consola/utils';\nimport { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { minVersion, satisfies, lt as semverLt, validRange } from 'semver';\nimport { z } from 'zod';\n\nimport type { PackageManager } from './detect-package-manager';\nimport { consola } from './logger';\nimport {\n createProject,\n fetchProjects,\n InfrastructureProjectValidationError,\n type ProjectListItem,\n} from './project';\nimport { sortPackageJsonFields } from './sort-package-json';\n\n// Exported so `cloudflare-context-symbol.spec.ts` can assert the version its\n// symbol-key assumption was verified against. Keep it exact: a range would\n// admit versions that key was never checked against, and that failure is silent\n// (null context, so every native-hosted store degrades to an in-process cache).\n//\n// This is what new projects are pinned to, not a floor existing ones are held\n// at -- see `reconcileOpenNextVersion`.\nexport const OPENNEXT_CLOUDFLARE_VERSION = '1.20.6';\n\n// The `next` peer range OPENNEXT_CLOUDFLARE_VERSION declares. Update both\n// together, from the new adapter's `peerDependencies.next`.\nexport const OPENNEXT_REQUIRED_NEXT_RANGE = '>=15.5.24 <16 || >=16.3.3';\n\nconst corePackageJsonSchema = z.looseObject({\n dependencies: z.record(z.string(), z.string()).optional(),\n});\n\n// Loose on purpose: the point is to carry unknown keys through untouched, so\n// this only asserts the file holds an object at all.\nconst projectJsonSchema = z.looseObject({});\n\n// Existing contents of `.bigcommerce/project.json`, or an empty object if it is\n// absent, unreadable, or not a JSON object. A corrupt file shouldn't fail setup\n// -- the keys this helper writes are enough to rebuild a working project.\nconst readProjectJson = (path: string): Record<string, unknown> => {\n if (!existsSync(path)) return {};\n\n try {\n const parsed = projectJsonSchema.safeParse(JSON.parse(readFileSync(path, 'utf-8')));\n\n return parsed.success ? parsed.data : {};\n } catch {\n return {};\n }\n};\n\nconst writeJson = (path: string, value: unknown) => {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(value, null, 2)}\\n`);\n};\n\nconst convertProxyToMiddleware = (projectDir: string) => {\n const proxyPath = join(projectDir, 'proxy.ts');\n const middlewarePath = join(projectDir, 'middleware.ts');\n\n if (!existsSync(proxyPath)) return;\n\n const contents = readFileSync(proxyPath, 'utf-8')\n .replace('export const proxy', 'export const middleware')\n .replace('export const config = {', \"export const config = {\\n runtime: 'experimental-edge',\");\n\n writeFileSync(middlewarePath, contents);\n unlinkSync(proxyPath);\n};\n\n// The default `instrumentation.ts` registers `@vercel/otel`, whose node\n// build OpenNext bundles into the worker chunk; workerd then throws on cold\n// start with \"Failed to prepare server\". A Vercel-deploying user may have\n// customized the hook though, so we prompt before removing it (and only drop\n// `@vercel/otel` if the user agrees — their customization probably imports it).\n// In non-TTY contexts (CI deploys, scripts), skip the cleanup with a warning so\n// no customization is silently wiped. Exported because callers run this on\n// already-transformed projects too, where `setupCommerceHosting` would\n// short-circuit.\nexport const cleanupCloudflareIncompatibilities = async (projectDir: string) => {\n const instrumentationPath = join(projectDir, 'instrumentation.ts');\n\n if (!existsSync(instrumentationPath)) return;\n\n if (!process.stdin.isTTY) {\n consola.warn(\n 'instrumentation.ts is present and may be incompatible with the Cloudflare Workers ' +\n 'bundle (the default @vercel/otel scaffolding throws at cold start under workerd). ' +\n 'Skipping automatic cleanup in non-interactive mode — re-run interactively to remove it, ' +\n 'or delete/gate it manually.',\n );\n\n return;\n }\n\n const shouldRemove = await confirm({\n message:\n 'Catalyst found instrumentation.ts, which is incompatible with the Cloudflare Workers ' +\n 'bundle when it uses @vercel/otel (causes \"Failed to prepare server\" at cold start).\\n' +\n 'Remove it and drop @vercel/otel from package.json? (required for native hosting)',\n default: true,\n });\n\n if (!shouldRemove) {\n consola.info(\n 'Leaving instrumentation.ts in place. The Cloudflare worker will continue to log ' +\n '\"Failed to prepare server\" at cold start until this is resolved manually.',\n );\n\n return;\n }\n\n unlinkSync(instrumentationPath);\n consola.info('Removed instrumentation.ts (incompatible with Cloudflare Workers).');\n\n const corePackageJsonPath = join(projectDir, 'package.json');\n\n if (existsSync(corePackageJsonPath)) {\n const pkg = corePackageJsonSchema.parse(JSON.parse(readFileSync(corePackageJsonPath, 'utf-8')));\n\n if (pkg.dependencies && '@vercel/otel' in pkg.dependencies) {\n const { '@vercel/otel': _removedVercelOtel, ...preservedDeps } = pkg.dependencies;\n\n pkg.dependencies = preservedDeps;\n writeJson(corePackageJsonPath, sortPackageJsonFields(pkg));\n consola.info('Dropped @vercel/otel from package.json.');\n }\n }\n};\n\n// The adapter pin lives in the project's own package.json, and `deploy` skips\n// `setupCommerceHosting` once transformed, so a CLI bump never reaches an\n// existing project by itself. `catalyst upgrade` can't move it either: the pin\n// is injected, so it is absent from the upstream tree and no merge ever sees it\n// (same reason `findStaleCli` checks the CLI's own pin out-of-band).\nexport const reconcileOpenNextVersion = async (\n projectDir: string,\n packageManager: PackageManager,\n { canUpgrade }: { canUpgrade: boolean },\n): Promise<boolean> => {\n const corePackageJsonPath = join(projectDir, 'package.json');\n\n if (!existsSync(corePackageJsonPath)) return false;\n\n const pkg = corePackageJsonSchema.parse(JSON.parse(readFileSync(corePackageJsonPath, 'utf-8')));\n const range = pkg.dependencies?.['@opennextjs/cloudflare'];\n\n // Not a Commerce Hosting project; adding the dep is setup's job.\n if (range === undefined) return false;\n\n // Tarball, git URL, or `link:` -- minVersion() throws on these.\n if (!validRange(range)) return false;\n\n // Already admits the target; their next install picks it up.\n if (satisfies(OPENNEXT_CLOUDFLARE_VERSION, range)) return false;\n\n const current = minVersion(range)?.version;\n\n // Only nudge a project that is behind; downgrading one ahead would be wrong.\n if (current === undefined || !semverLt(current, OPENNEXT_CLOUDFLARE_VERSION)) return false;\n\n const manualStep = `\\`${packageManager} add @opennextjs/cloudflare@${OPENNEXT_CLOUDFLARE_VERSION}\\``;\n const behind = `This project pins @opennextjs/cloudflare ${current}, but this CLI targets ${OPENNEXT_CLOUDFLARE_VERSION}.`;\n\n // Bumping past what the project's Next supports would leave an unsupported\n // dependency set, so don't offer an upgrade that can't work.\n const nextRange = pkg.dependencies?.next;\n const nextVersion =\n nextRange !== undefined && validRange(nextRange) ? minVersion(nextRange) : null;\n\n if (nextVersion !== null && !satisfies(nextVersion.version, OPENNEXT_REQUIRED_NEXT_RANGE)) {\n consola.warn(\n `${behind} That release needs Next.js ${OPENNEXT_REQUIRED_NEXT_RANGE}, but this project ` +\n `is on ${nextVersion.version}. Run \\`catalyst upgrade\\` to move core and Next first, ` +\n 'then re-run the deploy to pick up the adapter.',\n );\n\n return false;\n }\n\n // `--prebuilt` uploads an existing bundle, never rebuilt against a new adapter.\n if (!canUpgrade) {\n consola.warn(\n `${behind} The deploy will use the existing build output. Re-run without \\`--prebuilt\\`, ` +\n `or update it with ${manualStep}, to pick up adapter fixes released since then.`,\n );\n\n return false;\n }\n\n // Never rewrite deps unattended: pnpm treats the lockfile as frozen in CI, so\n // the install that has to follow would fail the deploy.\n if (!process.stdin.isTTY) {\n consola.warn(\n `${behind} Skipping the upgrade prompt in a non-interactive environment. Update it with ` +\n `${manualStep} and commit the lockfile to pick up adapter fixes released since then.`,\n );\n\n return false;\n }\n\n const shouldUpgrade = await confirm({\n message:\n `${behind} Adapter fixes released since then are not applied. ` +\n `Update it to ${OPENNEXT_CLOUDFLARE_VERSION} and reinstall now?`,\n default: true,\n });\n\n if (!shouldUpgrade) {\n consola.info(`Keeping @opennextjs/cloudflare ${current}. Update it later with ${manualStep}.`);\n\n return false;\n }\n\n pkg.dependencies = {\n ...pkg.dependencies,\n '@opennextjs/cloudflare': OPENNEXT_CLOUDFLARE_VERSION,\n };\n\n writeJson(corePackageJsonPath, sortPackageJsonFields(pkg));\n consola.info(`Updated @opennextjs/cloudflare to ${OPENNEXT_CLOUDFLARE_VERSION}.`);\n\n return true;\n};\n\nexport const setupCommerceHosting = async ({\n projectDir,\n projectUuid,\n storeHash,\n accessToken,\n}: {\n projectDir: string;\n projectUuid: string;\n storeHash?: string;\n accessToken?: string;\n}) => {\n await cleanupCloudflareIncompatibilities(projectDir);\n\n const corePackageJsonPath = join(projectDir, 'package.json');\n const pkg = corePackageJsonSchema.parse(JSON.parse(readFileSync(corePackageJsonPath, 'utf-8')));\n\n pkg.dependencies = {\n ...pkg.dependencies,\n '@opennextjs/cloudflare': OPENNEXT_CLOUDFLARE_VERSION,\n };\n\n writeJson(corePackageJsonPath, sortPackageJsonFields(pkg));\n\n const projectJsonPath = join(projectDir, '.bigcommerce', 'project.json');\n\n // Merge rather than rebuild. `catalyst env` stores deployment variables under\n // `env` in this same file and `apiHost` is persisted here too, so\n // constructing a fresh object silently dropped both. Losing `env` is the\n // costly one: those entries are sent as secrets on every `catalyst deploy`,\n // so a wipe means the next deploy ships a worker without its storefront\n // credentials, with nothing in the output mentioning env vars. `deploy` and\n // `projects link` both reach this on projects that already hold real values.\n const projectJson: Record<string, unknown> = {\n ...readProjectJson(projectJsonPath),\n projectUuid,\n framework: 'catalyst',\n };\n\n // Absent means \"not supplied on this run\", not \"clear it\" -- linking without\n // credentials must not drop credentials the project already had.\n if (storeHash) projectJson.storeHash = storeHash;\n if (accessToken) projectJson.accessToken = accessToken;\n\n writeJson(projectJsonPath, projectJson);\n\n convertProxyToMiddleware(projectDir);\n};\n\ninterface CommerceHostingApiContext {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n}\n\n// Thrown by `selectOrCreateInfrastructureProject` when the user declines the\n// \"Would you like to create one?\" prompt that surfaces when no projects exist.\n// Callers translate this into a context-appropriate error (e.g. \"Cannot deploy\n// without being linked to a project\").\nexport class NoLinkedProjectError extends Error {\n constructor() {\n super('No infrastructure project linked: user declined to create one.');\n this.name = 'NoLinkedProjectError';\n }\n}\n\nasync function promptForNewProjectName(api: CommerceHostingApiContext): Promise<ProjectListItem> {\n const newProjectName = await input({ message: 'Enter a name for the new project:' });\n\n const data = await createProject(newProjectName, api.storeHash, api.accessToken, api.apiHost);\n\n consola.success(`Project \"${data.name}\" created successfully.`);\n\n // Newly created — provisioning is async, hostnames not registered yet.\n return { uuid: data.uuid, name: data.name, deployment_hostnames: [] };\n}\n\n// Generic \"select an existing project, or create a new one\" prompt — used by\n// `catalyst projects link` and by `catalyst deploy` when its linked project is\n// missing. Distinct from `promptForCommerceHostingProject` which has\n// default-name + auto-create semantics tailored to `catalyst create`.\n//\n// Pass `linkedProjectUuid` to decorate the matching project's label with\n// `[linked]` so the user can see which one is the current selection.\nexport async function selectOrCreateInfrastructureProject(\n api: CommerceHostingApiContext,\n linkedProjectUuid?: string,\n): Promise<ProjectListItem> {\n consola.start('Fetching projects...');\n\n const existingProjects = await fetchProjects(api.storeHash, api.accessToken, api.apiHost);\n\n consola.success('Projects fetched.');\n\n // No existing projects on the store — skip the select prompt and offer\n // creation directly. Declining means we have nothing to link to.\n if (existingProjects.length === 0) {\n const shouldCreate = await confirm({\n message:\n 'There are not any hosting projects that you can link to yet. Would you like to create one?',\n default: true,\n });\n\n if (!shouldCreate) {\n throw new NoLinkedProjectError();\n }\n\n return promptForNewProjectName(api);\n }\n\n const choices = [\n ...existingProjects.map((p) => ({\n name: p.uuid === linkedProjectUuid ? `${p.name} ${colorize('green', '[linked]')}` : p.name,\n value: p.uuid,\n description: p.uuid,\n })),\n {\n name: 'Create a new project',\n value: 'create',\n description: 'Create a new hosting project for this Catalyst storefront.',\n },\n ];\n\n const selected = await select({\n message: 'Select a project or create a new project (Press <enter> to select).',\n choices,\n });\n\n if (selected === 'create') {\n return promptForNewProjectName(api);\n }\n\n const matched = existingProjects.find((p) => p.uuid === selected);\n\n if (!matched) {\n throw new Error(`Selected project ${String(selected)} not found in fetched list.`);\n }\n\n return matched;\n}\n\nexport async function promptForCommerceHostingProject(\n api: CommerceHostingApiContext,\n defaultName: string,\n autoUseDefaultName?: boolean,\n useExistingOnCollision?: boolean,\n): Promise<ProjectListItem> {\n const existingProjects = await fetchProjects(api.storeHash, api.accessToken, api.apiHost);\n const takenNames = existingProjects.map((project) => project.name);\n\n if (autoUseDefaultName) {\n return autoCreateCommerceHostingProject(\n api,\n defaultName,\n existingProjects,\n useExistingOnCollision,\n );\n }\n\n const conflict = existingProjects.find(\n (project) => project.name.toLowerCase() === defaultName.toLowerCase(),\n );\n\n if (!conflict) {\n return autoCreateCommerceHostingProject(\n api,\n defaultName,\n existingProjects,\n useExistingOnCollision,\n );\n }\n\n type Action = 'use-named' | 'select-from-list' | 'create';\n\n const hasOtherProjects = existingProjects.length > 1;\n\n const choices: Array<{ name: string; value: Action }> = [\n { name: `Use \"${conflict.name}\"`, value: 'use-named' },\n ];\n\n if (hasOtherProjects) {\n choices.push({ name: 'Select from my projects', value: 'select-from-list' });\n }\n\n choices.push({ name: 'Create a new project', value: 'create' });\n\n const action = await select<Action>({\n message: hasOtherProjects\n ? `It looks like you already have an existing Commerce Hosting project named \"${conflict.name}\". Would you like to use it, select from your projects, or create a new one?`\n : `It looks like you already have an existing Commerce Hosting project named \"${conflict.name}\". Would you like to use it, or create a new one?`,\n choices,\n });\n\n if (action === 'use-named') {\n consola.success(`Using existing Commerce Hosting project \"${conflict.name}\"`);\n\n return conflict;\n }\n\n if (action === 'create') {\n return promptAndCreateCommerceHostingProject(api, takenNames, defaultName);\n }\n\n const selected = await select<ProjectListItem | 'create-new'>({\n message: 'Which Commerce Hosting project would you like to use?',\n choices: [\n ...existingProjects.map((project) => ({\n name: project.name,\n value: project,\n description: project.uuid,\n })),\n new Separator(),\n { name: 'Create a new project', value: 'create-new' as const },\n ],\n });\n\n if (selected === 'create-new') {\n return promptAndCreateCommerceHostingProject(api, takenNames, defaultName);\n }\n\n consola.success(`Using existing Commerce Hosting project \"${selected.name}\"`);\n\n return selected;\n}\n\nexport async function promptAndCreateCommerceHostingProject(\n api: CommerceHostingApiContext,\n takenNames: readonly string[],\n defaultName?: string,\n): Promise<ProjectListItem> {\n const projectName = await input({\n message: 'What would you like to name your Commerce Hosting project?',\n default: defaultName,\n validate: (value) => {\n const trimmed = value.trim();\n\n if (!trimmed) return 'Project name is required';\n\n const conflict = takenNames.find((taken) => taken.toLowerCase() === trimmed.toLowerCase());\n\n if (conflict) {\n return `A Commerce Hosting project named \"${conflict}\" already exists`;\n }\n\n return true;\n },\n theme: {\n style: {\n help: () =>\n colorize(\n 'dim',\n '(The project that hosts your storefront on Commerce — often matches your folder name.)',\n ),\n },\n },\n });\n\n try {\n const created = await createProject(\n projectName.trim(),\n api.storeHash,\n api.accessToken,\n api.apiHost,\n );\n\n consola.success(`Commerce Hosting project \"${created.name}\" created successfully`);\n\n return { uuid: created.uuid, name: created.name, deployment_hostnames: [] };\n } catch (error) {\n if (error instanceof InfrastructureProjectValidationError) {\n consola.error(error.message);\n\n return promptAndCreateCommerceHostingProject(api, takenNames, defaultName);\n }\n\n throw error;\n }\n}\n\nasync function resolveCollisionChoice(\n existingName: string,\n useExistingOnCollision: boolean | undefined,\n): Promise<boolean> {\n if (useExistingOnCollision === true) return true;\n\n if (!process.stdin.isTTY) return false;\n\n return select<boolean>({\n message: `A Commerce Hosting project named \"${existingName}\" already exists. Use the existing project?`,\n choices: [\n { name: 'Yes', value: true },\n { name: 'No', value: false },\n ],\n });\n}\n\nasync function autoCreateCommerceHostingProject(\n api: CommerceHostingApiContext,\n name: string,\n existingProjects: readonly ProjectListItem[],\n useExistingOnCollision?: boolean,\n): Promise<ProjectListItem> {\n const existing = existingProjects.find(\n (project) => project.name.toLowerCase() === name.toLowerCase(),\n );\n\n if (existing) {\n const shouldUseExisting = await resolveCollisionChoice(existing.name, useExistingOnCollision);\n\n if (shouldUseExisting) {\n consola.success(`Using existing Commerce Hosting project \"${existing.name}\"`);\n\n return existing;\n }\n\n consola.error(\n 'Not reusing the existing project. Re-run with a different --project-name, or pass --use-existing to reuse it.',\n );\n process.exit(1);\n }\n\n try {\n const created = await createProject(name, api.storeHash, api.accessToken, api.apiHost);\n\n consola.success(`Commerce Hosting project \"${created.name}\" created successfully`);\n\n return { uuid: created.uuid, name: created.name, deployment_hostnames: [] };\n } catch (error) {\n if (error instanceof InfrastructureProjectValidationError) {\n consola.error(\n `Failed to create Commerce Hosting project \"${name}\": ${error.message}\\nRe-run with a different --project-name.`,\n );\n process.exit(1);\n }\n\n throw error;\n }\n}\n\n// Orchestrates prompt + file mutations. Callable from `catalyst create --hosting commerce`\n// (eager) and `catalyst deploy` (lazy). Idempotent — safe to re-run.\nexport async function runCommerceHostingSetup({\n api,\n projectDir,\n defaultProjectName,\n autoUseProjectName,\n useExistingOnCollision,\n}: {\n api: CommerceHostingApiContext;\n projectDir: string;\n defaultProjectName: string;\n autoUseProjectName?: boolean;\n useExistingOnCollision?: boolean;\n}): Promise<ProjectListItem> {\n const project = await promptForCommerceHostingProject(\n api,\n defaultProjectName,\n autoUseProjectName,\n useExistingOnCollision,\n );\n\n await setupCommerceHosting({\n projectDir,\n projectUuid: project.uuid,\n storeHash: api.storeHash,\n accessToken: api.accessToken,\n });\n\n return project;\n}\n","// Canonical order for top-level fields in core/package.json. Anything not in\n// this list is appended afterwards in its original position relative to other\n// unknown keys, so we don't drop or reshuffle uncommon fields like `keywords`.\nconst FIELD_ORDER = [\n 'name',\n 'description',\n 'version',\n 'private',\n 'engines',\n 'scripts',\n 'dependencies',\n 'devDependencies',\n] as const;\n\nexport function sortPackageJsonFields<T extends Record<string, unknown>>(pkg: T): T {\n const ordered: Record<string, unknown> = {};\n\n FIELD_ORDER.forEach((field) => {\n if (field in pkg) {\n ordered[field] = pkg[field];\n }\n });\n\n Object.keys(pkg).forEach((key) => {\n if (!(key in ordered)) {\n ordered[key] = pkg[key];\n }\n });\n\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return ordered as T;\n}\n","import { access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { detectPackageManager as detectFromDir } from 'nypm';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\n// Lockfile -> package manager, in nypm's own check order.\nconst PROJECT_LOCKFILES = [\n ['pnpm-lock.yaml', 'pnpm'],\n ['yarn.lock', 'yarn'],\n ['bun.lock', 'bun'],\n ['bun.lockb', 'bun'],\n ['package-lock.json', 'npm'],\n] as const satisfies ReadonlyArray<readonly [string, PackageManager]>;\n\n// Detect a project's package manager from its lockfile alone, returning null\n// when the directory has none so the caller can decide its own last resort.\n// Unlike detectProjectPackageManager() this never throws — nypm parses\n// package.json to read `packageManager`, which blows up on a manifest left full\n// of merge conflict markers — and it can express \"I don't know\", which nypm\n// can't, since it falls back to npm internally.\nexport const detectLockfileManager = async (dir: string): Promise<PackageManager | null> => {\n const found = await Promise.all(\n PROJECT_LOCKFILES.map(async ([file, manager]) =>\n access(join(dir, file))\n .then(() => manager)\n .catch(() => null),\n ),\n );\n\n return found.find((manager) => manager !== null) ?? null;\n};\n\n// Detect the package manager that INVOKED the CLI (via npx / pnpm dlx / yarn dlx\n// / bunx) by parsing the leading token of npm_config_user_agent, which every\n// manager sets when it spawns a child process. This is deliberately not\n// nypm.detectPackageManager(cwd): that keys off a lockfile in the project, which\n// a freshly extracted project does not have yet.\nexport const detectPackageManager = (): PackageManager => {\n const userAgent = process.env.npm_config_user_agent ?? '';\n const name = userAgent.split(' ')[0]?.split('/')[0];\n\n if (name === 'pnpm' || name === 'yarn' || name === 'bun') {\n return name;\n }\n\n // Some bunx versions omit npm_config_user_agent; fall back to the bun runtime marker.\n if (process.versions.bun) {\n return 'bun';\n }\n\n return 'npm';\n};\n\n// Detect the package manager an EXISTING project uses, from its lockfile or the\n// package.json `packageManager` field. Used by flows that run inside an\n// already-scaffolded project (e.g. `project link`), where a lockfile exists —\n// unlike detectPackageManager(), which infers the INVOKING manager for a freshly\n// extracted project that has no lockfile yet. Falls back to npm, since most\n// users will have it installed, when detection is inconclusive or returns a\n// manager we don't support.\nexport const detectProjectPackageManager = async (projectDir: string): Promise<PackageManager> => {\n const detected = await detectFromDir(projectDir);\n const name = detected?.name;\n\n if (name === 'pnpm' || name === 'yarn' || name === 'bun' || name === 'npm') {\n return name;\n }\n\n return 'npm';\n};\n","/* eslint-disable no-underscore-dangle */\n\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport function getModuleCliPath() {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = dirname(__filename);\n\n return join(__dirname, '..');\n}\n","import { installDependencies as installDeps } from 'nypm';\nimport yoctoSpinner from 'yocto-spinner';\n\nimport type { PackageManager } from './detect-package-manager';\n\n// Restore an env var to a captured previous value, unsetting it when it wasn't\n// set before (a plain assignment can't represent \"absent\").\nconst restoreEnv = (key: string, previous: string | undefined) => {\n if (previous === undefined) {\n Reflect.deleteProperty(process.env, key);\n } else {\n process.env[key] = previous;\n }\n};\n\n// nypm runs the install through tinyexec, which in silent mode drains the\n// child's stdout to completion BEFORE it starts reading stderr. pnpm sends its\n// progress to stdout but floods stderr with Node warnings — on Node 26 the\n// `File descriptor N opened in unmanaged mode` spam alone is thousands of\n// lines. That stderr fills its ~64KB pipe buffer while tinyexec is still busy\n// on stdout, pnpm blocks writing, and the whole install deadlocks (the original\n// \"hangs forever\" bug). These env vars keep the child quiet on stderr so the\n// buffer never fills:\n// - NODE_NO_WARNINGS: drop pnpm/corepack's internal Node warnings (the flood).\n// - COREPACK_ENABLE_DOWNLOAD_PROMPT: never block on corepack's download\n// confirmation (defensive; corepack already defaults this off for the\n// `corepack pnpm` entrypoint, but pin it so no path can stall on stdin).\nconst withQuietInstallEnv = async <T>(run: () => Promise<T>): Promise<T> => {\n const prevNodeNoWarnings = process.env.NODE_NO_WARNINGS;\n const prevDownloadPrompt = process.env.COREPACK_ENABLE_DOWNLOAD_PROMPT;\n\n process.env.NODE_NO_WARNINGS ??= '1';\n process.env.COREPACK_ENABLE_DOWNLOAD_PROMPT ??= '0';\n\n try {\n return await run();\n } finally {\n restoreEnv('NODE_NO_WARNINGS', prevNodeNoWarnings);\n restoreEnv('COREPACK_ENABLE_DOWNLOAD_PROMPT', prevDownloadPrompt);\n }\n};\n\nexport const installDependencies = async (\n projectDir: string,\n packageManager: PackageManager = 'pnpm',\n) => {\n const spinner = yoctoSpinner().start(\n `Installing dependencies with ${packageManager}. This could take a minute...`,\n );\n\n try {\n await withQuietInstallEnv(() => installDeps({ cwd: projectDir, silent: true, packageManager }));\n spinner.success('Dependencies installed successfully.');\n } catch (error) {\n const message = error instanceof Error ? error.message : 'unknown error';\n\n spinner.error(`Failed to install dependencies: ${message}`);\n throw error;\n }\n};\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { z } from 'zod';\n\nconst projectJsonSchema = z.looseObject({\n projectUuid: z.string().optional(),\n});\n\nconst packageJsonSchema = z.looseObject({\n dependencies: z.record(z.string(), z.string()).optional(),\n});\n\nexport interface ProjectState {\n projectUuid: string | undefined;\n hasMiddleware: boolean;\n hasProxy: boolean;\n hasOpenNextDep: boolean;\n\n // Derived signals — `isLinked` reflects intent (UUID registered via\n // `catalyst projects create` or commerce-hosting setup); `isTransformed`\n // reflects on-disk readiness (middleware.ts swapped in, OpenNext dep\n // installed). A deploy needs both, but `catalyst build` only cares about\n // `isTransformed` so it can dispatch to OpenNext vs `next build`.\n isLinked: boolean;\n isTransformed: boolean;\n isFullySetUp: boolean;\n}\n\nconst safeReadJson = (path: string): unknown => {\n try {\n return JSON.parse(readFileSync(path, 'utf-8'));\n } catch {\n return null;\n }\n};\n\n// Read-only inspection of a Catalyst project at `cwd` (typically `core/`).\n// Avoids `getProjectConfig()` deliberately — that would instantiate `Conf`\n// and create `.bigcommerce/` as a side effect.\nexport function getProjectState(cwd: string = process.cwd()): ProjectState {\n const projectJson = projectJsonSchema.safeParse(\n safeReadJson(join(cwd, '.bigcommerce', 'project.json')),\n );\n const projectUuid = projectJson.success ? projectJson.data.projectUuid : undefined;\n\n const hasMiddleware = existsSync(join(cwd, 'middleware.ts'));\n const hasProxy = existsSync(join(cwd, 'proxy.ts'));\n\n const pkgJson = packageJsonSchema.safeParse(safeReadJson(join(cwd, 'package.json')));\n const hasOpenNextDep = pkgJson.success\n ? Boolean(pkgJson.data.dependencies?.['@opennextjs/cloudflare'])\n : false;\n\n const isLinked = Boolean(projectUuid);\n const isTransformed = hasMiddleware && !hasProxy && hasOpenNextDep;\n const isFullySetUp = isLinked && isTransformed;\n\n return {\n projectUuid,\n hasMiddleware,\n hasProxy,\n hasOpenNextDep,\n isLinked,\n isTransformed,\n isFullySetUp,\n };\n}\n","import { UserActionableError } from './errors';\n\n// Env vars the core storefront build genuinely asserts on. Without these the\n// OpenNext/Next.js build fails deep inside prerendering with a raw stack trace:\n// BIGCOMMERCE_CHANNEL_ID is passed straight to createClient() with no fallback,\n// so the client constructor throws \"Client configuration must include a\n// channelId\" immediately; empty storefront token/store hash make Storefront API\n// calls fail; a missing AUTH_SECRET throws \"AUTH_SECRET is not set\" during\n// static generation. These are the values the app reads at build time — see\n// core/client/index.ts and core/auth/anonymous-session.ts.\nexport const REQUIRED_BUILD_ENV_VARS = [\n 'BIGCOMMERCE_STORE_HASH',\n 'BIGCOMMERCE_STOREFRONT_TOKEN',\n 'BIGCOMMERCE_CHANNEL_ID',\n 'AUTH_SECRET',\n] as const;\n\n// A var counts as missing when it's unset or only whitespace — the core reads\n// most of these with a `?? ''` fallback, so an empty value fails just as\n// cryptically as an absent one.\nexport const findMissingBuildEnv = (env: NodeJS.ProcessEnv = process.env): string[] => {\n return REQUIRED_BUILD_ENV_VARS.filter((name) => {\n const value = env[name];\n\n return value === undefined || value.trim() === '';\n });\n};\n\n// Fail fast with a clear, actionable message before we shell out to the build.\n// Naming the missing vars (and pointing at `--env-path`/`.env.local`) turns an\n// \"ugly build error\" into something the user can act on immediately.\nexport const assertRequiredBuildEnv = (env: NodeJS.ProcessEnv = process.env): void => {\n const missing = findMissingBuildEnv(env);\n\n if (missing.length === 0) {\n return;\n }\n\n const missingList = missing.map((name) => ` - ${name}`).join('\\n');\n\n throw new UserActionableError(\n `Missing required environment variable${missing.length === 1 ? '' : 's'} for the build:\\n` +\n `${missingList}\\n\\n` +\n 'These are read by the build itself, so they must be set before it runs. ' +\n 'The build automatically loads `.env.local` and `.env` from the current ' +\n `directory (${process.cwd()}) — add the variables above to one of those ` +\n 'files (`.env.local` takes precedence).\\n' +\n 'To load an env file from a different location, pass `--env-path <path>` ' +\n '(for example `--env-path ../.env.local` when running from a subdirectory).',\n );\n};\n","// The compatibility date, compatibility flags, Durable Object classes,\n// migration tag, and KV namespace binding below are mirrored in Ignition,\n// which builds its own Worker metadata at deploy time\n// (pkg/cloudflare/upload/metadata.go and\n// pkg/cloudflare/upload/migrations/migrations.go). Keep both sides in sync\n// when changing any of them.\n//\n// Note that only the CATALYST_ROUTES_KV *binding name* is shared with\n// Ignition — the namespace id here is a local-only placeholder (see below),\n// while Ignition binds the real per-project namespace it provisioned.\nexport function getCompatibilityDate(now = new Date()): string {\n const date = new Date(now);\n\n // One month behind the current date: recent enough to track Cloudflare\n // runtime behavior (per Cloudflare guidance), buffered enough to avoid\n // brand-new compatibility-date-gated changes. Ignition applies the same\n // offset at deploy time, so the bundle is never built against newer\n // semantics than it runs under.\n date.setUTCMonth(date.getUTCMonth() - 1);\n\n return date.toISOString().slice(0, 10);\n}\n\n// Namespace id for the routing cache KV binding in the *generated* config,\n// which only ever drives local `wrangler dev`/`opennextjs-cloudflare preview`\n// (where Miniflare keys its simulated store under `.wrangler/state/v3/kv`)\n// and the `wrangler deploy --dry-run` bundling step, which never resolves\n// bindings against the Cloudflare API. Ignition overwrites this with the real\n// per-project namespace id when it uploads the Worker.\n//\n// The value is deliberately not a 32-char lowercase hex string — the only\n// shape a real provisioned Cloudflare namespace id can take — so it cannot\n// collide with a production store's cache even if this config were somehow\n// used against the live API. Such a request fails closed with an invalid-id\n// error instead of reading or writing someone's real routing cache.\nconst LOCAL_ROUTES_KV_NAMESPACE_ID = 'catalyst-routes-kv-local';\n\nexport function getWranglerConfig(projectUuid: string) {\n return {\n $schema: 'node_modules/wrangler/config-schema.json',\n main: '../.open-next/worker.js',\n name: `project-${projectUuid}`,\n compatibility_date: getCompatibilityDate(),\n compatibility_flags: ['nodejs_compat', 'global_fetch_strictly_public'],\n observability: {\n enabled: true,\n head_sampling_rate: 0.05,\n logs: {\n enabled: true,\n head_sampling_rate: 1,\n invocation_logs: false,\n },\n },\n assets: {\n directory: '../.open-next/assets',\n binding: 'ASSETS',\n },\n services: [\n {\n binding: 'WORKER_SELF_REFERENCE',\n service: `project-${projectUuid}`,\n },\n ],\n r2_buckets: [\n {\n binding: 'NEXT_INC_CACHE_R2_BUCKET',\n bucket_name: `project-${projectUuid}`,\n },\n ],\n kv_namespaces: [\n {\n binding: 'CATALYST_ROUTES_KV',\n id: LOCAL_ROUTES_KV_NAMESPACE_ID,\n },\n ],\n durable_objects: {\n bindings: [\n {\n name: 'NEXT_CACHE_DO_QUEUE',\n class_name: 'DOQueueHandler',\n },\n {\n name: 'NEXT_TAG_CACHE_DO_SHARDED',\n class_name: 'DOShardedTagCache',\n },\n {\n name: 'NEXT_CACHE_DO_PURGE',\n class_name: 'BucketCachePurge',\n },\n ],\n },\n migrations: [\n {\n tag: 'v1',\n new_sqlite_classes: ['DOQueueHandler', 'DOShardedTagCache', 'BucketCachePurge'],\n },\n ],\n };\n}\n","import { confirm, select } from '@inquirer/prompts';\nimport { Command, InvalidArgumentError, Option } from 'commander';\nimport type Conf from 'conf';\nimport { colorize } from 'consola/utils';\n\nimport { canPrompt } from '../lib/can-prompt';\nimport {\n offerManagedCheckoutUrl,\n runChannelCheckoutUrlFlow,\n} from '../lib/channel-checkout-url-flow';\nimport { resolveChannel, runChannelSiteUrlFlow } from '../lib/channel-site-flow';\nimport {\n channelPlatformLabel,\n type ChannelSiteDetails,\n checkChannelEligibility,\n deleteChannelCheckoutUrl,\n fetchAvailableChannels,\n findChannelSiteUrl,\n getChannelInit,\n getChannelSite,\n sortChannelsByPlatform,\n updateChannelCheckoutUrl,\n} from '../lib/channels';\nimport { normalizeCheckoutUrl, warnOnCrossDomainCheckout } from '../lib/checkout-url';\nimport { NoLinkedProjectError } from '../lib/commerce-hosting';\nimport { runCreateChannelFlow } from '../lib/create-channel-flow';\nimport { parseEnvAssignment } from '../lib/env-config';\nimport { consola } from '../lib/logger';\nimport { LoginAbortedError, login as runInteractiveLogin } from '../lib/login';\nimport { getProjectConfig, type ProjectConfigSchema } from '../lib/project-config';\nimport { resolveCredentials } from '../lib/resolve-credentials';\nimport {\n accessTokenOption,\n apiHostOption,\n loginUrlOption,\n projectUuidOption,\n resolveApiHost,\n storeHashOption,\n} from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\nimport { writeEnv } from '../lib/write-env';\n\nconst parseChannelId = (value: string): number => {\n const parsed = Number.parseInt(value, 10);\n\n if (Number.isNaN(parsed)) {\n throw new InvalidArgumentError(`\"${value}\" is not a valid channel ID (expected a number).`);\n }\n\n return parsed;\n};\n\n// Adapts the shared normalizer to commander, which formats InvalidArgumentError\n// as an option-level usage error.\nconst parseCheckoutUrl = (value: string): string => {\n try {\n return normalizeCheckoutUrl(value);\n } catch (error) {\n throw new InvalidArgumentError(error instanceof Error ? error.message : String(error));\n }\n};\n\nconst CHECKOUT_URL_NOTES = `\nCheckout is hosted by BigCommerce, so a checkout URL must be a domain you have\npointed at BigCommerce with a certificate provisioned there — not one added with\n\\`catalyst domains add\\`, which only routes traffic to this project.\n\nBigCommerce also requires the checkout URL to share a main domain with the\nchannel's storefront URL, so that sessions carry between the two. This means a\ncustom checkout URL is only possible on a custom storefront domain; channels on\nan auto-generated deployment hostname use the shared checkout domain.`;\n\n// Resolve credentials from flags/env → persisted project config → interactive\n// login (persisting on success). Returns null when the user aborts login.\n// `channel link` is an onboarding command — a fresh clone has neither\n// .env.local nor .bigcommerce/project.json — so it logs the user in like\n// `catalyst projects create`, rather than erroring like the operational commands.\nasync function resolveCredentialsWithLogin(\n options: { storeHash?: string; accessToken?: string; loginUrl: string },\n config: Conf<ProjectConfigSchema>,\n apiHost: string,\n): Promise<{ storeHash: string; accessToken: string } | null> {\n const storeHash = options.storeHash ?? config.get('storeHash');\n const accessToken = options.accessToken ?? config.get('accessToken');\n\n if (storeHash && accessToken) {\n return { storeHash, accessToken };\n }\n\n try {\n const credentials = await runInteractiveLogin(options.loginUrl, apiHost);\n\n config.set('storeHash', credentials.storeHash);\n config.set('accessToken', credentials.accessToken);\n\n return credentials;\n } catch (error) {\n if (error instanceof LoginAbortedError) {\n return null;\n }\n\n throw error;\n }\n}\n\nconst update = new Command('update')\n .configureHelp({ showGlobalOptions: true })\n .description(\"Update a BigCommerce channel's storefront and checkout URLs.\")\n .addHelpText(\n 'after',\n `${CHECKOUT_URL_NOTES}\n\nWith no flags, this updates the storefront URL and prompts for the hostname.\nPass a checkout flag on its own to change only the checkout URL, leaving the\nstorefront URL alone.\n\nExamples:\n # Pick a channel and hostname interactively\n $ catalyst channels update\n\n # Point the storefront at a deployment hostname\n $ catalyst channels update --channel-id 123 --hostname my-storefront.example.com\n\n # Set both at once\n $ catalyst channels update --channel-id 123 --hostname my-storefront.example.com --checkout-url checkout.example.com\n\n # Change only the checkout URL\n $ catalyst channels update --channel-id 123 --checkout-url checkout.example.com\n\n # Fall back to the shared checkout domain\n $ catalyst channels update --channel-id 123 --remove-checkout-url`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .addOption(\n new Option(\n '--channel-id <id>',\n 'Skip the channel prompt and target this channel directly.',\n ).argParser((value: string) => Number(value)),\n )\n .addOption(\n new Option(\n '--hostname <hostname>',\n \"Skip the hostname prompt and use this hostname directly. Must be one of the project's deployment_hostnames.\",\n ),\n )\n .addOption(\n new Option(\n '--checkout-url <url>',\n \"Set the channel's checkout URL. Must share a main domain with the storefront URL.\",\n ).argParser(parseCheckoutUrl),\n )\n .addOption(\n new Option(\n '--remove-checkout-url',\n \"Remove the channel's custom checkout URL so checkout falls back to the shared checkout domain.\",\n ).conflicts('checkoutUrl'),\n )\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n // A checkout flag on its own means \"change only the checkout URL\": going\n // through the site-URL flow would prompt for a hostname the caller never\n // asked to change.\n const touchesCheckout = options.checkoutUrl !== undefined || options.removeCheckoutUrl === true;\n const updatesSiteUrl = options.hostname !== undefined || !touchesCheckout;\n // A site URL update deletes the checkout URL, so offer the managed-zone one next.\n const offersCheckout = updatesSiteUrl && !touchesCheckout && canPrompt();\n let channelId = options.channelId;\n let siteHostname: string | undefined;\n\n if (updatesSiteUrl) {\n try {\n ({ channelId, hostname: siteHostname } = await runChannelSiteUrlFlow({\n storeHash,\n accessToken,\n apiHost,\n projectUuid: options.projectUuid ?? config.get('projectUuid'),\n channelId: options.channelId,\n hostname: options.hostname,\n diagnoseCheckout: !offersCheckout,\n }));\n } catch (error) {\n if (error instanceof NoLinkedProjectError) {\n consola.info(\n \"When you're ready to create a project, run `catalyst projects create` or re-run `catalyst channels update`.\",\n );\n process.exit(0);\n\n // Unreachable in production; prevents continuation when process.exit is mocked in tests.\n return;\n }\n\n throw error;\n }\n }\n\n if (offersCheckout && channelId !== undefined && siteHostname !== undefined) {\n const offered = await offerManagedCheckoutUrl({\n storeHash,\n accessToken,\n apiHost,\n channelId,\n storefrontHostname: siteHostname,\n config,\n // Explicit command, so an earlier decline doesn't silence it.\n respectOptOut: false,\n defaultAnswer: true,\n });\n\n if (!offered) {\n warnOnCrossDomainCheckout(await getChannelSite(channelId, storeHash, accessToken, apiHost));\n }\n }\n\n if (touchesCheckout) {\n const channel =\n channelId === undefined\n ? await resolveChannel({ storeHash, accessToken, apiHost })\n : { id: channelId, name: undefined };\n const label = channel.name ? `\"${channel.name}\" (${channel.id})` : String(channel.id);\n\n if (options.checkoutUrl !== undefined) {\n const updated = await updateChannelCheckoutUrl(\n channel.id,\n options.checkoutUrl,\n storeHash,\n accessToken,\n apiHost,\n );\n\n consola.success(`Updated channel ${label} checkout URL to ${options.checkoutUrl}.`);\n reportChannelSite(updated);\n warnOnCrossDomainCheckout(updated);\n } else {\n await deleteChannelCheckoutUrl(channel.id, storeHash, accessToken, apiHost);\n\n consola.success(\n `Removed the custom checkout URL from channel ${label}. Checkout now uses the shared checkout domain.`,\n );\n\n // The fallback domain belongs to the default channel, so it can't be\n // known before the delete. Re-read the site to show where it landed, and\n // warn if that's a different domain than the storefront.\n const reverted = await getChannelSite(channel.id, storeHash, accessToken, apiHost);\n\n reportChannelSite(reverted);\n warnOnCrossDomainCheckout(reverted);\n }\n }\n\n process.exit(0);\n });\n\nconst link = new Command('link')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Link this Catalyst project to a BigCommerce channel and write its credentials to .env.local.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Pick a channel interactively (logs you in if needed)\n $ catalyst channels link\n\n # Non-interactive\n $ catalyst channels link --store-hash <hash> --access-token <token> --channel-id 123\n\n # Append extra environment variables to .env.local\n $ catalyst channels link --channel-id 123 --env MY_FLAG=1`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(loginUrlOption())\n .addOption(\n new Option('--channel-id <id>', 'Link this channel directly, skipping the picker.').argParser(\n parseChannelId,\n ),\n )\n .option(\n '--env <vars...>',\n 'Arbitrary environment variables to set in .env.local. Format: KEY=VALUE (repeatable).',\n )\n .addOption(\n new Option('--cli-api-origin <origin>', 'Catalyst CLI API origin')\n .default('https://cxm-prd.bigcommerceapp.com')\n .hideHelp(),\n )\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n const credentials = await resolveCredentialsWithLogin(options, config, apiHost);\n\n if (!credentials) {\n consola.info(\n 'Login aborted. Re-run `catalyst channels link` when you have your credentials ready.',\n );\n process.exit(0);\n\n return;\n }\n\n const { storeHash, accessToken } = credentials;\n\n await getTelemetry().identify(storeHash);\n\n let channelId = options.channelId;\n let channelName: string | undefined;\n\n if (channelId === undefined) {\n const availableChannels = await fetchAvailableChannels(storeHash, accessToken, apiHost);\n\n if (availableChannels.length === 0) {\n consola.info(\n 'No storefront channels found on this store. Create one with `catalyst create` and try again.',\n );\n process.exit(0);\n\n return;\n }\n\n channelId = await select({\n message: 'Which channel would you like to link?',\n choices: sortChannelsByPlatform(availableChannels).map((c) => ({\n name: c.name,\n value: c.id,\n description: channelPlatformLabel(c.platform),\n })),\n });\n\n channelName = availableChannels.find((c) => c.id === channelId)?.name;\n }\n\n const initData = await getChannelInit(channelId, storeHash, accessToken, options.cliApiOrigin);\n\n const envVars: Record<string, string> = { ...initData.envVars };\n\n // Inline `--env KEY=VALUE` overrides win over the channel-provided values.\n if (options.env) {\n options.env.forEach((entry) => {\n const { key, value } = parseEnvAssignment(entry);\n\n envVars[key] = value;\n });\n }\n\n // Writes .env.local in the current working directory — `channel link`\n // runs from inside `core/`, the same place `dev`/`build`/`deploy` run.\n writeEnv(process.cwd(), envVars);\n\n const label = channelName ? `\"${channelName}\" (${channelId})` : `${channelId}`;\n\n consola.success(\n `Linked to channel ${label} and wrote ${colorize('cyanBright', '.env.local')}.`,\n );\n consola.log(`Next steps:\\n\\n ${colorize('yellow', 'pnpm run dev')}`);\n\n process.exit(0);\n });\n\nconst create = new Command('create')\n .configureHelp({ showGlobalOptions: true })\n .description('Create a new Catalyst storefront channel on your BigCommerce store.')\n .addHelpText(\n 'after',\n `\nExamples:\n # Create a channel interactively (logs you in if needed)\n $ catalyst channels create\n\n # Non-interactive, and link it to this project afterwards\n $ catalyst channels create --name \"My Store\" --locale en --no-sample-data --link\n\n # Add additional storefront languages (max 4)\n $ catalyst channels create --name \"My Store\" --additional-locales es fr`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(loginUrlOption())\n .option('--name <name>', 'Name for the new channel. Skips the name prompt.')\n .option(\n '--locale <locale>',\n 'Default storefront locale (e.g. \"en\"). Skips the default-language prompt.',\n )\n .option(\n '--additional-locales <locales...>',\n 'Additional storefront locales, max 4 (e.g. --additional-locales es fr). Skips the additional-languages prompt.',\n )\n .addOption(new Option('--sample-data', 'Install sample data on the new channel.'))\n .addOption(new Option('--no-sample-data', 'Create the channel without sample data.'))\n .option(\n '--link',\n 'Link the new channel to this project — write its credentials to .env.local without prompting.',\n )\n .addOption(\n new Option('--cli-api-origin <origin>', 'Catalyst CLI API origin')\n .default('https://cxm-prd.bigcommerceapp.com')\n .hideHelp(),\n )\n .action(async (options) => {\n if (options.additionalLocales && options.additionalLocales.length > 4) {\n consola.error('You can only set up to 4 additional locales.');\n process.exit(1);\n\n return;\n }\n\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n const credentials = await resolveCredentialsWithLogin(options, config, apiHost);\n\n if (!credentials) {\n consola.info(\n 'Login aborted. Re-run `catalyst channels create` when you have your credentials ready.',\n );\n process.exit(0);\n\n return;\n }\n\n const { storeHash, accessToken } = credentials;\n\n await getTelemetry().identify(storeHash);\n\n const eligibility = await checkChannelEligibility(storeHash, accessToken, options.cliApiOrigin);\n\n if (!eligibility.eligible) {\n consola.warn(eligibility.message);\n process.exit(0);\n\n return;\n }\n\n const channelData = await runCreateChannelFlow({\n storeHash,\n accessToken,\n apiHost,\n cliApiOrigin: options.cliApiOrigin,\n name: options.name,\n locale: options.locale,\n additionalLocales: options.additionalLocales,\n sampleData: options.sampleData,\n });\n\n consola.success(`Created channel ${channelData.channelId}.`);\n consola.warn(\n 'A preview storefront has been deployed in your BigCommerce control panel. This preview may look different from your local environment as it may be running different code. Additionally, it may take a few minutes for the channel storefront to be accessible.',\n );\n\n // `--link` opts in non-interactively; otherwise ask before touching .env.local.\n const shouldLink = options.link\n ? true\n : await select({\n message: 'Would you like to link this channel to your project?',\n choices: [\n { name: 'Yes', value: true },\n { name: 'No', value: false },\n ],\n });\n\n if (shouldLink) {\n // Same write path as `channel link`: write the channel's credentials to\n // .env.local in the current working directory (where `dev`/`build`/`deploy` run).\n writeEnv(process.cwd(), channelData.envVars);\n\n consola.success(\n `Linked to channel ${channelData.channelId} and wrote ${colorize('cyanBright', '.env.local')}.`,\n );\n consola.log(`Next steps:\\n\\n ${colorize('yellow', 'pnpm run dev')}`);\n }\n\n process.exit(0);\n });\n\nconst CHECKOUT_LABEL_WIDTH = 'Storefront'.length;\n\nconst row = (label: string, value: string) => ` ${label.padEnd(CHECKOUT_LABEL_WIDTH)} ${value}`;\n\n// `primary` is the merchant-facing storefront, `canonical` BigCommerce's own\n// permanent address, `checkout` where hosted checkout lives — easy to conflate\n// when debugging a redirect.\nfunction reportChannelSite(site: ChannelSiteDetails): void {\n const canonical = findChannelSiteUrl(site, 'canonical');\n const checkout = findChannelSiteUrl(site, 'checkout');\n\n consola.log(row('Storefront', findChannelSiteUrl(site, 'primary') ?? site.url));\n\n if (canonical) {\n consola.log(row('Canonical', canonical));\n }\n\n consola.log(row('Checkout', checkout ?? '(none)'));\n\n if (!site.isCheckoutUrlCustomized) {\n consola.info(\n 'This channel has no checkout URL of its own, so checkout uses the default ' +\n \"channel's primary URL.\",\n );\n }\n}\n\ninterface ChannelTargetOptions {\n storeHash?: string;\n accessToken?: string;\n apiHost?: string;\n channelId?: number;\n}\n\n// Resolves credentials and the target channel — the preamble every\n// channel-scoped command below shares.\nasync function resolveChannelTarget(options: ChannelTargetOptions) {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n const channel = await resolveChannel({\n storeHash,\n accessToken,\n apiHost,\n channelId: options.channelId,\n // Read-only: these commands report on a channel, so the picker must not\n // say \"to update\" — the shared default is written for `channels update`.\n message: 'Select a channel.',\n });\n\n return {\n config,\n apiHost,\n storeHash,\n accessToken,\n channel,\n label: channel.name ? `\"${channel.name}\" (${channel.id})` : String(channel.id),\n };\n}\n\nconst info = new Command('info')\n .configureHelp({ showGlobalOptions: true })\n .description(\"Show a channel's site URLs — storefront, canonical and checkout.\")\n .addHelpText(\n 'after',\n `${CHECKOUT_URL_NOTES}\n\nExamples:\n # Pick a channel interactively; the same as bare \\`catalyst channels\\`\n $ catalyst channels info\n\n # Target a channel directly\n $ catalyst channels info --channel-id 123`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(\n new Option(\n '--channel-id <id>',\n 'Skip the channel prompt and target this channel directly.',\n ).argParser(parseChannelId),\n )\n .action(async (options: ChannelTargetOptions) => {\n const { apiHost, storeHash, accessToken, channel, label } = await resolveChannelTarget(options);\n\n consola.start('Fetching channel site...');\n\n const site = await getChannelSite(channel.id, storeHash, accessToken, apiHost);\n\n consola.success(`Channel ${label}:`);\n reportChannelSite(site);\n\n const report = warnOnCrossDomainCheckout(site);\n\n // The channel and site are already in hand, so offer to fix it rather than\n // making the user re-run `channels update --checkout-url`. Not on a managed\n // zone, where the diagnostic printed the command, nor without a TTY.\n if (report.crossDomain && report.storefrontOnManagedZone !== true) {\n const suggested = report.suggestion ?? '<domain>';\n\n if (!process.stdin.isTTY) {\n consola.info(\n `Set one with \\`catalyst channels update --channel-id ${channel.id} --checkout-url ${suggested}\\`.`,\n );\n process.exit(0);\n\n return;\n }\n\n const shouldSet = await confirm({\n message: 'Set a checkout URL for this channel now?',\n default: true,\n });\n\n if (shouldSet) {\n await runChannelCheckoutUrlFlow({\n storeHash,\n accessToken,\n apiHost,\n // Already chosen above; don't ask again.\n channelId: channel.id,\n channelName: channel.name,\n storefrontUrl: findChannelSiteUrl(site, 'primary') ?? site.url,\n });\n\n process.exit(0);\n\n return;\n }\n\n consola.info(\n `When you're ready, run \\`catalyst channels update --channel-id ${channel.id} --checkout-url <domain>\\`.`,\n );\n }\n\n process.exit(0);\n });\n\n// Resource commands are plural; the singular form stays as an alias so existing\n// scripts and muscle memory keep working.\nexport const channels = new Command('channels')\n .alias('channel')\n .configureHelp({ showGlobalOptions: true })\n .description('Manage BigCommerce channels.')\n // `info` is the default so bare `catalyst channels` reports the current\n // state, matching how `logs` defaults to `tail`.\n .addCommand(info, { isDefault: true })\n .addCommand(create)\n .addCommand(link)\n .addCommand(update);\n","// Whether an unrequested question can be asked. Also checks `CI`: some CI\n// setups allocate a pseudo-terminal, where a prompt would hang the job.\nexport function canPrompt(): boolean {\n return Boolean(process.stdin.isTTY) && !process.env.CI;\n}\n","import { confirm, input } from '@inquirer/prompts';\n\nimport { resolveChannel } from './channel-site-flow';\nimport {\n deleteChannelCheckoutUrl,\n findChannelSiteUrl,\n getChannelSite,\n updateChannelCheckoutUrl,\n} from './channels';\nimport {\n hostnameOf,\n isCrossDomainCheckout,\n isManagedHostingHostname,\n MANAGED_ZONE_CHECKOUT_PREFIX,\n managedCheckoutHostname,\n normalizeCheckoutUrl,\n suggestCheckoutUrl,\n waitForCheckoutHostname,\n warnOnCrossDomainCheckout,\n} from './checkout-url';\nimport { consola } from './logger';\nimport { type getProjectConfig } from './project-config';\n\nexport interface ChannelCheckoutUrlFlowOptions {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n // Non-interactive overrides. When supplied, the corresponding prompt is\n // skipped.\n channelId?: number;\n url?: string;\n // Set by a caller that already resolved the channel and fetched the site, so\n // the flow neither re-prompts nor re-reads.\n channelName?: string;\n storefrontUrl?: string;\n // On a managed zone the checkout hostname follows from this, so no prompt.\n storefrontHostname?: string;\n // Defaults to when BigCommerce stops trying to issue the certificate.\n certificateTimeoutMs?: number;\n}\n\n// Prompts for a checkout URL and writes it.\n//\n// Unlike a site URL this can't be derived from the deployment: BigCommerce —\n// not this project's worker — serves checkout, so the domain must already point\n// there with a certificate. Defaults to the `checkout.` subdomain of the\n// storefront, which the same-main-domain rule makes the near-certain answer.\nexport async function runChannelCheckoutUrlFlow(\n options: ChannelCheckoutUrlFlowOptions,\n): Promise<void> {\n const channel =\n options.channelId !== undefined\n ? { id: options.channelId, name: options.channelName }\n : await resolveChannel(options);\n const label = channel.name ? `\"${channel.name}\" (${channel.id})` : String(channel.id);\n\n if (\n options.storefrontHostname !== undefined &&\n (await setManagedCheckoutUrl({\n ...options,\n channelId: channel.id,\n label,\n storefrontHostname: options.storefrontHostname,\n timeoutMs: options.certificateTimeoutMs,\n }))\n ) {\n return;\n }\n\n let storefrontUrl = options.storefrontUrl;\n\n // The storefront URL only feeds the prompt default, so skip the read when the\n // caller already has it.\n if (!storefrontUrl) {\n const site = await getChannelSite(\n channel.id,\n options.storeHash,\n options.accessToken,\n options.apiHost,\n );\n\n storefrontUrl = findChannelSiteUrl(site, 'primary') ?? site.url;\n\n const currentCheckoutUrl = findChannelSiteUrl(site, 'checkout');\n\n consola.info(`Channel ${label} storefront is ${storefrontUrl}.`);\n\n if (currentCheckoutUrl) {\n consola.info(\n `Checkout is currently ${currentCheckoutUrl}${\n site.isCheckoutUrlCustomized ? '' : ', inherited from the default channel'\n }.`,\n );\n }\n }\n\n // Called without the hostname, e.g. `deploy --update-checkout-url` alone, a\n // managed-zone storefront still has nothing to ask. An explicit URL is\n // written as given.\n const storefrontHostname = hostnameOf(storefrontUrl);\n\n if (\n options.url === undefined &&\n options.storefrontHostname === undefined &&\n storefrontHostname !== undefined &&\n (await setManagedCheckoutUrl({\n ...options,\n channelId: channel.id,\n label,\n storefrontHostname,\n timeoutMs: options.certificateTimeoutMs,\n }))\n ) {\n return;\n }\n\n const answer =\n options.url ??\n (await input({\n message: 'Checkout URL for this channel (must share a main domain with the storefront)',\n default: suggestCheckoutUrl(storefrontUrl),\n }));\n\n const checkoutUrl = normalizeCheckoutUrl(answer);\n\n await updateChannelCheckoutUrl(\n channel.id,\n checkoutUrl,\n options.storeHash,\n options.accessToken,\n options.apiHost,\n );\n\n consola.success(`Updated channel ${label} checkout URL to ${checkoutUrl}.`);\n}\n\ninterface ManagedCheckoutUrlOptions {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n channelId: number;\n label: string;\n storefrontHostname: string;\n timeoutMs?: number;\n}\n\n// Points a managed-zone storefront's channel at its `c.` checkout hostname.\n// Writes first, since the write is what provisions the hostname, then waits\n// for the certificate and undoes the write if none issues. Resolves false off\n// the managed zone, so the caller prompts instead.\nasync function setManagedCheckoutUrl(options: ManagedCheckoutUrlOptions): Promise<boolean> {\n const { storeHash, accessToken, apiHost, channelId, label, storefrontHostname } = options;\n\n // On a custom domain the `c.` subdomain is the merchant's DNS, not ours.\n if (!isManagedHostingHostname(storefrontHostname)) return false;\n\n const hostname = managedCheckoutHostname(storefrontHostname);\n\n if (!hostname) {\n consola.warn(\n `${storefrontHostname} is too long to take a checkout prefix, so it has no checkout ` +\n 'hostname. Checkout keeps its current URL.',\n );\n\n return true;\n }\n\n const checkoutUrl = `https://${hostname}`;\n const site = await getChannelSite(channelId, storeHash, accessToken, apiHost);\n\n if (site.isCheckoutUrlCustomized) {\n // Already set: writing it again would hit `canonical-in-use`.\n const alreadySet = site.urls.some(\n (entry) => entry.type === 'checkout' && entry.url.replace(/\\/$/, '') === checkoutUrl,\n );\n\n if (!alreadySet) {\n consola.info(\n `Channel ${label} already has a custom checkout URL, so it was left alone. To replace ` +\n `it, run \\`catalyst channels update --channel-id ${channelId} --checkout-url ${checkoutUrl}\\`.`,\n );\n\n return true;\n }\n } else {\n await updateChannelCheckoutUrl(channelId, checkoutUrl, storeHash, accessToken, apiHost);\n consola.success(`Updated channel ${label} checkout URL to ${checkoutUrl}.`);\n }\n\n const ready = await waitForCheckoutHostname(hostname, {\n timeoutMs: options.timeoutMs,\n onWait: () =>\n consola.info(\n `Waiting for ${hostname} to be issued a certificate. This usually takes a minute or two...`,\n ),\n });\n\n if (ready) {\n consola.success(`${hostname} is serving checkout.`);\n\n return true;\n }\n\n await deleteChannelCheckoutUrl(channelId, storeHash, accessToken, apiHost);\n consola.warn(\n `${hostname} wasn't issued a certificate in time, so the checkout URL was removed and ` +\n \"checkout falls back to the default channel's. Re-run with `--update-checkout-url` to \" +\n 'try again.',\n );\n\n return true;\n}\n\nexport interface ManagedCheckoutOfferOptions {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n channelId: number;\n // The storefront hostname the channel's primary URL is on.\n storefrontHostname: string;\n config: ReturnType<typeof getProjectConfig>;\n // Honour a saved decline. Off for explicit commands.\n respectOptOut: boolean;\n // What Enter answers. No after a deploy, where the offer wasn't asked for.\n defaultAnswer: boolean;\n}\n\n// Offers to move a managed-zone storefront's checkout onto its `c.` hostname.\n// Never replaces a merchant's own custom checkout URL. Resolves whether it\n// asked, so an explicit command can fall back to the cross-domain warning.\nexport async function offerManagedCheckoutUrl(\n options: ManagedCheckoutOfferOptions,\n): Promise<boolean> {\n const { storeHash, accessToken, apiHost, channelId, storefrontHostname, config } = options;\n const declined = config.get('declinedCheckoutUrlChannels') ?? [];\n\n if (!isManagedHostingHostname(storefrontHostname)) return false;\n if (options.respectOptOut && declined.includes(channelId)) return false;\n\n const site = await getChannelSite(channelId, storeHash, accessToken, apiHost);\n\n if (site.isCheckoutUrlCustomized || !isCrossDomainCheckout(site)) return false;\n\n const shouldMove = await confirm({\n message:\n `Checkout is on ${findChannelSiteUrl(site, 'checkout') ?? 'another domain'}. Move it to ` +\n `https://${MANAGED_ZONE_CHECKOUT_PREFIX}${storefrontHostname} so shoppers stay on this ` +\n 'domain through payment?',\n default: options.defaultAnswer,\n });\n\n if (!shouldMove) {\n if (!declined.includes(channelId)) {\n config.set('declinedCheckoutUrlChannels', [...declined, channelId]);\n }\n\n warnOnCrossDomainCheckout(site);\n consola.info(\n `Won't ask again after deploys for channel ${channelId}. To set it later, run ` +\n `\\`catalyst channels update --channel-id ${channelId} --checkout-url ` +\n `https://${MANAGED_ZONE_CHECKOUT_PREFIX}${storefrontHostname}\\`.`,\n );\n\n return true;\n }\n\n await runChannelCheckoutUrlFlow({\n storeHash,\n accessToken,\n apiHost,\n channelId,\n storefrontHostname,\n });\n\n return true;\n}\n","import { select } from '@inquirer/prompts';\n\nimport {\n type Channel,\n fetchAvailableChannels,\n findChannelSiteUrl,\n getChannelSite,\n updateChannelSiteUrl,\n} from './channels';\nimport { warnOnCrossDomainCheckout } from './checkout-url';\nimport { selectOrCreateInfrastructureProject } from './commerce-hosting';\nimport { consola } from './logger';\nimport { fetchProjects, type ProjectListItem } from './project';\n\nexport interface ChannelSiteFlowOptions {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n // Linked project UUID (from --project-uuid or .bigcommerce/project.json). When\n // present and resolvable, skips the project picker; otherwise falls back to\n // `selectOrCreateInfrastructureProject`, which may throw NoLinkedProjectError\n // (caller decides how to surface it).\n projectUuid?: string;\n // Non-interactive overrides. When supplied, the corresponding prompt is\n // skipped.\n channelId?: number;\n hostname?: string;\n // When set, this hostname is pre-selected in the hostname prompt. Used by\n // `catalyst deploy --update-site-url` to default to the freshly-deployed\n // hostname.\n preferHostname?: string;\n // Warn if checkout is left on another domain. Off when the caller offers a fix next.\n diagnoseCheckout?: boolean;\n}\n\nasync function resolveProject(options: ChannelSiteFlowOptions): Promise<ProjectListItem> {\n const api = {\n storeHash: options.storeHash,\n accessToken: options.accessToken,\n apiHost: options.apiHost,\n };\n\n if (options.projectUuid) {\n const projects = await fetchProjects(api.storeHash, api.accessToken, api.apiHost);\n const matched = projects.find((p) => p.uuid === options.projectUuid);\n\n if (matched) return matched;\n\n consola.warn(\n `Project ${options.projectUuid} not found on this store. Pick another to continue.`,\n );\n }\n\n return selectOrCreateInfrastructureProject(api, options.projectUuid);\n}\n\n// Exported so `channels info` and `channels update` resolve channels the same\n// way rather than re-deriving the Catalyst-platform filter and its error copy.\nexport async function resolveChannel(options: {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n channelId?: number;\n // Overrides the picker copy for callers that aren't about to write anything —\n // `channels info` only reads, so \"to update\" would misdescribe it.\n message?: string;\n}): Promise<{ id: number; name?: string }> {\n if (options.channelId !== undefined) {\n return { id: options.channelId };\n }\n\n consola.start('Fetching channels...');\n\n const channels = await fetchAvailableChannels(\n options.storeHash,\n options.accessToken,\n options.apiHost,\n );\n\n consola.success('Channels fetched.');\n\n // Only Catalyst-platform channels can meaningfully be pointed at a Catalyst\n // deployment hostname; other storefront platforms (Stencil, etc.) are\n // filtered out so the picker stays focused.\n const catalystChannels = channels.filter((c: Channel) => c.platform === 'catalyst');\n\n if (catalystChannels.length === 0) {\n throw new Error(\n 'No Catalyst channels found on this store. Create one with `catalyst create` and try again.',\n );\n }\n\n const id = await select({\n message: options.message ?? 'Select the channel to update.',\n choices: catalystChannels.map((c: Channel) => ({\n name: c.name,\n value: c.id,\n description: `id: ${c.id}`,\n })),\n });\n\n const matched = catalystChannels.find((c) => c.id === id);\n\n return { id, name: matched?.name };\n}\n\nasync function resolveHostname(\n project: ProjectListItem,\n options: ChannelSiteFlowOptions,\n): Promise<string> {\n if (options.hostname) {\n return options.hostname;\n }\n\n if (project.deployment_hostnames.length === 0) {\n throw new Error(\n `Project \"${project.name}\" has no deployment hostnames yet. Run \\`catalyst deploy\\` first to create one.`,\n );\n }\n\n // When the caller knows which hostname they want surfaced first (e.g. the\n // freshly-deployed one from `catalyst deploy --update-site-url`), order it to\n // the top of the list so it's the default selection.\n const ordered = options.preferHostname\n ? [\n ...project.deployment_hostnames.filter((h) => h === options.preferHostname),\n ...project.deployment_hostnames.filter((h) => h !== options.preferHostname),\n ]\n : project.deployment_hostnames;\n\n const selected = await select({\n message: 'Select the hostname to point the channel at.',\n choices: ordered.map((h) => ({ name: h, value: h })),\n });\n\n return selected;\n}\n\nexport interface ChannelSiteFlowResult {\n channelId: number;\n // The hostname the site URL was set to, so a checkout step can pair with it.\n hostname: string;\n}\n\nexport async function runChannelSiteUrlFlow(\n options: ChannelSiteFlowOptions,\n): Promise<ChannelSiteFlowResult> {\n const project = await resolveProject(options);\n const channel = await resolveChannel(options);\n const hostname = await resolveHostname(project, options);\n const siteUrl = hostname.startsWith('https://') ? hostname : `https://${hostname}`;\n const channelLabel = channel.name ? `\"${channel.name}\" (${channel.id})` : String(channel.id);\n\n // Skip an unchanged site URL: sites-service deletes the checkout URL on every\n // site URL update, so re-sending it would drop the `c.` hostname. Best-effort:\n // if the read fails, write anyway.\n const current = await getChannelSite(\n channel.id,\n options.storeHash,\n options.accessToken,\n options.apiHost,\n ).catch(() => undefined);\n\n if (\n current &&\n (findChannelSiteUrl(current, 'primary') ?? current.url).replace(/\\/$/, '') === siteUrl\n ) {\n consola.info(`Channel ${channelLabel} site URL is already ${siteUrl}.`);\n } else {\n await updateChannelSiteUrl(\n channel.id,\n siteUrl,\n options.storeHash,\n options.accessToken,\n options.apiHost,\n );\n\n consola.success(`Updated channel ${channelLabel} site URL to ${siteUrl}.`);\n }\n\n // Moving the site URL is when checkout is most likely left behind. The PUT\n // response above carries no `urls`, hence the re-fetch. Soft-failed: the write\n // already succeeded, so a failed diagnostic mustn't look like a failed write.\n if (options.diagnoseCheckout === false) return { channelId: channel.id, hostname };\n\n try {\n const site = await getChannelSite(\n channel.id,\n options.storeHash,\n options.accessToken,\n options.apiHost,\n );\n\n const report = warnOnCrossDomainCheckout(site);\n\n // Can run mid-deploy, so it prints a command rather than prompting. Not on a\n // managed zone, where the diagnostic already printed one.\n if (report.crossDomain && report.storefrontOnManagedZone !== true) {\n consola.info('Set a checkout URL for this channel with:');\n consola.log(\n ` catalyst channels update --channel-id ${channel.id}` +\n ` --checkout-url ${report.suggestion ?? '<domain>'}`,\n );\n }\n } catch {\n // Diagnostics are advisory; the write above succeeded.\n }\n\n // Returned so a caller running several channel flows back to back — `channels\n // update --hostname --checkout-url`, or `deploy --update-site-url\n // --update-checkout-url` — reuses this channel instead of resolving it twice.\n return { channelId: channel.id, hostname };\n}\n","import { z } from 'zod';\n\nimport { assertAuthorized } from './auth-errors';\nimport { UserActionableError } from './errors';\nimport { httpError } from './http-errors';\nimport { getTelemetry } from './telemetry';\n\n// `origin` is the CLI-API gateway (configured via `--cli-api-origin`, default\n// `https://cxm-prd.bigcommerceapp.com`). Distinct from `apiHost` used for the\n// BC store API (api.bigcommerce.com).\nconst cliApiUrl = (origin: string, storeHash: string, path: string) =>\n `${origin}/stores/${storeHash}/cli-api/v3${path}`;\n\nconst channelsUrl = (storeHash: string, apiHost: string, query: Record<string, string> = {}) => {\n const params = new URLSearchParams(query).toString();\n\n return `https://${apiHost}/stores/${storeHash}/v3/channels${params ? `?${params}` : ''}`;\n};\n\nconst authHeaders = (accessToken: string) => ({\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n Accept: 'application/json',\n});\n\n// envVars values are coerced to strings: the BC API returns mixed primitives\n// (e.g. BIGCOMMERCE_CHANNEL_ID is a number) but they all end up in .env.local as text.\nconst envVarsSchema = z.record(z.string(), z.coerce.string());\n\nconst channelSchema = z.object({\n id: z.number(),\n name: z.string(),\n platform: z.string(),\n});\n\nexport type Channel = z.infer<typeof channelSchema>;\n\nconst channelsResponseSchema = z.object({\n data: z.array(channelSchema),\n});\n\n// Channels are surfaced Catalyst-first, then Next, then Stencil\n// (`bigcommerce`), then anything else — the order the `create` and\n// `channel link` pickers both present. Returns a sorted copy.\nconst CHANNEL_PLATFORM_ORDER = ['catalyst', 'next', 'bigcommerce'];\n\nexport function sortChannelsByPlatform(channels: Channel[]): Channel[] {\n return [...channels].sort((a, b) => {\n const aIndex = CHANNEL_PLATFORM_ORDER.indexOf(a.platform);\n const bIndex = CHANNEL_PLATFORM_ORDER.indexOf(b.platform);\n\n if (aIndex === -1 && bIndex === -1) return 0;\n if (aIndex === -1) return 1;\n if (bIndex === -1) return -1;\n\n return aIndex - bIndex;\n });\n}\n\n// Human-friendly platform name for channel pickers. `bigcommerce` is the\n// Stencil storefront platform; everything else is title-cased.\nexport function channelPlatformLabel(platform: string): string {\n return platform === 'bigcommerce'\n ? 'Stencil'\n : platform.charAt(0).toUpperCase() + platform.slice(1);\n}\n\nconst initResponseSchema = z.object({\n data: z.object({\n storefront_api_token: z.string(),\n envVars: envVarsSchema,\n }),\n});\n\nconst createChannelResponseSchema = z.object({\n data: z.object({\n id: z.number(),\n storefront_api_token: z.string(),\n envVars: envVarsSchema,\n }),\n});\n\nconst eligibilityResponseSchema = z.object({\n data: z.object({\n eligible: z.boolean(),\n message: z.string(),\n }),\n});\n\n// `type` is a plain string, not an enum: the API documents\n// `primary | canonical | checkout`, but an unrecognised role shouldn't crash a\n// diagnostic read.\nconst siteUrlSchema = z.object({\n url: z.string(),\n type: z.string(),\n});\n\n// `ssl_status` is documented `dedicated | shared` but comes back null on shared\n// SSL. The rest are optional because the narrower `PUT .../site` response omits\n// them.\nconst channelSiteSchema = z.object({\n data: z.object({\n id: z.number(),\n url: z.string(),\n channel_id: z.number(),\n ssl_status: z.string().nullable().optional(),\n is_checkout_url_customized: z.boolean().optional(),\n urls: z.array(siteUrlSchema).optional(),\n }),\n});\n\n// Tokens minted before `store_channel_settings`/`store_sites` joined\n// `DEVICE_OAUTH_SCOPES` 401/403 here, and re-login is the only recovery — so say\n// that rather than surfacing a bare status.\nfunction assertChannelSettingsAuthorized(response: Response, action: string): void {\n if (response.status === 401 || response.status === 403) {\n throw new UserActionableError(\n `${action} (${response.status}). Re-run \\`catalyst auth login\\` to refresh your access token with the store_channel_settings and store_sites scopes.`,\n );\n }\n}\n\nexport interface ChannelInit {\n storefrontToken: string;\n envVars: Record<string, string>;\n}\n\nexport async function getChannelInit(\n channelId: number | string,\n storeHash: string,\n accessToken: string,\n origin: string,\n): Promise<ChannelInit> {\n const response = await fetch(cliApiUrl(origin, storeHash, `/channels/${channelId}/init`), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to initialize channel');\n }\n\n const { data } = initResponseSchema.parse(await response.json());\n\n return { storefrontToken: data.storefront_api_token, envVars: data.envVars };\n}\n\nexport interface ChannelEligibility {\n eligible: boolean;\n message: string;\n}\n\nexport async function checkChannelEligibility(\n storeHash: string,\n accessToken: string,\n origin: string,\n): Promise<ChannelEligibility> {\n const response = await fetch(cliApiUrl(origin, storeHash, '/channels/catalyst/eligibility'), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to check Catalyst eligibility');\n }\n\n return eligibilityResponseSchema.parse(await response.json()).data;\n}\n\nexport interface CreatedChannel {\n channelId: number;\n storefrontToken: string;\n envVars: Record<string, string>;\n}\n\nexport async function createChannel(\n name: string,\n storefrontLocale: string,\n additionalLocales: string[],\n installSampleData: boolean,\n storeHash: string,\n accessToken: string,\n origin: string,\n): Promise<CreatedChannel> {\n const response = await fetch(cliApiUrl(origin, storeHash, '/channels/catalyst'), {\n method: 'POST',\n headers: { ...authHeaders(accessToken), 'Content-Type': 'application/json' },\n body: JSON.stringify({\n name,\n initialData: { type: installSampleData ? 'sample' : 'none' },\n deployStorefront: true,\n devOrigin: 'http://localhost:3000',\n storefrontLanguage: storefrontLocale,\n additionalLocales,\n }),\n });\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to create channel');\n }\n\n const { data } = createChannelResponseSchema.parse(await response.json());\n\n return {\n channelId: data.id,\n storefrontToken: data.storefront_api_token,\n envVars: data.envVars,\n };\n}\n\nexport async function fetchAvailableChannels(\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<Channel[]> {\n const response = await fetch(\n channelsUrl(storeHash, apiHost, { available: 'true', type: 'storefront' }),\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n Accept: 'application/json',\n },\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch channels');\n }\n\n return channelsResponseSchema.parse(await response.json()).data;\n}\n\nexport interface ChannelSite {\n id: number;\n url: string;\n channelId: number;\n}\n\nexport async function updateChannelSiteUrl(\n channelId: number,\n siteUrl: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<ChannelSite> {\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/channels/${channelId}/site`,\n {\n method: 'PUT',\n headers: {\n 'X-Auth-Token': accessToken,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'X-Correlation-Id': getTelemetry().correlationId,\n },\n body: JSON.stringify({ url: siteUrl }),\n },\n );\n\n assertChannelSettingsAuthorized(response, 'Failed to update channel site');\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to update channel site');\n }\n\n const res: unknown = await response.json();\n const { data } = channelSiteSchema.parse(res);\n\n return { id: data.id, url: data.url, channelId: data.channel_id };\n}\n\nexport interface ChannelSiteUrl {\n url: string;\n type: string;\n}\n\nexport interface ChannelSiteDetails extends ChannelSite {\n sslStatus: string | null;\n // When false, BigCommerce falls back to the *default* channel's primary URL —\n // not this channel's — which can silently put checkout on an unrelated domain.\n isCheckoutUrlCustomized: boolean;\n urls: ChannelSiteUrl[];\n}\n\nconst toChannelSiteDetails = (\n data: z.infer<typeof channelSiteSchema>['data'],\n): ChannelSiteDetails => ({\n id: data.id,\n url: data.url,\n channelId: data.channel_id,\n sslStatus: data.ssl_status ?? null,\n isCheckoutUrlCustomized: data.is_checkout_url_customized ?? false,\n urls: data.urls ?? [],\n});\n\nexport function findChannelSiteUrl(site: ChannelSiteDetails, type: string): string | undefined {\n return site.urls.find((entry) => entry.type === type)?.url;\n}\n\nexport async function getChannelSite(\n channelId: number,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<ChannelSiteDetails> {\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/channels/${channelId}/site`,\n { method: 'GET', headers: authHeaders(accessToken) },\n );\n\n assertChannelSettingsAuthorized(response, 'Failed to fetch channel site');\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch channel site');\n }\n\n const res: unknown = await response.json();\n\n return toChannelSiteDetails(channelSiteSchema.parse(res).data);\n}\n\n// Channel-scoped and hyphenated. The headless guide's `/sites/{site_id}/checkout_url`\n// is wrong; the OpenAPI spec and API reference both use this form.\nconst checkoutUrlPath = (storeHash: string, apiHost: string, channelId: number) =>\n `https://${apiHost}/stores/${storeHash}/v3/channels/${channelId}/site/checkout-url`;\n\n// BigCommerce requires the checkout URL to share a main domain with the\n// storefront and 422s otherwise. Not pre-validated here: the registrable domain\n// needs the public suffix list, and a wrong local check would block a valid\n// setup. `httpError` surfaces the API's own explanation instead.\nexport async function updateChannelCheckoutUrl(\n channelId: number,\n checkoutUrl: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<ChannelSiteDetails> {\n const response = await fetch(checkoutUrlPath(storeHash, apiHost, channelId), {\n method: 'PUT',\n headers: { ...authHeaders(accessToken), 'Content-Type': 'application/json' },\n body: JSON.stringify({ url: checkoutUrl }),\n });\n\n assertChannelSettingsAuthorized(response, 'Failed to update channel checkout URL');\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to update channel checkout URL');\n }\n\n const res: unknown = await response.json();\n\n return toChannelSiteDetails(channelSiteSchema.parse(res).data);\n}\n\n// Drops the channel back to the shared checkout domain. No useful response body.\nexport async function deleteChannelCheckoutUrl(\n channelId: number,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<void> {\n const response = await fetch(checkoutUrlPath(storeHash, apiHost, channelId), {\n method: 'DELETE',\n headers: authHeaders(accessToken),\n });\n\n assertChannelSettingsAuthorized(response, 'Failed to remove channel checkout URL');\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to remove channel checkout URL');\n }\n}\n","import { getDomain } from 'tldts';\n\nimport { type ChannelSiteDetails, findChannelSiteUrl } from './channels';\nimport { UserActionableError } from './errors';\nimport { consola } from './logger';\n\nconst normalizeHostname = (hostname: string) => hostname.toLowerCase().replace(/\\.$/, '');\n\nconst isSubdomainOf = (hostname: string, parent: string) => hostname.endsWith(`.${parent}`);\n\nexport function hostnameOf(url: string): string | undefined {\n try {\n return new URL(url).hostname;\n } catch {\n return undefined;\n }\n}\n\n// Whether two hostnames share a registrable domain — the relationship\n// BigCommerce requires between a channel's storefront and its checkout URL.\n//\n// Uses the public suffix list rather than comparing labels. BigCommerce does a\n// real registrable-domain comparison, which a hand-rolled rule can't match:\n// `store-x.example.store` and `store-x.c.example.store` share a registrable\n// domain and the API accepts that pairing, while `example.co.uk` and\n// `other.co.uk` do not. Every label-counting approximation gets one of those\n// two wrong, and being wrong here means telling a merchant to replace a working\n// checkout URL.\n//\n// `getDomain` returns null for a hostname with no registrable domain (an IP, or\n// a bare public suffix), which counts as not sharing.\nexport function sharesMainDomain(a: string, b: string): boolean {\n const first = getDomain(normalizeHostname(a));\n\n return first !== null && first === getDomain(normalizeHostname(b));\n}\n\n// Checkout hostname prefix on a managed zone. Short because it counts against\n// Cloudflare's 64-character certificate name limit.\nexport const MANAGED_ZONE_CHECKOUT_PREFIX = 'c.';\n\n// Longest name Cloudflare will issue a certificate for (RFC 5280).\nconst MAX_HOSTNAME_LENGTH = 64;\n\n// BigCommerce stops trying to issue the certificate after about six minutes\n// (a 60s delay, then 10 retries at 30s).\nconst CHECKOUT_HOSTNAME_READY_TIMEOUT_MS = 6 * 60 * 1000;\nconst CHECKOUT_HOSTNAME_POLL_INTERVAL_MS = 10 * 1000;\n\n// The checkout hostname for a managed-zone storefront, or undefined when it\n// would exceed the certificate name limit (older, longer hostnames).\nexport function managedCheckoutHostname(storefrontHostname: string): string | undefined {\n const hostname = MANAGED_ZONE_CHECKOUT_PREFIX + normalizeHostname(storefrontHostname);\n\n return hostname.length <= MAX_HOSTNAME_LENGTH ? hostname : undefined;\n}\n\n// Whether the hostname serves a certificate a client accepts. Any HTTP\n// response means the handshake worked; a bad certificate or name throws.\nasync function checkoutHostnameIsServing(hostname: string): Promise<boolean> {\n try {\n await fetch(`https://${hostname}/`, {\n method: 'HEAD',\n redirect: 'manual',\n signal: AbortSignal.timeout(10_000),\n });\n\n return true;\n } catch {\n return false;\n }\n}\n\n// Waits for a newly provisioned checkout hostname's certificate.\nexport async function waitForCheckoutHostname(\n hostname: string,\n { timeoutMs = CHECKOUT_HOSTNAME_READY_TIMEOUT_MS, onWait }: CheckoutHostnameWaitOptions = {},\n): Promise<boolean> {\n const deadline = Date.now() + timeoutMs;\n let waited = false;\n\n for (;;) {\n // One probe at a time: each asks whether the certificate has issued yet.\n // eslint-disable-next-line no-await-in-loop\n if (await checkoutHostnameIsServing(hostname)) return true;\n\n if (Date.now() + CHECKOUT_HOSTNAME_POLL_INTERVAL_MS >= deadline) return false;\n\n if (!waited) {\n waited = true;\n onWait?.();\n }\n\n // eslint-disable-next-line no-await-in-loop\n await new Promise((resolve) => setTimeout(resolve, CHECKOUT_HOSTNAME_POLL_INTERVAL_MS));\n }\n}\n\nexport interface CheckoutHostnameWaitOptions {\n timeoutMs?: number;\n // Called once, before the first wait, so the caller can explain the pause.\n onWait?: () => void;\n}\n\n// The checkout subdomain a merchant most likely wants:\n// `https://www.example.com` → `https://checkout.example.com`.\n//\n// Strips only a leading `www.`. Reducing to the last two labels would suggest\n// `https://checkout.co.uk` for a storefront on `www.example.co.uk`; prefixing\n// the host as-is can never produce a bare public suffix and always satisfies\n// the same-main-domain rule. Pre-fills an editable prompt, so a bad URL just\n// means no suggestion.\n//\n// `managedZone` suggests the `c.` hostname native hosting uses instead.\nexport function suggestCheckoutUrl(\n storefrontUrl: string,\n { managedZone = false }: { managedZone?: boolean } = {},\n): string | undefined {\n const host = hostnameOf(storefrontUrl);\n\n if (!host) return undefined;\n\n const normalized = normalizeHostname(host);\n\n if (managedZone) return `https://${MANAGED_ZONE_CHECKOUT_PREFIX}${normalized}`;\n\n return `https://checkout.${normalized.replace(/^www\\./, '')}`;\n}\n\n// Validates only the unambiguous parts: parses as a URL, uses https. A bare\n// hostname gets `https://` prefixed; path and query are dropped since the API\n// wants an origin.\nexport function normalizeCheckoutUrl(value: string): string {\n const withScheme = /^[a-z][a-z\\d+.-]*:\\/\\//i.test(value) ? value : `https://${value}`;\n let parsed: URL;\n\n try {\n parsed = new URL(withScheme);\n } catch {\n throw new UserActionableError(\n `\"${value}\" is not a valid URL. Pass a hostname or an https URL, e.g. https://checkout.example.com.`,\n );\n }\n\n if (parsed.protocol !== 'https:') {\n throw new UserActionableError(\n `The checkout URL must use https, but \"${value}\" uses ${parsed.protocol.replace(':', '')}.`,\n );\n }\n\n return parsed.origin;\n}\n\n// Zones native hosting generates hostnames under; mirrors ignition's\n// `reservedBaseDomainSuffixes`. Not derived from `deployment_hostnames`, which\n// also lists merchant domains.\nconst NATIVE_HOSTING_ZONES = [\n 'catalyst-sandbox.store',\n 'catalyst-sandbox-dev.store',\n 'catalyst-sandbox-staging.store',\n 'catalyst-sandbox-integration.store',\n 'ignition-demo.store',\n];\n\n// Whether native hosting generated the hostname, as opposed to it being the\n// merchant's own domain.\nexport function isManagedHostingHostname(hostname: string): boolean {\n const host = normalizeHostname(hostname);\n\n return NATIVE_HOSTING_ZONES.some((zone) => isSubdomainOf(host, zone));\n}\n\n// Whether checkout is on a different main domain from the storefront: the\n// test `warnOnCrossDomainCheckout` makes, without the output.\nexport function isCrossDomainCheckout(site: ChannelSiteDetails): boolean {\n const storefrontHost = hostnameOf(findChannelSiteUrl(site, 'primary') ?? site.url);\n const checkoutUrl = findChannelSiteUrl(site, 'checkout');\n const checkoutHost = checkoutUrl ? hostnameOf(checkoutUrl) : undefined;\n\n return Boolean(storefrontHost && checkoutHost && !sharesMainDomain(storefrontHost, checkoutHost));\n}\n\nexport interface CheckoutDomainReport {\n // True only when both hostnames were readable and don't share a registrable\n // domain. A missing or unreadable checkout URL is not \"cross domain\".\n crossDomain: boolean;\n // Undefined when checkout isn't cross-domain.\n storefrontOnManagedZone?: boolean;\n suggestion?: string;\n}\n\n// Warns when a channel's checkout domain doesn't share a main domain with its\n// storefront, which breaks session and cart continuity under third-party-cookie\n// restrictions. Nothing else surfaces it: the redirect is resolved server-side,\n// so a storefront moved to a new domain keeps redirecting to the old checkout.\n//\n// Returns its verdict so each caller can pick a fitting follow-up —\n// `channels checkout-url` offers to set the URL, `runChannelSiteUrlFlow` can be\n// mid-deploy and prints a command instead.\n//\n// Never throws: a diagnostic must not fail the command that called it.\nexport function warnOnCrossDomainCheckout(site: ChannelSiteDetails): CheckoutDomainReport {\n const storefrontUrl = findChannelSiteUrl(site, 'primary') ?? site.url;\n const storefrontHost = hostnameOf(storefrontUrl);\n const checkoutUrl = findChannelSiteUrl(site, 'checkout');\n\n if (!storefrontHost) return { crossDomain: false };\n\n const suggestion = suggestCheckoutUrl(storefrontUrl);\n const checkoutHost = checkoutUrl ? hostnameOf(checkoutUrl) : undefined;\n\n // Nothing to compare, and the command reports the absence itself.\n if (!checkoutHost || sharesMainDomain(storefrontHost, checkoutHost)) {\n return { crossDomain: false, suggestion };\n }\n\n // Both cases warn: the consequence is identical, and cross-domain checkout\n // costs real carts. Only the cause differs, which changes the wording and the\n // remedy. Kept to one sentence each — this fires on every channel that has\n // never had a checkout URL set, so a paragraph would train people to skip it.\n if (site.isCheckoutUrlCustomized) {\n consola.warn(\n `This channel's checkout URL (${checkoutHost}) is on a different domain than its ` +\n `storefront (${storefrontHost}) — most likely a storefront URL change left it behind.`,\n );\n } else {\n consola.warn(\n `Checkout is on the default channel's domain (${checkoutHost}), not this channel's ` +\n `storefront (${storefrontHost}).`,\n );\n }\n\n consola.info(\n 'Shopper sessions and carts may not carry into checkout in browsers that restrict ' +\n 'cross-domain cookies.',\n );\n\n const storefrontOnManagedZone = isManagedHostingHostname(storefrontHost);\n const report = {\n crossDomain: true,\n storefrontOnManagedZone,\n suggestion: storefrontOnManagedZone\n ? suggestCheckoutUrl(storefrontUrl, { managedZone: true })\n : suggestion,\n };\n\n if (storefrontOnManagedZone) {\n // Setting the checkout URL is what provisions this hostname.\n consola.info(\n `${storefrontHost} is an auto-generated deployment hostname, so its checkout hostname is ` +\n `${MANAGED_ZONE_CHECKOUT_PREFIX}${storefrontHost}. BigCommerce provisions it when it's ` +\n 'set as the checkout URL, and its certificate takes a few minutes to issue. Set it with:',\n );\n consola.log(\n ` catalyst channels update --channel-id ${site.channelId} --checkout-url ${report.suggestion ?? '<domain>'}`,\n );\n\n return report;\n }\n\n consola.info(\n `To put checkout on this channel's own domain, point ` +\n `${suggestion?.replace('https://', '') ?? 'your checkout subdomain'} at BigCommerce and ` +\n 'provision a certificate for it there.',\n );\n\n return report;\n}\n","import { checkbox, input, select } from '@inquirer/prompts';\nimport { colorize } from 'consola/utils';\n\nimport { createChannel, type CreatedChannel } from './channels';\nimport { UserActionableError } from './errors';\nimport { getAvailableLocales } from './localization';\nimport { consola } from './logger';\n\n// Human-readable summary of the allowed characters, reused in the prompt\n// validation and the flag-path error so both surface the same guidance.\nconst ALLOWED_CHANNEL_NAME_CHARS = 'letters, numbers, spaces, hyphens (-), and underscores (_)';\n\n// The Catalyst channels API rejects names containing other punctuation (e.g. an\n// apostrophe in \"Bob's Store\") with an opaque server error. Validate up front so\n// the user gets an immediate, actionable message instead. Letters/numbers are\n// matched with Unicode classes so non-ASCII names (accents, other scripts) pass.\nconst CHANNEL_NAME_PATTERN = /^[\\p{L}\\p{N} _-]+$/u;\n\n// Returns an error message when `name` is not a valid channel name, or\n// `undefined` when it is. Shared by the interactive prompt and the `--name` flag.\nexport function getChannelNameError(name: string): string | undefined {\n if (name.trim().length === 0) {\n return 'Channel name cannot be empty.';\n }\n\n if (!CHANNEL_NAME_PATTERN.test(name)) {\n return `\"${name}\" is not a valid channel name. Channel names may contain only ${ALLOWED_CHANNEL_NAME_CHARS}.`;\n }\n\n return undefined;\n}\n\nexport interface CreateChannelFlowOptions {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n cliApiOrigin: string;\n // Non-interactive overrides. When a value is supplied the corresponding\n // prompt is skipped, so a fully-flagged invocation runs headless.\n name?: string;\n locale?: string;\n additionalLocales?: string[];\n sampleData?: boolean;\n}\n\n// Shared channel-creation flow used by both `catalyst create` (while scaffolding)\n// and `catalyst channels create` (on an existing project). Prompts for anything\n// not provided as a flag, then POSTs to create the Catalyst channel.\nexport async function runCreateChannelFlow(\n options: CreateChannelFlowOptions,\n): Promise<CreatedChannel> {\n const { storeHash, accessToken, apiHost, cliApiOrigin } = options;\n\n // A `--name` flag skips the prompt (and its validation), so check it here to\n // fail fast with the same clear message rather than an opaque API rejection.\n if (options.name !== undefined) {\n const nameError = getChannelNameError(options.name);\n\n if (nameError) {\n throw new UserActionableError(nameError);\n }\n }\n\n const name =\n options.name ??\n (await input({\n message: 'What would you like to name your new channel?',\n validate: (value) => getChannelNameError(value) ?? true,\n }));\n\n // The locale list backs both the default-locale and additional-locales\n // prompts. Fetch it lazily and once — a fully-flagged run skips the call.\n let availableLocales: Awaited<ReturnType<typeof getAvailableLocales>> | undefined;\n const loadLocales = async () => {\n availableLocales ??= await getAvailableLocales(storeHash, accessToken, apiHost);\n\n return availableLocales;\n };\n\n const storefrontLocale =\n options.locale ??\n (await select({\n message: 'Which default language would you like to set for your channel?',\n default: 'en',\n choices: await loadLocales(),\n theme: {\n style: {\n help: () => colorize('dim', '(Select locale from the list or start typing the name)'),\n },\n },\n }));\n\n let additionalLocales = options.additionalLocales;\n\n if (additionalLocales === undefined) {\n const shouldAddAdditionalLocales = await select({\n message: 'Would you like to add additional languages?',\n choices: [\n { name: 'Yes', value: true },\n { name: 'No', value: false },\n ],\n });\n\n additionalLocales = [];\n\n if (shouldAddAdditionalLocales) {\n const localeChoices = (await loadLocales())\n .filter(({ value }) => value !== storefrontLocale)\n .map(({ name: localeName, value }) => ({ name: localeName, value, description: value }));\n\n additionalLocales = await checkbox({\n message: 'Which additional languages would you like to add to your channel?',\n choices: localeChoices,\n validate: (items) =>\n items.length <= 4 || 'You can only select up to 4 additional languages.',\n });\n }\n }\n\n const shouldInstallSampleData =\n options.sampleData ??\n (await select({\n message: 'Would you like to install sample data?',\n choices: [\n { name: 'Yes', value: true },\n { name: 'No', value: false },\n ],\n }));\n\n // The API call blocks for several seconds (it provisions the channel and,\n // when requested, populates sample data), so surface a spinner here — without\n // it the CLI looks frozen after the last prompt.\n consola.start('Creating channel...');\n\n const channel = await createChannel(\n name,\n storefrontLocale,\n additionalLocales,\n shouldInstallSampleData,\n storeHash,\n accessToken,\n cliApiOrigin,\n );\n\n consola.success('Channel created.');\n\n return channel;\n}\n","import { z } from 'zod';\n\nimport { assertAuthorized } from './auth-errors';\nimport { httpError } from './http-errors';\nimport { getTelemetry } from './telemetry';\n\nconst allowedLocales = [\n 'en',\n 'da',\n 'es-AR',\n 'es-CL',\n 'es-CO',\n 'es-MX',\n 'es-PE',\n 'es-419',\n 'es',\n 'it',\n 'nl',\n 'pl',\n 'pt',\n 'de',\n 'fr',\n 'ja',\n 'no',\n 'pt-BR',\n 'sv',\n];\n\nconst AvailableLocalesSuccessSchema = z.object({\n data: z.array(\n z.object({\n id: z.string(),\n name: z.string(),\n fallback: z.string().nullable(),\n is_supported: z.boolean(),\n }),\n ),\n});\n\nexport const getAvailableLocales = async (\n storeHash: string,\n accessToken: string,\n apiHost: string,\n) => {\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/settings/store/available-locales`,\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n Accept: 'application/json',\n },\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch available locales');\n }\n\n return AvailableLocalesSuccessSchema.parse(await response.json())\n .data.filter(({ id }) => allowedLocales.includes(id))\n .map(({ name, id }) => ({ name: `${name} (${id})`, value: id }));\n};\n","import type Conf from 'conf';\n\nimport { ProjectConfigSchema } from './project-config';\n\n// A single deployment environment variable as the infrastructure API expects\n// it. Merchant-supplied vars are always `secret` (see ProjectConfigSchema.env).\nexport interface DeploymentSecret {\n type: 'secret';\n key: string;\n value: string;\n}\n\n// Matches POSIX-ish env var names: leading letter/underscore, then\n// letters/digits/underscores. Keeps the stored config (and the deployment\n// payload) free of keys that wouldn't be valid env vars at runtime.\nconst ENV_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n// Parse a single `KEY=VALUE` assignment. Splits on the *first* `=` only, so\n// values containing `=` (e.g. base64 or tokens) survive intact. Validates the\n// key shape and rejects empty values.\nexport const parseEnvAssignment = (input: string): { key: string; value: string } => {\n const separatorIndex = input.indexOf('=');\n\n if (separatorIndex === -1) {\n throw new Error(`Invalid env var format: ${input}. Expected format: KEY=VALUE`);\n }\n\n const key = input.slice(0, separatorIndex).trim();\n const value = input.slice(separatorIndex + 1).trim();\n\n if (!key || !value) {\n throw new Error(`Invalid env var format: ${input}. Expected format: KEY=VALUE`);\n }\n\n if (!ENV_KEY_PATTERN.test(key)) {\n throw new Error(\n `Invalid env var name: ${key}. Names must start with a letter or underscore and contain only letters, numbers, and underscores.`,\n );\n }\n\n return { key, value };\n};\n\n// Read the persisted env var map (KEY -> VALUE), defaulting to empty.\nexport const getStoredEnv = (config: Conf<ProjectConfigSchema>): Record<string, string> => {\n return config.get('env') ?? {};\n};\n\n// Convert a persisted env var map into the deployment `secret` payload shape.\nexport const toDeploymentSecrets = (envVars: Record<string, string>): DeploymentSecret[] => {\n return Object.entries(envVars).map(([key, value]) => ({ type: 'secret', key, value }));\n};\n\n// Merge persisted secrets with inline `--secret` flag secrets, keyed by name.\n// Inline flags win on conflict so users can override a stored value per-run.\nexport const mergeDeploymentSecrets = (\n persisted: DeploymentSecret[],\n flagSecrets: DeploymentSecret[],\n): DeploymentSecret[] => {\n const byKey = new Map<string, DeploymentSecret>();\n\n persisted.forEach((secret) => byKey.set(secret.key, secret));\n flagSecrets.forEach((secret) => byKey.set(secret.key, secret));\n\n return Array.from(byKey.values());\n};\n","import Conf from 'conf';\n\nimport { consola } from './logger';\nimport { ProjectConfigSchema } from './project-config';\n\nexport function resolveCredentials(\n options: { storeHash?: string; accessToken?: string },\n config: Conf<ProjectConfigSchema>,\n): { storeHash: string; accessToken: string } {\n const storeHash = options.storeHash ?? config.get('storeHash');\n const accessToken = options.accessToken ?? config.get('accessToken');\n\n if (!storeHash || !accessToken) {\n consola.error('Missing credentials.');\n consola.info(\n 'Run `catalyst auth login`, or provide --store-hash and --access-token flags (or set CATALYST_STORE_HASH and CATALYST_ACCESS_TOKEN environment variables).',\n );\n process.exit(1);\n\n // Unreachable in production; prevents continuation when process.exit is mocked in tests.\n throw new Error('Missing credentials');\n }\n\n return { storeHash, accessToken };\n}\n","import { outputFileSync } from 'fs-extra/esm';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n// Matches an \"active\" env assignment — `KEY=VALUE` that isn't commented out.\n// The value is captured greedily (and may be empty) so blank documented keys\n// like `KEY=` still parse and `KEY=a=b` keeps the full value.\nconst ACTIVE_KEY_LINE = /^([A-Za-z_][A-Za-z0-9_]*)=(.*)$/;\n\nconst keyFromLine = (line: string): string | null => {\n const match = ACTIVE_KEY_LINE.exec(line);\n\n return match ? match[1] : null;\n};\n\n// Parse a .env-style body into an ordered KEY -> VALUE map, skipping comments\n// and blank lines. Last assignment wins, matching dotenv semantics.\nconst parseEnvValues = (contents: string): Map<string, string> => {\n const values = new Map<string, string>();\n\n contents.split('\\n').forEach((line) => {\n const match = ACTIVE_KEY_LINE.exec(line);\n\n if (match) {\n values.set(match[1], match[2]);\n }\n });\n\n return values;\n};\n\n// Writes .env.local at the project root — Next.js (and all the catalyst CLI\n// commands) read env vars from there, since the extracted project is the package\n// they run inside.\n//\n// `.env.example` (shipped with the scaffolded project) is the source of truth\n// for shape: the generated `.env.local` mirrors its ordering and per-key comment\n// blocks so the file stays self-documenting. Values supplied by the CLI are\n// substituted in place; documented keys we weren't given keep the example's own\n// line (blank or default) so the user still sees what's expected. Any existing\n// `.env.local` is reconciled rather than clobbered — the user's current values\n// are preserved unless the CLI is explicitly supplying a new one.\nexport const writeEnv = (projectDir: string, envVars: Record<string, string>) => {\n const examplePath = join(projectDir, '.env.example');\n const localPath = join(projectDir, '.env.local');\n\n const existingLocal = existsSync(localPath)\n ? parseEnvValues(readFileSync(localPath, 'utf-8'))\n : new Map<string, string>();\n\n // CLI-supplied vars win over what's already on disk so a re-run (e.g.\n // `channel link`) updates credentials in place; anything the CLI didn't touch\n // falls back to the user's existing value. An empty CLI value is treated as\n // \"not supplied\" — the channel init API returns blank placeholders for keys it\n // doesn't own (e.g. MAKESWIFT_SITE_API_KEY), and those must not clobber a real\n // value the user already has on disk.\n const resolve = (key: string): string | undefined => {\n if (key in envVars && envVars[key] !== '') {\n return envVars[key];\n }\n\n return existingLocal.get(key);\n };\n\n // Without a template we can't follow the documented ordering/comments, so fall\n // back to a flat merge that still preserves the user's existing values.\n if (!existsSync(examplePath)) {\n const keys = [...new Set([...existingLocal.keys(), ...Object.keys(envVars)])];\n\n outputFileSync(localPath, `${keys.map((key) => `${key}=${resolve(key) ?? ''}`).join('\\n')}\\n`);\n\n return;\n }\n\n // Drop a single trailing newline before splitting so we don't reproduce a\n // spurious blank line; the final `join` re-adds exactly one.\n const exampleLines = readFileSync(examplePath, 'utf-8').replace(/\\n$/, '').split('\\n');\n const exampleKeys = new Set<string>();\n\n const lines = exampleLines.map((line) => {\n const key = keyFromLine(line);\n\n // Comments and blank lines are copied verbatim, preserving each key's\n // leading comment block.\n if (key === null) {\n return line;\n }\n\n exampleKeys.add(key);\n\n const value = resolve(key);\n\n // Documented keys without a value keep the example's own line so defaults\n // (e.g. `BIGCOMMERCE_CHANNEL_ID=1`) and blank placeholders survive.\n return value === undefined ? line : `${key}=${value}`;\n });\n\n // Keys the CLI supplied — or the user already had — that the template doesn't\n // document get appended in a clearly separated section, preserving the order\n // they were first seen (existing keys first, then newly supplied ones).\n const extraKeys: string[] = [];\n\n [...existingLocal.keys()].forEach((key) => {\n if (!exampleKeys.has(key)) {\n extraKeys.push(key);\n }\n });\n\n Object.keys(envVars).forEach((key) => {\n if (!exampleKeys.has(key) && !extraKeys.includes(key)) {\n extraKeys.push(key);\n }\n });\n\n if (extraKeys.length > 0) {\n lines.push('', '# Additional variables set by the Catalyst CLI (not in .env.example).');\n\n extraKeys.forEach((key) => {\n lines.push(`${key}=${resolve(key) ?? ''}`);\n });\n }\n\n outputFileSync(localPath, `${lines.join('\\n')}\\n`);\n};\n","import { Command, InvalidArgumentError, Option } from '@commander-js/extra-typings';\nimport { input, select } from '@inquirer/prompts';\nimport { execSync } from 'child_process';\nimport { colorize } from 'consola/utils';\nimport { pathExistsSync } from 'fs-extra/esm';\nimport kebabCase from 'lodash.kebabcase';\nimport { join } from 'path';\n\nimport { DEFAULT_LOGIN_URL } from '../lib/auth';\nimport {\n channelPlatformLabel,\n checkChannelEligibility,\n fetchAvailableChannels,\n getChannelInit,\n sortChannelsByPlatform,\n} from '../lib/channels';\nimport { promptForCommerceHostingProject, setupCommerceHosting } from '../lib/commerce-hosting';\nimport { runCreateChannelFlow } from '../lib/create-channel-flow';\nimport { detectPackageManager } from '../lib/detect-package-manager';\nimport { extractCatalyst } from '../lib/extract-catalyst';\nimport { initGitRepo } from '../lib/init-git-repo';\nimport { installDependencies } from '../lib/install-dependencies';\nimport { consola } from '../lib/logger';\nimport { login, LoginAbortedError } from '../lib/login';\nimport { hasProjectsAccess, type ProjectListItem } from '../lib/project';\nimport { getProjectConfig } from '../lib/project-config';\nimport { rewriteCorePackage } from '../lib/rewrite-core-package';\nimport { setupCoreProject } from '../lib/setup-core-project';\nimport { accessTokenOption, storeHashOption } from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\nimport { writeEnv } from '../lib/write-env';\n\nfunction getPlatformCheckCommand(command: string): string {\n const isWindows = process.platform === 'win32';\n\n return isWindows ? `where.exe ${command}` : `which ${command}`;\n}\n\nfunction parseChannelId(value: string): number {\n const parsed = parseInt(value, 10);\n\n if (Number.isNaN(parsed)) {\n throw new InvalidArgumentError(`\"${value}\" is not a valid channel ID (expected a number).`);\n }\n\n return parsed;\n}\n\n// Variadic argParser: called once per `--env KEY=VALUE`, accumulating into a\n// merged record. Splits on the first `=` so values containing `=` are preserved.\nfunction parseEnvFlag(\n value: string,\n previous: Record<string, string> = {},\n): Record<string, string> {\n const eqIdx = value.indexOf('=');\n\n if (eqIdx <= 0) {\n throw new InvalidArgumentError(`Expected KEY=VALUE, got \"${value}\".`);\n }\n\n const key = value.substring(0, eqIdx);\n const val = value.substring(eqIdx + 1);\n\n if (!val) {\n throw new InvalidArgumentError(`Expected KEY=VALUE with non-empty value, got \"${value}\".`);\n }\n\n return { ...previous, [key]: val };\n}\n\nasync function handleChannelSelection(storeHash: string, accessToken: string, apiHost: string) {\n const channels = await fetchAvailableChannels(storeHash, accessToken, apiHost);\n\n const existingChannel = await select({\n message: 'Which channel would you like to use?',\n choices: sortChannelsByPlatform(channels).map((ch) => ({\n name: ch.name,\n value: ch,\n description: `Channel Platform: ${channelPlatformLabel(ch.platform)}`,\n })),\n });\n\n return existingChannel.id;\n}\n\nasync function setupProject(options: {\n projectName?: string;\n projectDir: string;\n}): Promise<{ projectName: string; projectDir: string }> {\n let { projectName, projectDir } = options;\n\n if (!pathExistsSync(projectDir)) {\n consola.error(`--project-dir ${projectDir} is not a valid path`);\n process.exit(1);\n }\n\n if (projectName) {\n projectName = kebabCase(projectName);\n projectDir = join(options.projectDir, projectName);\n\n if (pathExistsSync(projectDir)) {\n consola.error(`${projectDir} already exists`);\n process.exit(1);\n }\n }\n\n if (!projectName) {\n const validateProjectName = (i: string) => {\n const formatted = kebabCase(i);\n\n if (!formatted) return 'Project name is required';\n\n const targetDir = join(options.projectDir, formatted);\n\n if (pathExistsSync(targetDir)) return `Destination '${targetDir}' already exists`;\n\n projectName = formatted;\n projectDir = targetDir;\n\n return true;\n };\n\n await input({\n message: 'What do you want to name your project directory?',\n default: 'my-catalyst-app',\n validate: validateProjectName,\n });\n }\n\n if (!projectName) throw new Error('Something went wrong, projectName is not defined');\n if (!projectDir) throw new Error('Something went wrong, projectDir is not defined');\n\n return { projectName, projectDir };\n}\n\nfunction checkRequiredTools() {\n try {\n execSync(getPlatformCheckCommand('git'), { stdio: 'ignore' });\n } catch {\n consola.error('git is required to create a Catalyst project');\n process.exit(1);\n }\n}\n\nexport const create = new Command('create')\n .configureHelp({ showGlobalOptions: true })\n .description('Scaffold and connect a Catalyst storefront to your BigCommerce store.')\n .addHelpText(\n 'after',\n `\nExamples:\n # Interactive scaffold (default — self-hosted, no hosting prompt)\n $ catalyst create\n\n # Non-interactive: skip the project-name prompt\n $ catalyst create --project-name my-store\n\n # Eagerly set up Commerce Hosting at create time\n $ catalyst create --project-name my-store --hosting commerce`,\n )\n .option('--project-name <name>', 'Name of your Catalyst project')\n .option('--project-dir <dir>', 'Directory in which to create your project', process.cwd())\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .option('--channel-id <id>', 'BigCommerce channel ID', parseChannelId)\n .option('--storefront-token <token>', 'BigCommerce storefront token')\n .option(\n '--gh-ref <ref>',\n 'Extract a specific ref (tag, branch, or commit) from the source repository',\n '@bigcommerce/catalyst-core@latest',\n )\n .option('--repository <repository>', 'GitHub repository to extract from', 'bigcommerce/catalyst')\n .option(\n '--env <vars...>',\n 'Arbitrary environment variables to set in .env.local. Format: KEY=VALUE (repeatable).',\n parseEnvFlag,\n )\n .addOption(\n new Option(\n '--hosting <mode>',\n 'Hosting mode: \"self-hosted\" (default) or \"commerce\" to set up Commerce Hosting at create time. When omitted, scaffolding is hosting-agnostic; run `catalyst deploy` later to opt in.',\n ).choices(['self-hosted', 'commerce'] as const),\n )\n .option(\n '--use-existing',\n 'Only used with --hosting commerce and --project-name. When the named project already exists on the store, reuse it instead of prompting. Has no effect without --hosting commerce.',\n )\n .addOption(\n new Option('--bigcommerce-hostname <hostname>', 'BigCommerce hostname')\n .default('bigcommerce.com')\n .hideHelp(),\n )\n .addOption(\n new Option('--login-url <url>', 'BigCommerce login URL.')\n .env('BIGCOMMERCE_LOGIN_URL')\n .default(DEFAULT_LOGIN_URL)\n .hideHelp(),\n )\n .addOption(\n new Option('--cli-api-origin <origin>', 'Catalyst CLI API origin')\n .default('https://cxm-prd.bigcommerceapp.com')\n .hideHelp(),\n )\n // eslint-disable-next-line complexity\n .action(async (options) => {\n const { ghRef, repository } = options;\n\n if (options.useExisting && options.hosting !== 'commerce') {\n consola.warn('--use-existing has no effect without --hosting commerce. Ignoring.');\n }\n\n checkRequiredTools();\n\n const { projectName, projectDir } = await setupProject({\n projectName: options.projectName,\n projectDir: options.projectDir,\n });\n\n let storeHash = options.storeHash;\n let accessToken = options.accessToken;\n let channelId = options.channelId;\n let storefrontToken = options.storefrontToken;\n\n let envVars: Record<string, string> = {};\n\n // Always require store creds. `--channel-id` + `--storefront-token` aren't\n // enough on their own — the storefront also needs BIGCOMMERCE_STORE_HASH at\n // runtime, and downstream catalyst commands (deploy, project, ...) need an\n // access token. Device login covers the missing pieces; the user picks the\n // store during the OAuth flow regardless of any partial flags they passed.\n if (!storeHash || !accessToken) {\n const apiHost = `api.${options.bigcommerceHostname}`;\n\n try {\n const credentials = await login(options.loginUrl, apiHost);\n\n storeHash = credentials.storeHash;\n accessToken = credentials.accessToken;\n } catch (error) {\n if (error instanceof LoginAbortedError) {\n consola.info(\n 'Login aborted. Re-run `catalyst create` when you have your credentials ready.',\n );\n process.exit(0);\n\n return;\n }\n\n throw error;\n }\n }\n\n const useCommerceHosting = options.hosting === 'commerce';\n\n await getTelemetry().identify(storeHash);\n\n // Seed env vars from local state when all three were flag-provided. Channel\n // resolution below overwrites this wholesale via `envVars = { ...initData.envVars }`,\n // which is fine — that path means the user wanted us to fetch fresh values.\n if (storeHash && channelId && storefrontToken) {\n envVars.BIGCOMMERCE_STORE_HASH = storeHash;\n envVars.BIGCOMMERCE_CHANNEL_ID = channelId.toString();\n envVars.BIGCOMMERCE_STOREFRONT_TOKEN = storefrontToken;\n }\n\n // Resolve channel only when we have creds and are missing channel info.\n if (storeHash && accessToken && (!channelId || !storefrontToken)) {\n const apiHost = `api.${options.bigcommerceHostname}`;\n const cliApiOrigin = options.cliApiOrigin;\n\n if (channelId && !storefrontToken) {\n const initData = await getChannelInit(channelId, storeHash, accessToken, cliApiOrigin);\n\n envVars = { ...initData.envVars };\n storefrontToken = initData.storefrontToken;\n } else if (!channelId) {\n const eligibility = await checkChannelEligibility(storeHash, accessToken, cliApiOrigin);\n\n if (!eligibility.eligible) {\n consola.warn(eligibility.message);\n }\n\n let shouldCreateChannel;\n\n if (eligibility.eligible) {\n shouldCreateChannel = await select({\n message: 'Would you like to create a new channel?',\n choices: [\n { name: 'Yes', value: true },\n { name: 'No', value: false },\n ],\n });\n }\n\n if (shouldCreateChannel) {\n const channelData = await runCreateChannelFlow({\n storeHash,\n accessToken,\n apiHost,\n cliApiOrigin,\n });\n\n channelId = channelData.channelId;\n storefrontToken = channelData.storefrontToken;\n envVars = { ...channelData.envVars };\n\n consola.success('Channel created successfully.');\n consola.warn(\n 'A preview storefront has been deployed in your BigCommerce control panel. This preview may look different from your local environment as it may be running different code. Additionally, it may take a few minutes for the channel storefront to be accessible.',\n );\n }\n\n if (!shouldCreateChannel) {\n channelId = await handleChannelSelection(storeHash, accessToken, apiHost);\n\n const initData = await getChannelInit(channelId, storeHash, accessToken, cliApiOrigin);\n\n envVars = { ...initData.envVars };\n storefrontToken = initData.storefrontToken;\n }\n }\n }\n\n if (options.env) {\n Object.assign(envVars, options.env);\n }\n\n if (options.storeHash) envVars.BIGCOMMERCE_STORE_HASH = options.storeHash;\n if (options.channelId) envVars.BIGCOMMERCE_CHANNEL_ID = options.channelId.toString();\n if (options.storefrontToken) envVars.BIGCOMMERCE_STOREFRONT_TOKEN = options.storefrontToken;\n\n if (useCommerceHosting && accessToken) {\n envVars.BIGCOMMERCE_ACCESS_TOKEN = accessToken;\n }\n\n // Resolve the Commerce Hosting project before extraction so credential checks\n // and prompts happen up-front. We defer the file mutations\n // (`setupCommerceHosting`) until after extraction.\n let commerceHostingProject: ProjectListItem | undefined;\n\n if (useCommerceHosting && storeHash && accessToken) {\n const apiHost = `api.${options.bigcommerceHostname}`;\n const hasAccess = await hasProjectsAccess(storeHash, accessToken, apiHost);\n\n if (!hasAccess) {\n consola.error(\n 'This store does not have access to the Infrastructure Projects API. Contact support@bigcommerce.com to enable it.',\n );\n process.exit(1);\n }\n\n commerceHostingProject = await promptForCommerceHostingProject(\n { storeHash, accessToken, apiHost },\n projectName,\n !!options.projectName,\n options.useExisting,\n );\n }\n\n consola.info(`Creating '${projectName}' at '${projectDir}'`);\n\n const packageManager = detectPackageManager();\n\n // Anything that mutates `projectDir` runs inside this block. If a step\n // fails, the directory is likely partially populated — surface that to the\n // user so they can clean up before retrying. We don't auto-delete because\n // they may want to inspect the partial state first.\n try {\n await extractCatalyst({ repository, ref: ghRef, projectDir });\n // Turn the extracted core/ into an installable standalone project\n // (resolve workspace deps, drop `private`, record the catalyst version/ref).\n await rewriteCorePackage(projectDir, ghRef);\n setupCoreProject(projectDir);\n\n if (useCommerceHosting && commerceHostingProject && storeHash && accessToken) {\n await setupCommerceHosting({\n projectDir,\n projectUuid: commerceHostingProject.uuid,\n storeHash,\n accessToken,\n });\n }\n\n // Persist the credentials we just authenticated with into the new\n // project's `.bigcommerce/project.json` (gitignored). Every command\n // resolves credentials from this file, so without it `catalyst deploy`\n // and `catalyst projects create` would fail or re-prompt for login\n // immediately after `create` already logged the user in.\n //\n // Ordered after `setupCommerceHosting`, which writes the same file to\n // record `projectUuid`. Both merge into existing contents now, so the\n // order no longer matters for correctness — kept so the credentials\n // written here are the ones that land last.\n if (storeHash && accessToken) {\n const projectConfig = getProjectConfig(projectDir);\n\n projectConfig.set('storeHash', storeHash);\n projectConfig.set('accessToken', accessToken);\n }\n\n // Write env before install — matters for postinstall scripts that may\n // resolve env-driven config.\n writeEnv(projectDir, envVars);\n\n await installDependencies(projectDir, packageManager);\n initGitRepo(projectDir);\n } catch (error) {\n if (pathExistsSync(projectDir)) {\n consola.warn(\n `Setup failed before completion. '${projectDir}' may be in a partial state — review and delete it before re-running 'catalyst create'.`,\n );\n }\n\n throw error;\n }\n\n consola.success(`Created '${projectName}' at '${projectDir}'`);\n\n const steps = [`cd ${projectName} && ${packageManager} run dev`];\n\n if (useCommerceHosting) {\n steps.push(\n `Run 'cd ${projectName} && ${packageManager} run deploy' when ready to deploy to Commerce Hosting.`,\n );\n }\n\n consola.log(\n `Next steps:\\n\\n${steps.map((step) => ` ${colorize('yellow', step)}`).join('\\n')}`,\n );\n });\n","import { mkdirSync } from 'fs';\nimport { Readable } from 'stream';\nimport { pipeline } from 'stream/promises';\nimport type { ReadableStream as NodeReadableStream } from 'stream/web';\nimport { x } from 'tar';\n\nimport { consola } from './logger';\n\nconst SUBDIR = 'core';\nconst MAX_ATTEMPTS = 3;\n\nconst codeloadUrl = (repository: string, ref: string) =>\n `https://codeload.github.com/${repository}/tar.gz/${encodeURIComponent(ref)}`;\n\nconst wait = (ms: number) =>\n new Promise((resolve) => {\n setTimeout(resolve, ms);\n });\n\n// Download the repo tarball from GitHub's codeload endpoint and stream-extract\n// ONLY the `core/` subdirectory into `projectDir`, so merchants receive a clean\n// standalone project instead of the whole monorepo. Mirrors create-next-app:\n// fetch -> stream.pipeline -> tar.x({ strip, filter }).\n//\n// The archive's top-level directory is dynamic (e.g.\n// `catalyst--bigcommerce-catalyst-core-1.6.2` for a tag, `catalyst-canary` for a\n// branch), so we never hardcode it — `filter` keeps entries whose first path\n// segment after the top dir is `core/`, and `strip: 2` drops `<top>/core` so the\n// contents land at the project root.\nconst downloadAndExtract = async (repository: string, ref: string, projectDir: string) => {\n const url = codeloadUrl(repository, ref);\n const response = await fetch(url);\n\n if (!response.ok || !response.body) {\n throw new Error(`Failed to download ${url} (HTTP ${response.status})`);\n }\n\n await pipeline(\n // Node's global fetch types `body` as the DOM ReadableStream; it is the same\n // object Readable.fromWeb expects at runtime.\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n Readable.fromWeb(response.body as NodeReadableStream<Uint8Array>),\n x({\n cwd: projectDir,\n strip: 2,\n filter: (path) => path.split('/')[1] === SUBDIR,\n }),\n );\n};\n\n// Retries the download up to MAX_ATTEMPTS with linear backoff, following\n// create-next-app's pattern. Recursive rather than looped to keep each await off\n// the hot loop path (and satisfy lint).\nconst attemptDownload = async (\n repository: string,\n ref: string,\n projectDir: string,\n attempt = 1,\n): Promise<void> => {\n try {\n await downloadAndExtract(repository, ref, projectDir);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'unknown error';\n\n if (attempt >= MAX_ATTEMPTS) {\n throw new Error(`Failed to download Catalyst after ${MAX_ATTEMPTS} attempts: ${message}`);\n }\n\n consola.warn(`Download attempt ${attempt} failed (${message}). Retrying...`);\n await wait(attempt * 1000);\n\n return attemptDownload(repository, ref, projectDir, attempt + 1);\n }\n};\n\nexport const extractCatalyst = async ({\n repository,\n ref,\n projectDir,\n}: {\n repository: string;\n ref: string;\n projectDir: string;\n}) => {\n consola.info(`Downloading ${repository}#${ref}...`);\n\n mkdirSync(projectDir, { recursive: true });\n\n await attemptDownload(repository, ref, projectDir);\n};\n","import { execSync } from 'child_process';\nimport { rmSync } from 'fs';\nimport { join } from 'path';\n\nimport { consola } from './logger';\n\nconst run = (command: string, cwd: string) => execSync(command, { cwd, stdio: 'ignore' });\n\n// Initialize a fresh git repository for the merchant with a single initial\n// commit. We no longer clone, so there is no history or upstream remote to carry\n// over — merchants add their own. Best-effort: a missing git or a pre-existing\n// repo shouldn't fail project creation, so we warn and roll back a partial init.\nexport const initGitRepo = (projectDir: string) => {\n try {\n run('git init', projectDir);\n run('git add -A', projectDir);\n run('git commit -m \"Initial commit from Catalyst\"', projectDir);\n consola.success('Initialized a git repository.');\n } catch {\n rmSync(join(projectDir, '.git'), { recursive: true, force: true });\n consola.warn('Could not initialize a git repository. Skipping.');\n }\n};\n","import { readFileSync, writeFileSync } from 'fs';\nimport { join } from 'path';\nimport { z } from 'zod';\n\nimport { consola } from './logger';\nimport { sortPackageJsonFields } from './sort-package-json';\n\n// Native-module build allowlist, lifted from the monorepo's root\n// pnpm-workspace.yaml `onlyBuiltDependencies`. A standalone install needs this so\n// pnpm (`pnpm.onlyBuiltDependencies`) and bun (`trustedDependencies`) run the\n// native postinstall builds without prompting. npm/yarn-classic run them anyway.\nconst NATIVE_BUILD_ALLOWLIST = [\n '@parcel/watcher',\n '@swc/core',\n '@vercel/speed-insights',\n 'esbuild',\n 'msw',\n 'protobufjs',\n 'puppeteer',\n 'sharp',\n 'workerd',\n];\n\nconst DEP_FIELDS = [\n 'dependencies',\n 'devDependencies',\n 'optionalDependencies',\n 'peerDependencies',\n] as const;\n\nconst corePackageJsonSchema = z.looseObject({\n version: z.string().optional(),\n private: z.boolean().optional(),\n scripts: z.record(z.string(), z.string()).optional(),\n dependencies: z.record(z.string(), z.string()).optional(),\n devDependencies: z.record(z.string(), z.string()).optional(),\n optionalDependencies: z.record(z.string(), z.string()).optional(),\n peerDependencies: z.record(z.string(), z.string()).optional(),\n pnpm: z.looseObject({}).optional(),\n catalyst: z.looseObject({}).optional(),\n});\n\nconst registryVersionSchema = z.object({ version: z.string() });\n\n// Resolve the published npm version for a workspace dependency. The extracted\n// tag tree still carries `workspace:^` (core is private, so changesets' publish-\n// time rewrite never touches the committed tree) — so we resolve the real\n// version at extraction time from the npm registry.\n//\n// NOTE: `latest` answers for today, not for `ref`. These packages version\n// independently of core (the changesets config has no `linked`/`fixed` group),\n// so scaffolding from an older `--gh-ref` can splice in a newer version than\n// that tag shipped. Harmless while they stay in step, wrong at the first major\n// bump. `catalyst upgrade` reads the versions out of the tag's own\n// `packages/*/package.json`; this path can't yet, because `extractCatalyst`\n// filters the tarball down to `core/`. Tracked as a follow-up.\nconst resolvePublishedVersion = async (pkgName: string): Promise<string> => {\n const response = await fetch(`https://registry.npmjs.org/${pkgName}/latest`);\n\n if (!response.ok) {\n throw new Error(\n `Could not resolve a published version for \"${pkgName}\" (HTTP ${response.status}). ` +\n 'The extracted project still references it via the workspace protocol and cannot be installed.',\n );\n }\n\n const { version } = registryVersionSchema.parse(await response.json());\n\n return `^${version}`;\n};\n\n// Transforms an extracted `core/package.json` into an installable, standalone\n// manifest: resolves `workspace:` deps to published versions, drops `private`,\n// bakes the native-build allowlist for pnpm/bun, strips monorepo-only (turbo)\n// scripts, and records the Catalyst version/ref the project was created from.\n// Also writes `.npmrc` so npm tolerates react-headroom's stale react peer range.\nexport const rewriteCorePackage = async (projectDir: string, ref: string) => {\n const packageJsonPath = join(projectDir, 'package.json');\n const pkg = corePackageJsonSchema.parse(JSON.parse(readFileSync(packageJsonPath, 'utf-8')));\n\n // Collect every workspace-protocol dependency across all dep fields, keeping a\n // reference to its owning record so we can rewrite it in place after resolving.\n const workspaceDeps = DEP_FIELDS.flatMap((field) => {\n const deps = pkg[field];\n\n if (!deps) return [];\n\n return Object.entries(deps)\n .filter(([, range]) => range.startsWith('workspace:'))\n .map(([name]) => ({ deps, name }));\n });\n\n await Promise.all(\n workspaceDeps.map(async ({ deps, name }) => {\n const resolved = await resolvePublishedVersion(name);\n\n deps[name] = resolved;\n consola.info(`Resolved ${name} to ${resolved}`);\n }),\n );\n\n // Merchants need an installable project; `private` blocks publish/install ergonomics.\n delete pkg.private;\n\n // Drop any monorepo-only scripts that shell out to turbo.\n if (pkg.scripts) {\n pkg.scripts = Object.fromEntries(\n Object.entries(pkg.scripts).filter(([, command]) => !command.includes('turbo')),\n );\n }\n\n pkg.pnpm = { ...pkg.pnpm, onlyBuiltDependencies: NATIVE_BUILD_ALLOWLIST };\n pkg.trustedDependencies = NATIVE_BUILD_ALLOWLIST;\n\n // Track what this project was scaffolded from (consumed by `catalyst upgrade`\n // and the backend user-agent). `ref` is the exact ref extracted.\n pkg.catalyst = { ...pkg.catalyst, version: pkg.version, ref };\n\n writeFileSync(packageJsonPath, `${JSON.stringify(sortPackageJsonFields(pkg), null, 2)}\\n`);\n\n // react-headroom (unmaintained) declares a react <=18 peer; core ships react 19.\n // pnpm/yarn/bun tolerate it, but npm errors ERESOLVE without this.\n writeFileSync(join(projectDir, '.npmrc'), 'legacy-peer-deps=true\\n');\n};\n","import { mkdirSync, readFileSync, writeFileSync } from 'fs';\nimport { dirname, join } from 'path';\nimport { z } from 'zod';\n\nimport PACKAGE_INFO from '../../../package.json';\n\nimport { sortPackageJsonFields } from './sort-package-json';\n\nconst corePackageJsonSchema = z.looseObject({\n scripts: z.record(z.string(), z.string()).optional(),\n devDependencies: z.record(z.string(), z.string()).optional(),\n});\n\nconst writeJson = (path: string, value: unknown) => {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, `${JSON.stringify(value, null, 2)}\\n`);\n};\n\n// Wires Catalyst CLI scripts and the `@bigcommerce/catalyst` dev dependency into\n// a freshly extracted project. Always runs at create time, regardless of hosting\n// choice — `catalyst build` / `catalyst start` / `catalyst deploy` dispatch on\n// project state, so these scripts work for self-hosted projects too without\n// rewrite. The CLI is a build-time tool (it only backs those npm scripts), never\n// imported at runtime, so it belongs in devDependencies, not dependencies.\nexport const setupCoreProject = (projectDir: string) => {\n const corePackageJsonPath = join(projectDir, 'package.json');\n const pkg = corePackageJsonSchema.parse(JSON.parse(readFileSync(corePackageJsonPath, 'utf-8')));\n\n pkg.scripts = {\n ...pkg.scripts,\n build: 'npm run generate && catalyst build',\n start: 'catalyst start',\n deploy: 'npm run generate && catalyst deploy',\n };\n\n pkg.devDependencies = {\n ...pkg.devDependencies,\n '@bigcommerce/catalyst': PACKAGE_INFO.version,\n };\n\n writeJson(corePackageJsonPath, sortPackageJsonFields(pkg));\n};\n","import { Command, Option } from 'commander';\n\nimport {\n collectDiagnostics,\n type ConfigSource,\n type Diagnostics,\n type ResolvedValue,\n} from '../lib/collect-diagnostics';\nimport { consola } from '../lib/logger';\n\nconst yesNo = (value: boolean): string => (value ? 'yes' : 'no');\n\nconst presence = (value: boolean): string => (value ? 'present' : 'absent');\n\nconst formatResolved = (value: ResolvedValue): string =>\n value.present ? `present (source: ${value.source})` : 'not set';\n\nconst formatSource = (source: ConfigSource): string =>\n source === 'unset' ? 'not set' : `set (${source})`;\n\nconst formatStorefront = (name: string | null, version: string | null): string => {\n if (!version) {\n return '(unknown)';\n }\n\n return name ? `${name}@${version}` : version;\n};\n\nconst formatList = (values: string[]): string => (values.length > 0 ? values.join(', ') : '(none)');\n\nconst envVarLines = (vars: Record<string, ConfigSource>): string[] =>\n Object.entries(vars).map(([name, source]) => ` ${name}: ${formatSource(source)}`);\n\n// Build a human-readable, copy-pasteable report. Kept to plain text (no colors)\n// so it survives a paste into a GitHub issue or support ticket unchanged.\nconst formatReport = (d: Diagnostics): string => {\n const lines = [\n 'Catalyst CLI Diagnostics',\n '',\n 'CLI',\n ` Package: ${d.cli.name}`,\n ` Version: ${d.cli.version}`,\n '',\n 'Runtime',\n ` Node: ${d.runtime.node}`,\n ` Platform: ${d.runtime.platform} (${d.runtime.arch})`,\n ` OS release: ${d.runtime.osRelease}`,\n ` Package manager: ${d.runtime.packageManager}`,\n '',\n 'Project',\n ` Directory: ${d.project.cwd}`,\n ` Storefront: ${formatStorefront(d.project.storefrontName, d.project.storefrontVersion)}`,\n ` Project UUID: ${d.project.projectUuid ?? '(not linked)'}`,\n ` Linked: ${yesNo(d.project.isLinked)}`,\n ` Transformed: ${yesNo(d.project.isTransformed)}`,\n ` Fully set up: ${yesNo(d.project.isFullySetUp)}`,\n ` middleware.ts: ${presence(d.project.hasMiddleware)}`,\n ` proxy.ts: ${presence(d.project.hasProxy)}`,\n ` OpenNext dep: ${d.project.hasOpenNextDep ? 'installed' : 'not installed'}`,\n '',\n 'Config (resolved without secrets)',\n ` Store hash: ${formatResolved(d.config.storeHash)}`,\n ` Access token: ${formatResolved(d.config.accessToken)}`,\n ` Project UUID: ${formatResolved(d.config.projectUuid)}`,\n ` API host: ${d.config.apiHost.present ? formatResolved(d.config.apiHost) : 'default (api.bigcommerce.com)'}`,\n ` project.json keys: ${formatList(d.config.projectJsonKeys)}`,\n ` Stored env keys: ${formatList(d.config.storedEnvKeys)}`,\n '',\n 'CLI environment variables (used to run the CLI)',\n ...envVarLines(d.config.cliEnvVars),\n '',\n 'Build environment variables (used to build the Next.js app)',\n ...envVarLines(d.config.buildEnvVars),\n '',\n 'Telemetry',\n ` Enabled: ${yesNo(d.telemetry.enabled)}`,\n ` Correlation ID: ${d.telemetry.correlationId}`,\n '',\n 'Files',\n ...Object.entries(d.files).map(([name, exists]) => ` ${name}: ${presence(exists)}`),\n ];\n\n return lines.join('\\n');\n};\n\nexport const debug = new Command('debug')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Print a diagnostic report (CLI, runtime, project, and config state) to include when filing a bug report. Never prints secret values — credentials and env vars are reported by presence only.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Print a human-readable report\n $ catalyst debug\n\n # Print machine-readable JSON (useful for copy/paste or piping)\n $ catalyst debug --json`,\n )\n .addOption(new Option('--json', 'Output the report as JSON.'))\n .action((options: { json?: boolean }) => {\n const diagnostics = collectDiagnostics();\n\n if (options.json) {\n consola.log(JSON.stringify(diagnostics, null, 2));\n\n return;\n }\n\n consola.log(formatReport(diagnostics));\n });\n","import { parse } from 'dotenv';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { release } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { z } from 'zod';\n\nimport PACKAGE_INFO from '../../../package.json';\n\nimport { detectPackageManager, type PackageManager } from './detect-package-manager';\nimport { getProjectState } from './project-state';\nimport { getTelemetry } from './telemetry';\n\n// Env vars the CLI itself reads to run commands (credential/flag bindings in\n// shared-options.ts plus the telemetry opt-out). We report only WHERE each is\n// set (or that it is unset) — never its value — so the report can never leak a\n// token, secret, or store identifier.\nexport const CLI_ENV_VARS = [\n 'CATALYST_STORE_HASH',\n 'CATALYST_ACCESS_TOKEN',\n 'CATALYST_PROJECT_UUID',\n 'CATALYST_API_HOST',\n 'BIGCOMMERCE_LOGIN_URL',\n 'CATALYST_TELEMETRY_DISABLED',\n] as const;\n\n// Env vars the storefront (Next.js app) build reads, not the CLI. Mirrors\n// REQUIRED_BUILD_ENV_VARS in required-build-env.ts — the values `build`/`deploy`\n// assert on before shelling out to the OpenNext/Next.js build.\nexport const BUILD_ENV_VARS = [\n 'BIGCOMMERCE_STORE_HASH',\n 'BIGCOMMERCE_STOREFRONT_TOKEN',\n 'BIGCOMMERCE_CHANNEL_ID',\n 'AUTH_SECRET',\n] as const;\n\n// Env files `build`/`deploy` auto-load, in precedence order (see build-env.ts).\n// `debug` doesn't load them into process.env — it only inspects their KEYS so\n// the report reflects what a build would resolve, without side effects.\nconst ENV_FILES = ['.env.local', '.env'] as const;\n\n// Lockfile -> package manager, checked in this order. This detects the\n// project's package manager (what `build`/`deploy` shell out to) rather than\n// whatever invoked the CLI, which is what a bug report actually needs.\nconst PROJECT_LOCKFILES: ReadonlyArray<readonly [string, PackageManager]> = [\n ['pnpm-lock.yaml', 'pnpm'],\n ['yarn.lock', 'yarn'],\n ['bun.lock', 'bun'],\n ['bun.lockb', 'bun'],\n ['package-lock.json', 'npm'],\n];\n\n// Where a value resolved from, following the CLI's priority chain\n// (process.env > .env.local > .env > .bigcommerce/project.json). Flags are\n// excluded because `debug` takes none of the credential flags itself.\nexport type EnvSource = 'process.env' | (typeof ENV_FILES)[number];\nexport type ConfigSource = EnvSource | 'project.json' | 'unset';\n\nexport interface ResolvedValue {\n present: boolean;\n source: ConfigSource;\n}\n\nexport interface Diagnostics {\n cli: {\n name: string;\n version: string;\n };\n runtime: {\n node: string;\n platform: string;\n arch: string;\n osRelease: string;\n packageManager: PackageManager;\n };\n project: {\n cwd: string;\n // The storefront package name + version from the project's package.json,\n // resolved the same way `upgrade` does. `name` identifies the Catalyst\n // family (catalyst-core, catalyst-makeswift, …). null when absent.\n storefrontName: string | null;\n storefrontVersion: string | null;\n projectUuid: string | null;\n isLinked: boolean;\n isTransformed: boolean;\n isFullySetUp: boolean;\n hasMiddleware: boolean;\n hasProxy: boolean;\n hasOpenNextDep: boolean;\n };\n config: {\n storeHash: ResolvedValue;\n accessToken: ResolvedValue;\n projectUuid: ResolvedValue;\n // The API host override. 'unset' means the CLI falls back to its default\n // (api.bigcommerce.com). Resolved like the credentials above.\n apiHost: ResolvedValue;\n // Top-level keys present in .bigcommerce/project.json (names only — values\n // are never included so masked secrets like accessToken can't leak).\n projectJsonKeys: string[];\n // Names of persisted deployment env vars (project.json `env` map keys only).\n storedEnvKeys: string[];\n // Env var name -> where it resolved from ('unset' if nowhere), split by\n // consumer: `cliEnvVars` are read by the CLI, `buildEnvVars` by the Next.js\n // app build. The value is never included, only the source.\n cliEnvVars: Record<string, ConfigSource>;\n buildEnvVars: Record<string, ConfigSource>;\n };\n telemetry: {\n enabled: boolean;\n correlationId: string;\n };\n // Relative path -> whether the file/directory exists on disk. Presence only;\n // contents are never read into the report.\n files: Record<string, boolean>;\n}\n\nexport interface CollectDiagnosticsOptions {\n cwd?: string;\n env?: NodeJS.ProcessEnv;\n}\n\n// A value counts as present only when it is a non-empty, non-whitespace string —\n// mirroring how the build treats \"\" the same as unset (see required-build-env.ts).\nconst hasValue = (value: string | undefined): boolean => value !== undefined && value.trim() !== '';\n\ninterface EnvLayer {\n source: EnvSource;\n values: Record<string, string | undefined>;\n}\n\n// Build the ordered env layers the CLI resolves against: the real environment\n// first, then the auto-loaded env files. File values are parsed into memory\n// only to detect presence — they are never surfaced in the report.\nconst buildEnvLayers = (cwd: string, env: NodeJS.ProcessEnv): EnvLayer[] => {\n const layers: EnvLayer[] = [{ source: 'process.env', values: env }];\n\n ENV_FILES.forEach((file) => {\n const path = join(cwd, file);\n\n if (!existsSync(path)) {\n return;\n }\n\n try {\n layers.push({ source: file, values: parse(readFileSync(path, 'utf-8')) });\n } catch {\n // A malformed/unreadable env file shouldn't break the report.\n }\n });\n\n return layers;\n};\n\n// The first layer (process.env > .env.local > .env) that carries a non-empty\n// value for any of the given keys. Returns only the source — never a value.\nconst resolveEnvSource = (layers: EnvLayer[], ...keys: string[]): EnvSource | undefined =>\n layers.find((layer) => keys.some((key) => hasValue(layer.values[key])))?.source;\n\n// Map each named var to the layer it resolves from (or 'unset'), values omitted.\nconst resolveEnvVars = (\n layers: EnvLayer[],\n names: readonly string[],\n): Record<string, ConfigSource> =>\n Object.fromEntries(names.map((name) => [name, resolveEnvSource(layers, name) ?? 'unset']));\n\n// Resolve which source (if any) supplies a credential, without exposing the\n// value itself. Env layers win over project.json, matching build/deploy.\nconst resolveValue = (\n envSource: EnvSource | undefined,\n configValue: string | undefined,\n): ResolvedValue => {\n if (envSource) {\n return { present: true, source: envSource };\n }\n\n if (hasValue(configValue)) {\n return { present: true, source: 'project.json' };\n }\n\n return { present: false, source: 'unset' };\n};\n\nconst asString = (value: unknown): string | undefined =>\n typeof value === 'string' ? value : undefined;\n\nconst lockfileManager = (dir: string): PackageManager | undefined =>\n PROJECT_LOCKFILES.find(([file]) => existsSync(join(dir, file)))?.[1];\n\n// Detect the project's package manager from the nearest lockfile, walking up\n// from cwd so it still works when the CLI is run from a subdirectory (e.g.\n// `core/` in a monorepo, where the lockfile lives at the repo root). Falls back\n// to the manager that invoked the CLI when no lockfile is found anywhere.\nconst detectProjectPackageManager = (cwd: string): PackageManager => {\n let dir = cwd;\n\n for (;;) {\n const match = lockfileManager(dir);\n\n if (match) {\n return match;\n }\n\n const parent = dirname(dir);\n\n if (parent === dir) {\n // Reached the filesystem root without finding a lockfile.\n return detectPackageManager();\n }\n\n dir = parent;\n }\n};\n\n// An open object schema: known credential fields plus any other keys the file\n// may carry, all kept as `unknown` so we can enumerate key names without\n// coercing (or trusting the type of) their values.\nconst projectJsonSchema = z.looseObject({});\n\nconst safeReadJson = (path: string): unknown => {\n try {\n return JSON.parse(readFileSync(path, 'utf-8'));\n } catch {\n return null;\n }\n};\n\n// Read .bigcommerce/project.json as a raw object without going through\n// getProjectConfig() — that instantiates Conf and would create .bigcommerce/ as\n// a side effect (see project-state.ts). Returns null when absent, malformed, or\n// not a JSON object.\nconst readProjectJson = (cwd: string): Record<string, unknown> | null => {\n const result = projectJsonSchema.safeParse(\n safeReadJson(join(cwd, '.bigcommerce', 'project.json')),\n );\n\n return result.success ? result.data : null;\n};\n\n// Mirrors upgrade.ts: `catalyst.version` is the source of truth for the\n// storefront version, falling back to the plain `version`. `name` identifies\n// which Catalyst family the project is on (e.g. @bigcommerce/catalyst-core).\nconst storefrontPackageSchema = z.looseObject({\n name: z.string().optional(),\n version: z.string().optional(),\n catalyst: z.looseObject({ version: z.string().optional() }).optional(),\n});\n\nconst readStorefrontInfo = (cwd: string): { name: string | null; version: string | null } => {\n const result = storefrontPackageSchema.safeParse(safeReadJson(join(cwd, 'package.json')));\n\n if (!result.success) {\n return { name: null, version: null };\n }\n\n return {\n name: result.data.name ?? null,\n version: result.data.catalyst?.version ?? result.data.version ?? null,\n };\n};\n\nconst readStoredEnvKeys = (projectJson: Record<string, unknown> | null): string[] => {\n const env = projectJson?.env;\n\n if (typeof env === 'object' && env !== null && !Array.isArray(env)) {\n return Object.keys(env).sort();\n }\n\n return [];\n};\n\n// Gather a diagnostic snapshot of the CLI, runtime, project, and config state.\n// By construction this never includes secret values — credentials are reported\n// as presence + source only, and file/env checks report existence only.\nexport function collectDiagnostics({\n cwd = process.cwd(),\n env = process.env,\n}: CollectDiagnosticsOptions = {}): Diagnostics {\n const state = getProjectState(cwd);\n const telemetry = getTelemetry();\n const projectJson = readProjectJson(cwd);\n const storefront = readStorefrontInfo(cwd);\n\n // The CLI reads its own config only from the real environment (Commander\n // `.env()` bindings) and .bigcommerce/project.json — never from .env files\n // (see the note in program.ts). Only the storefront BUILD vars are loaded\n // from .env.local/.env, and only by `build`/`deploy`, so only those are\n // resolved across the file layers.\n const cliEnv: EnvLayer[] = [{ source: 'process.env', values: env }];\n const buildEnv = buildEnvLayers(cwd, env);\n\n return {\n cli: {\n name: PACKAGE_INFO.name,\n version: PACKAGE_INFO.version,\n },\n runtime: {\n node: process.version,\n platform: process.platform,\n arch: process.arch,\n osRelease: release(),\n packageManager: detectProjectPackageManager(cwd),\n },\n project: {\n cwd,\n storefrontName: storefront.name,\n storefrontVersion: storefront.version,\n projectUuid: state.projectUuid ?? null,\n isLinked: state.isLinked,\n isTransformed: state.isTransformed,\n isFullySetUp: state.isFullySetUp,\n hasMiddleware: state.hasMiddleware,\n hasProxy: state.hasProxy,\n hasOpenNextDep: state.hasOpenNextDep,\n },\n config: {\n storeHash: resolveValue(\n resolveEnvSource(cliEnv, 'CATALYST_STORE_HASH', 'BIGCOMMERCE_STORE_HASH'),\n asString(projectJson?.storeHash),\n ),\n accessToken: resolveValue(\n resolveEnvSource(cliEnv, 'CATALYST_ACCESS_TOKEN'),\n asString(projectJson?.accessToken),\n ),\n projectUuid: resolveValue(\n resolveEnvSource(cliEnv, 'CATALYST_PROJECT_UUID'),\n asString(projectJson?.projectUuid),\n ),\n apiHost: resolveValue(\n resolveEnvSource(cliEnv, 'CATALYST_API_HOST'),\n asString(projectJson?.apiHost),\n ),\n projectJsonKeys: projectJson ? Object.keys(projectJson).sort() : [],\n storedEnvKeys: readStoredEnvKeys(projectJson),\n cliEnvVars: resolveEnvVars(cliEnv, CLI_ENV_VARS),\n buildEnvVars: resolveEnvVars(buildEnv, BUILD_ENV_VARS),\n },\n telemetry: {\n enabled: telemetry.isEnabled(),\n correlationId: telemetry.correlationId,\n },\n files: {\n '.env.local': existsSync(join(cwd, '.env.local')),\n '.env': existsSync(join(cwd, '.env')),\n '.bigcommerce/project.json': existsSync(join(cwd, '.bigcommerce', 'project.json')),\n '.bigcommerce/wrangler.jsonc': existsSync(join(cwd, '.bigcommerce', 'wrangler.jsonc')),\n '.open-next/': existsSync(join(cwd, '.open-next')),\n 'package.json': existsSync(join(cwd, 'package.json')),\n },\n };\n}\n","import { confirm } from '@inquirer/prompts';\nimport AdmZip from 'adm-zip';\nimport { Command, Option } from 'commander';\nimport { colorize } from 'consola/utils';\nimport { access, readdir, readFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport yoctoSpinner from 'yocto-spinner';\nimport { z } from 'zod';\n\nimport { assertAuthorized } from '../lib/auth-errors';\nimport { loadBuildEnv } from '../lib/build-env';\nimport { runChannelCheckoutUrlFlow } from '../lib/channel-checkout-url-flow';\nimport { runChannelSiteUrlFlow } from '../lib/channel-site-flow';\nimport {\n cleanupCloudflareIncompatibilities,\n NoLinkedProjectError,\n reconcileOpenNextVersion,\n selectOrCreateInfrastructureProject,\n setupCommerceHosting,\n} from '../lib/commerce-hosting';\nimport { deployedChannelId, offerChannelUrlUpdates } from '../lib/deploy-channel-urls';\nimport { getDeploymentErrorMessage } from '../lib/deployment-errors';\nimport { detectProjectPackageManager } from '../lib/detect-package-manager';\nimport {\n getStoredEnv,\n mergeDeploymentSecrets,\n parseEnvAssignment,\n toDeploymentSecrets,\n} from '../lib/env-config';\nimport { httpError } from '../lib/http-errors';\nimport { installDependencies } from '../lib/install-dependencies';\nimport { consola } from '../lib/logger';\nimport { getProjectConfig } from '../lib/project-config';\nimport { getProjectState } from '../lib/project-state';\nimport { resolveCredentials } from '../lib/resolve-credentials';\nimport {\n accessTokenOption,\n apiHostOption,\n envPathOption,\n projectUuidOption,\n resolveApiHost,\n storeHashOption,\n} from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\n\nimport { buildCatalystProject, parseWranglerVersion, WRANGLER_VERSION } from './build';\n\nconst stepsEnum = z.enum([\n 'initializing',\n 'downloading',\n 'unzipping',\n 'processing',\n 'deploying',\n 'finalizing',\n 'complete',\n]);\n\nconst STEPS: Record<z.infer<typeof stepsEnum>, string> = {\n initializing: 'Initializing...',\n downloading: 'Downloading...',\n unzipping: 'Unzipping...',\n processing: 'Processing...',\n deploying: 'Deploying...',\n finalizing: 'Finalizing...',\n complete: 'Complete',\n};\n\nconst UploadSignatureSchema = z.object({\n data: z.object({\n upload_url: z.url(),\n upload_uuid: z.string(),\n }),\n});\n\nconst CreateDeploymentSchema = z.object({\n data: z.object({\n deployment_uuid: z.uuid(),\n }),\n});\n\nconst ProjectSchema = z.object({\n data: z.array(\n z.object({\n uuid: z.uuid(),\n name: z.string(),\n }),\n ),\n});\n\nconst DeploymentStatusSchema = z.object({\n deployment_uuid: z.uuid(),\n deployment_status: z.enum(['queued', 'in_progress', 'failed', 'completed']),\n event: z\n .object({\n step: stepsEnum,\n progress: z.number(),\n })\n .nullable(),\n deployment_hostnames: z.array(z.string()).optional(),\n error: z\n .object({\n code: z.number(),\n })\n .optional(),\n});\n\nexport const generateBundleZip = async () => {\n consola.info('Generating bundle...');\n\n const bigcommerceDir = join(process.cwd(), '.bigcommerce');\n const distDir = join(process.cwd(), '.bigcommerce', 'dist');\n\n // Check if .bigcommerce/dist exists\n try {\n await access(distDir);\n } catch {\n throw new Error(`Dist directory not found: ${distDir}`);\n }\n\n // Check if .bigcommerce/dist is not empty\n const buildDirContents = await readdir(distDir);\n\n if (buildDirContents.length === 0) {\n throw new Error(`Dist directory is empty: ${distDir}`);\n }\n\n const outputZip = join(bigcommerceDir, 'bundle.zip');\n\n // Use AdmZip to create the zip\n const zip = new AdmZip();\n\n zip.addLocalFolder(distDir, 'output');\n zip.writeZip(outputZip);\n\n consola.success(`Bundle created at: ${outputZip}`);\n};\n\nexport const generateUploadSignature = async (\n storeHash: string,\n accessToken: string,\n apiHost: string,\n) => {\n consola.info('Generating upload signature...');\n\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/deployments/uploads`,\n {\n method: 'POST',\n headers: {\n 'X-Auth-Token': accessToken,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'X-Correlation-Id': getTelemetry().correlationId,\n },\n body: JSON.stringify({}),\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to generate upload signature');\n }\n\n const res: unknown = await response.json();\n const { data } = UploadSignatureSchema.parse(res);\n\n consola.success('Upload signature generated.');\n\n return data;\n};\n\nexport const uploadBundleZip = async (uploadUrl: string) => {\n consola.info('Uploading bundle...');\n\n const zipPath = join(process.cwd(), '.bigcommerce', 'bundle.zip');\n\n // Read the zip file as a buffer\n const fileBuffer = await readFile(zipPath);\n\n const response = await fetch(uploadUrl, {\n method: 'PUT',\n headers: {\n 'Content-Type': 'application/zip',\n },\n body: fileBuffer,\n });\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to upload bundle');\n }\n\n consola.success('Bundle uploaded successfully.');\n\n return true;\n};\n\nconst NATIVE_HOSTING_ENV = {\n type: 'plain_text',\n key: 'CATALYST_HOSTING',\n value: 'native',\n} as const;\n\nexport const parseEnvironmentVariables = (secretOption?: string[]) => {\n return secretOption?.map((envVar) => {\n const { key, value } = parseEnvAssignment(envVar);\n\n return {\n type: 'secret' as const,\n key,\n value,\n };\n });\n};\n\nexport const createDeployment = async (\n projectUuid: string,\n uploadUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n environmentVariables?: Array<{ type: 'secret' | 'plain_text'; key: string; value: string }>,\n) => {\n consola.info('Creating deployment...');\n\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/deployments`,\n {\n method: 'POST',\n headers: {\n 'X-Auth-Token': accessToken,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'X-Correlation-Id': getTelemetry().correlationId,\n },\n body: JSON.stringify({\n project_uuid: projectUuid,\n upload_uuid: uploadUuid,\n environment_variables: environmentVariables,\n }),\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to create deployment');\n }\n\n const res: unknown = await response.json();\n const { data } = CreateDeploymentSchema.parse(res);\n\n consola.success('Deployment started...');\n\n return data;\n};\n\nexport const getDeploymentStatus = async (\n deploymentUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<string | undefined> => {\n consola.info('Fetching deployment status...');\n\n const spinner = yoctoSpinner().start('Fetching...');\n\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/deployments/${deploymentUuid}/events`,\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n Accept: 'text/event-stream',\n Connection: 'keep-alive',\n 'X-Correlation-Id': getTelemetry().correlationId,\n },\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to open deployment event stream');\n }\n\n const reader = response.body?.getReader();\n\n if (!reader) {\n throw new Error('Failed to read event stream.');\n }\n\n const decoder = new TextDecoder();\n let done = false;\n let deploymentHostname: string | undefined;\n\n while (!done) {\n // eslint-disable-next-line no-await-in-loop\n const { value, done: streamDone } = await reader.read();\n let json: unknown;\n\n if (value) {\n const chunk = decoder.decode(value, { stream: true }).trim();\n const split = chunk\n .split('\\n\\n')\n .map((s) => s.replace('data:', '').trim())\n .filter(Boolean);\n\n // eslint-disable-next-line no-loop-func\n split.forEach((event) => {\n try {\n json = JSON.parse(event);\n } catch (error) {\n consola.warn(`Failed to parse event, dropping from stream. Event: ${event}`, error);\n\n return;\n }\n\n const data = DeploymentStatusSchema.parse(json);\n\n if (data.error) {\n throw new Error(\n `Deployment failed (error code ${data.error.code}): ${getDeploymentErrorMessage(data.error.code)}`,\n );\n }\n\n if (data.event && STEPS[data.event.step] !== spinner.text) {\n spinner.text = STEPS[data.event.step];\n }\n\n if (data.deployment_hostnames && data.deployment_hostnames.length > 0) {\n deploymentHostname = data.deployment_hostnames[0];\n }\n });\n }\n\n done = streamDone;\n }\n\n spinner.success('Deployment completed successfully.');\n\n if (deploymentHostname) {\n consola.success(\n `View your deployment at: ${colorize('blue', `https://${deploymentHostname}`)}`,\n );\n }\n\n return deploymentHostname;\n};\n\nexport const fetchProject = async (\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n) => {\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/projects`,\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n 'X-Correlation-Id': getTelemetry().correlationId,\n },\n },\n );\n\n assertAuthorized(response);\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch projects');\n }\n\n const res: unknown = await response.json();\n const { data } = ProjectSchema.parse(res);\n\n return data.find((project) => project.uuid === projectUuid);\n};\n\nexport const deploy = new Command('deploy')\n .configureHelp({ showGlobalOptions: true })\n .description('Deploy your application to Cloudflare.')\n .addHelpText(\n 'after',\n `\nEnvironment variables saved with \\`catalyst env add\\` are sent automatically on every deploy.\nUse \\`--secret\\` to set or override a variable for a single run.\n\nWithout \\`--update-site-url\\` or \\`--update-checkout-url\\`, an interactive deploy offers to\npoint the channel's site URL at the deployment and to move its checkout onto the same domain.\nEach is checked on every deploy; declining either is saved in .bigcommerce/project.json.\n\nExample:\n $ catalyst deploy --secret BIGCOMMERCE_STORE_HASH=<YOUR_STORE_HASH> --secret BIGCOMMERCE_STOREFRONT_TOKEN=<YOUR_STOREFRONT_TOKEN>`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option(\n '--update-site-url',\n \"After a successful deploy, prompt to update a channel's site URL to the new hostname.\",\n )\n .option(\n '--update-checkout-url',\n \"After a successful deploy, prompt to update a channel's checkout URL.\",\n )\n .addOption(\n new Option(\n '--secret <value>',\n 'Secret to set for this deployment (repeatable). Overrides a stored value for the same key. Format: --secret KEY=VALUE',\n ).argParser((value: string, previous: string[] = []) => {\n return previous.concat([value]);\n }),\n )\n .option('--dry-run', 'Run the command to generate the bundle without uploading or deploying.')\n .option(\n '--prebuilt',\n 'Skip the build step. Requires .bigcommerce/dist/ to already contain build output.',\n )\n .addOption(\n new Option(\n '--wrangler-version <version>',\n `Wrangler version or dist-tag to build with. Ignored with --prebuilt. Defaults to ${WRANGLER_VERSION}.`,\n ).argParser(parseWranglerVersion),\n )\n .addOption(envPathOption())\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n const telemetry = getTelemetry();\n\n await telemetry.identify(storeHash);\n\n // Resolve a *valid* projectUuid before doing any expensive build/upload\n // work. If the linked UUID no longer exists on the server (e.g. project\n // deleted out from under us), prompt the user to pick a new one rather\n // than failing mid-deploy.\n const linkedProjectUuid = options.projectUuid ?? config.get('projectUuid');\n let projectUuid: string;\n\n const promptForProject = async (): Promise<{ uuid: string; name: string }> => {\n try {\n return await selectOrCreateInfrastructureProject({\n storeHash,\n accessToken,\n apiHost,\n });\n } catch (error) {\n if (error instanceof NoLinkedProjectError) {\n consola.info(\n \"When you're ready to create a project, run `catalyst projects create` or re-run `catalyst deploy`.\",\n );\n process.exit(0);\n }\n\n throw error;\n }\n };\n\n if (linkedProjectUuid) {\n const existing = await fetchProject(linkedProjectUuid, storeHash, accessToken, apiHost);\n\n if (existing) {\n projectUuid = linkedProjectUuid;\n } else {\n consola.warn(\n `The linked project (${linkedProjectUuid}) no longer exists on this store. It may have been deleted.`,\n );\n\n const selected = await promptForProject();\n\n projectUuid = selected.uuid;\n config.set('projectUuid', projectUuid);\n consola.success(`Linked project \"${selected.name}\".`);\n }\n } else {\n consola.info('No project is currently linked.');\n\n const selected = await promptForProject();\n\n projectUuid = selected.uuid;\n config.set('projectUuid', projectUuid);\n consola.success(`Linked project \"${selected.name}\".`);\n }\n\n // The OpenNext build pipeline requires the project to be transformed\n // (proxy.ts → middleware.ts, @opennextjs/cloudflare installed). Run setup\n // here so first-run `catalyst deploy` works on a fresh self-hosted scaffold\n // without forcing the user to re-run after a separate setup step.\n if (!getProjectState().isTransformed) {\n const shouldSetup = await confirm({\n message:\n 'Your project is not yet set up for Commerce Hosting deployments. Would you like to run the Commerce Hosting setup now?',\n default: true,\n });\n\n if (!shouldSetup) {\n consola.info(\"When you're ready to deploy, re-run `catalyst deploy` to complete setup.\");\n process.exit(0);\n }\n\n const projectDir = process.cwd();\n\n await setupCommerceHosting({ projectDir, projectUuid, storeHash, accessToken });\n consola.success('Commerce Hosting setup complete.');\n\n // Match the manager the project was scaffolded with (from its lockfile),\n // rather than forcing pnpm on npm/yarn/bun projects.\n const packageManager = await detectProjectPackageManager(projectDir);\n\n await installDependencies(projectDir, packageManager);\n } else {\n // Existing Commerce Hosting users may carry artifacts incompatible with\n // the Cloudflare worker bundle from earlier Catalyst versions\n // (`core/instrumentation.ts`, `@vercel/otel`). Sweep them on every deploy\n // so the fix lands without forcing a re-link.\n await cleanupCloudflareIncompatibilities(process.cwd());\n\n // The build path offers to move a stale adapter pin. `--prebuilt` skips\n // the build, so surface it here instead -- without changing dependencies\n // the existing bundle was never compiled against.\n if (options.prebuilt) {\n const projectDir = process.cwd();\n\n await reconcileOpenNextVersion(projectDir, await detectProjectPackageManager(projectDir), {\n canUpgrade: false,\n });\n }\n }\n\n if (options.prebuilt) {\n const distDir = join(process.cwd(), '.bigcommerce', 'dist');\n\n try {\n await access(distDir);\n } catch {\n throw new Error(\n 'No build output found at .bigcommerce/dist/. Run `catalyst build` first or remove `--prebuilt` to build automatically.',\n );\n }\n\n const contents = await readdir(distDir);\n\n if (contents.length === 0) {\n throw new Error(\n 'No build output found at .bigcommerce/dist/. Run `catalyst build` first or remove `--prebuilt` to build automatically.',\n );\n }\n\n consola.info('Using existing build output (--prebuilt).');\n } else {\n // The build reads storefront env vars (BIGCOMMERCE_*). Load them from the\n // env file(s) before building so both the build and any pre-build checks\n // see them. Skipped for --prebuilt above, which doesn't run the build.\n loadBuildEnv({ envPath: options.envPath });\n\n await buildCatalystProject(projectUuid, options.wranglerVersion);\n }\n\n await generateBundleZip();\n\n if (options.dryRun) {\n consola.info('Dry run enabled — skipping upload and deployment steps.');\n consola.info('Next steps (skipped):');\n consola.info('- Generate upload signature');\n consola.info('- Upload bundle.zip');\n consola.info('- Create deployment');\n\n process.exit(0);\n }\n\n const uploadSignature = await generateUploadSignature(storeHash, accessToken, apiHost);\n\n await uploadBundleZip(uploadSignature.upload_url);\n\n // Merge persisted env vars (`catalyst env add`) with any inline `--secret`\n // flags. Inline flags win on conflict, letting users override a stored\n // value for a single run.\n const flagSecrets = parseEnvironmentVariables(options.secret) ?? [];\n const persistedSecrets = toDeploymentSecrets(getStoredEnv(config));\n const mergedSecrets = mergeDeploymentSecrets(persistedSecrets, flagSecrets);\n const environmentVariables = [...mergedSecrets, NATIVE_HOSTING_ENV];\n\n const { deployment_uuid: deploymentUuid } = await createDeployment(\n projectUuid,\n uploadSignature.upload_uuid,\n storeHash,\n accessToken,\n apiHost,\n environmentVariables,\n );\n\n const deploymentHostname = await getDeploymentStatus(\n deploymentUuid,\n storeHash,\n accessToken,\n apiHost,\n );\n\n // Soft-failed: the bundle is already live, so a non-zero exit here would\n // misrepresent what happened.\n const warnChannelFlowFailed = (what: string, error: unknown) => {\n consola.warn(\n `Failed to update channel ${what}: ${error instanceof Error ? error.message : String(error)}`,\n );\n consola.info(\n 'Update it manually in the control panel, or re-run `catalyst auth login` if the token is missing the store_channel_settings scope.',\n );\n };\n\n // Carried over so both flags don't ask which channel twice.\n let resolvedChannelId: number | undefined;\n\n // Set by --update-site-url, so checkout pairs with the hostname actually used.\n let siteHostname: string | undefined;\n\n if (options.updateSiteUrl) {\n try {\n ({ channelId: resolvedChannelId, hostname: siteHostname } = await runChannelSiteUrlFlow({\n storeHash,\n accessToken,\n apiHost,\n projectUuid,\n preferHostname: deploymentHostname,\n }));\n } catch (error) {\n warnChannelFlowFailed('site URL', error);\n }\n }\n\n if (options.updateCheckoutUrl) {\n try {\n await runChannelCheckoutUrlFlow({\n storeHash,\n accessToken,\n apiHost,\n channelId: resolvedChannelId,\n storefrontHostname: siteHostname,\n });\n } catch (error) {\n warnChannelFlowFailed('checkout URL', error);\n }\n }\n\n // Neither flag: offer both. Explicit flags mean the caller already decided.\n if (!options.updateSiteUrl && !options.updateCheckoutUrl) {\n try {\n await offerChannelUrlUpdates({\n storeHash,\n accessToken,\n apiHost,\n projectUuid,\n config,\n deploymentHostname,\n channelId: deployedChannelId(mergedSecrets),\n });\n } catch (error) {\n warnChannelFlowFailed('URLs', error);\n }\n }\n });\n","import { confirm } from '@inquirer/prompts';\n\nimport { canPrompt } from './can-prompt';\nimport { offerManagedCheckoutUrl } from './channel-checkout-url-flow';\nimport { runChannelSiteUrlFlow } from './channel-site-flow';\nimport { findChannelSiteUrl, getChannelSite } from './channels';\nimport { isManagedHostingHostname } from './checkout-url';\nimport { type DeploymentSecret } from './env-config';\nimport { consola } from './logger';\nimport { fetchProjects } from './project';\nimport { type getProjectConfig } from './project-config';\n\nexport interface DeployChannelUrlOptions {\n storeHash: string;\n accessToken: string;\n apiHost: string;\n projectUuid: string;\n config: ReturnType<typeof getProjectConfig>;\n // The hostname the deploy just went live on.\n deploymentHostname?: string;\n // The channel the storefront was built for, if known.\n channelId?: number;\n}\n\n// The channel a deployment serves. Deployment secrets win, as in OpenNext's\n// runtime; env files are the fallback (not loaded with `--prebuilt`).\nexport function deployedChannelId(secrets: DeploymentSecret[]): number | undefined {\n const raw =\n secrets.find((secret) => secret.key === 'BIGCOMMERCE_CHANNEL_ID')?.value ??\n process.env.BIGCOMMERCE_CHANNEL_ID;\n const id = Number(raw);\n\n return Number.isInteger(id) && id > 0 ? id : undefined;\n}\n\n// After an interactive deploy, offers to point the channel at the deployment\n// and to move its checkout onto the same domain. Each is checked on every\n// deploy; a decline is saved per channel.\nexport async function offerChannelUrlUpdates(options: DeployChannelUrlOptions): Promise<void> {\n const { storeHash, accessToken, apiHost, projectUuid, config, channelId } = options;\n\n // No channel means nothing to key the opt-outs on.\n if (!canPrompt() || channelId === undefined) return;\n\n const [site, projects] = await Promise.all([\n getChannelSite(channelId, storeHash, accessToken, apiHost),\n fetchProjects(storeHash, accessToken, apiHost),\n ]);\n const deploymentHostnames =\n projects.find((project) => project.uuid === projectUuid)?.deployment_hostnames ?? [];\n const storefrontUrl = (findChannelSiteUrl(site, 'primary') ?? site.url).replace(/\\/$/, '');\n\n let storefrontHostname = deploymentHostnames.find(\n (deployed) => storefrontUrl === `https://${deployed}`,\n );\n\n storefrontHostname ??= await offerSiteUrl({ ...options, channelId }, storefrontUrl);\n\n // Not on this project, so a `c.` hostname under it wouldn't match.\n if (storefrontHostname === undefined) return;\n\n await offerManagedCheckoutUrl({\n storeHash,\n accessToken,\n apiHost,\n channelId,\n storefrontHostname,\n config,\n respectOptOut: true,\n defaultAnswer: false,\n });\n}\n\n// Resolves the hostname the site URL was set to, or undefined when it wasn't.\nasync function offerSiteUrl(\n options: DeployChannelUrlOptions & { channelId: number },\n storefrontUrl: string,\n): Promise<string | undefined> {\n const { storeHash, accessToken, apiHost, projectUuid, config, channelId } = options;\n const declined = config.get('declinedSiteUrlChannels') ?? [];\n\n if (declined.includes(channelId)) return undefined;\n\n const shouldUpdate = await confirm({\n message: `Channel ${channelId}'s site URL is ${storefrontUrl}. Point it at this deployment?`,\n // Unasked-for after a deploy, so Enter mustn't change a live channel.\n default: false,\n });\n\n if (!shouldUpdate) {\n config.set('declinedSiteUrlChannels', [...declined, channelId]);\n consola.info(\n `Won't ask again for channel ${channelId}. To change it later, run ` +\n `\\`catalyst channels update --channel-id ${channelId}\\`.`,\n );\n\n return undefined;\n }\n\n const { hostname } = await runChannelSiteUrlFlow({\n storeHash,\n accessToken,\n apiHost,\n projectUuid,\n // The deploy knows both; the hostname picker only shows if it reported none.\n channelId,\n hostname: options.deploymentHostname,\n // On the managed zone the checkout offer follows; elsewhere, warn instead.\n diagnoseCheckout: !isManagedHostingHostname(options.deploymentHostname ?? ''),\n });\n\n return hostname;\n}\n","const ERROR_MESSAGES: Record<number, string> = {\n 10: 'Something went wrong on our end. Please try again. If the issue persists, contact support.',\n 20: \"We couldn't retrieve your bundle. This is usually a temporary issue — please try deploying again. If the problem continues, contact support.\",\n 30: 'Your bundle could not be extracted. This may mean your build output is too large (max 64 MB compressed / 512 MB uncompressed) or the archive is corrupted. Try reducing your build size or rebuilding your project and deploying again.',\n 40: `There's a problem with your build output. This could be caused by:\n- A worker.js file larger than 40 MB\n- An individual asset file larger than 25 MB\n- More than 1,000 total files in the bundle`,\n 50: 'Deployment failed. This is usually a temporary issue — please try again. If the problem persists, contact support.',\n 60: \"Your code was deployed, but we couldn't determine your deployment URL. Please try deploying again. If the issue persists, contact support.\",\n};\n\nexport function getDeploymentErrorMessage(code: number): string {\n return (\n ERROR_MESSAGES[code] ??\n `Deployment failed with an unexpected error (code: ${code}). Please try again. If the issue persists, contact support.`\n );\n}\n","import { confirm, select } from '@inquirer/prompts';\nimport { Command, Option } from 'commander';\nimport { colorize } from 'consola/utils';\n\nimport {\n claimDomain,\n CreatedDomain,\n createDomain,\n deleteDomain,\n Domain,\n DomainBoundToProjectError,\n DomainOwnershipVerificationError,\n DomainStatus,\n DomainStatusFilter,\n findDomain,\n getDomain,\n listDomains,\n OwnershipVerification,\n PointingRecords,\n transferDomain,\n} from '../lib/domains';\nimport { UserActionableError } from '../lib/errors';\nimport { consola } from '../lib/logger';\nimport { fetchProjects } from '../lib/project';\nimport { getProjectConfig } from '../lib/project-config';\nimport { resolveCredentials } from '../lib/resolve-credentials';\nimport {\n accessTokenOption,\n apiHostOption,\n projectUuidOption,\n resolveApiHost,\n resolveProjectUuid,\n storeHashOption,\n} from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\n\nconst WAIT_INTERVAL_MS = 5000;\nconst WAIT_TIMEOUT_MS = 5 * 60 * 1000;\nconst DOMAIN_STATUS_FILTERS: DomainStatusFilter[] = ['pending', 'verified', 'failed'];\nconst RECORD_TYPE_WIDTH = 'CNAME'.length;\n\nconst STATUS_COLORS: Record<DomainStatus, Parameters<typeof colorize>[0]> = {\n pending: 'yellow',\n verified: 'green',\n failed: 'red',\n unknown: 'gray',\n};\n\nconst STATUS_LABELS: Record<DomainStatus, string> = {\n pending: 'pending',\n verified: 'active',\n failed: 'failed',\n unknown: 'unknown',\n};\n\ninterface DomainCommandContext {\n projectUuid: string;\n storeHash: string;\n accessToken: string;\n apiHost: string;\n}\n\ninterface DomainCommandOptions {\n storeHash?: string;\n accessToken?: string;\n apiHost?: string;\n projectUuid?: string;\n}\n\ninterface WaitForDomainVerificationOptions extends DomainCommandContext {\n domain: string;\n intervalMs?: number;\n timeoutMs?: number;\n}\n\nconst sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));\n\nfunction resolveDomainCommandContext(options: DomainCommandOptions): DomainCommandContext {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n const projectUuid = resolveProjectUuid(options);\n\n return {\n projectUuid,\n storeHash,\n accessToken,\n apiHost,\n };\n}\n\n// Resolves the destination project for a transfer. Uses `--to-project-uuid`\n// when given; otherwise fetches the store's projects and prompts the user to\n// pick one, excluding the source project (a domain can't be transferred to the\n// project it already belongs to).\nasync function resolveDestinationProject(\n domain: string,\n context: DomainCommandContext,\n toProjectUuid?: string,\n): Promise<string> {\n if (toProjectUuid) {\n if (toProjectUuid === context.projectUuid) {\n throw new UserActionableError('The destination project must differ from the source project.');\n }\n\n return toProjectUuid;\n }\n\n consola.start('Fetching projects...');\n\n const projects = await fetchProjects(context.storeHash, context.accessToken, context.apiHost);\n\n consola.success('Projects fetched.');\n\n const destinations = projects.filter((project) => project.uuid !== context.projectUuid);\n\n if (destinations.length === 0) {\n throw new UserActionableError(\n 'No other projects to transfer to. Create another project with `catalyst projects create` first.',\n );\n }\n\n return select({\n message: `Select the project to transfer ${domain} to (Press <enter> to select).`,\n choices: destinations.map((project) => ({\n name: project.name,\n value: project.uuid,\n description: project.uuid,\n })),\n });\n}\n\nexport function formatDomainStatus(status: DomainStatus): string {\n return colorize(STATUS_COLORS[status], STATUS_LABELS[status]);\n}\n\nexport function formatDomain(domain: Domain): string {\n return `${domain.domain} ${formatDomainStatus(domain.verification_status)}`;\n}\n\n// Renders the records to publish as an indented block:\n//\n// A 198.51.100.10\n// CNAME shop.hosting.bigcommerce.com\n//\n// Returns null when there's nothing publishable: the API withholds the records\n// until the domain is bound, and nulls individual values it doesn't have.\nexport function formatPointingRecords(records?: PointingRecords | null): string | null {\n const rows: string[] = [];\n\n if (records?.a_record_value) {\n rows.push(`${'A'.padEnd(RECORD_TYPE_WIDTH)} ${records.a_record_value}`);\n }\n\n if (records?.cname_record_value) {\n rows.push(`${'CNAME'.padEnd(RECORD_TYPE_WIDTH)} ${records.cname_record_value}`);\n }\n\n if (rows.length === 0) {\n return null;\n }\n\n return rows.map((row) => ` ${row}`).join('\\n');\n}\n\nexport function formatOwnershipVerification(record: OwnershipVerification): string {\n const lines = [\n 'Add this DNS record to verify ownership:',\n ` Type: ${record.type}`,\n ` Name: ${record.name}`,\n ];\n\n if (record.value) {\n lines.push(` Value: ${record.value}`);\n }\n\n return lines.join('\\n');\n}\n\nexport async function waitForDomainVerification({\n domain,\n projectUuid,\n storeHash,\n accessToken,\n apiHost,\n intervalMs = WAIT_INTERVAL_MS,\n timeoutMs = WAIT_TIMEOUT_MS,\n}: WaitForDomainVerificationOptions): Promise<Domain> {\n const startedAt = Date.now();\n let current = await getDomain(domain, projectUuid, storeHash, accessToken, apiHost);\n\n while (current.verification_status === 'pending' && Date.now() - startedAt < timeoutMs) {\n // eslint-disable-next-line no-await-in-loop\n await sleep(intervalMs);\n // eslint-disable-next-line no-await-in-loop\n current = await getDomain(domain, projectUuid, storeHash, accessToken, apiHost);\n }\n\n return current;\n}\n\nconst add = new Command('add')\n .configureHelp({ showGlobalOptions: true })\n .description('Add a custom domain to the current Native Hosting project.')\n .argument('<domain>', 'Custom domain to add.')\n .addHelpText(\n 'after',\n `\nThe DNS records that point the domain at this project are printed once the domain\nis added. They are returned only by this command, so save them: publish the CNAME\nfor a subdomain, or the A record for an apex domain.\n\nExamples:\n $ catalyst domains add www.example.com\n\n # Wait until the domain leaves pending verification\n $ catalyst domains add www.example.com --wait`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--wait', 'Poll until domain verification completes or times out.')\n .action(async (domain, options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n consola.start(`Adding domain ${domain}...`);\n\n let created: CreatedDomain;\n\n try {\n created = await createDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n } catch (error) {\n if (error instanceof DomainOwnershipVerificationError) {\n consola.warn(`${domain} is already in use on another store.`);\n consola.log(formatOwnershipVerification(error.ownershipVerification));\n consola.info('Once the record is live, claim it with:');\n consola.log(` catalyst domains claim ${domain}`);\n process.exit(1);\n\n return;\n }\n\n if (error instanceof DomainBoundToProjectError) {\n consola.warn(`${domain} is already bound to another project in this store.`);\n consola.info('To move it to this project, run:');\n consola.log(\n ` catalyst domains transfer ${domain} --project-uuid ${error.projectUuid} --to-project-uuid ${context.projectUuid}`,\n );\n process.exit(1);\n\n return;\n }\n\n throw error;\n }\n\n consola.success(`Domain ${created.domain} added.`);\n\n // Only the create response carries the records, so they're read from\n // `created` rather than from `result` — polling re-fetches the domain\n // resource, which doesn't include them.\n const records = formatPointingRecords(created.pointing_records);\n let result: Domain = created;\n\n if (options.wait && result.verification_status === 'pending') {\n consola.start(`Waiting for ${result.domain} to verify...`);\n result = await waitForDomainVerification({ domain: result.domain, ...context });\n }\n\n consola.log(formatDomain(result));\n\n if (records) {\n consola.info(`Point ${created.domain} at this project with one of these DNS records:`);\n consola.log(records);\n consola.info(\n 'Use the CNAME for a subdomain, or the A record for an apex domain. Save them now — only `domains add` returns them.',\n );\n }\n\n if (result.verification_status === 'pending') {\n consola.info(\n `Run \\`catalyst domains status ${result.domain}\\` to check verification progress.`,\n );\n }\n\n process.exit(0);\n });\n\nconst list = new Command('list')\n .configureHelp({ showGlobalOptions: true })\n .description('List custom domains for the current Native Hosting project.')\n .addHelpText(\n 'after',\n `\nExamples:\n $ catalyst domains list\n\n # Show pending domains only\n $ catalyst domains list --status pending`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--domain <domain>', 'Only show a specific domain.')\n .addOption(\n new Option('--status <status>', 'Filter by verification status.').choices(\n DOMAIN_STATUS_FILTERS,\n ),\n )\n .action(async (options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n consola.start('Fetching domains...');\n\n const result = await listDomains(\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n {\n domains: options.domain ? [options.domain] : undefined,\n verificationStatus: options.status,\n },\n );\n\n consola.success('Domains fetched.');\n\n if (result.length === 0) {\n consola.info('No custom domains found.');\n process.exit(0);\n\n return;\n }\n\n result.forEach((item) => consola.log(formatDomain(item)));\n process.exit(0);\n });\n\nconst showStatus = new Command('status')\n .configureHelp({ showGlobalOptions: true })\n .description('Show the status of a custom domain on the current Native Hosting project.')\n .argument('<domain>', 'Custom domain to check.')\n .addHelpText(\n 'after',\n `\nExamples:\n $ catalyst domains status www.example.com\n\n # Wait until the domain leaves pending verification\n $ catalyst domains status www.example.com --wait`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--wait', 'Poll until domain verification completes or times out.')\n .action(async (domain, options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n consola.start(`Fetching status for ${domain}...`);\n\n let result = await getDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n consola.success('Domain status fetched.');\n\n if (options.wait && result.verification_status === 'pending') {\n consola.start(`Waiting for ${result.domain} to verify...`);\n result = await waitForDomainVerification({ domain: result.domain, ...context });\n }\n\n consola.log(formatDomain(result));\n process.exit(0);\n });\n\nconst claim = new Command('claim')\n .configureHelp({ showGlobalOptions: true })\n .description('Claim a custom domain that is currently in use on another store.')\n .argument('<domain>', 'Custom domain to claim.')\n .addHelpText(\n 'after',\n `\nClaiming requires publishing the ownership-verification TXT record returned when\nyou try to add a domain that is already in use on another store. Publish the\nrecord with your DNS provider, then run this command to complete the claim.\n\nExamples:\n $ catalyst domains claim www.example.com\n\n # Wait until the claimed domain leaves pending verification\n $ catalyst domains claim www.example.com --wait`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--wait', 'Poll until domain verification completes or times out.')\n .action(async (domain, options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n consola.start(`Claiming domain ${domain}...`);\n\n try {\n await claimDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n } catch (error) {\n if (error instanceof DomainOwnershipVerificationError) {\n consola.warn(`Ownership of ${domain} could not be verified yet.`);\n consola.log(formatOwnershipVerification(error.ownershipVerification));\n consola.info('Once the record is live, run the claim again:');\n consola.log(` catalyst domains claim ${domain}`);\n process.exit(1);\n\n return;\n }\n\n throw error;\n }\n\n consola.success(`Domain ${domain} claimed.`);\n\n let result = await getDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n if (options.wait && result.verification_status === 'pending') {\n consola.start(`Waiting for ${result.domain} to verify...`);\n result = await waitForDomainVerification({ domain: result.domain, ...context });\n }\n\n consola.log(formatDomain(result));\n process.exit(0);\n });\n\nconst transfer = new Command('transfer')\n .configureHelp({ showGlobalOptions: true })\n .description('Transfer a custom domain to another project in the same store.')\n .argument('<domain>', 'Custom domain to transfer.')\n .addHelpText(\n 'after',\n `\nThe domain is transferred from the current project to the destination project.\nOmit --to-project-uuid to pick the destination from a list of your projects.\n\nExamples:\n # Pick the destination project interactively\n $ catalyst domains transfer www.example.com\n\n # Transfer to a specific project\n $ catalyst domains transfer www.example.com --to-project-uuid <uuid>`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--to-project-uuid <uuid>', 'Destination project UUID. Prompts to choose one if omitted.')\n .option('--wait', 'Poll until domain verification completes or times out.')\n .action(async (domain, options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n // Confirm the domain is on the source project before doing anything else.\n // `transfer` moves a domain *from* the current project, so a domain that\n // lives elsewhere can't be transferred from here — catch it now instead of\n // letting the API reject the transfer with an opaque ownership error after\n // the user has already picked a destination.\n consola.start(`Checking ${domain} on the current project...`);\n\n const owned = await findDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n if (!owned) {\n // The domain isn't on the linked project. Scan the store's other projects\n // so we can point the user at the exact owner — `domains list` only shows\n // the *current* project's domains, so it can't help them find where the\n // domain actually lives.\n consola.start(`Locating the project that owns ${domain}...`);\n\n const projects = await fetchProjects(context.storeHash, context.accessToken, context.apiHost);\n const candidates = projects.filter((project) => project.uuid !== context.projectUuid);\n const matches = await Promise.all(\n candidates.map(async (project) => ({\n project,\n found: await findDomain(\n domain,\n project.uuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n ),\n })),\n );\n const owner = matches.find((match) => match.found)?.project;\n\n if (!owner) {\n throw new UserActionableError(\n `${domain} isn't on any project in this store. If it's in use on another store, ` +\n `claim it with \\`catalyst domains claim ${domain}\\`; otherwise double-check the domain name.`,\n );\n }\n\n const toSuffix = options.toProjectUuid ? ` --to-project-uuid ${options.toProjectUuid}` : '';\n\n consola.warn(\n `${domain} is on project \"${owner.name}\" (${owner.uuid}), not the current project.`,\n );\n consola.info('Re-run the transfer from that project:');\n consola.log(` catalyst domains transfer ${domain} --project-uuid ${owner.uuid}${toSuffix}`);\n process.exit(1);\n\n return;\n }\n\n consola.success(`${domain} found on the current project.`);\n\n const newProjectUuid = await resolveDestinationProject(domain, context, options.toProjectUuid);\n\n consola.start(`Transferring domain ${domain}...`);\n\n await transferDomain(\n domain,\n context.projectUuid,\n newProjectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n consola.success(`Domain ${domain} transferred.`);\n\n let result = await getDomain(\n domain,\n newProjectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n if (options.wait && result.verification_status === 'pending') {\n consola.start(`Waiting for ${result.domain} to verify...`);\n result = await waitForDomainVerification({\n domain: result.domain,\n projectUuid: newProjectUuid,\n storeHash: context.storeHash,\n accessToken: context.accessToken,\n apiHost: context.apiHost,\n });\n }\n\n consola.log(formatDomain(result));\n process.exit(0);\n });\n\nconst remove = new Command('remove')\n .configureHelp({ showGlobalOptions: true })\n .description('Remove a custom domain from the current Native Hosting project.')\n .argument('<domain>', 'Custom domain to remove.')\n .addHelpText(\n 'after',\n `\nExamples:\n $ catalyst domains remove www.example.com\n\n # Skip confirmation for an active domain\n $ catalyst domains remove www.example.com --force`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--force', 'Skip the confirmation prompt before removing an active domain.')\n .action(async (domain, options) => {\n const context = resolveDomainCommandContext(options);\n\n await getTelemetry().identify(context.storeHash);\n\n consola.start(`Fetching status for ${domain}...`);\n\n const current = await getDomain(\n domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n if (current.verification_status === 'verified' && !options.force) {\n const confirmed = await confirm({\n message: `Remove active domain ${current.domain}? Traffic may stop routing to this project.`,\n default: false,\n });\n\n if (!confirmed) {\n consola.info('Aborted. No domain was removed.');\n process.exit(0);\n\n return;\n }\n }\n\n consola.start(`Removing domain ${current.domain}...`);\n\n await deleteDomain(\n current.domain,\n context.projectUuid,\n context.storeHash,\n context.accessToken,\n context.apiHost,\n );\n\n consola.success(`Domain ${current.domain} removed.`);\n process.exit(0);\n });\n\nexport const domains = new Command('domains')\n .alias('domain')\n .configureHelp({ showGlobalOptions: true })\n .description('Manage custom domains for the current Native Hosting project.')\n .addCommand(add)\n .addCommand(list)\n .addCommand(showStatus)\n .addCommand(claim)\n .addCommand(transfer)\n .addCommand(remove);\n","/* eslint-disable max-classes-per-file -- the two domain-collision error types are co-located with the response parsing that throws them */\nimport { z } from 'zod';\n\nimport { assertAuthorized } from './auth-errors';\nimport { UserActionableError } from './errors';\nimport { formatV3Error } from './observability';\nimport { getTelemetry } from './telemetry';\n\nexport const domainStatusSchema = z.enum(['pending', 'verified', 'failed', 'unknown']);\n\nexport type DomainStatus = z.infer<typeof domainStatusSchema>;\n\n// The DNS records the merchant publishes to point a domain at their project.\n// The API sends `pointing_records: null` until the domain is bound and the\n// records are known, and nulls individual values it doesn't have, so every\n// field is treated as optional.\nconst pointingRecordsSchema = z.object({\n a_record_value: z.string().nullish(),\n cname_record_value: z.string().nullish(),\n});\n\nexport type PointingRecords = z.infer<typeof pointingRecordsSchema>;\n\nconst domainSchema = z.object({\n domain: z.string(),\n project_uuid: z.string(),\n verification_status: domainStatusSchema,\n});\n\n// Only the create endpoint returns the records — they're layered onto the domain\n// resource in that one response, so the domain shape itself stays without them.\n// A caller that doesn't keep them can't fetch them again.\nconst createdDomainSchema = domainSchema.extend({\n pointing_records: pointingRecordsSchema.nullish(),\n});\n\nconst ownershipVerificationSchema = z.object({\n type: z.string(),\n name: z.string(),\n value: z.string().optional(),\n});\n\nexport type OwnershipVerification = z.infer<typeof ownershipVerificationSchema>;\n\nconst ownershipVerificationMetaSchema = z.object({\n meta: z.object({\n ownership_verification: ownershipVerificationSchema,\n }),\n});\n\n// Raised when the Domains API rejects an add/claim because ownership of a\n// domain bound to another store has not been verified. Carries the TXT record\n// the caller must publish so the command can render actionable next steps\n// instead of an opaque error.\nexport class DomainOwnershipVerificationError extends UserActionableError {\n readonly ownershipVerification: OwnershipVerification;\n\n constructor(message: string, ownershipVerification: OwnershipVerification) {\n super(message);\n this.name = 'DomainOwnershipVerificationError';\n this.ownershipVerification = ownershipVerification;\n }\n}\n\nfunction parseOwnershipVerification(body: unknown): OwnershipVerification | undefined {\n const parsed = ownershipVerificationMetaSchema.safeParse(body);\n\n return parsed.success ? parsed.data.meta.ownership_verification : undefined;\n}\n\nconst boundProjectMetaSchema = z.object({\n meta: z.object({\n project_uuid: z.string(),\n }),\n});\n\n// Raised when the Domains API rejects an add/claim because the domain is\n// already bound to a different project in the *same* store. Carries the UUID of\n// that project so the caller can point the user at `domains transfer`.\nexport class DomainBoundToProjectError extends UserActionableError {\n readonly projectUuid: string;\n\n constructor(message: string, projectUuid: string) {\n super(message);\n this.name = 'DomainBoundToProjectError';\n this.projectUuid = projectUuid;\n }\n}\n\nfunction parseBoundProjectUuid(body: unknown): string | undefined {\n const parsed = boundProjectMetaSchema.safeParse(body);\n\n return parsed.success ? parsed.data.meta.project_uuid : undefined;\n}\n\nconst domainResponseSchema = z.object({\n data: domainSchema,\n});\n\nconst createdDomainResponseSchema = z.object({\n data: createdDomainSchema,\n});\n\nconst domainListResponseSchema = z.object({\n data: z.array(domainSchema),\n});\n\nexport type Domain = z.infer<typeof domainSchema>;\nexport type CreatedDomain = z.infer<typeof createdDomainSchema>;\nexport type DomainStatusFilter = Exclude<DomainStatus, 'unknown'>;\n\ninterface ListDomainsFilters {\n domains?: string[];\n verificationStatus?: DomainStatusFilter;\n}\n\nconst DOMAINS_API_NOT_ENABLED =\n 'Infrastructure Domains API not enabled. If you are part of the beta, contact support@bigcommerce.com to enable it.';\n\nfunction domainsUrl(storeHash: string, projectUuid: string, apiHost: string) {\n return `https://${apiHost}/stores/${storeHash}/v3/infrastructure/projects/${projectUuid}/domains`;\n}\n\nfunction domainUrl(storeHash: string, projectUuid: string, domain: string, apiHost: string) {\n return `${domainsUrl(storeHash, projectUuid, apiHost)}/${encodeURIComponent(domain)}`;\n}\n\nfunction domainClaimUrl(storeHash: string, projectUuid: string, domain: string, apiHost: string) {\n return `${domainUrl(storeHash, projectUuid, domain, apiHost)}/claim`;\n}\n\nfunction domainTransferUrl(\n storeHash: string,\n projectUuid: string,\n domain: string,\n apiHost: string,\n) {\n return `${domainUrl(storeHash, projectUuid, domain, apiHost)}/transfer`;\n}\n\nfunction authHeaders(accessToken: string) {\n return {\n Accept: 'application/json',\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n };\n}\n\nfunction formatResponseStatus(response: Response, message?: string): string {\n return [response.status, response.statusText || message].filter(Boolean).join(' ');\n}\n\nfunction buildErrorMessage(response: Response, body: unknown, action: string): string {\n const message = formatV3Error(body);\n\n if (response.status >= 500) {\n const status = formatResponseStatus(response, message);\n\n return `${action}: ${status}. This is a server-side response from the Domains API.`;\n }\n\n return message ?? `${action}: ${response.statusText}`;\n}\n\n// Throws for any non-OK Domains API response. Surfaces typed errors for the two\n// claimable/movable conflicts so callers can guide the user: a\n// `meta.ownership_verification` TXT record (domain on another store → claim) or\n// a `meta.project_uuid` (domain on another project in this store → transfer).\n// Otherwise throws a plain formatted error.\nasync function assertDomainResponse(response: Response, action: string): Promise<void> {\n assertAuthorized(response);\n\n if (response.status === 403) {\n throw new UserActionableError(DOMAINS_API_NOT_ENABLED);\n }\n\n if (response.ok) {\n return;\n }\n\n const body: unknown = await response.json().catch(() => null);\n const message = buildErrorMessage(response, body, action);\n const ownershipVerification = parseOwnershipVerification(body);\n\n if (ownershipVerification) {\n throw new DomainOwnershipVerificationError(message, ownershipVerification);\n }\n\n const boundProjectUuid = parseBoundProjectUuid(body);\n\n if (boundProjectUuid) {\n throw new DomainBoundToProjectError(message, boundProjectUuid);\n }\n\n // 5xx responses are server-side failures worth escalating, so keep the\n // Correlation ID + support framing. A 4xx (validation, not-found, conflict)\n // is a clear, user-actionable response — surface just the message.\n if (response.status >= 500) {\n throw new Error(message);\n }\n\n throw new UserActionableError(message);\n}\n\nexport async function createDomain(\n domain: string,\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<CreatedDomain> {\n const response = await fetch(domainsUrl(storeHash, projectUuid, apiHost), {\n method: 'POST',\n headers: {\n ...authHeaders(accessToken),\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ domain }),\n });\n\n await assertDomainResponse(response, 'Failed to add domain');\n\n const result: unknown = await response.json();\n\n return createdDomainResponseSchema.parse(result).data;\n}\n\nexport async function getDomain(\n domain: string,\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<Domain> {\n const response = await fetch(domainUrl(storeHash, projectUuid, domain, apiHost), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n await assertDomainResponse(response, 'Failed to fetch domain');\n\n const result: unknown = await response.json();\n\n return domainResponseSchema.parse(result).data;\n}\n\n// Like `getDomain`, but returns null when the domain isn't present on the\n// given project (404) instead of throwing. Used by `transfer` to confirm the\n// source project actually owns the domain before attempting the move, so the\n// user gets clear guidance instead of the API's opaque ownership rejection.\nexport async function findDomain(\n domain: string,\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<Domain | null> {\n const response = await fetch(domainUrl(storeHash, projectUuid, domain, apiHost), {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n if (response.status === 404) {\n return null;\n }\n\n await assertDomainResponse(response, 'Failed to fetch domain');\n\n const result: unknown = await response.json();\n\n return domainResponseSchema.parse(result).data;\n}\n\nexport async function listDomains(\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n filters: ListDomainsFilters = {},\n): Promise<Domain[]> {\n const search = new URLSearchParams();\n\n if (filters.domains && filters.domains.length > 0) {\n search.set('domain:in', filters.domains.join(','));\n }\n\n if (filters.verificationStatus) {\n search.set('verification_status', filters.verificationStatus);\n }\n\n const query = search.toString();\n const url = `${domainsUrl(storeHash, projectUuid, apiHost)}${query ? `?${query}` : ''}`;\n const response = await fetch(url, {\n method: 'GET',\n headers: authHeaders(accessToken),\n });\n\n await assertDomainResponse(response, 'Failed to fetch domains');\n\n const result: unknown = await response.json();\n\n return domainListResponseSchema.parse(result).data;\n}\n\nexport async function deleteDomain(\n domain: string,\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<void> {\n const response = await fetch(domainUrl(storeHash, projectUuid, domain, apiHost), {\n method: 'DELETE',\n headers: authHeaders(accessToken),\n });\n\n await assertDomainResponse(response, `Failed to remove domain: ${response.statusText}`);\n}\n\nexport async function claimDomain(\n domain: string,\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<void> {\n const response = await fetch(domainClaimUrl(storeHash, projectUuid, domain, apiHost), {\n method: 'POST',\n headers: authHeaders(accessToken),\n });\n\n await assertDomainResponse(response, 'Failed to claim domain');\n}\n\n// Moves a domain from its current project (`projectUuid`, the source) to\n// `newProjectUuid` (the destination) within the same store. The API rejects a\n// transfer where the destination equals the source.\nexport async function transferDomain(\n domain: string,\n projectUuid: string,\n newProjectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n): Promise<void> {\n const response = await fetch(domainTransferUrl(storeHash, projectUuid, domain, apiHost), {\n method: 'POST',\n headers: {\n ...authHeaders(accessToken),\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({ new_project_uuid: newProjectUuid }),\n });\n\n await assertDomainResponse(response, 'Failed to transfer domain');\n}\n","import { colorize } from 'consola/utils';\nimport { z } from 'zod';\n\nimport { assertAuthorized } from './auth-errors';\nimport { UserActionableError } from './errors';\nimport { httpError } from './http-errors';\nimport { getTelemetry } from './telemetry';\n\nexport const LOG_LEVELS = ['debug', 'info', 'warn', 'error'] as const;\nexport type LogLevel = (typeof LOG_LEVELS)[number];\n\nconst SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;\n\nconst logEntrySchema = z.object({\n timestamp: z.string().nullable().optional(),\n entry_type: z.string().optional(),\n level: z.string().optional(),\n messages: z.array(z.unknown()).optional(),\n is_exception: z.boolean().optional(),\n exception_name: z.string().optional(),\n request: z\n .object({\n method: z.string().optional(),\n url: z.string().optional(),\n status_code: z.number().optional(),\n })\n .nullable()\n .optional(),\n});\n\nconst queryLogsSchema = z.object({\n data: z.array(logEntrySchema),\n meta: z\n .object({\n cursor_pagination: z\n .object({\n // The REST proxy exposes page availability via links, while the\n // gRPC response uses has_next_page/has_prev_page. Accept both while\n // the API contract is transitioning.\n has_next_page: z.boolean().optional(),\n has_prev_page: z.boolean().optional(),\n start_cursor: z.string().nullable().optional(),\n end_cursor: z.string().nullable().optional(),\n links: z\n .object({\n next: z.string().optional(),\n previous: z.string().optional(),\n })\n .optional(),\n })\n .optional(),\n })\n .optional(),\n});\n\nexport type LogEntry = z.infer<typeof logEntrySchema>;\nexport type QueryLogsResult = z.infer<typeof queryLogsSchema>;\n\nexport interface QueryLogsParams {\n start: string;\n end: string;\n entryType?: 'log' | 'request';\n method?: string;\n statusCode?: number;\n urlLike?: string;\n levelMin?: LogLevel;\n limit?: number;\n after?: string;\n before?: string;\n}\n\nconst v3ErrorSchema = z.object({\n title: z.string().optional(),\n errors: z.record(z.string(), z.string()).optional(),\n});\n\nexport function formatV3Error(body: unknown): string | undefined {\n const parsed = v3ErrorSchema.safeParse(body);\n\n if (!parsed.success) return undefined;\n\n const { title, errors } = parsed.data;\n const fieldErrors =\n errors && Object.keys(errors).length > 0\n ? Object.entries(errors)\n .map(([field, message]) => `${field}: ${message}`)\n .join('; ')\n : undefined;\n\n if (title && fieldErrors) return `${title} (${fieldErrors})`;\n\n return title ?? fieldErrors;\n}\n\n// Accepts either an ISO-8601 timestamp or a Unix epoch (seconds) and returns\n// milliseconds since epoch, or null when the value can't be parsed.\nfunction parseTimeInput(value: string): number | null {\n const trimmed = value.trim();\n\n if (/^\\d+$/.test(trimmed)) {\n return Number(trimmed) * 1000;\n }\n\n const ms = Date.parse(trimmed);\n\n return Number.isNaN(ms) ? null : ms;\n}\n\nconst DURATION_UNIT_MS: Record<string, number> = {\n s: 1000,\n m: 60 * 1000,\n h: 60 * 60 * 1000,\n d: 24 * 60 * 60 * 1000,\n};\n\nfunction parseDuration(value: string): number | null {\n const match = /^(\\d+)([smhd])$/.exec(value.trim());\n\n if (!match) return null;\n\n return Number(match[1]) * DURATION_UNIT_MS[match[2]];\n}\n\nexport function resolveTimeWindow(\n opts: { start?: string; end?: string; since?: string },\n nowMs = Date.now(),\n): {\n start: string;\n end: string;\n} {\n const { since } = opts;\n let { start, end } = opts;\n let startMs: number | null;\n let endMs: number | null;\n\n if (end) {\n endMs = parseTimeInput(end);\n\n if (endMs === null) {\n throw new UserActionableError(\n `Invalid --end value \"${end}\". Provide an ISO-8601 timestamp or a Unix epoch (seconds).`,\n );\n }\n } else {\n endMs = nowMs;\n end = new Date(endMs).toISOString();\n }\n\n if (since) {\n const durationMs = parseDuration(since);\n\n if (durationMs === null) {\n throw new UserActionableError(\n `Invalid --since value \"${since}\". Provide a duration like 30m, 6h, or 2d (units: s, m, h, d).`,\n );\n }\n\n startMs = endMs - durationMs;\n start = new Date(startMs).toISOString();\n } else if (start) {\n startMs = parseTimeInput(start);\n\n if (startMs === null) {\n throw new UserActionableError(\n `Invalid --start value \"${start}\". Provide an ISO-8601 timestamp or a Unix epoch (seconds).`,\n );\n }\n } else {\n throw new UserActionableError(\n 'Provide a time window with --since <duration> or --start <time>.',\n );\n }\n\n if (startMs > endMs) {\n throw new UserActionableError('Invalid time window: --start must be before or equal to --end.');\n }\n\n if (endMs - startMs > SEVEN_DAYS_MS) {\n throw new UserActionableError('Invalid time window: the range must not exceed 7 days.');\n }\n\n return { start, end };\n}\n\nconst LEVEL_COLORS: Record<string, Parameters<typeof colorize>[0]> = {\n debug: 'gray',\n info: 'green',\n warn: 'yellow',\n error: 'red',\n};\n\nexport type LogLineFormat = 'default' | 'short' | 'request';\n\nconst UNKNOWN_TIME = 'unknown';\n\nfunction isRedundantExceptionName(name: string, message: string): boolean {\n const parts = name\n .split('<*>')\n .map((part) => part.trim())\n .filter((part) => part.length > 0);\n\n return parts.length > 0 && parts.every((part) => message.includes(part));\n}\n\nconst stringifyMessage = (message: unknown) =>\n typeof message === 'string' ? message : JSON.stringify(message);\n\nconst joinMessages = (messages: LogEntry['messages']) =>\n (messages ?? []).map(stringifyMessage).join(' ').replace(/\\s+/g, ' ').trim();\n\n// Identifies Cloudflare's auto-generated per-request invocation row (as\n// opposed to real application output like console.* or exceptions).\nexport function isRequestLogEntry(entry: LogEntry): boolean {\n if (entry.entry_type != null) return entry.entry_type === 'request';\n\n // Older API deployments don't send entry_type. Fall back to a heuristic:\n // the auto-generated row's message is exactly \"<method> <url>\", duplicating\n // the entry's request details.\n const method = entry.request?.method;\n const url = entry.request?.url;\n\n if (!method || !url) return false;\n\n return joinMessages(entry.messages) === `${method} ${url}`;\n}\n\nexport function formatLogEntry(entry: LogEntry, format: LogLineFormat = 'default'): string {\n const message = joinMessages(entry.messages);\n\n if (format === 'short') return message;\n\n const level = entry.level ?? 'unknown';\n const coloredLevel = colorize(LEVEL_COLORS[level.toLowerCase()] ?? 'white', level.toUpperCase());\n\n const exceptionStr =\n entry.is_exception &&\n entry.exception_name &&\n !isRedundantExceptionName(entry.exception_name, message)\n ? ` ${colorize('red', `[${entry.exception_name}]`)}`\n : '';\n\n let requestStr = '';\n\n if (format === 'request' && entry.request) {\n const parts: string[] = [];\n\n if (entry.request.method) parts.push(entry.request.method);\n if (entry.request.url) parts.push(entry.request.url);\n\n // status_code 0 is the backend's \"unknown\" sentinel — omit it.\n const status = entry.request.status_code ? ` (${entry.request.status_code})` : '';\n\n if (parts.length > 0) requestStr = ` ${parts.join(' ')}${status}`;\n }\n\n // A request row carries no application output — its message only duplicates\n // the request details — so print it as a bare request line, without a level\n // bracket or message.\n if (format === 'request' && isRequestLogEntry(entry)) {\n return `[${entry.timestamp ?? UNKNOWN_TIME}]${requestStr}`;\n }\n\n // `requestStr` is empty outside the `request` format, so the level stays\n // adjacent to the timestamp there and only slides after the request details\n // when they are present.\n return `[${entry.timestamp ?? UNKNOWN_TIME}]${requestStr} [${coloredLevel}]${exceptionStr} ${message}`;\n}\n\nexport async function queryLogs(\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n params: QueryLogsParams,\n): Promise<QueryLogsResult> {\n const search = new URLSearchParams();\n\n search.set('start', params.start);\n search.set('end', params.end);\n\n if (params.entryType) search.set('entry_type', params.entryType);\n if (params.method) search.set('method', params.method);\n if (params.statusCode != null) search.set('status_code', String(params.statusCode));\n if (params.urlLike) search.set('url:like', params.urlLike); // colon param\n if (params.levelMin) search.set('level:min', params.levelMin); // colon param\n if (params.limit != null) search.set('limit', String(params.limit));\n if (params.after) search.set('after', params.after);\n if (params.before) search.set('before', params.before);\n\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/logs/${projectUuid}?${search.toString()}`,\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n 'X-Correlation-Id': getTelemetry().correlationId,\n Accept: 'application/json',\n },\n },\n );\n\n assertAuthorized(response);\n\n if (response.status === 403) {\n throw new UserActionableError(\n 'Infrastructure Logs API not enabled. If you are part of the beta, contact support@bigcommerce.com to enable it.',\n );\n }\n\n if (response.status === 404) {\n // The gateway also 404s when the token belongs to a different store than\n // the one in the URL, so a bad credential pairing looks identical to a\n // missing project.\n throw new UserActionableError(\n 'Project not found. Check the project UUID, and that --store-hash and --access-token belong to the store that owns the project.',\n );\n }\n\n // 400 (bad UUID) and 422 (invalid window/filter) both carry the field-keyed\n // v3 error envelope — surface its message rather than the bare status.\n if (response.status === 400 || response.status === 422) {\n const body: unknown = await response.json().catch(() => null);\n\n throw new UserActionableError(formatV3Error(body) ?? 'Invalid log query.');\n }\n\n if (!response.ok) {\n throw await httpError(response, 'Failed to fetch logs');\n }\n\n const res: unknown = await response.json();\n\n return queryLogsSchema.parse(res);\n}\n","import { Command } from 'commander';\n\nimport { getStoredEnv, parseEnvAssignment } from '../lib/env-config';\nimport { consola } from '../lib/logger';\nimport { getProjectConfig } from '../lib/project-config';\n\n// Values are secrets, so we never print them back. A fixed-width mask avoids\n// leaking the length of the stored value.\nconst MASK = '••••••';\n\nconst add = new Command('add')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Add or update one or more deployment environment variables. Stored in .bigcommerce/project.json and sent as secrets on every `catalyst deploy`.',\n )\n .argument('<vars...>', 'One or more environment variables in KEY=VALUE format.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst env add BIGCOMMERCE_STORE_HASH=abc123 BIGCOMMERCE_STOREFRONT_TOKEN=ey...`,\n )\n .action((vars: string[]) => {\n const config = getProjectConfig();\n const stored = { ...getStoredEnv(config) };\n\n // Parse everything before writing so a single invalid entry doesn't leave a\n // partial update behind.\n const parsed = vars.map((entry) => parseEnvAssignment(entry));\n\n parsed.forEach(({ key, value }) => {\n stored[key] = value;\n });\n\n config.set('env', stored);\n\n const keys = parsed.map(({ key }) => key);\n\n consola.success(\n `Saved ${keys.length} environment variable${keys.length === 1 ? '' : 's'} to .bigcommerce/project.json:`,\n );\n keys.forEach((key) => consola.log(` ${key}=${MASK}`));\n\n process.exit(0);\n });\n\nconst remove = new Command('remove')\n .configureHelp({ showGlobalOptions: true })\n .description('Remove one or more stored deployment environment variables.')\n .argument('<keys...>', 'One or more environment variable names to remove.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst env remove BIGCOMMERCE_STORE_HASH BIGCOMMERCE_STOREFRONT_TOKEN`,\n )\n .action((keys: string[]) => {\n const config = getProjectConfig();\n const stored = getStoredEnv(config);\n const toRemove = new Set<string>();\n\n keys.forEach((key) => {\n if (key in stored) {\n toRemove.add(key);\n } else {\n consola.warn(`No stored environment variable named \"${key}\". Skipping.`);\n }\n });\n\n const next = Object.fromEntries(Object.entries(stored).filter(([key]) => !toRemove.has(key)));\n\n config.set('env', next);\n\n const removed = Array.from(toRemove);\n\n if (removed.length > 0) {\n consola.success(\n `Removed ${removed.length} environment variable${removed.length === 1 ? '' : 's'}: ${removed.join(', ')}.`,\n );\n }\n\n process.exit(0);\n });\n\nconst list = new Command('list')\n .configureHelp({ showGlobalOptions: true })\n .description('List stored deployment environment variables (values are masked).')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst env list`,\n )\n .action(() => {\n const config = getProjectConfig();\n const stored = getStoredEnv(config);\n const keys = Object.keys(stored).sort();\n\n if (keys.length === 0) {\n consola.info('No environment variables stored. Add one with `catalyst env add KEY=VALUE`.');\n process.exit(0);\n\n return;\n }\n\n keys.forEach((key) => consola.log(`${key}=${MASK}`));\n\n process.exit(0);\n });\n\nexport const env = new Command('env')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Manage persistent deployment environment variables. These are sent as secrets on every `catalyst deploy`, so you no longer need to pass `--secret` each time.',\n )\n .addCommand(add)\n .addCommand(remove)\n .addCommand(list);\n","import { Command, InvalidArgumentError, Option } from 'commander';\nimport { colorize } from 'consola/utils';\nimport { z } from 'zod';\n\nimport { UnauthorizedError } from '../lib/auth-errors';\nimport { httpError } from '../lib/http-errors';\nimport { consola } from '../lib/logger';\nimport {\n formatLogEntry,\n isRequestLogEntry,\n LOG_LEVELS,\n queryLogs,\n QueryLogsResult,\n resolveTimeWindow,\n} from '../lib/observability';\nimport { getProjectConfig } from '../lib/project-config';\nimport { resolveCredentials } from '../lib/resolve-credentials';\nimport {\n accessTokenOption,\n apiHostOption,\n projectUuidOption,\n resolveApiHost,\n resolveProjectUuid,\n storeHashOption,\n} from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\n\ntype LogFormat = 'json' | 'pretty' | 'default' | 'short' | 'request';\n\nconst DEFAULT_CONNECTION_TTL_MS = 1 * 60 * 1000; // 1 minute\nconst MAX_RETRIES = 5;\n\nconst isFatalStatusCode = (status: number) => status >= 400 && status < 500;\n\nconst LEVEL_COLORS: Record<string, Parameters<typeof colorize>[0]> = {\n INFO: 'green',\n WARN: 'yellow',\n ERROR: 'red',\n DEBUG: 'gray',\n};\n\nconst LogEventSchema = z\n .object({\n uuid: z.string(),\n project_uuid: z.string(),\n request: z.object({\n method: z.string(),\n url: z.string(),\n status_code: z.number(),\n }),\n logs: z.array(\n z.object({\n timestamp: z.string(),\n level: z.string(),\n messages: z.array(z.unknown()),\n }),\n ),\n exceptions: z.array(z.unknown()),\n timestamp: z.string(),\n })\n .loose();\n\nclass StreamError extends Error {\n fatal: boolean;\n\n constructor(message: string, fatal: boolean) {\n super(message);\n this.fatal = fatal;\n }\n}\n\nconst formatMessages = (messages: unknown[]) =>\n messages.map((m) => (typeof m === 'string' ? m : JSON.stringify(m))).join(' ');\n\ntype LogEvent = z.infer<typeof LogEventSchema>;\n\n// Builds a `request` format line. The log entry is optional: a request that\n// logged nothing still has a timestamp, method, URL and status worth printing.\nconst formatRequestLine = (event: LogEvent, entry?: LogEvent['logs'][number]) => {\n const { request } = event;\n const msg = entry ? formatMessages(entry.messages) : '';\n const msgPart = msg ? ` ${msg}` : '';\n // The level labels the message, so an entry with nothing to say prints as a\n // bare request line — same as an event that carried no entries at all.\n const level = msg ? entry?.level.toUpperCase() : undefined;\n const levelPart = level ? ` [${colorize(LEVEL_COLORS[level] ?? 'white', level)}]` : '';\n\n return (\n `[${entry?.timestamp ?? event.timestamp}] ` +\n `${request.method} ${request.url} (${request.status_code})${levelPart}${msgPart}`\n );\n};\n\nconst formatLogEvent = (event: LogEvent, format: 'default' | 'short' | 'request') => {\n const { logs: logEntries, exceptions } = event;\n\n // `request` output is about the request, not the messages it emitted, so an\n // event with no log entries still prints one line. Otherwise requests that\n // logged nothing silently disappear from the stream.\n if (format === 'request' && logEntries.length === 0) {\n consola.log(formatRequestLine(event));\n }\n\n logEntries.forEach((entry) => {\n const msg = formatMessages(entry.messages);\n const level = entry.level.toUpperCase();\n const coloredLevel = colorize(LEVEL_COLORS[level] ?? 'white', level);\n\n switch (format) {\n case 'short':\n consola.log(msg);\n break;\n\n case 'request':\n consola.log(formatRequestLine(event, entry));\n break;\n\n default:\n consola.log(`[${entry.timestamp}] [${coloredLevel}] ${msg}`);\n break;\n }\n });\n\n exceptions.forEach((exception) => {\n consola.error(`[${event.timestamp}] EXCEPTION`, exception);\n });\n};\n\nexport const parseSSEEvent = (raw: string): string | null => {\n const joined = raw\n .split('\\n')\n .flatMap((line) => (line.startsWith('data:') ? [line.slice(5).trim()] : []))\n .join('\\n');\n\n return joined.length > 0 ? joined : null;\n};\n\nconst processLogEvent = (event: string, format: LogFormat) => {\n if (format === 'json') {\n process.stdout.write(`${event}\\n`);\n\n return;\n }\n\n try {\n const parsed: unknown = JSON.parse(event);\n const logEvent = LogEventSchema.parse(parsed);\n\n if (format === 'pretty') {\n consola.log(JSON.stringify(logEvent, null, 2));\n } else {\n formatLogEvent(logEvent, format);\n }\n } catch {\n consola.warn(`Failed to parse log event: ${event}`);\n }\n};\n\ntype TimeoutRaceResult<T> = { kind: 'value'; value: T } | { kind: 'timeout' };\n\n// Races a promise against a timer so a hung `reader.read()` doesn't block the\n// read pump. Without this, the connection TTL check never runs when the API\n// proxy half-closes the socket — bytes stop arriving but no FIN/error\n// surfaces, so the read promise stays pending forever.\nconst raceWithTimeout = async <T>(\n promise: Promise<T>,\n timeoutMs: number,\n): Promise<TimeoutRaceResult<T>> => {\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined;\n\n const timeoutPromise = new Promise<TimeoutRaceResult<T>>((resolve) => {\n timeoutHandle = setTimeout(() => resolve({ kind: 'timeout' }), timeoutMs);\n });\n\n try {\n return await Promise.race([\n promise.then((value): TimeoutRaceResult<T> => ({ kind: 'value', value })),\n timeoutPromise,\n ]);\n } finally {\n if (timeoutHandle) clearTimeout(timeoutHandle);\n }\n};\n\nconst openLogStream = async (\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n) => {\n const response = await fetch(\n `https://${apiHost}/stores/${storeHash}/v3/infrastructure/logs/${projectUuid}/tail`,\n {\n method: 'GET',\n headers: {\n 'X-Auth-Token': accessToken,\n Accept: 'text/event-stream',\n Connection: 'keep-alive',\n },\n },\n );\n\n // An invalid/expired token won't recover by reconnecting — surface the\n // re-auth guidance and stop the loop (fatal) rather than burning retries.\n if (response.status === 401) {\n throw new StreamError(new UnauthorizedError().message, true);\n }\n\n if (!response.ok) {\n const error = await httpError(response, 'Failed to open log stream');\n\n throw new StreamError(error.message, isFatalStatusCode(response.status));\n }\n\n const reader = response.body?.getReader();\n\n if (!reader) {\n throw new StreamError('Failed to read log stream.', true);\n }\n\n return reader;\n};\n\n// Reasons the read pump stops on its own (vs. throwing). The outer reconnect\n// loop maps each to a user-facing message — or silence — and opens a fresh\n// stream.\ntype Rotation = 'ttl' | 'idle-timeout' | 'stream-done';\n\nconst pumpUntilRotation = async (\n reader: ReadableStreamDefaultReader<Uint8Array>,\n format: LogFormat,\n connectionTtlMs: number,\n): Promise<Rotation> => {\n const decoder = new TextDecoder();\n const connectTime = Date.now();\n let buffer = '';\n let receivedData = false;\n\n // eslint-disable-next-line no-constant-condition, @typescript-eslint/no-unnecessary-condition\n while (true) {\n const remainingTtlMs = connectionTtlMs - (Date.now() - connectTime);\n\n if (remainingTtlMs <= 0) {\n void reader.cancel();\n\n return 'ttl';\n }\n\n // eslint-disable-next-line no-await-in-loop\n const readResult = await raceWithTimeout(reader.read(), remainingTtlMs);\n\n if (readResult.kind === 'timeout') {\n void reader.cancel();\n\n // No data for the whole window: proxy likely half-closed the socket.\n // If data flowed earlier, treat it as a normal TTL boundary instead.\n return receivedData ? 'ttl' : 'idle-timeout';\n }\n\n const { value, done: streamDone } = readResult.value;\n\n if (value) {\n receivedData = true;\n buffer += decoder.decode(value, { stream: true });\n\n const parts = buffer.split('\\n\\n');\n\n // Last element is either empty (complete event) or a partial chunk to carry over\n buffer = parts.pop() ?? '';\n\n parts\n .map((raw) => parseSSEEvent(raw))\n .filter((event): event is string => event !== null)\n .forEach((event) => processLogEvent(event, format));\n }\n\n if (streamDone) {\n void reader.cancel();\n\n return 'stream-done';\n }\n }\n};\n\nexport const tailLogs = async (\n projectUuid: string,\n storeHash: string,\n accessToken: string,\n apiHost: string,\n format: LogFormat,\n connectionTtlMs = DEFAULT_CONNECTION_TTL_MS,\n) => {\n consola.info('Tailing logs...');\n\n let retries = 0;\n\n // eslint-disable-next-line no-constant-condition, @typescript-eslint/no-unnecessary-condition\n while (true) {\n try {\n // eslint-disable-next-line no-await-in-loop\n const reader = await openLogStream(projectUuid, storeHash, accessToken, apiHost);\n\n retries = 0;\n\n // eslint-disable-next-line no-await-in-loop\n const rotation = await pumpUntilRotation(reader, format, connectionTtlMs);\n\n if (rotation === 'idle-timeout') {\n consola.warn('Log stream idle, reconnecting...');\n }\n // 'ttl' and 'stream-done' are healthy rotations — reconnect silently.\n } catch (error) {\n if (error instanceof StreamError && error.fatal) {\n throw error;\n }\n\n const isServerDisconnect = error instanceof TypeError && error.message === 'terminated';\n\n if (isServerDisconnect) {\n consola.warn('Log stream closed by server, reconnecting...');\n } else {\n retries += 1;\n\n if (retries >= MAX_RETRIES) {\n throw new Error(`Failed to connect to log stream after ${MAX_RETRIES} retries.`);\n }\n\n consola.warn(\n `Log stream disconnected, reconnecting (attempt ${retries}/${MAX_RETRIES})...`,\n error,\n );\n }\n }\n }\n};\n\nconst tail = new Command('tail')\n .configureHelp({ showGlobalOptions: true })\n .description('Tail live logs from your deployed application.')\n .addHelpText(\n 'after',\n `\nFormats:\n default One line per log message: timestamp, level, and message.\n short Message text only.\n request One line per log message: timestamp, request method, URL, status\n code, level, and message. Requests that logged no messages are\n printed too, without the level and message.\n pretty Indented JSON of the whole event.\n json Raw JSON, one event per line (useful for piping to other tools).\n\nThe \\`default\\` and \\`short\\` formats only print requests that produced a log\nmessage. Use \\`--format request\\` (or \\`json\\`/\\`pretty\\`) to see every request,\nincluding ones with no message body.\n\nExamples:\n $ catalyst logs tail\n\n # Tail logs with request format\n $ catalyst logs tail --format request\n\n # Tail logs as raw JSON (useful for piping to other tools)\n $ catalyst logs tail --format json`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .addOption(\n new Option('--format <format>', 'Output format for log events.')\n .choices(['json', 'pretty', 'default', 'short', 'request'])\n .default('default'),\n )\n .action(async (options) => {\n try {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n const projectUuid = resolveProjectUuid(options);\n\n await tailLogs(projectUuid, storeHash, accessToken, apiHost, options.format);\n } catch (error) {\n consola.error(error);\n process.exit(1);\n }\n });\n\n// Validates a numeric flag client-side so typos fail instantly with a clear\n// message instead of sending NaN (or an out-of-range value) to the API.\nconst parseIntInRange = (flag: string, min: number, max: number) => (value: string) => {\n const parsed = Number(value);\n\n if (!Number.isInteger(parsed) || parsed < min || parsed > max) {\n throw new InvalidArgumentError(`${flag} must be an integer between ${min} and ${max}.`);\n }\n\n return parsed;\n};\n\n// A bare `catalyst` is only on PATH for global installs. When the CLI runs\n// through a package manager (`pnpm catalyst`, `npx catalyst`, ...) the printed\n// hint must include that wrapper or copy-pasting it fails with\n// \"command not found\".\nfunction invocationPrefix(): string {\n const packageManager = process.env.npm_config_user_agent?.split('/')[0];\n\n switch (packageManager) {\n case 'pnpm':\n case 'yarn':\n return `${packageManager} catalyst`;\n\n case 'bun':\n return 'bunx catalyst';\n\n case 'npm':\n return 'npx catalyst';\n\n default:\n return 'catalyst';\n }\n}\n\ninterface QueryHintOptions {\n method?: string;\n statusCode?: number;\n urlLike?: string;\n levelMin?: string;\n limit?: number;\n format: string;\n}\n\nfunction printPaginationHints(\n pagination: NonNullable<QueryLogsResult['meta']>['cursor_pagination'],\n start: string,\n end: string,\n options: QueryHintOptions,\n): void {\n // The REST API signals availability with `links` URLs. Retain the gRPC\n // booleans as a compatibility fallback for direct API consumers.\n const hasNextPage = Boolean(pagination?.links?.next) || pagination?.has_next_page === true;\n const hasPrevPage = Boolean(pagination?.links?.previous) || pagination?.has_prev_page === true;\n const endCursor = pagination?.end_cursor;\n const startCursor = pagination?.start_cursor;\n\n if (!(hasNextPage && endCursor) && !(hasPrevPage && startCursor)) return;\n\n const quoteArg = (value: string) => (/\\s/.test(value) ? `'${value}'` : value);\n // Cursors are only valid with the same window and filters, so pin the\n // resolved absolute timestamps (a --since window drifts with \"now\").\n const baseFlags = [\n `--start ${quoteArg(start)}`,\n `--end ${quoteArg(end)}`,\n ...(options.method ? [`--method ${quoteArg(options.method)}`] : []),\n ...(options.statusCode != null ? [`--status-code ${options.statusCode}`] : []),\n ...(options.urlLike ? [`--url-like ${quoteArg(options.urlLike)}`] : []),\n ...(options.levelMin ? [`--level-min ${options.levelMin}`] : []),\n ...(options.limit != null ? [`--limit ${options.limit}`] : []),\n // The entry_type filter derives from --format (default/short request only\n // application logs), so echoing --format is enough to reproduce it.\n ...(options.format !== 'default' ? [`--format ${options.format}`] : []),\n ];\n const command = `${invocationPrefix()} logs query ${baseFlags.join(' ')}`;\n\n if (hasNextPage && endCursor) {\n consola.info(`More results available. Next page:\\n ${command} --after ${quoteArg(endCursor)}`);\n }\n\n if (hasPrevPage && startCursor) {\n consola.info(\n `Newer results available. Previous page:\\n ${command} --before ${quoteArg(startCursor)}`,\n );\n }\n}\n\nconst query = new Command('query')\n .configureHelp({ showGlobalOptions: true })\n .description('Query historical logs from your deployed application.')\n .addHelpText(\n 'after',\n `\nSpecify a time window with \\`--since\\` (relative to now) or \\`--start\\`/\\`--end\\`\n(ISO-8601 timestamps or Unix epoch seconds, UTC). The window may not exceed\n7 days. Entries print oldest-first; timestamps are UTC. Page toward older\nentries by passing a previous page's end cursor to \\`--after\\` (the CLI prints\na ready-to-run command when more entries are available), or toward newer\nentries with \\`--before\\`. Cursors are only valid with the same window and\nfilters they came from. With \\`--format json\\`, the pagination cursors are\nemitted as a final \\`{\"meta\": ...}\\` line after the entries.\n\nThe \\`default\\` and \\`short\\` formats show only application log output,\nexcluding Cloudflare's auto-generated per-request rows. Use\n\\`--format request\\` (or \\`json\\`/\\`pretty\\`) to include them.\n\nExamples:\n # Last hour of logs\n $ catalyst logs query --since 1h\n\n # Newest 20 errors in the window (follow the printed --after hint for more)\n $ catalyst logs query --since 24h --level-min error --limit 20\n\n # Everything from today (UTC)\n $ catalyst logs query --start 2026-06-11T00:00:00Z\n\n # Errors only for a specific path\n $ catalyst logs query --since 24h --level-min error --url-like /cart\n\n # Errors with request details (method, URL, status)\n $ catalyst logs query --since 1h --level-min error --format request\n\n # Raw JSON (NDJSON) for piping to other tools\n $ catalyst logs query --since 2d --format json`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .addOption(\n new Option(\n '--since <duration>',\n 'Relative window ending at --end (default: now), e.g. 30m, 6h, 2d (units: s, m, h, d).',\n ).conflicts('start'),\n )\n .option('--start <time>', 'Window start: ISO-8601 timestamp or Unix epoch (seconds).')\n .option(\n '--end <time>',\n 'Window end: ISO-8601 timestamp or Unix epoch (seconds). Defaults to now. The window must not exceed 7 days.',\n )\n .option('--method <method>', 'Filter by request HTTP method (case-insensitive).')\n .addOption(\n new Option('--status-code <code>', 'Filter by response status code (100-599).').argParser(\n parseIntInRange('--status-code', 100, 599),\n ),\n )\n .option('--url-like <substring>', 'Filter by URL substring (case-sensitive).')\n .addOption(\n new Option('--level-min <level>', 'Minimum log level.').choices(Array.from(LOG_LEVELS)),\n )\n .addOption(\n new Option(\n '--limit <count>',\n 'Maximum entries per page (1-500). Defaults to the API default (100).',\n ).argParser(parseIntInRange('--limit', 1, 500)),\n )\n .addOption(\n new Option(\n '--after <cursor>',\n \"Return the page after (older than) this cursor, from a previous page's end_cursor.\",\n ).conflicts('before'),\n )\n .addOption(\n new Option(\n '--before <cursor>',\n \"Return the page before (newer than) this cursor, from a previous page's start_cursor.\",\n ),\n )\n .addOption(\n new Option('--format <format>', 'Output format for log entries.')\n .choices(['json', 'pretty', 'default', 'short', 'request'])\n .default('default'),\n )\n .action(async (options) => {\n try {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n const projectUuid = resolveProjectUuid(options);\n const { start, end } = resolveTimeWindow(options);\n\n // default/short show only application output, so ask the API to filter\n // out Cloudflare's per-request rows (they don't consume the page limit).\n const hideRequestRows = options.format === 'default' || options.format === 'short';\n\n const result = await queryLogs(projectUuid, storeHash, accessToken, apiHost, {\n start,\n end,\n entryType: hideRequestRows ? 'log' : undefined,\n method: options.method,\n statusCode: options.statusCode,\n urlLike: options.urlLike,\n levelMin: options.levelMin,\n limit: options.limit,\n after: options.after,\n before: options.before,\n });\n\n const entries = result.data;\n const ordered = [...entries].reverse();\n\n if (options.format === 'json') {\n ordered.forEach((entry) => process.stdout.write(`${JSON.stringify(entry)}\\n`));\n\n // Entries carry no cursors, so scripted pagination needs the meta\n // echoed back; a trailing line keeps the stream line-delimited.\n const cursorPagination = result.meta?.cursor_pagination;\n\n if (cursorPagination) {\n process.stdout.write(\n `${JSON.stringify({ meta: { cursor_pagination: cursorPagination } })}\\n`,\n );\n }\n\n return;\n }\n\n if (options.format === 'pretty') {\n ordered.forEach((entry) => consola.log(JSON.stringify(entry, null, 2)));\n\n return;\n }\n\n if (entries.length === 0) {\n consola.info('No log entries found for the given window and filters.');\n\n return;\n }\n\n // `json`/`pretty` returned above, leaving the human line formats — capture\n // the narrowed value so it survives into the forEach closure.\n const lineFormat = options.format;\n\n // Older API deployments ignore the entry_type param, so also drop\n // request rows client-side — a no-op against new APIs.\n const visible = hideRequestRows\n ? ordered.filter((entry) => !isRequestLogEntry(entry))\n : ordered;\n const hiddenCount = ordered.length - visible.length;\n\n visible.forEach((entry) => consola.log(formatLogEntry(entry, lineFormat)));\n\n const shownPart = `${visible.length} ${visible.length === 1 ? 'entry' : 'entries'} shown`;\n\n consola.info(\n hiddenCount > 0\n ? `${shownPart}, ${hiddenCount} request ${hiddenCount === 1 ? 'row' : 'rows'} hidden (oldest first, times in UTC). Use --format request to see request rows.`\n : `${shownPart} (oldest first, times in UTC).`,\n );\n\n printPaginationHints(result.meta?.cursor_pagination, start, end, options);\n } catch (error) {\n consola.error(error instanceof Error ? error.message : error);\n process.exit(1);\n }\n });\n\nexport const logs = new Command('logs')\n .alias('log')\n .configureHelp({ showGlobalOptions: true })\n .description('View logs from your deployed application.')\n .addCommand(tail, { isDefault: true })\n .addCommand(query);\n","import { confirm, input, select } from '@inquirer/prompts';\nimport { Command } from 'commander';\nimport { colorize } from 'consola/utils';\n\nimport {\n cleanupCloudflareIncompatibilities,\n NoLinkedProjectError,\n selectOrCreateInfrastructureProject,\n setupCommerceHosting,\n} from '../lib/commerce-hosting';\nimport { detectProjectPackageManager } from '../lib/detect-package-manager';\nimport { installDependencies } from '../lib/install-dependencies';\nimport { consola } from '../lib/logger';\nimport { LoginAbortedError, login as runInteractiveLogin } from '../lib/login';\nimport { createProject, deleteProject, fetchProjects } from '../lib/project';\nimport { getProjectConfig } from '../lib/project-config';\nimport { getProjectState } from '../lib/project-state';\nimport { resolveCredentials } from '../lib/resolve-credentials';\nimport {\n accessTokenOption,\n apiHostOption,\n loginUrlOption,\n projectUuidOption,\n resolveApiHost,\n storeHashOption,\n} from '../lib/shared-options';\nimport { getTelemetry } from '../lib/telemetry';\n\n// `catalyst projects link` runs from the project root, which is what\n// `setupCommerceHosting` and `installDependencies` expect.\nasync function offerCommerceHostingSetup(\n projectUuid: string,\n credentials?: { storeHash: string; accessToken: string },\n) {\n const projectDir = process.cwd();\n\n // Already-transformed projects skip the setup prompt below — but they may\n // still carry artifacts incompatible with the Cloudflare worker bundle\n // (e.g. `core/instrumentation.ts`, `@vercel/otel`). Run cleanup so existing\n // Commerce Hosting users pick up these fixes on re-link without prompting.\n if (getProjectState().isTransformed) {\n await cleanupCloudflareIncompatibilities(projectDir);\n\n return;\n }\n\n const shouldSetup = await confirm({\n message:\n 'Your project has been linked, but is not fully set up for Commerce Hosting deployments yet. Would you like to run the setup now?',\n default: true,\n });\n\n if (!shouldSetup) return;\n\n await setupCommerceHosting({\n projectDir,\n projectUuid,\n storeHash: credentials?.storeHash,\n accessToken: credentials?.accessToken,\n });\n\n consola.success('Commerce Hosting setup complete.');\n\n // Match the manager the project was scaffolded with (from its lockfile),\n // rather than forcing pnpm on npm/yarn/bun projects.\n const packageManager = await detectProjectPackageManager(projectDir);\n\n await installDependencies(projectDir, packageManager);\n}\n\nconst list = new Command('list')\n .configureHelp({ showGlobalOptions: true })\n .description('List BigCommerce infrastructure projects for your store.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst projects list`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n consola.start('Fetching projects...');\n\n const storeProjects = await fetchProjects(storeHash, accessToken, apiHost);\n\n consola.success('Projects fetched.');\n\n if (storeProjects.length === 0) {\n consola.info('No projects found.');\n process.exit(0);\n\n return;\n }\n\n const linkedProjectUuid = config.get('projectUuid');\n\n const projectList = storeProjects.map((p) => {\n const marker = p.uuid === linkedProjectUuid ? ` ${colorize('green', '[linked]')}` : '';\n const hostnames =\n p.deployment_hostnames.length === 0\n ? [' (not deployed)']\n : p.deployment_hostnames.map(\n (hostname) => ` ${colorize('blue', `https://${hostname}`)}`,\n );\n\n return [`${p.name} (${p.uuid})${marker}`, ...hostnames].join('\\n');\n });\n\n // Single log call so projects are blank-line separated without each blank\n // picking up a reporter timestamp.\n consola.log(projectList.join('\\n\\n'));\n\n process.exit(0);\n });\n\nconst create = new Command('create')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Create a new BigCommerce infrastructure project and link it to your local Catalyst project. Walks you through logging in if you are not authenticated yet.',\n )\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst projects create`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(loginUrlOption())\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n let storeHash = options.storeHash ?? config.get('storeHash');\n let accessToken = options.accessToken ?? config.get('accessToken');\n\n if (!storeHash || !accessToken) {\n consola.info(\n \"You're not logged in yet. Let's get you authenticated before creating a project.\",\n );\n\n try {\n const credentials = await runInteractiveLogin(options.loginUrl, apiHost);\n\n storeHash = credentials.storeHash;\n accessToken = credentials.accessToken;\n\n config.set('storeHash', storeHash);\n config.set('accessToken', accessToken);\n\n consola.success(`Logged in to store ${storeHash}.`);\n } catch (error) {\n if (error instanceof LoginAbortedError) {\n consola.info(\n 'Login aborted. Re-run `catalyst projects create` when you have your credentials ready.',\n );\n process.exit(0);\n\n return;\n }\n\n throw error;\n }\n }\n\n await getTelemetry().identify(storeHash);\n\n const newProjectName = await input({ message: 'Enter a name for the new project:' });\n\n const data = await createProject(newProjectName, storeHash, accessToken, apiHost);\n\n consola.success(`Project \"${data.name}\" created successfully.`);\n\n consola.start('Writing project UUID to .bigcommerce/project.json...');\n config.set('projectUuid', data.uuid);\n config.set('storeHash', storeHash);\n config.set('accessToken', accessToken);\n consola.success('Project UUID written to .bigcommerce/project.json.');\n\n process.exit(0);\n });\n\nexport const link = new Command('link')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Link your local Catalyst project to a BigCommerce infrastructure project. You can provide a project UUID directly, or fetch and select from available projects using your store credentials.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Link interactively (prompts to select or create)\n $ catalyst projects link\n\n # Link using a project UUID directly\n $ catalyst projects link --project-uuid <UUID>`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n\n const writeProjectConfig = (\n uuid: string,\n credentials?: { storeHash: string; accessToken: string },\n ) => {\n consola.start('Writing project UUID to .bigcommerce/project.json...');\n config.set('projectUuid', uuid);\n\n if (credentials) {\n config.set('storeHash', credentials.storeHash);\n config.set('accessToken', credentials.accessToken);\n }\n\n consola.success('Project UUID written to .bigcommerce/project.json.');\n };\n\n if (options.projectUuid) {\n writeProjectConfig(options.projectUuid);\n await offerCommerceHostingSetup(options.projectUuid);\n\n process.exit(0);\n\n return;\n }\n\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n let selected;\n\n try {\n selected = await selectOrCreateInfrastructureProject(\n { storeHash, accessToken, apiHost },\n config.get('projectUuid'),\n );\n } catch (error) {\n if (error instanceof NoLinkedProjectError) {\n consola.info(\n \"When you're ready to create a project, run `catalyst projects create` or re-run `catalyst projects link`.\",\n );\n process.exit(0);\n\n // Unreachable in production; prevents continuation when process.exit is mocked in tests.\n throw error;\n }\n\n throw error;\n }\n\n writeProjectConfig(selected.uuid, { storeHash, accessToken });\n await offerCommerceHostingSetup(selected.uuid, { storeHash, accessToken });\n\n process.exit(0);\n });\n\nconst del = new Command('delete')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Permanently delete a BigCommerce infrastructure project. This action is irreversible.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Select a project to delete interactively\n $ catalyst projects delete\n\n # Delete a specific project (still prompts for confirmation)\n $ catalyst projects delete --project-uuid <UUID>\n\n # Skip the confirmation prompt\n $ catalyst projects delete --project-uuid <UUID> --force`,\n )\n .addOption(storeHashOption())\n .addOption(accessTokenOption())\n .addOption(apiHostOption())\n .addOption(projectUuidOption())\n .option('--force', 'Skip the confirmation prompt before deleting.')\n .action(async (options) => {\n const config = getProjectConfig();\n const apiHost = resolveApiHost(options, config);\n const { storeHash, accessToken } = resolveCredentials(options, config);\n\n await getTelemetry().identify(storeHash);\n\n let targetUuid: string | undefined = options.projectUuid;\n let targetName: string | undefined;\n\n if (!targetUuid) {\n consola.start('Fetching projects...');\n\n const storeProjects = await fetchProjects(storeHash, accessToken, apiHost);\n\n consola.success('Projects fetched.');\n\n if (storeProjects.length === 0) {\n consola.info('No projects found.');\n process.exit(0);\n\n return;\n }\n\n const linkedProjectUuid = config.get('projectUuid');\n\n const selected = await select({\n message: 'Select a project to delete (Press <enter> to select).',\n choices: [\n ...storeProjects.map((p) => ({\n name:\n p.uuid === linkedProjectUuid ? `${p.name} ${colorize('green', '[linked]')}` : p.name,\n value: p.uuid,\n description: p.uuid,\n })),\n { name: 'Cancel', value: 'cancel', description: 'Exit without deleting any project.' },\n ],\n });\n\n if (selected === 'cancel') {\n consola.info('Aborted. No project was deleted.');\n process.exit(0);\n\n return;\n }\n\n const matched = storeProjects.find((p) => p.uuid === selected);\n\n if (!matched) {\n throw new Error(`Selected project ${String(selected)} not found in fetched list.`);\n }\n\n targetUuid = matched.uuid;\n targetName = matched.name;\n }\n\n if (!options.force) {\n const label = targetName ? `\"${targetName}\" (${targetUuid})` : targetUuid;\n\n const confirmed = await confirm({\n message: `Are you sure you want to delete project ${label}? This action is irreversible and will permanently destroy the project and all of its data.`,\n default: false,\n });\n\n if (!confirmed) {\n consola.info('Aborted. No project was deleted.');\n process.exit(0);\n\n return;\n }\n }\n\n consola.start(`Deleting project ${targetUuid}...`);\n\n await deleteProject(targetUuid, storeHash, accessToken, apiHost);\n\n consola.success(`Project ${targetUuid} deleted.`);\n\n if (config.get('projectUuid') === targetUuid) {\n config.delete('projectUuid');\n consola.info('Removed project UUID from .bigcommerce/project.json.');\n }\n\n process.exit(0);\n });\n\n// Resource commands are plural; the singular form stays as an alias so existing\n// scripts and muscle memory keep working.\nexport const projects = new Command('projects')\n .alias('project')\n .configureHelp({ showGlobalOptions: true })\n .description('Manage your BigCommerce infrastructure projects.')\n .addCommand(create)\n .addCommand(list)\n .addCommand(link)\n .addCommand(del);\n","import { Command } from 'commander';\nimport { execa } from 'execa';\nimport { existsSync, lstatSync, symlinkSync } from 'node:fs';\nimport { join, relative } from 'node:path';\n\nimport { consola } from '../lib/logger';\nimport { getProjectState } from '../lib/project-state';\n\nexport const start = new Command('start')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'Start a local preview of your Catalyst storefront using the OpenNext Cloudflare adapter.',\n )\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst start`,\n )\n .action(async () => {\n // Project must be transformed before the OpenNext preview can run. If it\n // isn't, fall through to `next start` so this command works for self-hosted\n // Catalyst projects too.\n const state = getProjectState();\n\n if (!state.isTransformed) {\n consola.info('Project is not set up for Commerce Hosting — running `next start`.');\n\n await execa('pnpm', ['exec', 'next', 'start'], {\n stdio: 'inherit',\n cwd: process.cwd(),\n });\n\n return;\n }\n\n const envLocal = join(process.cwd(), '.env.local');\n const devVars = join(process.cwd(), '.bigcommerce', '.dev.vars');\n\n if (existsSync(envLocal)) {\n if (!existsSync(devVars)) {\n const target = relative(join(process.cwd(), '.bigcommerce'), envLocal);\n\n symlinkSync(target, devVars);\n consola.success('Symlinked .bigcommerce/.dev.vars → .env.local');\n } else if (!lstatSync(devVars).isSymbolicLink()) {\n consola.warn(\n '.bigcommerce/.dev.vars already exists and is not a symlink. ' +\n 'Wrangler will use it instead of .env.local.',\n );\n }\n } else {\n consola.warn(\n 'No .env.local file found. The preview server may fail without environment variables.\\n' +\n 'Create a .env.local file in your project root with the required variables.',\n );\n }\n\n await execa(\n 'pnpm',\n [\n 'exec',\n 'opennextjs-cloudflare',\n 'preview',\n '--config',\n join('.bigcommerce', 'wrangler.jsonc'),\n ],\n {\n stdio: 'inherit',\n cwd: process.cwd(),\n },\n );\n });\n","import { Argument, Command, Option } from 'commander';\nimport { colorize } from 'consola/utils';\n\nimport { consola } from '../lib/logger';\nimport { getTelemetry } from '../lib/telemetry';\n\nconst telemetryService = getTelemetry();\nlet isEnabled = telemetryService.isEnabled();\n\nexport const telemetry = new Command('telemetry')\n .configureHelp({ showGlobalOptions: true })\n .description(\n 'View or change CLI telemetry collection status. Enabling telemetry helps BigCommerce support diagnose and troubleshoot errors you encounter when using the CLI.',\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Show telemetry status\n $ catalyst telemetry\n\n # Enable telemetry collection\n $ catalyst telemetry enable\n\n # Disable telemetry collection\n $ catalyst telemetry --disable`,\n )\n .addArgument(new Argument('[arg]').choices(['disable', 'enable', 'status']))\n .addOption(new Option('--enable', `Enables CLI telemetry collection.`).conflicts('disable'))\n .option('--disable', `Disables CLI telemetry collection.`)\n .action((arg, options) => {\n if (options.enable || arg === 'enable') {\n telemetryService.setEnabled(true);\n isEnabled = true;\n\n consola.success('Success!\\n');\n } else if (options.disable || arg === 'disable') {\n telemetryService.setEnabled(false);\n\n if (isEnabled) {\n consola.success('Your preference has been saved.');\n } else {\n consola.info(`Catalyst CLI telemetry collection is already disabled.`);\n }\n\n isEnabled = false;\n } else {\n consola.info('Catalyst CLI Telemetry\\n');\n }\n\n consola.info(\n `Status: ${colorize('bold', isEnabled ? colorize('green', 'Enabled') : colorize('red', 'Disabled'))}`,\n );\n\n if (!isEnabled) {\n consola.info(\n `You have opted-out of Catalyst CLI telemetry. No data will be collected from your machine.`,\n );\n }\n });\n","import { Command, Option } from '@commander-js/extra-typings';\nimport { confirm } from '@inquirer/prompts';\nimport { execa } from 'execa';\nimport {\n access,\n copyFile,\n cp,\n mkdir,\n mkdtemp,\n readdir,\n readFile,\n rename,\n rm,\n writeFile,\n} from 'node:fs/promises';\nimport { homedir, tmpdir } from 'node:os';\nimport { dirname, join, relative } from 'node:path';\nimport { minVersion, satisfies, lt as semverLt, validRange, valid as validSemver } from 'semver';\nimport yoctoSpinner from 'yocto-spinner';\nimport { z } from 'zod';\n\nimport { cleanupCloudflareIncompatibilities } from '../lib/commerce-hosting';\nimport { detectLockfileManager, PackageManager } from '../lib/detect-package-manager';\nimport { consola } from '../lib/logger';\nimport { getProjectState } from '../lib/project-state';\nimport { getTelemetry } from '../lib/telemetry';\n\nconst CorePackageJson = z.object({\n name: z.string().optional(),\n version: z.string(),\n catalyst: z.object({ version: z.string(), ref: z.string() }).optional(),\n});\n\nconst DEP_FIELDS = [\n 'dependencies',\n 'devDependencies',\n 'optionalDependencies',\n 'peerDependencies',\n] as const;\n\nconst DepsPackageJson = z.looseObject({\n dependencies: z.record(z.string(), z.string()).optional(),\n devDependencies: z.record(z.string(), z.string()).optional(),\n optionalDependencies: z.record(z.string(), z.string()).optional(),\n peerDependencies: z.record(z.string(), z.string()).optional(),\n});\n\nconst WorkspacePackageJson = z.object({ name: z.string(), version: z.string() });\n\n// The CLI itself. `catalyst create` pins it exactly in devDependencies and it\n// doesn't exist in the upstream tree, so no merge will ever move it.\nconst CATALYST_CLI_PACKAGE = '@bigcommerce/catalyst';\n\n// Catalyst versions are git tags on the upstream monorepo (e.g.\n// \"@bigcommerce/catalyst-core@1.7.0\"), NOT npm packages. GitHub serves a\n// tarball for any tag via the repos/<owner>/<repo>/tarball/<ref> endpoint.\nconst DEFAULT_REPOSITORY = 'bigcommerce/catalyst';\n\n// Moving tags that don't pin a concrete version. When the target is one of\n// these we resolve the real version from the downloaded core/package.json so\n// catalyst.ref records a stable pin rather than the alias.\nconst MOVING_TAGS = new Set(['latest', 'canary', 'alpha']);\n\n// Known Catalyst package families, used to reconstruct a base ref from a\n// project's package.json `name` when `catalyst.ref` is missing.\nconst KNOWN_FAMILIES = new Set([\n '@bigcommerce/catalyst-core',\n '@bigcommerce/catalyst-makeswift',\n '@bigcommerce/catalyst-b2b-makeswift',\n '@bigcommerce/catalyst-b2b',\n]);\n\nconst CACHE_DIR = join(homedir(), '.cache', 'catalyst-cli', 'cores');\n\n// ── small fs helpers ──────────────────────────────────────────────────────────\nconst pathExists = (p: string) =>\n access(p)\n .then(() => true)\n .catch(() => false);\n\nasync function listFiles(dir: string, prefix = ''): Promise<string[]> {\n const entries = await readdir(dir, { withFileTypes: true }).catch(() => []);\n\n const nested = await Promise.all(\n entries.map((entry) => {\n const rel = prefix ? `${prefix}/${entry.name}` : entry.name;\n\n return entry.isDirectory() ? listFiles(join(dir, entry.name), rel) : Promise.resolve([rel]);\n }),\n );\n\n return nested.flat();\n}\n\nasync function filesEqual(a: string, b: string): Promise<boolean> {\n const [ba, bb] = await Promise.all([\n readFile(a).catch(() => null),\n readFile(b).catch(() => null),\n ]);\n\n return ba !== null && bb !== null && ba.equals(bb);\n}\n\n// Returns the fraction of files in baseDir that exist and are identical in\n// destDir. Used to validate an inferred base: a correct base scores ~0.7-0.8+\n// (the files the merchant hasn't touched); a wrong base scores much lower.\nexport async function computeBaseSimilarity(baseDir: string, destDir: string): Promise<number> {\n const baseFiles = await listFiles(baseDir);\n\n if (baseFiles.length === 0) return 0;\n\n const matches = await Promise.all(\n baseFiles.map((rel) => filesEqual(join(baseDir, rel), join(destDir, rel))),\n );\n\n return matches.filter(Boolean).length / baseFiles.length;\n}\n\nasync function isBinary(p: string): Promise<boolean> {\n const buf = await readFile(p).catch(() => null);\n\n if (!buf) return false;\n\n // Same heuristic git uses: a NUL byte near the start means binary.\n return buf.subarray(0, 8000).includes(0);\n}\n\nasync function copyInto(src: string, dest: string): Promise<void> {\n await mkdir(dirname(dest), { recursive: true });\n await copyFile(src, dest);\n}\n\n// ── ref parsing ─────────────────────────────────────────────────────────────\n// Splits \"@bigcommerce/catalyst-core@1.7.0\" → { packageName, version }.\n// The last \"@\" separates the version (scoped names start with \"@\").\nexport function parseRef(ref: string): { packageName: string; version: string } {\n const lastAt = ref.lastIndexOf('@');\n\n if (lastAt <= 0) throw new Error(`Cannot parse ref \"${ref}\" — expected <package>@<version>.`);\n\n return { packageName: ref.slice(0, lastAt), version: ref.slice(lastAt + 1) };\n}\n\nasync function readResolvedVersion(coreDir: string): Promise<string> {\n const raw = await readFile(join(coreDir, 'package.json'), 'utf-8');\n const pkg = CorePackageJson.parse(JSON.parse(raw));\n\n // catalyst.version is the source of truth; older tags lack it and fall back to version.\n return pkg.catalyst?.version ?? pkg.version;\n}\n\n// ── Catalyst dependency reconciliation ────────────────────────────────────────\n// Every tag's committed core/package.json still carries `workspace:` specifiers\n// for the Catalyst packages: core is `private`, so it is never published and\n// pnpm's publish-time rewrite never runs on the tagged tree. Base and theirs\n// therefore agree on those lines, the merge correctly leaves ours alone, and the\n// merchant's Catalyst dependency versions never move. `catalyst create` resolves\n// them at scaffold time instead, which is why flat projects hold a real range\n// and monorepo-structure projects still hold `workspace:^`.\n\n// Package name → the version that tag published. Indexing can miss: a package\n// that didn't exist yet at an older ref simply isn't in that tag's manifest.\nexport type WorkspaceVersions = Record<string, string | undefined>;\n\n// A Catalyst dependency the merchant still references through the workspace\n// protocol, alongside the published version it would migrate to.\nexport interface WorkspaceDepFinding {\n name: string;\n ours: string;\n version: string;\n}\n\nconst readDepSpecifiers = (raw: string): Record<string, string | undefined> => {\n let parsed: z.infer<typeof DepsPackageJson>;\n\n try {\n parsed = DepsPackageJson.parse(JSON.parse(raw));\n } catch {\n return {}; // conflict markers or hand-broken JSON — nothing to reconcile\n }\n\n return Object.fromEntries(DEP_FIELDS.flatMap((field) => Object.entries(parsed[field] ?? {})));\n};\n\n// Scoped package names carry \"@\" and \"/\", and some carry \".\"; escape before\n// embedding in a pattern.\nconst escapeRegExp = (value: string) => value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n\n// Swap a dependency's `workspace:` specifier for `^<version>` in raw\n// package.json text. Deliberately textual rather than a JSON round-trip: parsing\n// and re-stringifying would reformat the whole file, desyncing the downloaded\n// trees from the merchant's copy and turning a one-line dependency bump into a\n// whole-file conflict. It also keeps working on a file that still has conflict\n// markers in other sections.\nexport const rewriteWorkspaceSpecifier = (raw: string, name: string, version: string): string =>\n raw.replace(\n new RegExp(`(\"${escapeRegExp(name)}\"\\\\s*:\\\\s*)\"workspace:[^\"]*\"`, 'g'),\n (_match, key: string) => `${key}\"^${version}\"`,\n );\n\n// Rewrites the downloaded base/theirs package.json so each side names the\n// version its own tag actually shipped. The normal 3-way merge then carries the\n// bump for free — or conflicts, if the merchant pinned deliberately.\n//\n// A dependency the merchant still holds as `workspace:` is skipped on both\n// sides: normalizing there would manufacture a conflict on something that works\n// fine as-is. Those come back as findings for the migration prompt instead.\nexport async function normalizeWorkspaceDeps(\n ourPkgRaw: string,\n baseDir: string,\n theirsDir: string,\n baseVersions: WorkspaceVersions,\n targetVersions: WorkspaceVersions,\n): Promise<{ workspace: WorkspaceDepFinding[]; bumped: string[] }> {\n const basePath = join(baseDir, 'package.json');\n const theirsPath = join(theirsDir, 'package.json');\n const [originalBase, originalTheirs] = await Promise.all([\n readFile(basePath, 'utf-8').catch(() => null),\n readFile(theirsPath, 'utf-8').catch(() => null),\n ]);\n\n if (originalBase === null || originalTheirs === null) return { workspace: [], bumped: [] };\n\n const ourSpecifiers = readDepSpecifiers(ourPkgRaw);\n const names = new Set(\n [\n ...Object.entries(readDepSpecifiers(originalBase)),\n ...Object.entries(readDepSpecifiers(originalTheirs)),\n ]\n .filter(([, range]) => range?.startsWith('workspace:'))\n .map(([name]) => name),\n );\n\n const decisions = [...names].map((name) => ({\n name,\n ours: ourSpecifiers[name],\n baseVersion: baseVersions[name],\n targetVersion: targetVersions[name],\n }));\n\n const workspace = decisions.flatMap(({ name, ours, targetVersion }) =>\n ours?.startsWith('workspace:') && targetVersion !== undefined\n ? [{ name, ours, version: targetVersion }]\n : [],\n );\n\n // Everything else gets both sides pinned to the version its own tag shipped.\n // A version is missing when the package didn't exist at that ref yet; leave\n // that side untouched so the merge sees no change rather than a bogus one.\n const normalizable = decisions.filter(({ ours }) => !ours?.startsWith('workspace:'));\n\n const baseRaw = normalizable.reduce(\n (acc, { name, baseVersion }) =>\n baseVersion === undefined ? acc : rewriteWorkspaceSpecifier(acc, name, baseVersion),\n originalBase,\n );\n const theirsRaw = normalizable.reduce(\n (acc, { name, targetVersion }) =>\n targetVersion === undefined ? acc : rewriteWorkspaceSpecifier(acc, name, targetVersion),\n originalTheirs,\n );\n const bumped = normalizable\n .filter(\n ({ baseVersion, targetVersion }) =>\n baseVersion !== undefined && targetVersion !== undefined && baseVersion !== targetVersion,\n )\n .map(({ name }) => name);\n\n await Promise.all([\n baseRaw === originalBase ? null : writeFile(basePath, baseRaw),\n theirsRaw === originalTheirs ? null : writeFile(theirsPath, theirsRaw),\n ]);\n\n return { workspace, bumped };\n}\n\n// Applies the findings to the merchant's own package.json text.\nexport const migrateWorkspaceDeps = (raw: string, findings: WorkspaceDepFinding[]): string =>\n findings.reduce((acc, { name, version }) => rewriteWorkspaceSpecifier(acc, name, version), raw);\n\n// The CLI that performs upgrades can't upgrade itself through the merge, so\n// check npm directly. Best-effort: a registry hiccup must never fail an upgrade.\nexport async function findStaleCli(\n pkgRaw: string,\n): Promise<{ current: string; latest: string } | null> {\n const range = readDepSpecifiers(pkgRaw)[CATALYST_CLI_PACKAGE];\n\n // A merchant may point the dep at a tarball, git URL, or `link:` path, none of\n // which minVersion() can parse (it throws rather than returning null).\n if (range === undefined || !validRange(range)) return null;\n\n const body: unknown = await fetch(`https://registry.npmjs.org/${CATALYST_CLI_PACKAGE}/latest`, {\n // A hanging registry would otherwise stall the CLI indefinitely.\n signal: AbortSignal.timeout(5000),\n })\n .then((res) => (res.ok ? res.json() : null))\n .catch(() => null);\n const latest = z.object({ version: z.string() }).safeParse(body).data?.version;\n\n // The registry promises a string, not a semver one, and an unparseable version\n // would throw straight out of satisfies(). A range that already admits the\n // published version needs no advisory either — the next install picks it up,\n // which leaves this for the exact pin `catalyst create` writes.\n if (latest === undefined || !validSemver(latest) || satisfies(latest, range)) return null;\n\n const current = minVersion(range)?.version;\n\n return current !== undefined && semverLt(current, latest) ? { current, latest } : null;\n}\n\n// ── CLI-managed npm scripts ───────────────────────────────────────────────────\n// `catalyst create` points `build`/`start`/`deploy` at the CLI (see\n// setup-core-project.ts) so they dispatch on project state. The upstream tree\n// keeps its own `next`-based commands, so in every created project those lines\n// are a permanent ours-vs-base delta — and a delta that conflicts the moment\n// core edits a neighbouring line. Core 1.11.0 inserted `\"test\": \"vitest run\"`\n// directly below `\"start\"` and did exactly that; resolving the hunk toward\n// theirs (the obvious choice, since you do want the new `test` script) silently\n// reverted `catalyst start` to `next start`.\n//\n// So pin both downloaded sides to the commands the project already has for those\n// keys. The merge then sees no change there at all, ours survives untouched, and\n// additions around it still apply cleanly. Only keys where ours already differs\n// from base get pinned: where ours matches base there is no delta to conflict\n// with, and leaving that alone lets a genuine upstream edit through.\nconst CLI_MANAGED_SCRIPTS = ['build', 'start', 'deploy'] as const;\n\nconst ScriptsPackageJson = z.looseObject({\n scripts: z.record(z.string(), z.string()).optional(),\n});\n\n// A CLI-managed script the two tags disagree about. Pinning hides that from the\n// merge, so it gets reported rather than lost silently. `null` on either side\n// means that tag didn't carry the script at all.\nexport interface ManagedScriptFinding {\n name: string;\n base: string | null;\n theirs: string | null;\n}\n\nconst readScripts = (raw: string): Record<string, string | undefined> => {\n try {\n return ScriptsPackageJson.parse(JSON.parse(raw)).scripts ?? {};\n } catch {\n return {}; // conflict markers or hand-broken JSON — nothing to reconcile\n }\n};\n\n// Locates the `\"scripts\"` object in raw package.json text. The alternation steps\n// over complete JSON strings, so a brace inside a command can't end the match\n// early.\nconst SCRIPTS_BLOCK = /\"scripts\"\\s*:\\s*\\{(?:[^{}\"]|\"(?:[^\"\\\\]|\\\\.)*\")*\\}/;\n\n// Sets a script's command in raw package.json text, appending the entry when the\n// side doesn't have it yet (no upstream tag carries `deploy`). Deliberately\n// textual rather than a JSON round-trip, for the same reason as\n// rewriteWorkspaceSpecifier: re-stringifying would reformat the whole file and\n// desync the downloaded trees from the merchant's copy, turning a one-line script\n// change into a whole-file conflict.\nexport const rewriteScriptCommand = (raw: string, name: string, command: string): string => {\n const block = SCRIPTS_BLOCK.exec(raw);\n\n if (!block) return raw;\n\n const splice = (replacement: string) =>\n raw.slice(0, block.index) + replacement + raw.slice(block.index + block[0].length);\n\n // Function replacer so `$&` / `$1` inside a command can't interpolate.\n const updated = block[0].replace(\n new RegExp(`(\"${escapeRegExp(name)}\"\\\\s*:\\\\s*)\"(?:[^\"\\\\\\\\]|\\\\\\\\.)*\"`),\n (_match, key: string) => `${key}${JSON.stringify(command)}`,\n );\n\n if (updated !== block[0]) return splice(updated);\n\n // Absent — append, reusing the block's own indentation so the inserted line is\n // byte-identical to the one `catalyst create` writes into the project.\n const closeIdx = block[0].length - 1;\n const head = block[0].slice(0, closeIdx).replace(/\\s+$/, '');\n const closeIndent = /\\n([ \\t]*)$/.exec(block[0].slice(0, closeIdx))?.[1] ?? '';\n const entryIndent = /\\n([ \\t]*)\"/.exec(block[0])?.[1] ?? `${closeIndent} `;\n const separator = head.endsWith('{') ? '' : ',';\n\n return splice(\n `${head}${separator}\\n${entryIndent}${JSON.stringify(name)}: ${JSON.stringify(command)}\\n${closeIndent}}`,\n );\n};\n\n// Rewrites the downloaded base/theirs package.json so both sides carry the\n// project's own commands for the CLI-managed scripts.\nexport async function normalizeManagedScripts(\n ourPkgRaw: string,\n baseDir: string,\n theirsDir: string,\n): Promise<{ pinned: string[]; upstreamChanged: ManagedScriptFinding[] }> {\n const basePath = join(baseDir, 'package.json');\n const theirsPath = join(theirsDir, 'package.json');\n const [originalBase, originalTheirs] = await Promise.all([\n readFile(basePath, 'utf-8').catch(() => null),\n readFile(theirsPath, 'utf-8').catch(() => null),\n ]);\n\n if (originalBase === null || originalTheirs === null) return { pinned: [], upstreamChanged: [] };\n\n const ourScripts = readScripts(ourPkgRaw);\n const baseScripts = readScripts(originalBase);\n const theirsScripts = readScripts(originalTheirs);\n\n const decisions = CLI_MANAGED_SCRIPTS.flatMap((name) => {\n const ours = ourScripts[name];\n\n return ours !== undefined && ours !== baseScripts[name] ? [{ name, ours }] : [];\n });\n\n // Report whenever the two tags disagree about the script, which covers core\n // changing the command, introducing it, and dropping it. Pinning makes the\n // merge blind to all three: an introduced command gets overwritten with the\n // project's own, and a dropped one gets written back.\n const upstreamChanged = decisions.flatMap<ManagedScriptFinding>(({ name }) => {\n const base = baseScripts[name] ?? null;\n const theirs = theirsScripts[name] ?? null;\n\n return base !== theirs ? [{ name, base, theirs }] : [];\n });\n\n const baseRaw = decisions.reduce(\n (acc, { name, ours }) => rewriteScriptCommand(acc, name, ours),\n originalBase,\n );\n const theirsRaw = decisions.reduce(\n (acc, { name, ours }) => rewriteScriptCommand(acc, name, ours),\n originalTheirs,\n );\n\n await Promise.all([\n baseRaw === originalBase ? null : writeFile(basePath, baseRaw),\n theirsRaw === originalTheirs ? null : writeFile(theirsPath, theirsRaw),\n ]);\n\n return { pinned: decisions.map(({ name }) => name), upstreamChanged };\n}\n\n// ── per-file 3-way merge engine ───────────────────────────────────────────────\ntype MergeOutcome = 'applied' | 'added' | 'deleted' | 'conflicted';\n\n// Runs git merge-file (standalone, no object store) writing the merged result\n// (with <<<ours/===/theirs>>> markers on conflict) to `oursPath`.\nasync function mergeFile(oursPath: string, basePath: string, theirsPath: string): Promise<boolean> {\n const merged = await execa(\n 'git',\n [\n 'merge-file',\n '-p',\n '-L',\n 'ours',\n '-L',\n 'base',\n '-L',\n 'theirs',\n oursPath,\n basePath,\n theirsPath,\n ],\n { reject: false, stripFinalNewline: false },\n );\n\n // git merge-file exits 0 (clean) or N>0 (N conflict hunks) — both are normal.\n // A fatal error (e.g. unreadable file) produces stderr output; guard against\n // overwriting the user's file with empty/partial stdout in that case.\n if (merged.stderr) throw new Error(`git merge-file failed: ${merged.stderr}`);\n\n await writeFile(oursPath, merged.stdout);\n\n return (merged.exitCode ?? 0) > 0; // >0 = conflict hunks\n}\n\nasync function mergeModified(\n rel: string,\n baseDir: string,\n theirsDir: string,\n catalystRoot: string,\n): Promise<MergeOutcome | null> {\n const basePath = join(baseDir, rel);\n const theirsPath = join(theirsDir, rel);\n const oursPath = join(catalystRoot, rel);\n\n // Upstream didn't actually change this file — nothing to do.\n if (await filesEqual(basePath, theirsPath)) return null;\n\n // Merchant deleted a file upstream modifies → restore theirs, flag for review.\n if (!(await pathExists(oursPath))) {\n await copyInto(theirsPath, oursPath);\n\n return 'conflicted';\n }\n\n if ((await isBinary(basePath)) || (await isBinary(theirsPath)) || (await isBinary(oursPath))) {\n if (await filesEqual(oursPath, basePath)) {\n await copyInto(theirsPath, oursPath);\n\n return 'applied';\n }\n\n return 'conflicted'; // binary both-changed — can't 3-way; leave ours\n }\n\n return (await mergeFile(oursPath, basePath, theirsPath)) ? 'conflicted' : 'applied';\n}\n\nasync function mergeAdded(\n rel: string,\n theirsDir: string,\n catalystRoot: string,\n emptyFile: string,\n): Promise<MergeOutcome> {\n const theirsPath = join(theirsDir, rel);\n const oursPath = join(catalystRoot, rel);\n\n if (!(await pathExists(oursPath))) {\n await copyInto(theirsPath, oursPath);\n\n return 'added';\n }\n\n if (await filesEqual(oursPath, theirsPath)) return 'applied'; // merchant already has it\n\n if ((await isBinary(oursPath)) || (await isBinary(theirsPath))) return 'conflicted';\n\n // Both added a different version — merge against an empty ancestor.\n const hadConflict = await mergeFile(oursPath, emptyFile, theirsPath);\n\n return hadConflict ? 'conflicted' : 'applied';\n}\n\nasync function mergeDeleted(\n rel: string,\n baseDir: string,\n catalystRoot: string,\n): Promise<MergeOutcome | null> {\n const basePath = join(baseDir, rel);\n const oursPath = join(catalystRoot, rel);\n\n if (!(await pathExists(oursPath))) return null; // already gone\n\n // Merchant kept upstream's version → safe to delete. Otherwise it's a\n // delete/modify conflict: keep ours and flag.\n if (await filesEqual(oursPath, basePath)) {\n await rm(oursPath, { force: true });\n\n return 'deleted';\n }\n\n return 'conflicted';\n}\n\nexport interface MergeResult {\n applied: string[];\n added: string[];\n deleted: string[];\n conflicted: string[];\n}\n\n// Per-file engine: walk the changed-file set and merge each file with\n// `git merge-file`. Needs no git object store, so it works on shallow / no-history\n// merchant repos. Trade-off: no rename detection (a rename = delete + add).\nexport async function mergeCorePerFile(\n baseDir: string,\n theirsDir: string,\n catalystRoot: string,\n emptyFile: string,\n): Promise<MergeResult> {\n const baseFiles = new Set(await listFiles(baseDir));\n const theirsFiles = new Set(await listFiles(theirsDir));\n const result: MergeResult = { applied: [], added: [], deleted: [], conflicted: [] };\n\n const decide = async (rel: string): Promise<void> => {\n const inBase = baseFiles.has(rel);\n const inTheirs = theirsFiles.has(rel);\n\n let outcome: MergeOutcome | null;\n\n if (inBase && inTheirs) {\n outcome = await mergeModified(rel, baseDir, theirsDir, catalystRoot);\n } else if (inTheirs) {\n outcome = await mergeAdded(rel, theirsDir, catalystRoot, emptyFile);\n } else {\n outcome = await mergeDeleted(rel, baseDir, catalystRoot);\n }\n\n if (outcome) result[outcome].push(rel);\n };\n\n await Promise.all([...new Set([...baseFiles, ...theirsFiles])].map(decide));\n\n return result;\n}\n\n// ── merge strategy selection ───────────────────────────────────────────────────\nexport type MergeStrategy = 'auto' | 'tree' | 'per-file';\n\n// `git merge-tree --write-tree` (the whole-tree engine) landed in git 2.38.\nexport async function gitSupportsMergeTree(): Promise<boolean> {\n try {\n const { stdout } = await execa('git', ['--version']);\n const match = /(\\d+)\\.(\\d+)/.exec(stdout);\n\n if (!match) return false;\n\n const [major, minor] = [Number(match[1]), Number(match[2])];\n\n return major > 2 || (major === 2 && minor >= 38);\n } catch {\n return false;\n }\n}\n\n// 'auto' resolves to the whole-tree engine when git supports it, else per-file.\nexport async function resolveStrategy(strategy: MergeStrategy): Promise<'tree' | 'per-file'> {\n if (strategy !== 'auto') return strategy;\n\n if (await gitSupportsMergeTree()) return 'tree';\n\n consola.warn('git < 2.38 — using the per-file merge engine (no `git merge-tree`).');\n\n return 'per-file';\n}\n\n// ── whole-tree 3-way merge engine (git merge-tree, 2.38+) ──────────────────────\n// Builds base/ours/theirs as commits in a throwaway object store, runs a real\n// recursive merge (rename detection, modify/delete, mode changes, binary — all\n// native to git), then materialises the merged tree into the catalyst root.\n// Conflicts come back as in-blob <<<ours/===/theirs>>> markers; like per-file it\n// never aborts. Branch names `ours`/`theirs` make the markers match the per-file\n// engine's labels.\nexport async function mergeCoreTree(\n baseDir: string,\n theirsDir: string,\n catalystRoot: string,\n): Promise<MergeResult> {\n const scratch = await mkdtemp(join(tmpdir(), 'catalyst-merge-'));\n\n try {\n await execa('git', ['init', '-q', scratch]);\n // Disable line-ending conversion so checkout-index writes LF on all platforms.\n await execa('git', ['config', 'core.autocrlf', 'false'], {\n env: { ...process.env, GIT_DIR: join(scratch, '.git') },\n });\n\n const env = {\n ...process.env,\n GIT_DIR: join(scratch, '.git'),\n GIT_AUTHOR_NAME: 'catalyst',\n GIT_AUTHOR_EMAIL: 'catalyst@bigcommerce.com',\n GIT_COMMITTER_NAME: 'catalyst',\n GIT_COMMITTER_EMAIL: 'catalyst@bigcommerce.com',\n };\n\n // Snapshot a directory as a tree object (own index per side; .gitignore is\n // honoured, so build artifacts like node_modules never enter the tree).\n const writeTree = async (workTree: string, tag: string): Promise<string> => {\n const sideEnv = {\n ...env,\n GIT_WORK_TREE: workTree,\n GIT_INDEX_FILE: join(scratch, `index.${tag}`),\n };\n\n await execa('git', ['add', '-A'], { env: sideEnv });\n\n return (await execa('git', ['write-tree'], { env: sideEnv })).stdout.trim();\n };\n\n const commitTree = (tree: string, parent?: string) =>\n execa('git', ['commit-tree', tree, '-m', 'x', ...(parent ? ['-p', parent] : [])], {\n env,\n }).then((r) => r.stdout.trim());\n\n // Run sequentially to avoid concurrent writes to the shared object store\n // on Windows, where simultaneous git processes cause EPERM on object files.\n const baseTree = await writeTree(baseDir, 'base');\n const oursTree = await writeTree(catalystRoot, 'ours');\n const theirsTree = await writeTree(theirsDir, 'theirs');\n\n const baseCommit = await commitTree(baseTree);\n const [oursCommit, theirsCommit] = await Promise.all([\n commitTree(oursTree, baseCommit),\n commitTree(theirsTree, baseCommit),\n ]);\n\n await Promise.all([\n execa('git', ['branch', 'ours', oursCommit], { env }),\n execa('git', ['branch', 'theirs', theirsCommit], { env }),\n ]);\n\n // -z --name-only output: <merged-tree-oid> NUL, then conflicted paths each\n // NUL-terminated, then an empty field marks the end of the conflicted set\n // (everything after is informational messages we don't need).\n const merge = await execa(\n 'git',\n [\n 'merge-tree',\n '--write-tree',\n '-z',\n '--name-only',\n `--merge-base=${baseCommit}`,\n 'ours',\n 'theirs',\n ],\n { env, reject: false },\n );\n\n if ((merge.exitCode ?? 0) > 1)\n throw new Error(merge.stderr || merge.stdout.slice(0, 500) || 'git merge-tree failed');\n\n // -z --name-only emits <merged-tree-oid>, then conflicted paths, then an\n // empty field; everything after that is informational and ignored.\n const fields = merge.stdout.split('\\0');\n const mergedTree = fields[0];\n const afterOid = fields.slice(1);\n const emptyAt = afterOid.indexOf('');\n const conflicted = afterOid.slice(0, emptyAt === -1 ? afterOid.length : emptyAt);\n const conflictedSet = new Set(conflicted);\n\n // Materialise the merged tree into the catalyst root (conflict markers are\n // already baked into the conflicted blobs).\n const outEnv = {\n ...env,\n GIT_WORK_TREE: catalystRoot,\n GIT_INDEX_FILE: join(scratch, 'index.out'),\n };\n\n await execa('git', ['read-tree', mergedTree], { env: outEnv });\n await execa('git', ['checkout-index', '-a', '-f'], { env: outEnv });\n\n // Classify ours → merged. -z --name-status emits [status, path, status, …].\n const diff = await execa(\n 'git',\n ['diff', '-z', '--no-renames', '--name-status', oursTree, mergedTree],\n { env },\n );\n\n const tokens = diff.stdout.split('\\0');\n const changes: Array<{ status: string; path: string }> = [];\n\n for (let i = 0; i + 1 < tokens.length; i += 2) {\n const status = tokens[i];\n const path = tokens[i + 1];\n\n if (status && path && !conflictedSet.has(path)) {\n changes.push({ status, path });\n }\n }\n\n // checkout-index only writes; it won't remove paths the merge dropped.\n const deleted = changes.filter((change) => change.status === 'D').map((change) => change.path);\n\n await Promise.all(deleted.map((path) => rm(join(catalystRoot, path), { force: true })));\n\n return {\n applied: changes\n .filter((change) => change.status !== 'A' && change.status !== 'D')\n .map((change) => change.path),\n added: changes.filter((change) => change.status === 'A').map((change) => change.path),\n deleted,\n conflicted,\n };\n } finally {\n await rm(scratch, { recursive: true, force: true, maxRetries: 10, retryDelay: 500 });\n }\n}\n\n// ── index staging ──────────────────────────────────────────────────────────────\n// After the merge, stage everything that merged cleanly (so the merchant only\n// reviews what needs attention) and register conflicted files as real unmerged\n// index entries: stage 1 = base, 2 = ours (the committed pre-upgrade blob),\n// 3 = theirs. `git status` then reports them as conflicts (UU / AA / DU), which\n// lights up editors' merge UIs. No MERGE_HEAD — the target tag isn't an ancestor,\n// so resolving is a normal `git add` + commit, not a merge commit.\nexport async function applyIndexState(\n gitRoot: string,\n relDir: string,\n baseDir: string,\n theirsDir: string,\n result: MergeResult,\n stampedPkg: boolean,\n): Promise<void> {\n const toRepoPath = (rel: string) => (relDir === '.' ? rel : `${relDir}/${rel}`);\n const pkgRel = 'package.json';\n\n // If the stamp resolved package.json (stripped its conflict markers and wrote\n // clean JSON), treat it as a clean file rather than a conflict — it should be\n // staged normally so it shows up in `git diff --cached`, not registered as UU.\n const stillConflicted = result.conflicted.filter((rel) => !(stampedPkg && rel === pkgRel));\n const conflictedRepoPaths = new Set(stillConflicted.map(toRepoPath));\n\n // 1. Pre-stage the clean changes (+ the resolved package.json when stamped).\n const clean = [...result.applied, ...result.added, ...result.deleted].map(toRepoPath);\n\n if (stampedPkg) clean.push(toRepoPath(pkgRel));\n\n const toStage = [...new Set(clean)].filter((path) => !conflictedRepoPaths.has(path));\n\n if (toStage.length) {\n await execa('git', ['add', '-A', '--', ...toStage], { cwd: gitRoot });\n }\n\n if (stillConflicted.length === 0) return;\n\n // 2. Conflicts → unmerged index entries. ours = the committed blob (the\n // clean-tree precondition guarantees the worktree matched HEAD before the\n // merge); base/theirs blobs get written into the repo's object store.\n const OID = /^[0-9a-f]{40,64}$/;\n // Detect SHA-256 repos (git 2.29+). SHA-1 uses a 40-zero null OID; SHA-256 uses 64.\n const gitFormat = (\n await execa('git', ['rev-parse', '--show-object-format'], { cwd: gitRoot, reject: false })\n ).stdout.trim();\n const NULL_OID = gitFormat === 'sha256' ? '0'.repeat(64) : '0'.repeat(40);\n\n // Write a file's content as a blob; null if the file is absent or the OID\n // comes back malformed (guards against shell wrappers polluting stdout).\n const hashBlob = async (file: string): Promise<string | null> => {\n if (!(await pathExists(file))) return null;\n\n const oid = (\n await execa('git', ['hash-object', '-w', '--', file], { cwd: gitRoot })\n ).stdout.trim();\n\n return OID.test(oid) ? oid : null;\n };\n\n // ours mode + blob via `ls-tree`. Unlike `rev-parse HEAD:<path>`, ls-tree\n // never echoes a missing path back as if it were an object name.\n const headEntry = async (repoPath: string): Promise<{ mode: string; oid: string } | null> => {\n const { stdout } = await execa('git', ['ls-tree', 'HEAD', '--', repoPath], {\n cwd: gitRoot,\n reject: false,\n });\n const match = /^(\\d{6}) blob ([0-9a-f]+)\\t/.exec(stdout);\n\n return match ? { mode: match[1], oid: match[2] } : null;\n };\n\n const records = await Promise.all(\n stillConflicted.map(async (rel) => {\n const repoPath = toRepoPath(rel);\n const [base, ours, theirs] = await Promise.all([\n hashBlob(join(baseDir, rel)),\n headEntry(repoPath),\n hashBlob(join(theirsDir, rel)),\n ]);\n\n return [\n `0 ${NULL_OID}\\t${repoPath}`,\n ...(base ? [`100644 ${base} 1\\t${repoPath}`] : []),\n ...(ours ? [`${ours.mode} ${ours.oid} 2\\t${repoPath}`] : []),\n ...(theirs ? [`100644 ${theirs} 3\\t${repoPath}`] : []),\n ].join('\\n');\n }),\n );\n\n await execa('git', ['update-index', '--index-info'], {\n cwd: gitRoot,\n input: `${records.join('\\n')}\\n`,\n });\n}\n\n// ── project (destination) layout resolution ───────────────────────────────────\n// The command is merchant-facing and must support two repo shapes:\n// * flat (future) — core/ contents at the repo root (package.json at root)\n// * nested (deprecated monorepo clone) — core/package.json under <root>/core\n// We locate the package.json carrying the `catalyst` field; if none has it yet\n// we fall back to the most likely Catalyst package.json so the auto-detect path\n// can still run.\ninterface Project {\n gitRoot: string;\n catalystRoot: string;\n relDir: string; // \".\" (flat) or \"core\" (nested), relative to gitRoot\n pkgPath: string;\n rawContent: string;\n pkg: z.infer<typeof CorePackageJson>;\n}\n\nexport async function resolveProject(cwd: string): Promise<Project | null> {\n let gitRoot: string;\n\n try {\n gitRoot = (await execa('git', ['rev-parse', '--show-toplevel'], { cwd })).stdout.trim();\n } catch {\n return null;\n }\n\n // Probe order favours the nested core/ first (a monorepo clone also has a\n // root package.json we don't want), then flat, then the cwd variants.\n const candidateDirs = [...new Set([join(gitRoot, 'core'), gitRoot, join(cwd, 'core'), cwd])];\n\n const parsed = (\n await Promise.all(\n candidateDirs.map(async (dir) => {\n const pkgPath = join(dir, 'package.json');\n const raw = await readFile(pkgPath, 'utf-8').catch(() => null);\n\n if (!raw) return null;\n\n let pkgJson: unknown;\n\n try {\n pkgJson = JSON.parse(raw);\n } catch {\n return null;\n }\n\n const result = CorePackageJson.safeParse(pkgJson);\n\n return result.success ? { dir, pkgPath, raw, pkg: result.data } : null;\n }),\n )\n ).filter((entry) => entry !== null);\n\n if (parsed.length === 0) return null;\n\n // Prefer the package.json that already declares `catalyst`; otherwise fall\n // back to one that looks like a Catalyst project (known family name).\n const chosen =\n parsed.find((p) => p.pkg.catalyst?.ref) ??\n parsed.find((p) => p.pkg.name !== undefined && KNOWN_FAMILIES.has(p.pkg.name)) ??\n parsed[0];\n\n return {\n gitRoot,\n catalystRoot: chosen.dir,\n relDir: relative(gitRoot, chosen.dir) || '.',\n pkgPath: chosen.pkgPath,\n rawContent: chosen.raw,\n pkg: chosen.pkg,\n };\n}\n\n// ── tarball download (source side stays the monorepo) ─────────────────────────\n// Harvests the versions the monorepo's publishable packages carried at this ref.\n// This is the only place they're knowable: the tag's core/package.json names them\n// as `workspace:`, and they version independently of core (no changesets\n// `linked`/`fixed` group), so an npm `latest` lookup would answer for today\n// rather than for the ref being downloaded.\nconst readWorkspaceVersions = async (repoDir: string): Promise<WorkspaceVersions> => {\n const packagesDir = join(repoDir, 'packages');\n const entries = await readdir(packagesDir, { withFileTypes: true }).catch(() => []);\n\n const manifests = await Promise.all(\n entries\n .filter((entry) => entry.isDirectory())\n .map(async (entry) => {\n const raw = await readFile(join(packagesDir, entry.name, 'package.json'), 'utf-8').catch(\n () => null,\n );\n\n if (raw === null) return null;\n\n try {\n return WorkspacePackageJson.parse(JSON.parse(raw));\n } catch {\n return null;\n }\n }),\n );\n\n return Object.fromEntries(\n manifests.filter((pkg) => pkg !== null).map(({ name, version }) => [name, version]),\n );\n};\n\nconst readCachedVersions = async (path: string): Promise<WorkspaceVersions | null> => {\n const raw = await readFile(path, 'utf-8').catch(() => null);\n\n if (raw === null) return null;\n\n try {\n return z.record(z.string(), z.string()).parse(JSON.parse(raw));\n } catch {\n return null;\n }\n};\n\nexport async function downloadCore(\n repository: string,\n ref: string,\n destDir: string,\n token?: string,\n): Promise<WorkspaceVersions> {\n // Never cache moving tags (latest/canary/alpha) — they'd go stale silently.\n const cacheable = !MOVING_TAGS.has(parseRef(ref).version);\n // Use a separator before the ref so that repository strings differing only\n // by characters that sanitize to '_' (e.g. '/' vs '_') produce distinct keys.\n const cacheKey = `${repository.replace(/[^a-zA-Z0-9._-]/g, '_')}__${ref.replace(/[^a-zA-Z0-9._-]/g, '_')}`;\n const cachePath = join(CACHE_DIR, cacheKey);\n const versionsPath = `${cachePath}.versions.json`;\n\n // Guard against a partially-written cache entry: two concurrent downloadCore\n // calls for the same ref can race — the first creates cachePath mid-copy, and\n // the second sees it as present but gets an incomplete directory. Validate with\n // a package.json sentinel (every extracted core/ tree must have one) plus the\n // versions sidecar, which also makes entries written before the sidecar existed\n // fall through to a fresh download rather than answering with no versions.\n const cachedVersions =\n cacheable && (await pathExists(join(cachePath, 'package.json')))\n ? await readCachedVersions(versionsPath)\n : null;\n\n if (cachedVersions) {\n await cp(cachePath, destDir, { recursive: true });\n\n return cachedVersions;\n }\n\n // encodeURIComponent turns \"@bigcommerce/catalyst-core@1.7.0\" into\n // \"%40bigcommerce%2Fcatalyst-core%401.7.0\", which the API accepts.\n const url = `https://api.github.com/repos/${repository}/tarball/${encodeURIComponent(ref)}`;\n const headers: Record<string, string> = {\n 'User-Agent': 'catalyst-cli',\n Accept: 'application/vnd.github+json',\n };\n\n if (token) headers.Authorization = `Bearer ${token}`;\n\n const res = await fetch(url, { headers });\n\n if (!res.ok) {\n let hint = '';\n\n if (res.status === 404) hint = ` — tag \"${ref}\" not found in ${repository}`;\n if (res.status === 403) hint = ' — GitHub rate limit hit; set GITHUB_TOKEN to raise it';\n\n throw new Error(`GitHub returned ${res.status} for ${ref}${hint}`);\n }\n\n const tarballPath = `${destDir}.tgz`;\n const rawDir = `${destDir}.raw`;\n\n await writeFile(tarballPath, Buffer.from(await res.arrayBuffer()));\n await mkdir(rawDir, { recursive: true });\n // --strip-components=1 drops the \"bigcommerce-catalyst-<sha>/\" top dir.\n await execa('tar', ['-xzf', tarballPath, '-C', rawDir, '--strip-components=1']);\n\n // Source is expected to be the monorepo (core/ inside); fall back to the\n // extracted root for a hypothetical flat-source tag (insurance, not a target).\n const coreDir = join(rawDir, 'core');\n const sourceDir = (await pathExists(coreDir)) ? coreDir : rawDir;\n\n // Read the sibling packages before rawDir is torn down — destDir keeps core/ only.\n const workspaceVersions = await readWorkspaceVersions(rawDir);\n\n await rename(sourceDir, destDir);\n await rm(tarballPath, { force: true });\n await rm(rawDir, { recursive: true, force: true });\n\n if (cacheable) {\n await mkdir(CACHE_DIR, { recursive: true });\n await cp(destDir, cachePath, { recursive: true })\n .then(() => writeFile(versionsPath, JSON.stringify(workspaceVersions)))\n .catch(() => {\n /* best-effort cache; ignore failures */\n });\n }\n\n return workspaceVersions;\n}\n\n// ── base-ref resolution / auto-detect ─────────────────────────────────────────\n// Returns the base ref to diff from, auto-detecting when catalyst.ref is absent.\nexport async function resolveBaseRef(\n project: Project,\n fromOption: string | undefined,\n assumeYes: boolean,\n): Promise<string | null> {\n if (project.pkg.catalyst?.ref) return project.pkg.catalyst.ref;\n if (fromOption) return fromOption;\n\n // Older projects mirror the Catalyst version in `version`; the package `name`\n // tells us the family. Propose the inferred ref and let the merchant confirm.\n const family =\n project.pkg.name && KNOWN_FAMILIES.has(project.pkg.name)\n ? project.pkg.name\n : '@bigcommerce/catalyst-core';\n const guess = `${family}@${project.pkg.version}`;\n\n consola.warn(`No \\`catalyst.ref\\` found in package.json. Inferred base: ${guess}`);\n\n if (assumeYes) return guess;\n\n const ok = await confirm({ message: `Upgrade from ${guess}?`, default: true }).catch(() => false);\n\n if (!ok) {\n consola.info('Re-run with `--from <ref>` to set the base version explicitly.');\n\n return null;\n }\n\n return guess;\n}\n\n// ── summary output ────────────────────────────────────────────────────────────\nfunction printWorkspaceFindings(findings: WorkspaceDepFinding[]): void {\n if (findings.length === 0) return;\n\n const pad = Math.max(...findings.map((finding) => finding.name.length));\n const rows = findings\n .map((finding) => ` ${finding.name.padEnd(pad)} ${finding.ours} → ^${finding.version}`)\n .join('\\n');\n\n consola.warn(\n `Catalyst dependencies still using the workspace protocol (${findings.length}):\\n${rows}\\n\\nThey resolve to your local packages/ copies, which \\`catalyst upgrade\\` does not update — so they never receive upgrades.`,\n );\n}\n\n// Pinning the CLI-managed scripts keeps the merge off those lines, so an upstream\n// edit to one of them would otherwise vanish without a trace. Report it instead.\nfunction printManagedScriptFindings(findings: ManagedScriptFinding[]): void {\n if (findings.length === 0) return;\n\n const pad = Math.max(...findings.map((finding) => finding.name.length));\n const show = (command: string | null) => command ?? '(absent)';\n const rows = findings\n .map(\n (finding) => ` ${finding.name.padEnd(pad)} ${show(finding.base)} → ${show(finding.theirs)}`,\n )\n .join('\\n');\n\n consola.warn(\n `Core's own version of ${findings.length} npm script${findings.length === 1 ? '' : 's'} the CLI manages for you changed:\\n${rows}\\n\\nYour project keeps its \\`catalyst\\`-backed command, which is almost always what you want — \\`catalyst build\\`/\\`start\\`/\\`deploy\\` wrap the equivalent \\`next\\` command. Apply the change by hand only if you have opted out of the CLI scripts.`,\n );\n}\n\ninterface Summary {\n result: MergeResult;\n relDir: string;\n stampedPkg: boolean;\n migratedDeps: number;\n packageManager: PackageManager;\n staleCli: { current: string; latest: string } | null;\n}\n\nfunction printSummary({\n result,\n relDir,\n stampedPkg,\n migratedDeps,\n packageManager,\n staleCli,\n}: Summary): void {\n // package.json is excluded from the conflict list when the stamp resolved it.\n const unresolved = result.conflicted.filter((f) => !(stampedPkg && f === 'package.json'));\n\n const parts = [\n `${result.applied.length} updated`,\n `${result.added.length} added`,\n `${result.deleted.length} removed`,\n ];\n\n if (unresolved.length) parts.push(`${unresolved.length} with conflicts`);\n\n consola.log(`\\n${parts.join(', ')}`);\n\n // Any package.json change can move dependencies, and the upgrade never installs,\n // so the lockfile is left behind either way.\n const pkgConflicted = unresolved.includes('package.json');\n const depsChanged =\n migratedDeps > 0 ||\n [...result.applied, ...result.added, ...result.conflicted].includes('package.json');\n\n // Stay quiet while package.json itself is unresolved: an install against a\n // manifest full of conflict markers just fails. It joins the resolution steps\n // below instead, so it runs in the right order.\n if (depsChanged && !pkgConflicted) {\n consola.info(\n `Dependencies changed — run \\`${packageManager} install\\` to update your lockfile.`,\n );\n }\n\n if (unresolved.length) {\n const files = unresolved.map((f) => ` ${f}`).join('\\n');\n const install = depsChanged && pkgConflicted ? ` && ${packageManager} install` : '';\n\n consola.warn(\n `\\nStaged the clean changes. ${unresolved.length} file(s) need conflict resolution (the <<<ours/===/theirs>>> markers):\\n${files}\\n\\nResolve them, then: git add ${relDir} && git commit${install}`,\n );\n } else {\n consola.success('Staged all changes — review with `git diff --cached`, then commit.');\n }\n\n if (staleCli) {\n consola.info(\n `Your Catalyst CLI is behind (${staleCli.current} → ${staleCli.latest}). Update it with \\`${packageManager} add -D ${CATALYST_CLI_PACKAGE}@${staleCli.latest}\\`.`,\n );\n }\n}\n\nexport async function reconcileNativeHosting(\n catalystRoot: string,\n result: MergeResult,\n): Promise<void> {\n const state = getProjectState(catalystRoot);\n\n if (!state.isLinked && !state.isTransformed) return;\n\n const instrumentationRel = 'instrumentation.ts';\n const instrumentationPath = join(catalystRoot, instrumentationRel);\n const hadInstrumentation = await pathExists(instrumentationPath);\n\n try {\n await cleanupCloudflareIncompatibilities(catalystRoot);\n } catch (err) {\n consola.warn(\n `Couldn't fully reconcile native-hosting files (${err instanceof Error ? err.message : String(err)}). Remove @vercel/otel from package.json by hand if the merge brought it back.`,\n );\n }\n\n if (hadInstrumentation && !(await pathExists(instrumentationPath))) {\n result.conflicted = result.conflicted.filter((rel) => rel !== instrumentationRel);\n result.applied = result.applied.filter((rel) => rel !== instrumentationRel);\n result.added = result.added.filter((rel) => rel !== instrumentationRel);\n }\n}\n\nexport const upgrade = new Command('upgrade')\n .configureHelp({ showGlobalOptions: true })\n .aliases([\n 'up',\n // These are hidden aliases\n 'upgrayedd',\n 'ugrad',\n ])\n .description('Upgrade your Catalyst project to a newer version by applying a 3-way merge.')\n .argument('[version]', 'Target version to upgrade to (default: latest)')\n .addOption(\n new Option(\n '--ref <ref>',\n 'Full git tag to upgrade to, e.g. an integration family like @bigcommerce/catalyst-makeswift@1.7.0. Overrides [version].',\n ),\n )\n .addOption(new Option('--from <ref>', 'Base ref to upgrade from (when catalyst.ref is missing)'))\n .option('--dry-run', 'Generate and display the diff without applying it')\n .option('--yes', 'Skip confirmation prompts (e.g. inferred base ref)')\n .addOption(\n new Option(\n '--strategy <strategy>',\n 'Merge engine: tree (git merge-tree, full fidelity), per-file (git merge-file, no-history fallback), or auto (tree when git >= 2.38, else per-file)',\n )\n .choices(['auto', 'tree', 'per-file'] as const)\n .default('auto' as const)\n .hideHelp(),\n )\n .addOption(\n new Option('--repository <owner/repo>', 'GitHub repository to pull versions from').default(\n DEFAULT_REPOSITORY,\n ),\n )\n .addHelpText(\n 'after',\n `\nExamples:\n # Upgrade to the latest Catalyst version\n $ catalyst upgrade\n\n # Upgrade to a specific version\n $ catalyst upgrade 1.8.0\n\n # Preview what would change without applying\n $ catalyst upgrade --dry-run\n\n # Upgrade to an integration family (makeswift, b2b-makeswift, ...)\n $ catalyst upgrade --ref @bigcommerce/catalyst-makeswift@1.7.0\n\nConflicts are written as standard <<<ours/===/theirs>>> markers — the upgrade\nnever aborts. Versions are git tags on the repository (not npm). Set GITHUB_TOKEN\nto raise the GitHub API rate limit.`,\n )\n // eslint-disable-next-line complexity\n .action(async (version, options) => {\n // ── 1. Resolve the merchant project (flat or nested layout) ───────────\n const project = await resolveProject(process.cwd());\n\n if (!project) {\n consola.error(\n 'Run `catalyst upgrade` from inside a Catalyst git repository (flat core/ repo or a project containing core/).',\n );\n process.exit(1);\n }\n\n const { gitRoot, catalystRoot, relDir, pkgPath } = project;\n\n // ── 2. Resolve base + target refs ─────────────────────────────────────\n const baseRef = await resolveBaseRef(project, options.from, options.yes ?? false);\n\n if (!baseRef) process.exit(1);\n\n let basePackage: string;\n let upstreamRef: string;\n let upstreamTagVersion: string;\n\n try {\n ({ packageName: basePackage } = parseRef(baseRef));\n upstreamRef = options.ref ?? `${basePackage}@${version ?? 'latest'}`;\n ({ version: upstreamTagVersion } = parseRef(upstreamRef));\n } catch {\n consola.error(\n `Invalid ref format — expected <package>@<version> (e.g. @bigcommerce/catalyst-core@1.7.0). Got: \"${baseRef}\"`,\n );\n process.exit(1);\n }\n\n if (upstreamRef === baseRef) {\n consola.success('Already up to date.');\n\n return;\n }\n\n // ── 3. Require a clean working tree at the catalyst root (preview exempt) ─\n // The merge writes in place, so pre-existing uncommitted edits would be\n // indistinguishable from the upgrade. Committing/stashing first gives the\n // merchant a clean point to diff and roll back from.\n if (!options.dryRun) {\n const statusArgs = relDir === '.' ? [] : ['--', relDir];\n const status = await execa('git', ['status', '--porcelain', ...statusArgs], {\n cwd: gitRoot,\n reject: false,\n });\n\n if (status.stdout.trim()) {\n const where = relDir === '.' ? 'The repo' : `${relDir}/`;\n\n consola.error(\n `${where} has uncommitted changes. Commit or stash them before upgrading, so the upgrade is isolated and reversible:\\n git add ${relDir} && git commit -m \"snapshot before upgrade\"\\n # or: git stash`,\n );\n process.exit(1);\n }\n }\n\n // ── 3b. Backfill catalyst.ref when it was inferred ────────────────────\n // If catalyst.ref was absent and the user confirmed an inferred base (not\n // an explicit --from), write the field and stage it so it travels with the\n // upgrade commit. Runs after the clean-tree check so we only add to an\n // already-clean index. --from is excluded: the user already knows the base\n // and shouldn't get an extra staged change they didn't ask for.\n if (!project.pkg.catalyst?.ref && !options.from && !options.dryRun) {\n const { version: baseVersion } = parseRef(baseRef);\n const rawPkg = await readFile(pkgPath, 'utf-8');\n const parsedPkg = z.record(z.string(), z.unknown()).parse(JSON.parse(rawPkg));\n\n parsedPkg.catalyst = { version: baseVersion, ref: baseRef };\n await writeFile(pkgPath, `${JSON.stringify(parsedPkg, null, 2)}\\n`);\n await execa('git', ['add', '--', pkgPath], { cwd: gitRoot });\n consola.success(`Added catalyst.ref → ${baseRef}`);\n }\n\n const token = process.env.GITHUB_TOKEN;\n const tmpDir = await mkdtemp(join(tmpdir(), 'catalyst-upgrade-'));\n\n try {\n const baseDir = join(tmpDir, 'base');\n const theirsDir = join(tmpDir, 'theirs');\n const emptyFile = join(tmpDir, '.empty');\n\n await writeFile(emptyFile, '');\n\n // Start the registry check now so its round-trip overlaps the tarball\n // downloads rather than adding dead air after the merge. Reading the\n // pre-merge manifest is also more robust: the CLI dependency isn't in\n // either upstream tree, so nothing below can move it, and this way the\n // advisory survives a merge that leaves conflict markers in package.json.\n const staleCliCheck = findStaleCli(project.rawContent).catch(() => null);\n\n const downloadSpinner = yoctoSpinner().start(`Downloading ${baseRef} and ${upstreamRef}...`);\n\n let baseVersions: WorkspaceVersions;\n let targetVersions: WorkspaceVersions;\n\n try {\n [baseVersions, targetVersions] = await Promise.all([\n downloadCore(options.repository, baseRef, baseDir, token),\n downloadCore(options.repository, upstreamRef, theirsDir, token),\n ]);\n downloadSpinner.success('Downloaded both versions.');\n } catch (err) {\n downloadSpinner.error('Download failed');\n throw err;\n }\n\n // When the base was auto-inferred (no catalyst.ref, no --from), validate\n // the guess by checking how many base files are unmodified in the project.\n // A correct base scores ~70-80%+; a wrong guess (e.g. merchant manually\n // bumped their version field without actually upgrading) scores much lower.\n if (!project.pkg.catalyst?.ref && !options.from) {\n const similarity = await computeBaseSimilarity(baseDir, catalystRoot);\n const pct = Math.round(similarity * 100);\n\n if (similarity < 0.5) {\n consola.warn(\n `Low confidence in inferred base ${baseRef} (${pct}% of base files match your project). If the merge result looks off, re-run with \\`--from <correct-version>\\` to set the base explicitly.`,\n );\n }\n }\n\n // For moving tags (latest/canary/alpha) we don't know the real version\n // until the tarball lands, so read it from the downloaded package.json.\n // For concrete tags the version is already in the tag itself.\n const resolvedVersion = MOVING_TAGS.has(upstreamTagVersion)\n ? await readResolvedVersion(theirsDir)\n : upstreamTagVersion;\n const newRef = MOVING_TAGS.has(upstreamTagVersion)\n ? `${basePackage}@${resolvedVersion}`\n : upstreamRef;\n\n // ── 3c. Teach the merge about Catalyst dependency versions ──────────\n // Runs before the dry run so the preview shows the dependency change too.\n // rawContent predates the 3b backfill, which only touches the `catalyst`\n // field — dependency specifiers are identical either way.\n const { workspace: workspaceDeps, bumped } = await normalizeWorkspaceDeps(\n project.rawContent,\n baseDir,\n theirsDir,\n baseVersions,\n targetVersions,\n );\n\n // ── 3d. Keep the merge off the CLI-managed npm scripts ──────────────\n // Also before the dry run, so the preview matches what will be applied.\n const { upstreamChanged: managedScripts } = await normalizeManagedScripts(\n project.rawContent,\n baseDir,\n theirsDir,\n );\n\n // ── 4. Dry run: show the unified diff and stop ──────────────────────\n if (options.dryRun) {\n const diffSpinner = yoctoSpinner().start('Generating diff...');\n const diff = await execa(\n 'git',\n ['diff', '--no-index', '--binary', '--diff-algorithm=histogram', 'base', 'theirs'],\n { cwd: tmpDir, reject: false, stripFinalNewline: false },\n );\n\n if ((diff.exitCode ?? 0) > 1) {\n diffSpinner.error('Failed to generate diff');\n throw new Error(diff.stderr);\n }\n\n if (!diff.stdout.trim()) {\n diffSpinner.success('No differences between versions — already up to date.');\n\n return;\n }\n\n const fileCount = (diff.stdout.match(/^diff --git /gm) ?? []).length;\n\n diffSpinner.success(`Diff ready — ${fileCount} file(s) affected.`);\n consola.log('\\nDiff preview (--dry-run, not applied):\\n');\n consola.log(diff.stdout);\n\n printWorkspaceFindings(workspaceDeps);\n printManagedScriptFindings(managedScripts);\n\n return;\n }\n\n // ── 5. Apply via 3-way merge (whole-tree by default, per-file fallback) ─\n const strategy = await resolveStrategy(options.strategy);\n const mergeSpinner = yoctoSpinner().start(`Merging changes (${strategy})...`);\n const result =\n strategy === 'tree'\n ? await mergeCoreTree(baseDir, theirsDir, catalystRoot)\n : await mergeCorePerFile(baseDir, theirsDir, catalystRoot, emptyFile);\n const total =\n result.applied.length +\n result.added.length +\n result.deleted.length +\n result.conflicted.length;\n\n if (total === 0) {\n mergeSpinner.success('No differences between versions — already up to date.');\n\n return;\n }\n\n if (result.conflicted.length) {\n mergeSpinner.warning('Merged with conflicts — resolve the markers, then commit.');\n } else {\n mergeSpinner.success('Merged cleanly.');\n }\n\n // ── 6. Stamp catalyst.ref (skip if package.json itself conflicted) ──\n const patchedRaw = await readFile(pkgPath, 'utf-8');\n\n // Non-null once the stamp has written clean JSON, and then it is exactly\n // what sits on disk. Stays null when package.json came out of the merge\n // carrying conflict markers.\n let stampedText: string | null = null;\n\n try {\n const patchedPkg = z.record(z.string(), z.unknown()).parse(JSON.parse(patchedRaw));\n\n patchedPkg.catalyst = { version: resolvedVersion, ref: newRef };\n stampedText = `${JSON.stringify(patchedPkg, null, 2)}\\n`;\n await writeFile(pkgPath, stampedText);\n consola.success(`catalyst.ref updated → ${newRef}`);\n } catch {\n // package.json has conflict markers (scripts, deps, etc.). The catalyst\n // field was added cleanly by ours and should sit outside the conflict\n // blocks — so replace just that field in-place, leaving all other conflict\n // markers intact for the merchant to resolve normally.\n const catalystReplacement = JSON.stringify(\n { version: resolvedVersion, ref: newRef },\n null,\n 2,\n )\n .split('\\n')\n .map((line, i) => (i === 0 ? line : ` ${line}`))\n .join('\\n');\n\n // Use a function replacer to prevent $-interpolation in the replacement string\n // (e.g. $& or $1 in a ref/version value would silently corrupt the output).\n const updated = patchedRaw.replace(\n /\"catalyst\":\\s*\\{[^}]*\\}/,\n () => `\"catalyst\": ${catalystReplacement}`,\n );\n\n if (updated !== patchedRaw) {\n await writeFile(pkgPath, updated);\n // stampedText stays null — the file still has conflict markers in other\n // sections, so it must stay as a UU unmerged entry so the editor shows\n // the merge UI. Only the catalyst field was resolved in place.\n consola.success(`catalyst.ref updated → ${newRef}`);\n consola.info(\n 'package.json still has conflicts in other sections — resolve them, then: git add package.json',\n );\n } else {\n consola.warn(\n `package.json has conflicts — after resolving, add:\\n \"catalyst\": { \"version\": \"${resolvedVersion}\", \"ref\": \"${newRef}\" }`,\n );\n }\n }\n\n printManagedScriptFindings(managedScripts);\n\n // ── 6b. Offer to migrate workspace-protocol Catalyst dependencies ────\n printWorkspaceFindings(workspaceDeps);\n\n let migratedDeps = 0;\n\n if (workspaceDeps.length) {\n // Rewriting a package.json that still holds conflict markers could land\n // inside a hunk the merchant hasn't reviewed, so the swap is only ever\n // applied to a file the stamp already parsed cleanly. Past that, --yes\n // means yes (as it does for the inferred base ref), and a non-interactive\n // run falls through to printing the versions.\n const accepted =\n stampedText !== null &&\n (options.yes === true ||\n (Boolean(process.stdin.isTTY) &&\n (await confirm({\n message: 'Replace them with the published versions?',\n default: true,\n }).catch(() => false))));\n\n if (accepted && stampedText !== null) {\n await writeFile(pkgPath, migrateWorkspaceDeps(stampedText, workspaceDeps));\n migratedDeps = workspaceDeps.length;\n consola.success(\n `Migrated ${migratedDeps} dependenc${migratedDeps === 1 ? 'y' : 'ies'} to published versions.`,\n );\n } else {\n consola.info(\n \"Keeping the workspace references. Switching abandons any local packages/ copy you've customized; otherwise apply the versions above in package.json and reinstall.\",\n );\n }\n }\n\n await reconcileNativeHosting(catalystRoot, result);\n\n // ── 7. Stage the clean changes; mark conflicts as real unmerged entries ─\n // Staging is a convenience; the merge already landed on disk, so never let\n // a git quirk here fail the whole upgrade.\n try {\n await applyIndexState(gitRoot, relDir, baseDir, theirsDir, result, stampedText !== null);\n } catch (err) {\n consola.warn(\n `Couldn't auto-stage the changes (${err instanceof Error ? err.message : String(err)}). Your files are merged on disk — run \\`git add ${relDir}\\` yourself.`,\n );\n }\n\n const gitVersion = await execa('git', ['--version'])\n .then((r) => r.stdout.trim())\n .catch(() => 'unknown');\n\n // The lockfile lives at the repo root for both layouts and is committed by\n // every real project, so it answers this on its own. Catalyst scaffolds with\n // pnpm, which makes it the least-surprising answer when there isn't one.\n const packageManager = (await detectLockfileManager(gitRoot)) ?? 'pnpm';\n const staleCli = await staleCliCheck;\n\n await getTelemetry().track('upgrade', {\n strategy,\n gitVersion,\n dryRun: Boolean(options.dryRun),\n applied: result.applied.length,\n added: result.added.length,\n deleted: result.deleted.length,\n conflicts: result.conflicted.length,\n hasConflicts: result.conflicted.length > 0,\n workspaceDepsFound: workspaceDeps.length,\n workspaceDepsMigrated: migratedDeps,\n catalystDepsBumped: bumped.length,\n cliOutdated: staleCli !== null,\n });\n\n printSummary({\n result,\n relDir,\n stampedPkg: stampedText !== null,\n migratedDeps,\n packageManager,\n staleCli,\n });\n } finally {\n await rm(tmpDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 500 });\n }\n });\n","import { Command } from 'commander';\n\nimport PACKAGE_INFO from '../../../package.json';\nimport { consola } from '../lib/logger';\n\nexport const version = new Command('version')\n .configureHelp({ showGlobalOptions: true })\n .description('Display detailed version information.')\n .addHelpText(\n 'after',\n `\nExample:\n $ catalyst version`,\n )\n .action(() => {\n consola.log('Version Information:');\n consola.log(`CLI Version: ${PACKAGE_INFO.version}`);\n consola.log(`Node Version: ${process.version}`);\n consola.log(`Platform: ${process.platform} (${process.arch})`);\n });\n","import { Command, type CommandUnknownOpts } from '@commander-js/extra-typings';\n\nimport { getTelemetry } from '../lib/telemetry';\n\nconst allowlistArguments = ['--keep-temp-dir', '--api-host', '--project-uuid'];\n\nfunction parseArguments(args: string[]) {\n return args.reduce<Record<string, string>>((result, arg, index, array) => {\n if (arg.includes('=')) {\n const [key, value] = arg.split('=');\n\n if (allowlistArguments.includes(key)) {\n return {\n ...result,\n [key]: value,\n };\n }\n }\n\n if (allowlistArguments.includes(arg)) {\n const nextValue =\n array[index + 1] && !array[index + 1].startsWith('--') ? array[index + 1] : null;\n\n if (nextValue && !nextValue.includes('--')) {\n return {\n ...result,\n [arg]: nextValue,\n };\n }\n }\n\n return result;\n }, {});\n}\n\nfunction getCommandPath(cmd: CommandUnknownOpts): string {\n const parts: string[] = [];\n let current: CommandUnknownOpts | null = cmd;\n\n while (current.parent) {\n parts.unshift(current.name());\n current = current.parent;\n }\n\n return parts.join(' ');\n}\n\nexport const telemetryPreHook = async (thisCommand: Command, actionCommand: CommandUnknownOpts) => {\n const telemetry = getTelemetry();\n const commandName = getCommandPath(actionCommand);\n\n telemetry.commandName = commandName;\n\n // Return the await to get a proper stack trace.\n // eslint-disable-next-line @typescript-eslint/no-confusing-void-expression\n return await telemetry.track(commandName, {\n ...parseArguments(thisCommand.args),\n });\n};\n\nexport const telemetryPostHook = async () => {\n const telemetry = getTelemetry();\n\n await telemetry.track('command_completed', { durationMs: telemetry.durationMs() });\n await telemetry.analytics.closeAndFlush();\n};\n","#!/usr/bin/env node\nimport { UserActionableError } from './lib/errors';\nimport { consola } from './lib/logger';\nimport { getTelemetry } from './lib/telemetry';\nimport { program } from './program';\n\nconst handleFatalError = async (error: unknown) => {\n const telemetry = getTelemetry();\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorStack = error instanceof Error ? error.stack : undefined;\n\n try {\n await telemetry.track('error', {\n commandName: telemetry.commandName,\n errorMessage,\n errorStack,\n durationMs: telemetry.durationMs(),\n });\n await telemetry.analytics.closeAndFlush();\n } catch {\n // Don't mask the original error\n }\n\n // A user-actionable error (invalid/expired token, a clear 4xx validation or\n // conflict response, a feature that isn't enabled) already tells the user what\n // to do — print it without the \"share your Correlation ID with support\" noise\n // that only helps for genuine bugs and server-side failures.\n if (error instanceof UserActionableError) {\n consola.error(errorMessage);\n process.exit(1);\n }\n\n consola.error(errorMessage);\n\n if (telemetry.isEnabled()) {\n consola.info(\n `Correlation ID: ${telemetry.correlationId}\\nShare this Correlation ID with BigCommerce support.`,\n );\n } else {\n consola.info(\n 'Enable telemetry (`catalyst telemetry enable`) for improved troubleshooting with BigCommerce support.',\n );\n }\n\n process.exit(1);\n};\n\nprocess.on('uncaughtException', (error) => {\n void handleFatalError(error);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n void handleFatalError(reason);\n});\n\nvoid (async () => {\n try {\n await program.parseAsync(process.argv);\n } catch (error) {\n await handleFatalError(error);\n }\n})();\n"],"mappings":"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","names":["Command","colorize","Option","z","z","z","z","resolve","z","z","z","Conf","config","StoreProfileSchema","z","fetchStoreProfile","config","projects","login","Option","Command","Option","execa","join","colorize","colorize","confirm","input","colorize","existsSync","join","z","z","existsSync","join","confirm","input","colorize","join","dirname","join","yoctoSpinner","run","existsSync","readFileSync","join","z","projectJsonSchema","env","join","execa","Command","Option","config","confirm","select","Command","InvalidArgumentError","Option","colorize","confirm","input","select","z","query","authHeaders","z","channels","resolve","projects","channels","select","input","config","confirm","input","select","colorize","z","z","input","select","colorize","input","config","config","existsSync","readFileSync","join","resolve","InvalidArgumentError","config","Command","Option","select","colorize","confirm","Command","InvalidArgumentError","Option","input","select","execSync","colorize","join","mkdirSync","resolve","mkdirSync","join","join","readFileSync","writeFileSync","join","z","corePackageJsonSchema","z","version","join","readFileSync","writeFileSync","mkdirSync","readFileSync","writeFileSync","dirname","join","z","corePackageJsonSchema","z","writeJson","mkdirSync","dirname","writeFileSync","join","readFileSync","parseChannelId","InvalidArgumentError","channels","select","join","input","execSync","create","Command","Option","colorize","Command","Option","existsSync","readFileSync","dirname","join","z","PROJECT_LOCKFILES","env","join","existsSync","readFileSync","detectProjectPackageManager","dirname","projectJsonSchema","z","safeReadJson","readProjectJson","telemetry","version","Command","Option","confirm","Command","Option","colorize","access","join","yoctoSpinner","z","confirm","config","projects","confirm","z","join","access","yoctoSpinner","colorize","Command","Option","config","telemetry","confirm","confirm","select","Command","Option","colorize","z","colorize","z","z","start","colorize","z","authHeaders","getDomain","query","resolve","config","projects","select","colorize","row","getDomain","Command","Option","confirm","Command","add","Command","config","remove","list","Command","InvalidArgumentError","Option","colorize","z","LEVEL_COLORS","z","colorize","resolve","Command","Option","config","InvalidArgumentError","start","confirm","input","select","Command","colorize","confirm","list","Command","config","colorize","create","input","link","select","Command","execa","existsSync","join","Command","execa","join","existsSync","Command","Option","colorize","Command","Option","colorize","Command","Option","confirm","execa","access","copyFile","cp","readdir","readFile","rm","writeFile","dirname","join","relative","minVersion","satisfies","semverLt","validRange","validSemver","yoctoSpinner","z","z","DEP_FIELDS","join","access","readdir","readFile","dirname","copyFile","version","writeFile","validRange","validSemver","satisfies","minVersion","semverLt","execa","rm","env","resolveProject","relative","cp","confirm","Command","Option","yoctoSpinner","Command","Command","telemetry","Command","colorize","create","telemetry"]}