Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: move command config closer to action #935

Merged
merged 1 commit into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/brave-onions-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bigcommerce/create-catalyst": patch
---

Move CLI command configuration closer to command action handlers
49 changes: 46 additions & 3 deletions packages/create-catalyst/src/commands/create.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Command, Option } from '@commander-js/extra-typings';
import { input, select } from '@inquirer/prompts';
import chalk from 'chalk';
import { exec as execCallback } from 'child_process';
Expand All @@ -7,19 +8,61 @@ import { join } from 'path';
import { promisify } from 'util';
import { z } from 'zod';

import { type CreateCommandOptions } from '..';
import { checkStorefrontLimit } from '../utils/check-storefront-limit';
import { cloneCatalyst } from '../utils/clone-catalyst';
import { getLatestCoreTag } from '../utils/get-latest-core-tag';
import { Https } from '../utils/https';
import { installDependencies } from '../utils/install-dependencies';
import { login } from '../utils/login';
import { parse } from '../utils/parse';
import { getPackageManager, packageManagerChoices } from '../utils/pm';
import { spinner } from '../utils/spinner';
import { writeEnv } from '../utils/write-env';

const exec = promisify(execCallback);

export const create = async (options: CreateCommandOptions) => {
export const create = new Command('create')
.description('Command to scaffold and connect a Catalyst storefront to your BigCommerce store')
.option('--project-name <name>', 'Name of your Catalyst project')
.option('--project-dir <dir>', 'Directory in which to create your project', process.cwd())
.option('--store-hash <hash>', 'BigCommerce store hash')
.option('--access-token <token>', 'BigCommerce access token')
.option('--channel-id <id>', 'BigCommerce channel ID')
.option('--customer-impersonation-token <token>', 'BigCommerce customer impersonation token')
.addOption(
new Option(
'--gh-ref <ref>',
'Clone a specific ref from the bigcommerce/catalyst repository',
).default(getLatestCoreTag),
)
.addOption(
new Option('--bigcommerce-hostname <hostname>', 'BigCommerce hostname')
.default('bigcommerce.com')
.hideHelp(),
)
.addOption(
new Option('--sample-data-api-url <url>', 'BigCommerce sample data API URL')
.default('https://api.bc-sample.store')
.hideHelp(),
)
.addOption(
new Option('--package-manager <pm>', 'Override detected package manager')
.choices(packageManagerChoices)
.default(getPackageManager())
.hideHelp(),
)
.addOption(
new Option('--code-editor <editor>', 'Your preferred code editor')
.choices(['vscode'])
.default('vscode')
.hideHelp(),
)
.addOption(
new Option('--include-functional-tests', 'Include the functional test suite')
.default(false)
.hideHelp(),
)
.action(async (options) => {
const { packageManager, codeEditor, includeFunctionalTests } = options;

const URLSchema = z.string().url();
Expand Down Expand Up @@ -219,4 +262,4 @@ export const create = async (options: CreateCommandOptions) => {
'\nNext steps:\n',
chalk.yellow(`\ncd ${projectName} && ${packageManager} run dev\n`),
);
};
});
24 changes: 20 additions & 4 deletions packages/create-catalyst/src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,29 @@
import { Command, Option } from '@commander-js/extra-typings';
import { input, select } from '@inquirer/prompts';
import chalk from 'chalk';
import * as z from 'zod';

import { type InitCommandOptions } from '../index';
import { checkStorefrontLimit } from '../utils/check-storefront-limit';
import { Https } from '../utils/https';
import { login } from '../utils/login';
import { parse } from '../utils/parse';
import { writeEnv } from '../utils/write-env';

