Files
AFFiNE-Mirror/tools/cli/src/command.ts
T
fengmk2 d6000ce70b chore(tools): add @affine/admin to available packages (#12507)
![image.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/hTwOityLamd4hitrae7M/52e2017b-cd59-4549-8c24-be84b7000d56.png)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->

## Summary by CodeRabbit

- **New Features**
  - Added '@affine/admin' to the list of selectable packages for development commands.
- **Enhancements**
  - Improved package selection prompt by displaying up to 10 choices at a time for easier navigation.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-05-26 03:31:32 +00:00

143 lines
3.9 KiB
TypeScript

import { AliasToPackage } from '@affine-tools/utils/distribution';
import { Logger } from '@affine-tools/utils/logger';
import { exec, execAsync, spawn } from '@affine-tools/utils/process';
import { type PackageName, Workspace } from '@affine-tools/utils/workspace';
import { Command as BaseCommand, Option } from 'clipanion';
import inquirer from 'inquirer';
import * as t from 'typanion';
import type { CliContext } from './context';
export abstract class Command extends BaseCommand<CliContext> {
// @ts-expect-error hack: Get the command name
cmd = this.constructor.paths[0][0];
get logger() {
return new Logger(this.cmd);
}
get workspace() {
return this.context.workspace;
}
set workspace(workspace: Workspace) {
this.context.workspace = workspace;
}
exec = exec.bind(null, this.cmd);
execAsync = execAsync.bind(null, this.cmd);
spawn = spawn.bind(null, this.cmd);
}
export abstract class PackageCommand extends Command {
protected availablePackageNameArgs = (
Workspace.PackageNames as string[]
).concat(Array.from(AliasToPackage.keys()));
protected packageNameValidator = t.isOneOf(
this.availablePackageNameArgs.map(k => t.isLiteral(k))
);
protected packageNameOrAlias = Option.String('--package,-p', {
required: true,
validator: this.packageNameValidator,
description: 'The package name or alias to be run with',
});
get package(): PackageName {
const name =
AliasToPackage.get(this.packageNameOrAlias as any) ??
(this.packageNameOrAlias as PackageName);
// check
this.workspace.getPackage(name);
return name;
}
protected _deps = Option.Boolean('--deps', false, {
description:
'Execute the same command in workspace dependencies, if defined.',
});
get deps() {
return this._deps;
}
waitDeps = Option.Boolean('--wait-deps', false, {
description: 'Wait for dependencies to be ready before running the command',
});
}
export abstract class PackagesCommand extends Command {
protected availablePackageNameArgs = (
Workspace.PackageNames as string[]
).concat(Array.from(AliasToPackage.keys()));
protected packageNameValidator = t.isOneOf(
this.availablePackageNameArgs.map(k => t.isLiteral(k))
);
protected packageNamesOrAliases = Option.Array('--package,-p', {
required: true,
validator: t.isArray(this.packageNameValidator),
});
get packages() {
return this.packageNamesOrAliases.map(
name => AliasToPackage.get(name as any) ?? name
);
}
deps = Option.Boolean('--deps', false, {
description:
'Execute the same command in workspace dependencies, if defined.',
});
}
export abstract class PackageSelectorCommand extends Command {
protected availablePackages = Workspace.PackageNames;
protected availablePackageNameArgs = (
Workspace.PackageNames as string[]
).concat(Array.from(AliasToPackage.keys()));
protected packageNameValidator = t.isOneOf(
this.availablePackageNameArgs.map(k => t.isLiteral(k))
);
protected packageNameOrAlias = Option.String('--package,-p', {
validator: this.packageNameValidator,
description: 'The package name or alias to be run with',
});
async getPackage(): Promise<PackageName> {
let name = this.packageNameOrAlias
? (AliasToPackage.get(this.packageNameOrAlias as any) ??
this.packageNameOrAlias)
: undefined;
if (!name) {
const answer = await inquirer.prompt([
{
type: 'list',
name: 'package',
message: 'Which package do you want to dev?',
choices: this.availablePackages.map(name => ({
name,
value: name,
})),
pageSize: 10,
default: '@affine/web',
},
]);
name = answer.package as PackageName;
}
// check
this.workspace.getPackage(name as PackageName);
return name as PackageName;
}
}
export { Option };