export const init = async (options: InitCommandOptions) => {
export const init = new Command('init')
.description('Connect a BigCommerce store with an existing Catalyst project')
.option('--store-hash <hash>', 'BigCommerce store hash')
.option('--access-token <token>', 'BigCommerce access token')
.addOption(
new Option('--bigcommerce-hostname <hostname>', 'BigCommerce hostname')
.default('bigcommerce.com')
.hideHelp(),
)
.addOption(
new Option('--sample-data-api-url <url>', 'BigCommerce sample data API URL')
.default('https://api.bc-sample.store')
.hideHelp(),
)
.action(async (options) => {
const projectDir = process.cwd();

const URLSchema = z.string().url();
Expand Down Expand Up @@ -85,7 +99,9 @@ export const init = async (options: InitCommandOptions) => {
const existingChannel = await select({
message: 'Which channel would you like to use?',
choices: availableChannels.data
.sort((a, b) => channelSortOrder.indexOf(a.platform) - channelSortOrder.indexOf(b.platform))
.sort(
(a, b) => channelSortOrder.indexOf(a.platform) - channelSortOrder.indexOf(b.platform),
)
.map((ch) => ({
name: ch.name,
value: ch,
Expand Down Expand Up @@ -116,4 +132,4 @@ export const init = async (options: InitCommandOptions) => {
accessToken,
customerImpersonationToken,
});
};
});
77 changes: 5 additions & 72 deletions packages/create-catalyst/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
#!/usr/bin/env node

import { Command, Option } from '@commander-js/extra-typings';
import { program } from '@commander-js/extra-typings';
import chalk from 'chalk';
import { satisfies } from 'semver';

import PACKAGE_INFO from '../package.json';

import { create } from './commands/create';
import { init } from './commands/init';
import { getLatestCoreTag } from './utils/get-latest-core-tag';
import { getPackageManager, packageManagerChoices } from './utils/pm';

if (!satisfies(process.version, PACKAGE_INFO.engines.node)) {
console.error(
Expand All @@ -27,76 +25,11 @@ if (!satisfies(process.version, PACKAGE_INFO.engines.node)) {

console.log(chalk.cyanBright(`\n◢ ${PACKAGE_INFO.name} v${PACKAGE_INFO.version}\n`));

export type Options<T> = T extends Command<infer Args, infer Opts> ? [...Args, Opts, T] : never;

const program = new Command()
program
.name(PACKAGE_INFO.name)
.version(PACKAGE_INFO.version)
.description('A command line tool to create a new Catalyst project.');

const createCommand = program
.command('create', { isDefault: true })
.description('Command to scaffold and connect a Catalyst storefront to your BigCommerce store')
.option('--project-name <name>', 'Name of your Catalyst project')
.option('--project-dir <dir>', 'Directory in which to create your project', process.cwd())
.option('--store-hash <hash>', 'BigCommerce store hash')
.option('--access-token <token>', 'BigCommerce access token')
.option('--channel-id <id>', 'BigCommerce channel ID')
.option('--customer-impersonation-token <token>', 'BigCommerce customer impersonation token')
.addOption(
new Option(
'--gh-ref <ref>',
'Clone a specific ref from the bigcommerce/catalyst repository',
).default(getLatestCoreTag),
)
.addOption(
new Option('--bigcommerce-hostname <hostname>', 'BigCommerce hostname')
.default('bigcommerce.com')
.hideHelp(),
)
.addOption(
new Option('--sample-data-api-url <url>', 'BigCommerce sample data API URL')
.default('https://api.bc-sample.store')
.hideHelp(),
)
.addOption(
new Option('--package-manager <pm>', 'Override detected package manager')
.choices(packageManagerChoices)
.default(getPackageManager())
.hideHelp(),
)
.addOption(
new Option('--code-editor <editor>', 'Your preferred code editor')
.choices(['vscode'])
.default('vscode')
.hideHelp(),
)
.addOption(
new Option('--include-functional-tests', 'Include the functional test suite')
.default(false)
.hideHelp(),
)
.action((opts) => create(opts));

export type CreateCommandOptions = Options<typeof createCommand>[0];

const initCommand = program
.command('init')
.description('Connect a BigCommerce store with an existing Catalyst project')
.option('--store-hash <hash>', 'BigCommerce store hash')
.option('--access-token <token>', 'BigCommerce access token')
.addOption(
new Option('--bigcommerce-hostname <hostname>', 'BigCommerce hostname')
.default('bigcommerce.com')
.hideHelp(),
)
.addOption(
new Option('--sample-data-api-url <url>', 'BigCommerce sample data API URL')
.default('https://api.bc-sample.store')
.hideHelp(),
)
.action((opts) => init(opts));

export type InitCommandOptions = Options<typeof initCommand>[0];
.description('A command line tool to create a new Catalyst project.')
.addCommand(create, { isDefault: true })
.addCommand(init);

program.parse(process.argv);
Loading